The 63/64 Gas Forwarding Rule
The EVM has a fundamental principle: when a contract executes an external call, it forwards a maximum of 63/64 of available gas to the called contract, retaining 1/64 for post-call operations.Why This Rule Exists
The EVM reserves 1/64 of gas to:- Handle the return from the external call
- Execute cleanup operations
- Prevent complete gas exhaustion that would brick the calling contract
Impact on Hook Execution
When the trampoline calls a hook with a specified gas limit:hook.gasLimit gas due to:
- The 63/64 forwarding rule
- Operations executed before the call
HooksTrampoline.sol:63-65:
gasleft() * 63 / 64 gas will be forwarded to the hook.
Gas Limit Enforcement Algorithm
Step 1: Pre-Call Gas Check
- Calculates how much gas would be forwarded using the 63/64 rule
- Checks if this is less than the requested gas limit
- Reverts if insufficient gas is available
Step 2: Capped Hook Execution
- The hook cannot consume more than its allocated gas
- Remaining gas is preserved for subsequent hooks and settlement logic
Why Gas Wasting is Needed: revertByWastingGas()
The revertByWastingGas() function is critical for proper gas estimation on certain Ethereum node implementations.
Implementation
FromHooksTrampoline.sol:88-90:
The Nethermind Estimation Issue
Some node implementations (notably Nethermind) have a problem witheth_estimateGas:
- Normal behavior:
eth_estimateGasshould return the gas limit needed for a transaction to succeed - Nethermind issue: When a transaction uses less gas on revert than on success, Nethermind returns the gas used in a successful transaction instead of the gas limit
HooksTrampoline.sol:79-87:
“If gas isn’t wasted or wasted through other means (for example, usingassembly { invalid() }) then an affected node will incorrectly estimate (througheth_estimateGas) the gas needed by the transaction: it will return gas used in a successful transaction instead of the gas limit used in the successful transaction.”
Why Other Approaches Don’t Work
Alternative gas wasting methods fail for estimation:assembly { invalid() }— Consumed gas is not properly trackedrevert()— Uses minimal gas, doesn’t trigger the correct estimation behavior- Early return — Doesn’t consume enough gas
The gas wasting mechanism is specifically designed for gas estimation. During actual transaction execution, the pre-call check prevents this code path from being reached when there’s sufficient gas.
Real Examples from Tests
Example 1: Gas Limit Enforcement
FromHooksTrampoline.t.sol:116-135:
- A hook requests 100,000 gas
- The trampoline is called with only 99,999 gas
- The pre-call check detects insufficient gas and reverts
Example 2: Precise Gas Forwarding
FromHooksTrampoline.t.sol:31-50:
- Hook receives approximately the specified gas limit (within 200 gas)
- Small variance due to Solidity runtime overhead
- Gas forwarding is precise enough for practical use
Example 3: Multiple Hook Gas Management
FromHooksTrampoline.t.sol:137-156:
- Each hook in the array has its gas limit enforced independently
- Total gas must be sufficient for all hooks combined
- The trampoline reverts if any hook would receive insufficient gas
Gas Overhead Components
FromGasLimitEnforcement.t.sol:14-27, the test suite identifies several overhead components:
Trampoline Overhead (~4,000 gas)
Includes:- Function call setup
- Access control check (
onlySettlementmodifier) - Loop iteration for hook array
- Gas calculation (
gasleft() * 63 / 64) - Comparison and conditional logic
Call Overhead
FromHooksTrampoline.t.sol:111:
- Cold storage access: 2,600 gas
- Call cost: 700 gas
- Factor of 2: Accounts for both the call and potential storage operations
Calculating Required Gas
To properly call the trampoline with a desired hook gas limit, account for all overheads:GasLimitEnforcement.t.sol:154-160, this calculation:
- Adds the trampoline overhead to the desired gas
- Multiplies by 64/63 to account for the EVM’s gas forwarding rule
- Returns the total gas limit needed for the trampoline call
Example Calculation
For a hook needing 100,000 gas:When calling the trampoline, always provide
(desiredHookGas + overhead) * 64/63 to ensure the hook receives its full gas allocation.Edge Cases and Limitations
Known Imprecision
FromGasLimitEnforcement.t.sol:103-124, there’s a known edge case where the trampoline’s gas check is imprecise:
- Not revert despite insufficient gas
- But the hook still fails to execute properly
- The hook safely fails (doesn’t cause issues)
- The gas deficit is small and predictable
- It doesn’t affect settlement integrity
Gas Efficiency
FromGasLimitEnforcement.t.sol:126-141, the trampoline overhead is bounded:
Protection Against Gas Attacks
The “Hummer” Attack
FromHooksTrampoline.t.sol:189-204, the test suite includes a contract designed to consume massive amounts of gas:
- Attempts to allocate memory up to
type(uint256).max - Would consume enormous amounts of gas if uncapped
- Is safely contained by the gas limit enforcement
HooksTrampoline.t.sol:97-114, even with this attack:
- The malicious hook consumes only its allocated gas limit
- Total gas used is
gasLimit + overhead(predictable and bounded) - The attack is completely neutralized
Best Practices
- Set Conservative Gas Limits: Account for worst-case execution in your hooks
- Include Overhead: When calling the trampoline, use
(hookGas + overhead) * 64/63 - Test Gas Usage: Use tests like
test_SpecifiesGasLimitto verify your hooks receive adequate gas - Handle Reverts: Design hooks to fail gracefully if gas is insufficient
- Monitor Estimations: Be aware of potential Nethermind estimation issues in your tooling
Summary
| Concept | Key Takeaway |
|---|---|
| 63/64 Rule | EVM forwards at most 63/64 of available gas to external calls |
| Gas Enforcement | Pre-call check + capped execution prevents gas attacks |
| Gas Wasting | Infinite loop needed for proper gas estimation on Nethermind |
| Overhead | Account for ~4,000 gas trampoline overhead + call costs |
| Attack Protection | Gas limits safely contain malicious hooks attempting to drain gas |
| Imprecision | Small gas deficit (~500-3,000) may not trigger revert but hook still fails safely |
The trampoline’s gas management is designed to be conservative: it may slightly under-allocate gas to hooks, but this ensures settlement safety and prevents gas-based attacks.
Additional Reading
- Security Model — Understanding access control and privilege isolation
- Settlement Flow — How hooks integrate into the complete settlement lifecycle