Pattern 4A
Probe the reserve precompile after risky operations
Without checking, your bundle reverts at tx end with no information about which sub-call dipped the account below reserve. With the precompile, you can blame the right UserOp.
Before
function executeNaive(Op[] calldata ops) external payable {
for (uint256 i = 0; i < ops.length; i++) {
(bool ok, ) = ops[i].target.call{value: ops[i].value}(ops[i].data);
require(ok, "op reverted");
}
// If one of the ops dropped the bundler below 10 MON reserve,
// the WHOLE tx reverts at completion. The bundler has no way
// to tell which op was the offender.
}After
address constant RESERVE_PRECOMPILE = address(0x1001);
bytes4 constant DIPPED = 0x3a61584e;
function executeAware(Op[] calldata ops) external payable {
for (uint256 i = 0; i < ops.length; i++) {
(bool ok, ) = ops[i].target.call{value: ops[i].value}(ops[i].data);
require(ok, "op reverted");
// CALL (not STATICCALL) — required by MIP-4 spec.
(bool pOk, bytes memory r) = RESERVE_PRECOMPILE.call(
abi.encodeWithSelector(DIPPED)
);
require(pOk && r.length == 32);
if (abi.decode(r, (bool))) revert BadOp(i);
}
}Before: naive contract
Tx trace contains no probe of 0x1001. If any op had dipped the sender below reserve, the bundler would have no way to identify the offender.
View tx on MonadscanAfter: MIP-4 aware
Tx trace contains a CALL to 0x1001 with selector 0x3a61584e (dippedIntoReserve) after each op. Correct integration of the MIP-4 precompile.
View tx on MonadscanMIP-4 adds a precompile at 0x1001 that returns whether the current account state violates the 10 MON reserve. Bundlers (ERC-4337 entrypoints, multicall aggregators) should call it after each sub-operation: if it returns true, revert immediately with a structured error naming the offender. Critical detail: the call must be a CALL, not STATICCALL. The spec explicitly disallows STATICCALL. Of the ~340 contracts attempting to use the precompile on mainnet today, every single one is calling it via STATICCALL and reverting. The 'after' tx linked below is, to our knowledge, the first correct integration of 0x1001 on Monad mainnet: a real bundler tx whose trace contains a successful CALL to 0x1001 with selector 0x3a61584e. Use this contract (src linked) as the reference.