Skip to content

Commit

Permalink
Improve BisqEasy amount validation
Browse files Browse the repository at this point in the history
* Before, When offer had min/max amounts, those were used to find
  the min/max base amounts. This is wrong. Now, the quote amount
  decided in the contract is used in order to calculate the base amount.

* Remove quote validation. This doesn't apply for this protocol.
  • Loading branch information
mrblue313 committed Nov 9, 2023
1 parent c2ca123 commit 5e05592
Showing 1 changed file with 17 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
import bisq.contract.ContractSignatureData;
import bisq.contract.bisq_easy.BisqEasyContract;
import bisq.offer.Offer;
import bisq.offer.amount.OfferAmountUtil;
import bisq.offer.bisq_easy.BisqEasyOffer;
import bisq.offer.price.PriceUtil;
import bisq.trade.ServiceProvider;
import bisq.trade.bisq_easy.BisqEasyTrade;
import bisq.trade.protocol.events.TradeMessageHandler;
Expand Down Expand Up @@ -103,8 +103,7 @@ protected void verifyMessage(BisqEasyTakeOfferRequest message) {

checkArgument(message.getSender().equals(takersContract.getTaker().getNetworkId()));

validateAmount(takersOffer, takersContract, true);
validateAmount(takersOffer, takersContract, false);
validateAmount(takersOffer, takersContract);

checkArgument(takersOffer.getBaseSidePaymentMethodSpecs().contains(takersContract.getBaseSidePaymentMethodSpec()));
checkArgument(takersOffer.getQuoteSidePaymentMethodSpecs().contains(takersContract.getQuoteSidePaymentMethodSpec()));
Expand All @@ -118,42 +117,25 @@ private void commitToModel(ContractSignatureData takersContractSignatureData, Co
trade.getMaker().getContractSignatureData().set(makersContractSignatureData);
}

private void validateAmount(BisqEasyOffer takersOffer, BisqEasyContract takersContract, boolean isBase) {
double tolerancePercentage = 0.01;

Optional<Monetary> minAmount = getMinAmount(takersOffer, takersContract, isBase);
Optional<Monetary> maxAmount = getMaxAmount(takersOffer, takersContract, isBase);

checkArgument(minAmount.isPresent() && maxAmount.isPresent(), "No market price available for validation.");
private void validateAmount(BisqEasyOffer takersOffer, BisqEasyContract takersContract) {
Optional<Monetary> amount = getAmount(takersOffer, takersContract);
checkArgument(amount.isPresent(), "No market price available for validation.");

long toleranceAmountForMin = (long) (minAmount.get().getValue() * tolerancePercentage);
long toleranceAmountForMax = (long) (maxAmount.get().getValue() * tolerancePercentage);
long minAmountWithTolerance = minAmount.get().getValue() - toleranceAmountForMin;
long maxAmountWithTolerance = maxAmount.get().getValue() + toleranceAmountForMax;
double tolerancePercentage = 0.01;
long tolerance = (long) (amount.get().getValue() * tolerancePercentage);
long minAmountWithTolerance = amount.get().getValue() - tolerance;
long maxAmountWithTolerance = amount.get().getValue() + tolerance;

long amount = isBase ? takersContract.getBaseSideAmount() : takersContract.getQuoteSideAmount();
long takersAmount = takersContract.getBaseSideAmount();
String errorMsg = "Market price deviation is too big.";
checkArgument(amount >= minAmountWithTolerance, errorMsg);
checkArgument(amount <= maxAmountWithTolerance, errorMsg);
}

private Optional<Monetary> getMinAmount(BisqEasyOffer takersOffer, BisqEasyContract takersContract, boolean isBase) {
return isBase
? OfferAmountUtil.findBaseSideMinOrFixedAmount(
serviceProvider.getBondedRolesService().getMarketPriceService(),
takersOffer.getAmountSpec(), takersContract.getAgreedPriceSpec(), takersOffer.getMarket())
: OfferAmountUtil.findQuoteSideMinOrFixedAmount(
serviceProvider.getBondedRolesService().getMarketPriceService(),
takersOffer.getAmountSpec(), takersContract.getAgreedPriceSpec(), takersOffer.getMarket());
checkArgument(takersAmount >= minAmountWithTolerance, errorMsg);
checkArgument(takersAmount <= maxAmountWithTolerance, errorMsg);
}

private Optional<Monetary> getMaxAmount(BisqEasyOffer takersOffer, BisqEasyContract takersContract, boolean isBase) {
return isBase
? OfferAmountUtil.findBaseSideMaxOrFixedAmount(
serviceProvider.getBondedRolesService().getMarketPriceService(),
takersOffer.getAmountSpec(), takersContract.getAgreedPriceSpec(), takersOffer.getMarket())
: OfferAmountUtil.findQuoteSideMaxOrFixedAmount(
serviceProvider.getBondedRolesService().getMarketPriceService(),
takersOffer.getAmountSpec(), takersContract.getAgreedPriceSpec(), takersOffer.getMarket());
private Optional<Monetary> getAmount(BisqEasyOffer takersOffer, BisqEasyContract takersContract) {
return PriceUtil.findQuote(serviceProvider.getBondedRolesService().getMarketPriceService(),
takersContract.getAgreedPriceSpec(), takersOffer.getMarket())
.map(quote -> quote.toBaseSideMonetary(Monetary.from(takersContract.getQuoteSideAmount(),
takersOffer.getMarket().getQuoteCurrencyCode())));
}
}

0 comments on commit 5e05592

Please sign in to comment.