mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-08-09 15:12:26 -04:00
set minimum trade amount to 0.05 XMR (#1857)
This commit is contained in:
parent
3680e1d4ee
commit
fd2c0f335f
12 changed files with 75 additions and 67 deletions
|
@ -404,7 +404,7 @@ public class OfferBookService {
|
|||
}
|
||||
|
||||
// validate max offers with same key images
|
||||
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());
|
||||
if (numOffersWithSharedKeyImages > Restrictions.getMaxOffersWithSharedFunds()) throw new RuntimeException("More than " + Restrictions.getMaxOffersWithSharedFunds() + " offers exist with same same key images as new offerId=" + offerPayload.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,8 +61,8 @@ import haveno.core.trade.statistics.ReferralIdService;
|
|||
import haveno.core.user.AutoConfirmSettings;
|
||||
import haveno.core.user.Preferences;
|
||||
import haveno.core.util.coin.CoinFormatter;
|
||||
import static haveno.core.xmr.wallet.Restrictions.getMaxSecurityDepositAsPercent;
|
||||
import static haveno.core.xmr.wallet.Restrictions.getMinSecurityDepositAsPercent;
|
||||
import static haveno.core.xmr.wallet.Restrictions.getMaxSecurityDepositPct;
|
||||
import static haveno.core.xmr.wallet.Restrictions.getMinSecurityDepositPct;
|
||||
import haveno.network.p2p.P2PService;
|
||||
import java.math.BigInteger;
|
||||
import java.util.HashMap;
|
||||
|
@ -240,12 +240,12 @@ public class OfferUtil {
|
|||
PaymentAccount paymentAccount,
|
||||
String currencyCode) {
|
||||
checkNotNull(p2PService.getAddress(), "Address must not be null");
|
||||
checkArgument(securityDeposit <= getMaxSecurityDepositAsPercent(),
|
||||
checkArgument(securityDeposit <= getMaxSecurityDepositPct(),
|
||||
"securityDeposit must not exceed " +
|
||||
getMaxSecurityDepositAsPercent());
|
||||
checkArgument(securityDeposit >= getMinSecurityDepositAsPercent(),
|
||||
getMaxSecurityDepositPct());
|
||||
checkArgument(securityDeposit >= getMinSecurityDepositPct(),
|
||||
"securityDeposit must not be less than " +
|
||||
getMinSecurityDepositAsPercent() + " but was " + securityDeposit);
|
||||
getMinSecurityDepositPct() + " but was " + securityDeposit);
|
||||
checkArgument(!filterManager.isCurrencyBanned(currencyCode),
|
||||
Res.get("offerbook.warning.currencyBanned"));
|
||||
checkArgument(!filterManager.isPaymentMethodBanned(paymentAccount.getPaymentMethod()),
|
||||
|
|
|
@ -540,8 +540,8 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||
|
||||
// check clone limit
|
||||
int numClones = getOpenOfferGroup(sourceOffer.getGroupId()).size();
|
||||
if (numClones >= Restrictions.MAX_OFFERS_WITH_SHARED_FUNDS) {
|
||||
errorMessageHandler.handleErrorMessage("Cannot create offer because maximum number of " + Restrictions.MAX_OFFERS_WITH_SHARED_FUNDS + " cloned offers with shared funds reached.");
|
||||
if (numClones >= Restrictions.getMaxOffersWithSharedFunds()) {
|
||||
errorMessageHandler.handleErrorMessage("Cannot create offer because maximum number of " + Restrictions.getMaxOffersWithSharedFunds() + " cloned offers with shared funds reached.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1565,8 +1565,8 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||
}
|
||||
|
||||
// verify max length of extra info
|
||||
if (offer.getOfferPayload().getExtraInfo() != null && offer.getOfferPayload().getExtraInfo().length() > Restrictions.MAX_EXTRA_INFO_LENGTH) {
|
||||
errorMessage = "Extra info is too long for offer " + request.offerId + ". Max length is " + Restrictions.MAX_EXTRA_INFO_LENGTH + " but got " + offer.getOfferPayload().getExtraInfo().length();
|
||||
if (offer.getOfferPayload().getExtraInfo() != null && offer.getOfferPayload().getExtraInfo().length() > Restrictions.getMaxExtraInfoLength()) {
|
||||
errorMessage = "Extra info is too long for offer " + request.offerId + ". Max length is " + Restrictions.getMaxExtraInfoLength() + " but got " + offer.getOfferPayload().getExtraInfo().length();
|
||||
log.warn(errorMessage);
|
||||
sendAckMessage(request.getClass(), peer, request.getPubKeyRing(), request.getOfferId(), request.getUid(), false, errorMessage);
|
||||
return;
|
||||
|
@ -1611,8 +1611,8 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||
}
|
||||
|
||||
// verify maker security deposit
|
||||
if (offer.getSellerSecurityDepositPct() != Restrictions.MIN_SECURITY_DEPOSIT_PCT) {
|
||||
errorMessage = "Wrong seller security deposit for offer " + request.offerId + ". Expected " + Restrictions.MIN_SECURITY_DEPOSIT_PCT + " but got " + offer.getSellerSecurityDepositPct();
|
||||
if (offer.getSellerSecurityDepositPct() != Restrictions.getMinSecurityDepositPct()) {
|
||||
errorMessage = "Wrong seller security deposit for offer " + request.offerId + ". Expected " + Restrictions.getMinSecurityDepositPct() + " but got " + offer.getSellerSecurityDepositPct();
|
||||
log.warn(errorMessage);
|
||||
sendAckMessage(request.getClass(), peer, request.getPubKeyRing(), request.getOfferId(), request.getUid(), false, errorMessage);
|
||||
return;
|
||||
|
@ -1652,16 +1652,16 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||
}
|
||||
|
||||
// verify seller's security deposit
|
||||
if (offer.getSellerSecurityDepositPct() < Restrictions.MIN_SECURITY_DEPOSIT_PCT) {
|
||||
errorMessage = "Insufficient seller security deposit for offer " + request.offerId + ". Expected at least " + Restrictions.MIN_SECURITY_DEPOSIT_PCT + " but got " + offer.getSellerSecurityDepositPct();
|
||||
if (offer.getSellerSecurityDepositPct() < Restrictions.getMinSecurityDepositPct()) {
|
||||
errorMessage = "Insufficient seller security deposit for offer " + request.offerId + ". Expected at least " + Restrictions.getMinSecurityDepositPct() + " but got " + offer.getSellerSecurityDepositPct();
|
||||
log.warn(errorMessage);
|
||||
sendAckMessage(request.getClass(), peer, request.getPubKeyRing(), request.getOfferId(), request.getUid(), false, errorMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
// verify buyer's security deposit
|
||||
if (offer.getBuyerSecurityDepositPct() < Restrictions.MIN_SECURITY_DEPOSIT_PCT) {
|
||||
errorMessage = "Insufficient buyer security deposit for offer " + request.offerId + ". Expected at least " + Restrictions.MIN_SECURITY_DEPOSIT_PCT + " but got " + offer.getBuyerSecurityDepositPct();
|
||||
if (offer.getBuyerSecurityDepositPct() < Restrictions.getMinSecurityDepositPct()) {
|
||||
errorMessage = "Insufficient buyer security deposit for offer " + request.offerId + ". Expected at least " + Restrictions.getMinSecurityDepositPct() + " but got " + offer.getBuyerSecurityDepositPct();
|
||||
log.warn(errorMessage);
|
||||
sendAckMessage(request.getClass(), peer, request.getPubKeyRing(), request.getOfferId(), request.getUid(), false, errorMessage);
|
||||
return;
|
||||
|
|
|
@ -59,7 +59,7 @@ public class SecurityDepositValidator extends NumberValidator {
|
|||
private ValidationResult validateIfNotTooLowPercentageValue(String input) {
|
||||
try {
|
||||
double percentage = ParsingUtils.parsePercentStringToDouble(input);
|
||||
double minPercentage = Restrictions.getMinSecurityDepositAsPercent();
|
||||
double minPercentage = Restrictions.getMinSecurityDepositPct();
|
||||
if (percentage < minPercentage)
|
||||
return new ValidationResult(false,
|
||||
Res.get("validation.inputTooSmall", FormattingUtils.formatToPercentWithSymbol(minPercentage)));
|
||||
|
@ -73,7 +73,7 @@ public class SecurityDepositValidator extends NumberValidator {
|
|||
private ValidationResult validateIfNotTooHighPercentageValue(String input) {
|
||||
try {
|
||||
double percentage = ParsingUtils.parsePercentStringToDouble(input);
|
||||
double maxPercentage = Restrictions.getMaxSecurityDepositAsPercent();
|
||||
double maxPercentage = Restrictions.getMaxSecurityDepositPct();
|
||||
if (percentage > maxPercentage)
|
||||
return new ValidationResult(false,
|
||||
Res.get("validation.inputTooLarge", FormattingUtils.formatToPercentWithSymbol(maxPercentage)));
|
||||
|
|
|
@ -623,8 +623,8 @@ public final class Preferences implements PersistedDataHost, BridgeAddressProvid
|
|||
}
|
||||
|
||||
public void setSecurityDepositAsPercent(double securityDepositAsPercent, PaymentAccount paymentAccount) {
|
||||
double max = Restrictions.getMaxSecurityDepositAsPercent();
|
||||
double min = Restrictions.getMinSecurityDepositAsPercent();
|
||||
double max = Restrictions.getMaxSecurityDepositPct();
|
||||
double min = Restrictions.getMinSecurityDepositPct();
|
||||
|
||||
if (PaymentAccountUtil.isCryptoCurrencyAccount(paymentAccount))
|
||||
prefPayload.setSecurityDepositAsPercentForCrypto(Math.min(max, Math.max(min, securityDepositAsPercent)));
|
||||
|
@ -853,12 +853,12 @@ public final class Preferences implements PersistedDataHost, BridgeAddressProvid
|
|||
double value = PaymentAccountUtil.isCryptoCurrencyAccount(paymentAccount) ?
|
||||
prefPayload.getSecurityDepositAsPercentForCrypto() : prefPayload.getSecurityDepositAsPercent();
|
||||
|
||||
if (value < Restrictions.getMinSecurityDepositAsPercent()) {
|
||||
value = Restrictions.getMinSecurityDepositAsPercent();
|
||||
if (value < Restrictions.getMinSecurityDepositPct()) {
|
||||
value = Restrictions.getMinSecurityDepositPct();
|
||||
setSecurityDepositAsPercent(value, paymentAccount);
|
||||
}
|
||||
|
||||
return value == 0 ? Restrictions.getDefaultSecurityDepositAsPercent() : value;
|
||||
return value == 0 ? Restrictions.getDefaultSecurityDepositPct() : value;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -41,7 +41,7 @@ import java.util.Map;
|
|||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static haveno.core.xmr.wallet.Restrictions.getDefaultSecurityDepositAsPercent;
|
||||
import static haveno.core.xmr.wallet.Restrictions.getDefaultSecurityDepositPct;
|
||||
|
||||
@Slf4j
|
||||
@Data
|
||||
|
@ -120,10 +120,10 @@ public final class PreferencesPayload implements PersistableEnvelope {
|
|||
private String rpcPw;
|
||||
@Nullable
|
||||
private String takeOfferSelectedPaymentAccountId;
|
||||
private double securityDepositAsPercent = getDefaultSecurityDepositAsPercent();
|
||||
private double securityDepositAsPercent = getDefaultSecurityDepositPct();
|
||||
private int ignoreDustThreshold = 600;
|
||||
private int clearDataAfterDays = Preferences.CLEAR_DATA_AFTER_DAYS_DEFAULT;
|
||||
private double securityDepositAsPercentForCrypto = getDefaultSecurityDepositAsPercent();
|
||||
private double securityDepositAsPercentForCrypto = getDefaultSecurityDepositPct();
|
||||
private int blockNotifyPort;
|
||||
private boolean tacAcceptedV120;
|
||||
private double bsqAverageTrimThreshold = 0.05;
|
||||
|
|
|
@ -26,12 +26,12 @@ import java.math.BigInteger;
|
|||
public class Restrictions {
|
||||
|
||||
// configure restrictions
|
||||
public static final double MIN_SECURITY_DEPOSIT_PCT = 0.15;
|
||||
public static final double MAX_SECURITY_DEPOSIT_PCT = 0.5;
|
||||
public static BigInteger MIN_TRADE_AMOUNT = HavenoUtils.xmrToAtomicUnits(0.1);
|
||||
public static BigInteger MIN_SECURITY_DEPOSIT = HavenoUtils.xmrToAtomicUnits(0.1);
|
||||
public static int MAX_EXTRA_INFO_LENGTH = 1500;
|
||||
public static int MAX_OFFERS_WITH_SHARED_FUNDS = 10;
|
||||
private static final double MIN_SECURITY_DEPOSIT_PCT = 0.15;
|
||||
private static final double MAX_SECURITY_DEPOSIT_PCT = 0.5;
|
||||
private static final BigInteger MIN_TRADE_AMOUNT = HavenoUtils.xmrToAtomicUnits(0.05);
|
||||
private static final BigInteger MIN_SECURITY_DEPOSIT = HavenoUtils.xmrToAtomicUnits(0.1);
|
||||
private static final int MAX_EXTRA_INFO_LENGTH = 1500;
|
||||
private static final int MAX_OFFERS_WITH_SHARED_FUNDS = 10;
|
||||
|
||||
// At mediation we require a min. payout to the losing party to keep incentive for the trader to accept the
|
||||
// mediated payout. For Refund agent cases we do not have that restriction.
|
||||
|
@ -57,15 +57,15 @@ public class Restrictions {
|
|||
return MIN_TRADE_AMOUNT;
|
||||
}
|
||||
|
||||
public static double getDefaultSecurityDepositAsPercent() {
|
||||
public static double getDefaultSecurityDepositPct() {
|
||||
return MIN_SECURITY_DEPOSIT_PCT;
|
||||
}
|
||||
|
||||
public static double getMinSecurityDepositAsPercent() {
|
||||
public static double getMinSecurityDepositPct() {
|
||||
return MIN_SECURITY_DEPOSIT_PCT;
|
||||
}
|
||||
|
||||
public static double getMaxSecurityDepositAsPercent() {
|
||||
public static double getMaxSecurityDepositPct() {
|
||||
return MAX_SECURITY_DEPOSIT_PCT;
|
||||
}
|
||||
|
||||
|
@ -73,6 +73,14 @@ public class Restrictions {
|
|||
return MIN_SECURITY_DEPOSIT;
|
||||
}
|
||||
|
||||
public static int getMaxExtraInfoLength() {
|
||||
return MAX_EXTRA_INFO_LENGTH;
|
||||
}
|
||||
|
||||
public static int getMaxOffersWithSharedFunds() {
|
||||
return MAX_OFFERS_WITH_SHARED_FUNDS;
|
||||
}
|
||||
|
||||
// This value must be lower than MIN_BUYER_SECURITY_DEPOSIT and SELLER_SECURITY_DEPOSIT
|
||||
public static BigInteger getMinRefundAtMediatedDispute() {
|
||||
if (MIN_REFUND_AT_MEDIATED_DISPUTE == null)
|
||||
|
|
|
@ -76,11 +76,11 @@ public class CoinUtilTest {
|
|||
BigInteger result = CoinUtil.getAdjustedAmount(
|
||||
HavenoUtils.xmrToAtomicUnits(0.1),
|
||||
Price.valueOf("USD", 1000_0000),
|
||||
HavenoUtils.xmrToAtomicUnits(0.1),
|
||||
Restrictions.getMinTradeAmount(),
|
||||
HavenoUtils.xmrToAtomicUnits(0.2),
|
||||
1);
|
||||
assertEquals(
|
||||
HavenoUtils.formatXmr(Restrictions.MIN_TRADE_AMOUNT, true),
|
||||
HavenoUtils.formatXmr(Restrictions.getMinTradeAmount(), true),
|
||||
HavenoUtils.formatXmr(result, true),
|
||||
"Minimum trade amount allowed should be adjusted to the smallest trade allowed."
|
||||
);
|
||||
|
@ -95,7 +95,7 @@ public class CoinUtilTest {
|
|||
fail("Expected IllegalArgumentException to be thrown when amount is too low.");
|
||||
} catch (IllegalArgumentException iae) {
|
||||
assertEquals(
|
||||
"amount must be above minimum of 0.1 xmr but was 0.0 xmr",
|
||||
"amount must be above minimum of 0.05 xmr but was 0.0 xmr",
|
||||
iae.getMessage(),
|
||||
"Unexpected exception message."
|
||||
);
|
||||
|
@ -104,11 +104,11 @@ public class CoinUtilTest {
|
|||
result = CoinUtil.getAdjustedAmount(
|
||||
HavenoUtils.xmrToAtomicUnits(0.1),
|
||||
Price.valueOf("USD", 1000_0000),
|
||||
HavenoUtils.xmrToAtomicUnits(0.1),
|
||||
Restrictions.getMinTradeAmount(),
|
||||
HavenoUtils.xmrToAtomicUnits(0.2),
|
||||
1);
|
||||
assertEquals(
|
||||
"0.10 XMR",
|
||||
"0.05 XMR",
|
||||
HavenoUtils.formatXmr(result, true),
|
||||
"Minimum allowed trade amount should not be adjusted."
|
||||
);
|
||||
|
@ -116,11 +116,11 @@ public class CoinUtilTest {
|
|||
result = CoinUtil.getAdjustedAmount(
|
||||
HavenoUtils.xmrToAtomicUnits(0.1),
|
||||
Price.valueOf("USD", 1000_0000),
|
||||
HavenoUtils.xmrToAtomicUnits(0.1),
|
||||
Restrictions.getMinTradeAmount(),
|
||||
HavenoUtils.xmrToAtomicUnits(0.25),
|
||||
1);
|
||||
assertEquals(
|
||||
"0.10 XMR",
|
||||
"0.05 XMR",
|
||||
HavenoUtils.formatXmr(result, true),
|
||||
"Minimum trade amount allowed should respect maxTradeLimit and factor, if possible."
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue