feat: implement reserve balance introspection changes#3
feat: implement reserve balance introspection changes#3QEDK wants to merge 10 commits intoreleases/v0.9-monadfrom
Conversation
QEDK
commented
Feb 23, 2026
- implements precompile changes as part of userop execution
- adds simulated testcases to assert execution outcome
Greptile SummaryThis PR adds reserve balance introspection to the ERC-4337 EntryPoint, enforcing that UserOperations cannot dip into a Monad-specific reserve balance during execution. After a successful UserOp call, the EntryPoint queries a precompile at
Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Bundler
participant EP as EntryPoint
participant Inner as innerHandleOp
participant Account
participant RB as ReserveBalance<br/>Precompile (0x1001)
Bundler->>EP: handleOps([userOp], beneficiary)
EP->>EP: _iterateValidationPhase()
EP->>Inner: innerHandleOp(callData, opInfo, context)
Inner->>Account: Exec.call(sender, callData)
Account-->>Inner: success / revert
alt callData succeeded
Inner->>RB: call(dippedIntoReserve())
RB-->>Inner: bool dipped
alt dipped == true or call failed
Inner-->>EP: revert(INNER_REVERT_DIPPED_INTO_RESERVE)
EP->>EP: _emitReserveBalanceViolatedEvent()
EP->>EP: _emitUserOperationEvent(success=false)
EP->>EP: collected = prefund (no refund)
else dipped == false
Inner->>EP: _postExecution(opSucceeded)
EP->>EP: _emitUserOperationEvent(success=true)
end
else callData reverted
Note over Inner: Skip reserve check<br/>(state already rolled back)
Inner->>EP: _postExecution(opReverted)
end
EP->>Bundler: _compensate(beneficiary, collected)
Last reviewed commit: 6c16c17 |
There was a problem hiding this comment.
Pull request overview
This pull request implements reserve balance introspection for ERC-4337 UserOperations by adding a precompile check that prevents successful operations from dipping into reserve balances.
Changes:
- Added IReserveBalance interface and reserve balance precompile integration in EntryPoint
- Added UserOperationReserveBalanceViolated event for tracking violations
- Added comprehensive test coverage for reserve balance checks across regular accounts, EIP-7702 accounts, and mixed batches
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| contracts/interfaces/IReserveBalance.sol | New interface defining the reserve balance precompile contract at address 0x1001 |
| contracts/interfaces/IEntryPoint.sol | Added UserOperationReserveBalanceViolated event declaration |
| contracts/core/EntryPoint.sol | Implemented reserve balance check after UserOp execution with special revert handling and event emission |
| test/entrypoint.test.ts | Added tests for reserve balance violations in regular account scenarios |
| test/entrypointsimulations.test.ts | Set up precompile mock for simulation tests |
| test/entrypoint-7702.test.ts | Added comprehensive tests for reserve balance violations with EIP-7702 accounts and mixed batches |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| abi.encodeWithSelector(IReserveBalance.dippedIntoReserve.selector) | ||
| ); | ||
| if (!success || ret.length != 32) { | ||
| return true; |
There was a problem hiding this comment.
As a design point: if this is instead return false this becomes chain independent and, when run on non-monad chains that do not have reserve balance, will correctly return that the contract is not in a reverting state.
There was a problem hiding this comment.
we did consider it but it's highly unlikely that this would be deployed on other chains due to the difference in bytecode (and thus, address) and also the side-effect in case a different precompile was to be made available at the same address. i'm erring on the side on caution here but we can consider a chain ID-based condition if we do need it to be agnostic (just that we haven't found a good reason yet).