From 6ced880c97f276c3a13d287b9091d9b4d25558de Mon Sep 17 00:00:00 2001 From: atarpara Date: Sat, 29 Aug 2026 14:38:46 +0530 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=A5=A2=20Add=20note=20to=20DynamicArr?= =?UTF-8?q?ayLib=20and=20DynamicBufferLib?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/DynamicArrayLib.sol | 5 +++++ src/utils/DynamicBufferLib.sol | 5 +++++ src/utils/g/DynamicArrayLib.sol | 5 +++++ src/utils/g/DynamicBufferLib.sol | 5 +++++ 4 files changed, 20 insertions(+) diff --git a/src/utils/DynamicArrayLib.sol b/src/utils/DynamicArrayLib.sol index 9756de5f29..780a3551c2 100644 --- a/src/utils/DynamicArrayLib.sol +++ b/src/utils/DynamicArrayLib.sol @@ -11,6 +11,11 @@ library DynamicArrayLib { /// @dev Type to represent a dynamic array in memory. /// You can directly assign to `data`, and the `p` function will /// take care of the memory allocation. + /// + /// Note: The capacity is a prime-checksummed word before the array. If you assign + /// an array you did not allocate (e.g. from calldata), that word can + /// masquerade as a capacity, making `p` skip reallocation and write out of bounds. + /// If you are not directly assigning to `data`, you don't have to worry about it. struct DynamicArray { uint256[] data; } diff --git a/src/utils/DynamicBufferLib.sol b/src/utils/DynamicBufferLib.sol index be054129d0..b5a8e49a8e 100644 --- a/src/utils/DynamicBufferLib.sol +++ b/src/utils/DynamicBufferLib.sol @@ -12,6 +12,11 @@ library DynamicBufferLib { /// @dev Type to represent a dynamic buffer in memory. /// You can directly assign to `data`, and the `p` function will /// take care of the memory allocation. + /// + /// Note: The capacity is a prime-checksummed word before the buffer. If you assign + /// a bytes you did not allocate (e.g. from calldata), that word can + /// masquerade as a capacity, making `p` skip reallocation and write out of bounds. + /// If you are not directly assigning to `data`, you don't have to worry about it. struct DynamicBuffer { bytes data; } diff --git a/src/utils/g/DynamicArrayLib.sol b/src/utils/g/DynamicArrayLib.sol index 6cc3d549b6..2304f0e1bb 100644 --- a/src/utils/g/DynamicArrayLib.sol +++ b/src/utils/g/DynamicArrayLib.sol @@ -10,6 +10,11 @@ pragma solidity ^0.8.13; /// @dev Type to represent a dynamic array in memory. /// You can directly assign to `data`, and the `p` function will /// take care of the memory allocation. +/// +/// Note: The capacity is a prime-checksummed word before the array. If you assign +/// an array you did not allocate (e.g. from calldata), that word can +/// masquerade as a capacity, making `p` skip reallocation and write out of bounds. +/// If you are not directly assigning to `data`, you don't have to worry about it. struct DynamicArray { uint256[] data; } diff --git a/src/utils/g/DynamicBufferLib.sol b/src/utils/g/DynamicBufferLib.sol index 0e9c3ee81c..06e2066220 100644 --- a/src/utils/g/DynamicBufferLib.sol +++ b/src/utils/g/DynamicBufferLib.sol @@ -10,6 +10,11 @@ pragma solidity ^0.8.13; /// @dev Type to represent a dynamic buffer in memory. /// You can directly assign to `data`, and the `p` function will /// take care of the memory allocation. +/// +/// Note: The capacity is a prime-checksummed word before the buffer. If you assign +/// a bytes you did not allocate (e.g. from calldata), that word can +/// masquerade as a capacity, making `p` skip reallocation and write out of bounds. +/// If you are not directly assigning to `data`, you don't have to worry about it. struct DynamicBuffer { bytes data; } From ac17239be4f4e8876bd32e71042a083f88a531cd Mon Sep 17 00:00:00 2001 From: atarpara Date: Wed, 2 Sep 2026 15:18:09 +0530 Subject: [PATCH 2/2] T --- src/utils/DynamicArrayLib.sol | 3 ++- src/utils/g/DynamicArrayLib.sol | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/utils/DynamicArrayLib.sol b/src/utils/DynamicArrayLib.sol index 780a3551c2..c800ca7479 100644 --- a/src/utils/DynamicArrayLib.sol +++ b/src/utils/DynamicArrayLib.sol @@ -15,7 +15,8 @@ library DynamicArrayLib { /// Note: The capacity is a prime-checksummed word before the array. If you assign /// an array you did not allocate (e.g. from calldata), that word can /// masquerade as a capacity, making `p` skip reallocation and write out of bounds. - /// If you are not directly assigning to `data`, you don't have to worry about it. + /// Arrays brought in via `wrap` carry the same risk, as `wrap` assigns to `data` too. + /// If you are not assigning to `data` or using `wrap`, you don't have to worry about it. struct DynamicArray { uint256[] data; } diff --git a/src/utils/g/DynamicArrayLib.sol b/src/utils/g/DynamicArrayLib.sol index 2304f0e1bb..c09e539a47 100644 --- a/src/utils/g/DynamicArrayLib.sol +++ b/src/utils/g/DynamicArrayLib.sol @@ -14,7 +14,8 @@ pragma solidity ^0.8.13; /// Note: The capacity is a prime-checksummed word before the array. If you assign /// an array you did not allocate (e.g. from calldata), that word can /// masquerade as a capacity, making `p` skip reallocation and write out of bounds. -/// If you are not directly assigning to `data`, you don't have to worry about it. +/// Arrays brought in via `wrap` carry the same risk, as `wrap` assigns to `data` too. +/// If you are not assigning to `data` or using `wrap`, you don't have to worry about it. struct DynamicArray { uint256[] data; }