Abstract
This EIP introduces a new instruction that allows EOF contracts to control the portion of gas forwarded to callees without exposing exact gas values.
Motivation
With the introduction of revamped CALL instructions in EIP-7069, direct gas limiting for calls is no longer possible. However, there are legitimate use cases where limiting the gas forwarded to callees is necessary.
This EIP addresses this need by allowing contracts to specify a percentage of available gas to be forwarded, without exposing exact gas amounts. This maintains the benefits of gas non-observability while providing necessary control.
A key problem with always forwarding all available gas is that a malicious callee could consume all gas during execution (even in case of a revert), potentially causing denial of service. By allowing the caller to restrict the forwarded gas to a specific portion, this risk can be mitigated.
By default, the gas split is set to 63/64 to match the existing behavior defined in EIP-150.
With future multidimensional gas models, this instruction could potentially restrict all gas types.
Specification
A new instruction CALL_GAS_SPLIT is introduced. This instruction:
- Deduct the gas and pop one item from the stack representing a gas fraction.
- If fraction is more than
65535(u16::MAX) throw a halt. - Calculates the gas split by using the current gas by spliting it by floored value as
split_gas=(gas*value)//65535.And preserves gas split until the end of the call. - The preserved gas split should be used in all
EXT*CALLoperations to set gas limit asmax(split_gas, gas_left).
If this value is not set, the EVM interpreter MUST maintain the 63/64 rule that was previously used as default.
Gas cost of new opcode is set to 3 (VERYLOW) and it covers the cost of poping item from stack, checking if it is less than 65536, reading current gas and calculating gas split and saving gas split for later use.
Rationale
Several alternatives were considered for implementing gas split functionality:
Adding gas split parameters directly to EXT*CALL call instructions: While possible, this would require setting the split for each call individually. Having a standalone instruction allows setting the split once for multiple calls.
Hardcoding the gas split value as immediate: This would be restrictive for dynamic scenarios where the number of calls is only known at runtime.
Using a stack item for CALL_GAS_SPLIT: This approach was chosen as it provides the most flexibility, allowing dynamic adjustment of the gas split ratio.
Flooring popped value allows push 0xffff, CALL_GAS_SPLIT to be used to set full gas forwarding and 65535 parts seems big enought.
An alternative to using current gas for a split when CALL_GAS_SPLIT is called would be to split current gas when EXT*CALL is used. This alternative would make gas inconsistent and dependent on the amount of gas that was used. The chosen approach gives the benefit of using the same gas limit.
Removing 63/64 rule is up to debate and it would depend on EVM implementation can support big call stacks.
Backwards Compatibility
This EIP is fully backward compatible if the opcode is not used and will not disrupt other instructions. State tests should be created to verify this.
Security Considerations
The introduction of CALL_GAS_SPLIT allows contracts to limit the gas forwarded to callees, which can help prevent certain denial-of-service attacks. However, setting the gas split too low might prevent legitimate callees from completing their execution.
Implementations must ensure that the gas calculation does not overflow, especially when using 64-bit integers in testing environments.
Copyright
Copyright and related rights waived via CC0.
