Skip to content

fix(evm): only treat 3-topic logs as in-contract transfers (follow-up to #4844)#4852

Open
guo wants to merge 1 commit into
masterfrom
fix/evm-incontract-transfer-topic-guard
Open

fix(evm): only treat 3-topic logs as in-contract transfers (follow-up to #4844)#4852
guo wants to merge 1 commit into
masterfrom
fix/evm-incontract-transfer-topic-guard

Conversation

@guo

@guo guo commented Jun 7, 2026

Copy link
Copy Markdown
Member

Summary

Follow-up hardening to #4844. StateDBAdapter.AddLog still calls
log.Panic("Invalid in contract transfer topics") when a log's first topic
equals the in-contract-transfer sentinel but the topic count is not exactly 3.

_inContractTransfer is hash.BytesToHash256([]byte{byte(IN_CONTRACT_TRANSFER)}),
i.e. the all-zero topic, and log topics are EVM-controlled. #4844 added a
len(topics) > 0 guard that removed the empty-topic (LOG0) index-out-of-range,
but a 1- or 2-topic log whose first topic is all-zero still enters the branch and
hits the len != 3 panic.

Genuine in-contract transfers are always emitted by the protocol with exactly
three topics (type, from, to), so the correct guard is to enter the special
handling only when len(topics) == 3. Any other shape is an ordinary log and is
appended as such. This removes the remaining panic without changing behavior for
real in-contract-transfer logs or for any normal log (real event signatures are
non-zero keccak hashes, so honest traffic never carries an all-zero first topic).

Change

  • AddLog: gate the in-contract-transfer handling on
    len(topics) == 3 && topics[0] == _inContractTransfer; drop the now-dead
    len != 3 panic. Malformed shapes fall through to the normal log append.

Test

  • Added TestAddLogInContractTransferTopicShape: asserts AddLog does not panic
    on a 1-topic log whose topic0 is the sentinel (recorded as a normal log), and
    that a well-formed 3-topic in-contract transfer is still recorded as a
    transaction log with the correct sender/recipient.
  • go test ./action/protocol/execution/evm/ -race — full package passes.

🤖 Generated with Claude Code

AddLog still called log.Panic("Invalid in contract transfer topics") when a
log's first topic matched the in-contract-transfer sentinel but the topic
count was not exactly 3. _inContractTransfer is the all-zero topic and log
topics are EVM-controlled, so a 1- or 2-topic log with an all-zero first
topic reached that branch and panicked. #4844 added a len(topics) > 0 guard
that removed the empty-topic index-out-of-range, but left the len != 3 panic
on the 1-/2-topic shape.

Genuine in-contract transfers are always emitted with exactly three topics
(type, from, to), so gate the special-casing on len(topics) == 3; any other
shape is an ordinary log and is appended as such. This removes the remaining
panic without changing behavior for real in-contract-transfer logs or for
any normal log.

Add a regression test covering both the malformed-shape and well-formed paths.
@guo guo requested a review from a team as a code owner June 7, 2026 16:42
@guo guo requested review from CoderZhi and envestcc June 7, 2026 16:42
@sonarqubecloud

sonarqubecloud Bot commented Jun 7, 2026

Copy link
Copy Markdown

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