From 6db8d1be71253f84409d52c13f5f52902efa2185 Mon Sep 17 00:00:00 2001 From: William Morriss Date: Mon, 28 Jul 2025 17:55:13 -0500 Subject: [PATCH 1/4] remove copy --- src/Payments.sol | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/Payments.sol b/src/Payments.sol index 24c08da4..7ca14ef2 100644 --- a/src/Payments.sol +++ b/src/Payments.sol @@ -1571,7 +1571,7 @@ contract Payments is Initializable, UUPSUpgradeable, OwnableUpgradeable, Reentra uint256[] storage allRailIds = isPayer ? payerRails[token][addr] : payeeRails[token][addr]; uint256 railsLength = allRailIds.length; - RailInfo[] memory tempResults = new RailInfo[](railsLength); + RailInfo[] memory results = new RailInfo[](railsLength); uint256 resultCount = 0; for (uint256 i = 0; i < railsLength; i++) { @@ -1582,22 +1582,16 @@ contract Payments is Initializable, UUPSUpgradeable, OwnableUpgradeable, Reentra if (rail.from == address(0)) continue; // Add rail to our temporary array - tempResults[resultCount] = + results[resultCount] = RailInfo({railId: railId, isTerminated: rail.endEpoch > 0, endEpoch: rail.endEpoch}); resultCount++; } - // Create correctly sized final result array - RailInfo[] memory result = new RailInfo[](resultCount); - - // Only copy if we have results (avoid unnecessary operations) - if (resultCount > 0) { - for (uint256 i = 0; i < resultCount; i++) { - result[i] = tempResults[i]; - } + assembly ("memory-safe") { + mstore(results, resultCount) } - return result; + return results; } /// @notice Number of pending rate-change entries for a rail From 5079fca633bbb42bd87916990c4dcd0a4bd4366a Mon Sep 17 00:00:00 2001 From: William Morriss Date: Mon, 28 Jul 2025 18:06:17 -0500 Subject: [PATCH 2/4] document --- src/Payments.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Payments.sol b/src/Payments.sol index 7ca14ef2..e4df0e45 100644 --- a/src/Payments.sol +++ b/src/Payments.sol @@ -1587,6 +1587,7 @@ contract Payments is Initializable, UUPSUpgradeable, OwnableUpgradeable, Reentra resultCount++; } + // Truncate assembly ("memory-safe") { mstore(results, resultCount) } From 03c944d8ab6da4dd41c09d15e15515bfeb07d511 Mon Sep 17 00:00:00 2001 From: William Morriss Date: Mon, 28 Jul 2025 18:07:01 -0500 Subject: [PATCH 3/4] update comment --- src/Payments.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Payments.sol b/src/Payments.sol index e4df0e45..030920e5 100644 --- a/src/Payments.sol +++ b/src/Payments.sol @@ -1581,7 +1581,7 @@ contract Payments is Initializable, UUPSUpgradeable, OwnableUpgradeable, Reentra // Skip non-existent rails if (rail.from == address(0)) continue; - // Add rail to our temporary array + // Add rail info to results results[resultCount] = RailInfo({railId: railId, isTerminated: rail.endEpoch > 0, endEpoch: rail.endEpoch}); resultCount++; From e3f18bac2275c1d3086549abfa2be260bde52bbf Mon Sep 17 00:00:00 2001 From: William Morriss Date: Mon, 28 Jul 2025 18:07:30 -0500 Subject: [PATCH 4/4] forge fmt --- src/Payments.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Payments.sol b/src/Payments.sol index 030920e5..f3041859 100644 --- a/src/Payments.sol +++ b/src/Payments.sol @@ -1582,8 +1582,7 @@ contract Payments is Initializable, UUPSUpgradeable, OwnableUpgradeable, Reentra if (rail.from == address(0)) continue; // Add rail info to results - results[resultCount] = - RailInfo({railId: railId, isTerminated: rail.endEpoch > 0, endEpoch: rail.endEpoch}); + results[resultCount] = RailInfo({railId: railId, isTerminated: rail.endEpoch > 0, endEpoch: rail.endEpoch}); resultCount++; }