@ledgerhq/coin-tron
Version:
Ledger Tron Coin integration
163 lines (121 loc) • 5.36 kB
text/typescript
import BigNumber from "bignumber.js";
import { abiDecodeTrc20Transfer, abiEncodeTrc20Transfer } from "./utils";
describe("abiEncodeTrc20Transfer", () => {
it("encodes large TRC20 amount without precision loss (uint256 beyond 2^53)", () => {
const amount = new BigNumber("1000000000000000000000000000");
const address = "41a614f803b6fd780986a42c78ec9c7f77e6ded13c";
const encoded = abiEncodeTrc20Transfer(address, amount);
const amountHex = encoded.slice(-64);
const decoded = new BigNumber(amountHex, 16);
expect(decoded).toEqual(amount);
});
});
describe("abiDecodeTrc20Transfer", () => {
it("decodes TRC20 transfer data correctly", () => {
const recipientHex = "a614f803b6fd780986a42c78ec9c7f77e6ded13c";
const amount = new BigNumber("1000000");
const data =
"a9059cbb" + recipientHex.padStart(64, "0") + amount.toString(16).padStart(64, "0");
const result = abiDecodeTrc20Transfer(data);
expect(result).not.toBeNull();
expect(result!.to).toBe("41" + recipientHex);
expect(result!.amount).toEqual(amount);
});
it("handles data with 0x prefix", () => {
const recipientHex = "a614f803b6fd780986a42c78ec9c7f77e6ded13c";
const amount = new BigNumber("500000");
const data =
"0xa9059cbb" + recipientHex.padStart(64, "0") + amount.toString(16).padStart(64, "0");
const result = abiDecodeTrc20Transfer(data);
expect(result).not.toBeNull();
expect(result!.amount).toEqual(amount);
});
it("returns null for non-transfer function selector", () => {
const data = "12345678" + "0".repeat(128);
const result = abiDecodeTrc20Transfer(data);
expect(result).toBeNull();
});
it("returns null for data that is too short", () => {
const result = abiDecodeTrc20Transfer("a9059cbb");
expect(result).toBeNull();
});
it("returns null for odd-length hex string", () => {
const recipientHex = "a614f803b6fd780986a42c78ec9c7f77e6ded13c";
const amount = new BigNumber("1000000");
const validData =
"a9059cbb" + recipientHex.padStart(64, "0") + amount.toString(16).padStart(64, "0");
const oddLengthData = validData + "f";
const result = abiDecodeTrc20Transfer(oddLengthData);
expect(result).toBeNull();
});
it("decodes large amounts without precision loss", () => {
const recipientHex = "a614f803b6fd780986a42c78ec9c7f77e6ded13c";
const amount = new BigNumber("1000000000000000000000000000");
const data =
"a9059cbb" + recipientHex.padStart(64, "0") + amount.toString(16).padStart(64, "0");
const result = abiDecodeTrc20Transfer(data);
expect(result).not.toBeNull();
expect(result!.amount).toEqual(amount);
});
it("returns null for data with non-hex characters", () => {
const data = "a9059cbb" + "g".repeat(128);
const result = abiDecodeTrc20Transfer(data);
expect(result).toBeNull();
});
it("returns null for data with special characters", () => {
const data = "a9059cbb" + "0".repeat(60) + "$$$$" + "0".repeat(64);
const result = abiDecodeTrc20Transfer(data);
expect(result).toBeNull();
});
it("returns null for empty string", () => {
const result = abiDecodeTrc20Transfer("");
expect(result).toBeNull();
});
it("decodes zero amount correctly", () => {
const recipientHex = "a614f803b6fd780986a42c78ec9c7f77e6ded13c";
const data = "a9059cbb" + recipientHex.padStart(64, "0") + "0".repeat(64);
const result = abiDecodeTrc20Transfer(data);
expect(result).not.toBeNull();
expect(result!.amount).toEqual(new BigNumber(0));
});
it("handles uppercase selector", () => {
const recipientHex = "a614f803b6fd780986a42c78ec9c7f77e6ded13c";
const amount = new BigNumber("1000000");
const data =
"A9059CBB" + recipientHex.padStart(64, "0") + amount.toString(16).padStart(64, "0");
const result = abiDecodeTrc20Transfer(data);
expect(result).not.toBeNull();
expect(result!.amount).toEqual(amount);
});
it("handles data with extra trailing bytes", () => {
const recipientHex = "a614f803b6fd780986a42c78ec9c7f77e6ded13c";
const amount = new BigNumber("1000000");
const data =
"a9059cbb" +
recipientHex.padStart(64, "0") +
amount.toString(16).padStart(64, "0") +
"deadbeef";
const result = abiDecodeTrc20Transfer(data);
expect(result).not.toBeNull();
expect(result!.amount).toEqual(amount);
});
it("roundtrip encode/decode preserves data", () => {
const address = "a614f803b6fd780986a42c78ec9c7f77e6ded13c";
const amount = new BigNumber("123456789012345678901234567890");
const encoded = "a9059cbb" + abiEncodeTrc20Transfer(address, amount);
const decoded = abiDecodeTrc20Transfer(encoded);
expect(decoded).not.toBeNull();
expect(decoded!.to).toBe("41" + address);
expect(decoded!.amount).toEqual(amount);
});
it("decodes max uint256 value", () => {
const recipientHex = "a614f803b6fd780986a42c78ec9c7f77e6ded13c";
const maxUint256 = new BigNumber(
"115792089237316195423570985008687907853269984665640564039457584007913129639935",
);
const data = "a9059cbb" + recipientHex.padStart(64, "0") + "f".repeat(64);
const result = abiDecodeTrc20Transfer(data);
expect(result).not.toBeNull();
expect(result!.amount).toEqual(maxUint256);
});
});