Skip to content

Commit 92460c3

Browse files
fix(sdk-coin-sol): cannot blind sing enablemenet sol tokens
TICKET: WP-5744
1 parent 16b178d commit 92460c3

File tree

3 files changed

+517
-10
lines changed

3 files changed

+517
-10
lines changed

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

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import BigNumber from 'bignumber.js';
66
import * as base58 from 'bs58';
77

88
import {
9+
AuditDecryptedKeyParams,
910
BaseBroadcastTransactionOptions,
1011
BaseBroadcastTransactionResult,
1112
BaseCoin,
@@ -27,9 +28,13 @@ import {
2728
MPCTx,
2829
MPCTxs,
2930
MPCUnsignedTx,
31+
MultisigType,
32+
multisigTypes,
3033
OvcInput,
3134
OvcOutput,
3235
ParsedTransaction,
36+
PopulatedIntent,
37+
PrebuildTransactionWithIntentOptions,
3338
PresignTransactionOptions,
3439
PublicKey,
3540
RecoveryTxRequest,
@@ -40,14 +45,10 @@ import {
4045
TransactionRecipient,
4146
VerifyAddressOptions,
4247
VerifyTransactionOptions,
43-
MultisigType,
44-
multisigTypes,
45-
AuditDecryptedKeyParams,
46-
PopulatedIntent,
47-
PrebuildTransactionWithIntentOptions,
4848
} from '@bitgo/sdk-core';
4949
import { auditEddsaPrivateKey, getDerivationPath } from '@bitgo/sdk-lib-mpc';
5050
import { BaseNetwork, CoinFamily, coins, BaseCoin as StaticsBaseCoin } from '@bitgo/statics';
51+
import { TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from '@solana/spl-token';
5152
import * as _ from 'lodash';
5253
import * as request from 'superagent';
5354
import { KeyPair as SolKeyPair, Transaction, TransactionBuilder, TransactionBuilderFactory } from './lib';
@@ -60,7 +61,6 @@ import {
6061
isValidPublicKey,
6162
validateRawTransaction,
6263
} from './lib/utils';
63-
import { TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from '@solana/spl-token';
6464

6565
export const DEFAULT_SCAN_FACTOR = 20; // default number of receive addresses to scan for funds
6666

@@ -173,6 +173,8 @@ export interface SolConsolidationRecoveryOptions extends MPCConsolidationRecover
173173
}
174174

175175
const HEX_REGEX = /^[0-9a-fA-F]+$/;
176+
const BLIND_SIGNING_TX_TYPES_TO_CHECK = { enabletoken: 'AssociatedTokenAccountInitialization' };
177+
const BLIND_SIGNING_TX_TYPES_WITH_EMPTY_OUTPUTS = ['enabletoken'];
176178

177179
export class Sol extends BaseCoin {
178180
protected readonly _staticsCoin: Readonly<StaticsBaseCoin>;
@@ -233,6 +235,32 @@ export class Sol extends BaseCoin {
233235
return Math.pow(10, this._staticsCoin.decimalPlaces);
234236
}
235237

238+
verifyTxType(expectedTypeFromUserParams: string | undefined, actualTypeFromDecoded: string | undefined): void {
239+
// do nothing, let the tx fail way down as always
240+
if (expectedTypeFromUserParams === undefined || actualTypeFromDecoded === undefined) return;
241+
242+
// ex: user param comes with 'enabletoken' included in BLIND SIGNING -> if fails later in the IF check
243+
// ex: user param comes with 'transfer' non included in BLIND SIGNING-> correctPrebuildTxType goes undefined and IF later goes false so it pass
244+
// check the unit tests for this.
245+
const correctPrebuildTxType = BLIND_SIGNING_TX_TYPES_TO_CHECK[expectedTypeFromUserParams];
246+
247+
if (correctPrebuildTxType && correctPrebuildTxType !== actualTypeFromDecoded) {
248+
throw new Error(
249+
`Tx type "${actualTypeFromDecoded}" does not match expected txParams type "${expectedTypeFromUserParams}"`
250+
);
251+
}
252+
}
253+
254+
verifyNoOutputs(expectedTypeFromUserParams: string | undefined, decodedTxHex: TransactionExplanation): void {
255+
if (
256+
expectedTypeFromUserParams &&
257+
BLIND_SIGNING_TX_TYPES_WITH_EMPTY_OUTPUTS.includes(expectedTypeFromUserParams) &&
258+
decodedTxHex.outputs?.length > 0
259+
) {
260+
throw new Error(`Tx outputs were found when none were expected for sol enablement tokens`);
261+
}
262+
}
263+
236264
async verifyTransaction(params: SolVerifyTransactionOptions): Promise<boolean> {
237265
// asset name to transfer amount map
238266
const totalAmount: Record<string, BigNumber> = {};
@@ -261,6 +289,9 @@ export class Sol extends BaseCoin {
261289
transaction.fromRawTransaction(rawTxBase64);
262290
const explainedTx = transaction.explainTransaction();
263291

292+
this.verifyNoOutputs(txParams.type, explainedTx);
293+
this.verifyTxType(txParams.type, explainedTx.type);
294+
264295
// users do not input recipients for consolidation requests as they are generated by the server
265296
if (txParams.recipients !== undefined) {
266297
const filteredRecipients = txParams.recipients?.map((recipient) =>

0 commit comments

Comments
 (0)