mirror of
https://github.com/haveno-dex/haveno-ts.git
synced 2025-01-23 21:21:20 -05:00
test buyer and seller payout tx fee and amount
This commit is contained in:
parent
6725b44792
commit
29af0f4d14
36
dist/protobuf/grpc_pb.d.ts
vendored
36
dist/protobuf/grpc_pb.d.ts
vendored
@ -2650,12 +2650,6 @@ export class TradeInfo extends jspb.Message {
|
|||||||
getTakerFee(): string;
|
getTakerFee(): string;
|
||||||
setTakerFee(value: string): TradeInfo;
|
setTakerFee(value: string): TradeInfo;
|
||||||
|
|
||||||
getTakerFeeTxId(): string;
|
|
||||||
setTakerFeeTxId(value: string): TradeInfo;
|
|
||||||
|
|
||||||
getPayoutTxId(): string;
|
|
||||||
setPayoutTxId(value: string): TradeInfo;
|
|
||||||
|
|
||||||
getAmount(): string;
|
getAmount(): string;
|
||||||
setAmount(value: string): TradeInfo;
|
setAmount(value: string): TradeInfo;
|
||||||
|
|
||||||
@ -2665,6 +2659,24 @@ export class TradeInfo extends jspb.Message {
|
|||||||
getSellerSecurityDeposit(): string;
|
getSellerSecurityDeposit(): string;
|
||||||
setSellerSecurityDeposit(value: string): TradeInfo;
|
setSellerSecurityDeposit(value: string): TradeInfo;
|
||||||
|
|
||||||
|
getBuyerDepositTxFee(): string;
|
||||||
|
setBuyerDepositTxFee(value: string): TradeInfo;
|
||||||
|
|
||||||
|
getSellerDepositTxFee(): string;
|
||||||
|
setSellerDepositTxFee(value: string): TradeInfo;
|
||||||
|
|
||||||
|
getBuyerPayoutTxFee(): string;
|
||||||
|
setBuyerPayoutTxFee(value: string): TradeInfo;
|
||||||
|
|
||||||
|
getSellerPayoutTxFee(): string;
|
||||||
|
setSellerPayoutTxFee(value: string): TradeInfo;
|
||||||
|
|
||||||
|
getBuyerPayoutAmount(): string;
|
||||||
|
setBuyerPayoutAmount(value: string): TradeInfo;
|
||||||
|
|
||||||
|
getSellerPayoutAmount(): string;
|
||||||
|
setSellerPayoutAmount(value: string): TradeInfo;
|
||||||
|
|
||||||
getPrice(): string;
|
getPrice(): string;
|
||||||
setPrice(value: string): TradeInfo;
|
setPrice(value: string): TradeInfo;
|
||||||
|
|
||||||
@ -2733,6 +2745,9 @@ export class TradeInfo extends jspb.Message {
|
|||||||
getTakerDepositTxId(): string;
|
getTakerDepositTxId(): string;
|
||||||
setTakerDepositTxId(value: string): TradeInfo;
|
setTakerDepositTxId(value: string): TradeInfo;
|
||||||
|
|
||||||
|
getPayoutTxId(): string;
|
||||||
|
setPayoutTxId(value: string): TradeInfo;
|
||||||
|
|
||||||
serializeBinary(): Uint8Array;
|
serializeBinary(): Uint8Array;
|
||||||
toObject(includeInstance?: boolean): TradeInfo.AsObject;
|
toObject(includeInstance?: boolean): TradeInfo.AsObject;
|
||||||
static toObject(includeInstance: boolean, msg: TradeInfo): TradeInfo.AsObject;
|
static toObject(includeInstance: boolean, msg: TradeInfo): TradeInfo.AsObject;
|
||||||
@ -2749,11 +2764,15 @@ export namespace TradeInfo {
|
|||||||
date: number,
|
date: number,
|
||||||
role: string,
|
role: string,
|
||||||
takerFee: string,
|
takerFee: string,
|
||||||
takerFeeTxId: string,
|
|
||||||
payoutTxId: string,
|
|
||||||
amount: string,
|
amount: string,
|
||||||
buyerSecurityDeposit: string,
|
buyerSecurityDeposit: string,
|
||||||
sellerSecurityDeposit: string,
|
sellerSecurityDeposit: string,
|
||||||
|
buyerDepositTxFee: string,
|
||||||
|
sellerDepositTxFee: string,
|
||||||
|
buyerPayoutTxFee: string,
|
||||||
|
sellerPayoutTxFee: string,
|
||||||
|
buyerPayoutAmount: string,
|
||||||
|
sellerPayoutAmount: string,
|
||||||
price: string,
|
price: string,
|
||||||
arbitratorNodeAddress: string,
|
arbitratorNodeAddress: string,
|
||||||
tradePeerNodeAddress: string,
|
tradePeerNodeAddress: string,
|
||||||
@ -2776,6 +2795,7 @@ export namespace TradeInfo {
|
|||||||
tradeVolume: string,
|
tradeVolume: string,
|
||||||
makerDepositTxId: string,
|
makerDepositTxId: string,
|
||||||
takerDepositTxId: string,
|
takerDepositTxId: string,
|
||||||
|
payoutTxId: string,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
814
dist/protobuf/grpc_pb.js
vendored
814
dist/protobuf/grpc_pb.js
vendored
File diff suppressed because it is too large
Load Diff
2
dist/protobuf/grpc_pb.js.map
vendored
2
dist/protobuf/grpc_pb.js.map
vendored
File diff suppressed because one or more lines are too long
40
dist/protobuf/pb_pb.d.ts
vendored
40
dist/protobuf/pb_pb.d.ts
vendored
@ -3180,11 +3180,11 @@ export class DisputeResult extends jspb.Message {
|
|||||||
getArbitratorSignature_asB64(): string;
|
getArbitratorSignature_asB64(): string;
|
||||||
setArbitratorSignature(value: Uint8Array | string): DisputeResult;
|
setArbitratorSignature(value: Uint8Array | string): DisputeResult;
|
||||||
|
|
||||||
getBuyerPayoutAmount(): number;
|
getBuyerPayoutAmountBeforeCost(): number;
|
||||||
setBuyerPayoutAmount(value: number): DisputeResult;
|
setBuyerPayoutAmountBeforeCost(value: number): DisputeResult;
|
||||||
|
|
||||||
getSellerPayoutAmount(): number;
|
getSellerPayoutAmountBeforeCost(): number;
|
||||||
setSellerPayoutAmount(value: number): DisputeResult;
|
setSellerPayoutAmountBeforeCost(value: number): DisputeResult;
|
||||||
|
|
||||||
getSubtractFeeFrom(): DisputeResult.SubtractFeeFrom;
|
getSubtractFeeFrom(): DisputeResult.SubtractFeeFrom;
|
||||||
setSubtractFeeFrom(value: DisputeResult.SubtractFeeFrom): DisputeResult;
|
setSubtractFeeFrom(value: DisputeResult.SubtractFeeFrom): DisputeResult;
|
||||||
@ -3220,8 +3220,8 @@ export namespace DisputeResult {
|
|||||||
summaryNotes: string,
|
summaryNotes: string,
|
||||||
chatMessage?: ChatMessage.AsObject,
|
chatMessage?: ChatMessage.AsObject,
|
||||||
arbitratorSignature: Uint8Array | string,
|
arbitratorSignature: Uint8Array | string,
|
||||||
buyerPayoutAmount: number,
|
buyerPayoutAmountBeforeCost: number,
|
||||||
sellerPayoutAmount: number,
|
sellerPayoutAmountBeforeCost: number,
|
||||||
subtractFeeFrom: DisputeResult.SubtractFeeFrom,
|
subtractFeeFrom: DisputeResult.SubtractFeeFrom,
|
||||||
arbitratorPubKey: Uint8Array | string,
|
arbitratorPubKey: Uint8Array | string,
|
||||||
closeDate: number,
|
closeDate: number,
|
||||||
@ -6030,9 +6030,6 @@ export class Trade extends jspb.Message {
|
|||||||
getTakerFee(): number;
|
getTakerFee(): number;
|
||||||
setTakerFee(value: number): Trade;
|
setTakerFee(value: number): Trade;
|
||||||
|
|
||||||
getTotalTxFee(): number;
|
|
||||||
setTotalTxFee(value: number): Trade;
|
|
||||||
|
|
||||||
getTakeOfferDate(): number;
|
getTakeOfferDate(): number;
|
||||||
setTakeOfferDate(value: number): Trade;
|
setTakeOfferDate(value: number): Trade;
|
||||||
|
|
||||||
@ -6125,7 +6122,6 @@ export namespace Trade {
|
|||||||
payoutTxKey: string,
|
payoutTxKey: string,
|
||||||
amount: number,
|
amount: number,
|
||||||
takerFee: number,
|
takerFee: number,
|
||||||
totalTxFee: number,
|
|
||||||
takeOfferDate: number,
|
takeOfferDate: number,
|
||||||
price: number,
|
price: number,
|
||||||
state: Trade.State,
|
state: Trade.State,
|
||||||
@ -6531,6 +6527,12 @@ export class TradePeer extends jspb.Message {
|
|||||||
getExchangedMultisigHex(): string;
|
getExchangedMultisigHex(): string;
|
||||||
setExchangedMultisigHex(value: string): TradePeer;
|
setExchangedMultisigHex(value: string): TradePeer;
|
||||||
|
|
||||||
|
getUpdatedMultisigHex(): string;
|
||||||
|
setUpdatedMultisigHex(value: string): TradePeer;
|
||||||
|
|
||||||
|
getDepositsConfirmedMessageAcked(): boolean;
|
||||||
|
setDepositsConfirmedMessageAcked(value: boolean): TradePeer;
|
||||||
|
|
||||||
getDepositTxHash(): string;
|
getDepositTxHash(): string;
|
||||||
setDepositTxHash(value: string): TradePeer;
|
setDepositTxHash(value: string): TradePeer;
|
||||||
|
|
||||||
@ -6546,11 +6548,14 @@ export class TradePeer extends jspb.Message {
|
|||||||
getSecurityDeposit(): number;
|
getSecurityDeposit(): number;
|
||||||
setSecurityDeposit(value: number): TradePeer;
|
setSecurityDeposit(value: number): TradePeer;
|
||||||
|
|
||||||
getUpdatedMultisigHex(): string;
|
getUnsignedPayoutTxHex(): string;
|
||||||
setUpdatedMultisigHex(value: string): TradePeer;
|
setUnsignedPayoutTxHex(value: string): TradePeer;
|
||||||
|
|
||||||
getDepositsConfirmedMessageAcked(): boolean;
|
getPayoutTxFee(): number;
|
||||||
setDepositsConfirmedMessageAcked(value: boolean): TradePeer;
|
setPayoutTxFee(value: number): TradePeer;
|
||||||
|
|
||||||
|
getPayoutAmount(): number;
|
||||||
|
setPayoutAmount(value: number): TradePeer;
|
||||||
|
|
||||||
serializeBinary(): Uint8Array;
|
serializeBinary(): Uint8Array;
|
||||||
toObject(includeInstance?: boolean): TradePeer.AsObject;
|
toObject(includeInstance?: boolean): TradePeer.AsObject;
|
||||||
@ -6589,13 +6594,16 @@ export namespace TradePeer {
|
|||||||
preparedMultisigHex: string,
|
preparedMultisigHex: string,
|
||||||
madeMultisigHex: string,
|
madeMultisigHex: string,
|
||||||
exchangedMultisigHex: string,
|
exchangedMultisigHex: string,
|
||||||
|
updatedMultisigHex: string,
|
||||||
|
depositsConfirmedMessageAcked: boolean,
|
||||||
depositTxHash: string,
|
depositTxHash: string,
|
||||||
depositTxHex: string,
|
depositTxHex: string,
|
||||||
depositTxKey: string,
|
depositTxKey: string,
|
||||||
depositTxFee: number,
|
depositTxFee: number,
|
||||||
securityDeposit: number,
|
securityDeposit: number,
|
||||||
updatedMultisigHex: string,
|
unsignedPayoutTxHex: string,
|
||||||
depositsConfirmedMessageAcked: boolean,
|
payoutTxFee: number,
|
||||||
|
payoutAmount: number,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
812
dist/protobuf/pb_pb.js
vendored
812
dist/protobuf/pb_pb.js
vendored
File diff suppressed because it is too large
Load Diff
2
dist/protobuf/pb_pb.js.map
vendored
2
dist/protobuf/pb_pb.js.map
vendored
File diff suppressed because one or more lines are too long
@ -89,7 +89,8 @@ class PeerContext {
|
|||||||
depositTx: moneroTs.MoneroTx;
|
depositTx: moneroTs.MoneroTx;
|
||||||
depositTxFee: bigint;
|
depositTxFee: bigint;
|
||||||
securityDepositActual: bigint;
|
securityDepositActual: bigint;
|
||||||
payoutAmount: bigint
|
payoutTxFee: bigint;
|
||||||
|
payoutAmount: bigint;
|
||||||
|
|
||||||
constructor(ctx?: Partial<PeerContext>) {
|
constructor(ctx?: Partial<PeerContext>) {
|
||||||
Object.assign(this, ctx);
|
Object.assign(this, ctx);
|
||||||
@ -259,6 +260,10 @@ class TradeContext {
|
|||||||
return this.disputeWinner === DisputeResult.Winner.BUYER ? this.getSeller() : this.getBuyer();
|
return this.disputeWinner === DisputeResult.Winner.BUYER ? this.getSeller() : this.getBuyer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isOfflineFlow() {
|
||||||
|
return this.buyerOfflineAfterDisputeOpened || this.sellerOfflineAfterDisputeOpened || this.buyerOfflineAfterPaymentSent || this.buyerOfflineAfterTake || this.sellerOfflineAfterTake;
|
||||||
|
}
|
||||||
|
|
||||||
static init(ctxP: Partial<TradeContext> | undefined): TradeContext {
|
static init(ctxP: Partial<TradeContext> | undefined): TradeContext {
|
||||||
let ctx = ctxP instanceof TradeContext ? ctxP : new TradeContext(ctxP);
|
let ctx = ctxP instanceof TradeContext ? ctxP : new TradeContext(ctxP);
|
||||||
if (!ctx.offerAmount && ctx.tradeAmount) ctx.offerAmount = ctx.tradeAmount;
|
if (!ctx.offerAmount && ctx.tradeAmount) ctx.offerAmount = ctx.tradeAmount;
|
||||||
@ -1755,7 +1760,7 @@ test("Can resolve disputes (CI)", async () => {
|
|||||||
await executeTrades(ctxs.slice(configIdx, configIdx === undefined ? undefined : configIdx + 1), {concurrentTrades: !testBalancesSequentially});
|
await executeTrades(ctxs.slice(configIdx, configIdx === undefined ? undefined : configIdx + 1), {concurrentTrades: !testBalancesSequentially});
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Can go offline while resolving disputes (CI)", async () => {
|
test("Can go offline while resolving a dispute (CI)", async () => {
|
||||||
let traders: HavenoClient[] = [];
|
let traders: HavenoClient[] = [];
|
||||||
let ctx: Partial<TradeContext> = {};
|
let ctx: Partial<TradeContext> = {};
|
||||||
let err: any;
|
let err: any;
|
||||||
@ -2455,10 +2460,7 @@ async function executeTrade(ctxP: Partial<TradeContext>): Promise<string> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// test balances after payout tx unless other trades can interfere
|
// test balances after payout tx unless other trades can interfere
|
||||||
if (!ctx.concurrentTrades) {
|
if (!ctx.concurrentTrades) await testAmountsAfterComplete(ctx);
|
||||||
await testBalancesAfterComplete(ctx, ctx.getMaker());
|
|
||||||
await testBalancesAfterComplete(ctx, ctx.getTaker());
|
|
||||||
}
|
|
||||||
|
|
||||||
// test payout unlock
|
// test payout unlock
|
||||||
await testTradePayoutUnlock(ctx);
|
await testTradePayoutUnlock(ctx);
|
||||||
@ -2787,7 +2789,7 @@ async function testOpenDispute(ctxP: Partial<TradeContext>) {
|
|||||||
await arbitrator.addNotificationListener(notification => { HavenoUtils.log(3, "Arbitrator received notification " + notification.getType() + " " + (notification.getChatMessage() ? notification.getChatMessage()?.getMessage() : "")); arbitratorNotifications.push(notification); });
|
await arbitrator.addNotificationListener(notification => { HavenoUtils.log(3, "Arbitrator received notification " + notification.getType() + " " + (notification.getChatMessage() ? notification.getChatMessage()?.getMessage() : "")); arbitratorNotifications.push(notification); });
|
||||||
|
|
||||||
// arbitrator sends chat messages to traders
|
// arbitrator sends chat messages to traders
|
||||||
HavenoUtils.log(1, "Testing chat messages");
|
HavenoUtils.log(1, "Arbitrator sending chat messages to traders. tradeId=" + ctx.offerId + ", disputeId=" + openerDispute.getId());
|
||||||
await ctx.arbitrator.havenod!.sendDisputeChatMessage(arbDisputeOpener!.getId(), "Arbitrator chat message to dispute opener", []);
|
await ctx.arbitrator.havenod!.sendDisputeChatMessage(arbDisputeOpener!.getId(), "Arbitrator chat message to dispute opener", []);
|
||||||
await ctx.arbitrator.havenod!.sendDisputeChatMessage(arbDisputePeer!.getId(), "Arbitrator chat message to dispute peer", []);
|
await ctx.arbitrator.havenod!.sendDisputeChatMessage(arbDisputePeer!.getId(), "Arbitrator chat message to dispute peer", []);
|
||||||
|
|
||||||
@ -2887,8 +2889,6 @@ async function resolveDispute(ctxP: Partial<TradeContext>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// resolve dispute according to configuration
|
// resolve dispute according to configuration
|
||||||
const winnerd = ctx.disputeWinner === DisputeResult.Winner.BUYER ? ctx.getBuyer().havenod : ctx.getSeller().havenod;
|
|
||||||
const loserd = ctx.disputeWinner === DisputeResult.Winner.BUYER ? ctx.getSeller().havenod : ctx.getBuyer().havenod;
|
|
||||||
HavenoUtils.log(1, "Resolving dispute for trade " + ctx.offerId);
|
HavenoUtils.log(1, "Resolving dispute for trade " + ctx.offerId);
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
await arbitrator.resolveDispute(ctx.offerId!, ctx.disputeWinner!, ctx.disputeReason!, ctx.disputeSummary!, ctx.disputeWinnerAmount);
|
await arbitrator.resolveDispute(ctx.offerId!, ctx.disputeWinner!, ctx.disputeReason!, ctx.disputeSummary!, ctx.disputeWinnerAmount);
|
||||||
@ -2926,7 +2926,10 @@ async function resolveDispute(ctxP: Partial<TradeContext>) {
|
|||||||
await testTradeState(await ctx.arbitrator.havenod!.getTrade(ctx.offerId!), {phase: "COMPLETED", payoutState: ["PAYOUT_PUBLISHED", "PAYOUT_CONFIRMED", "PAYOUT_UNLOCKED"], disputeState: "DISPUTE_CLOSED", isCompleted: true, isPayoutPublished: true});
|
await testTradeState(await ctx.arbitrator.havenod!.getTrade(ctx.offerId!), {phase: "COMPLETED", payoutState: ["PAYOUT_PUBLISHED", "PAYOUT_CONFIRMED", "PAYOUT_UNLOCKED"], disputeState: "DISPUTE_CLOSED", isCompleted: true, isPayoutPublished: true});
|
||||||
|
|
||||||
// signing peer has payout tx id on 0 conf (peers must wait for confirmation to see outgoing tx)
|
// signing peer has payout tx id on 0 conf (peers must wait for confirmation to see outgoing tx)
|
||||||
if (winnerd) ctx.payoutTxId = (await winnerd!.getTrade(ctx.offerId!)).getPayoutTxId()
|
const winnerd = ctx.disputeWinner === DisputeResult.Winner.BUYER ? ctx.getBuyer().havenod : ctx.getSeller().havenod;
|
||||||
|
const loserd = ctx.disputeWinner === DisputeResult.Winner.BUYER ? ctx.getSeller().havenod : ctx.getBuyer().havenod;
|
||||||
|
const signerd = winnerd ? winnerd : loserd;
|
||||||
|
ctx.payoutTxId = (await signerd!.getTrade(ctx.offerId!)).getPayoutTxId();
|
||||||
|
|
||||||
// record balances on completion
|
// record balances on completion
|
||||||
if (!ctx.maker.balancesAfterPayout) {
|
if (!ctx.maker.balancesAfterPayout) {
|
||||||
@ -2935,45 +2938,68 @@ async function resolveDispute(ctxP: Partial<TradeContext>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// test balances after payout tx unless concurrent trades
|
// test balances after payout tx unless concurrent trades
|
||||||
if (!ctx.concurrentTrades) {
|
if (!ctx.concurrentTrades) await testAmountsAfterComplete(ctx);
|
||||||
if (winnerd) await testBalancesAfterComplete(ctx, ctx.getDisputeWinner()!);
|
|
||||||
if (loserd) await testBalancesAfterComplete(ctx, ctx.getDisputeLoser()!);
|
|
||||||
}
|
|
||||||
|
|
||||||
// test payout unlock
|
// test payout unlock
|
||||||
await testTradePayoutUnlock(ctx);
|
await testTradePayoutUnlock(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testBalancesAfterComplete(tradeCtx: TradeContext, peerCtx: PeerContext) {
|
async function testAmountsAfterComplete(tradeCtx: TradeContext) {
|
||||||
|
|
||||||
// update context
|
// get payout tx
|
||||||
const trade = await peerCtx.havenod?.getTrade(tradeCtx.offerId!)!;
|
|
||||||
peerCtx.trade = trade;
|
|
||||||
if (!tradeCtx.payoutTxId) throw new Error("Missing payout tx id");
|
if (!tradeCtx.payoutTxId) throw new Error("Missing payout tx id");
|
||||||
const payoutTx = await monerod.getTx(tradeCtx.payoutTxId);
|
const payoutTx = await monerod.getTx(tradeCtx.payoutTxId);
|
||||||
const payoutTxFee = BigInt(payoutTx!.getFee());
|
const payoutTxFee = BigInt(payoutTx!.getFee());
|
||||||
|
|
||||||
// calculate expected payout amount for normal trade
|
// get expected payouts for normal trade
|
||||||
if (tradeCtx.getDisputeOpener() === undefined) {
|
const isDisputedTrade = tradeCtx.getDisputeOpener() !== undefined;
|
||||||
let receiveAmount: bigint = tradeCtx.getBuyer() == peerCtx ? BigInt(trade.getAmount()) : 0n;
|
if (!isDisputedTrade) {
|
||||||
peerCtx.payoutAmount = peerCtx.securityDepositActual + receiveAmount - (payoutTxFee / 2n);
|
tradeCtx.getBuyer().payoutTxFee = payoutTxFee / 2n;
|
||||||
}
|
tradeCtx.getBuyer().payoutAmount = tradeCtx.getBuyer().securityDepositActual + tradeCtx.tradeAmount! - tradeCtx.getBuyer().payoutTxFee;
|
||||||
|
tradeCtx.getSeller().payoutTxFee = payoutTxFee / 2n;
|
||||||
|
tradeCtx.getSeller().payoutAmount = tradeCtx.getSeller().securityDepositActual - tradeCtx.getSeller().payoutTxFee;
|
||||||
|
} else {
|
||||||
|
|
||||||
// calculate expected payout amount for dispute trade
|
// get expected payouts for disputed trade
|
||||||
else {
|
|
||||||
const winnerGetsAll = tradeCtx.disputeWinnerAmount === tradeCtx.maker.securityDepositActual! + tradeCtx.taker.securityDepositActual! + tradeCtx.tradeAmount!;
|
const winnerGetsAll = tradeCtx.disputeWinnerAmount === tradeCtx.maker.securityDepositActual! + tradeCtx.taker.securityDepositActual! + tradeCtx.tradeAmount!;
|
||||||
if (tradeCtx.getDisputeWinner() === peerCtx) {
|
if (tradeCtx.disputeWinnerAmount) {
|
||||||
if (tradeCtx.disputeWinnerAmount) peerCtx.payoutAmount = tradeCtx.disputeWinnerAmount - (winnerGetsAll ? payoutTxFee : 0n);
|
tradeCtx.getDisputeWinner()!.payoutTxFee = winnerGetsAll ? payoutTxFee : 0n;
|
||||||
else peerCtx.payoutAmount = tradeCtx.tradeAmount! + peerCtx.securityDepositActual - (payoutTxFee / 2n);
|
tradeCtx.getDisputeWinner()!.payoutAmount = tradeCtx.disputeWinnerAmount - tradeCtx.getDisputeWinner()!.payoutTxFee;
|
||||||
|
tradeCtx.getDisputeLoser()!.payoutTxFee = winnerGetsAll ? 0n : payoutTxFee;
|
||||||
|
tradeCtx.getDisputeLoser()!.payoutAmount = tradeCtx.maker.securityDepositActual! + tradeCtx.taker.securityDepositActual! + tradeCtx.tradeAmount! - tradeCtx.disputeWinnerAmount - tradeCtx.getDisputeLoser()!.payoutTxFee;
|
||||||
} else {
|
} else {
|
||||||
if (tradeCtx.disputeWinnerAmount) {
|
tradeCtx.getDisputeWinner()!.payoutTxFee = payoutTxFee / 2n;
|
||||||
const multisigBalance = tradeCtx.maker.securityDepositActual! + tradeCtx.taker.securityDepositActual! + tradeCtx.tradeAmount!;
|
tradeCtx.getDisputeWinner()!.payoutAmount = tradeCtx.tradeAmount! + tradeCtx.getDisputeWinner()!.securityDepositActual - tradeCtx.getDisputeWinner()!.payoutTxFee;
|
||||||
peerCtx.payoutAmount = multisigBalance - tradeCtx.disputeWinnerAmount - (winnerGetsAll ? 0n : payoutTxFee);
|
tradeCtx.getDisputeLoser()!.payoutTxFee = payoutTxFee / 2n;
|
||||||
}
|
tradeCtx.getDisputeLoser()!.payoutAmount = tradeCtx.getDisputeLoser()!.securityDepositActual - tradeCtx.getDisputeLoser()!.payoutTxFee;
|
||||||
else peerCtx.payoutAmount = peerCtx.securityDepositActual - (payoutTxFee / 2n);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: payout tx is unknown to offline non-signer until confirmed
|
||||||
|
if (isDisputedTrade || tradeCtx.isOfflineFlow()) {
|
||||||
|
await mineToHeight(await monerod.getHeight() + 1);
|
||||||
|
await wait(TestConfig.maxWalletStartupMs + tradeCtx.walletSyncPeriodMs * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// test trade payouts
|
||||||
|
if (tradeCtx.maker.havenod) await testPeerAmountsAfterComplete(tradeCtx, tradeCtx.getMaker());
|
||||||
|
if (tradeCtx.taker.havenod) await testPeerAmountsAfterComplete(tradeCtx, tradeCtx.getTaker());
|
||||||
|
}
|
||||||
|
|
||||||
|
async function testPeerAmountsAfterComplete(tradeCtx: TradeContext, peerCtx: PeerContext) {
|
||||||
|
|
||||||
|
// get trade
|
||||||
|
const trade = await peerCtx.havenod.getTrade(tradeCtx.offerId!);
|
||||||
|
|
||||||
|
// test trade amounts
|
||||||
|
const isBuyer = tradeCtx.getBuyer() === peerCtx;
|
||||||
|
if (isBuyer) expect(BigInt(trade.getBuyerDepositTxFee())).toEqual(tradeCtx.getBuyer().depositTxFee); // TODO: get and test peer's security deposit tx fee?
|
||||||
|
else expect(BigInt(trade.getSellerDepositTxFee())).toEqual(tradeCtx.getSeller().depositTxFee);
|
||||||
|
expect(BigInt(trade.getBuyerPayoutTxFee())).toEqual(tradeCtx.getBuyer().payoutTxFee);
|
||||||
|
expect(BigInt(trade.getSellerPayoutTxFee())).toEqual(tradeCtx.getSeller().payoutTxFee);
|
||||||
|
expect(BigInt(trade.getBuyerPayoutAmount())).toEqual(tradeCtx.getBuyer().payoutAmount);
|
||||||
|
expect(BigInt(trade.getSellerPayoutAmount())).toEqual(tradeCtx.getSeller().payoutAmount);
|
||||||
|
|
||||||
// test balance change after payout tx
|
// test balance change after payout tx
|
||||||
const differenceAfterPayout = BigInt(peerCtx.balancesAfterPayout?.getBalance()!) - BigInt(peerCtx.balancesBeforePayout?.getBalance()!);
|
const differenceAfterPayout = BigInt(peerCtx.balancesAfterPayout?.getBalance()!) - BigInt(peerCtx.balancesBeforePayout?.getBalance()!);
|
||||||
expect(differenceAfterPayout).toEqual(peerCtx.payoutAmount);
|
expect(differenceAfterPayout).toEqual(peerCtx.payoutAmount);
|
||||||
|
Loading…
Reference in New Issue
Block a user