security deposit is based on trade amount

This commit is contained in:
woodser 2023-10-31 14:57:49 -04:00
parent 7610d65d38
commit 23525d89ee
40 changed files with 215 additions and 158 deletions

View file

@ -64,7 +64,8 @@ public class CreateOfferUsingFixedPriceTest extends AbstractOfferTest {
assertEquals(10_000_000, newOffer.getMinAmount()); assertEquals(10_000_000, newOffer.getMinAmount());
assertEquals("3600", newOffer.getVolume()); assertEquals("3600", newOffer.getVolume());
assertEquals("3600", newOffer.getMinVolume()); assertEquals("3600", newOffer.getMinVolume());
assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(audAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(audAccount.getId(), newOffer.getPaymentAccountId());
assertEquals(XMR, newOffer.getBaseCurrencyCode()); assertEquals(XMR, newOffer.getBaseCurrencyCode());
assertEquals("AUD", newOffer.getCounterCurrencyCode()); assertEquals("AUD", newOffer.getCounterCurrencyCode());
@ -80,7 +81,8 @@ public class CreateOfferUsingFixedPriceTest extends AbstractOfferTest {
assertEquals(10_000_000, newOffer.getMinAmount()); assertEquals(10_000_000, newOffer.getMinAmount());
assertEquals("3600", newOffer.getVolume()); assertEquals("3600", newOffer.getVolume());
assertEquals("3600", newOffer.getMinVolume()); assertEquals("3600", newOffer.getMinVolume());
assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(audAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(audAccount.getId(), newOffer.getPaymentAccountId());
assertEquals(XMR, newOffer.getBaseCurrencyCode()); assertEquals(XMR, newOffer.getBaseCurrencyCode());
assertEquals("AUD", newOffer.getCounterCurrencyCode()); assertEquals("AUD", newOffer.getCounterCurrencyCode());
@ -110,7 +112,8 @@ public class CreateOfferUsingFixedPriceTest extends AbstractOfferTest {
assertEquals(10_000_000, newOffer.getMinAmount()); assertEquals(10_000_000, newOffer.getMinAmount());
assertEquals("3000", newOffer.getVolume()); assertEquals("3000", newOffer.getVolume());
assertEquals("3000", newOffer.getMinVolume()); assertEquals("3000", newOffer.getMinVolume());
assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(usdAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(usdAccount.getId(), newOffer.getPaymentAccountId());
assertEquals(XMR, newOffer.getBaseCurrencyCode()); assertEquals(XMR, newOffer.getBaseCurrencyCode());
assertEquals(USD, newOffer.getCounterCurrencyCode()); assertEquals(USD, newOffer.getCounterCurrencyCode());
@ -126,7 +129,8 @@ public class CreateOfferUsingFixedPriceTest extends AbstractOfferTest {
assertEquals(10_000_000, newOffer.getMinAmount()); assertEquals(10_000_000, newOffer.getMinAmount());
assertEquals("3000", newOffer.getVolume()); assertEquals("3000", newOffer.getVolume());
assertEquals("3000", newOffer.getMinVolume()); assertEquals("3000", newOffer.getMinVolume());
assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(usdAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(usdAccount.getId(), newOffer.getPaymentAccountId());
assertEquals(XMR, newOffer.getBaseCurrencyCode()); assertEquals(XMR, newOffer.getBaseCurrencyCode());
assertEquals(USD, newOffer.getCounterCurrencyCode()); assertEquals(USD, newOffer.getCounterCurrencyCode());
@ -156,7 +160,8 @@ public class CreateOfferUsingFixedPriceTest extends AbstractOfferTest {
assertEquals(5_000_000, newOffer.getMinAmount()); assertEquals(5_000_000, newOffer.getMinAmount());
assertEquals("2950", newOffer.getVolume()); assertEquals("2950", newOffer.getVolume());
assertEquals("1475", newOffer.getMinVolume()); assertEquals("1475", newOffer.getMinVolume());
assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(eurAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(eurAccount.getId(), newOffer.getPaymentAccountId());
assertEquals(XMR, newOffer.getBaseCurrencyCode()); assertEquals(XMR, newOffer.getBaseCurrencyCode());
assertEquals(EUR, newOffer.getCounterCurrencyCode()); assertEquals(EUR, newOffer.getCounterCurrencyCode());
@ -172,7 +177,8 @@ public class CreateOfferUsingFixedPriceTest extends AbstractOfferTest {
assertEquals(5_000_000, newOffer.getMinAmount()); assertEquals(5_000_000, newOffer.getMinAmount());
assertEquals("2950", newOffer.getVolume()); assertEquals("2950", newOffer.getVolume());
assertEquals("1475", newOffer.getMinVolume()); assertEquals("1475", newOffer.getMinVolume());
assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(eurAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(eurAccount.getId(), newOffer.getPaymentAccountId());
assertEquals(XMR, newOffer.getBaseCurrencyCode()); assertEquals(XMR, newOffer.getBaseCurrencyCode());
assertEquals(EUR, newOffer.getCounterCurrencyCode()); assertEquals(EUR, newOffer.getCounterCurrencyCode());

View file

@ -80,7 +80,8 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct()); assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct());
assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getAmount());
assertEquals(10_000_000, newOffer.getMinAmount()); assertEquals(10_000_000, newOffer.getMinAmount());
assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(usdAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(usdAccount.getId(), newOffer.getPaymentAccountId());
assertEquals(BTC, newOffer.getBaseCurrencyCode()); assertEquals(BTC, newOffer.getBaseCurrencyCode());
assertEquals(USD, newOffer.getCounterCurrencyCode()); assertEquals(USD, newOffer.getCounterCurrencyCode());
@ -94,7 +95,8 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct()); assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct());
assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getAmount());
assertEquals(10_000_000, newOffer.getMinAmount()); assertEquals(10_000_000, newOffer.getMinAmount());
assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(usdAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(usdAccount.getId(), newOffer.getPaymentAccountId());
assertEquals(BTC, newOffer.getBaseCurrencyCode()); assertEquals(BTC, newOffer.getBaseCurrencyCode());
assertEquals(USD, newOffer.getCounterCurrencyCode()); assertEquals(USD, newOffer.getCounterCurrencyCode());
@ -126,7 +128,8 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct()); assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct());
assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getAmount());
assertEquals(10_000_000, newOffer.getMinAmount()); assertEquals(10_000_000, newOffer.getMinAmount());
assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(nzdAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(nzdAccount.getId(), newOffer.getPaymentAccountId());
assertEquals(BTC, newOffer.getBaseCurrencyCode()); assertEquals(BTC, newOffer.getBaseCurrencyCode());
assertEquals("NZD", newOffer.getCounterCurrencyCode()); assertEquals("NZD", newOffer.getCounterCurrencyCode());
@ -140,7 +143,8 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct()); assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct());
assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getAmount());
assertEquals(10_000_000, newOffer.getMinAmount()); assertEquals(10_000_000, newOffer.getMinAmount());
assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(nzdAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(nzdAccount.getId(), newOffer.getPaymentAccountId());
assertEquals(BTC, newOffer.getBaseCurrencyCode()); assertEquals(BTC, newOffer.getBaseCurrencyCode());
assertEquals("NZD", newOffer.getCounterCurrencyCode()); assertEquals("NZD", newOffer.getCounterCurrencyCode());
@ -172,7 +176,8 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct()); assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct());
assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getAmount());
assertEquals(5_000_000, newOffer.getMinAmount()); assertEquals(5_000_000, newOffer.getMinAmount());
assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(gbpAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(gbpAccount.getId(), newOffer.getPaymentAccountId());
assertEquals(BTC, newOffer.getBaseCurrencyCode()); assertEquals(BTC, newOffer.getBaseCurrencyCode());
assertEquals("GBP", newOffer.getCounterCurrencyCode()); assertEquals("GBP", newOffer.getCounterCurrencyCode());
@ -186,7 +191,8 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct()); assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct());
assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getAmount());
assertEquals(5_000_000, newOffer.getMinAmount()); assertEquals(5_000_000, newOffer.getMinAmount());
assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(gbpAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(gbpAccount.getId(), newOffer.getPaymentAccountId());
assertEquals(BTC, newOffer.getBaseCurrencyCode()); assertEquals(BTC, newOffer.getBaseCurrencyCode());
assertEquals("GBP", newOffer.getCounterCurrencyCode()); assertEquals("GBP", newOffer.getCounterCurrencyCode());
@ -218,7 +224,8 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct()); assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct());
assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getAmount());
assertEquals(5_000_000, newOffer.getMinAmount()); assertEquals(5_000_000, newOffer.getMinAmount());
assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(brlAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(brlAccount.getId(), newOffer.getPaymentAccountId());
assertEquals(BTC, newOffer.getBaseCurrencyCode()); assertEquals(BTC, newOffer.getBaseCurrencyCode());
assertEquals("BRL", newOffer.getCounterCurrencyCode()); assertEquals("BRL", newOffer.getCounterCurrencyCode());
@ -232,7 +239,8 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct()); assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct());
assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getAmount());
assertEquals(5_000_000, newOffer.getMinAmount()); assertEquals(5_000_000, newOffer.getMinAmount());
assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(brlAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(brlAccount.getId(), newOffer.getPaymentAccountId());
assertEquals(BTC, newOffer.getBaseCurrencyCode()); assertEquals(BTC, newOffer.getBaseCurrencyCode());
assertEquals("BRL", newOffer.getCounterCurrencyCode()); assertEquals("BRL", newOffer.getCounterCurrencyCode());

View file

@ -75,7 +75,8 @@ public class CreateXMROffersTest extends AbstractOfferTest {
assertEquals("0.00500000", newOffer.getPrice()); assertEquals("0.00500000", newOffer.getPrice());
assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(100_000_000L, newOffer.getAmount());
assertEquals(75_000_000L, newOffer.getMinAmount()); assertEquals(75_000_000L, newOffer.getMinAmount());
assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(alicesXmrAcct.getId(), newOffer.getPaymentAccountId()); assertEquals(alicesXmrAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(XMR, newOffer.getBaseCurrencyCode()); assertEquals(XMR, newOffer.getBaseCurrencyCode());
assertEquals(BTC, newOffer.getCounterCurrencyCode()); assertEquals(BTC, newOffer.getCounterCurrencyCode());
@ -91,7 +92,8 @@ public class CreateXMROffersTest extends AbstractOfferTest {
assertEquals("0.00500000", newOffer.getPrice()); assertEquals("0.00500000", newOffer.getPrice());
assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(100_000_000L, newOffer.getAmount());
assertEquals(75_000_000L, newOffer.getMinAmount()); assertEquals(75_000_000L, newOffer.getMinAmount());
assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(alicesXmrAcct.getId(), newOffer.getPaymentAccountId()); assertEquals(alicesXmrAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(XMR, newOffer.getBaseCurrencyCode()); assertEquals(XMR, newOffer.getBaseCurrencyCode());
assertEquals(BTC, newOffer.getCounterCurrencyCode()); assertEquals(BTC, newOffer.getCounterCurrencyCode());
@ -119,7 +121,8 @@ public class CreateXMROffersTest extends AbstractOfferTest {
assertEquals("0.00500000", newOffer.getPrice()); assertEquals("0.00500000", newOffer.getPrice());
assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(100_000_000L, newOffer.getAmount());
assertEquals(50_000_000L, newOffer.getMinAmount()); assertEquals(50_000_000L, newOffer.getMinAmount());
assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(alicesXmrAcct.getId(), newOffer.getPaymentAccountId()); assertEquals(alicesXmrAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(XMR, newOffer.getBaseCurrencyCode()); assertEquals(XMR, newOffer.getBaseCurrencyCode());
assertEquals(BTC, newOffer.getCounterCurrencyCode()); assertEquals(BTC, newOffer.getCounterCurrencyCode());
@ -135,7 +138,8 @@ public class CreateXMROffersTest extends AbstractOfferTest {
assertEquals("0.00500000", newOffer.getPrice()); assertEquals("0.00500000", newOffer.getPrice());
assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(100_000_000L, newOffer.getAmount());
assertEquals(50_000_000L, newOffer.getMinAmount()); assertEquals(50_000_000L, newOffer.getMinAmount());
assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(alicesXmrAcct.getId(), newOffer.getPaymentAccountId()); assertEquals(alicesXmrAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(XMR, newOffer.getBaseCurrencyCode()); assertEquals(XMR, newOffer.getBaseCurrencyCode());
assertEquals(BTC, newOffer.getCounterCurrencyCode()); assertEquals(BTC, newOffer.getCounterCurrencyCode());
@ -169,7 +173,8 @@ public class CreateXMROffersTest extends AbstractOfferTest {
assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(100_000_000L, newOffer.getAmount());
assertEquals(75_000_000L, newOffer.getMinAmount()); assertEquals(75_000_000L, newOffer.getMinAmount());
assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(alicesXmrAcct.getId(), newOffer.getPaymentAccountId()); assertEquals(alicesXmrAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(XMR, newOffer.getBaseCurrencyCode()); assertEquals(XMR, newOffer.getBaseCurrencyCode());
assertEquals(BTC, newOffer.getCounterCurrencyCode()); assertEquals(BTC, newOffer.getCounterCurrencyCode());
@ -189,7 +194,8 @@ public class CreateXMROffersTest extends AbstractOfferTest {
assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(100_000_000L, newOffer.getAmount());
assertEquals(75_000_000L, newOffer.getMinAmount()); assertEquals(75_000_000L, newOffer.getMinAmount());
assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(alicesXmrAcct.getId(), newOffer.getPaymentAccountId()); assertEquals(alicesXmrAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(XMR, newOffer.getBaseCurrencyCode()); assertEquals(XMR, newOffer.getBaseCurrencyCode());
assertEquals(BTC, newOffer.getCounterCurrencyCode()); assertEquals(BTC, newOffer.getCounterCurrencyCode());
@ -218,7 +224,8 @@ public class CreateXMROffersTest extends AbstractOfferTest {
assertTrue(newOffer.getUseMarketBasedPrice()); assertTrue(newOffer.getUseMarketBasedPrice());
assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(100_000_000L, newOffer.getAmount());
assertEquals(50_000_000L, newOffer.getMinAmount()); assertEquals(50_000_000L, newOffer.getMinAmount());
assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(alicesXmrAcct.getId(), newOffer.getPaymentAccountId()); assertEquals(alicesXmrAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(XMR, newOffer.getBaseCurrencyCode()); assertEquals(XMR, newOffer.getBaseCurrencyCode());
assertEquals(BTC, newOffer.getCounterCurrencyCode()); assertEquals(BTC, newOffer.getCounterCurrencyCode());
@ -233,7 +240,8 @@ public class CreateXMROffersTest extends AbstractOfferTest {
assertTrue(newOffer.getUseMarketBasedPrice()); assertTrue(newOffer.getUseMarketBasedPrice());
assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(100_000_000L, newOffer.getAmount());
assertEquals(50_000_000L, newOffer.getMinAmount()); assertEquals(50_000_000L, newOffer.getMinAmount());
assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); assertEquals(.15, newOffer.getBuyerSecurityDepositPct());
assertEquals(.15, newOffer.getSellerSecurityDepositPct());
assertEquals(alicesXmrAcct.getId(), newOffer.getPaymentAccountId()); assertEquals(alicesXmrAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(XMR, newOffer.getBaseCurrencyCode()); assertEquals(XMR, newOffer.getBaseCurrencyCode());
assertEquals(BTC, newOffer.getCounterCurrencyCode()); assertEquals(BTC, newOffer.getCounterCurrencyCode());

View file

@ -60,9 +60,9 @@ abstract class AbstractTradeListBuilder extends AbstractTableBuilder {
@Nullable @Nullable
protected final MixedTradeFeeColumn colMixedTradeFee; protected final MixedTradeFeeColumn colMixedTradeFee;
@Nullable @Nullable
protected final Column<Long> colBuyerDeposit; protected final Column<Double> colBuyerDeposit;
@Nullable @Nullable
protected final Column<Long> colSellerDeposit; protected final Column<Double> colSellerDeposit;
@Nullable @Nullable
protected final Column<String> colPaymentMethod; protected final Column<String> colPaymentMethod;
@Nullable @Nullable

View file

@ -61,8 +61,8 @@ class ClosedTradeTableBuilder extends AbstractTradeListBuilder {
colMixedTradeFee.addRow(toTradeFeeBtc.apply(t), false); colMixedTradeFee.addRow(toTradeFeeBtc.apply(t), false);
colBuyerDeposit.addRow(t.getOffer().getBuyerSecurityDeposit()); colBuyerDeposit.addRow(t.getOffer().getBuyerSecurityDepositPct());
colSellerDeposit.addRow(t.getOffer().getSellerSecurityDeposit()); colSellerDeposit.addRow(t.getOffer().getSellerSecurityDepositPct());
colOfferType.addRow(toOfferType.apply(t)); colOfferType.addRow(toOfferType.apply(t));
}); });
} }

View file

@ -18,6 +18,7 @@
package haveno.cli.table.builder; package haveno.cli.table.builder;
import haveno.cli.table.column.CryptoVolumeColumn; import haveno.cli.table.column.CryptoVolumeColumn;
import haveno.cli.table.column.DoubleColumn;
import haveno.cli.table.column.BooleanColumn; import haveno.cli.table.column.BooleanColumn;
import haveno.cli.table.column.BtcColumn; import haveno.cli.table.column.BtcColumn;
import haveno.cli.table.column.Column; import haveno.cli.table.column.Column;
@ -169,8 +170,8 @@ class TradeTableColumnSupplier {
: null; : null;
}; };
final Function<String, Column<Long>> toSecurityDepositColumn = (name) -> isClosedTradeTblBuilder.get() final Function<String, Column<Double>> toSecurityDepositColumn = (name) -> isClosedTradeTblBuilder.get()
? new SatoshiColumn(name) ? new DoubleColumn(name)
: null; : null;
final Supplier<StringColumn> offerTypeColumn = () -> isTradeDetailTblBuilder.get() final Supplier<StringColumn> offerTypeColumn = () -> isTradeDetailTblBuilder.get()

View file

@ -156,7 +156,7 @@ public class CoreOffersService {
double marketPriceMargin, double marketPriceMargin,
long amountAsLong, long amountAsLong,
long minAmountAsLong, long minAmountAsLong,
double buyerSecurityDeposit, double securityDeposit,
String triggerPriceAsString, String triggerPriceAsString,
boolean reserveExactAmount, boolean reserveExactAmount,
String paymentAccountId, String paymentAccountId,
@ -183,7 +183,7 @@ public class CoreOffersService {
price, price,
useMarketBasedPrice, useMarketBasedPrice,
exactMultiply(marketPriceMargin, 0.01), exactMultiply(marketPriceMargin, 0.01),
buyerSecurityDeposit, securityDeposit,
paymentAccount); paymentAccount);
verifyPaymentAccountIsValidForNewOffer(offer, paymentAccount); verifyPaymentAccountIsValidForNewOffer(offer, paymentAccount);

View file

@ -54,8 +54,8 @@ public class OfferInfo implements Payload {
private final String minVolume; private final String minVolume;
private final long makerFee; private final long makerFee;
@Nullable @Nullable
private final long buyerSecurityDeposit; private final double buyerSecurityDepositPct;
private final long sellerSecurityDeposit; private final double sellerSecurityDepositPct;
private final String triggerPrice; private final String triggerPrice;
private final String paymentAccountId; private final String paymentAccountId;
private final String paymentMethodId; private final String paymentMethodId;
@ -89,8 +89,8 @@ public class OfferInfo implements Payload {
this.volume = builder.getVolume(); this.volume = builder.getVolume();
this.minVolume = builder.getMinVolume(); this.minVolume = builder.getMinVolume();
this.makerFee = builder.getMakerFee(); this.makerFee = builder.getMakerFee();
this.buyerSecurityDeposit = builder.getBuyerSecurityDeposit(); this.buyerSecurityDepositPct = builder.getBuyerSecurityDepositPct();
this.sellerSecurityDeposit = builder.getSellerSecurityDeposit(); this.sellerSecurityDepositPct = builder.getSellerSecurityDepositPct();
this.triggerPrice = builder.getTriggerPrice(); this.triggerPrice = builder.getTriggerPrice();
this.paymentAccountId = builder.getPaymentAccountId(); this.paymentAccountId = builder.getPaymentAccountId();
this.paymentMethodId = builder.getPaymentMethodId(); this.paymentMethodId = builder.getPaymentMethodId();
@ -158,8 +158,8 @@ public class OfferInfo implements Payload {
.withVolume(roundedVolume) .withVolume(roundedVolume)
.withMinVolume(roundedMinVolume) .withMinVolume(roundedMinVolume)
.withMakerFee(offer.getMakerFee().longValueExact()) .withMakerFee(offer.getMakerFee().longValueExact())
.withBuyerSecurityDeposit(offer.getBuyerSecurityDeposit().longValueExact()) .withBuyerSecurityDepositPct(offer.getBuyerSecurityDepositPct())
.withSellerSecurityDeposit(offer.getSellerSecurityDeposit().longValueExact()) .withSellerSecurityDepositPct(offer.getSellerSecurityDepositPct())
.withPaymentAccountId(offer.getMakerPaymentAccountId()) .withPaymentAccountId(offer.getMakerPaymentAccountId())
.withPaymentMethodId(offer.getPaymentMethod().getId()) .withPaymentMethodId(offer.getPaymentMethod().getId())
.withPaymentMethodShortName(offer.getPaymentMethod().getShortName()) .withPaymentMethodShortName(offer.getPaymentMethod().getShortName())
@ -191,8 +191,8 @@ public class OfferInfo implements Payload {
.setVolume(volume) .setVolume(volume)
.setMinVolume(minVolume) .setMinVolume(minVolume)
.setMakerFee(makerFee) .setMakerFee(makerFee)
.setBuyerSecurityDeposit(buyerSecurityDeposit) .setBuyerSecurityDepositPct(buyerSecurityDepositPct)
.setSellerSecurityDeposit(sellerSecurityDeposit) .setSellerSecurityDepositPct(sellerSecurityDepositPct)
.setTriggerPrice(triggerPrice == null ? "0" : triggerPrice) .setTriggerPrice(triggerPrice == null ? "0" : triggerPrice)
.setPaymentAccountId(paymentAccountId) .setPaymentAccountId(paymentAccountId)
.setPaymentMethodId(paymentMethodId) .setPaymentMethodId(paymentMethodId)
@ -226,8 +226,8 @@ public class OfferInfo implements Payload {
.withVolume(proto.getVolume()) .withVolume(proto.getVolume())
.withMinVolume(proto.getMinVolume()) .withMinVolume(proto.getMinVolume())
.withMakerFee(proto.getMakerFee()) .withMakerFee(proto.getMakerFee())
.withBuyerSecurityDeposit(proto.getBuyerSecurityDeposit()) .withBuyerSecurityDepositPct(proto.getBuyerSecurityDepositPct())
.withSellerSecurityDeposit(proto.getSellerSecurityDeposit()) .withSellerSecurityDepositPct(proto.getSellerSecurityDepositPct())
.withTriggerPrice(proto.getTriggerPrice()) .withTriggerPrice(proto.getTriggerPrice())
.withPaymentAccountId(proto.getPaymentAccountId()) .withPaymentAccountId(proto.getPaymentAccountId())
.withPaymentMethodId(proto.getPaymentMethodId()) .withPaymentMethodId(proto.getPaymentMethodId())

View file

@ -39,8 +39,8 @@ public final class OfferInfoBuilder {
private String volume; private String volume;
private String minVolume; private String minVolume;
private long makerFee; private long makerFee;
private long buyerSecurityDeposit; private double buyerSecurityDepositPct;
private long sellerSecurityDeposit; private double sellerSecurityDepositPct;
private String triggerPrice; private String triggerPrice;
private boolean isCurrencyForMakerFeeBtc; private boolean isCurrencyForMakerFeeBtc;
private String paymentAccountId; private String paymentAccountId;
@ -112,13 +112,13 @@ public final class OfferInfoBuilder {
return this; return this;
} }
public OfferInfoBuilder withBuyerSecurityDeposit(long buyerSecurityDeposit) { public OfferInfoBuilder withBuyerSecurityDepositPct(double buyerSecurityDepositPct) {
this.buyerSecurityDeposit = buyerSecurityDeposit; this.buyerSecurityDepositPct = buyerSecurityDepositPct;
return this; return this;
} }
public OfferInfoBuilder withSellerSecurityDeposit(long sellerSecurityDeposit) { public OfferInfoBuilder withSellerSecurityDepositPct(double sellerSecurityDepositPct) {
this.sellerSecurityDeposit = sellerSecurityDeposit; this.sellerSecurityDepositPct = sellerSecurityDepositPct;
return this; return this;
} }

View file

@ -103,7 +103,7 @@ public class CreateOfferService {
Price fixedPrice, Price fixedPrice,
boolean useMarketBasedPrice, boolean useMarketBasedPrice,
double marketPriceMargin, double marketPriceMargin,
double buyerSecurityDepositAsDouble, double securityDepositAsDouble,
PaymentAccount paymentAccount) { PaymentAccount paymentAccount) {
log.info("create and get offer with offerId={}, " + log.info("create and get offer with offerId={}, " +
@ -114,7 +114,7 @@ public class CreateOfferService {
"marketPriceMargin={}, " + "marketPriceMargin={}, " +
"amount={}, " + "amount={}, " +
"minAmount={}, " + "minAmount={}, " +
"buyerSecurityDeposit={}", "securityDeposit={}",
offerId, offerId,
currencyCode, currencyCode,
direction, direction,
@ -123,7 +123,7 @@ public class CreateOfferService {
marketPriceMargin, marketPriceMargin,
amount, amount,
minAmount, minAmount,
buyerSecurityDepositAsDouble); securityDepositAsDouble);
// verify fixed price xor market price with margin // verify fixed price xor market price with margin
if (fixedPrice != null) { if (fixedPrice != null) {
@ -161,10 +161,7 @@ public class CreateOfferService {
List<String> acceptedCountryCodes = PaymentAccountUtil.getAcceptedCountryCodes(paymentAccount); List<String> acceptedCountryCodes = PaymentAccountUtil.getAcceptedCountryCodes(paymentAccount);
String bankId = PaymentAccountUtil.getBankId(paymentAccount); String bankId = PaymentAccountUtil.getBankId(paymentAccount);
List<String> acceptedBanks = PaymentAccountUtil.getAcceptedBanks(paymentAccount); List<String> acceptedBanks = PaymentAccountUtil.getAcceptedBanks(paymentAccount);
double sellerSecurityDepositAsDouble = getSellerSecurityDepositAsDouble(buyerSecurityDepositAsDouble);
BigInteger makerFee = HavenoUtils.getMakerFee(amount); BigInteger makerFee = HavenoUtils.getMakerFee(amount);
BigInteger buyerSecurityDeposit = getBuyerSecurityDeposit(amount, buyerSecurityDepositAsDouble);
BigInteger sellerSecurityDeposit = getSellerSecurityDeposit(amount, sellerSecurityDepositAsDouble);
long maxTradePeriod = paymentAccount.getMaxTradePeriod(); long maxTradePeriod = paymentAccount.getMaxTradePeriod();
// reserved for future use cases // reserved for future use cases
@ -180,7 +177,7 @@ public class CreateOfferService {
direction); direction);
offerUtil.validateOfferData( offerUtil.validateOfferData(
buyerSecurityDepositAsDouble, securityDepositAsDouble,
paymentAccount, paymentAccount,
currencyCode, currencyCode,
makerFee); makerFee);
@ -206,8 +203,8 @@ public class CreateOfferService {
Version.VERSION, Version.VERSION,
xmrWalletService.getWallet().getHeight(), xmrWalletService.getWallet().getHeight(),
makerFee.longValueExact(), makerFee.longValueExact(),
buyerSecurityDeposit.longValueExact(), securityDepositAsDouble,
sellerSecurityDeposit.longValueExact(), securityDepositAsDouble,
maxTradeLimit, maxTradeLimit,
maxTradePeriod, maxTradePeriod,
useAutoClose, useAutoClose,

View file

@ -279,7 +279,7 @@ public class Offer implements NetworkPayload, PersistablePayload {
// get the amount needed for the maker to reserve the offer // get the amount needed for the maker to reserve the offer
public BigInteger getReserveAmount() { public BigInteger getReserveAmount() {
BigInteger reserveAmount = getDirection() == OfferDirection.BUY ? getBuyerSecurityDeposit() : getSellerSecurityDeposit(); BigInteger reserveAmount = getDirection() == OfferDirection.BUY ? getMaxBuyerSecurityDeposit() : getMaxSellerSecurityDeposit();
if (getDirection() == OfferDirection.SELL) reserveAmount = reserveAmount.add(getAmount()); if (getDirection() == OfferDirection.SELL) reserveAmount = reserveAmount.add(getAmount());
reserveAmount = reserveAmount.add(getMakerFee()); reserveAmount = reserveAmount.add(getMakerFee());
return reserveAmount; return reserveAmount;
@ -289,12 +289,20 @@ public class Offer implements NetworkPayload, PersistablePayload {
return BigInteger.valueOf(offerPayload.getMakerFee()); return BigInteger.valueOf(offerPayload.getMakerFee());
} }
public BigInteger getBuyerSecurityDeposit() { public BigInteger getMaxBuyerSecurityDeposit() {
return BigInteger.valueOf(offerPayload.getBuyerSecurityDeposit()); return offerPayload.getMaxBuyerSecurityDeposit();
} }
public BigInteger getSellerSecurityDeposit() { public BigInteger getMaxSellerSecurityDeposit() {
return BigInteger.valueOf(offerPayload.getSellerSecurityDeposit()); return offerPayload.getMaxSellerSecurityDeposit();
}
public double getBuyerSecurityDepositPct() {
return offerPayload.getBuyerSecurityDepositPct();
}
public double getSellerSecurityDepositPct() {
return offerPayload.getSellerSecurityDepositPct();
} }
public BigInteger getMaxTradeLimit() { public BigInteger getMaxTradeLimit() {

View file

@ -28,6 +28,8 @@ import haveno.common.util.CollectionUtils;
import haveno.common.util.Hex; import haveno.common.util.Hex;
import haveno.common.util.JsonExclude; import haveno.common.util.JsonExclude;
import haveno.common.util.Utilities; import haveno.common.util.Utilities;
import haveno.core.trade.HavenoUtils;
import haveno.core.xmr.wallet.Restrictions;
import haveno.network.p2p.NodeAddress; import haveno.network.p2p.NodeAddress;
import haveno.network.p2p.storage.payload.ExpirablePayload; import haveno.network.p2p.storage.payload.ExpirablePayload;
import haveno.network.p2p.storage.payload.ProtectedStoragePayload; import haveno.network.p2p.storage.payload.ProtectedStoragePayload;
@ -39,6 +41,7 @@ import lombok.extern.slf4j.Slf4j;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.math.BigInteger;
import java.security.PublicKey; import java.security.PublicKey;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -130,8 +133,8 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
private final List<String> acceptedBankIds; private final List<String> acceptedBankIds;
private final long blockHeightAtOfferCreation; private final long blockHeightAtOfferCreation;
private final long makerFee; private final long makerFee;
private final long buyerSecurityDeposit; private final double buyerSecurityDepositPct;
private final long sellerSecurityDeposit; private final double sellerSecurityDepositPct;
private final long maxTradeLimit; private final long maxTradeLimit;
private final long maxTradePeriod; private final long maxTradePeriod;
@ -176,8 +179,8 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
String versionNr, String versionNr,
long blockHeightAtOfferCreation, long blockHeightAtOfferCreation,
long makerFee, long makerFee,
long buyerSecurityDeposit, double buyerSecurityDepositPct,
long sellerSecurityDeposit, double sellerSecurityDepositPct,
long maxTradeLimit, long maxTradeLimit,
long maxTradePeriod, long maxTradePeriod,
boolean useAutoClose, boolean useAutoClose,
@ -217,8 +220,8 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
this.acceptedBankIds = acceptedBankIds; this.acceptedBankIds = acceptedBankIds;
this.blockHeightAtOfferCreation = blockHeightAtOfferCreation; this.blockHeightAtOfferCreation = blockHeightAtOfferCreation;
this.makerFee = makerFee; this.makerFee = makerFee;
this.buyerSecurityDeposit = buyerSecurityDeposit; this.buyerSecurityDepositPct = buyerSecurityDepositPct;
this.sellerSecurityDeposit = sellerSecurityDeposit; this.sellerSecurityDepositPct = sellerSecurityDepositPct;
this.maxTradeLimit = maxTradeLimit; this.maxTradeLimit = maxTradeLimit;
this.maxTradePeriod = maxTradePeriod; this.maxTradePeriod = maxTradePeriod;
this.useAutoClose = useAutoClose; this.useAutoClose = useAutoClose;
@ -261,8 +264,8 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
versionNr, versionNr,
blockHeightAtOfferCreation, blockHeightAtOfferCreation,
makerFee, makerFee,
buyerSecurityDeposit, buyerSecurityDepositPct,
sellerSecurityDeposit, sellerSecurityDepositPct,
maxTradeLimit, maxTradeLimit,
maxTradePeriod, maxTradePeriod,
useAutoClose, useAutoClose,
@ -300,6 +303,24 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
return getBaseCurrencyCode().equals("XMR") ? getCounterCurrencyCode() : getBaseCurrencyCode(); return getBaseCurrencyCode().equals("XMR") ? getCounterCurrencyCode() : getBaseCurrencyCode();
} }
public BigInteger getMaxBuyerSecurityDeposit() {
return getBuyerSecurityDepositForTradeAmount(BigInteger.valueOf(getAmount()));
}
public BigInteger getMaxSellerSecurityDeposit() {
return getSellerSecurityDepositForTradeAmount(BigInteger.valueOf(getAmount()));
}
public BigInteger getBuyerSecurityDepositForTradeAmount(BigInteger tradeAmount) {
BigInteger securityDepositUnadjusted = HavenoUtils.xmrToAtomicUnits(HavenoUtils.atomicUnitsToXmr(tradeAmount) * getBuyerSecurityDepositPct());
return Restrictions.getMinBuyerSecurityDeposit().max(securityDepositUnadjusted);
}
public BigInteger getSellerSecurityDepositForTradeAmount(BigInteger tradeAmount) {
BigInteger securityDepositUnadjusted = HavenoUtils.xmrToAtomicUnits(HavenoUtils.atomicUnitsToXmr(tradeAmount) * getSellerSecurityDepositPct());
return Restrictions.getMinSellerSecurityDeposit().max(securityDepositUnadjusted);
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// PROTO BUFFER // PROTO BUFFER
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -323,8 +344,8 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
.setVersionNr(versionNr) .setVersionNr(versionNr)
.setBlockHeightAtOfferCreation(blockHeightAtOfferCreation) .setBlockHeightAtOfferCreation(blockHeightAtOfferCreation)
.setMakerFee(makerFee) .setMakerFee(makerFee)
.setBuyerSecurityDeposit(buyerSecurityDeposit) .setBuyerSecurityDepositPct(buyerSecurityDepositPct)
.setSellerSecurityDeposit(sellerSecurityDeposit) .setSellerSecurityDepositPct(sellerSecurityDepositPct)
.setMaxTradeLimit(maxTradeLimit) .setMaxTradeLimit(maxTradeLimit)
.setMaxTradePeriod(maxTradePeriod) .setMaxTradePeriod(maxTradePeriod)
.setUseAutoClose(useAutoClose) .setUseAutoClose(useAutoClose)
@ -377,8 +398,8 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
proto.getVersionNr(), proto.getVersionNr(),
proto.getBlockHeightAtOfferCreation(), proto.getBlockHeightAtOfferCreation(),
proto.getMakerFee(), proto.getMakerFee(),
proto.getBuyerSecurityDeposit(), proto.getBuyerSecurityDepositPct(),
proto.getSellerSecurityDeposit(), proto.getSellerSecurityDepositPct(),
proto.getMaxTradeLimit(), proto.getMaxTradeLimit(),
proto.getMaxTradePeriod(), proto.getMaxTradePeriod(),
proto.getUseAutoClose(), proto.getUseAutoClose(),
@ -422,8 +443,8 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
",\r\n acceptedBankIds=" + acceptedBankIds + ",\r\n acceptedBankIds=" + acceptedBankIds +
",\r\n blockHeightAtOfferCreation=" + blockHeightAtOfferCreation + ",\r\n blockHeightAtOfferCreation=" + blockHeightAtOfferCreation +
",\r\n makerFee=" + makerFee + ",\r\n makerFee=" + makerFee +
",\r\n buyerSecurityDeposit=" + buyerSecurityDeposit + ",\r\n buyerSecurityDepositPct=" + buyerSecurityDepositPct +
",\r\n sellerSecurityDeposit=" + sellerSecurityDeposit + ",\r\n sellerSecurityDeposiPct=" + sellerSecurityDepositPct +
",\r\n maxTradeLimit=" + maxTradeLimit + ",\r\n maxTradeLimit=" + maxTradeLimit +
",\r\n maxTradePeriod=" + maxTradePeriod + ",\r\n maxTradePeriod=" + maxTradePeriod +
",\r\n useAutoClose=" + useAutoClose + ",\r\n useAutoClose=" + useAutoClose +
@ -460,8 +481,8 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
object.add("versionNr", context.serialize(offerPayload.getVersionNr())); object.add("versionNr", context.serialize(offerPayload.getVersionNr()));
object.add("blockHeightAtOfferCreation", context.serialize(offerPayload.getBlockHeightAtOfferCreation())); object.add("blockHeightAtOfferCreation", context.serialize(offerPayload.getBlockHeightAtOfferCreation()));
object.add("makerFee", context.serialize(offerPayload.getMakerFee())); object.add("makerFee", context.serialize(offerPayload.getMakerFee()));
object.add("buyerSecurityDeposit", context.serialize(offerPayload.getBuyerSecurityDeposit())); object.add("buyerSecurityDepositPct", context.serialize(offerPayload.getBuyerSecurityDepositPct()));
object.add("sellerSecurityDeposit", context.serialize(offerPayload.getSellerSecurityDeposit())); object.add("sellerSecurityDepositPct", context.serialize(offerPayload.getSellerSecurityDepositPct()));
object.add("maxTradeLimit", context.serialize(offerPayload.getMaxTradeLimit())); object.add("maxTradeLimit", context.serialize(offerPayload.getMaxTradeLimit()));
object.add("maxTradePeriod", context.serialize(offerPayload.getMaxTradePeriod())); object.add("maxTradePeriod", context.serialize(offerPayload.getMaxTradePeriod()));
object.add("useAutoClose", context.serialize(offerPayload.isUseAutoClose())); object.add("useAutoClose", context.serialize(offerPayload.isUseAutoClose()));

View file

@ -1167,9 +1167,17 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
return; return;
} }
// verify security deposits are equal
if (offer.getBuyerSecurityDepositPct() != offer.getSellerSecurityDepositPct()) {
errorMessage = "Buyer and seller security deposits are not equal for offer " + request.offerId;
log.info(errorMessage);
sendAckMessage(request.getClass(), peer, request.getPubKeyRing(), request.getOfferId(), request.getUid(), false, errorMessage);
return;
}
// verify maker's reserve tx (double spend, trade fee, trade amount, mining fee) // verify maker's reserve tx (double spend, trade fee, trade amount, mining fee)
BigInteger sendAmount = offer.getDirection() == OfferDirection.BUY ? BigInteger.valueOf(0) : offer.getAmount(); BigInteger sendAmount = offer.getDirection() == OfferDirection.BUY ? BigInteger.valueOf(0) : offer.getAmount();
BigInteger securityDeposit = offer.getDirection() == OfferDirection.BUY ? offer.getBuyerSecurityDeposit() : offer.getSellerSecurityDeposit(); BigInteger securityDeposit = offer.getDirection() == OfferDirection.BUY ? offer.getMaxBuyerSecurityDeposit() : offer.getMaxSellerSecurityDeposit();
Tuple2<MoneroTx, BigInteger> txResult = xmrWalletService.verifyTradeTx( Tuple2<MoneroTx, BigInteger> txResult = xmrWalletService.verifyTradeTx(
offer.getId(), offer.getId(),
tradeFee, tradeFee,
@ -1512,8 +1520,8 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
originalOfferPayload.getVersionNr(), originalOfferPayload.getVersionNr(),
originalOfferPayload.getBlockHeightAtOfferCreation(), originalOfferPayload.getBlockHeightAtOfferCreation(),
originalOfferPayload.getMakerFee(), originalOfferPayload.getMakerFee(),
originalOfferPayload.getBuyerSecurityDeposit(), originalOfferPayload.getBuyerSecurityDepositPct(),
originalOfferPayload.getSellerSecurityDeposit(), originalOfferPayload.getSellerSecurityDepositPct(),
originalOfferPayload.getMaxTradeLimit(), originalOfferPayload.getMaxTradeLimit(),
originalOfferPayload.getMaxTradePeriod(), originalOfferPayload.getMaxTradePeriod(),
originalOfferPayload.isUseAutoClose(), originalOfferPayload.isUseAutoClose(),

View file

@ -52,7 +52,7 @@ public class MakerReserveOfferFunds extends Task<PlaceOfferModel> {
// create reserve tx // create reserve tx
BigInteger makerFee = offer.getMakerFee(); BigInteger makerFee = offer.getMakerFee();
BigInteger sendAmount = offer.getDirection() == OfferDirection.BUY ? BigInteger.valueOf(0) : offer.getAmount(); BigInteger sendAmount = offer.getDirection() == OfferDirection.BUY ? BigInteger.valueOf(0) : offer.getAmount();
BigInteger securityDeposit = offer.getDirection() == OfferDirection.BUY ? offer.getBuyerSecurityDeposit() : offer.getSellerSecurityDeposit(); BigInteger securityDeposit = offer.getDirection() == OfferDirection.BUY ? offer.getMaxBuyerSecurityDeposit() : offer.getMaxSellerSecurityDeposit();
String returnAddress = model.getXmrWalletService().getOrCreateAddressEntry(offer.getId(), XmrAddressEntry.Context.TRADE_PAYOUT).getAddressString(); String returnAddress = model.getXmrWalletService().getOrCreateAddressEntry(offer.getId(), XmrAddressEntry.Context.TRADE_PAYOUT).getAddressString();
XmrAddressEntry fundingEntry = model.getXmrWalletService().getAddressEntry(offer.getId(), XmrAddressEntry.Context.OFFER_FUNDING).orElse(null); XmrAddressEntry fundingEntry = model.getXmrWalletService().getAddressEntry(offer.getId(), XmrAddressEntry.Context.OFFER_FUNDING).orElse(null);
Integer preferredSubaddressIndex = fundingEntry == null ? null : fundingEntry.getSubaddressIndex(); Integer preferredSubaddressIndex = fundingEntry == null ? null : fundingEntry.getSubaddressIndex();

View file

@ -45,10 +45,10 @@ public class ValidateOffer extends Task<PlaceOfferModel> {
checkBINotNullOrZero(offer.getAmount(), "Amount"); checkBINotNullOrZero(offer.getAmount(), "Amount");
checkBINotNullOrZero(offer.getMinAmount(), "MinAmount"); checkBINotNullOrZero(offer.getMinAmount(), "MinAmount");
checkBINotNullOrZero(offer.getMakerFee(), "MakerFee"); checkBINotNullOrZero(offer.getMakerFee(), "MakerFee");
checkBINotNullOrZero(offer.getBuyerSecurityDeposit(), "buyerSecurityDeposit");
checkBINotNullOrZero(offer.getSellerSecurityDeposit(), "sellerSecurityDeposit");
//checkCoinNotNullOrZero(offer.getTxFee(), "txFee"); // TODO: remove from data model //checkCoinNotNullOrZero(offer.getTxFee(), "txFee"); // TODO: remove from data model
checkBINotNullOrZero(offer.getMaxTradeLimit(), "MaxTradeLimit"); checkBINotNullOrZero(offer.getMaxTradeLimit(), "MaxTradeLimit");
if (offer.getBuyerSecurityDepositPct() <= 0) throw new IllegalArgumentException("Buyer security deposit must be positive but was " + offer.getBuyerSecurityDepositPct());
if (offer.getSellerSecurityDepositPct() <= 0) throw new IllegalArgumentException("Seller security deposit must be positive but was " + offer.getSellerSecurityDepositPct());
// We remove those checks to be more flexible with future changes. // We remove those checks to be more flexible with future changes.
/*checkArgument(offer.getMakerFee().value >= FeeService.getMinMakerFee(offer.isCurrencyForMakerFeeBtc()).value, /*checkArgument(offer.getMakerFee().value >= FeeService.getMinMakerFee(offer.isCurrencyForMakerFeeBtc()).value,

View file

@ -100,8 +100,8 @@ public class TakeOfferModel implements Model {
this.useSavingsWallet = useSavingsWallet; this.useSavingsWallet = useSavingsWallet;
this.amount = tradeAmount.min(BigInteger.valueOf(getMaxTradeLimit())); this.amount = tradeAmount.min(BigInteger.valueOf(getMaxTradeLimit()));
this.securityDeposit = offer.getDirection() == SELL this.securityDeposit = offer.getDirection() == SELL
? offer.getBuyerSecurityDeposit() ? offer.getOfferPayload().getBuyerSecurityDepositForTradeAmount(amount)
: offer.getSellerSecurityDeposit(); : offer.getOfferPayload().getSellerSecurityDepositForTradeAmount(amount);
this.takerFee = HavenoUtils.getTakerFee(amount); this.takerFee = HavenoUtils.getTakerFee(amount);
calculateVolume(); calculateVolume();

View file

@ -1057,7 +1057,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
// The amount we would get if we do a new trade with current price // The amount we would get if we do a new trade with current price
BigInteger potentialAmountAtDisputeOpening = priceAtDisputeOpening.getAmountByVolume(contract.getTradeVolume()); BigInteger potentialAmountAtDisputeOpening = priceAtDisputeOpening.getAmountByVolume(contract.getTradeVolume());
BigInteger buyerSecurityDeposit = BigInteger.valueOf(offerPayload.getBuyerSecurityDeposit()); BigInteger buyerSecurityDeposit = offerPayload.getMaxBuyerSecurityDeposit();
BigInteger minRefundAtMediatedDispute = Restrictions.getMinRefundAtMediatedDispute(); BigInteger minRefundAtMediatedDispute = Restrictions.getMinRefundAtMediatedDispute();
// minRefundAtMediatedDispute is always larger as buyerSecurityDeposit at mediated payout, we ignore refund agent case here as there it can be 0. // minRefundAtMediatedDispute is always larger as buyerSecurityDeposit at mediated payout, we ignore refund agent case here as there it can be 0.
BigInteger maxLossSecDeposit = buyerSecurityDeposit.subtract(minRefundAtMediatedDispute); BigInteger maxLossSecDeposit = buyerSecurityDeposit.subtract(minRefundAtMediatedDispute);

View file

@ -55,7 +55,7 @@ public abstract class BuyerTrade extends Trade {
@Override @Override
public BigInteger getPayoutAmount() { public BigInteger getPayoutAmount() {
checkNotNull(getAmount(), "Invalid state: getTradeAmount() = null"); checkNotNull(getAmount(), "Invalid state: getTradeAmount() = null");
return checkNotNull(getOffer()).getBuyerSecurityDeposit().add(getAmount()); return getAmount().add(getBuyerSecurityDepositBeforeMiningFee());
} }
@Override @Override

View file

@ -85,11 +85,13 @@ public class ClosedTradableFormatter {
} }
public String getBuyerSecurityDepositAsString(Tradable tradable) { public String getBuyerSecurityDepositAsString(Tradable tradable) {
return HavenoUtils.formatXmr(tradable.getOffer().getBuyerSecurityDeposit()); Trade trade = castToTrade(tradable);
return HavenoUtils.formatXmr(trade.getBuyerSecurityDepositBeforeMiningFee());
} }
public String getSellerSecurityDepositAsString(Tradable tradable) { public String getSellerSecurityDepositAsString(Tradable tradable) {
return HavenoUtils.formatXmr(tradable.getOffer().getSellerSecurityDeposit()); Trade trade = castToTrade(tradable);
return HavenoUtils.formatXmr(trade.getSellerSecurityDepositBeforeMiningFee());
} }
public String getTradeFeeAsString(Tradable tradable, boolean appendCode) { public String getTradeFeeAsString(Tradable tradable, boolean appendCode) {

View file

@ -122,7 +122,7 @@ public class HavenoUtils {
} }
public static BigInteger xmrToAtomicUnits(double xmr) { public static BigInteger xmrToAtomicUnits(double xmr) {
return BigDecimal.valueOf(xmr).multiply(new BigDecimal(XMR_AU_MULTIPLIER)).toBigInteger(); return BigDecimal.valueOf(xmr).multiply(new BigDecimal(XMR_AU_MULTIPLIER)).setScale(8).toBigInteger();
} }
public static long xmrToCentineros(double xmr) { public static long xmrToCentineros(double xmr) {
@ -176,6 +176,10 @@ public class HavenoUtils {
return applyDecimals(formatted, Math.max(2, decimalPlaces)) + (appendCode ? " XMR" : ""); return applyDecimals(formatted, Math.max(2, decimalPlaces)) + (appendCode ? " XMR" : "");
} }
public static String formatPercent(double percent) {
return (percent * 100) + "%";
}
private static String applyDecimals(String decimalStr, int decimalPlaces) { private static String applyDecimals(String decimalStr, int decimalPlaces) {
if (decimalStr.contains(".")) return decimalStr + getNumZeros(decimalPlaces - (decimalStr.length() - decimalStr.indexOf(".") - 1)); if (decimalStr.contains(".")) return decimalStr + getNumZeros(decimalPlaces - (decimalStr.length() - decimalStr.indexOf(".") - 1));
else return decimalStr + "." + getNumZeros(decimalPlaces); else return decimalStr + "." + getNumZeros(decimalPlaces);

View file

@ -26,8 +26,6 @@ import lombok.extern.slf4j.Slf4j;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.math.BigInteger; import java.math.BigInteger;
import static com.google.common.base.Preconditions.checkNotNull;
@Slf4j @Slf4j
public abstract class SellerTrade extends Trade { public abstract class SellerTrade extends Trade {
SellerTrade(Offer offer, SellerTrade(Offer offer,
@ -54,7 +52,7 @@ public abstract class SellerTrade extends Trade {
@Override @Override
public BigInteger getPayoutAmount() { public BigInteger getPayoutAmount() {
return checkNotNull(getOffer()).getSellerSecurityDeposit(); return getSellerSecurityDepositBeforeMiningFee();
} }
@Override @Override

View file

@ -1628,6 +1628,14 @@ public abstract class Trade implements Tradable, Model {
return BigInteger.valueOf(takerFee); return BigInteger.valueOf(takerFee);
} }
public BigInteger getBuyerSecurityDepositBeforeMiningFee() {
return offer.getOfferPayload().getBuyerSecurityDepositForTradeAmount(getAmount());
}
public BigInteger getSellerSecurityDepositBeforeMiningFee() {
return offer.getOfferPayload().getSellerSecurityDepositForTradeAmount(getAmount());
}
@Override @Override
public BigInteger getTotalTxFee() { public BigInteger getTotalTxFee() {
return BigInteger.valueOf(totalTxFee); return BigInteger.valueOf(totalTxFee);

View file

@ -17,7 +17,6 @@
package haveno.core.trade; package haveno.core.trade;
import haveno.core.offer.Offer;
import haveno.core.support.dispute.Dispute; import haveno.core.support.dispute.Dispute;
import haveno.core.xmr.wallet.BtcWalletService; import haveno.core.xmr.wallet.BtcWalletService;
import lombok.Getter; import lombok.Getter;
@ -36,6 +35,8 @@ import java.util.function.Consumer;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
// TODO: remove for XMR?
@Slf4j @Slf4j
public class TradeDataValidation { public class TradeDataValidation {
@ -127,9 +128,8 @@ public class TradeDataValidation {
// Check amount // Check amount
TransactionOutput output = delayedPayoutTx.getOutput(0); TransactionOutput output = delayedPayoutTx.getOutput(0);
Offer offer = checkNotNull(trade.getOffer()); BigInteger msOutputAmount = trade.getBuyerSecurityDepositBeforeMiningFee()
BigInteger msOutputAmount = offer.getBuyerSecurityDeposit() .add(trade.getSellerSecurityDepositBeforeMiningFee())
.add(offer.getSellerSecurityDeposit())
.add(checkNotNull(trade.getAmount())); .add(checkNotNull(trade.getAmount()));
if (!output.getValue().equals(msOutputAmount)) { if (!output.getValue().equals(msOutputAmount)) {

View file

@ -81,7 +81,7 @@ public class ArbitratorProcessDepositRequest extends TradeTask {
boolean isFromBuyer = trader == trade.getBuyer(); boolean isFromBuyer = trader == trade.getBuyer();
BigInteger tradeFee = isFromTaker ? trade.getTakerFee() : trade.getMakerFee(); BigInteger tradeFee = isFromTaker ? trade.getTakerFee() : trade.getMakerFee();
BigInteger sendAmount = isFromBuyer ? BigInteger.valueOf(0) : trade.getAmount(); BigInteger sendAmount = isFromBuyer ? BigInteger.valueOf(0) : trade.getAmount();
BigInteger securityDeposit = isFromBuyer ? offer.getBuyerSecurityDeposit() : offer.getSellerSecurityDeposit(); BigInteger securityDeposit = isFromBuyer ? trade.getBuyerSecurityDepositBeforeMiningFee() : trade.getSellerSecurityDepositBeforeMiningFee();
String depositAddress = processModel.getMultisigAddress(); String depositAddress = processModel.getMultisigAddress();
// verify deposit tx // verify deposit tx

View file

@ -48,15 +48,15 @@ public class ArbitratorProcessReserveTx extends TradeTask {
runInterceptHook(); runInterceptHook();
Offer offer = trade.getOffer(); Offer offer = trade.getOffer();
InitTradeRequest request = (InitTradeRequest) processModel.getTradeMessage(); InitTradeRequest request = (InitTradeRequest) processModel.getTradeMessage();
boolean isFromTaker = request.getSenderNodeAddress().equals(trade.getTaker().getNodeAddress()); boolean isFromMaker = request.getSenderNodeAddress().equals(trade.getMaker().getNodeAddress());
boolean isFromBuyer = isFromTaker ? offer.getDirection() == OfferDirection.SELL : offer.getDirection() == OfferDirection.BUY; boolean isFromBuyer = isFromMaker ? offer.getDirection() == OfferDirection.BUY : offer.getDirection() == OfferDirection.SELL;
// TODO (woodser): if signer online, should never be called by maker // TODO (woodser): if signer online, should never be called by maker
// process reserve tx with expected values // process reserve tx with expected values
BigInteger tradeFee = isFromTaker ? trade.getTakerFee() : trade.getMakerFee(); BigInteger tradeFee = isFromMaker ? trade.getMakerFee() : trade.getTakerFee();
BigInteger sendAmount = isFromBuyer ? BigInteger.valueOf(0) : offer.getAmount(); BigInteger sendAmount = isFromBuyer ? BigInteger.valueOf(0) : isFromMaker ? offer.getAmount() : trade.getAmount(); // maker reserve tx is for offer amount
BigInteger securityDeposit = isFromBuyer ? offer.getBuyerSecurityDeposit() : offer.getSellerSecurityDeposit(); BigInteger securityDeposit = isFromMaker ? isFromBuyer ? offer.getMaxBuyerSecurityDeposit() : offer.getMaxSellerSecurityDeposit() : isFromBuyer ? trade.getBuyerSecurityDepositBeforeMiningFee() : trade.getSellerSecurityDepositBeforeMiningFee();
Tuple2<MoneroTx, BigInteger> txResult; Tuple2<MoneroTx, BigInteger> txResult;
try { try {
txResult = trade.getXmrWalletService().verifyTradeTx( txResult = trade.getXmrWalletService().verifyTradeTx(
@ -71,11 +71,11 @@ public class ArbitratorProcessReserveTx extends TradeTask {
null); null);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
throw new RuntimeException("Error processing reserve tx from " + (isFromTaker ? "taker " : "maker ") + request.getSenderNodeAddress() + ", offerId=" + offer.getId() + ": " + e.getMessage()); throw new RuntimeException("Error processing reserve tx from " + (isFromMaker ? "maker " : "taker ") + request.getSenderNodeAddress() + ", offerId=" + offer.getId() + ": " + e.getMessage());
} }
// save reserve tx to model // save reserve tx to model
TradePeer trader = isFromTaker ? processModel.getTaker() : processModel.getMaker(); TradePeer trader = isFromMaker ? processModel.getMaker() : processModel.getTaker();
trader.setReserveTxHash(request.getReserveTxHash()); trader.setReserveTxHash(request.getReserveTxHash());
trader.setReserveTxHex(request.getReserveTxHex()); trader.setReserveTxHex(request.getReserveTxHex());
trader.setReserveTxKey(request.getReserveTxKey()); trader.setReserveTxKey(request.getReserveTxKey());

View file

@ -99,7 +99,7 @@ public class MaybeSendSignContractRequest extends TradeTask {
trade.getSelf().setPaymentAccountPayload(trade.getProcessModel().getPaymentAccountPayload(trade.getSelf().getPaymentAccountId())); trade.getSelf().setPaymentAccountPayload(trade.getProcessModel().getPaymentAccountPayload(trade.getSelf().getPaymentAccountId()));
// TODO: security deposit should be based on trade amount, not max offer amount // TODO: security deposit should be based on trade amount, not max offer amount
BigInteger securityDeposit = trade instanceof BuyerTrade ? trade.getOffer().getBuyerSecurityDeposit() : trade.getOffer().getSellerSecurityDeposit(); BigInteger securityDeposit = trade instanceof BuyerTrade ? trade.getBuyerSecurityDepositBeforeMiningFee() : trade.getSellerSecurityDepositBeforeMiningFee();
trade.getSelf().setSecurityDeposit(securityDeposit.subtract(depositTx.getFee())); trade.getSelf().setSecurityDeposit(securityDeposit.subtract(depositTx.getFee()));
// maker signs deposit hash nonce to avoid challenge protocol // maker signs deposit hash nonce to avoid challenge protocol

View file

@ -41,8 +41,8 @@ public class TakerReserveTradeFunds extends TradeTask {
// create reserve tx // create reserve tx
BigInteger takerFee = trade.getTakerFee(); BigInteger takerFee = trade.getTakerFee();
BigInteger sendAmount = trade.getOffer().getDirection() == OfferDirection.BUY ? trade.getOffer().getAmount() : BigInteger.valueOf(0); BigInteger sendAmount = trade.getOffer().getDirection() == OfferDirection.BUY ? trade.getAmount() : BigInteger.valueOf(0);
BigInteger securityDeposit = trade.getOffer().getDirection() == OfferDirection.BUY ? trade.getOffer().getSellerSecurityDeposit() : trade.getOffer().getBuyerSecurityDeposit(); BigInteger securityDeposit = trade.getOffer().getDirection() == OfferDirection.BUY ? trade.getSellerSecurityDepositBeforeMiningFee() : trade.getBuyerSecurityDepositBeforeMiningFee();
String returnAddress = model.getXmrWalletService().getOrCreateAddressEntry(trade.getOffer().getId(), XmrAddressEntry.Context.TRADE_PAYOUT).getAddressString(); String returnAddress = model.getXmrWalletService().getOrCreateAddressEntry(trade.getOffer().getId(), XmrAddressEntry.Context.TRADE_PAYOUT).getAddressString();
MoneroTxWallet reserveTx = model.getXmrWalletService().createReserveTx(takerFee, sendAmount, securityDeposit, returnAddress, false, null); MoneroTxWallet reserveTx = model.getXmrWalletService().createReserveTx(takerFee, sendAmount, securityDeposit, returnAddress, false, null);

View file

@ -13,7 +13,6 @@ import haveno.common.util.Utilities;
import haveno.core.api.AccountServiceListener; import haveno.core.api.AccountServiceListener;
import haveno.core.api.CoreAccountService; import haveno.core.api.CoreAccountService;
import haveno.core.api.CoreMoneroConnectionsService; import haveno.core.api.CoreMoneroConnectionsService;
import haveno.core.offer.Offer;
import haveno.core.trade.BuyerTrade; import haveno.core.trade.BuyerTrade;
import haveno.core.trade.HavenoUtils; import haveno.core.trade.HavenoUtils;
import haveno.core.trade.MakerTrade; import haveno.core.trade.MakerTrade;
@ -385,11 +384,10 @@ public class XmrWalletService {
} }
// create deposit tx // create deposit tx
Offer offer = trade.getProcessModel().getOffer();
String multisigAddress = trade.getProcessModel().getMultisigAddress(); String multisigAddress = trade.getProcessModel().getMultisigAddress();
BigInteger tradeFee = trade instanceof MakerTrade ? trade.getOffer().getMakerFee() : trade.getTakerFee(); BigInteger tradeFee = trade instanceof MakerTrade ? trade.getOffer().getMakerFee() : trade.getTakerFee();
BigInteger sendAmount = trade instanceof BuyerTrade ? BigInteger.valueOf(0) : trade.getAmount(); BigInteger sendAmount = trade instanceof BuyerTrade ? BigInteger.valueOf(0) : trade.getAmount();
BigInteger securityDeposit = trade instanceof BuyerTrade ? offer.getBuyerSecurityDeposit() : offer.getSellerSecurityDeposit(); // TODO: security deposit should be based on trade amount BigInteger securityDeposit = trade instanceof BuyerTrade ? trade.getBuyerSecurityDepositBeforeMiningFee() : trade.getSellerSecurityDepositBeforeMiningFee();
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
log.info("Creating deposit tx with multisig address={}", multisigAddress); log.info("Creating deposit tx with multisig address={}", multisigAddress);
MoneroTxWallet depositTx = createTradeTx(tradeFee, sendAmount, securityDeposit, multisigAddress, reserveExactAmount, preferredSubaddressIndex); MoneroTxWallet depositTx = createTradeTx(tradeFee, sendAmount, securityDeposit, multisigAddress, reserveExactAmount, preferredSubaddressIndex);
@ -445,17 +443,6 @@ public class XmrWalletService {
.setSubtractFeeFrom(1) .setSubtractFeeFrom(1)
.setPriority(XmrWalletService.PROTOCOL_FEE_PRIORITY)); // pay fee from security deposit .setPriority(XmrWalletService.PROTOCOL_FEE_PRIORITY)); // pay fee from security deposit
// check if tx uses exact input, since wallet2 can prefer to spend 2 outputs
if (reserveExactAmount) {
BigInteger exactInputAmount = tradeFee.add(sendAmount).add(securityDeposit);
BigInteger inputSum = BigInteger.valueOf(0);
for (MoneroOutputWallet txInput : tradeTx.getInputsWallet()) {
MoneroOutputWallet input = wallet.getOutputs(new MoneroOutputQuery().setKeyImage(txInput.getKeyImage())).get(0);
inputSum = inputSum.add(input.getAmount());
}
if (inputSum.compareTo(exactInputAmount) > 0) throw new RuntimeException("Cannot create transaction with exact input amount");
}
// freeze inputs // freeze inputs
for (MoneroOutput input : tradeTx.getInputs()) wallet.freezeOutput(input.getKeyImage().getHex()); for (MoneroOutput input : tradeTx.getInputs()) wallet.freezeOutput(input.getKeyImage().getHex());
saveMainWallet(); saveMainWallet();

View file

@ -291,8 +291,8 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
depositColumn.setComparator(Comparator.comparing(item -> { depositColumn.setComparator(Comparator.comparing(item -> {
boolean isSellOffer = item.getOffer().getDirection() == OfferDirection.SELL; boolean isSellOffer = item.getOffer().getDirection() == OfferDirection.SELL;
BigInteger deposit = isSellOffer ? BigInteger deposit = isSellOffer ?
item.getOffer().getBuyerSecurityDeposit() : item.getOffer().getMaxBuyerSecurityDeposit() :
item.getOffer().getSellerSecurityDeposit(); item.getOffer().getMaxSellerSecurityDeposit();
long amountValue = item.getOffer().getAmount().longValueExact(); long amountValue = item.getOffer().getAmount().longValueExact();
if ((deposit == null || amountValue == 0)) { if ((deposit == null || amountValue == 0)) {
@ -1015,8 +1015,8 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
super.updateItem(item, empty); super.updateItem(item, empty);
if (item != null && !empty) { if (item != null && !empty) {
var isSellOffer = item.getOffer().getDirection() == OfferDirection.SELL; var isSellOffer = item.getOffer().getDirection() == OfferDirection.SELL;
var deposit = isSellOffer ? item.getOffer().getBuyerSecurityDeposit() : var deposit = isSellOffer ? item.getOffer().getMaxBuyerSecurityDeposit() :
item.getOffer().getSellerSecurityDeposit(); item.getOffer().getMaxSellerSecurityDeposit();
if (deposit == null) { if (deposit == null) {
setText(Res.get("shared.na")); setText(Res.get("shared.na"));
setGraphic(null); setGraphic(null);

View file

@ -460,11 +460,11 @@ class TakeOfferDataModel extends OfferDataModel {
} }
public BigInteger getBuyerSecurityDeposit() { public BigInteger getBuyerSecurityDeposit() {
return offer.getBuyerSecurityDeposit(); return offer.getOfferPayload().getBuyerSecurityDepositForTradeAmount(amount.get());
} }
public BigInteger getSellerSecurityDeposit() { public BigInteger getSellerSecurityDeposit() {
return offer.getSellerSecurityDeposit(); return offer.getOfferPayload().getSellerSecurityDepositForTradeAmount(amount.get());
} }
public boolean isRoundedForAtmCash() { public boolean isRoundedForAtmCash() {

View file

@ -154,11 +154,11 @@ public class ContractWindow extends Overlay<ContractWindow> {
VolumeUtil.formatVolumeWithCode(contract.getTradeVolume())); VolumeUtil.formatVolumeWithCode(contract.getTradeVolume()));
String securityDeposit = Res.getWithColAndCap("shared.buyer") + String securityDeposit = Res.getWithColAndCap("shared.buyer") +
" " + " " +
HavenoUtils.formatXmr(offer.getBuyerSecurityDeposit(), true) + HavenoUtils.formatXmr(offer.getOfferPayload().getBuyerSecurityDepositForTradeAmount(contract.getTradeAmount()), true) +
" / " + " / " +
Res.getWithColAndCap("shared.seller") + Res.getWithColAndCap("shared.seller") +
" " + " " +
HavenoUtils.formatXmr(offer.getSellerSecurityDeposit(), true); HavenoUtils.formatXmr(offer.getOfferPayload().getSellerSecurityDepositForTradeAmount(contract.getTradeAmount()), true);
addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("shared.securityDeposit"), securityDeposit); addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("shared.securityDeposit"), securityDeposit);
addConfirmationLabelTextField(gridPane, addConfirmationLabelTextField(gridPane,
++rowIndex, ++rowIndex,

View file

@ -334,11 +334,11 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
DisplayUtils.formatDateTime(offer.getDate())); DisplayUtils.formatDateTime(offer.getDate()));
String value = Res.getWithColAndCap("shared.buyer") + String value = Res.getWithColAndCap("shared.buyer") +
" " + " " +
HavenoUtils.formatXmr(offer.getBuyerSecurityDeposit(), true) + HavenoUtils.formatXmr(offer.getOfferPayload().getMaxBuyerSecurityDeposit(), true) +
" / " + " / " +
Res.getWithColAndCap("shared.seller") + Res.getWithColAndCap("shared.seller") +
" " + " " +
HavenoUtils.formatXmr(offer.getSellerSecurityDeposit(), true); HavenoUtils.formatXmr(offer.getOfferPayload().getMaxSellerSecurityDeposit(), true);
addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("shared.securityDeposit"), value); addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("shared.securityDeposit"), value);
if (countryCode != null && !isF2F) if (countryCode != null && !isF2F)

View file

@ -203,11 +203,11 @@ public class TradeDetailsWindow extends Overlay<TradeDetailsWindow> {
DisplayUtils.formatDateTime(trade.getDate())); DisplayUtils.formatDateTime(trade.getDate()));
String securityDeposit = Res.getWithColAndCap("shared.buyer") + String securityDeposit = Res.getWithColAndCap("shared.buyer") +
" " + " " +
HavenoUtils.formatXmr(offer.getBuyerSecurityDeposit(), true) + HavenoUtils.formatXmr(offer.getMaxBuyerSecurityDeposit(), true) +
" / " + " / " +
Res.getWithColAndCap("shared.seller") + Res.getWithColAndCap("shared.seller") +
" " + " " +
HavenoUtils.formatXmr(offer.getSellerSecurityDeposit(), true); HavenoUtils.formatXmr(offer.getMaxSellerSecurityDeposit(), true);
addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("shared.securityDeposit"), securityDeposit); addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("shared.securityDeposit"), securityDeposit);
NodeAddress arbitratorNodeAddress = trade.getArbitratorNodeAddress(); NodeAddress arbitratorNodeAddress = trade.getArbitratorNodeAddress();

View file

@ -210,10 +210,10 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
return "BTC" + tradeFee; return "BTC" + tradeFee;
}, Comparator.nullsFirst(Comparator.naturalOrder()))); }, Comparator.nullsFirst(Comparator.naturalOrder())));
buyerSecurityDepositColumn.setComparator(nullsFirstComparing(o -> buyerSecurityDepositColumn.setComparator(nullsFirstComparing(o ->
o.getTradable().getOffer() != null ? o.getTradable().getOffer().getBuyerSecurityDeposit() : null o.getTradable().getOffer() != null ? o.getTradable().getOffer().getMaxBuyerSecurityDeposit() : null
)); ));
sellerSecurityDepositColumn.setComparator(nullsFirstComparing(o -> sellerSecurityDepositColumn.setComparator(nullsFirstComparing(o ->
o.getTradable().getOffer() != null ? o.getTradable().getOffer().getSellerSecurityDeposit() : null o.getTradable().getOffer() != null ? o.getTradable().getOffer().getMaxSellerSecurityDeposit() : null
)); ));
stateColumn.setComparator(Comparator.comparing(ClosedTradesListItem::getState)); stateColumn.setComparator(Comparator.comparing(ClosedTradesListItem::getState));

View file

@ -95,7 +95,7 @@ class DuplicateOfferDataModel extends MutableOfferDataModel {
} }
private double getBuyerSecurityAsPercent(Offer offer) { private double getBuyerSecurityAsPercent(Offer offer) {
BigInteger offerBuyerSecurityDeposit = getBoundedBuyerSecurityDeposit(offer.getBuyerSecurityDeposit()); BigInteger offerBuyerSecurityDeposit = getBoundedBuyerSecurityDeposit(offer.getMaxBuyerSecurityDeposit());
double offerBuyerSecurityDepositAsPercent = CoinUtil.getAsPercentPerBtc(offerBuyerSecurityDeposit, double offerBuyerSecurityDepositAsPercent = CoinUtil.getAsPercentPerBtc(offerBuyerSecurityDeposit,
offer.getAmount()); offer.getAmount());
return Math.min(offerBuyerSecurityDepositAsPercent, return Math.min(offerBuyerSecurityDepositAsPercent,

View file

@ -122,13 +122,15 @@ class EditOfferDataModel extends MutableOfferDataModel {
else else
paymentAccount.setSelectedTradeCurrency(selectedTradeCurrency); paymentAccount.setSelectedTradeCurrency(selectedTradeCurrency);
} }
// TODO: update for XMR to use percent as double?
// If the security deposit got bounded because it was below the coin amount limit, it can be bigger // If the security deposit got bounded because it was below the coin amount limit, it can be bigger
// by percentage than the restriction. We can't determine the percentage originally entered at offer // by percentage than the restriction. We can't determine the percentage originally entered at offer
// creation, so just use the default value as it doesn't matter anyway. // creation, so just use the default value as it doesn't matter anyway.
double buyerSecurityDepositPercent = CoinUtil.getAsPercentPerBtc(offer.getBuyerSecurityDeposit(), offer.getAmount()); double buyerSecurityDepositPercent = CoinUtil.getAsPercentPerBtc(offer.getMaxBuyerSecurityDeposit(), offer.getAmount());
if (buyerSecurityDepositPercent > Restrictions.getMaxBuyerSecurityDepositAsPercent() if (buyerSecurityDepositPercent > Restrictions.getMaxBuyerSecurityDepositAsPercent()
&& offer.getBuyerSecurityDeposit().equals(Restrictions.getMinBuyerSecurityDeposit())) && offer.getMaxBuyerSecurityDeposit().equals(Restrictions.getMinBuyerSecurityDeposit()))
buyerSecurityDepositPct.set(Restrictions.getDefaultBuyerSecurityDepositAsPercent()); buyerSecurityDepositPct.set(Restrictions.getDefaultBuyerSecurityDepositAsPercent());
else else
buyerSecurityDepositPct.set(buyerSecurityDepositPercent); buyerSecurityDepositPct.set(buyerSecurityDepositPercent);
@ -199,8 +201,8 @@ class EditOfferDataModel extends MutableOfferDataModel {
offerPayload.getVersionNr(), offerPayload.getVersionNr(),
offerPayload.getBlockHeightAtOfferCreation(), offerPayload.getBlockHeightAtOfferCreation(),
offerPayload.getMakerFee(), offerPayload.getMakerFee(),
offerPayload.getBuyerSecurityDeposit(), offerPayload.getBuyerSecurityDepositPct(),
offerPayload.getSellerSecurityDeposit(), offerPayload.getSellerSecurityDepositPct(),
offerPayload.getMaxTradeLimit(), offerPayload.getMaxTradeLimit(),
offerPayload.getMaxTradePeriod(), offerPayload.getMaxTradePeriod(),
offerPayload.isUseAutoClose(), offerPayload.isUseAutoClose(),

View file

@ -304,8 +304,8 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
Trade trade = dataModel.getTrade(); Trade trade = dataModel.getTrade();
if (offer != null && trade != null && trade.getAmount() != null) { if (offer != null && trade != null && trade.getAmount() != null) {
BigInteger securityDeposit = dataModel.isBuyer() ? BigInteger securityDeposit = dataModel.isBuyer() ?
offer.getBuyerSecurityDeposit() offer.getMaxBuyerSecurityDeposit()
: offer.getSellerSecurityDeposit(); : offer.getMaxSellerSecurityDeposit();
BigInteger minSecurityDeposit = dataModel.isBuyer() ? BigInteger minSecurityDeposit = dataModel.isBuyer() ?
Restrictions.getMinBuyerSecurityDeposit() : Restrictions.getMinBuyerSecurityDeposit() :

View file

@ -85,7 +85,6 @@ import javafx.scene.text.Text;
import javafx.util.Callback; import javafx.util.Callback;
import javafx.util.Duration; import javafx.util.Duration;
import lombok.Getter; import lombok.Getter;
import org.bitcoinj.core.Coin;
import org.fxmisc.easybind.EasyBind; import org.fxmisc.easybind.EasyBind;
import org.fxmisc.easybind.Subscription; import org.fxmisc.easybind.Subscription;
@ -691,8 +690,8 @@ public abstract class DisputeView extends ActivatableView<VBox, Void> {
String paymentMethod = Res.get(contract.getPaymentMethodId()); String paymentMethod = Res.get(contract.getPaymentMethodId());
String currency = CurrencyUtil.getNameAndCode(contract.getOfferPayload().getCurrencyCode()); String currency = CurrencyUtil.getNameAndCode(contract.getOfferPayload().getCurrencyCode());
String tradeAmount = HavenoUtils.formatXmr(contract.getTradeAmount(), true); String tradeAmount = HavenoUtils.formatXmr(contract.getTradeAmount(), true);
String buyerDeposit = Coin.valueOf(contract.getOfferPayload().getBuyerSecurityDeposit()).toFriendlyString(); String buyerDeposit = HavenoUtils.formatXmr(contract.getOfferPayload().getBuyerSecurityDepositForTradeAmount(contract.getTradeAmount()), true);
String sellerDeposit = Coin.valueOf(contract.getOfferPayload().getSellerSecurityDeposit()).toFriendlyString(); String sellerDeposit = HavenoUtils.formatXmr(contract.getOfferPayload().getSellerSecurityDepositForTradeAmount(contract.getTradeAmount()), true);
stringBuilder.append("Payment method: ") stringBuilder.append("Payment method: ")
.append(paymentMethod) .append(paymentMethod)
.append("\n") .append("\n")
@ -702,7 +701,7 @@ public abstract class DisputeView extends ActivatableView<VBox, Void> {
.append("Trade amount: ") .append("Trade amount: ")
.append(tradeAmount) .append(tradeAmount)
.append("\n") .append("\n")
.append("Buyer/seller security deposit: ") .append("Buyer/seller security deposit %: ")
.append(buyerDeposit) .append(buyerDeposit)
.append("/") .append("/")
.append(sellerDeposit) .append(sellerDeposit)

View file

@ -523,16 +523,16 @@ message OfferInfo {
uint64 min_amount = 7 [jstype = JS_STRING]; uint64 min_amount = 7 [jstype = JS_STRING];
string volume = 8; string volume = 8;
string min_volume = 9; string min_volume = 9;
uint64 buyer_security_deposit = 10 [jstype = JS_STRING]; double buyer_security_deposit_pct = 10;
string trigger_price = 11; double seller_security_deposit_pct = 11;
string payment_account_id = 12; string trigger_price = 12;
string payment_method_id = 13; string payment_account_id = 13;
string payment_method_short_name = 14; string payment_method_id = 14;
string base_currency_code = 15; string payment_method_short_name = 15;
string counter_currency_code = 16; string base_currency_code = 16;
uint64 date = 17; string counter_currency_code = 17;
string state = 18; uint64 date = 18;
uint64 seller_security_deposit = 19 [jstype = JS_STRING]; string state = 19;
uint64 maker_fee = 20 [jstype = JS_STRING]; uint64 maker_fee = 20 [jstype = JS_STRING];
bool is_activated = 21; bool is_activated = 21;
bool is_my_offer = 22; bool is_my_offer = 22;

View file

@ -623,8 +623,8 @@ message OfferPayload {
string version_nr = 19; string version_nr = 19;
int64 block_height_at_offer_creation = 20; int64 block_height_at_offer_creation = 20;
int64 maker_fee = 21; int64 maker_fee = 21;
int64 buyer_security_deposit = 22; double buyer_security_deposit_pct = 22;
int64 seller_security_deposit = 23; double seller_security_deposit_pct = 23;
int64 max_trade_limit = 24; int64 max_trade_limit = 24;
int64 max_trade_period = 25; int64 max_trade_period = 25;
bool use_auto_close = 26; bool use_auto_close = 26;