Skip to main content
The Hooks Trampoline implements sophisticated gas management to prevent malicious or misconfigured hooks from consuming excessive gas and disrupting settlements.

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:
The call doesn’t receive exactly hook.gasLimit gas due to:
  1. The 63/64 forwarding rule
  2. Operations executed before the call
From HooksTrampoline.sol:63-65:
The trampoline calculates that approximately gasleft() * 63 / 64 gas will be forwarded to the hook.

Gas Limit Enforcement Algorithm

Step 1: Pre-Call Gas Check

Before executing each hook:
  1. Calculates how much gas would be forwarded using the 63/64 rule
  2. Checks if this is less than the requested gas limit
  3. Reverts if insufficient gas is available

Step 2: Capped Hook Execution

The hook is called with exactly the specified gas limit, ensuring:
  • The hook cannot consume more than its allocated gas
  • Remaining gas is preserved for subsequent hooks and settlement logic
The trampoline may provide slightly less gas than specified due to overhead between gas reading and call execution. From HooksTrampoline.sol:48-52: “The trampoline tries to ensure that the hook is called with exactly the gas limit specified in the hook, however in some circumstances it may be a bit smaller than that.”

Why Gas Wasting is Needed: revertByWastingGas()

The revertByWastingGas() function is critical for proper gas estimation on certain Ethereum node implementations.

Implementation

From HooksTrampoline.sol:88-90:
This infinite loop consumes all available gas, triggering an out-of-gas revert.

The Nethermind Estimation Issue

Some node implementations (notably Nethermind) have a problem with eth_estimateGas:
  • Normal behavior: eth_estimateGas should 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
From HooksTrampoline.sol:79-87:
“If gas isn’t wasted or wasted through other means (for example, using assembly { invalid() }) then an affected node will incorrectly estimate (through eth_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 tracked
  • revert() — Uses minimal gas, doesn’t trigger the correct estimation behavior
  • Early return — Doesn’t consume enough gas
Only burning all gas through an infinite loop provides reliable estimation behavior across all node implementations.
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

From HooksTrampoline.t.sol:116-135:
This test demonstrates:
  • 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

From HooksTrampoline.t.sol:31-50:
This test shows:
  • 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

From HooksTrampoline.t.sol:137-156:
This demonstrates:
  • 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

From GasLimitEnforcement.t.sol:14-27, the test suite identifies several overhead components:

Trampoline Overhead (~4,000 gas)

Includes:
  • Function call setup
  • Access control check (onlySettlement modifier)
  • Loop iteration for hook array
  • Gas calculation (gasleft() * 63 / 64)
  • Comparison and conditional logic

Call Overhead

From HooksTrampoline.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:
From GasLimitEnforcement.t.sol:154-160, this calculation:
  1. Adds the trampoline overhead to the desired gas
  2. Multiplies by 64/63 to account for the EVM’s gas forwarding rule
  3. 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

From GasLimitEnforcement.t.sol:103-124, there’s a known edge case where the trampoline’s gas check is imprecise:
In a narrow range (~500-3,000 gas deficit), the trampoline may:
  • Not revert despite insufficient gas
  • But the hook still fails to execute properly
This is acceptable because:
  • The hook safely fails (doesn’t cause issues)
  • The gas deficit is small and predictable
  • It doesn’t affect settlement integrity

Gas Efficiency

From GasLimitEnforcement.t.sol:126-141, the trampoline overhead is bounded:
The trampoline’s overhead is consistently under 60,000 gas, making it efficient for production use.

Protection Against Gas Attacks

The “Hummer” Attack

From HooksTrampoline.t.sol:189-204, the test suite includes a contract designed to consume massive amounts of gas:
This attack:
  • 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
From HooksTrampoline.t.sol:97-114, even with this attack:
The test confirms:
  • 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

  1. Set Conservative Gas Limits: Account for worst-case execution in your hooks
  2. Include Overhead: When calling the trampoline, use (hookGas + overhead) * 64/63
  3. Test Gas Usage: Use tests like test_SpecifiesGasLimit to verify your hooks receive adequate gas
  4. Handle Reverts: Design hooks to fail gracefully if gas is insufficient
  5. Monitor Estimations: Be aware of potential Nethermind estimation issues in your tooling

Summary

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
Last modified on March 4, 2026