Skip to content

Commit 19938af

Browse files
committed
fix(sdk-coin-ada): relax verifyTransaction amount check for gas tank
Ticket: CSHLD-34
1 parent 77a911f commit 19938af

File tree

3 files changed

+96
-2
lines changed

3 files changed

+96
-2
lines changed

modules/sdk-coin-ada/src/ada.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,10 @@ export class Ada extends BaseCoin {
139139
for (const recipient of txParams.recipients) {
140140
let find = false;
141141
for (const output of explainedTx.outputs) {
142-
if (recipient.address === output.address && recipient.amount === output.amount) {
142+
if (
143+
recipient.address === output.address &&
144+
(recipient.amount === 'max' || BigInt(output.amount) >= BigInt(recipient.amount))
145+
) {
143146
find = true;
144147
}
145148
}

modules/sdk-coin-ada/src/adaToken.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export class AdaToken extends Ada {
137137
}
138138
const multiAssets = output.multiAssets as CardanoWasm.MultiAsset;
139139
const tokenQty = multiAssets.get_asset(policyScriptHash, assetName);
140-
return tokenQty && tokenQty.to_str() === recipient.amount;
140+
return tokenQty && (recipient.amount === 'max' || BigInt(tokenQty.to_str()) >= BigInt(recipient.amount));
141141
});
142142

143143
if (!found) {

modules/sdk-coin-ada/test/unit/ada.ts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,97 @@ describe('ADA', function () {
249249
validTransaction.should.equal(true);
250250
});
251251

252+
it('should succeed when output amount >= requested amount for any gas tank address (WIN-9022)', async () => {
253+
// WIN-9022: gas tank transactions cause the server to absorb dust change into the
254+
// output, so the actual output amount may be larger than requested. The >= check
255+
// allows this for ANY address as long as the output sends at least what was requested.
256+
const txPrebuild = newTxPrebuild();
257+
const testCases = [
258+
{ address: rawTx.outputAddress1.address, amount: '2000000' },
259+
{ address: rawTx.outputAddress1.address, amount: '1' },
260+
{ address: rawTx.outputAddress1.address, amount: '5000000' },
261+
{ address: rawTx.outputAddress2.address, amount: '1' },
262+
];
263+
for (const { address, amount } of testCases) {
264+
const txParams = {
265+
recipients: [{ address, amount }],
266+
};
267+
const isTransactionVerified = await basecoin.verifyTransaction({
268+
txParams,
269+
txPrebuild,
270+
verification: {},
271+
});
272+
isTransactionVerified.should.equal(true);
273+
}
274+
});
275+
276+
it('should fail when requested amount exceeds actual output amount', async () => {
277+
const txPrebuild = newTxPrebuild();
278+
const txParams = {
279+
recipients: [
280+
{
281+
address: rawTx.outputAddress1.address,
282+
amount: '9999999999',
283+
},
284+
],
285+
};
286+
287+
await basecoin
288+
.verifyTransaction({ txParams, txPrebuild, verification: {} })
289+
.should.be.rejectedWith('cannot find recipient in expected output');
290+
});
291+
292+
it('should succeed when recipient amount is max', async () => {
293+
const txPrebuild = newTxPrebuild();
294+
const txParams = {
295+
recipients: [
296+
{
297+
address: rawTx.outputAddress1.address,
298+
amount: 'max',
299+
},
300+
],
301+
};
302+
303+
const isTransactionVerified = await basecoin.verifyTransaction({
304+
txParams,
305+
txPrebuild,
306+
verification: {},
307+
});
308+
isTransactionVerified.should.equal(true);
309+
});
310+
311+
it('should fail when address does not match any output regardless of amount', async () => {
312+
const txPrebuild = newTxPrebuild();
313+
const txParams = {
314+
recipients: [
315+
{
316+
address: 'addr_test1vrcx9yqtect97qlfq0hmttsd6ns38kvqw6lhcsyjwsh6zuqdpvg6u',
317+
amount: '1',
318+
},
319+
],
320+
};
321+
322+
await basecoin
323+
.verifyTransaction({ txParams, txPrebuild, verification: {} })
324+
.should.be.rejectedWith('cannot find recipient in expected output');
325+
});
326+
327+
it('should fail when recipient amount is max but address does not match', async () => {
328+
const txPrebuild = newTxPrebuild();
329+
const txParams = {
330+
recipients: [
331+
{
332+
address: '9f7b0675db59d19b4bd9c8c72eaabba75a9863d02b30115b8b3c3ca5c20f0254',
333+
amount: 'max',
334+
},
335+
],
336+
};
337+
338+
await basecoin
339+
.verifyTransaction({ txParams, txPrebuild, verification: {} })
340+
.should.be.rejectedWith('cannot find recipient in expected output');
341+
});
342+
252343
it('should verify a valid consolidation transaction', async () => {
253344
const consolidationTx = {
254345
txRequestId: '1b5c79c5-ab7c-4f47-912b-de6a95fb0779',

0 commit comments

Comments
 (0)