Alert Source Discuss
⚠️ Draft Standards Track: Core

EIP-7519: Atomic Storage Operations SCREDIT and SDEBIT

Add atomic operations for incrementing and decrementing storage slots

Authors Danno Ferrin (@shemnon)
Created 2023-09-16
Discussion Link https://ethereum-magicians.org/t/eip-7519-atomic-storage-operations-scredit-and-sdebit/15818
Requires EIP-2200, EIP-2929

Abstract

Two new opcodes that atomically mutate smart contract storage are proposed: SCREDIT, which increments a storage slot by a specified value, and SDEBIT, which decrements a storage slot by a specified value. Overflow and underflow errors are enforced, reverting when an unsigned 256-bit integer would overflow or underflow.

Motivation

There has been a large amount of energy around parallel EVMs across multiple chains, however there is a lack of parallel primitives within the EVM to support any model other than optimistic concurrency control (OCC). By adding concurrent increment and decrement operations more advanced parallel environments can be introduced in Layer 2 networks.

This also provides the opportunity to serve the principal use case of increment and decrement: token balances. We can introduce failures on overflow and underflow conditions and provide an operation that is also useful outside of parallel use cases.

Specification

Two operations to atomically increment and decrement a storage will be introduced at 0xTBD. Each operation takes two stack arguments and has no immediate arguments. Gas schedule will be the same as SSTORE.

Mnemonic Op Input Output
SCREDIT 0xTBD 2 0
SDEBIT 0xTBD+1 2 0

SCREDIT

SCREDIT: slot, value

Description

Adds value to the value stored in contract storage slot. If an overflow would occur the operation halts exceptionally.

Gas Charging

Gas charging is identical to SSTORE. including interactions with the warm storage slot list. Any future modifications to the SSTORE gas charges will also apply to SCREDIT.

Execution

Not valid python, not suitable for EELS yet

slot = evm_stack.pop()
value = evm_stack.pop()

storage_value = read_contract_storage(slot)
storage_value = storage_value + value

if storage_value >= 2**256 :
  raise Exception("scredit overflow")
 
write_contract_storage(storage_value)

SDEBIT

SDEBIT: slot, value

Description

Subtracts value to the value stored in contract storage slot. If an underflow would occur the operation halts exceptionally.

Gas Charging

Gas charging is identical to SSTORE, including interactions with the warm storage slot list. Any future modifications to the SSTORE gas charges will also apply to SDEBIT.

Execution

Not valid python, not suitable for EELS yet

slot = evm_stack.pop()
value = evm_stack.pop()

storage_value = read_contract_storage(slot)
storage_value = storage_value - value

if storage_value < 0 :
  raise Exception("sdebit underflow")
 
write_contract_storage(storage_value)

Rationale

The primary consideration when choosing between alternatives is that the primary intended audiences is token contracts and other asset-tracking contracts combined with a desire to ship the minimum necessary changes to enable that use case. General concurrency controls is not a goal of this EIP.

Enforcing Overflow Semantics

When allowing for out-of-order execution there needs to be mechanism to handle any possible order of execution. OCC handles this by validating pre- and post-conditions, and re-evaluating the transactions if those invariants did not hold. This technique breaks down around writing to balances and counters.

Increment/decrement with rollover checking allows for simple handling of balances and counters while allowing for functional read support ensuring that sufficient balance or count exists without depending on the exact values. This allows for evaluation models where the only post-condition checked is to validate that the storage slots could handle all possible re-ordering of transactions.

Gas Schedule

The decision to cost the operations at the exact same value as SSTORE is partly for ease of implementation and partly as an incentive to compilers and developers.

These semantics could be implemented in the EVM today, but it would also include a SLOAD, DUP, LT, JUMPI and REVERT instructions. The EVM, however, can do these operations much more efficiently than via opcodes. First, each SSTORE always incurs a slot load in order to apply EIP-2200 gas calculation rules. This load is essential if there is no paired SLOAD. Math libraries for 256-bit numbers can all easily be made sensitive to overflow and underflow, if they are not already present. Conditional logic handling is also much faster in the operation logic as most of the overhead would be operation parsing and stack management when interpreted.

The net impact of the most relevant operations to the most expensive evaluation (an ADD and LT operation, above the cost of a plain SSTORE) would be 4 gas, or 0.2% of the current cost of a SSTORE. Finally, database access costs dominate the real cost of the operation. A 0.2% overhead may disappear in I/O stalls.

Keeping the cost the same makes implementations of gas charging vert simple.

Storage Slots Only

This most important use case for this EIP asset balances and not general concurrency controls. Hence, only enabling credit and debit operations on storage slots (which persist across transactions). Parallel execution within a transaction and more generic tools like locks and semaphores have very limited utility within this scope. The lack of in-transaction parallel execution also precludes the use of such primitives against transient storage (as defined in EIP-1153).

Opcode Instead of System Contract

One alternative, particularly viable for Layer 2 chains, would be to implement SCREDIT and SDEBIT as system contracts. The primary objection to system contracts for other operations is the gas cost overhead of constructing a call. Because a SSTORE is always greater than the cost of a call it would be possible to build in a discount. However, there is no such accommodation that can be made for the code size needed to invoke such a call.

Backwards Compatibility

These opcodes are not simple replacements for SLOAD-(ADD|SUB)-SSTORE sequence because there is an overflow/underflow check

There is no EVM functionality removed by this proposal.

Test Cases

Test for overflow and non-overflow for the following values and values before and after:

1, 2^8, 2^16, 2^32, 2^64, 2^128 2^255, 2^256-1.

Reference Implementation

/# TBD

Security Considerations

The use of revert to handle over/underflow represents a new halt condition that auditors will need to consider when examining reentrancy concerns.

Copyright and related rights waived via CC0.

Citation

Please cite this document as:

Danno Ferrin (@shemnon), "EIP-7519: Atomic Storage Operations SCREDIT and SDEBIT [DRAFT]," Ethereum Improvement Proposals, no. 7519, September 2023. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7519.