mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-08-05 21:24:19 -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
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue