Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
131 commits
Select commit Hold shift + click to select a range
9eb5f1c
Add memory utils
ernestognw Sep 4, 2024
2d397f4
Fix tests upgradeable
ernestognw Sep 4, 2024
2a0fb7e
Add docs
ernestognw Sep 5, 2024
a7e61c3
Make use of the library
ernestognw Sep 5, 2024
1aae8bb
Update docs/modules/ROOT/pages/utilities.adoc
ernestognw Oct 9, 2024
1b2679a
Merge branch 'master' into utils/memory
Amxx Mar 6, 2025
d514606
fix tests
Amxx Mar 6, 2025
14fa04e
Update contracts/utils/Memory.sol
ernestognw May 7, 2025
d0d55fc
Update contracts/utils/Memory.sol
arr00 May 7, 2025
7b3cb66
Add RLP library
ernestognw May 10, 2025
95149f8
Add TrieProof library
ernestognw May 11, 2025
ad5d4ac
up
ernestognw May 11, 2025
18540ef
Add docs
ernestognw May 11, 2025
163f27c
Workaround stack too deep
ernestognw May 24, 2025
c484289
Add Changesets
ernestognw May 29, 2025
e0d4790
Add more changesets
ernestognw Jun 7, 2025
a6f9053
Add FV and fuzz tests
ernestognw Jun 7, 2025
e2b5e4c
Merge branch 'master' into feature/rlp
ernestognw Jun 7, 2025
203d1a2
up
ernestognw Jun 7, 2025
48eabc1
docs
ernestognw Jun 7, 2025
63ced95
up pragma
ernestognw Jun 7, 2025
f342756
Add missing Bytes test
ernestognw Jun 7, 2025
23dba37
Add unit tests
ernestognw Jun 7, 2025
0cacca2
up pragma
ernestognw Jun 7, 2025
831e8ab
Move TrieProof
ernestognw Jun 7, 2025
5da111f
Fix countLeadingZeroes
ernestognw Jun 8, 2025
ba2293e
nits
ernestognw Jun 8, 2025
9409bc6
Improve
ernestognw Jun 8, 2025
e740dac
Fix
ernestognw Jun 8, 2025
0332ffe
Add Memory.sol library
ernestognw Jun 8, 2025
608e3cd
Merge branch 'master' into utils/memory
ernestognw Jun 8, 2025
ac92bb4
up
ernestognw Jun 8, 2025
6094bb7
Merge branch 'master' into utils/memory
ernestognw Jun 8, 2025
6bb96d5
WIP: Add more Memory functions
ernestognw Jun 8, 2025
860e5a8
up
ernestognw Jun 8, 2025
ecdb768
revert
ernestognw Jun 8, 2025
95907aa
Update docs
ernestognw Jun 8, 2025
124ccee
Nit
ernestognw Jun 8, 2025
c3237df
Finish fuzz tests and FV
ernestognw Jun 9, 2025
27f0a9b
up
ernestognw Jun 9, 2025
282ce39
up
ernestognw Jun 9, 2025
bdd2cf1
Add operations to Math.sol
ernestognw Jun 9, 2025
42c79f1
Add new equal, nibbles and countLeadingZeroes functions
ernestognw Jun 9, 2025
5754ab8
Rename countLeadingZeroes to clz
ernestognw Jun 9, 2025
44f0e14
up
ernestognw Jun 9, 2025
05c73bd
Pragma changes
ernestognw Jun 9, 2025
3a6fbf6
up
ernestognw Jun 9, 2025
e67e8b4
up
ernestognw Jul 4, 2025
3385718
Rename to in Math library and update corresponding tests for consis…
ernestognw Jul 9, 2025
40d7922
Update return types of reverseBits functions to match their respectiv…
ernestognw Jul 9, 2025
89860bc
Refactor reverseBits functions in to use fixed-size byte types
ernestognw Jul 9, 2025
9b58730
Test nits
ernestognw Jul 9, 2025
77ffa8c
Simplify
ernestognw Jul 9, 2025
ce91c80
up
ernestognw Jul 9, 2025
b3e3add
Move reverse functions to Bytes.sol
ernestognw Jul 9, 2025
2f3107c
Move Bytes.t.sol
ernestognw Jul 9, 2025
4383e01
Merge branch 'master' into feat/bytes-rlp
ernestognw Jul 9, 2025
5a44b11
up
ernestognw Jul 9, 2025
d6db2d7
Document
ernestognw Jul 9, 2025
3847050
Remove extra functions
ernestognw Jul 9, 2025
4fd1947
Update docs
ernestognw Jul 9, 2025
c4e0375
up
ernestognw Jul 9, 2025
acb14cb
Merge branch 'utils/memory' into feature/rlp
ernestognw Jul 9, 2025
2208006
Merge branch 'feat/math-reverse-bits' into feature/rlp
ernestognw Jul 9, 2025
13f4d8f
Merge branch 'feat/bytes-rlp' into feature/rlp
ernestognw Jul 9, 2025
502a520
Merge branch 'master' into feature/rlp
ernestognw Jul 12, 2025
aab9274
Merge branch 'master' into feature/rlp
Amxx Jul 15, 2025
aa26e48
up
Amxx Jul 15, 2025
948f0a1
Merge branch 'master' into feature/rlp
ernestognw Jul 31, 2025
d4bfb8b
Fix compilation
ernestognw Jul 31, 2025
138de7f
Remove dangling clz
ernestognw Jul 31, 2025
5efeb37
Make nibbles function private
ernestognw Jul 31, 2025
00ff228
Remove nibbles test
ernestognw Jul 31, 2025
c58c7fd
Remove TrieProof library
ernestognw Jul 31, 2025
d1aa944
Add some tests
ernestognw Aug 1, 2025
0925577
Merge branch 'master' into feature/rlp
ernestognw Aug 26, 2025
590b7d7
Use Bytes.concat
ernestognw Aug 26, 2025
8928039
Use Math.ternary
ernestognw Aug 27, 2025
bb027df
refactor encoding to reduce memory allocation
Amxx Sep 4, 2025
ec4a5c1
refactor tests to use ethers.encodeRlp as a reference
Amxx Sep 4, 2025
b75dc7c
fix comments
Amxx Sep 4, 2025
fc208c8
use mstore8 to avoid shift
Amxx Sep 4, 2025
fe0597c
decoding works
Amxx Sep 6, 2025
106764e
Add Memory.slice and refactor RLP read/decode
Amxx Sep 6, 2025
b55b1db
testing
Amxx Sep 6, 2025
e490d79
inspired by
Amxx Sep 6, 2025
bde8251
remove unecessary imports
Amxx Sep 6, 2025
8b6ea8c
read bool and string
Amxx Sep 7, 2025
dba642d
Bytes.Accumulator & RLP.encoder
Amxx Sep 8, 2025
5e3ce7c
reorder
Amxx Sep 8, 2025
4d39206
Merge branch 'master' into feature/rlp
Amxx Sep 10, 2025
902b222
document Bytes.accumulator
Amxx Sep 10, 2025
b301b06
pragma fix
Amxx Sep 10, 2025
1b112b2
mock stateless
Amxx Sep 10, 2025
9c0e924
slither
Amxx Sep 10, 2025
c48e623
Memory slice doc
Amxx Sep 10, 2025
b10ae8c
Update enums.js
Amxx Sep 10, 2025
d411318
avoid load error
Amxx Sep 10, 2025
df528af
fuzz test Memory slices
Amxx Sep 10, 2025
da61a5e
coverage
Amxx Sep 10, 2025
fadc8ac
Merge branch 'master' into feature/rlp
Amxx Sep 15, 2025
283ce7c
remove unused code
Amxx Sep 15, 2025
5561d52
Merge branch 'feature/rlp' of https://github.com/ernestognw/openzeppe…
Amxx Sep 15, 2025
33b57b5
Move Bytes.Accumulator to a dedicated file in utils/structs
Amxx Sep 15, 2025
8b86b1b
add changeset entry
Amxx Sep 15, 2025
785ae84
Update test/utils/Bytes.t.sol
Amxx Sep 15, 2025
452d4b8
Update .changeset/wise-webs-fly.md
Amxx Sep 15, 2025
00af6a4
pragma
Amxx Sep 16, 2025
27dd119
update solidity-coverage
Amxx Sep 16, 2025
93f4d4b
add slice support to Accumulator
Amxx Sep 16, 2025
0e503b4
revert solidity-coverage update
Amxx Sep 16, 2025
9cfaceb
Update .changeset/modern-moments-raise.md
Amxx Sep 17, 2025
07f5db8
move fuzzing test
Amxx Sep 17, 2025
8534802
zero out-of-slice bytes when doing load(Slice,uint256)
Amxx Sep 17, 2025
c3df360
doc
Amxx Sep 17, 2025
8c98d4a
dec -> hex
Amxx Sep 17, 2025
6efa28d
up
ernestognw Sep 17, 2025
7478616
Reorder private functions
ernestognw Sep 18, 2025
fb62ca3
Docs
ernestognw Sep 18, 2025
698221f
Add to CHANGELOG
ernestognw Sep 18, 2025
5fa4c3e
Merge branch 'master' into feature/rlp
ernestognw Sep 18, 2025
2bd9cc4
Delete .changeset/lovely-cooks-add.md
ernestognw Sep 18, 2025
fefd039
Uncomment invalid tests
ernestognw Sep 18, 2025
f2e5c81
up
ernestognw Sep 18, 2025
ff4c153
dynamic allocation of space for lists
Amxx Sep 18, 2025
dd242c2
use a single custom error
Amxx Sep 18, 2025
46914e9
Update contracts/utils/RLP.sol
Amxx Sep 18, 2025
fdcb15f
Memory pointer equality
Amxx Sep 18, 2025
0c5d508
test panic code of out-of-bound slice operations
Amxx Sep 19, 2025
42dd3d3
Avoid Accumulators NatSpec to show up on docs sidebar
ernestognw Sep 19, 2025
371595d
Pointer forward
Amxx Sep 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/itchy-turkeys-allow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'openzeppelin-solidity': minor
---

