You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Our team at FuzzingLabs discovered a non-compliance in the gas GTxDataNonZero and GTxDataZero calculation.
Overview
The Ethereum Yellow Paper specifies gas costs for transaction data based on its content:
GTxDataNonZero = 16:
This gas cost is applied to each non-zero byte in the transaction data (calldata). Non-zero bytes are more expensive to process because they increase the complexity of state computation and transmission.
GTxDataZero = 4:
This gas cost is applied to each zero byte in the transaction data (calldata). Zero bytes are less expensive to process because they require fewer computational resources.
These costs are part of the total transaction gas cost and are essential for properly accounting for the computational resources required to handle transaction data.
Issue Observed in LEVM
LEVM fails to correctly calculate GTxDataNonZero and GTxDataZero in certain scenarios, particularly during transactions involving contract creation (CREATE or CREATE2).
Details:
During a CREATE operation, the bytecode (contract input) contains the actual data that should be used to compute the gas cost for GTxDataNonZero and GTxDataZero.
However, in LEVM, the gas cost calculation for transaction data (tx_calldata) incorrectly passes the calldata instead of the bytecode.
Since calldata is empty during a CREATE transaction, the calculated gas cost for data is 0, regardless of the actual content of the bytecode.
let calldata_cost =
gas_cost::tx_calldata(&initial_call_frame.calldata).map_err(VMError::OutOfGas)?;
Expected Behavior:
The gas cost for transaction data during a CREATE transaction should be based on the bytecode provided as input, not the calldata :
let calldata_cost =
gas_cost::tx_calldata(&initial_call_frame.bytecode).map_err(VMError::OutOfGas)?;
Impact of Non-Compliance
Underestimation of Gas Costs:
The gas consumed during a CREATE transaction is significantly underestimated, as the bytecode is not properly accounted for.
Deviation from Ethereum Specifications:
This behavior violates the Ethereum Yellow Paper's rules for transaction gas costs, specifically the handling of GTxDataNonZero and GTxDataZero.
Potential Exploits:
Attackers could exploit this miscalculation to deploy contracts with large and complex bytecode at a lower-than-expected gas cost, gaining an unfair advantage.
Recommendations for Fixing the Issue
Correct Argument for Gas Cost Calculation:
Ensure that the gas cost calculation for transaction data (txcall) uses the bytecode (input) instead of the calldata during CREATE transactions.
#[test]fntest_non_compliance_gas_cost_GTxDataNonZero_GTxDataZero(){letmut vm = new_vm_with_bytecode(Bytes::copy_from_slice(&[0x5f])).unwrap();
vm.tx_kind = TxKind::Create;
vm.env.gas_price = U256::zero();
vm.env.gas_limit = U256::from(100_000_000);let res = vm.transact().unwrap();assert_eq!(res.gas_used,53020);}
Backtrace
thread 'test_non_compliance_gas_cost_GTxDataNonZero_GTxDataZero' panicked at crates/vm/levm/tests/edge_case_tests.rs:20:5:
assertion `left == right` failed
left:53004
right:53020
stack backtrace:0: rust_begin_unwind
at /rustc/8adb4b30f40e6fbd21dc1ba26c3301c7eeb6de3c/library/std/src/panicking.rs:665:51:core::panicking::panic_fmt
at /rustc/8adb4b30f40e6fbd21dc1ba26c3301c7eeb6de3c/library/core/src/panicking.rs:76:142:core::panicking::assert_failed_inner
3: core::panicking::assert_failed
4: edge_case_tests::test_non_compliance_gas_cost_GTxDataNonZero_GTxDataZero
at ./tests/edge_case_tests.rs:20:55:edge_case_tests::test_non_compliance_gas_cost_GTxDataNonZero_GTxDataZero::{{closure}}
at ./tests/edge_case_tests.rs:12:616:core::ops::function::FnOnce::call_once
at /home/mhoste/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:57:core::ops::function::FnOnce::call_once
at /rustc/8adb4b30f40e6fbd21dc1ba26c3301c7eeb6de3c/library/core/src/ops/function.rs:250:5
note:Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
failures:
test_non_compliance_gas_cost_GTxDataNonZero_GTxDataZero
test result:FAILED.0 passed;1 failed;0 ignored;0 measured;27 filtered out; finished in0.12s
The text was updated successfully, but these errors were encountered:
**Motivation**
<!-- Why does this pull request exist? What are its goals? -->
**Description**
<!-- A clear and concise general description of the changes this PR
introduces -->
- `number_of_words` is now calculated in a more performant way, without
iterating calldata.
- The initial_call_frame in Create is now initialized with empty
bytecode and the corresponding calldata send in the transaction. ->
After validations the calldata will be assigned to the bytecode and it
will be erased. This is mostly for using calldata for calculating some
gas costs.
<!-- Link to issues: Resolves#111, Resolves#222 -->
Closes#1362, #1363
Running tests:
- ✓ Summary: 1547/4100 (37.73)
Our team at FuzzingLabs discovered a non-compliance in the gas GTxDataNonZero and GTxDataZero calculation.
Overview
The Ethereum Yellow Paper specifies gas costs for transaction data based on its content:
GTxDataNonZero = 16
:This gas cost is applied to each non-zero byte in the transaction data (
calldata
). Non-zero bytes are more expensive to process because they increase the complexity of state computation and transmission.GTxDataZero = 4
:This gas cost is applied to each zero byte in the transaction data (
calldata
). Zero bytes are less expensive to process because they require fewer computational resources.These costs are part of the total transaction gas cost and are essential for properly accounting for the computational resources required to handle transaction data.
Issue Observed in LEVM
LEVM fails to correctly calculate
GTxDataNonZero
andGTxDataZero
in certain scenarios, particularly during transactions involving contract creation (CREATE
orCREATE2
).Details:
CREATE
operation, thebytecode
(contract input) contains the actual data that should be used to compute the gas cost forGTxDataNonZero
andGTxDataZero
.calldata
instead of thebytecode
.calldata
is empty during aCREATE
transaction, the calculated gas cost for data is 0, regardless of the actual content of thebytecode
.Code line :
Expected Behavior:
CREATE
transaction should be based on the bytecode provided as input, not thecalldata
:Impact of Non-Compliance
CREATE
transaction is significantly underestimated, as thebytecode
is not properly accounted for.GTxDataNonZero
andGTxDataZero
.bytecode
at a lower-than-expected gas cost, gaining an unfair advantage.Recommendations for Fixing the Issue
txcall
) uses thebytecode
(input) instead of thecalldata
duringCREATE
transactions.Step to reproduce
Add to test :
Backtrace
The text was updated successfully, but these errors were encountered: