TIP-1016: Exempt Storage Creation from Gas Limits
Abstract
Storage creation operations (new state elements, account creation, contract code storage) continue to consume and be charged for gas, but this gas does not count against transaction or block gas limits. This allows increasing contract code pricing to 2,500 gas/byte without preventing large contract deployments, and prevents new account creation from reducing effective throughput.
Motivation
TIP-1000 increased storage creation costs to 250,000 gas per operation and 1,000 gas/byte for contract code. This created two problems:
-
Contract deployment constraints: 24KB contracts require ~26M gas, forcing us to:
- Keep transaction gas cap at 30M (would prefer 16M)
- Keep general gas limit at 30M (would prefer lower)
- Limit contract code to 1,000 gas/byte (would prefer 2,500)
-
New account throughput penalty: TIP-20 transfer to new address costs 271,000 gas total (26k execution + 245k storage) vs 24,000 gas to existing. At 500M payment lane gas limit:
- With storage creation gas: only 1,847 new account transfers/block = 3,694 TPS
- Without storage creation gas: ~19,000 new account transfers/block = ~38,000 TPS
- ~5x throughput improvement by exempting storage creation gas from limits
The root cause: storage creation gas counts against limits designed for execution time constraints. Storage creation is permanent (disk) not ephemeral (CPU), and shouldn't be bounded by per-block execution limits.
Specification
Gas Accounting
All operations consume gas, but storage creation operations now split their cost into two components:
-
Execution gas: Compute, memory, calldata, and the computational cost of storage operations (writing, hashing)
- Counts toward protocol limits (transaction and block)
-
Storage creation gas: The permanent storage burden of storage creation
- Does NOT count toward protocol limits
- Still counts toward user's
gas_limit
Gas Limits
Storage creation gas counts against the user's transaction gas limit (to prevent surprise costs) but NOT against protocol limits:
User Authorization:
execution_gas + storage_creation_gas <= transaction.gas_limit
Protocol Limits:
execution_gas <= max_transaction_gas_limit (EIP-7825, e.g. 16M)
general_execution_gas <= general_gas_limit (e.g. 25M, for non-payment txs)
payment_execution_gas <= payment_lane_limit (500M, for payment txs)
Cost:
total_gas = execution_gas + storage_creation_gas
cost = total_gas × (base_fee_per_gas + priority_fee)
Rationale:
- User's
gas_limitbounds total cost (no surprise charges) - Protocol limits bound only execution gas (block time constraint, not disk I/O)
- Storage doesn't reduce block execution capacity or prevent large contracts
- Note: Tempo has two block limits - general gas limit (~25M) for contracts and payment lane limit (500M) for simple transfers
Storage Gas Operations
Storage creation operations split their cost between execution gas (computational overhead) and storage creation gas (permanent storage burden):
| Operation | Execution Gas | Storage Gas | Total | Against Limits |
|---|---|---|---|---|
| Cold SSTORE (zero → non-zero) | 5,000 | 245,000 | 250,000 | 5,000 |
| 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 |
Notes:
- Execution gas reflects computational cost (writing, hashing) and counts toward protocol limits
- Storage creation gas reflects permanent storage burden and does NOT count toward protocol limits
- All gas (execution + storage) counts toward user's
gas_limitand is charged atbase_fee_per_gas
Contract Creation Pricing
Contract code storage cost increases from 1,000 to 2,500 gas/byte (200 execution + 2,300 storage).
Example for 24KB contract:
- Contract code execution gas:
24,576 × 200 = 4,915,200 - Contract code storage creation gas:
24,576 × 2,300 = 56,524,800 - Contract metadata execution gas:
5,000 - Contract metadata storage creation gas:
495,000 - Account creation execution gas:
5,000 - Account creation storage creation gas:
245,000 - Deployment logic execution gas: ~2M
Totals:
- Execution gas: ~7M (counts toward protocol limits)
- Storage creation gas: ~57M (doesn't count toward protocol limits)
- Total gas: ~64M (user must authorize with
gas_limit >= 64M) - Can deploy with protocol max_transaction_gas_limit = 16M (only ~7M counts)
Examples
TIP-20 Transfer to New Address
- Transfer logic: ~21,000 execution gas
- New balance slot: 5,000 execution gas + 245,000 storage creation gas
- Total: 26,000 execution gas + 245,000 storage creation gas = 271,000 gas
- User must authorize:
gas_limit >= 271,000 - Counts toward block limit: 26,000 execution gas
- Total cost: 271,000 gas
TIP-20 Transfer to Existing Address
- Transfer logic: ~21,000 execution gas
- Update existing slot: ~2,900 execution gas (hot SSTORE)
- Total: ~24,000 execution gas
- User must authorize:
gas_limit >= 24,000 - Counts toward block limit: ~24,000 execution gas
- Total cost: ~24,000 gas
Block Throughput
At 500M payment lane execution gas limit:
- New account transfers: ~26k execution gas each → ~19,000 transfers/block
- Existing account transfers: ~24k execution gas each → ~21,000 transfers/block
- ~20,000 TPS on average (vs 3,334 TPS in TIP-1000)
- Storage creation gas doesn't reduce block capacity
Invariants
- User Authorization:
execution_gas + storage_creation_gasMUST NOT exceedtransaction.gas_limit(prevents surprise costs) - Protocol Transaction Limit:
execution_gasMUST NOT exceedmax_transaction_gas_limit(EIP-7825 limit, e.g. 16M) - Protocol Block Limits: Block
execution_gasMUST NOT exceed applicable limit:- General transactions:
general_gas_limit(25M target, currently 30M) - Payment lane transactions:
payment_lane_limit(500M)
- General transactions:
- Storage Gas Exemption: Storage creation gas component MUST NOT count toward protocol limits (transaction and block)
- Execution Gas Component: Storage creation operations MUST charge execution gas for computational overhead (writing, hashing)
- Total Cost: Transaction cost MUST equal
(execution_gas + storage_creation_gas) × (base_fee_per_gas + priority_fee) - Gas Split: Storage creation operations MUST split cost into execution gas (computational) and storage creation gas (permanent burden)
- Hot vs Cold: Hot SSTORE (non-zero → non-zero) has NO storage creation gas component; cold SSTORE (zero → non-zero) has both
Changes from TIP-1000
| Parameter | TIP-1000 | TIP-1016 |
|---|---|---|
| Contract code pricing | 1,000 gas/byte | 2,500 gas/byte (200 exec + 2,300 storage) |
| Cold SSTORE pricing | 250,000 gas | 250,000 gas (5,000 exec + 245,000 storage) |
| Account creation pricing | 250,000 gas | 250,000 gas (5,000 exec + 245,000 storage) |
| Storage creation gas counts toward user's gas_limit | Yes | Yes (no change) |
| Storage creation gas counts toward protocol limits | Yes | No (exempted) |
| Execution gas counts toward protocol limits | Yes | Yes (no change) |
| Max transaction gas limit (EIP-7825) | 30M | Can reduce to 16M |
| Block gas limit for execution | 30M | 25M (ideal target) |
| Block gas limit for payments lane | 500M | 500M (unchanged) |
| Block gas limit for storage | 500M (shared) | Unlimited (exempted) |
Key Benefits
- Higher contract code pricing: 2,500 gas/byte (vs 1,000) provides better state growth protection ($50M for 1TB vs $20M)
- Lower protocol transaction limit: Can use 16M max_transaction_gas_limit while deploying 24KB contracts (~7M execution gas counts)
- Better throughput for new accounts: ~19,000 new account transfers/block vs 1,847 in TIP-1000 (~10x improvement)
- Accounts for computational cost: Storage operations still charge execution gas for writing/hashing (not completely free)
- No surprise costs: User's
gas_limitstill bounds total cost (no griefing) - No complexity: Single gas unit, one basefee, existing transaction format works
Economic Impact
| Operation | TIP-1000 Cost | TIP-1016 Cost |
|---|---|---|
| TIP-20 transfer (existing) | ~50k gas = 0.1 cent | ~24k gas = 0.05 cent |
| TIP-20 transfer (new) | ~300k gas = 0.6 cent | ~271k gas = 0.54 cent |
| 1KB contract | ~1.75M gas = 3.5 cents | ~3.25M gas = 6.5 cents |
| 24KB contract | ~30M gas = 60 cents | ~64M gas = 128 cents |
Cost calculations assume base_fee = 2 × 10^10 attodollars (1 token unit = 1 microdollar = 10^-6 USD).
Note: Costs are similar to TIP-1000, but protocol limits now only count execution gas, enabling higher contract code pricing and better throughput.