`RLP`: Add a library for encoding and decoding data in Ethereum's Recursive Length Prefix format.
5 changes: 5 additions & 0 deletions .changeset/modern-moments-raise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'openzeppelin-solidity': minor
---

`Memory`: Add a UDVT for handling slices on memory space similarly to calldata slices.
5 changes: 5 additions & 0 deletions .changeset/wise-webs-fly.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'openzeppelin-solidity': minor
---

`Accumulators`: A library for merging an arbitrary dynamic number of bytes buffers.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
### Breaking changes

- `SignerERC7702` is renamed as `SignerEIP7702`. Imports and inheritance must be updated to that new name and path. Behavior is unmodified.
- Update minimum pragma to 0.8.24 in `Votes`, `VotesExtended`, `ERC20Votes`, `Strings`, `ERC1155URIStorage`, `MessageHashUtils`, `ERC721URIStorage`, `ERC721Votes`, `ERC721Wrapper`, `ERC721Burnable`, `ERC721Consecutive`, `ERC721Enumerable`, `ERC721Pausable`, `ERC721Royalty`, `ERC721Wrapper`, `EIP712`, and `ERC7739`. ([#5726](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5726))
- Update minimum pragma to 0.8.24 in `Votes`, `VotesExtended`, `ERC20Votes`, `Strings`, `ERC1155URIStorage`, `MessageHashUtils`, `ERC721URIStorage`, `ERC721Votes`, `ERC721Wrapper`, `ERC721Burnable`, `ERC721Consecutive`, `ERC721Enumerable`, `ERC721Pausable`, `ERC721Royalty`, `ERC721Wrapper`, `EIP712`, `ERC4626` and `ERC7739`. ([#5726](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5726))

### Deprecation

Expand Down
2 changes: 2 additions & 0 deletions contracts/mocks/Stateless.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity ^0.8.26;

// We keep these imports and a dummy contract just to we can run the test suite after transpilation.

import {Accumulators} from "../utils/structs/Accumulators.sol";
import {Address} from "../utils/Address.sol";
import {Arrays} from "../utils/Arrays.sol";
import {AuthorityUtils} from "../access/manager/AuthorityUtils.sol";
Expand Down Expand Up @@ -44,6 +45,7 @@ import {P256} from "../utils/cryptography/P256.sol";
import {Packing} from "../utils/Packing.sol";
import {Panic} from "../utils/Panic.sol";
import {RelayedCall} from "../utils/RelayedCall.sol";
import {RLP} from "../utils/RLP.sol";
import {RSA} from "../utils/cryptography/RSA.sol";
import {SafeCast} from "../utils/math/SafeCast.sol";
import {SafeERC20} from "../token/ERC20/utils/SafeERC20.sol";
Expand Down
2 changes: 1 addition & 1 deletion contracts/token/ERC20/extensions/ERC4626.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/ERC4626.sol)

pragma solidity ^0.8.20;
pragma solidity ^0.8.24;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason for this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're keeping it we should add it to the changelog. I did in 698221f

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This imports memory, and memory needs 0.24 because it does mcopy


import {IERC20, IERC20Metadata, ERC20} from "../ERC20.sol";
import {SafeERC20} from "../utils/SafeERC20.sol";
Expand Down
96 changes: 93 additions & 3 deletions contracts/utils/Memory.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;
pragma solidity ^0.8.24;

import {Panic} from "./Panic.sol";
import {Math} from "./math/Math.sol";

/**
* @dev Utilities to manipulate memory.
*
* Memory is a contiguous and dynamic byte array in which Solidity stores non-primitive types.
* This library provides functions to manipulate pointers to this dynamic array.
* This library provides functions to manipulate pointers to this dynamic array and work with slices of it.
*
* Slices provide a view into a portion of memory without copying data, enabling efficient substring operations.
*
* WARNING: When manipulating memory, make sure to follow the Solidity documentation
* WARNING: When manipulating memory pointers or slices, make sure to follow the Solidity documentation
* guidelines for https://docs.soliditylang.org/en/v0.8.20/assembly.html#memory-safety[Memory Safety].
*/
library Memory {
Expand Down Expand Up @@ -41,4 +46,89 @@ library Memory {
function asPointer(bytes32 value) internal pure returns (Pointer) {
return Pointer.wrap(value);
}

/// @dev Move a pointer forward by a given offset.
function forward(Pointer ptr, uint256 offset) internal pure returns (Pointer) {
return Pointer.wrap(bytes32(uint256(Pointer.unwrap(ptr)) + offset));
}

/// @dev Equality comparator for memory pointers.
function equal(Pointer ptr1, Pointer ptr2) internal pure returns (bool) {
return Pointer.unwrap(ptr1) == Pointer.unwrap(ptr2);
}

type Slice is bytes32;

/// @dev Get a slice representation of a bytes object in memory
function asSlice(bytes memory self) internal pure returns (Slice result) {
assembly ("memory-safe") {
result := or(shl(128, mload(self)), add(self, 0x20))
}
}

/// @dev Returns the length of a given slice (equiv to self.length for calldata slices)
function length(Slice self) internal pure returns (uint256 result) {
assembly ("memory-safe") {
result := shr(128, self)
}
}

/// @dev Offset a memory slice (equivalent to self[start:] for calldata slices)
function slice(Slice self, uint256 offset) internal pure returns (Slice) {
if (offset > length(self)) Panic.panic(Panic.ARRAY_OUT_OF_BOUNDS);
return _asSlice(length(self) - offset, forward(_pointer(self), offset));
}

/// @dev Offset and cut a Slice (equivalent to self[start:start+length] for calldata slices)
function slice(Slice self, uint256 offset, uint256 len) internal pure returns (Slice) {
if (offset + len > length(self)) Panic.panic(Panic.ARRAY_OUT_OF_BOUNDS);
return _asSlice(len, forward(_pointer(self), offset));
}

/**
* @dev Read a bytes32 buffer from a given Slice at a specific offset
*
* NOTE: If offset > length(slice) - 0x20, part of the return value will be out of bound of the slice. These bytes are zeroed.
*/
function load(Slice self, uint256 offset) internal pure returns (bytes32 value) {
uint256 outOfBoundBytes = Math.saturatingSub(0x20 + offset, length(self));
if (outOfBoundBytes > 0x1f) Panic.panic(Panic.ARRAY_OUT_OF_BOUNDS);

assembly ("memory-safe") {
value := and(mload(add(and(self, shr(128, not(0))), offset)), shl(mul(8, outOfBoundBytes), not(0)))
}
}

/// @dev Extract the data corresponding to a Slice (allocate new memory)
function toBytes(Slice self) internal pure returns (bytes memory result) {
uint256 len = length(self);
Memory.Pointer ptr = _pointer(self);
assembly ("memory-safe") {
result := mload(0x40)
mstore(result, len)
mcopy(add(result, 0x20), ptr, len)
mstore(0x40, add(add(result, len), 0x20))
}
}

/**
* @dev Private helper: create a slice from raw values (length and pointer)
*
* NOTE: this function MUST NOT be called with `len` or `ptr` that exceed `2**128-1`. This should never be
* the case of slices produced by `asSlice(bytes)`, and function that reduce the scope of slices
* (`slice(Slice,uint256)` and `slice(Slice,uint256, uint256)`) should not cause this issue if the parent slice is
* correct.
*/
function _asSlice(uint256 len, Memory.Pointer ptr) private pure returns (Slice result) {
assembly ("memory-safe") {
result := or(shl(128, len), ptr)
}
}

/// @dev Returns the memory location of a given slice (equiv to self.offset for calldata slices)
function _pointer(Slice self) private pure returns (Memory.Pointer result) {
assembly ("memory-safe") {
result := and(self, shr(128, not(0)))
}
}
}
6 changes: 6 additions & 0 deletions contracts/utils/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Miscellaneous contracts and libraries containing utility functions you can use t
* {ReentrancyGuard}: A modifier that can prevent reentrancy during certain functions.
* {ReentrancyGuardTransient}: Variant of {ReentrancyGuard} that uses transient storage (https://eips.ethereum.org/EIPS/eip-1153[EIP-1153]).
* {ERC165}, {ERC165Checker}: Utilities for inspecting interfaces supported by contracts.
* {Accumulators}: A library for merging an arbitrary dynamic number of bytes buffers.
* {BitMaps}: A simple library to manage boolean value mapped to a numerical index in an efficient way.
* {Checkpoints}: A data structure to store values mapped to a strictly increasing key. Can be used for storing and accessing values over time.
* {CircularBuffer}: A data structure to store the last N values pushed to it.
Expand All @@ -38,6 +39,7 @@ Miscellaneous contracts and libraries containing utility functions you can use t
* {Packing}: A library for packing and unpacking multiple values into bytes32.
* {Panic}: A library to revert with https://docs.soliditylang.org/en/v0.8.20/control-structures.html#panic-via-assert-and-error-via-require[Solidity panic codes].
* {RelayedCall}: A library for performing calls that use minimal and predictable relayers to hide the sender.
* {RLP}: Library for encoding and decoding data in Ethereum's Recursive Length Prefix format.
* {ShortStrings}: Library to encode (and decode) short strings into (or from) a single bytes32 slot for optimizing costs. Short strings are limited to 31 characters.
* {SlotDerivation}: Methods for deriving storage slot from ERC-7201 namespaces as well as from constructions such as mapping and arrays.
* {StorageSlot}: Methods for accessing specific storage slots formatted as common primitive types.
Expand Down Expand Up @@ -84,6 +86,8 @@ Ethereum contracts have no native concept of an interface, so applications must

== Data Structures

{{Accumulators}}

{{BitMaps}}

{{Checkpoints}}
Expand Down Expand Up @@ -138,6 +142,8 @@ Ethereum contracts have no native concept of an interface, so applications must

{{RelayedCall}}

{{RLP}}

{{ShortStrings}}

{{SlotDerivation}}
Expand Down
Loading