Skip to content

Commit 36f08c4

Browse files
committed
fix(sdk-coin-avaxp): stake output cannot be 0
throw error if change output is 0 for permissionless validator tx CR-1073 TICKET: CR-1073
1 parent 0005adc commit 36f08c4

File tree

4 files changed

+34
-1
lines changed

4 files changed

+34
-1
lines changed

modules/sdk-coin-avaxp/src/lib/permissionlessValidatorTxBuilder.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,10 +476,16 @@ export class PermissionlessValidatorTxBuilder extends TransactionBuilder {
476476
stakeOutputs.push(stakeOutput);
477477

478478
if (currentTotal >= totalTarget) {
479+
const changeOutputAmount = currentTotal - totalTarget;
480+
if (changeOutputAmount <= 0) {
481+
throw new BuildTransactionError(
482+
'Change output amount must be greater than 0. Stake less or more to avoid 0 amount in utxo output.'
483+
);
484+
}
479485
const changeOutput = new avaxSerial.TransferableOutput(
480486
assetId,
481487
new TransferOutput(
482-
new BigIntPr(currentTotal - totalTarget),
488+
new BigIntPr(changeOutputAmount),
483489
new OutputOwners(
484490
new BigIntPr(this.transaction._locktime),
485491
new Int(this.transaction._threshold),

modules/sdk-coin-avaxp/test/resources/avaxp.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,7 @@ export const BUILD_AND_SIGN_ADD_PERMISSIONLESS_VALIDATOR_SAMPLE = {
614614
startTime: '1656423398',
615615
endTime: '1659053398',
616616
stakeAmount: '2370000000',
617+
stakeAmountNoOutput: '4097000000',
617618
delegationFeeRate: 10,
618619
nodeId: 'NodeID-2hMqBQdjZMWdHvYu7ZPLA2CmrAdbTvpGf',
619620
blsPublicKey: '0xad9e9476b701edec88e53b1c314456053b3cf846a1192117872e41455f440c074d6ee89530d45e88f79ac0eda06f2887',

modules/sdk-coin-avaxp/test/resources/errors.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ export const ERROR_CHAIN_ID_LENGTH = 'Chain id are 32 byte size';
2727
export const ERROR_KEY_CANNOT_SIGN = 'Private key cannot sign the transaction';
2828

2929
export const ERROR_AMOUNT = 'Amount must be greater than 0';
30+
export const ERROR_CHANGE_AMOUNT =
31+
'Change output amount must be greater than 0. Stake less or more to avoid 0 amount in utxo output.';
3032

3133
export const ERROR_NONCE = 'Nonce must be greater or equal than 0';
3234

modules/sdk-coin-avaxp/test/unit/lib/permissionlessValidatorTxBuilder.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import * as AvaxpLib from '../../../src/lib';
88
import { TransactionBuilderFactory } from '../../../src/lib';
99
import { PermissionlessValidatorTxBuilder } from '../../../src/lib/permissionlessValidatorTxBuilder';
1010
import * as testData from '../../resources/avaxp';
11+
import { ERROR_CHANGE_AMOUNT } from '../../resources/errors';
1112
// import { pvm } from '@bitgo/avalanchejs';
1213

1314
describe('AvaxP permissionlessValidatorTxBuilder', () => {
@@ -298,4 +299,27 @@ describe('AvaxP permissionlessValidatorTxBuilder', () => {
298299
console.log(fullSignedTx.toJson());
299300
});
300301
});
302+
it('Should fail to build if utxos change output 0', async () => {
303+
const unixNow = BigInt(Math.round(new Date().getTime() / 1000));
304+
const startTime = unixNow + BigInt(60);
305+
const endTime = startTime + BigInt(60 * 60 * 24 + 600);
306+
307+
const txBuilder = new AvaxpLib.TransactionBuilderFactory(coins.get('tavaxp'))
308+
.getPermissionlessValidatorTxBuilder()
309+
.threshold(testData.BUILD_AND_SIGN_ADD_PERMISSIONLESS_VALIDATOR_SAMPLE.threshold)
310+
.locktime(testData.BUILD_AND_SIGN_ADD_PERMISSIONLESS_VALIDATOR_SAMPLE.locktime)
311+
.recoverMode(false)
312+
.fromPubKey(testData.BUILD_AND_SIGN_ADD_PERMISSIONLESS_VALIDATOR_SAMPLE.bitgoAddresses)
313+
.startTime(startTime.toString())
314+
.endTime(endTime.toString())
315+
.stakeAmount(testData.BUILD_AND_SIGN_ADD_PERMISSIONLESS_VALIDATOR_SAMPLE.stakeAmountNoOutput)
316+
.delegationFeeRate(testData.BUILD_AND_SIGN_ADD_PERMISSIONLESS_VALIDATOR_SAMPLE.delegationFeeRate)
317+
.nodeID(testData.BUILD_AND_SIGN_ADD_PERMISSIONLESS_VALIDATOR_SAMPLE.nodeId)
318+
.blsPublicKey(testData.BUILD_AND_SIGN_ADD_PERMISSIONLESS_VALIDATOR_SAMPLE.blsPublicKey)
319+
.blsSignature(testData.BUILD_AND_SIGN_ADD_PERMISSIONLESS_VALIDATOR_SAMPLE.blsSignature)
320+
.utxos(testData.BUILD_AND_SIGN_ADD_PERMISSIONLESS_VALIDATOR_SAMPLE.utxos);
321+
await txBuilder.build().catch((error) => {
322+
assert(error.message === ERROR_CHANGE_AMOUNT);
323+
});
324+
});
301325
});

0 commit comments

Comments
 (0)