mirror of
https://github.com/haveno-dex/haveno.git
synced 2024-11-17 00:07:49 +00:00
automatically adjust offer and trade amount for grpc fixed-price offers
This commit is contained in:
parent
4017fa108a
commit
849a1c9c55
3 changed files with 39 additions and 11 deletions
|
@ -20,7 +20,10 @@ package haveno.core.api;
|
|||
import haveno.common.handlers.ErrorMessageHandler;
|
||||
import haveno.common.handlers.ResultHandler;
|
||||
import haveno.core.offer.Offer;
|
||||
import haveno.core.offer.OfferDirection;
|
||||
import haveno.core.offer.OfferUtil;
|
||||
import haveno.core.offer.takeoffer.TakeOfferModel;
|
||||
import haveno.core.payment.payload.PaymentMethod;
|
||||
import haveno.core.support.messages.ChatMessage;
|
||||
import haveno.core.support.traderchat.TradeChatSession;
|
||||
import haveno.core.support.traderchat.TraderChatManager;
|
||||
|
@ -32,6 +35,7 @@ import haveno.core.trade.TradeUtil;
|
|||
import haveno.core.trade.protocol.BuyerProtocol;
|
||||
import haveno.core.trade.protocol.SellerProtocol;
|
||||
import haveno.core.user.User;
|
||||
import haveno.core.util.coin.CoinUtil;
|
||||
import haveno.core.util.validation.BtcAddressValidator;
|
||||
import haveno.core.xmr.model.AddressEntry;
|
||||
import haveno.core.xmr.wallet.BtcWalletService;
|
||||
|
@ -64,6 +68,7 @@ class CoreTradesService {
|
|||
private final TradeManager tradeManager;
|
||||
private final TraderChatManager traderChatManager;
|
||||
private final TradeUtil tradeUtil;
|
||||
private final OfferUtil offerUtil;
|
||||
private final User user;
|
||||
|
||||
@Inject
|
||||
|
@ -75,6 +80,7 @@ class CoreTradesService {
|
|||
TradeManager tradeManager,
|
||||
TraderChatManager traderChatManager,
|
||||
TradeUtil tradeUtil,
|
||||
OfferUtil offerUtil,
|
||||
User user) {
|
||||
this.coreContext = coreContext;
|
||||
this.coreWalletsService = coreWalletsService;
|
||||
|
@ -84,6 +90,7 @@ class CoreTradesService {
|
|||
this.tradeManager = tradeManager;
|
||||
this.traderChatManager = traderChatManager;
|
||||
this.tradeUtil = tradeUtil;
|
||||
this.offerUtil = offerUtil;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
|
@ -105,6 +112,21 @@ class CoreTradesService {
|
|||
// default to offer amount
|
||||
BigInteger amount = amountAsLong == 0 ? offer.getAmount() : BigInteger.valueOf(amountAsLong);
|
||||
|
||||
// adjust amount for fixed-price offer (based on TakeOfferViewModel)
|
||||
String currencyCode = offer.getCurrencyCode();
|
||||
OfferDirection direction = offer.getOfferPayload().getDirection();
|
||||
long maxTradeLimit = offerUtil.getMaxTradeLimit(paymentAccount, currencyCode, direction);
|
||||
if (offer.getPrice() != null) {
|
||||
if (PaymentMethod.isRoundedForAtmCash(paymentAccount.getPaymentMethod().getId())) {
|
||||
amount = CoinUtil.getRoundedAtmCashAmount(amount, offer.getPrice(), maxTradeLimit);
|
||||
} else if (offer.isTraditionalOffer()
|
||||
&& !amount.equals(offer.getMinAmount()) && !amount.equals(amount)) {
|
||||
// We only apply the rounding if the amount is variable (minAmount is lower as amount).
|
||||
// Otherwise we could get an amount lower then the minAmount set by rounding
|
||||
amount = CoinUtil.getRoundedAmount(amount, offer.getPrice(), maxTradeLimit, offer.getCurrencyCode(), offer.getPaymentMethodId());
|
||||
}
|
||||
}
|
||||
|
||||
// synchronize access to take offer model // TODO (woodser): to avoid synchronizing, don't use stateful model
|
||||
BigInteger takerFee;
|
||||
BigInteger fundsNeededForTrade;
|
||||
|
|
|
@ -100,7 +100,7 @@ public class CreateOfferService {
|
|||
String currencyCode,
|
||||
BigInteger amount,
|
||||
BigInteger minAmount,
|
||||
Price price,
|
||||
Price fixedPrice,
|
||||
boolean useMarketBasedPrice,
|
||||
double marketPriceMargin,
|
||||
double buyerSecurityDepositAsDouble,
|
||||
|
@ -109,7 +109,7 @@ public class CreateOfferService {
|
|||
log.info("create and get offer with offerId={}, " +
|
||||
"currencyCode={}, " +
|
||||
"direction={}, " +
|
||||
"price={}, " +
|
||||
"fixedPrice={}, " +
|
||||
"useMarketBasedPrice={}, " +
|
||||
"marketPriceMargin={}, " +
|
||||
"amount={}, " +
|
||||
|
@ -118,7 +118,7 @@ public class CreateOfferService {
|
|||
offerId,
|
||||
currencyCode,
|
||||
direction,
|
||||
price == null ? null : price.getValue(),
|
||||
fixedPrice == null ? null : fixedPrice.getValue(),
|
||||
useMarketBasedPrice,
|
||||
marketPriceMargin,
|
||||
amount,
|
||||
|
@ -126,24 +126,31 @@ public class CreateOfferService {
|
|||
buyerSecurityDepositAsDouble);
|
||||
|
||||
// verify fixed price xor market price with margin
|
||||
if (price != null) {
|
||||
if (fixedPrice != null) {
|
||||
if (useMarketBasedPrice) throw new IllegalArgumentException("Can create offer with fixed price or floating market price but not both");
|
||||
if (marketPriceMargin != 0) throw new IllegalArgumentException("Cannot set market price margin with fixed price");
|
||||
}
|
||||
|
||||
long creationTime = new Date().getTime();
|
||||
NodeAddress makerAddress = p2PService.getAddress();
|
||||
boolean useMarketBasedPriceValue = price == null &&
|
||||
boolean useMarketBasedPriceValue = fixedPrice == null &&
|
||||
useMarketBasedPrice &&
|
||||
isMarketPriceAvailable(currencyCode) &&
|
||||
!PaymentMethod.isFixedPriceOnly(paymentAccount.getPaymentMethod().getId());
|
||||
|
||||
// verify price
|
||||
if (price == null && !useMarketBasedPriceValue) {
|
||||
throw new IllegalArgumentException("Must provide fixed price because market price is unavailable");
|
||||
if (fixedPrice == null && !useMarketBasedPriceValue) {
|
||||
throw new IllegalArgumentException("Must provide fixed price");
|
||||
}
|
||||
|
||||
long priceAsLong = price != null ? price.getValue() : 0L;
|
||||
// adjust amount and min amount for fixed-price offer
|
||||
long maxTradeLimit = offerUtil.getMaxTradeLimit(paymentAccount, currencyCode, direction);
|
||||
if (fixedPrice != null) {
|
||||
amount = CoinUtil.getRoundedAmount(amount, fixedPrice, maxTradeLimit, currencyCode, paymentAccount.getPaymentMethod().getId());
|
||||
minAmount = CoinUtil.getRoundedAmount(minAmount, fixedPrice, maxTradeLimit, currencyCode, paymentAccount.getPaymentMethod().getId());
|
||||
}
|
||||
|
||||
long priceAsLong = fixedPrice != null ? fixedPrice.getValue() : 0L;
|
||||
double marketPriceMarginParam = useMarketBasedPriceValue ? marketPriceMargin : 0;
|
||||
long amountAsLong = amount != null ? amount.longValueExact() : 0L;
|
||||
long minAmountAsLong = minAmount != null ? minAmount.longValueExact() : 0L;
|
||||
|
@ -158,7 +165,6 @@ public class CreateOfferService {
|
|||
BigInteger makerFee = HavenoUtils.getMakerFee(amount);
|
||||
BigInteger buyerSecurityDeposit = getBuyerSecurityDeposit(amount, buyerSecurityDepositAsDouble);
|
||||
BigInteger sellerSecurityDeposit = getSellerSecurityDeposit(amount, sellerSecurityDepositAsDouble);
|
||||
long maxTradeLimit = offerUtil.getMaxTradeLimit(paymentAccount, currencyCode, direction);
|
||||
long maxTradePeriod = paymentAccount.getMaxTradePeriod();
|
||||
|
||||
// reserved for future use cases
|
||||
|
|
|
@ -302,10 +302,10 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
|||
Price tradePrice = dataModel.tradePrice;
|
||||
long maxTradeLimit = dataModel.getMaxTradeLimit();
|
||||
if (PaymentMethod.isRoundedForAtmCash(dataModel.getPaymentMethod().getId())) {
|
||||
BigInteger adjustedAmountForHalCash = CoinUtil.getRoundedAtmCashAmount(dataModel.getAmount().get(),
|
||||
BigInteger adjustedAmountForAtm = CoinUtil.getRoundedAtmCashAmount(dataModel.getAmount().get(),
|
||||
tradePrice,
|
||||
maxTradeLimit);
|
||||
dataModel.applyAmount(adjustedAmountForHalCash);
|
||||
dataModel.applyAmount(adjustedAmountForAtm);
|
||||
amount.set(HavenoUtils.formatXmr(dataModel.getAmount().get()));
|
||||
} else if (dataModel.getOffer().isTraditionalOffer()) {
|
||||
if (!isAmountEqualMinAmount(dataModel.getAmount().get()) && (!isAmountEqualMaxAmount(dataModel.getAmount().get()))) {
|
||||
|
|
Loading…
Reference in a new issue