From cb55693d4ed85ca682874184dbd1e6072ab292a8 Mon Sep 17 00:00:00 2001 From: sqrrm Date: Thu, 29 Aug 2019 16:54:48 +0200 Subject: [PATCH 1/2] Set active currencies as high chargeback risk --- .../account/sign/SignedWitnessService.java | 23 ++++++++++++++----- .../witness/AccountAgeRestrictions.java | 8 ++++--- .../bisq/core/offer/OfferRestrictions.java | 6 ++--- .../bisq/core/payment/ChargeBackRisk.java | 4 ++-- .../bisq/core/payment/PaymentAccountUtil.java | 7 ++++-- .../core/payment/payload/PaymentMethod.java | 13 ++++++++--- 6 files changed, 42 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/bisq/core/account/sign/SignedWitnessService.java b/core/src/main/java/bisq/core/account/sign/SignedWitnessService.java index 6de14845efb..0c9f6d49c69 100644 --- a/core/src/main/java/bisq/core/account/sign/SignedWitnessService.java +++ b/core/src/main/java/bisq/core/account/sign/SignedWitnessService.java @@ -26,6 +26,7 @@ import bisq.core.arbitration.DisputeResult; import bisq.core.payment.ChargeBackRisk; import bisq.core.payment.payload.PaymentAccountPayload; +import bisq.core.payment.payload.PaymentMethod; import bisq.network.p2p.P2PService; import bisq.network.p2p.storage.P2PDataStorage; @@ -147,7 +148,10 @@ public List getVerifiedWitnessAgeList(AccountAgeWitness accountAgeWitness) } // Arbitrators sign with EC key - public SignedWitness signAccountAgeWitness(Coin tradeAmount, AccountAgeWitness accountAgeWitness, ECKey key, PublicKey peersPubKey) { + public SignedWitness signAccountAgeWitness(Coin tradeAmount, + AccountAgeWitness accountAgeWitness, + ECKey key, + PublicKey peersPubKey) { String accountAgeWitnessHashAsHex = Utilities.encodeToHex(accountAgeWitness.getHash()); String signatureBase64 = key.signMessage(accountAgeWitnessHashAsHex); SignedWitness signedWitness = new SignedWitness(true, @@ -162,7 +166,9 @@ public SignedWitness signAccountAgeWitness(Coin tradeAmount, AccountAgeWitness a } // Any peer can sign with DSA key - public SignedWitness signAccountAgeWitness(Coin tradeAmount, AccountAgeWitness accountAgeWitness, PublicKey peersPubKey) throws CryptoException { + public SignedWitness signAccountAgeWitness(Coin tradeAmount, + AccountAgeWitness accountAgeWitness, + PublicKey peersPubKey) throws CryptoException { byte[] signature = Sig.sign(keyRing.getSignatureKeyPair().getPrivate(), accountAgeWitness.getHash()); SignedWitness signedWitness = new SignedWitness(false, accountAgeWitness.getHash(), @@ -238,7 +244,8 @@ public Set getTrustedPeerSignedWitnessSet(AccountAgeWitness accou // We go one level up by using the signer Key to lookup for SignedWitness objects which contain the signerKey as // witnessOwnerPubKey - public Set getSignedWitnessSetByOwnerPubKey(byte[] ownerPubKey, Stack excluded) { + public Set getSignedWitnessSetByOwnerPubKey(byte[] ownerPubKey, + Stack excluded) { return signedWitnessMap.values().stream() .filter(e -> Arrays.equals(e.getWitnessOwnerPubKey(), ownerPubKey)) .filter(e -> !excluded.contains(new P2PDataStorage.ByteArray(e.getSignerPubKey()))) @@ -270,7 +277,9 @@ public boolean isValidAccountAgeWitness(AccountAgeWitness accountAgeWitness) { * @param excludedPubKeys stack to prevent recursive loops * @return true if signedWitness is valid, false otherwise. */ - private boolean isValidSignedWitnessInternal(SignedWitness signedWitness, long childSignedWitnessDateMillis, Stack excludedPubKeys) { + private boolean isValidSignedWitnessInternal(SignedWitness signedWitness, + long childSignedWitnessDateMillis, + Stack excludedPubKeys) { if (!verifySignature(signedWitness)) { return false; } @@ -323,8 +332,9 @@ private void publishSignedWitness(SignedWitness signedWitness) { } // Arbitrator signing - public List getBuyerPaymentAccounts(long safeDate) { + public List getBuyerPaymentAccounts(long safeDate, PaymentMethod paymentMethod) { return disputeManager.getDisputesAsObservableList().stream() + .filter(dispute -> dispute.getContract().getPaymentMethodId().equals(paymentMethod.getId())) .filter(this::hasChargebackRisk) .filter(this::isBuyerWinner) .map(this::getBuyerData) @@ -335,7 +345,8 @@ public List getBuyerPaymentAccounts(long safeDate) { } private boolean hasChargebackRisk(Dispute dispute) { - return chargeBackRisk.hasChargebackRisk(dispute.getContract().getPaymentMethodId()); + return chargeBackRisk.hasChargebackRisk(dispute.getContract().getPaymentMethodId(), + dispute.getContract().getOfferPayload().getCurrencyCode()); } private boolean isBuyerWinner(Dispute dispute) { diff --git a/core/src/main/java/bisq/core/account/witness/AccountAgeRestrictions.java b/core/src/main/java/bisq/core/account/witness/AccountAgeRestrictions.java index cdf327501da..04c6ab2af43 100644 --- a/core/src/main/java/bisq/core/account/witness/AccountAgeRestrictions.java +++ b/core/src/main/java/bisq/core/account/witness/AccountAgeRestrictions.java @@ -55,7 +55,7 @@ public static long getMyTradeLimitAtCreateOffer(AccountAgeWitnessService account String currencyCode, OfferPayload.Direction direction) { if (direction == OfferPayload.Direction.BUY && - PaymentMethod.hasChargebackRisk(paymentAccount.getPaymentMethod()) && + PaymentMethod.hasChargebackRisk(paymentAccount.getPaymentMethod(), currencyCode) && AccountAgeRestrictions.isMyAccountAgeImmature(accountAgeWitnessService, paymentAccount)) { return OfferRestrictions.TOLERATED_SMALL_TRADE_AMOUNT.value; } else { @@ -68,11 +68,13 @@ public static long getMyTradeLimitAtTakeOffer(AccountAgeWitnessService accountAg Offer offer, String currencyCode, OfferPayload.Direction direction) { - if (direction == OfferPayload.Direction.BUY && PaymentMethod.hasChargebackRisk(paymentAccount.getPaymentMethod()) && + if (direction == OfferPayload.Direction.BUY && + PaymentMethod.hasChargebackRisk(paymentAccount.getPaymentMethod(), currencyCode) && AccountAgeRestrictions.isMakersAccountAgeImmature(accountAgeWitnessService, offer)) { // Taker is seller return OfferRestrictions.TOLERATED_SMALL_TRADE_AMOUNT.value; - } else if (direction == OfferPayload.Direction.SELL && PaymentMethod.hasChargebackRisk(paymentAccount.getPaymentMethod()) && + } else if (direction == OfferPayload.Direction.SELL && + PaymentMethod.hasChargebackRisk(paymentAccount.getPaymentMethod(), currencyCode) && AccountAgeRestrictions.isMyAccountAgeImmature(accountAgeWitnessService, paymentAccount)) { // Taker is buyer return OfferRestrictions.TOLERATED_SMALL_TRADE_AMOUNT.value; diff --git a/core/src/main/java/bisq/core/offer/OfferRestrictions.java b/core/src/main/java/bisq/core/offer/OfferRestrictions.java index 53905478992..d91f6d414ea 100644 --- a/core/src/main/java/bisq/core/offer/OfferRestrictions.java +++ b/core/src/main/java/bisq/core/offer/OfferRestrictions.java @@ -28,13 +28,13 @@ public class OfferRestrictions { public static boolean isOfferRisky(Offer offer) { return offer != null && offer.isBuyOffer() && - PaymentMethod.hasChargebackRisk(offer.getPaymentMethod()) && + PaymentMethod.hasChargebackRisk(offer.getPaymentMethod(), offer.getCurrencyCode()) && isMinTradeAmountRisky(offer); } public static boolean isSellOfferRisky(Offer offer) { return offer != null && - PaymentMethod.hasChargebackRisk(offer.getPaymentMethod()) && + PaymentMethod.hasChargebackRisk(offer.getPaymentMethod(), offer.getCurrencyCode()) && isMinTradeAmountRisky(offer); } @@ -44,7 +44,7 @@ public static boolean isTradeRisky(Trade trade) { Offer offer = trade.getOffer(); return offer != null && - PaymentMethod.hasChargebackRisk(offer.getPaymentMethod()) && + PaymentMethod.hasChargebackRisk(offer.getPaymentMethod(), offer.getCurrencyCode()) && trade.getTradeAmount() != null && isAmountRisky(trade.getTradeAmount()); } diff --git a/core/src/main/java/bisq/core/payment/ChargeBackRisk.java b/core/src/main/java/bisq/core/payment/ChargeBackRisk.java index 32ca2500c50..6faa91c9402 100644 --- a/core/src/main/java/bisq/core/payment/ChargeBackRisk.java +++ b/core/src/main/java/bisq/core/payment/ChargeBackRisk.java @@ -23,7 +23,7 @@ @Singleton public class ChargeBackRisk { - public boolean hasChargebackRisk(String id) { - return PaymentMethod.hasChargebackRisk(id); + public boolean hasChargebackRisk(String id, String currencyCode) { + return PaymentMethod.hasChargebackRisk(id, currencyCode); } } diff --git a/core/src/main/java/bisq/core/payment/PaymentAccountUtil.java b/core/src/main/java/bisq/core/payment/PaymentAccountUtil.java index 7dc43f623c2..b4bba4f4e76 100644 --- a/core/src/main/java/bisq/core/payment/PaymentAccountUtil.java +++ b/core/src/main/java/bisq/core/payment/PaymentAccountUtil.java @@ -67,7 +67,7 @@ public static boolean isSellOfferAndAllTakerPaymentAccountsForOfferImmature(Offe private static boolean isTakerAccountForOfferMature(Offer offer, PaymentAccount takerPaymentAccount, AccountAgeWitnessService accountAgeWitnessService) { - return !PaymentMethod.hasChargebackRisk(offer.getPaymentMethod()) || + return !PaymentMethod.hasChargebackRisk(offer.getPaymentMethod(), offer.getCurrencyCode()) || !OfferRestrictions.isMinTradeAmountRisky(offer) || (isTakerPaymentAccountValidForOffer(offer, takerPaymentAccount) && !AccountAgeRestrictions.isMyAccountAgeImmature(accountAgeWitnessService, takerPaymentAccount)); @@ -84,7 +84,10 @@ public static boolean hasMakerAnyMatureAccountForBuyOffer(Collection currencyWithChargebackRisk = + new ArrayList<>(Arrays.asList("EUR", "USD", "GBP", "CAD", "AUD")); + static { paymentMethods.sort((o1, o2) -> { String id1 = o1.getId(); @@ -316,15 +321,17 @@ public boolean isAsset() { return this.equals(BLOCK_CHAINS_INSTANT) || this.equals(BLOCK_CHAINS); } - public static boolean hasChargebackRisk(PaymentMethod paymentMethod) { + public static boolean hasChargebackRisk(PaymentMethod paymentMethod, String currencyCode) { if (paymentMethod == null) return false; String id = paymentMethod.getId(); - return hasChargebackRisk(id); + return hasChargebackRisk(id, currencyCode); } - public static boolean hasChargebackRisk(String id) { + public static boolean hasChargebackRisk(String id, String currencyCode) { + if (!currencyWithChargebackRisk.contains(currencyCode)) + return false; return id.equals(PaymentMethod.SEPA_ID) || id.equals(PaymentMethod.SEPA_INSTANT_ID) || id.equals(PaymentMethod.INTERAC_E_TRANSFER_ID) || From dec5982b2a0c0bf0b6cbe3c3d65b9b0f7dd8c45f Mon Sep 17 00:00:00 2001 From: sqrrm Date: Fri, 30 Aug 2019 13:57:23 +0200 Subject: [PATCH 2/2] Add BRL as mature market Move mature currency settings to CurrencyUtil as that seems a better fit --- .../main/java/bisq/core/locale/CurrencyUtil.java | 13 +++++++++++++ .../bisq/core/payment/payload/PaymentMethod.java | 9 +++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/bisq/core/locale/CurrencyUtil.java b/core/src/main/java/bisq/core/locale/CurrencyUtil.java index 096766960b5..ac8a8350174 100644 --- a/core/src/main/java/bisq/core/locale/CurrencyUtil.java +++ b/core/src/main/java/bisq/core/locale/CurrencyUtil.java @@ -295,6 +295,19 @@ public static List getAllRevolutCurrencies() { return currencies; } + public static List getMatureMarketCurrencies() { + ArrayList currencies = new ArrayList<>(Arrays.asList( + new FiatCurrency("EUR"), + new FiatCurrency("USD"), + new FiatCurrency("GBP"), + new FiatCurrency("CAD"), + new FiatCurrency("AUD"), + new FiatCurrency("BRL") + )); + currencies.sort(Comparator.comparing(TradeCurrency::getCode)); + return currencies; + } + public static boolean isFiatCurrency(String currencyCode) { try { return currencyCode != null diff --git a/core/src/main/java/bisq/core/payment/payload/PaymentMethod.java b/core/src/main/java/bisq/core/payment/payload/PaymentMethod.java index eab64932760..883efc7866d 100644 --- a/core/src/main/java/bisq/core/payment/payload/PaymentMethod.java +++ b/core/src/main/java/bisq/core/payment/payload/PaymentMethod.java @@ -17,6 +17,7 @@ package bisq.core.payment.payload; +import bisq.core.locale.CurrencyUtil; import bisq.core.locale.Res; import bisq.core.payment.TradeLimits; @@ -188,11 +189,6 @@ public final class PaymentMethod implements PersistablePayload, Comparable { BLOCK_CHAINS_INSTANT = new PaymentMethod(BLOCK_CHAINS_INSTANT_ID, TimeUnit.HOURS.toMillis(1), DEFAULT_TRADE_LIMIT_VERY_LOW_RISK) )); - // Mature markets where chargeback risk is higher due to more liquidity - @Getter - private final static List currencyWithChargebackRisk = - new ArrayList<>(Arrays.asList("EUR", "USD", "GBP", "CAD", "AUD")); - static { paymentMethods.sort((o1, o2) -> { String id1 = o1.getId(); @@ -330,7 +326,8 @@ public static boolean hasChargebackRisk(PaymentMethod paymentMethod, String curr } public static boolean hasChargebackRisk(String id, String currencyCode) { - if (!currencyWithChargebackRisk.contains(currencyCode)) + if (CurrencyUtil.getMatureMarketCurrencies().stream() + .noneMatch(c -> c.getCode().equals(currencyCode))) return false; return id.equals(PaymentMethod.SEPA_ID) || id.equals(PaymentMethod.SEPA_INSTANT_ID) ||