From e19ceaf176b8be047400c5869c3bb8639af4bd24 Mon Sep 17 00:00:00 2001 From: Dankrad Feist Date: Thu, 26 Feb 2026 11:34:03 +0200 Subject: [PATCH 1/3] Fix base fee description in TIP-1010 --- tips/tip-1010.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tips/tip-1010.md b/tips/tip-1010.md index c548497157..ac15f28a23 100644 --- a/tips/tip-1010.md +++ b/tips/tip-1010.md @@ -40,7 +40,7 @@ The parameters defined in this TIP represent the initial mainnet configuration a **Note on units**: Attodollars (10^-18 USD) are the gas price unit. TIP-20 tokens use 6 decimals, so 1 token unit = 1 microdollar (10^-6 USD). Conversion: attodollars / 10^12 = microdollars. -**Note**: The base fee may fluctuate based on network demand through the existing EIP-1559-style mechanism. This value represents the target equilibrium base fee. +**Note**: The base fee is fixed per protocol version and does not adjust dynamically based on block utilization. Unlike EIP-1559, there is no in-protocol mechanism that raises or lowers the base fee in response to congestion. Changes to the base fee require a hardfork upgrade. ## Payment Lane Gas Limit From 419a156881f033cdb72388f4b83f94f2a050e58f Mon Sep 17 00:00:00 2001 From: Dankrad Feist Date: Thu, 26 Feb 2026 14:43:17 +0200 Subject: [PATCH 2/3] Fix TIP-1000 and TIP-1010 per review feedback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TIP-1000: - Clarify SSTORE cold/warm access: 250k is the state creation component, EIP-2929 access cost (2100 cold / 100 warm) is charged separately - Fix all "keccak + codesize" references to "keccak + nonce" (codesize is not stored as a separate account field) - Clarify that the 500k CREATE cost includes the contract's nonce write; there is no separate 250k account creation charge for contracts - Add 7702 delegation keccak write cost (250k for no-delegation → delegation) - Remove sender account creation cost from contract deployment examples (assume initialized sender) TIP-1010: - Rename "Payment Lane Gas Limit" to "Block Gas Limit" (500M is total, not payment-specific) and add gas budget breakdown - Fix test case 3 from stale 25M to 30M general gas limit - Replace vague Invariant 1 with concrete base fee invariant - Fix Invariant 5 to match shared capacity model (non-shared 450M, general 30M, shared 50M) - Remove sender account creation from tx gas cap rationale and cost table Also fix misleading test comment in evm.rs and TxBuilder.sol constant comment. Made-with: Cursor --- crates/revm/src/evm.rs | 2 +- tips/ref-impls/test/helpers/TxBuilder.sol | 2 +- tips/tip-1000.md | 48 ++++++++++++----------- tips/tip-1010.md | 34 +++++++++------- 4 files changed, 47 insertions(+), 39 deletions(-) diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index 3fccb20d5a..751a9c9a5e 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -1697,7 +1697,7 @@ mod tests { // Simple initcode: PUSH1 0x00 PUSH1 0x00 RETURN (deploys empty contract) let initcode = vec![0x60, 0x00, 0x60, 0x00, 0xF3]; - // T1 costs: CREATE cost (500k) + new account for sender (250k) + new account for contract (250k) + // T1 costs: CREATE cost (500k, covers keccak + nonce) + new account for sender (250k) + base costs let tx = TxBuilder::new() .create(&initcode) .gas_limit(1_000_000) diff --git a/tips/ref-impls/test/helpers/TxBuilder.sol b/tips/ref-impls/test/helpers/TxBuilder.sol index 135c032ec5..81e6ab13c6 100644 --- a/tips/ref-impls/test/helpers/TxBuilder.sol +++ b/tips/ref-impls/test/helpers/TxBuilder.sol @@ -46,7 +46,7 @@ library TxBuilder { uint64 constant STATE_CREATION_COST = 250_000; // SSTORE zero→non-zero uint64 constant CREATE_BASE_COST = 500_000; // CREATE/CREATE2 base uint64 constant CODE_DEPOSIT_COST = 1000; // per byte - uint64 constant CREATE_FIELDS_COST = 500_000; // keccak + codesize (2 × 250,000) + uint64 constant CREATE_FIELDS_COST = 500_000; // keccak + nonce (2 × 250,000) // ============ Gas Calculation Helpers ============ diff --git a/tips/tip-1000.md b/tips/tip-1000.md index 2dbe3be1ba..3f5ab486db 100644 --- a/tips/tip-1000.md +++ b/tips/tip-1000.md @@ -12,7 +12,7 @@ status: Approved ## Abstract -This TIP increases the gas cost for creating new state elements, accounts, and contract code to provide economic protection against state growth spam attacks. The proposal increases the cost of writing a new state element from 20,000 gas to 250,000 gas, introduces a 250,000 gas charge for account creation (when the account's nonce is first written), and implements a new contract creation cost model: 1,000 gas per byte of contract code plus 500,000 gas for keccak hash and codesize fields. +This TIP increases the gas cost for creating new state elements, accounts, and contract code to provide economic protection against state growth spam attacks. The proposal increases the cost of writing a new state element from 20,000 gas to 250,000 gas, introduces a 250,000 gas charge for account creation (when the account's nonce is first written), and implements a new contract creation cost model: 1,000 gas per byte of contract code plus 500,000 gas for keccak hash and nonce fields. ## Motivation @@ -50,7 +50,10 @@ These units provide precise economic accounting while maintaining human-readable - Writing a new state element (SSTORE to a zero slot) costs 20,000 gas **Proposed Behavior:** -- Writing a new state element (SSTORE to a zero slot) costs 250,000 gas +- Writing a new state element (SSTORE to a zero slot) costs 250,000 gas for the state creation component (replacing 20,000 gas) +- The EIP-2929 access cost is charged separately: 2,100 gas for cold access, 100 gas for warm access +- Total cost for a cold zero-to-nonzero SSTORE: 2,100 + 250,000 = 252,100 gas +- Total cost for a warm zero-to-nonzero SSTORE: 100 + 250,000 = 250,100 gas This applies to all storage slot writes that transition from zero to non-zero, including: - Contract storage slots @@ -77,7 +80,7 @@ This applies to all storage slot writes that transition from zero to non-zero, i - The charge also applies to other nonces with [nonce keys](/protocol/transactions/spec-tempo-transaction#specification) (2D nonces) - Transactions with a nonce value of 0 need to supply at least 271,000 gas and are otherwise invalid - For EOA accounts: charged on the first transaction sent from that address (when the account is first used) -- For contract accounts: charged when the contract is deployed (CREATE or CREATE2) +- For contract accounts: the nonce write is included in the 500,000 gas CREATE cost (see Contract Creation); there is no separate account creation charge - **Important:** When tokens are transferred TO a new address, the recipient's nonce remains 0, so no account creation cost is charged. The account creation cost only applies when the account is first used (sends a transaction). - The charge is in addition to any other gas costs for the transaction @@ -96,11 +99,11 @@ This applies to all storage slot writes that transition from zero to non-zero, i **Implementation Details:** - The code storage cost is calculated as: `code_size × 1,000` -- Additional state creation costs: 2 × 250,000 gas = 500,000 gas for keccak hash and codesize fields +- Additional state creation costs: 2 × 250,000 gas = 500,000 gas for keccak hash and nonce fields (the contract's nonce is set to 1 on creation) - Total contract creation cost: `(code_size × 1,000) + 500,000` gas - This replaces the existing EVM per-byte cost for contract creation (not an additional charge) - Applies to both CREATE and CREATE2 operations -- The account creation cost (250,000 gas) is separate and still applies when the contract account's nonce transitions from 0 to 1 +- The 500,000 gas includes the contract account's nonce write (0 → 1); there is no separate account creation charge for the contract ### Intrinsic transaction gas @@ -109,8 +112,9 @@ A transaction is invalid if the minimal costs of a (reverting) transaction can't * Transaction with `nonce == 0` require an additional 250,000 gas * Tempo transactions with any `nonce_key` and `nonce == 0` require an additional 250,000 gas * Changes to EIP-7702 authorization lists: - * EIP-7702 authorisation list entries with `auth_list.nonce == 0` require an additional 250,000 gas. * The base cost per authorization is reduced to 12,500 gas + * EIP-7702 authorisation list entries with `auth_list.nonce == 0` require an additional 250,000 gas (account creation for the nonce field) + * EIP-7702 authorisation list entries going from no delegation to delegation require an additional 250,000 gas (state creation for the keccak/code hash field) * There is no refund if the account already exists * The additional initial cost for CREATE transactions that deploy a contract is increased to 500,000 from currently 32,000 (to reflect the upfront cost in contract creation) * If the first transaction in a batch is a CREATE transaction, the additional cost of 500,000 needs to be charged @@ -126,10 +130,10 @@ Tempo transaction key authorisations can't determine whether it is going to crea | Operation | Current Gas Cost | Proposed Gas Cost | Change | |-----------|------------------|-------------------|--------| -| New state element (SSTORE zero → non-zero) | 20,000 | 250,000 | +230,000 | +| New state element (SSTORE zero → non-zero, state creation component) | 20,000 | 250,000 | +230,000 | | Account creation (first nonce write) | 0 | 250,000 | +250,000 | | Contract creation (per byte) | 200 | 1,000 | +800 | -| Contract creation (keccak + codesize fields) | Included in base | 500,000 | +500,000 | +| Contract creation (keccak + nonce fields) | Included in base | 500,000 | +500,000 | | Existing state element (SSTORE non-zero → non-zero) | 5,000 | 5,000 | No change | | Existing state element (SSTORE non-zero → zero) | -15,000 (refund) | -15,000 (refund) | No change | @@ -219,12 +223,11 @@ These costs serve as a significant economic deterrent against state growth spam - Example for 1,000 byte contract: 32,000 + (1,000 × 200) = 232,000 gas ≈ 0.46 cents **Proposed Cost:** -- Account creation: 250,000 gas - Contract code storage: code_size × 1,000 gas - Keccak + nonce fields: 500,000 gas (2 × 250,000) -- Example for 1,000 byte contract: 250,000 + (1,000 × 1,000) + 500,000 = 1,750,000 gas ≈ **3.5 cents** +- Example for 1,000 byte contract: (1,000 × 1,000) + 500,000 = 1,500,000 gas ≈ **3.0 cents** -**Impact:** Contract deployment costs increase significantly, especially for larger contracts. A 100 byte contract costs (100 × 1,000) + 500,000 + 250,000 = 850,000 gas = 1.7 cents total. +**Impact:** Contract deployment costs increase significantly, especially for larger contracts. A 100 byte contract costs (100 × 1,000) + 500,000 = 600,000 gas = 1.2 cents. ## Implementation Requirements @@ -237,14 +240,14 @@ The node implementation must: - Charge 250,000 gas instead of 20,000 gas for these operations 2. **Detect account creation:** - - Track when an account's nonce transitions from 0 to 1 + - Track when an EOA account's nonce transitions from 0 to 1 - Charge 250,000 gas for this transition - - Apply to both EOA and contract account creation + - For contract accounts, the nonce write is included in the 500,000 CREATE cost 3. **Implement contract creation pricing:** - Replace existing EVM per-byte cost for contract code storage - Charge 1,000 gas per byte of contract code (linear pricing) - - Charge 500,000 gas (2 × 250,000) for keccak hash and codesize fields + - Charge 500,000 gas (2 × 250,000) for keccak hash and nonce fields - Total formula: `(code_size × 1,000) + 500,000` - Apply to both CREATE and CREATE2 operations @@ -263,15 +266,14 @@ The test suite must verify: 2. **Account creation:** - First transaction from EOA charges 250,000 gas for account creation (when nonce transitions 0 → 1) - - Contract deployment (CREATE) charges 250,000 gas for account creation - - Contract deployment (CREATE2) charges 250,000 gas for account creation + - Contract deployment does NOT charge a separate 250,000 gas for the contract's account creation (the nonce write is included in the 500,000 CREATE cost) - Transfer TO a new address does NOT charge account creation fee (recipient's nonce remains 0) - Subsequent transactions from the same account do not charge account creation fee 3. **Contract creation:** - Contract code storage replaces EVM per-byte cost with new pricing model - Each byte of contract code costs 1,000 gas (linear pricing) - - Keccak hash and codesize fields cost 500,000 gas (2 × 250,000) total + - Keccak hash and nonce fields cost 500,000 gas (2 × 250,000) total - Total cost formula: `(code_size × 1,000) + 500,000` gas - Example: 100 byte contract costs (100 × 1,000) + 500,000 = 600,000 gas - Both CREATE and CREATE2 use the same pricing @@ -294,7 +296,7 @@ The test suite must verify: 6. **Economic calculations:** - Verify gas costs match expected dollar amounts - Verify attack cost calculations for large-scale state creation - - Verify contract creation costs match formula: `(code_size × 1,000) + 500,000 + 250,000` (including account creation) + - Verify contract creation costs match formula: `(code_size × 1,000) + 500,000` (nonce write included in CREATE cost) - Verify Tempo-specific operations charge correctly for new state creation --- @@ -303,9 +305,9 @@ The test suite must verify: The following invariants must always hold: -1. **State Creation Cost Invariant:** Any SSTORE operation that writes a non-zero value to a zero slot MUST charge exactly 250,000 gas (not 20,000 gas). +1. **State Creation Cost Invariant:** Any SSTORE operation that writes a non-zero value to a zero slot MUST charge 250,000 gas for the state creation component (not 20,000 gas). The total gas charged also includes the EIP-2929 access cost: 2,100 gas for cold access or 100 gas for warm access, resulting in a total of 252,100 gas (cold) or 250,100 gas (warm). -2. **Account Creation Cost Invariant:** The first transaction that causes an account's nonce to transition from 0 to 1 MUST charge exactly 250,000 gas for account creation. +2. **Account Creation Cost Invariant:** The first transaction sent from an EOA (causing the sender's nonce to transition from 0 to 1) MUST charge exactly 250,000 gas for account creation. For contract accounts, the nonce write is included in the 500,000 gas CREATE cost. 3. **Existing State Invariant:** SSTORE operations that modify existing non-zero state (non-zero to non-zero) MUST continue to charge 5,000 gas and MUST NOT be affected by this change. @@ -313,7 +315,7 @@ The following invariants must always hold: 5. **Gas Accounting Invariant:** The total gas charged for a transaction creating N new state elements and M new accounts (where M is the number of accounts whose nonce transitions from 0 to 1 in this transaction) MUST equal: base_transaction_gas + operation_gas + (N × 250,000) + (M × 250,000). Note: Transferring tokens TO a new address does not create the account (nonce remains 0), so M = 0 in that case. -6. **Contract Creation Cost Invariant:** Contract creation (CREATE/CREATE2) MUST charge exactly `(code_size × 1,000) + 500,000` gas for code storage, replacing the existing EVM per-byte cost. This includes: 1,000 gas per byte of contract code (linear pricing) and 500,000 gas (2 × 250,000) for keccak hash and codesize fields. The account creation cost (250,000 gas) is charged separately. +6. **Contract Creation Cost Invariant:** Contract creation (CREATE/CREATE2) MUST charge exactly `(code_size × 1,000) + 500,000` gas for code storage, replacing the existing EVM per-byte cost. This includes: 1,000 gas per byte of contract code (linear pricing) and 500,000 gas (2 × 250,000) for keccak hash and nonce fields. The 500,000 gas covers the contract's nonce write (0 → 1); there is no separate account creation charge for the contract. 7. **Economic Deterrent Invariant:** The cost to create 1 TB of state MUST be at least $50 million, and the cost to create 10 TB of state MUST be at least $500 million, based on the assumed gas price of 1 cent per 500,000 gas. @@ -324,8 +326,8 @@ The test suite must cover: 1. **Basic state creation:** Single SSTORE to zero slot charges 250,000 gas 2. **Multiple state creation:** Multiple SSTORE operations to zero slots each charge 250,000 gas 3. **Account creation (EOA):** First transaction from new EOA charges 250,000 gas -4. **Account creation (CREATE):** Contract deployment via CREATE charges 250,000 gas for account creation -5. **Account creation (CREATE2):** Contract deployment via CREATE2 charges 250,000 gas for account creation +4. **Contract creation (CREATE):** Contract deployment via CREATE charges 500,000 gas for keccak + nonce fields (no separate account creation charge) +5. **Contract creation (CREATE2):** Contract deployment via CREATE2 charges 500,000 gas for keccak + nonce fields (no separate account creation charge) 6. **Contract creation (small):** Contract with 100 bytes charges (100 × 1,000) + 500,000 = 600,000 gas for code storage 7. **Contract creation (medium):** Contract with 1,000 bytes charges (1,000 × 1,000) + 500,000 = 1,500,000 gas for code storage 8. **Contract creation (large):** Contract with 10,000 bytes charges (10,000 × 1,000) + 500,000 = 10,500,000 gas for code storage diff --git a/tips/tip-1010.md b/tips/tip-1010.md index ac15f28a23..04ef1acaf1 100644 --- a/tips/tip-1010.md +++ b/tips/tip-1010.md @@ -42,7 +42,7 @@ The parameters defined in this TIP represent the initial mainnet configuration a **Note**: The base fee is fixed per protocol version and does not adjust dynamically based on block utilization. Unlike EIP-1559, there is no in-protocol mechanism that raises or lowers the base fee in response to congestion. Changes to the base fee require a hardfork upgrade. -## Payment Lane Gas Limit +## Block Gas Limit **Value**: 500,000,000 gas per block (total block gas limit) @@ -51,14 +51,20 @@ The parameters defined in this TIP represent the initial mainnet configuration a - With 500ms block time: `10,000 × 2 = 20,000 TPS` for payment transactions - This capacity supports Tempo's target throughput for payment use cases -**Constraints**: -- Only transactions qualifying for the payment lane (simple TIP-20 transfers, memos, etc.) may exceed the `general_gas_limit` -- Complex contract interactions use the general gas limit instead +**Gas Budget Breakdown**: +- **Total block gas limit**: 500,000,000 gas +- **Shared gas limit** (validator subblocks): 50,000,000 gas (`block_gas_limit / 10`) +- **Non-shared gas limit** (proposer pool): 450,000,000 gas (`block_gas_limit - shared_gas_limit`) +- **General gas limit** (non-payment cap): 30,000,000 gas (see below) :::info -**Shared capacity model**: The payment lane is non-dedicated. General and payment transactions selected by the proposer share the non-shared gas budget (`block_gas_limit - shared_gas_limit` = 450M). General transactions are capped at `general_gas_limit` (30M), guaranteeing that at least 420M gas remains available for proposer payment transactions. The remaining 50M (`shared_gas_limit`) is reserved for validator subblocks as defined in the Sub-block Specification. +**Shared capacity model**: The payment lane is non-dedicated. General and payment transactions selected by the proposer share the non-shared gas budget (450M). General transactions are capped at `general_gas_limit` (30M), guaranteeing that at least 420M gas remains available for proposer payment transactions. The remaining 50M (`shared_gas_limit`) is reserved for validator subblocks as defined in the Sub-block Specification. ::: +**Constraints**: +- Only transactions qualifying for the payment lane (simple TIP-20 transfers, memos, etc.) may exceed the `general_gas_limit` +- Complex contract interactions use the general gas limit instead + ## Main Transaction Gas Limit **Value**: 30,000,000 gas per block (`general_gas_limit`) @@ -85,11 +91,10 @@ The parameters defined in this TIP represent the initial mainnet configuration a - Accommodates deployment of maximum-size contracts (24,576 bytes per EIP-170) under TIP-1000 state creation costs: - Base transaction cost: 21,000 gas - Calldata for initcode (up to 49,152 bytes per EIP-3860): ~500,000-800,000 gas - - CREATE base cost (TIP-1000, includes keccak/codesize fields): 500,000 gas (replaces old 32,000) + - CREATE base cost (TIP-1000, includes keccak/nonce fields): 500,000 gas (replaces old 32,000) - Initcode execution: variable (~3,000 gas minimum) - Contract code storage (TIP-1000): `24,576 bytes × 1,000 gas/byte = 24,576,000 gas` - - Account creation (TIP-1000): 250,000 gas - - **Total**: ~25,850,000-26,150,000 gas (fits within 30M limit) + - **Total**: ~25,600,000-25,900,000 gas (fits within 30M limit) ## Gas Schedule Summary @@ -119,13 +124,13 @@ At full payment lane utilization: | TIP-20 transfer (new recipient) | 300,000 | $0.006 (0.6 cent / 6,000 microdollars) | | First transaction from new account | 300,000 | $0.006 (0.6 cent / 6,000 microdollars) | | Small contract deployment (1KB) | ~1,800,000 | $0.036 (3.6 cents / 36,000 microdollars) | -| Max contract deployment (24,576 bytes) | ~26,200,000 | $0.524 (~52 cents / 524,000 microdollars) | +| Max contract deployment (24,576 bytes) | ~25,900,000 | $0.518 (~52 cents / 518,000 microdollars) | --- # Invariants -1. **Base Fee Floor**: The base fee MUST NOT fall below a minimum threshold that would enable economically viable spam attacks. +1. **Base Fee Invariant**: The base fee is fixed at `2 × 10^10` attodollars per protocol version and can only be changed via a hardfork upgrade. At the current base fee, a TIP-20 transfer (50,000 gas) MUST cost approximately 0.1 cent (1,000 microdollars). 2. **Payment Lane Priority**: Transactions qualifying for the payment lane MUST be able to consume up to the remaining block gas capacity (total gas limit minus gas already consumed by general transactions). @@ -133,9 +138,10 @@ At full payment lane utilization: 4. **Transaction Gas Cap**: No single transaction MUST be allowed to consume more than the transaction gas cap (30,000,000 gas). -5. **Block Gas Validity**: A block MUST be invalid if either: - - Payment lane transactions exceed the payment lane gas limit - - General transactions exceed the general gas limit +5. **Block Gas Validity**: A block MUST be invalid if any of the following hold: + - Total gas used by proposer pool transactions (payment + general) exceeds the non-shared gas limit (450M) + - Total gas used by non-payment (general) transactions exceeds the general gas limit (30M) + - Total gas used by validator subblock transactions exceeds the shared gas limit (50M) ## Implementation Notes @@ -149,7 +155,7 @@ These parameters are configured at the chainspec level and applied during block 1. **Base fee targeting**: Verify that at equilibrium, TIP-20 transfers cost approximately 0.1 cent (1,000 microdollars) 2. **Payment lane capacity**: Verify that 10,000 TIP-20 transfers can be included in a single block -3. **General gas limit**: Verify that general transactions are correctly bounded by the 25M gas limit +3. **General gas limit**: Verify that general transactions are correctly bounded by the 30M gas limit 4. **Transaction gas cap**: Verify that transactions exceeding 30M gas are rejected 5. **Contract deployment**: Verify that a 24KB contract can be deployed within the transaction gas cap 6. **Lane separation**: Verify that payment lane and general transactions are independently tracked From b94a99d8a4ce2a7c0e59ddc0c224a7e13b19e1ea Mon Sep 17 00:00:00 2001 From: Derek Cofausper <256792747+decofe@users.noreply.github.com> Date: Mon, 2 Mar 2026 15:20:57 +0000 Subject: [PATCH 3/3] docs: replace keccak+nonce references with fixed upfront contract creation cost Co-authored-by: dankrad <6130607+dankrad@users.noreply.github.com> Amp-Thread-ID: https://ampcode.com/threads/T-019caf21-c046-73f2-a4bd-b279c660d758 Co-authored-by: Amp --- crates/revm/src/evm.rs | 2 +- tips/ref-impls/test/helpers/TxBuilder.sol | 2 +- tips/tip-1000.md | 30 +++++++++++------------ tips/tip-1010.md | 2 +- tips/tip-1016.md | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index f13525b2a7..1c68578687 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -1722,7 +1722,7 @@ mod tests { // Simple initcode: PUSH1 0x00 PUSH1 0x00 RETURN (deploys empty contract) let initcode = vec![0x60, 0x00, 0x60, 0x00, 0xF3]; - // T1 costs: CREATE cost (500k, covers keccak + nonce) + new account for sender (250k) + base costs + // T1 costs: CREATE cost (500k, fixed upfront contract creation cost) + new account for sender (250k) + base costs let tx = TxBuilder::new() .create(&initcode) .gas_limit(1_000_000) diff --git a/tips/ref-impls/test/helpers/TxBuilder.sol b/tips/ref-impls/test/helpers/TxBuilder.sol index 81e6ab13c6..606ddc26cc 100644 --- a/tips/ref-impls/test/helpers/TxBuilder.sol +++ b/tips/ref-impls/test/helpers/TxBuilder.sol @@ -46,7 +46,7 @@ library TxBuilder { uint64 constant STATE_CREATION_COST = 250_000; // SSTORE zero→non-zero uint64 constant CREATE_BASE_COST = 500_000; // CREATE/CREATE2 base uint64 constant CODE_DEPOSIT_COST = 1000; // per byte - uint64 constant CREATE_FIELDS_COST = 500_000; // keccak + nonce (2 × 250,000) + uint64 constant CREATE_FIELDS_COST = 500_000; // fixed upfront contract creation cost // ============ Gas Calculation Helpers ============ diff --git a/tips/tip-1000.md b/tips/tip-1000.md index 3f5ab486db..94faef450b 100644 --- a/tips/tip-1000.md +++ b/tips/tip-1000.md @@ -12,7 +12,7 @@ status: Approved ## Abstract -This TIP increases the gas cost for creating new state elements, accounts, and contract code to provide economic protection against state growth spam attacks. The proposal increases the cost of writing a new state element from 20,000 gas to 250,000 gas, introduces a 250,000 gas charge for account creation (when the account's nonce is first written), and implements a new contract creation cost model: 1,000 gas per byte of contract code plus 500,000 gas for keccak hash and nonce fields. +This TIP increases the gas cost for creating new state elements, accounts, and contract code to provide economic protection against state growth spam attacks. The proposal increases the cost of writing a new state element from 20,000 gas to 250,000 gas, introduces a 250,000 gas charge for account creation (when the account's nonce is first written), and implements a new contract creation cost model: 1,000 gas per byte of contract code plus a fixed upfront contract creation cost of 500,000 gas. ## Motivation @@ -80,7 +80,7 @@ This applies to all storage slot writes that transition from zero to non-zero, i - The charge also applies to other nonces with [nonce keys](/protocol/transactions/spec-tempo-transaction#specification) (2D nonces) - Transactions with a nonce value of 0 need to supply at least 271,000 gas and are otherwise invalid - For EOA accounts: charged on the first transaction sent from that address (when the account is first used) -- For contract accounts: the nonce write is included in the 500,000 gas CREATE cost (see Contract Creation); there is no separate account creation charge +- For contract accounts: included in the fixed 500,000 gas CREATE cost (see Contract Creation); there is no separate account creation charge - **Important:** When tokens are transferred TO a new address, the recipient's nonce remains 0, so no account creation cost is charged. The account creation cost only applies when the account is first used (sends a transaction). - The charge is in addition to any other gas costs for the transaction @@ -94,16 +94,16 @@ This applies to all storage slot writes that transition from zero to non-zero, i **Proposed Behavior:** - Contract creation replaces the existing EVM per-byte cost with a new pricing model: - Each byte: 1,000 gas per byte (linear pricing) - - TX create cost: 2 × 250,000 gas = 500,000 gas for keccak hash and nonce fields + - Fixed upfront contract creation cost: 500,000 gas - This pricing applies to the contract code size (the bytecode being deployed) **Implementation Details:** - The code storage cost is calculated as: `code_size × 1,000` -- Additional state creation costs: 2 × 250,000 gas = 500,000 gas for keccak hash and nonce fields (the contract's nonce is set to 1 on creation) +- Fixed upfront contract creation cost: 500,000 gas - Total contract creation cost: `(code_size × 1,000) + 500,000` gas - This replaces the existing EVM per-byte cost for contract creation (not an additional charge) - Applies to both CREATE and CREATE2 operations -- The 500,000 gas includes the contract account's nonce write (0 → 1); there is no separate account creation charge for the contract +- The fixed 500,000 gas covers the contract account creation; there is no separate account creation charge for the contract ### Intrinsic transaction gas @@ -133,7 +133,7 @@ Tempo transaction key authorisations can't determine whether it is going to crea | New state element (SSTORE zero → non-zero, state creation component) | 20,000 | 250,000 | +230,000 | | Account creation (first nonce write) | 0 | 250,000 | +250,000 | | Contract creation (per byte) | 200 | 1,000 | +800 | -| Contract creation (keccak + nonce fields) | Included in base | 500,000 | +500,000 | +| Contract creation (fixed upfront cost) | Included in base | 500,000 | +500,000 | | Existing state element (SSTORE non-zero → non-zero) | 5,000 | 5,000 | No change | | Existing state element (SSTORE non-zero → zero) | -15,000 (refund) | -15,000 (refund) | No change | @@ -155,7 +155,7 @@ Based on the assumptions: **Contract Creation:** - Per byte: 1,000 gas = **0.002 cents (20 microdollars) per byte** -- Keccak + nonce fields: 500,000 gas (2 × 250,000) = **1.0 cent (10,000 microdollars)** +- Fixed upfront cost: 500,000 gas = **1.0 cent (10,000 microdollars)** - Example: 1,000 byte contract = (1,000 × 1,000) + 500,000 = 1,500,000 gas = **3.0 cents (30,000 microdollars)** ### Attack Cost Analysis @@ -224,7 +224,7 @@ These costs serve as a significant economic deterrent against state growth spam **Proposed Cost:** - Contract code storage: code_size × 1,000 gas -- Keccak + nonce fields: 500,000 gas (2 × 250,000) +- Fixed upfront contract creation cost: 500,000 gas - Example for 1,000 byte contract: (1,000 × 1,000) + 500,000 = 1,500,000 gas ≈ **3.0 cents** **Impact:** Contract deployment costs increase significantly, especially for larger contracts. A 100 byte contract costs (100 × 1,000) + 500,000 = 600,000 gas = 1.2 cents. @@ -242,12 +242,12 @@ The node implementation must: 2. **Detect account creation:** - Track when an EOA account's nonce transitions from 0 to 1 - Charge 250,000 gas for this transition - - For contract accounts, the nonce write is included in the 500,000 CREATE cost + - For contract accounts, the fixed 500,000 gas CREATE cost applies instead 3. **Implement contract creation pricing:** - Replace existing EVM per-byte cost for contract code storage - Charge 1,000 gas per byte of contract code (linear pricing) - - Charge 500,000 gas (2 × 250,000) for keccak hash and nonce fields + - Charge a fixed upfront contract creation cost of 500,000 gas - Total formula: `(code_size × 1,000) + 500,000` - Apply to both CREATE and CREATE2 operations @@ -273,7 +273,7 @@ The test suite must verify: 3. **Contract creation:** - Contract code storage replaces EVM per-byte cost with new pricing model - Each byte of contract code costs 1,000 gas (linear pricing) - - Keccak hash and nonce fields cost 500,000 gas (2 × 250,000) total + - Fixed upfront contract creation cost: 500,000 gas - Total cost formula: `(code_size × 1,000) + 500,000` gas - Example: 100 byte contract costs (100 × 1,000) + 500,000 = 600,000 gas - Both CREATE and CREATE2 use the same pricing @@ -307,7 +307,7 @@ The following invariants must always hold: 1. **State Creation Cost Invariant:** Any SSTORE operation that writes a non-zero value to a zero slot MUST charge 250,000 gas for the state creation component (not 20,000 gas). The total gas charged also includes the EIP-2929 access cost: 2,100 gas for cold access or 100 gas for warm access, resulting in a total of 252,100 gas (cold) or 250,100 gas (warm). -2. **Account Creation Cost Invariant:** The first transaction sent from an EOA (causing the sender's nonce to transition from 0 to 1) MUST charge exactly 250,000 gas for account creation. For contract accounts, the nonce write is included in the 500,000 gas CREATE cost. +2. **Account Creation Cost Invariant:** The first transaction sent from an EOA (causing the sender's nonce to transition from 0 to 1) MUST charge exactly 250,000 gas for account creation. For contract accounts, the fixed 500,000 gas CREATE cost applies instead. 3. **Existing State Invariant:** SSTORE operations that modify existing non-zero state (non-zero to non-zero) MUST continue to charge 5,000 gas and MUST NOT be affected by this change. @@ -315,7 +315,7 @@ The following invariants must always hold: 5. **Gas Accounting Invariant:** The total gas charged for a transaction creating N new state elements and M new accounts (where M is the number of accounts whose nonce transitions from 0 to 1 in this transaction) MUST equal: base_transaction_gas + operation_gas + (N × 250,000) + (M × 250,000). Note: Transferring tokens TO a new address does not create the account (nonce remains 0), so M = 0 in that case. -6. **Contract Creation Cost Invariant:** Contract creation (CREATE/CREATE2) MUST charge exactly `(code_size × 1,000) + 500,000` gas for code storage, replacing the existing EVM per-byte cost. This includes: 1,000 gas per byte of contract code (linear pricing) and 500,000 gas (2 × 250,000) for keccak hash and nonce fields. The 500,000 gas covers the contract's nonce write (0 → 1); there is no separate account creation charge for the contract. +6. **Contract Creation Cost Invariant:** Contract creation (CREATE/CREATE2) MUST charge exactly `(code_size × 1,000) + 500,000` gas for code storage, replacing the existing EVM per-byte cost. This includes: 1,000 gas per byte of contract code (linear pricing) and a fixed upfront contract creation cost of 500,000 gas. There is no separate account creation charge for the contract. 7. **Economic Deterrent Invariant:** The cost to create 1 TB of state MUST be at least $50 million, and the cost to create 10 TB of state MUST be at least $500 million, based on the assumed gas price of 1 cent per 500,000 gas. @@ -326,8 +326,8 @@ The test suite must cover: 1. **Basic state creation:** Single SSTORE to zero slot charges 250,000 gas 2. **Multiple state creation:** Multiple SSTORE operations to zero slots each charge 250,000 gas 3. **Account creation (EOA):** First transaction from new EOA charges 250,000 gas -4. **Contract creation (CREATE):** Contract deployment via CREATE charges 500,000 gas for keccak + nonce fields (no separate account creation charge) -5. **Contract creation (CREATE2):** Contract deployment via CREATE2 charges 500,000 gas for keccak + nonce fields (no separate account creation charge) +4. **Contract creation (CREATE):** Contract deployment via CREATE charges a fixed upfront cost of 500,000 gas (no separate account creation charge) +5. **Contract creation (CREATE2):** Contract deployment via CREATE2 charges a fixed upfront cost of 500,000 gas (no separate account creation charge) 6. **Contract creation (small):** Contract with 100 bytes charges (100 × 1,000) + 500,000 = 600,000 gas for code storage 7. **Contract creation (medium):** Contract with 1,000 bytes charges (1,000 × 1,000) + 500,000 = 1,500,000 gas for code storage 8. **Contract creation (large):** Contract with 10,000 bytes charges (10,000 × 1,000) + 500,000 = 10,500,000 gas for code storage diff --git a/tips/tip-1010.md b/tips/tip-1010.md index 04ef1acaf1..50bd431a1b 100644 --- a/tips/tip-1010.md +++ b/tips/tip-1010.md @@ -91,7 +91,7 @@ The parameters defined in this TIP represent the initial mainnet configuration a - Accommodates deployment of maximum-size contracts (24,576 bytes per EIP-170) under TIP-1000 state creation costs: - Base transaction cost: 21,000 gas - Calldata for initcode (up to 49,152 bytes per EIP-3860): ~500,000-800,000 gas - - CREATE base cost (TIP-1000, includes keccak/nonce fields): 500,000 gas (replaces old 32,000) + - CREATE base cost (TIP-1000, fixed upfront contract creation cost): 500,000 gas (replaces old 32,000) - Initcode execution: variable (~3,000 gas minimum) - Contract code storage (TIP-1000): `24,576 bytes × 1,000 gas/byte = 24,576,000 gas` - **Total**: ~25,600,000-25,900,000 gas (fits within 30M limit) diff --git a/tips/tip-1016.md b/tips/tip-1016.md index 05287cefeb..5e7d1be50c 100644 --- a/tips/tip-1016.md +++ b/tips/tip-1016.md @@ -79,7 +79,7 @@ Storage creation operations split their cost between execution gas (computationa | Hot SSTORE (non-zero → non-zero) | 2,900 | 0 | 2,900 | 2,900 | | Account creation (nonce 0 → 1) | 5,000 | 245,000 | 250,000 | 5,000 | | Contract code storage (per byte) | 200 | 2,300 | 2,500 | 200 | -| Contract metadata (keccak + nonce) | 5,000 | 495,000 | 500,000 | 5,000 | +| Contract creation (fixed upfront cost) | 5,000 | 495,000 | 500,000 | 5,000 | **Notes:** - Execution gas reflects computational cost (writing, hashing) and counts toward protocol limits