Conversation
…#513) Co-authored-by: Wei Lin <wei@avaprotocol.org>
Co-authored-by: Wei Lin <wei@avaprotocol.org>
Co-authored-by: Wei Lin <wei@avaprotocol.org>
Co-authored-by: Wei Lin <wei@avaprotocol.org>
|
@claude, review this PR |
|
Claude finished @chrisli30's task in 3m 43s —— View job PR Review: fix: Tenderly state overrides for simulation balance propagation
SummaryThis PR bundles four distinct fixes. The simulation state injection for ERC20 Transfer triggers is the most substantial piece of new infrastructure; the JWT audience fix and loop partial-failure reporting are well-motivated corrections. The summarization fallback is a clean improvement. Overall the approach is sound. There are several items below worth addressing before merge. Issues Found1. Logic bug: non-zero balance falls through to an error, not the reference-holder probe
The comment at line 227 says Fix: restructure so the reference-holder probe runs any time the direct probe fails, regardless of balance: // After the primary probe fails, try reference holders unconditionally
// (for zero-balance holders AND for non-standard layouts).2. Excessive
|
Code ReviewOverall this is solid, well-structured work with good test coverage. A few issues worth addressing before merge. Bugs / Correctness1. Partial iteration failure detection is broken when
if iterationFailCount > 0 && firstError != nil {If per-iteration runner errors don't propagate into 2.
// ETH path — nil guarded ✓
if vm.smartWalletConfig != nil && vm.smartWalletConfig.EthRpcUrl != "" {
// ERC20 path — no nil guard ✗
if err := vm.simulationState.InjectERC20BalanceChange(ctx, vm.smartWalletConfig, ...)
Performance3. Two RPC connections opened per ERC20 balance injection
client, err := ethclient.DialContext(ctx, rpcURL)
if err != nil { ... }
defer client.Close()
mappingSlot, err := s.probeERC20BalanceSlotWithClient(ctx, client, tokenContract, holder)The current approach opens up to two TCP connections per simulated transfer event. 4.
n.logger.Info("injectEventTriggerStateOverrides: called",
"simulationStateEmpty", vm.simulationState.IsEmpty())
Similarly, the new n.logger.Info("SimulateTask: state override check",
"triggerType", triggerType, ...)This belongs at Code Quality5. Hardcoded
if roleStr, ok := v.(string); ok && ApiRole(roleStr) == "admin" {If there's an 6.
type StateDiffEntry struct {
Address string `json:"address"`
Key string `json:"key"`
Original string `json:"original"`
Dirty string `json:"dirty"`
}would remove the defensive type assertions in 7. func erc20BalanceSlot(holder common.Address, mappingSlot int64) common.Hash {
key := common.LeftPadBytes(holder.Bytes(), 32)
slot := common.LeftPadBytes(big.NewInt(mappingSlot).Bytes(), 32)
return crypto.Keccak256Hash(append(key, slot...))
}This path is called in a loop over var buf [64]byte
copy(buf[12:32], holder.Bytes())
big.NewInt(mappingSlot).FillBytes(buf[32:])
return crypto.Keccak256Hash(buf[:])Test Coverage8. Integration test silently skips in CI
Minor Nits
|
- Handle iterationFailCount > 0 with firstError == nil (fallback message) - Add nil guard for vm.smartWalletConfig on ERC20 injection path - Demote debug/trace logs from Info to Debug level - Add comment explaining slot 51 (Compound cToken contracts)
- Handle iterationFailCount > 0 with firstError == nil (generic fallback) - Add nil guard for vm.smartWalletConfig on ERC20 injection path - Demote simulation debug logs from Info to Debug level - Remove IsEmpty() mutex acquisition from log arguments - Add comment explaining commonBalanceSlots entries
This pull request introduces several improvements and fixes across the aggregator, authentication, simulation, and summarization components. The most significant changes are the addition of simulation state injection for event triggers (especially for ERC20 transfers), enhancements to loop step error handling, and improved extraction of contract addresses in summarization logic. Comprehensive tests for simulation state management and ERC20 balance overrides have also been added.
Simulation and State Injection Enhancements:
Added the
injectEventTriggerStateOverridesandinjectTransferEventStatemethods incore/taskengine/engine.goto automatically inject balance changes into the simulation state when a Transfer event is detected, ensuring downstream contract write simulations reflect the correct balances. This fixes issues where simulated contract writes would incorrectly fail due to missing balance updates. [1] [2]Introduced
core/taskengine/simulation_state_test.gowith detailed tests for simulation state map operations, ERC20 balance slot computation, and integration scenarios where balance overrides are required for successful contract write simulations.Authentication and JWT Handling:
Modified JWT creation in
aggregator/key.goto ensure theaudclaim uses the smart wallet chain ID, aligning with the verifier's expectations and supporting cross-chain configurations. Also updated the issuer to use a constant. [1] [2]Updated JWT verification logic in
core/auth/user.goto allow admin-role JWTs to manage any wallet and to clarify subject matching for per-wallet keys.Loop Step and Summarization Improvements:
Changed loop step result handling in
core/taskengine/manual_trigger_loop_test.goso that partial iteration failures cause the step to reportsuccess=falsewith a descriptive error, supporting better detection of partial successes.Improved contract address and method name extraction in summarization logic for LOOP steps in
core/taskengine/summarizer_context_memory.go, including a fallback that checks iteration-level metadata. AddedextractResolvedContractAddressFromLoopOutputfor robust address extraction from loop outputs. [1] [2]Other:
structpbin summarizer context memory tests.