Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set active currencies as high chargeback risk #3164

Merged
merged 2 commits into from
Aug 30, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -147,7 +148,10 @@ public List<Long> 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,
Expand All @@ -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(),
Expand Down Expand Up @@ -238,7 +244,8 @@ public Set<SignedWitness> 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<SignedWitness> getSignedWitnessSetByOwnerPubKey(byte[] ownerPubKey, Stack<P2PDataStorage.ByteArray> excluded) {
public Set<SignedWitness> getSignedWitnessSetByOwnerPubKey(byte[] ownerPubKey,
Stack<P2PDataStorage.ByteArray> excluded) {
return signedWitnessMap.values().stream()
.filter(e -> Arrays.equals(e.getWitnessOwnerPubKey(), ownerPubKey))
.filter(e -> !excluded.contains(new P2PDataStorage.ByteArray(e.getSignerPubKey())))
Expand Down Expand Up @@ -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<P2PDataStorage.ByteArray> excludedPubKeys) {
private boolean isValidSignedWitnessInternal(SignedWitness signedWitness,
long childSignedWitnessDateMillis,
Stack<P2PDataStorage.ByteArray> excludedPubKeys) {
if (!verifySignature(signedWitness)) {
return false;
}
Expand Down Expand Up @@ -323,8 +332,9 @@ private void publishSignedWitness(SignedWitness signedWitness) {
}

// Arbitrator signing
public List<BuyerDataItem> getBuyerPaymentAccounts(long safeDate) {
public List<BuyerDataItem> 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)
Expand All @@ -335,7 +345,8 @@ public List<BuyerDataItem> 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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions core/src/main/java/bisq/core/offer/OfferRestrictions.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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());
}
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/bisq/core/payment/ChargeBackRisk.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
7 changes: 5 additions & 2 deletions core/src/main/java/bisq/core/payment/PaymentAccountUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -84,7 +84,10 @@ public static boolean hasMakerAnyMatureAccountForBuyOffer(Collection<PaymentAcco

private static boolean hasMyMatureAccountForBuyOffer(PaymentAccount myPaymentAccount,
AccountAgeWitnessService accountAgeWitnessService) {
return !PaymentMethod.hasChargebackRisk(myPaymentAccount.getPaymentMethod()) ||
if (myPaymentAccount.selectedTradeCurrency == null)
return false;
return !PaymentMethod.hasChargebackRisk(myPaymentAccount.getPaymentMethod(),
myPaymentAccount.selectedTradeCurrency.getCode()) ||
!AccountAgeRestrictions.isMyAccountAgeImmature(accountAgeWitnessService, myPaymentAccount);
}

Expand Down
13 changes: 10 additions & 3 deletions core/src/main/java/bisq/core/payment/payload/PaymentMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,11 @@ 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<String> currencyWithChargebackRisk =
new ArrayList<>(Arrays.asList("EUR", "USD", "GBP", "CAD", "AUD"));

static {
paymentMethods.sort((o1, o2) -> {
String id1 = o1.getId();
Expand Down Expand Up @@ -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) ||
Expand Down