diff --git a/.changeset/giant-guests-refuse.md b/.changeset/giant-guests-refuse.md new file mode 100644 index 000000000000..8df69de2eed5 --- /dev/null +++ b/.changeset/giant-guests-refuse.md @@ -0,0 +1,5 @@ +--- +"@ledgerhq/coin-evm": patch +--- + +return error when tx from tokenAccount has no amount diff --git a/libs/coin-evm/src/__tests__/unit/getTransactionStatus.unit.test.ts b/libs/coin-evm/src/__tests__/unit/getTransactionStatus.unit.test.ts index 883914c1099d..3d19e7540a56 100644 --- a/libs/coin-evm/src/__tests__/unit/getTransactionStatus.unit.test.ts +++ b/libs/coin-evm/src/__tests__/unit/getTransactionStatus.unit.test.ts @@ -177,11 +177,10 @@ describe("EVM Family", () => { expect(res.errors).toEqual({}); }); - it("should detect tx without amount (because of useAllAmount) but from tokenAccount and not return error", async () => { + it("should detect tx without amount from tokenAccount and return error", async () => { const tx = { ...eip1559Tx, amount: new BigNumber(0), - useAllAmount: true, subAccountId: tokenAccount.id, }; const res = await getTransactionStatus( @@ -198,7 +197,11 @@ describe("EVM Family", () => { tx, ); - expect(res.errors).toEqual({}); + expect(res.errors).toEqual( + expect.objectContaining({ + amount: new AmountRequired(), + }), + ); }); it("should detect account not having enough balance for a tx and have an error", async () => { diff --git a/libs/coin-evm/src/getTransactionStatus.ts b/libs/coin-evm/src/getTransactionStatus.ts index 13dae54534db..7d0bdb50c389 100644 --- a/libs/coin-evm/src/getTransactionStatus.ts +++ b/libs/coin-evm/src/getTransactionStatus.ts @@ -90,11 +90,17 @@ const validateAmount = ( const warnings: ValidationIssues = {}; const isTokenTransaction = account?.type === "TokenAccount"; - const isSmartContractInteraction = isTokenTransaction || transaction.data; // if the transaction is a smart contract interaction, it's normal that transaction has no amount - const transactionHasFees = - legacyTransactionHasFees(transaction as EvmTransactionLegacy) || - eip1559TransactionHasFees(transaction as EvmTransactionEIP1559); - const canHaveZeroAmount = isSmartContractInteraction && transactionHasFees; + const isSmartContractInteraction = !!transaction.data; + + /** + * A transaction can have no amount if: + * - it's a smart contract interaction not crafted by the Live + * (i.e: data coming from a third party using Wallet-API for example) + * OR + * - it's an NFT transaction + * (since for an NFT transaction, the "amount" is under the `nft.quantity` property) + */ + const canHaveZeroAmount = isSmartContractInteraction && !isTokenTransaction; // if no amount or 0 if ((!transaction.amount || transaction.amount.isZero()) && !canHaveZeroAmount) {