diff --git a/modules/bitgo/test/v2/unit/recovery.ts b/modules/bitgo/test/v2/unit/recovery.ts index fc1b0b8d9a..3389819e51 100644 --- a/modules/bitgo/test/v2/unit/recovery.ts +++ b/modules/bitgo/test/v2/unit/recovery.ts @@ -277,8 +277,8 @@ describe('Recovery:', function () { should.exist(recoveryTx); recoveryTx.coin.should.equal('ttrx'); - recoveryTx.feeInfo.fee.should.equal('1000000'); - recoveryTx.recoveryAmount.should.equal(900147400); + recoveryTx.feeInfo.fee.should.equal('2100000'); + recoveryTx.recoveryAmount.should.equal(899047400); recoveryTx.txHex.should.equal( '{"visible":false,"txID":"98b398e3027e601870a86b0785f1f1d301f087dbaafe44337507b5001bae0d49","raw_data":{"contract":[{"parameter":{"value":{"amount":10000000,"owner_address":"41e7e11df2c5704888c3cb63fb43a9498bd1812cb2","to_address":"41f5f414d447aafe70bb9b9d93912cbc4c54f0c014"},"type_url":"type.googleapis.com/protocol.TransferContract"},"type":"TransferContract"}],"ref_block_bytes":"a762","ref_block_hash":"18dfe946fbf7a0ac","expiration":1676746443000,"timestamp":1676659983799},"raw_data_hex":"0a02a762220818dfe946fbf7a0ac40f89181afe6305a69080112650a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412340a1541e7e11df2c5704888c3cb63fb43a9498bd1812cb2121541f5f414d447aafe70bb9b9d93912cbc4c54f0c01418c8d19cad0370b78be485e630","signature":["79a110116657e75be81400ad4a9f738fd098695fc5fc6009176aa1c27924c4cdb2989fe2052b70c739b10cd3881c9872660b83998dc9316e6c8d11fb588d731d00","250d0bae2491596bd800d830aa9d4c6d25e1d01a4c860b856d6000a8ab8fa2082a1ae20168e0ab97c9ffd64824b483b9843db74e9553d5d9e68a3a64d414dd1201"]}' ); @@ -311,8 +311,8 @@ describe('Recovery:', function () { should.exist(recoveryTx); recoveryTx.coin.should.equal('ttrx'); - recoveryTx.feeInfo.fee.should.equal('1000000'); - recoveryTx.recoveryAmount.should.equal(199000000); + recoveryTx.feeInfo.fee.should.equal('2100000'); + recoveryTx.recoveryAmount.should.equal(197900000); recoveryTx.addressInfo.address.should.equal('TNeGpwAurk7kjQLdcdWhFr8YP8E9Za8w1x'); recoveryTx.addressInfo.chain.should.equal(0); recoveryTx.addressInfo.index.should.equal(1); @@ -359,8 +359,8 @@ describe('Recovery:', function () { should.exist(recoveryTx); recoveryTx.coin.should.equal('ttrx'); - recoveryTx.feeInfo.fee.should.equal('1000000'); - recoveryTx.recoveryAmount.should.equal(900147400); + recoveryTx.feeInfo.fee.should.equal('2100000'); + recoveryTx.recoveryAmount.should.equal(899047400); recoveryTx.tx.txID.should.equal('98b398e3027e601870a86b0785f1f1d301f087dbaafe44337507b5001bae0d49'); recoveryTx.tx.raw_data_hex.should.equal( '0a02a762220818dfe946fbf7a0ac40f89181afe6305a69080112650a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412340a1541e7e11df2c5704888c3cb63fb43a9498bd1812cb2121541f5f414d447aafe70bb9b9d93912cbc4c54f0c01418c8d19cad0370b78be485e630' @@ -383,8 +383,8 @@ describe('Recovery:', function () { should.exist(recoveryTx); recoveryTx.coin.should.equal('ttrx'); - recoveryTx.feeInfo.fee.should.equal('1000000'); - recoveryTx.recoveryAmount.should.equal(900147400); + recoveryTx.feeInfo.fee.should.equal('2100000'); + recoveryTx.recoveryAmount.should.equal(899047400); recoveryTx.tx.txID.should.equal('98b398e3027e601870a86b0785f1f1d301f087dbaafe44337507b5001bae0d49'); recoveryTx.tx.raw_data_hex.should.equal( '0a02a762220818dfe946fbf7a0ac40f89181afe6305a69080112650a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412340a1541e7e11df2c5704888c3cb63fb43a9498bd1812cb2121541f5f414d447aafe70bb9b9d93912cbc4c54f0c01418c8d19cad0370b78be485e630' diff --git a/modules/sdk-coin-trx/src/trx.ts b/modules/sdk-coin-trx/src/trx.ts index 1cfd18e7c6..dd2da9c034 100644 --- a/modules/sdk-coin-trx/src/trx.ts +++ b/modules/sdk-coin-trx/src/trx.ts @@ -33,6 +33,7 @@ import { TransactionReceipt } from './lib/iface'; import { isInteger, isUndefined } from 'lodash'; export const MINIMUM_TRON_MSIG_TRANSACTION_FEE = 1e6; +export const SAFE_TRON_TRANSACTION_FEE = 2.1 * 1e6; // TRON foundation recommends 2.1 TRX as fees for guaranteed transaction export const RECOVER_TRANSACTION_EXPIRY = 86400000; // 24 hour export interface TronSignTransactionOptions extends SignTransactionOptions { @@ -616,7 +617,7 @@ export class Trx extends BaseCoin { // call the node to get our account balance const accountInfo = await this.getAccountBalancesFromNode(address); - if (accountInfo.data[0] && accountInfo.data[0].balance > MINIMUM_TRON_MSIG_TRANSACTION_FEE) { + if (accountInfo.data[0] && accountInfo.data[0].balance > SAFE_TRON_TRANSACTION_FEE) { account = accountInfo; recoveryAmount = accountInfo.data[0].balance; userXPrv = userKey.toBase58(); // assign derived userXPrx @@ -692,10 +693,10 @@ export class Trx extends BaseCoin { ); } } - // construct the tx - - // there's an assumption here being made about fees: for a wallet that hasn't been used in awhile, the implication is - // it has maximum bandwidth. thus, a recovery should cost the minimum amount (1e6 sun or 1 Tron) - if (!recoveryAmount || MINIMUM_TRON_MSIG_TRANSACTION_FEE > recoveryAmount) { + + // a sweep potentially needs to pay for multi-sig transfer, destination account activation and bandwidth + // TRON foundation recommends 2.1 TRX for guaranteed confirmation + if (!recoveryAmount || SAFE_TRON_TRANSACTION_FEE > recoveryAmount) { throw new Error('Amount of funds to recover wouldnt be able to fund a send'); } @@ -731,7 +732,7 @@ export class Trx extends BaseCoin { }; } - const recoveryAmountMinusFees = recoveryAmount - MINIMUM_TRON_MSIG_TRANSACTION_FEE; + const recoveryAmountMinusFees = recoveryAmount - SAFE_TRON_TRANSACTION_FEE; const buildTx = await this.getBuildTransaction(recoveryAddressHex, accountToRecoverAddr, recoveryAmountMinusFees); // construct our tx @@ -743,7 +744,7 @@ export class Trx extends BaseCoin { // this tx should be enough to drop into a node if (isUnsignedSweep) { - return this.formatForOfflineVault(tx, MINIMUM_TRON_MSIG_TRANSACTION_FEE, recoveryAmountMinusFees, addressInfo); + return this.formatForOfflineVault(tx, SAFE_TRON_TRANSACTION_FEE, recoveryAmountMinusFees, addressInfo); } const userPrv = this.xprvToCompressedPrv(userXPrv); @@ -758,12 +759,7 @@ export class Trx extends BaseCoin { txBuilder.sign({ key: backupPrv }); } const txSigned = await txBuilder.build(); - return this.formatForOfflineVault( - txSigned, - MINIMUM_TRON_MSIG_TRANSACTION_FEE, - recoveryAmountMinusFees, - addressInfo - ); + return this.formatForOfflineVault(txSigned, SAFE_TRON_TRANSACTION_FEE, recoveryAmountMinusFees, addressInfo); } /**