From a0246fde7bc083e9cbce786aa625db750e78f70e Mon Sep 17 00:00:00 2001 From: ernestognw Date: Fri, 25 Apr 2025 13:18:35 -0600 Subject: [PATCH 1/4] Remove Arrays library usage from EnumerableSetExtended --- .../utils/structs/EnumerableSetExtended.sol | 29 +++++++++++++++++-- lib/forge-std | 2 +- scripts/generate/templates/Enumerable.opts.js | 1 + .../templates/EnumerableSetExtended.js | 17 +++++++++-- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/contracts/utils/structs/EnumerableSetExtended.sol b/contracts/utils/structs/EnumerableSetExtended.sol index cc38406b..82a9f85e 100644 --- a/contracts/utils/structs/EnumerableSetExtended.sol +++ b/contracts/utils/structs/EnumerableSetExtended.sol @@ -3,7 +3,6 @@ pragma solidity ^0.8.20; -import {Arrays} from "@openzeppelin/contracts/utils/Arrays.sol"; import {Hashes} from "@openzeppelin/contracts/utils/cryptography/Hashes.sol"; /** @@ -121,7 +120,19 @@ library EnumerableSetExtended { for (uint256 i = 0; i < len; ++i) { delete set._positions[set._values[i]]; } - Arrays.unsafeSetLength(set._values, 0); + unsafeSetLength(set._values, 0); + } + + /** + * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden. + * + * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased. + */ + // Replace when these are available in Arrays.sol + function unsafeSetLength(string[] storage array, uint256 len) internal { + assembly ("memory-safe") { + sstore(array.slot, len) + } } /** @@ -241,7 +252,19 @@ library EnumerableSetExtended { for (uint256 i = 0; i < len; ++i) { delete set._positions[set._values[i]]; } - Arrays.unsafeSetLength(set._values, 0); + unsafeSetLength(set._values, 0); + } + + /** + * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden. + * + * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased. + */ + // Replace when these are available in Arrays.sol + function unsafeSetLength(bytes[] storage array, uint256 len) internal { + assembly ("memory-safe") { + sstore(array.slot, len) + } } /** diff --git a/lib/forge-std b/lib/forge-std index 6abf6698..841c3a3e 160000 --- a/lib/forge-std +++ b/lib/forge-std @@ -1 +1 @@ -Subproject commit 6abf66980050ab03a35b52bdab814f55001d6929 +Subproject commit 841c3a3e8b7612f76599797b93da5a61899c2aa8 diff --git a/scripts/generate/templates/Enumerable.opts.js b/scripts/generate/templates/Enumerable.opts.js index 0691b8d5..0b503d07 100644 --- a/scripts/generate/templates/Enumerable.opts.js +++ b/scripts/generate/templates/Enumerable.opts.js @@ -11,6 +11,7 @@ const typeDescr = ({ type, size = 0, memory = false }) => { }; const toSetTypeDescr = value => ({ + underlying: value.name.toLowerCase(), name: value.name + 'Set', value, }); diff --git a/scripts/generate/templates/EnumerableSetExtended.js b/scripts/generate/templates/EnumerableSetExtended.js index 54d56f80..05e00740 100644 --- a/scripts/generate/templates/EnumerableSetExtended.js +++ b/scripts/generate/templates/EnumerableSetExtended.js @@ -4,7 +4,6 @@ const { SET_TYPES } = require('./Enumerable.opts'); const header = `\ pragma solidity ^0.8.20; -import {Arrays} from "@openzeppelin/contracts/utils/Arrays.sol"; import {Hashes} from "@openzeppelin/contracts/utils/cryptography/Hashes.sol"; /** @@ -46,7 +45,7 @@ import {Hashes} from "@openzeppelin/contracts/utils/cryptography/Hashes.sol"; */ `; -const set = ({ name, value }) => `\ +const set = ({ underlying, name, value }) => `\ struct ${name} { // Storage of set values ${value.type}[] _values; @@ -124,7 +123,19 @@ function clear(${name} storage set) internal { for (uint256 i = 0; i < len; ++i) { delete set._positions[set._values[i]]; } - Arrays.unsafeSetLength(set._values, 0); + unsafeSetLength(set._values, 0); +} + +/** + * @dev Helper to set the length of a dynamic array. Directly writing to \`.length\` is forbidden. + * + * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased. + */ +// Replace when these are available in Arrays.sol +function unsafeSetLength(${underlying}[] storage array, uint256 len) internal { + assembly ("memory-safe") { + sstore(array.slot, len) + } } /** From 525f73a2f4354779aa2b6560851783ce75654d3b Mon Sep 17 00:00:00 2001 From: ernestognw Date: Fri, 25 Apr 2025 13:39:35 -0600 Subject: [PATCH 2/4] review --- .../utils/structs/EnumerableSetExtended.sol | 24 ++++--------------- scripts/generate/templates/Enumerable.opts.js | 1 - .../templates/EnumerableSetExtended.js | 14 +++-------- 3 files changed, 7 insertions(+), 32 deletions(-) diff --git a/contracts/utils/structs/EnumerableSetExtended.sol b/contracts/utils/structs/EnumerableSetExtended.sol index 82a9f85e..60053086 100644 --- a/contracts/utils/structs/EnumerableSetExtended.sol +++ b/contracts/utils/structs/EnumerableSetExtended.sol @@ -120,16 +120,8 @@ library EnumerableSetExtended { for (uint256 i = 0; i < len; ++i) { delete set._positions[set._values[i]]; } - unsafeSetLength(set._values, 0); - } - - /** - * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden. - * - * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased. - */ - // Replace when these are available in Arrays.sol - function unsafeSetLength(string[] storage array, uint256 len) internal { + // Replace when these are available in Arrays.sol + string[] storage array = set._values; assembly ("memory-safe") { sstore(array.slot, len) } @@ -252,16 +244,8 @@ library EnumerableSetExtended { for (uint256 i = 0; i < len; ++i) { delete set._positions[set._values[i]]; } - unsafeSetLength(set._values, 0); - } - - /** - * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden. - * - * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased. - */ - // Replace when these are available in Arrays.sol - function unsafeSetLength(bytes[] storage array, uint256 len) internal { + // Replace when these are available in Arrays.sol + bytes[] storage array = set._values; assembly ("memory-safe") { sstore(array.slot, len) } diff --git a/scripts/generate/templates/Enumerable.opts.js b/scripts/generate/templates/Enumerable.opts.js index 0b503d07..0691b8d5 100644 --- a/scripts/generate/templates/Enumerable.opts.js +++ b/scripts/generate/templates/Enumerable.opts.js @@ -11,7 +11,6 @@ const typeDescr = ({ type, size = 0, memory = false }) => { }; const toSetTypeDescr = value => ({ - underlying: value.name.toLowerCase(), name: value.name + 'Set', value, }); diff --git a/scripts/generate/templates/EnumerableSetExtended.js b/scripts/generate/templates/EnumerableSetExtended.js index 05e00740..c4e565aa 100644 --- a/scripts/generate/templates/EnumerableSetExtended.js +++ b/scripts/generate/templates/EnumerableSetExtended.js @@ -45,7 +45,7 @@ import {Hashes} from "@openzeppelin/contracts/utils/cryptography/Hashes.sol"; */ `; -const set = ({ underlying, name, value }) => `\ +const set = ({ name, value }) => `\ struct ${name} { // Storage of set values ${value.type}[] _values; @@ -123,16 +123,8 @@ function clear(${name} storage set) internal { for (uint256 i = 0; i < len; ++i) { delete set._positions[set._values[i]]; } - unsafeSetLength(set._values, 0); -} - -/** - * @dev Helper to set the length of a dynamic array. Directly writing to \`.length\` is forbidden. - * - * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased. - */ -// Replace when these are available in Arrays.sol -function unsafeSetLength(${underlying}[] storage array, uint256 len) internal { + // Replace when these are available in Arrays.sol + ${value.type}[] storage array = set._values; assembly ("memory-safe") { sstore(array.slot, len) } From cc33d5cc874f2a14e243801e725467fd40afdea2 Mon Sep 17 00:00:00 2001 From: Arr00 <13561405+arr00@users.noreply.github.com> Date: Fri, 25 Apr 2025 15:44:42 -0400 Subject: [PATCH 3/4] Update scripts/generate/templates/EnumerableSetExtended.js --- scripts/generate/templates/EnumerableSetExtended.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/generate/templates/EnumerableSetExtended.js b/scripts/generate/templates/EnumerableSetExtended.js index c4e565aa..3215ab22 100644 --- a/scripts/generate/templates/EnumerableSetExtended.js +++ b/scripts/generate/templates/EnumerableSetExtended.js @@ -126,7 +126,7 @@ function clear(${name} storage set) internal { // Replace when these are available in Arrays.sol ${value.type}[] storage array = set._values; assembly ("memory-safe") { - sstore(array.slot, len) + sstore(array.slot, 0) } } From a2c2822c36e51f2d262e112dcffc7dc4cdf263b3 Mon Sep 17 00:00:00 2001 From: ernestognw Date: Fri, 25 Apr 2025 13:47:00 -0600 Subject: [PATCH 4/4] regenerate --- contracts/utils/structs/EnumerableSetExtended.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/utils/structs/EnumerableSetExtended.sol b/contracts/utils/structs/EnumerableSetExtended.sol index 60053086..f5691686 100644 --- a/contracts/utils/structs/EnumerableSetExtended.sol +++ b/contracts/utils/structs/EnumerableSetExtended.sol @@ -123,7 +123,7 @@ library EnumerableSetExtended { // Replace when these are available in Arrays.sol string[] storage array = set._values; assembly ("memory-safe") { - sstore(array.slot, len) + sstore(array.slot, 0) } } @@ -247,7 +247,7 @@ library EnumerableSetExtended { // Replace when these are available in Arrays.sol bytes[] storage array = set._values; assembly ("memory-safe") { - sstore(array.slot, len) + sstore(array.slot, 0) } }