Skip to content

Commit 8716dea

Browse files
authored
Merge pull request #7610 from BitGo/WP-5728/fix/dot-consolidation-blind-sign
feat(sdk-coin-dot): enhance DOT tx verification for consolidation to base address
2 parents df66a62 + 21ebce2 commit 8716dea

File tree

2 files changed

+91
-11
lines changed

2 files changed

+91
-11
lines changed

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

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,17 @@ import {
2929
multisigTypes,
3030
AuditDecryptedKeyParams,
3131
verifyEddsaTssWalletAddress,
32+
TxIntentMismatchRecipientError,
3233
} from '@bitgo/sdk-core';
3334
import { BaseCoin as StaticsBaseCoin, coins, PolkadotSpecNameType } from '@bitgo/statics';
34-
import { Interface, KeyPair as DotKeyPair, Transaction, TransactionBuilderFactory, Utils } from './lib';
35+
import {
36+
Interface,
37+
KeyPair as DotKeyPair,
38+
NativeTransferBuilder,
39+
Transaction,
40+
TransactionBuilderFactory,
41+
Utils,
42+
} from './lib';
3543
import '@polkadot/api-augment';
3644
import { ApiPromise, WsProvider } from '@polkadot/api';
3745
import { Material } from './lib/iface';
@@ -651,7 +659,7 @@ export class Dot extends BaseCoin {
651659
}
652660

653661
async verifyTransaction(params: VerifyTransactionOptions): Promise<boolean> {
654-
const { txPrebuild, txParams } = params;
662+
const { txPrebuild, txParams, verification, wallet, reqId } = params;
655663
if (!txParams) {
656664
throw new Error('missing txParams');
657665
}
@@ -665,7 +673,24 @@ export class Dot extends BaseCoin {
665673
}
666674

667675
const factory = this.getBuilder();
668-
const txBuilder = factory.from(txPrebuild.txHex) as any;
676+
const txBuilder = factory.from(txPrebuild.txHex) as unknown as NativeTransferBuilder;
677+
678+
if (verification?.consolidationToBaseAddress) {
679+
// Verify funds are sent to wallet's base address for consolidation
680+
const baseAddress = wallet?.coinSpecific()?.rootAddress || wallet?.coinSpecific()?.baseAddress;
681+
if (!baseAddress) {
682+
throw new Error('Unable to determine base address for consolidation');
683+
}
684+
if (txBuilder['_to'] !== baseAddress) {
685+
throw new TxIntentMismatchRecipientError(
686+
`Transaction destination address ${txBuilder['_to']} does not match wallet base address ${baseAddress}`,
687+
reqId,
688+
[txParams],
689+
txPrebuild.txHex,
690+
[{ address: txBuilder['_to'], amount: txBuilder['_amount'] }]
691+
);
692+
}
693+
}
669694

670695
if (txParams.recipients !== undefined) {
671696
if (txParams.recipients.length === 0) {
@@ -678,17 +703,25 @@ export class Dot extends BaseCoin {
678703
);
679704
}
680705

681-
// validate recipient is same as txBuilder._to
682-
if (txParams.recipients[0].address !== txBuilder._to) {
683-
throw new Error(
684-
`Recipient address ${txParams.recipients[0].address} does not match transaction destination address ${txBuilder._to}`
706+
// validate recipient is same as txBuilder['_to']
707+
if (txParams.recipients[0].address !== txBuilder['_to']) {
708+
throw new TxIntentMismatchRecipientError(
709+
`Recipient address ${txParams.recipients[0].address} does not match transaction destination address ${txBuilder['_to']}`,
710+
reqId,
711+
[txParams],
712+
txPrebuild.txHex,
713+
[{ address: txBuilder['_to'], amount: txBuilder['_amount'] }]
685714
);
686715
}
687716

688-
// and amount is same as txBuilder._amount
689-
if (txParams.recipients[0].amount !== txBuilder._amount) {
690-
throw new Error(
691-
`Recipient amount ${txParams.recipients[0].amount} does not match transaction amount ${txBuilder._amount}`
717+
// validate amount is same as txBuilder['_amount']
718+
if (txParams.recipients[0].amount !== txBuilder['_amount']) {
719+
throw new TxIntentMismatchRecipientError(
720+
`Recipient amount ${txParams.recipients[0].amount} does not match transaction amount ${txBuilder['_amount']}`,
721+
reqId,
722+
[txParams],
723+
txPrebuild.txHex,
724+
[{ address: txBuilder['_to'], amount: txBuilder['_amount'] }]
692725
);
693726
}
694727
}

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

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,53 @@ describe('DOT:', function () {
727727
const result = await basecoin.verifyTransaction({ txPrebuild, txParams });
728728
assert.strictEqual(result, true);
729729
});
730+
731+
it('should verify a valid consolidation transaction', async function () {
732+
const mockedWallet = {
733+
coinSpecific: () => ({
734+
baseAddress: '5CZh773vKGwKFCYUjGc31AwXCbf7TPkavdeuk2XoujJMjbBD',
735+
}),
736+
};
737+
const txPrebuild = {
738+
txHex:
739+
'0xa80a0300161b969b6b53ef81225feea3882284c778cd4a406d23215fcf492e83f75d42960b00204aa9d101eb600400000065900f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9a7b7420ee3e4fe2b88da0fc42b30897e18d56d8b56a1934211d9de730cf96de300',
740+
};
741+
742+
const result = await basecoin.verifyTransaction({
743+
txPrebuild,
744+
txParams: {},
745+
wallet: mockedWallet as any,
746+
verification: {
747+
consolidationToBaseAddress: true,
748+
},
749+
});
750+
assert.strictEqual(result, true);
751+
});
752+
753+
it('should reject a consolidation transaction with invalid destination address', async function () {
754+
const mockedWallet = {
755+
coinSpecific: () => ({
756+
baseAddress: '5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74',
757+
}),
758+
};
759+
const txPrebuild = {
760+
txHex:
761+
'0xa80a0300161b969b6b53ef81225feea3882284c778cd4a406d23215fcf492e83f75d42960b00204aa9d101eb600400000065900f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9a7b7420ee3e4fe2b88da0fc42b30897e18d56d8b56a1934211d9de730cf96de300',
762+
};
763+
764+
await basecoin
765+
.verifyTransaction({
766+
txPrebuild,
767+
txParams: {},
768+
wallet: mockedWallet as any,
769+
verification: {
770+
consolidationToBaseAddress: true,
771+
},
772+
})
773+
.should.be.rejectedWith(
774+
'Transaction destination address 5CZh773vKGwKFCYUjGc31AwXCbf7TPkavdeuk2XoujJMjbBD does not match wallet base address 5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74'
775+
);
776+
});
730777
});
731778

732779
describe('isWalletAddress', () => {

0 commit comments

Comments
 (0)