set minimum trade amount to 0.05 XMR (#1857)

This commit is contained in:
woodser 2025-07-21 09:57:54 -04:00 committed by GitHub
parent 3680e1d4ee
commit fd2c0f335f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 75 additions and 67 deletions

View file

@ -43,7 +43,7 @@ import java.util.stream.Collectors;
import static haveno.apitest.config.ApiTestConfig.BTC;
import static haveno.apitest.config.ApiTestRateMeterInterceptorConfig.getTestRateMeterInterceptorConfig;
import static haveno.cli.table.builder.TableType.BTC_BALANCE_TBL;
import static haveno.core.xmr.wallet.Restrictions.getDefaultSecurityDepositAsPercent;
import static haveno.core.xmr.wallet.Restrictions.getDefaultSecurityDepositPct;
import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Arrays.stream;
@ -158,7 +158,7 @@ public class MethodTest extends ApiTestCase {
}
public static final Supplier<Double> defaultSecurityDepositPct = () -> {
var defaultPct = BigDecimal.valueOf(getDefaultSecurityDepositAsPercent());
var defaultPct = BigDecimal.valueOf(getDefaultSecurityDepositPct());
if (defaultPct.precision() != 2)
throw new IllegalStateException(format(
"Unexpected decimal precision, expected 2 but actual is %d%n."

View file

@ -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());
}
}

View file

@ -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()),

View file

@ -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;

View file

@ -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)));

View file

@ -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

View file

@ -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;

View file

@ -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)

View file

@ -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."
);

View file

