Skip to content

fix(evm): reject overflow Amount in CheckTx under ForkEVMFixOverflow - #1306

Closed
vipwzw wants to merge 1 commit into
masterfrom
fix-evm-checktx-amount
Closed

fix(evm): reject overflow Amount in CheckTx under ForkEVMFixOverflow#1306
vipwzw wants to merge 1 commit into
masterfrom
fix-evm-checktx-amount

Conversation

@vipwzw

@vipwzw vipwzw commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

Problem

EVMContractAction.Amount is uint64, but the underlying chain33 account system uses int64. Amount > math.MaxInt64 wraps to a negative value downstream — the root cause of the fake msg.value attack (0-balance fake deposit draining real funds from bank-style contracts).

ForkEVMFixOverflow (d4ef8c1) already protects the exec layer (CanTransfer rejects overflow, Call/Create revert on Transfer failure, token precompile guarded, transfer-only path guarded). However, CheckTx still performs no amount validation (EvmType.Amount always returns 0, so framework-level checks see nothing), letting such transactions into the mempool and into blocks where they only fail at execution.

Fix

Under ForkEVMFixOverflow, CheckTx now decodes the action and rejects Amount > math.MaxInt64 with types.ErrAmount, so overflow transactions are refused at the mempool / block-check boundary too. Since chain33 runs CheckTx during block execution as well, this keeps malicious txs out of blocks entirely on fork-active chains.

Pre-fork behavior is intentionally unchanged (consensus compatibility).

Tests

New TestCheckTxRejectsAmountOverflow:

  • post-fork: MaxUint64 and MaxInt64+1 rejected with ErrAmount
  • post-fork: MaxInt64, 1e8, 0 accepted
  • pre-fork: MaxUint64 still accepted by CheckTx (historical behavior; exec-layer gate handles it there)

go test -ldflags=-checklinkname=0 ./plugin/dapp/evm/executor/ — all pass (including the existing TestWBTYOverflowAttackIntegration).

EVMContractAction.Amount is uint64 while the underlying account system
uses int64. The ForkEVMFixOverflow gate already protects the exec layer
(CanTransfer/Transfer/Call/Create), but CheckTx still lets such txs into
the mempool and into blocks, where they only fail at execution.

Reject Amount > math.MaxInt64 at CheckTx under the same fork, so the
fake msg.value attack vector is refused at the mempool/block-check
boundary as well. Pre-fork behavior is unchanged.

Adds TestCheckTxRejectsAmountOverflow covering: MaxUint64 and
MaxInt64+1 rejected post-fork, MaxInt64/1e8/0 accepted post-fork, and
pre-fork historical behavior preserved.
@vipwzw

vipwzw commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator Author

执行层已经做了拦截(ForkEVMFixOverflow:CanTransfer 的 MaxInt64 守卫、Call/Create 与 transfer-only 路径的 Transfer 返回值检查、token 预编译的 IsInt64 守卫),资金安全已有保障,CheckTx 这个位置不需要额外做拦截。先关闭该 PR。

@vipwzw vipwzw closed this Aug 25, 2026
@vipwzw

vipwzw commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator Author

testnode 全链路验证补充(master, ForkEVMFixOverflow 默认生效):伪充值交易 Amount=MaxUint64 在执行层被 fork gate 拦截后不会上链(QueryTx → tx not exist),攻击者仅损失部署 gas,evm 执行器账户余额为 0,无资金损失可复现。复现测试:plugin-worktrees/master-evm-check 下 plugin/dapp/evm/executor/fake_deposit_testnode_test.go(TestMasterEvmFakeDepositNoFundLoss, PASS)。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant