feat: add Stmt.externalCallWithReturn for ABI-encoded external calls#935
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
All 4 bugbot findings addressed:
Added 3 new tests: parameter shadow rejection, local redeclaration rejection, and view+staticcall acceptance. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
|
Both bugbot findings from the second review addressed:
Added test: multiple |
|
Re: bugbot findings on externalCallWithReturn Thanks for the thorough review. Addressing each finding:
Will fix findings #2 and #5 (the HIGH severity ones) in a follow-up commit. |
…926) Add a high-level statement that compiles to the common mstore(selector+args) → call/staticcall → revert forwarding → returndatacopy+mload pattern used throughout Morpho Blue for oracle price feeds, IRM borrow rate queries, and ERC20 balance checks. The generated Yul: 1. Stores the left-shifted selector at memory[0] 2. Stores each argument at sequential 32-byte offsets from memory[4] 3. Performs call() or staticcall() based on isStatic flag 4. Forwards revert data on call failure 5. Validates returndatasize ≥ 32 6. Copies and binds the return value to a local variable Includes 3 test groups (15 assertions) covering: - staticcall with no args (oracle pattern) - call with single arg (ERC20 balanceOf pattern) - call with multiple args (IRM borrowRate pattern) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. Remove redundant returndatacopy — call/staticcall already copies returndata to memory[0..32] via retOffset/retSize params 2. Emit statements flat instead of in a YulStmt.block so the resultVar binding is accessible to subsequent statements 3. Add resultVar shadowing/redeclaration validation matching Stmt.letVar 4. staticcall (isStatic=true) no longer incorrectly marked as writing state, allowing view functions to use staticcall external calls Adds 3 new tests: parameter shadow rejection, local redeclaration rejection, and view+staticcall acceptance. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Address bugbot findings: 1. Wrap call/revert/sizeCheck in a YulStmt.block so __ecwr_success is block-scoped. This prevents duplicate let declarations when multiple externalCallWithReturn statements appear in the same function body. The resultVar binding remains flat-scoped (outside the block) so subsequent statements can reference it. 2. Include the target expression in collectStmtNames for externalCallWithReturn, matching all other handler functions. Adds test: multiple externalCallWithReturn in same function compiles without collision. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3ea5b85 to
353319d
Compare
Summary
Adds
Stmt.externalCallWithReturn— a high-level statement that compiles the common ABI-encoded external call pattern used throughout Morpho Blue (oracle price feeds, IRM borrow rate queries, ERC20 balance checks) into correct Yul.Stmt.externalCallWithReturnvariant takes a target address, 4-byte selector, argument list, andisStaticflagmstore(shl(224, selector))+ arg encoding +call/staticcall+ revert forwarding +returndatasizevalidation +returndatacopy+mloadbindingPartial implementation of #926 — covers the single-return-value case. Multi-return and SafeTransfer sugar are planned as follow-up.
Test plan
lake build Compiler.ContractSpecFeatureTestpasses all existing + 3 new test groupslake build Compiler.ContractSpecbuilds cleanly (no warnings)lake build Verity.Proofs.Stdlib.SpecInterpreterbuilds cleanly🤖 Generated with Claude Code
Note
Medium Risk
Touches core compiler codegen and validation logic for external calls; incorrect encoding, revert forwarding, or scoping could produce wrong or unsafe EVM behavior despite added tests.
Overview
Adds a new statement variant,
Stmt.externalCallWithReturn, to express a common ABI-encoded external call that binds a singleuint256return value.The compiler now lowers this statement to Yul that ABI-encodes the selector/args in memory, performs
call/staticcall, forwards reverts with returned data, checksreturndatasize() >= 32, and binds the result viamload(0). All relevant analyses/validators (name collection, scoping, mutability/state-effects, interop checks, external target validation) and theSpecInterpreterare updated to recognize the new statement (interpreter treats it as unsupported like other linked-Yul features).Adds feature tests covering staticcall vs call, arg encoding offsets/calldata sizing, revert forwarding/size checks, and compile-time rejection of result-var shadowing/redeclaration and multiple uses in one function.
Written by Cursor Bugbot for commit 353319d. This will update automatically on new commits. Configure here.