@ -168,7 +168,7 @@ public abstract class MutableOfferDataModel extends OfferDataModel {
reserveExactAmount = preferences.getSplitOfferOutput();
useMarketBasedPrice.set(preferences.isUsePercentageBasedPrice());
securityDepositPct.set(Restrictions.getMinSecurityDepositAsPercent());
securityDepositPct.set(Restrictions.getMinSecurityDepositPct());
paymentAccountsChangeListener = change -> fillPaymentAccounts();
}
@ -338,7 +338,7 @@ public abstract class MutableOfferDataModel extends OfferDataModel {
}
private void setSuggestedSecurityDeposit(PaymentAccount paymentAccount) {
var minSecurityDeposit = Restrictions.getMinSecurityDepositAsPercent();
var minSecurityDeposit = Restrictions.getMinSecurityDepositPct();
try {
if (getTradeCurrency() == null) {
setSecurityDepositPct(minSecurityDeposit);
@ -369,7 +369,7 @@ public abstract class MutableOfferDataModel extends OfferDataModel {
}
// Suggested deposit is double the trade range over the previous lock time period, bounded by min/max deposit
var suggestedSecurityDeposit =
Math.min(2 * (max - min) / max, Restrictions.getMaxSecurityDepositAsPercent());
Math.min(2 * (max - min) / max, Restrictions.getMaxSecurityDepositPct());
securityDepositPct.set(Math.max(suggestedSecurityDeposit, minSecurityDeposit));
} catch (Throwable t) {
log.error(t.toString());
@ -472,14 +472,14 @@ public abstract class MutableOfferDataModel extends OfferDataModel {
return marketPriceMarginPct;
}
BigInteger getMaxTradeLimit() {
return offerUtil.getMaxTradeLimitForRelease(paymentAccount, tradeCurrencyCode.get(), direction, buyerAsTakerWithoutDeposit.get());
}
BigInteger getMinTradeLimit() {
return Restrictions.getMinTradeAmount();
}
BigInteger getMaxTradeLimit() {
return offerUtil.getMaxTradeLimitForRelease(paymentAccount, tradeCurrencyCode.get(), direction, buyerAsTakerWithoutDeposit.get());
}
///////////////////////////////////////////////////////////////////////////////////////////
// Utils
///////////////////////////////////////////////////////////////////////////////////////////
@ -537,10 +537,10 @@ public abstract class MutableOfferDataModel extends OfferDataModel {
// if the volume != amount * price, we need to adjust the amount
if (amount.get() == null || !volumeBefore.equals(price.get().getVolumeByAmount(amount.get()))) {
BigInteger value = price.get().getAmountByVolume(volumeBefore);
BigInteger minAmount = getMinTradeLimit();
BigInteger maxAmount = getMaxTradeLimit();
BigInteger minAmount = Restrictions.getMinTradeAmount();
value = value.min(maxAmount); // adjust if above maximum
value = value.max(minAmount); // adjust if below minimum
value = value.min(maxAmount); // adjust if above maximum
value = CoinUtil.getRoundedAmount(value, price.get(), minAmount, maxAmount, tradeCurrencyCode.get(), paymentAccount.getPaymentMethod().getId());
amount.set(value);
}
@ -689,7 +689,7 @@ public abstract class MutableOfferDataModel extends OfferDataModel {
double offerSellerSecurityDepositAsPercent = CoinUtil.getAsPercentPerXmr(offerSellerSecurityDeposit,
offer.getAmount());
return Math.min(offerSellerSecurityDepositAsPercent,
Restrictions.getMaxSecurityDepositAsPercent());
Restrictions.getMaxSecurityDepositPct());
}
ReadOnlyObjectProperty<BigInteger> totalToPayAsProperty() {

View file

@ -483,6 +483,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
buyerAsTakerWithoutDepositListener = (ov, oldValue, newValue) -> {
if (dataModel.paymentAccount != null) xmrValidator.setMaxValue(dataModel.paymentAccount.getPaymentMethod().getMaxTradeLimit(dataModel.getTradeCurrencyCode().get()));
xmrValidator.setMaxTradeLimit(dataModel.getMaxTradeLimit());
xmrValidator.setMinValue(dataModel.getMinTradeLimit());
if (amount.get() != null) amountValidationResult.set(isXmrInputValid(amount.get()));
updateSecurityDeposit();
setSecurityDepositToModel();
@ -601,7 +602,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
if (dataModel.paymentAccount != null)
xmrValidator.setMaxValue(dataModel.paymentAccount.getPaymentMethod().getMaxTradeLimit(dataModel.getTradeCurrencyCode().get()));
xmrValidator.setMaxTradeLimit(dataModel.getMaxTradeLimit());
xmrValidator.setMinValue(Restrictions.getMinTradeAmount());
xmrValidator.setMinValue(dataModel.getMinTradeLimit());
final boolean isBuy = dataModel.getDirection() == OfferDirection.BUY;
@ -741,7 +742,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
if (minAmount.get() != null)
minAmountValidationResult.set(isXmrInputValid(minAmount.get()));
} else if (amount.get() != null && xmrValidator.getMaxTradeLimit() != null && xmrValidator.getMaxTradeLimit().longValueExact() == OfferRestrictions.TOLERATED_SMALL_TRADE_AMOUNT.longValueExact()) {
if (ParsingUtils.parseNumberStringToDouble(amount.get()) < HavenoUtils.atomicUnitsToXmr(Restrictions.getMinTradeAmount())) {
if (ParsingUtils.parseNumberStringToDouble(amount.get()) < HavenoUtils.atomicUnitsToXmr(dataModel.getMinTradeLimit())) {
amountValidationResult.set(result);
} else {
amount.set(HavenoUtils.formatXmr(xmrValidator.getMaxTradeLimit()));
@ -980,7 +981,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
InputValidator.ValidationResult result = securityDepositValidator.validate(securityDeposit.get());
securityDepositValidationResult.set(result);
if (result.isValid) {
double defaultSecurityDeposit = Restrictions.getDefaultSecurityDepositAsPercent();
double defaultSecurityDeposit = Restrictions.getDefaultSecurityDepositPct();
String key = "buyerSecurityDepositIsLowerAsDefault";
double depositAsDouble = ParsingUtils.parsePercentStringToDouble(securityDeposit.get());
if (preferences.showAgain(key) && depositAsDouble < defaultSecurityDeposit) {
@ -1167,10 +1168,9 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
if (amount.get() != null && !amount.get().isEmpty()) {
BigInteger amount = HavenoUtils.coinToAtomicUnits(DisplayUtils.parseToCoinWith4Decimals(this.amount.get(), xmrFormatter));
BigInteger maxTradeLimit = dataModel.getMaxTradeLimit();
Price price = dataModel.getPrice().get();
if (price != null && price.isPositive()) {
amount = CoinUtil.getRoundedAmount(amount, price, dataModel.getMinAmount().get(), maxTradeLimit, tradeCurrencyCode.get(), dataModel.getPaymentAccount().getPaymentMethod().getId());
amount = CoinUtil.getRoundedAmount(amount, price, dataModel.getMinTradeLimit(), dataModel.getMaxTradeLimit(), tradeCurrencyCode.get(), dataModel.getPaymentAccount().getPaymentMethod().getId());
}
dataModel.setAmount(amount);
if (syncMinAmountWithAmount ||
@ -1227,7 +1227,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
if (securityDeposit.get() != null && !securityDeposit.get().isEmpty() && !isMinSecurityDeposit.get()) {
dataModel.setSecurityDepositPct(ParsingUtils.parsePercentStringToDouble(securityDeposit.get()));
} else {
dataModel.setSecurityDepositPct(Restrictions.getDefaultSecurityDepositAsPercent());
dataModel.setSecurityDepositPct(Restrictions.getDefaultSecurityDepositPct());
}
}
@ -1243,7 +1243,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
// If the security deposit in the model is not valid percent
String value = FormattingUtils.formatToPercent(dataModel.getSecurityDepositPct().get());
if (!securityDepositValidator.validate(value).isValid) {
dataModel.setSecurityDepositPct(Restrictions.getDefaultSecurityDepositAsPercent());
dataModel.setSecurityDepositPct(Restrictions.getDefaultSecurityDepositPct());
}
}
@ -1299,7 +1299,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
} else {
boolean hasBuyerAsTakerWithoutDeposit = dataModel.buyerAsTakerWithoutDeposit.get() && dataModel.isSellOffer();
securityDeposit.set(FormattingUtils.formatToPercent(hasBuyerAsTakerWithoutDeposit ?
Restrictions.getDefaultSecurityDepositAsPercent() : // use default percent if no deposit from buyer
Restrictions.getDefaultSecurityDepositPct() : // use default percent if no deposit from buyer
dataModel.getSecurityDepositPct().get()));
}
}
@ -1333,8 +1333,8 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
}
private ValidationResult getExtraInfoValidationResult() {
if (extraInfo.get() != null && !extraInfo.get().isEmpty() && extraInfo.get().length() > Restrictions.MAX_EXTRA_INFO_LENGTH) {
return new InputValidator.ValidationResult(false, Res.get("createOffer.extraInfo.invalid.tooLong", Restrictions.MAX_EXTRA_INFO_LENGTH));
if (extraInfo.get() != null && !extraInfo.get().isEmpty() && extraInfo.get().length() > Restrictions.getMaxExtraInfoLength()) {
return new InputValidator.ValidationResult(false, Res.get("createOffer.extraInfo.invalid.tooLong", Restrictions.getMaxExtraInfoLength()));
} else {
return new InputValidator.ValidationResult(true);
}

View file

@ -130,9 +130,9 @@ class EditOfferDataModel extends MutableOfferDataModel {
// 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.
double securityDepositPercent = CoinUtil.getAsPercentPerXmr(offer.getMaxSellerSecurityDeposit(), offer.getAmount());
if (securityDepositPercent > Restrictions.getMaxSecurityDepositAsPercent()
if (securityDepositPercent > Restrictions.getMaxSecurityDepositPct()
&& offer.getMaxSellerSecurityDeposit().equals(Restrictions.getMinSecurityDeposit()))
securityDepositPct.set(Restrictions.getDefaultSecurityDepositAsPercent());
securityDepositPct.set(Restrictions.getDefaultSecurityDepositPct());
else
securityDepositPct.set(securityDepositPercent);