Skip to content

Commit ecbf8e4

Browse files
committed
fix: add coverage for HBAR transfers to zero address and reserved system accounts
Signed-off-by: Logan Nguyen <[email protected]>
1 parent e3a961b commit ecbf8e4

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed

packages/server/tests/acceptance/rpc_batch1.spec.ts

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,116 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () {
987987
await Assertions.assertPredefinedRpcError(error, sendRawTransaction, true, relay, [signedTx, requestDetails]);
988988
});
989989

990+
it('@xts should fail "eth_sendRawTransaction" for HBAR crypto transfer to zero addresses', async function () {
991+
const sendHbarTx = {
992+
...defaultLegacyTransactionData,
993+
value: ONE_TINYBAR,
994+
to: ethers.ZeroAddress,
995+
nonce: await relay.getAccountNonce(accounts[0].address),
996+
gasPrice: await relay.gasPrice(),
997+
};
998+
999+
const signedSendHbarTx = await accounts[0].wallet.signTransaction(sendHbarTx);
1000+
const error = predefined.INTERNAL_ERROR('Transaction execution returns a null value');
1001+
1002+
await Assertions.assertPredefinedRpcError(error, sendRawTransaction, true, relay, [
1003+
signedSendHbarTx,
1004+
requestDetails,
1005+
]);
1006+
});
1007+
1008+
it('@xts should reject eth_sendRawTransaction requests for HBAR crypto transfers to reserved system account addresses (accounts ≤ 0.0.750) with INVALID_CONTRACT_ID.', async function () {
1009+
// https://github.com/hiero-ledger/hiero-consensus-node/blob/main/hedera-node/docs/system-accounts-operations.md
1010+
const hederaSystemAccounts = [
1011+
// system accounts
1012+
'0x0000000000000000000000000000000000000002', // 0.0.2 treasury
1013+
'0x0000000000000000000000000000000000000003', // 0.0.3
1014+
'0x0000000000000000000000000000000000000032', // 0.0.50 system admin
1015+
'0x0000000000000000000000000000000000000037', // 0.0.55 address book admin
1016+
'0x0000000000000000000000000000000000000039', // 0.0.57 exchange rates admin
1017+
'0x000000000000000000000000000000000000003a', // 0.0.58 freeze admin
1018+
'0x000000000000000000000000000000000000003b', // 0.0.59 system delete admin
1019+
'0x000000000000000000000000000000000000003c', // 0.0.60 system undelete admin
1020+
1021+
// system contracts (precompiles)
1022+
'0x0000000000000000000000000000000000000167', // 0.0.359 HTS
1023+
'0x0000000000000000000000000000000000000168', // 0.0.360 Exchange Rate
1024+
'0x0000000000000000000000000000000000000169', // 0.0.361 PRNG
1025+
'0x000000000000000000000000000000000000016a', // 0.0.362 HAS
1026+
1027+
// non-existent accounts
1028+
'0x00000000000000000000000000000000000001C2', // 0.0.450
1029+
'0x00000000000000000000000000000000000001FE', // 0.0.510
1030+
'0x00000000000000000000000000000000000002EE', // 0.0.750
1031+
];
1032+
1033+
for (const address of hederaSystemAccounts) {
1034+
const sendHbarTx = {
1035+
...defaultLegacyTransactionData,
1036+
value: ONE_TINYBAR,
1037+
to: address,
1038+
nonce: await relay.getAccountNonce(accounts[0].address),
1039+
gasPrice: await relay.gasPrice(),
1040+
};
1041+
1042+
const signedSendHbarTx = await accounts[0].wallet.signTransaction(sendHbarTx);
1043+
const txHash = await relay.sendRawTransaction(signedSendHbarTx);
1044+
const txReceipt = await relay.pollForValidTransactionReceipt(txHash);
1045+
1046+
expect(txReceipt.revertReason).to.not.be.null;
1047+
expect(txReceipt.revertReason).to.not.be.empty;
1048+
expect(Buffer.from((txReceipt.revertReason as string).slice(2), 'hex').toString('utf8')).to.equal(
1049+
'INVALID_CONTRACT_ID',
1050+
);
1051+
}
1052+
});
1053+
1054+
it('@xts should validate HBAR transfers to reserved system accounts based on account existence for accounts from 0.0.750 to 0.0.999', async function () {
1055+
const hederaSystemAccounts = [
1056+
// non-existent accounts
1057+
'0x00000000000000000000000000000000000002f1', // 0.0.753
1058+
'0x000000000000000000000000000000000000032A', // 0.0.810
1059+
1060+
// system accounts
1061+
'0x0000000000000000000000000000000000000320', // 0.0.800 staking reward account;
1062+
'0x0000000000000000000000000000000000000321', // 0.0.801 node reward account
1063+
1064+
// existent accounts
1065+
'0x00000000000000000000000000000000000003A2', // 0.0.930
1066+
'0x00000000000000000000000000000000000003A2', // 0.0.960
1067+
'0x00000000000000000000000000000000000003A2', // 0.0.999
1068+
];
1069+
1070+
for (const address of hederaSystemAccounts) {
1071+
const sendHbarTx = {
1072+
...defaultLegacyTransactionData,
1073+
value: ONE_TINYBAR,
1074+
to: address,
1075+
nonce: await relay.getAccountNonce(accounts[0].address),
1076+
gasPrice: await relay.gasPrice(),
1077+
};
1078+
1079+
const signedSendHbarTx = await accounts[0].wallet.signTransaction(sendHbarTx);
1080+
const txHash = await relay.sendRawTransaction(signedSendHbarTx);
1081+
const txReceipt = await relay.pollForValidTransactionReceipt(txHash);
1082+
1083+
// Crypto Transfers are successful if accounts exist
1084+
try {
1085+
const accountInfo = await global.mirrorNode.get(`/accounts/${address}`);
1086+
expect(accountInfo).to.exist;
1087+
expect(txReceipt.status).to.equal('0x1');
1088+
expect(txReceipt.revertReason).to.be.undefined;
1089+
} catch (error) {
1090+
expect(error.status).to.equal(404);
1091+
expect(txReceipt.revertReason).to.not.be.null;
1092+
expect(txReceipt.revertReason).to.not.be.empty;
1093+
expect(Buffer.from((txReceipt.revertReason as string).slice(2), 'hex').toString('utf8')).to.equal(
1094+
'INVALID_ALIAS_KEY',
1095+
);
1096+
}
1097+
}
1098+
});
1099+
9901100
it('@xts should execute "eth_sendRawTransaction" for deterministic deployment transaction', async function () {
9911101
// send gas money to the proxy deployer
9921102
const sendHbarTx = {

0 commit comments

Comments
 (0)