feat(exit-certificate): Step B2/B3 - ERC-20 detection and extra contract holder decomposition#1632
Conversation
Raise the default Step A trace window from 5000 to 150000 blocks to reduce the number of RPC round-trips when collecting addresses via debug_traceTransaction on chains with large block ranges. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…t holder decomposition - Add Step B2: probes contract addresses for the ERC-20 interface and detects which tracked wrapped tokens each contract holds. - Add Step B3: iterates over options.extraErc20Contracts, reusing B2 holder data when available or calling balanceOf for every EOA. - Extend Step C to incorporate SC-locked values from B2 detected ERC-20s. - Extend Step D to generate BridgeExit entries for ERC-20-locked balances. - Update run.go pipeline to execute B2 and B3 between B and C. - Add types, RPC helpers, tests, docs and example config for the new steps. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Claude finished @joanestebanr's task in 1m 41s —— View job ✅ Code Review Complete🚀 What's NewThis PR implements Steps B2 and B3 for the exit certificate tool, enabling:
🐛 Bug FixesNone — this PR is purely additive functionality. 📋 Config Updates{
"options": {
"stepAWindowSize": 150000, // Default increased from 5,000
"extraErc20Contracts": [ // New optional field
"0xTokenAddress1",
"0xTokenAddress2"
]
}
}Defaults:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ad4fcfe431
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| breakdowns = append(breakdowns, ERC20HolderBreakdown{ | ||
| Address: addr, | ||
| Holders: holders, | ||
| Detected: b2Detected[addr], // nil when not in B2 detected list | ||
| }) |
There was a problem hiding this comment.
Populate collateral for extra ERC-20s missing from B2
When extraErc20Contracts contains a vault/staking token that was not part of the Step B1 contract list (for example, a passive ERC-20 holder whose account was not touched by traced transactions), b2Detected[addr] is nil here. Step C skips every breakdown with Detected == nil, so the holder balances fetched in B3 are never converted into holder bridge exits and the value remains routed to the generic exit address. B3 should fetch/attach the wrapped-token holdings for configured contracts that B2 did not detect, or include those contracts in the B2 probe.
Useful? React with 👍 / 👎.
- Add missing fields to parameters.json.example: sovereignRollupAddr, l1GlobalExitRootAddress, stepAWindowSize, continueOnTraceError, abortOnGenesisBalance, ignoreUnclaimed, continueIfBalanceMismatch, bridgeServiceURL/Type, agglayerClient, agglayerAdminURL/Token. Replace legacy signerKeyPath/signerKeyPassword with signerConfig. - Fix extraERC20Contracts → extraErc20Contracts (correct JSON key) in zkevm-mainnet.json and zkevm-cardona.json. - Add l1GlobalExitRootAddress and continueIfBalanceMismatch to both zkevm-mainnet.json and zkevm-cardona.json. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Update TestLoadConfig_DefaultOptions to expect defaultStepAWindowSize=150000 - Update TestParseStepList: b alias and b-ranges now include b3 - Fix stale comment in parseStepList (b → b1/b2/b3) - gci: fix import ordering in config.go, integration_test.go, step_b2_test.go - mnd: replace magic number 3 with eip1474RevertCode constant in rpc.go - lll: shorten log line in step_b.go - unparam: remove silent/tokenLabel params from checkWrappedTokenBalances - goconst: extract eth_call/eth_getBalance as constants in step_b2_test.go Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
web3security
left a comment
There was a problem hiding this comment.
LGTM my only comment is that in case we finally decide to distributed WETH as ERC20 tokens individually, we should anyway add it since the beginning to avoid adding it after the process started by mistake. Thanks!
🔄 Changes Summary
totalSupply/balanceOf). Classifies contracts asDetectedERC20(holds ≥1 tracked wrapped token) orDiscardedERC20. Outputsstep-b2-detected-erc20s.jsonandstep-b2-discarded-erc20s.json.options.extraErc20Contracts. Reuses B2 holder data when available; otherwise callsbalanceOffor every EOA from Step A. Outputsstep-b3-erc20-holders.json.BridgeExitentries for ERC-20-locked balances from B2/B3.extraErc20Contractsoption; increaseddefaultStepAWindowSizefrom 5 000 to 150 000.run.go) updated to execute B2 and B3 between B and C.options.extraErc20Contracts(array of addresses). No breaking change — defaults to empty.📋 Config Updates
✅ Testing
step_b2_test.go) and Step B3 (step_b3_test.go); Step C tests extended.extraErc20Contractspopulated and verifystep-b2-detected-erc20s.json,step-b3-erc20-holders.jsonoutputs.🐞 Issues
📝 Notes
extraErc20Contractsis empty — no RPC calls made.defaultStepAWindowSizeraised to 150 000 to reduce RPC round-trips on chains with large block ranges.