Skip to content

Commit 52ce6b0

Browse files
Merge pull request #6785 from BitGo/WP-3968/fix/sol-consolidation-blind-sign
fix(sdk-coin-sol): add verification for Solana consolidation transactions
2 parents 6994b43 + f9207ad commit 52ce6b0

File tree

2 files changed

+416
-9
lines changed

2 files changed

+416
-9
lines changed

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

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,11 +232,17 @@ export class Sol extends BaseCoin {
232232
return Math.pow(10, this._staticsCoin.decimalPlaces);
233233
}
234234

235-
async verifyTransaction(params: SolVerifyTransactionOptions): Promise<any> {
235+
async verifyTransaction(params: SolVerifyTransactionOptions): Promise<boolean> {
236236
// asset name to transfer amount map
237237
const totalAmount: Record<string, BigNumber> = {};
238238
const coinConfig = coins.get(this.getChain());
239-
const { txParams: txParams, txPrebuild: txPrebuild, memo: memo, durableNonce: durableNonce } = params;
239+
const {
240+
txParams: txParams,
241+
txPrebuild: txPrebuild,
242+
memo: memo,
243+
durableNonce: durableNonce,
244+
verification: verificationOptions,
245+
} = params;
240246
const transaction = new Transaction(coinConfig);
241247
const rawTx = txPrebuild.txBase64 || txPrebuild.txHex;
242248
const consolidateId = txPrebuild.consolidateId;
@@ -312,6 +318,37 @@ export class Sol extends BaseCoin {
312318
if (recipientChecks.includes(false)) {
313319
throw new Error('Tx outputs does not match with expected txParams recipients');
314320
}
321+
} else if (verificationOptions?.consolidationToBaseAddress) {
322+
//verify funds are sent to walletRootAddress for a consolidation
323+
const filteredOutputs = explainedTx.outputs.map((output) => _.pick(output, ['address', 'amount', 'tokenName']));
324+
325+
// Cache to store already derived ATA addresses
326+
const ataAddressCache: Record<string, string> = {};
327+
328+
for (const output of filteredOutputs) {
329+
if (output.tokenName) {
330+
// Check cache first before deriving ATA address
331+
if (!ataAddressCache[output.tokenName]) {
332+
const tokenMintAddress = getSolTokenFromTokenName(output.tokenName);
333+
if (tokenMintAddress?.tokenAddress && tokenMintAddress?.programId) {
334+
ataAddressCache[output.tokenName] = await getAssociatedTokenAccountAddress(
335+
tokenMintAddress.tokenAddress,
336+
walletRootAddress as string,
337+
true,
338+
tokenMintAddress.programId
339+
);
340+
} else {
341+
throw new Error(`Unable to get token information for ${output.tokenName}`);
342+
}
343+
}
344+
345+
if (ataAddressCache[output.tokenName] !== output.address) {
346+
throw new Error('tx outputs does not match with expected address');
347+
}
348+
} else if (output.address !== walletRootAddress) {
349+
throw new Error('tx outputs does not match with expected address');
350+
}
351+
}
315352
}
316353

317354
const transactionJson = transaction.toJson();

0 commit comments

Comments
 (0)