Skip to content

Commit

Permalink
Merge pull request #3671 from BitGo/avaxc-recovery
Browse files Browse the repository at this point in the history
fix(sdk-coin-avaxc): fix recovery to multisig address
  • Loading branch information
sachushaji authored Jun 19, 2023
2 parents 100dc06 + c1e4504 commit 4287d38
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 12 deletions.
3 changes: 2 additions & 1 deletion modules/sdk-coin-avaxc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
},
"devDependencies": {
"@bitgo/sdk-api": "^1.10.5",
"@bitgo/sdk-test": "^1.2.23"
"@bitgo/sdk-test": "^1.2.23",
"ethers": "^5.1.3"
}
}
12 changes: 2 additions & 10 deletions modules/sdk-coin-avaxc/src/avaxc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
import { isValidEthAddress } from './lib/utils';
import { KeyPair as AvaxcKeyPair, TransactionBuilder } from './lib';
import request from 'superagent';
import { bufferToHex, pubToAddress } from 'ethereumjs-util';
import { pubToAddress } from 'ethereumjs-util';
import { Buffer } from 'buffer';
import {
AvaxSignTransactionOptions,
Expand Down Expand Up @@ -628,13 +628,6 @@ export class AvaxC extends BaseCoin {
gasLimit: gasLimit.toString(10),
};

// calculate send data
const sendMethodArgs = this.getSendMethodArgs(txInfo);
const sendMethodName = 'sendMultiSig';
const methodSignature = optionalDeps.ethAbi.methodID(sendMethodName, _.map(sendMethodArgs, 'type'));
const encodedArgs = optionalDeps.ethAbi.rawEncode(_.map(sendMethodArgs, 'type'), _.map(sendMethodArgs, 'value'));
const sendData = Buffer.concat([methodSignature, encodedArgs]);

const txBuilder = this.getTransactionBuilder() as TransactionBuilder;
txBuilder.counter(backupKeyNonce);
txBuilder.contract(params.walletContractAddress);
Expand All @@ -658,8 +651,7 @@ export class AvaxC extends BaseCoin {
.amount(recipients[0].amount)
.contractSequenceId(sequenceId)
.expirationTime(this.getDefaultExpireTime())
.to(params.recoveryDestination)
.data(bufferToHex(sendData as Buffer));
.to(params.recoveryDestination);

if (isUnsignedSweep) {
const tx = await txBuilder.build();
Expand Down
9 changes: 8 additions & 1 deletion modules/sdk-coin-avaxc/test/unit/avaxc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { AvaxSignTransactionOptions } from '../../src/iface';
import * as should from 'should';
import { EXPORT_C, IMPORT_C } from '../resources/avaxc';
import { TavaxP } from '@bitgo/sdk-coin-avaxp';
import { decodeTransaction, parseTransaction, walletSimpleABI } from './helpers';

nock.enableNetConnect();

Expand Down Expand Up @@ -888,8 +889,14 @@ describe('Avalanche C-Chain', function () {
recoveryDestination,
gasPrice,
});
const parsedTx = parseTransaction(recovery.txHex);

// id and tx will always be different because of expireTime
const decodedSendMultisigCallData = decodeTransaction(JSON.stringify(walletSimpleABI), parsedTx.data);

const safeTransferFromCallData = decodedSendMultisigCallData.args[2];
const safeTransferFromDestination = decodedSendMultisigCallData.args[0];
safeTransferFromDestination.toLowerCase().should.equal(recoveryDestination);
safeTransferFromCallData.should.be.equal('0x');
recovery.should.not.be.undefined();
recovery.should.have.properties('txHex', 'userKey', 'backupKey');
recovery.recipients.length.should.equal(1);
Expand Down
51 changes: 51 additions & 0 deletions modules/sdk-coin-avaxc/test/unit/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { ethers } from 'ethers';

export function decodeTransaction(abi: string, calldata: string): ethers.utils.TransactionDescription {
const contractInterface = new ethers.utils.Interface(abi);
return contractInterface.parseTransaction({ data: calldata });
}

export function parseTransaction(txHex: string): ethers.Transaction {
return ethers.utils.parseTransaction(txHex);
}

export const walletSimpleABI = [
{
inputs: [
{
internalType: 'address',
name: 'toAddress',
type: 'address',
},
{
internalType: 'uint256',
name: 'value',
type: 'uint256',
},
{
internalType: 'bytes',
name: 'data',
type: 'bytes',
},
{
internalType: 'uint256',
name: 'expireTime',
type: 'uint256',
},
{
internalType: 'uint256',
name: 'sequenceId',
type: 'uint256',
},
{
internalType: 'bytes',
name: 'signature',
type: 'bytes',
},
],
name: 'sendMultiSig',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
];

0 comments on commit 4287d38

Please sign in to comment.