Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
38 changes: 38 additions & 0 deletions extension/src/helpers/transactionResult.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,44 @@ describe("getSettledPathPaymentStrictSendAmount", () => {
getSettledPathPaymentStrictSendAmount(txResult.toXdr("base64"), 0),
).toBeNull();
});

it("returns null when the path payment succeeded but a later operation failed", () => {
// Stellar transactions are atomic: a txFailed result still reports the
// earlier operation's own success, but that path payment was rolled back
// and nothing settled. Reading the amount out of it would report volume
// for a swap that never happened.
const settledPathPayment = xdr.OperationResult.opInner(
xdr.OperationResultTr.pathPaymentStrictSend(
xdr.PathPaymentStrictSendResult.pathPaymentStrictSendSuccess(
new xdr.PathPaymentStrictSendResultSuccess({
offers: [],
last: new xdr.SimplePaymentResult({
destination: xdr.PublicKey.publicKeyTypeEd25519(
Keypair.random().rawPublicKey(),
),
asset: Asset.native().toXdrObject(),
amount: BigInt("50000000"),
}),
}),
),
),
);
const laterFailedOp = xdr.OperationResult.opInner(
xdr.OperationResultTr.payment(xdr.PaymentResult.paymentUnderfunded()),
);
const txResult = new xdr.TransactionResult({
feeCharged: BigInt("100"),
result: xdr.TransactionResultResult.txFailed([
settledPathPayment,
laterFailedOp,
]),
ext: xdr.TransactionResultExt.v0(),
});

expect(
getSettledPathPaymentStrictSendAmount(txResult.toXdr("base64"), 0),
).toBeNull();
});
});

describe("findPathPaymentStrictSendIndex", () => {
Expand Down
10 changes: 6 additions & 4 deletions extension/src/helpers/transactionResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,12 @@ export const getSettledPathPaymentStrictSendAmount = (
? innerResult.innerResultPair.result.result
: innerResult;

if (
innerTxResult.type !== "txSuccess" &&
innerTxResult.type !== "txFailed"
) {
// txSuccess only. A `txFailed` result still carries per-operation
// results, and an operation that succeeded before a later one failed
// reports its own success there — but Stellar transactions are atomic, so
// that path payment was rolled back and nothing settled. Reading an
// amount out of it would report volume for a swap that never happened.
if (innerTxResult.type !== "txSuccess") {
return null;
}
const opResults = innerTxResult.results;
Expand Down
Loading