mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-07-27 00:45:23 -04:00
fix incorrect deposit amount for range trades
improve display of reserved and pending balances by adjusting support subtracting fee from buyer and/or seller on dispute resolution validate trade amount is within offer amount expose maker's split output tx fee expose security deposit received from buyer and seller
This commit is contained in:
parent
0294062312
commit
05e2d925f0
25 changed files with 267 additions and 91 deletions
|
@ -69,6 +69,7 @@ import java.math.BigInteger;
|
|||
import java.security.KeyPair;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
@ -869,12 +870,29 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
// add any loss of precision to winner payout
|
||||
winnerPayoutAmount = winnerPayoutAmount.add(trade.getWallet().getUnlockedBalance().subtract(winnerPayoutAmount.add(loserPayoutAmount)));
|
||||
|
||||
// create dispute payout tx
|
||||
// create dispute payout tx config
|
||||
MoneroTxConfig txConfig = new MoneroTxConfig().setAccountIndex(0);
|
||||
txConfig.setPriority(XmrWalletService.PROTOCOL_FEE_PRIORITY);
|
||||
if (winnerPayoutAmount.compareTo(BigInteger.ZERO) > 0) txConfig.addDestination(winnerPayoutAddress, winnerPayoutAmount);
|
||||
if (loserPayoutAmount.compareTo(BigInteger.ZERO) > 0) txConfig.addDestination(loserPayoutAddress, loserPayoutAmount);
|
||||
txConfig.setSubtractFeeFrom(loserPayoutAmount.equals(BigInteger.ZERO) ? 0 : txConfig.getDestinations().size() - 1); // winner only pays fee if loser gets 0
|
||||
txConfig.setPriority(XmrWalletService.PROTOCOL_FEE_PRIORITY);
|
||||
|
||||
// configure who pays mining fee
|
||||
if (loserPayoutAmount.equals(BigInteger.ZERO)) txConfig.setSubtractFeeFrom(0); // winner pays fee if loser gets 0
|
||||
else {
|
||||
switch (disputeResult.getSubtractFeeFrom()) {
|
||||
case BUYER_AND_SELLER:
|
||||
txConfig.setSubtractFeeFrom(Arrays.asList(0, 1));
|
||||
break;
|
||||
case BUYER_ONLY:
|
||||
txConfig.setSubtractFeeFrom(disputeResult.getWinner() == Winner.BUYER ? 0 : 1);
|
||||
break;
|
||||
case SELLER_ONLY:
|
||||
txConfig.setSubtractFeeFrom(disputeResult.getWinner() == Winner.SELLER ? 0 : 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// create dispute payout tx
|
||||
MoneroTxWallet payoutTx = null;
|
||||
try {
|
||||
payoutTx = trade.getWallet().createTx(txConfig);
|
||||
|
|
|
@ -61,12 +61,21 @@ public final class DisputeResult implements NetworkPayload {
|
|||
PEER_WAS_LATE
|
||||
}
|
||||
|
||||
public enum SubtractFeeFrom {
|
||||
BUYER_ONLY,
|
||||
SELLER_ONLY,
|
||||
BUYER_AND_SELLER
|
||||
}
|
||||
|
||||
private final String tradeId;
|
||||
private final int traderId;
|
||||
@Setter
|
||||
@Nullable
|
||||
private Winner winner;
|
||||
private int reasonOrdinal = Reason.OTHER.ordinal();
|
||||
@Setter
|
||||
@Nullable
|
||||
private SubtractFeeFrom subtractFeeFrom;
|
||||
private final BooleanProperty tamperProofEvidenceProperty = new SimpleBooleanProperty();
|
||||
private final BooleanProperty idVerificationProperty = new SimpleBooleanProperty();
|
||||
private final BooleanProperty screenCastProperty = new SimpleBooleanProperty();
|
||||
|
@ -93,6 +102,7 @@ public final class DisputeResult implements NetworkPayload {
|
|||
int traderId,
|
||||
@Nullable Winner winner,
|
||||
int reasonOrdinal,
|
||||
@Nullable SubtractFeeFrom subtractFeeFrom,
|
||||
boolean tamperProofEvidence,
|
||||
boolean idVerification,
|
||||
boolean screenCast,
|
||||
|
@ -107,6 +117,7 @@ public final class DisputeResult implements NetworkPayload {
|
|||
this.traderId = traderId;
|
||||
this.winner = winner;
|
||||
this.reasonOrdinal = reasonOrdinal;
|
||||
this.subtractFeeFrom = subtractFeeFrom;
|
||||
this.tamperProofEvidenceProperty.set(tamperProofEvidence);
|
||||
this.idVerificationProperty.set(idVerification);
|
||||
this.screenCastProperty.set(screenCast);
|
||||
|
@ -129,6 +140,7 @@ public final class DisputeResult implements NetworkPayload {
|
|||
proto.getTraderId(),
|
||||
ProtoUtil.enumFromProto(DisputeResult.Winner.class, proto.getWinner().name()),
|
||||
proto.getReasonOrdinal(),
|
||||
ProtoUtil.enumFromProto(DisputeResult.SubtractFeeFrom.class, proto.getSubtractFeeFrom().name()),
|
||||
proto.getTamperProofEvidence(),
|
||||
proto.getIdVerification(),
|
||||
proto.getScreenCast(),
|
||||
|
@ -158,6 +170,7 @@ public final class DisputeResult implements NetworkPayload {
|
|||
Optional.ofNullable(arbitratorSignature).ifPresent(arbitratorSignature -> builder.setArbitratorSignature(ByteString.copyFrom(arbitratorSignature)));
|
||||
Optional.ofNullable(arbitratorPubKey).ifPresent(arbitratorPubKey -> builder.setArbitratorPubKey(ByteString.copyFrom(arbitratorPubKey)));
|
||||
Optional.ofNullable(winner).ifPresent(result -> builder.setWinner(protobuf.DisputeResult.Winner.valueOf(winner.name())));
|
||||
Optional.ofNullable(subtractFeeFrom).ifPresent(result -> builder.setSubtractFeeFrom(protobuf.DisputeResult.SubtractFeeFrom.valueOf(subtractFeeFrom.name())));
|
||||
Optional.ofNullable(chatMessage).ifPresent(chatMessage ->
|
||||
builder.setChatMessage(chatMessage.toProtoNetworkEnvelope().getChatMessage()));
|
||||
|
||||
|
@ -201,6 +214,7 @@ public final class DisputeResult implements NetworkPayload {
|
|||
}
|
||||
|
||||
public void setBuyerPayoutAmount(BigInteger buyerPayoutAmount) {
|
||||
if (buyerPayoutAmount.compareTo(BigInteger.ZERO) < 0) throw new IllegalArgumentException("buyerPayoutAmount cannot be negative");
|
||||
this.buyerPayoutAmount = buyerPayoutAmount.longValueExact();
|
||||
}
|
||||
|
||||
|
@ -209,6 +223,7 @@ public final class DisputeResult implements NetworkPayload {
|
|||
}
|
||||
|
||||
public void setSellerPayoutAmount(BigInteger sellerPayoutAmount) {
|
||||
if (sellerPayoutAmount.compareTo(BigInteger.ZERO) < 0) throw new IllegalArgumentException("sellerPayoutAmount cannot be negative");
|
||||
this.sellerPayoutAmount = sellerPayoutAmount.longValueExact();
|
||||
}
|
||||
|
||||
|
@ -231,6 +246,7 @@ public final class DisputeResult implements NetworkPayload {
|
|||
",\n traderId=" + traderId +
|
||||
",\n winner=" + winner +
|
||||
",\n reasonOrdinal=" + reasonOrdinal +
|
||||
",\n subtractFeeFrom=" + subtractFeeFrom +
|
||||
",\n tamperProofEvidenceProperty=" + tamperProofEvidenceProperty +
|
||||
",\n idVerificationProperty=" + idVerificationProperty +
|
||||
",\n screenCastProperty=" + screenCastProperty +
|
||||
|
|
|
@ -390,9 +390,25 @@ public final class ArbitrationManager extends DisputeManager<ArbitrationDisputeL
|
|||
BigInteger expectedWinnerAmount = disputeResult.getWinner() == Winner.BUYER ? disputeResult.getBuyerPayoutAmount() : disputeResult.getSellerPayoutAmount();
|
||||
BigInteger expectedLoserAmount = disputeResult.getWinner() == Winner.BUYER ? disputeResult.getSellerPayoutAmount() : disputeResult.getBuyerPayoutAmount();
|
||||
|
||||
// winner pays cost if loser gets nothing, otherwise loser pays cost
|
||||
if (expectedLoserAmount.equals(BigInteger.ZERO)) expectedWinnerAmount = expectedWinnerAmount.subtract(txCost);
|
||||
else expectedLoserAmount = expectedLoserAmount.subtract(txCost);
|
||||
// subtract mining fee from expected payouts
|
||||
if (expectedLoserAmount.equals(BigInteger.ZERO)) expectedWinnerAmount = expectedWinnerAmount.subtract(txCost); // winner pays fee if loser gets 0
|
||||
else {
|
||||
switch (disputeResult.getSubtractFeeFrom()) {
|
||||
case BUYER_AND_SELLER:
|
||||
BigInteger txCostSplit = txCost.divide(BigInteger.valueOf(2));
|
||||
expectedWinnerAmount = expectedWinnerAmount.subtract(txCostSplit);
|
||||
expectedLoserAmount = expectedLoserAmount.subtract(txCostSplit);
|
||||
break;
|
||||
case BUYER_ONLY:
|
||||
expectedWinnerAmount = expectedWinnerAmount.subtract(disputeResult.getWinner() == Winner.BUYER ? txCost : BigInteger.ZERO);
|
||||
expectedLoserAmount = expectedLoserAmount.subtract(disputeResult.getWinner() == Winner.BUYER ? BigInteger.ZERO : txCost);
|
||||
break;
|
||||
case SELLER_ONLY:
|
||||
expectedWinnerAmount = expectedWinnerAmount.subtract(disputeResult.getWinner() == Winner.BUYER ? BigInteger.ZERO : txCost);
|
||||
expectedLoserAmount = expectedLoserAmount.subtract(disputeResult.getWinner() == Winner.BUYER ? txCost : BigInteger.ZERO);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// verify winner and loser payout amounts
|
||||
if (!expectedWinnerAmount.equals(actualWinnerAmount)) throw new RuntimeException("Unexpected winner payout: " + expectedWinnerAmount + " vs " + actualWinnerAmount);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue