Skip to content

Commit

Permalink
Major overhaul to conform to EIP Walidator
Browse files Browse the repository at this point in the history
  • Loading branch information
wisecameron committed Dec 19, 2024
1 parent fba51e1 commit a83adc6
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 123 deletions.
247 changes: 124 additions & 123 deletions ERCS/erc-7844.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
---
ERC: 7844
title: "Consolidated Dynamic Storage (CDS)"
description: |
Introduces unbounded storage upgradeability from the contract level --
controlled by function invocations -- by blending extendable structs and dynamic storage spaces
composed of mapping-of-extendable-structs.
author: "Cameron Warnick [[email protected]](mailto:[email protected]), [github.com/wisecameron](https://github.com/wisecameron)"
discussions-to: "https://ethereum-magicians.org/t/erc-7844-consolidated-dynamic-storage-cds/22217"
status: "Draft"
type: "Standards Track"
category: "ERC"
created: "2024-12-13"
requires: "None"
eip: 7844
title: Consolidated Dynamic Storage (CDS)
description: Unbounded in-place storage structure upgradeability managed at the contract level.
author: Cameron Warnick (@wisecameron)
discussions-to: https://ethereum-magicians.org/t/erc-7844-consolidated-dynamic-storage-cds/22217
status: Draft
type: Standards Track
category: ERC
created: 2024-12-13
---

## Abstract
Expand All @@ -27,13 +23,11 @@ CDS achieves this by combining two core features:

This architecture centralizes storage management, enabling seamless storage-level integration for new contracts. By eliminating slot collisions, streamlining upgrades, and enabling dynamic state transparency, CDS is ideal for evolving systems like **DeFi protocols, DAOs**, and **modular frameworks** requiring frequent upgrades.

---

## Motivation

