Skip to content

Commit fd2c0f3

Browse files
authored
set minimum trade amount to 0.05 XMR (#1857)
1 parent 3680e1d commit fd2c0f3

File tree

12 files changed

+75
-67
lines changed

12 files changed

+75
-67
lines changed

apitest/src/test/java/haveno/apitest/method/MethodTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
import static haveno.apitest.config.ApiTestConfig.BTC;
4444
import static haveno.apitest.config.ApiTestRateMeterInterceptorConfig.getTestRateMeterInterceptorConfig;
4545
import static haveno.cli.table.builder.TableType.BTC_BALANCE_TBL;
46-
import static haveno.core.xmr.wallet.Restrictions.getDefaultSecurityDepositAsPercent;
46+
import static haveno.core.xmr.wallet.Restrictions.getDefaultSecurityDepositPct;
4747
import static java.lang.String.format;
4848
import static java.nio.charset.StandardCharsets.UTF_8;
4949
import static java.util.Arrays.stream;
@@ -158,7 +158,7 @@ protected final haveno.core.payment.PaymentAccount createPaymentAccount(GrpcClie
158158
}
159159

160160
public static final Supplier<Double> defaultSecurityDepositPct = () -> {
161-
var defaultPct = BigDecimal.valueOf(getDefaultSecurityDepositAsPercent());
161+
var defaultPct = BigDecimal.valueOf(getDefaultSecurityDepositPct());
162162
if (defaultPct.precision() != 2)
163163
throw new IllegalStateException(format(
164164
"Unexpected decimal precision, expected 2 but actual is %d%n."

core/src/main/java/haveno/core/offer/OfferBookService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ private void validateOfferPayload(OfferPayload offerPayload) {
404404
}
405405

406406
// validate max offers with same key images
407-
if (numOffersWithSharedKeyImages > Restrictions.MAX_OFFERS_WITH_SHARED_FUNDS) throw new RuntimeException("More than " + Restrictions.MAX_OFFERS_WITH_SHARED_FUNDS + " offers exist with same same key images as new offerId=" + offerPayload.getId());
407+
if (numOffersWithSharedKeyImages > Restrictions.getMaxOffersWithSharedFunds()) throw new RuntimeException("More than " + Restrictions.getMaxOffersWithSharedFunds() + " offers exist with same same key images as new offerId=" + offerPayload.getId());
408408
}
409409
}
410410

core/src/main/java/haveno/core/offer/OfferUtil.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@
6161
import haveno.core.user.AutoConfirmSettings;
6262
import haveno.core.user.Preferences;
6363
import haveno.core.util.coin.CoinFormatter;
64-
import static haveno.core.xmr.wallet.Restrictions.getMaxSecurityDepositAsPercent;
65-
import static haveno.core.xmr.wallet.Restrictions.getMinSecurityDepositAsPercent;
64+
import static haveno.core.xmr.wallet.Restrictions.getMaxSecurityDepositPct;
65+
import static haveno.core.xmr.wallet.Restrictions.getMinSecurityDepositPct;
6666
import haveno.network.p2p.P2PService;
6767
import java.math.BigInteger;
6868
import java.util.HashMap;
@@ -240,12 +240,12 @@ public void validateOfferData(double securityDeposit,
240240
PaymentAccount paymentAccount,
241241
String currencyCode) {
242242
checkNotNull(p2PService.getAddress(), "Address must not be null");
243-
checkArgument(securityDeposit <= getMaxSecurityDepositAsPercent(),
243+
checkArgument(securityDeposit <= getMaxSecurityDepositPct(),
244244
"securityDeposit must not exceed " +
245-
getMaxSecurityDepositAsPercent());
246-
checkArgument(securityDeposit >= getMinSecurityDepositAsPercent(),
245+
getMaxSecurityDepositPct());
246+
checkArgument(securityDeposit >= getMinSecurityDepositPct(),
247247
"securityDeposit must not be less than " +
248-
getMinSecurityDepositAsPercent() + " but was " + securityDeposit);
248+
getMinSecurityDepositPct() + " but was " + securityDeposit);
249249
checkArgument(!filterManager.isCurrencyBanned(currencyCode),
250250
Res.get("offerbook.warning.currencyBanned"));
251251
checkArgument(!filterManager.isPaymentMethodBanned(paymentAccount.getPaymentMethod()),

core/src/main/java/haveno/core/offer/OpenOfferManager.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -540,8 +540,8 @@ public void placeOffer(Offer offer,
540540

541541
// check clone limit
542542
int numClones = getOpenOfferGroup(sourceOffer.getGroupId()).size();
543-
if (numClones >= Restrictions.MAX_OFFERS_WITH_SHARED_FUNDS) {
544-
errorMessageHandler.handleErrorMessage("Cannot create offer because maximum number of " + Restrictions.MAX_OFFERS_WITH_SHARED_FUNDS + " cloned offers with shared funds reached.");
543+
if (numClones >= Restrictions.getMaxOffersWithSharedFunds()) {
544+
errorMessageHandler.handleErrorMessage("Cannot create offer because maximum number of " + Restrictions.getMaxOffersWithSharedFunds() + " cloned offers with shared funds reached.");
545545
return;
546546
}
547547
}
@@ -1565,8 +1565,8 @@ private void handleSignOfferRequest(SignOfferRequest request, NodeAddress peer)
15651565
}
15661566

15671567
// verify max length of extra info
1568-
if (offer.getOfferPayload().getExtraInfo() != null && offer.getOfferPayload().getExtraInfo().length() > Restrictions.MAX_EXTRA_INFO_LENGTH) {
1569-
errorMessage = "Extra info is too long for offer " + request.offerId + ". Max length is " + Restrictions.MAX_EXTRA_INFO_LENGTH + " but got " + offer.getOfferPayload().getExtraInfo().length();
1568+
if (offer.getOfferPayload().getExtraInfo() != null && offer.getOfferPayload().getExtraInfo().length() > Restrictions.getMaxExtraInfoLength()) {
1569+
errorMessage = "Extra info is too long for offer " + request.offerId + ". Max length is " + Restrictions.getMaxExtraInfoLength() + " but got " + offer.getOfferPayload().getExtraInfo().length();
15701570
log.warn(errorMessage);
15711571
sendAckMessage(request.getClass(), peer, request.getPubKeyRing(), request.getOfferId(), request.getUid(), false, errorMessage);
15721572
return;
@@ -1611,8 +1611,8 @@ private void handleSignOfferRequest(SignOfferRequest request, NodeAddress peer)
16111611
}
16121612

16131613
// verify maker security deposit
1614-
if (offer.getSellerSecurityDepositPct() != Restrictions.MIN_SECURITY_DEPOSIT_PCT) {
1615-
errorMessage = "Wrong seller security deposit for offer " + request.offerId + ". Expected " + Restrictions.MIN_SECURITY_DEPOSIT_PCT + " but got " + offer.getSellerSecurityDepositPct();
1614+
if (offer.getSellerSecurityDepositPct() != Restrictions.getMinSecurityDepositPct()) {
1615+
errorMessage = "Wrong seller security deposit for offer " + request.offerId + ". Expected " + Restrictions.getMinSecurityDepositPct() + " but got " + offer.getSellerSecurityDepositPct();
16161616
log.warn(errorMessage);
16171617
sendAckMessage(request.getClass(), peer, request.getPubKeyRing(), request.getOfferId(), request.getUid(), false, errorMessage);
16181618
return;
@@ -1652,16 +1652,16 @@ private void handleSignOfferRequest(SignOfferRequest request, NodeAddress peer)
16521652
}
16531653

16541654
// verify seller's security deposit
1655-
if (offer.getSellerSecurityDepositPct() < Restrictions.MIN_SECURITY_DEPOSIT_PCT) {
1656-
errorMessage = "Insufficient seller security deposit for offer " + request.offerId + ". Expected at least " + Restrictions.MIN_SECURITY_DEPOSIT_PCT + " but got " + offer.getSellerSecurityDepositPct();
1655+
if (offer.getSellerSecurityDepositPct() < Restrictions.getMinSecurityDepositPct()) {
1656+
errorMessage = "Insufficient seller security deposit for offer " + request.offerId + ". Expected at least " + Restrictions.getMinSecurityDepositPct() + " but got " + offer.getSellerSecurityDepositPct();
16571657
log.warn(errorMessage);
16581658
sendAckMessage(request.getClass(), peer, request.getPubKeyRing(), request.getOfferId(), request.getUid(), false, errorMessage);
16591659
return;
16601660
}
16611661

16621662
// verify buyer's security deposit
1663-
if (offer.getBuyerSecurityDepositPct() < Restrictions.MIN_SECURITY_DEPOSIT_PCT) {
1664-
errorMessage = "Insufficient buyer security deposit for offer " + request.offerId + ". Expected at least " + Restrictions.MIN_SECURITY_DEPOSIT_PCT + " but got " + offer.getBuyerSecurityDepositPct();
1663+
if (offer.getBuyerSecurityDepositPct() < Restrictions.getMinSecurityDepositPct()) {
1664+
errorMessage = "Insufficient buyer security deposit for offer " + request.offerId + ". Expected at least " + Restrictions.getMinSecurityDepositPct() + " but got " + offer.getBuyerSecurityDepositPct();
16651665
log.warn(errorMessage);
16661666
sendAckMessage(request.getClass(), peer, request.getPubKeyRing(), request.getOfferId(), request.getUid(), false, errorMessage);
16671667
return;

core/src/main/java/haveno/core/payment/validation/SecurityDepositValidator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public ValidationResult validate(String input) {
5959
private ValidationResult validateIfNotTooLowPercentageValue(String input) {
6060
try {
6161
double percentage = ParsingUtils.parsePercentStringToDouble(input);
62-
double minPercentage = Restrictions.getMinSecurityDepositAsPercent();
62+
double minPercentage = Restrictions.getMinSecurityDepositPct();
6363
if (percentage < minPercentage)
6464
return new ValidationResult(false,
6565
Res.get("validation.inputTooSmall", FormattingUtils.formatToPercentWithSymbol(minPercentage)));
@@ -73,7 +73,7 @@ private ValidationResult validateIfNotTooLowPercentageValue(String input) {
7373
private ValidationResult validateIfNotTooHighPercentageValue(String input) {
7474
try {
7575
double percentage = ParsingUtils.parsePercentStringToDouble(input);
76-
double maxPercentage = Restrictions.getMaxSecurityDepositAsPercent();
76+
double maxPercentage = Restrictions.getMaxSecurityDepositPct();
7777
if (percentage > maxPercentage)
7878
return new ValidationResult(false,
7979
Res.get("validation.inputTooLarge", FormattingUtils.formatToPercentWithSymbol(maxPercentage)));

core/src/main/java/haveno/core/user/Preferences.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -623,8 +623,8 @@ public void setWithdrawalTxFeeInVbytes(long withdrawalTxFeeInVbytes) {
623623
}
624624

625625
public void setSecurityDepositAsPercent(double securityDepositAsPercent, PaymentAccount paymentAccount) {
626-
double max = Restrictions.getMaxSecurityDepositAsPercent();
627-
double min = Restrictions.getMinSecurityDepositAsPercent();
626+
double max = Restrictions.getMaxSecurityDepositPct();
627+
double min = Restrictions.getMinSecurityDepositPct();
628628

629629
if (PaymentAccountUtil.isCryptoCurrencyAccount(paymentAccount))
630630
prefPayload.setSecurityDepositAsPercentForCrypto(Math.min(max, Math.max(min, securityDepositAsPercent)));
@@ -853,12 +853,12 @@ public double getSecurityDepositAsPercent(PaymentAccount paymentAccount) {
853853
double value = PaymentAccountUtil.isCryptoCurrencyAccount(paymentAccount) ?
854854
prefPayload.getSecurityDepositAsPercentForCrypto() : prefPayload.getSecurityDepositAsPercent();
855855

856-
if (value < Restrictions.getMinSecurityDepositAsPercent()) {
857-
value = Restrictions.getMinSecurityDepositAsPercent();
856+
if (value < Restrictions.getMinSecurityDepositPct()) {
857+
value = Restrictions.getMinSecurityDepositPct();
858858
setSecurityDepositAsPercent(value, paymentAccount);
859859
}
860860

861-
return value == 0 ? Restrictions.getDefaultSecurityDepositAsPercent() : value;
861+
return value == 0 ? Restrictions.getDefaultSecurityDepositPct() : value;
862862
}
863863

864864
@Override

core/src/main/java/haveno/core/user/PreferencesPayload.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
import java.util.Optional;
4242
import java.util.stream.Collectors;
4343

44-
import static haveno.core.xmr.wallet.Restrictions.getDefaultSecurityDepositAsPercent;
44+
import static haveno.core.xmr.wallet.Restrictions.getDefaultSecurityDepositPct;
4545

4646
@Slf4j
4747
@Data
@@ -120,10 +120,10 @@ public final class PreferencesPayload implements PersistableEnvelope {
120120
private String rpcPw;
121121
@Nullable
122122
private String takeOfferSelectedPaymentAccountId;
123-
private double securityDepositAsPercent = getDefaultSecurityDepositAsPercent();
123+
private double securityDepositAsPercent = getDefaultSecurityDepositPct();
124124
private int ignoreDustThreshold = 600;
125125
private int clearDataAfterDays = Preferences.CLEAR_DATA_AFTER_DAYS_DEFAULT;
126-
private double securityDepositAsPercentForCrypto = getDefaultSecurityDepositAsPercent();
126+
private double securityDepositAsPercentForCrypto = getDefaultSecurityDepositPct();
127127
private int blockNotifyPort;
128128
private boolean tacAcceptedV120;
129129
private double bsqAverageTrimThreshold = 0.05;

core/src/main/java/haveno/core/xmr/wallet/Restrictions.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@
2626
public class Restrictions {
2727

2828
// configure restrictions
29-
public static final double MIN_SECURITY_DEPOSIT_PCT = 0.15;
30-
public static final double MAX_SECURITY_DEPOSIT_PCT = 0.5;
31-
public static BigInteger MIN_TRADE_AMOUNT = HavenoUtils.xmrToAtomicUnits(0.1);
32-
public static BigInteger MIN_SECURITY_DEPOSIT = HavenoUtils.xmrToAtomicUnits(0.1);
33-
public static int MAX_EXTRA_INFO_LENGTH = 1500;
34-
public static int MAX_OFFERS_WITH_SHARED_FUNDS = 10;
29+
private static final double MIN_SECURITY_DEPOSIT_PCT = 0.15;
30+
private static final double MAX_SECURITY_DEPOSIT_PCT = 0.5;
31+
private static final BigInteger MIN_TRADE_AMOUNT = HavenoUtils.xmrToAtomicUnits(0.05);
32+
private static final BigInteger MIN_SECURITY_DEPOSIT = HavenoUtils.xmrToAtomicUnits(0.1);
33+
private static final int MAX_EXTRA_INFO_LENGTH = 1500;
34+
private static final int MAX_OFFERS_WITH_SHARED_FUNDS = 10;
3535

3636
// At mediation we require a min. payout to the losing party to keep incentive for the trader to accept the
3737
// mediated payout. For Refund agent cases we do not have that restriction.
@@ -57,22 +57,30 @@ public static BigInteger getMinTradeAmount() {
5757
return MIN_TRADE_AMOUNT;
5858
}
5959

60-
public static double getDefaultSecurityDepositAsPercent() {
60+
public static double getDefaultSecurityDepositPct() {
6161
return MIN_SECURITY_DEPOSIT_PCT;
6262
}
6363

64-
public static double getMinSecurityDepositAsPercent() {
64+
public static double getMinSecurityDepositPct() {
6565
return MIN_SECURITY_DEPOSIT_PCT;
6666
}
6767

68-
public static double getMaxSecurityDepositAsPercent() {
68+
public static double getMaxSecurityDepositPct() {
6969
return MAX_SECURITY_DEPOSIT_PCT;
7070
}
7171

7272
public static BigInteger getMinSecurityDeposit() {
7373
return MIN_SECURITY_DEPOSIT;
7474
}
7575

76+
public static int getMaxExtraInfoLength() {
77+
return MAX_EXTRA_INFO_LENGTH;
78+
}
79+
80+
public static int getMaxOffersWithSharedFunds() {
81+
return MAX_OFFERS_WITH_SHARED_FUNDS;
82+
}
83+
7684
// This value must be lower than MIN_BUYER_SECURITY_DEPOSIT and SELLER_SECURITY_DEPOSIT
7785
public static BigInteger getMinRefundAtMediatedDispute() {
7886
if (MIN_REFUND_AT_MEDIATED_DISPUTE == null)

core/src/test/java/haveno/core/util/coin/CoinUtilTest.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,11 @@ public void testGetAdjustedAmount() {
7676
BigInteger result = CoinUtil.getAdjustedAmount(
7777
HavenoUtils.xmrToAtomicUnits(0.1),
7878
Price.valueOf("USD", 1000_0000),
79-
HavenoUtils.xmrToAtomicUnits(0.1),
79+
Restrictions.getMinTradeAmount(),
8080
HavenoUtils.xmrToAtomicUnits(0.2),
8181
1);
8282
assertEquals(
83-
HavenoUtils.formatXmr(Restrictions.MIN_TRADE_AMOUNT, true),
83+
HavenoUtils.formatXmr(Restrictions.getMinTradeAmount(), true),
8484
HavenoUtils.formatXmr(result, true),
8585
"Minimum trade amount allowed should be adjusted to the smallest trade allowed."
8686
);
@@ -95,7 +95,7 @@ public void testGetAdjustedAmount() {
9595
fail("Expected IllegalArgumentException to be thrown when amount is too low.");
9696
} catch (IllegalArgumentException iae) {
9797
assertEquals(
98-
"amount must be above minimum of 0.1 xmr but was 0.0 xmr",
98+
"amount must be above minimum of 0.05 xmr but was 0.0 xmr",
9999
iae.getMessage(),
100100
"Unexpected exception message."
101101
);
@@ -104,23 +104,23 @@ public void testGetAdjustedAmount() {
104104
result = CoinUtil.getAdjustedAmount(
105105
HavenoUtils.xmrToAtomicUnits(0.1),
106106
Price.valueOf("USD", 1000_0000),
107-
HavenoUtils.xmrToAtomicUnits(0.1),
107+
Restrictions.getMinTradeAmount(),
108108
HavenoUtils.xmrToAtomicUnits(0.2),
109109
1);
110110
assertEquals(
111-
"0.10 XMR",
111+
"0.05 XMR",
112112
HavenoUtils.formatXmr(result, true),
113113
"Minimum allowed trade amount should not be adjusted."
114114
);
115115

116116
result = CoinUtil.getAdjustedAmount(
117117
HavenoUtils.xmrToAtomicUnits(0.1),
118118
Price.valueOf("USD", 1000_0000),
119-
HavenoUtils.xmrToAtomicUnits(0.1),
119+
Restrictions.getMinTradeAmount(),
120120
HavenoUtils.xmrToAtomicUnits(0.25),
121121
1);
122122
assertEquals(
123-
"0.10 XMR",
123+
"0.05 XMR",
124124
HavenoUtils.formatXmr(result, true),
125125
"Minimum trade amount allowed should respect maxTradeLimit and factor, if possible."
126126
);

0 commit comments

Comments
 (0)