![Scaling CDS](https://github.com/wisecameron/ConsolidatedDynamicStorage/blob/main/images/Scaling%20CDS.png)
![Scaling CDS](../assets/erc-7844/ScalingCDS.png)

The Ethereum ecosystem relies heavily on upgradeable smart contract patterns to enable flexibility in evolving protocols and systems. Contemporary solutions such as **Proxy-Delegate** patterns and the **Diamond Standard (ERC-2535)** have proven their utility but suffer from significant limitations:
The Ethereum ecosystem relies heavily on upgradeable smart contract patterns to enable flexibility in evolving protocols and systems. Contemporary solutions such as **Proxy-Delegate** patterns and the **Diamond Standard ([ERC-2535](https://eips.ethereum.org/EIPS/eip-2535))** have proven their utility but suffer from significant limitations:

Check failure on line 30 in ERCS/erc-7844.md

View workflow job for this annotation

GitHub Actions / EIP Walidator

non-relative link or image

error[markdown-rel-links]: non-relative link or image --> ERCS/erc-7844.md | 30 | The Ethereum ecosystem relies heavily on upgradeable smart contract patterns to enable flexibility in evolving protocols and systems... | = help: use `./eip-2535.md` instead = help: see https://ethereum.github.io/eipw/markdown-rel-links/

1. **Rigid Storage Layouts**:
- Proxy-based models and the Diamond Standard require **predefined storage layouts**. Developers must "reserve space" for potential future fields, which complicates upgrades and wastes storage.
Expand All @@ -46,8 +40,8 @@ The Ethereum ecosystem relies heavily on upgradeable smart contract patterns to
3. **Structural Inefficiency**:
- Proxy-delegate models require a one-to-one mapping between pure contracts and their storage, creating a *spiderweb pattern* of linked contracts. This introduces higher gas costs and added complexity. Additionally, cross-contract calls introduce clear convolution: for instance, a single cross-contract call would invoke: ProxyA, DelegateA, ProxyB, DelegateB. Diamonds can introduce similar convolution: while routing calls through diamonds introduces a consistent entry point, it also creates a bottleneck for growing systems. As more diamonds are introduced, a similar spiderweb pattern takes shape emerge.

![Scaling Proxy Delegate](https://github.com/wisecameron/ConsolidatedDynamicStorage/blob/main/images/Scaling%20Proxy%20Delegate.png)
![Scaling Diamonds](https://github.com/wisecameron/ConsolidatedDynamicStorage/blob/main/images/Scaling%20Diamonds.png)
![Scaling Proxy Delegate](../assets/erc-7844/ScalingProxyDelegate.png)
![Scaling Diamonds](../assets/erc-7844/ScalingDiamonds.png)

4. **Lack of In-Place Solutions**
- Existing solutions present a clear lack of contract-level control over the storage space. In the case of proxy-delegate models, an equivalent to *upgradeable structs* is technically achievable, but requires upgrading and swapping out contracts. For Diamond facets, the situation is more dire, as the storage layout is completely rigid unless paired with a proxy-delegate model.
Expand All @@ -71,13 +65,11 @@ The Ethereum ecosystem relies heavily on upgradeable smart contract patterns to

By solving these limitations, CDS simplifies upgradeability, reduces gas costs, and eliminates storage layout constraints, empowering developers to build evolving systems like DeFi protocols, modular frameworks, and DAOs with greater flexibility and confidence.

![Adaptability](https://github.com/wisecameron/ConsolidatedDynamicStorage/blob/main/images/Adaptability.png)
![Adaptability](../assets/erc-7844/Adaptability.png)

---
## Specification

## Specification

### Extendable Structs and Storage Spaces
**Extendable Structs and Storage Spaces**

- Extendable structs leverage dynamic mappings with deterministic field hashes (`keccak256`).
- The base struct remains immutable, while fields can be dynamically appended.
Expand Down Expand Up @@ -180,10 +172,99 @@ function insert_new_member(
}
```

## Interfaces

Check failure on line 175 in ERCS/erc-7844.md

View workflow job for this annotation

GitHub Actions / EIP Walidator

body has extra section(s)

error[markdown-order-section]: body has extra section(s) --> ERCS/erc-7844.md | 175 | ## Interfaces | ::: ERCS/erc-7844.md | 264 | ## Initialization | ::: ERCS/erc-7844.md | 360 | ## Gas Benchmarks (HoneyBadger) | = help: see https://ethereum.github.io/eipw/markdown-order-section/

```solidity
    function init_create(
    uint256[] memory types,
    uint256[] memory sizes
) external;
    function insert_new_member(
    uint256 valType,
    uint256 size,
    uint256 storageSpace
) external;
function push(
uint256 storageSpace
) external;
function pushMany(
    uint256 amount,
    uint256 storageSpace
) external;
function put(
    uint256 data,
    uint256 memberIndex,
    uint256 entryIndex,
    uint256 storageSpace
) external;
function put_string(
string memory data,
uint256 memberIndex,
uint256 entryIndex,
uint256 storageSpace
) external;
(optional) function put_batch(
   uint256[] memory values,
   uint256[] memory members,
   uint256 entryIndex,
   uint256 storageSpace
) external;
function get(
    uint256 memberIndex,
    uint256 entryIndex,
    uint256 storageSpace
) external view returns(uint256);
function get_string(
    uint256 memberIndex,
    uint256 entryIndex,
    uint256 storageSpace
) external view returns(string memory returnValue);
(optional) function get_batch(
    uint256[] memory members,
    uint256 entryIndex,
    uint256 storageSpace
) external view returns(uint256[] memory result);
function get_storage_space_state_data(
    uint256 storageSpace
) external view returns(
uint256 members,
uint256 entries,
uint256 stringIndex,
uint256 safeIndex
);
function total_members(
    uint256 storageSpace
) external view returns(uint256);
/**
* For string, bitCount->stringIndex, size param is extraneous.
*/
function get_member_data(
uint256 memberIndex,
uint256 storageSpace
) external view returns(
uint256 bitCount,
uint256 valSize,
uint256 valType,
)
```

## Initialization

![Basic Interaction Flow](https://github.com/wisecameron/ConsolidatedDynamicStorage/blob/main/images/Basic_interaction_flow_CDS.png)
![CDS Init, Extension](https://github.com/wisecameron/ConsolidatedDynamicStorage/blob/main/images/CDS%20Init,%20Extension.png)
![Basic Interaction Flow](../assets/erc-7844/BasicInteractionFlow.png)
![CDS Init, Extension](../assets/erc-7844/CDSInitExpansion.png)
Getting a finished system up and running is straightforward. The `init_create` function handles storage space creation in both an initialization and live extension setting. The function takes an array of types and sizes, which must conform to the above specifications, and be equivalent in length.

```solidity
Expand Down Expand Up @@ -215,96 +296,6 @@ function init_create(
storageSpaces += 1
}
```
## Interface

```solidity
    function init_create(
    uint256[] memory types,
    uint256[] memory sizes
) external;
    function insert_new_member(
    uint256 valType,
    uint256 size,
    uint256 storageSpace
) external;
function push(
uint256 storageSpace
) external;
    function pushMany(
    uint256 amount,
    uint256 storageSpace
) external;
    function put(
    uint256 data,
    uint256 memberIndex,
    uint256 entryIndex,
    uint256 storageSpace
) external;
function put_string(
string memory data,
uint256 memberIndex,
uint256 entryIndex,
uint256 storageSpace
) external;
   (optional) function put_batch(
   uint256[] memory values,
   uint256[] memory members,
   uint256 entryIndex,
   uint256 storageSpace
) external;
    function get(
    uint256 memberIndex,
    uint256 entryIndex,
    uint256 storageSpace
) external view returns(uint256);
    function get_string(
    uint256 memberIndex,
    uint256 entryIndex,
    uint256 storageSpace
) external view returns(string memory returnValue);
    (optional) function get_batch(
    uint256[] memory members,
    uint256 entryIndex,
    uint256 storageSpace
) external view returns(uint256[] memory result);
    function get_storage_space_state_data(
    uint256 storageSpace
) external view returns(
uint256 members,
uint256 entries,
uint256 stringIndex,
uint256 safeIndex
);
    function total_members(
    uint256 storageSpace
) external view returns(uint256);
/**
* For string, bitCount->stringIndex, size param is extraneous.
/*
function get_member_data(
uint256 memberIndex,
uint256 storageSpace
) external view returns(
uint256 bitCount,
uint256 valSize,
uint256 valType,
)
```

---

## Rationale

Expand All @@ -317,18 +308,15 @@ function init_create(

In short, CDS trades initial complexity for **long-term efficiency, safety, and flexibility**—a tradeoff that is more than justified for systems requiring cutting-edge upgradeability. As audited, plug-and-play implementations become available, CDS will become an **accessible and powerful tool** for developers building systems that demand efficiency and capabilities beyond what is currently accessible.

### **Why Not Diamond Storage?**
**Why Use CDS When Diamond Storage Exists?**

The **Diamond Standard (ERC-2535)** modularizes smart contract logic elegantly, but retains a rigid storage model. While facets can be upgraded post-deployment, **the storage layout itself remains static**. To mirror the capabilities of CDS, the Diamond storage layer would require its own proxy-delegate solution up-front. Developers would need to swap the diamond delegate, then re-connect all of its linked contracts. *In a production environment, this process represents both cost and risk.*
The **Diamond Standard ([ERC-2535](https://eips.ethereum.org/EIPS/eip-2535))** modularizes smart contract logic elegantly, but retains a rigid storage model. While facets can be upgraded post-deployment, **the storage layout itself remains static**. To mirror the capabilities of CDS, the Diamond storage layer would require its own proxy-delegate solution up-front. Developers would need to swap the diamond delegate, then re-connect all of its linked contracts. *In a production environment, this process represents both cost and risk.*

Check failure on line 313 in ERCS/erc-7844.md

View workflow job for this annotation

GitHub Actions / EIP Walidator

non-relative link or image

error[markdown-rel-links]: non-relative link or image --> ERCS/erc-7844.md | 313 | The **Diamond Standard ([ERC-2535](https://eips.ethereum.org/EIPS/eip-2535))** modularizes smart contract logic elegantly, but reta... | = help: use `./eip-2535.md` instead

---

## Backwards Compatibility

This ERC introduces a new design pattern and does not interfere with existing Solidity implementations. CDS *does* *not* implicitly interfere with common libraries such as those provided by OpenZeppelin, but is not supported explicitly. Library-imposed global data within linked contracts leveraging

---

## **Test Cases**

### **1. Core Functionality**
Expand Down Expand Up @@ -382,8 +370,21 @@ This ERC introduces a new design pattern and does not interfere with existing So
`put_batch([20, 20], [0, 1], 0, 0):` 22,895 gas
`get`: 9374 gas

---

## Implementation
## Reference Implementation

Refer to [CDS Minimal Example](https://github.com/wisecameron/ConsolidatedDynamicStorage/blob/main/contracts/CDSMinimal.sol)

Check failure on line 376 in ERCS/erc-7844.md

View workflow job for this annotation

GitHub Actions / EIP Walidator

non-relative link or image

error[markdown-rel-links]: non-relative link or image --> ERCS/erc-7844.md | 376 | Refer to [CDS Minimal Example](https://github.com/wisecameron/ConsolidatedDynamicStorage/blob/main/contracts/CDSMinimal.sol) |

## Security Considerations

While a CDS implementation imposes considerable overhead in terms of up-front effort, comprehensively addressing security risks is relatively straightforward.

**Hash Structure and Masking** Validate your hash structure and masks stringently. It is recommended to manually verify each operation at least once. Fuzzing the `init` and `insert_new_member` operations is also highly-advised. While the widespread utilization of complex assembly operations seems daunting, this process is more tedious than it is complicated. The key is to be diligent - it will either work, or it won't.

**Access Control** It is highly recommended to fully lock the system with a permission management scheme. The most basic example would be to use a `mapping(address -> boolean) hasPerms` with a related modifier. Users who lack authorization should never have direct access to the system, including view functions. In the case of views, we prevent access because there is no need for non-users to have insight into your storage space scheme. It is recommended to use an abstraction layer via an additional contract to ensure that this information is abstracted away, and that users can't pry into data they shouldn't have access to.

**Types and Sizes** Types and sizes also represent an important vulnerability point. It is crucial to verify that types are within bounds, and to thoroughly verify that values conform to expected size(s). It is best practice to revert when encountering an incorrect size (ie; boolean, size 16) rather than correcting it in-place.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
Binary file added assets/erc-7844/Adaptability.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/erc-7844/BasicInteractionFlow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/erc-7844/CDSInitExpansion.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/erc-7844/ScalingCDS.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/erc-7844/ScalingDiamonds.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/erc-7844/ScalingProxyDelegate.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit a83adc6

Please sign in to comment.