Vulnerability Details
In this consolidatePendingStakes
function, the variable i
is initialized as int256
to handle potential negative values during the decrement (See line number 129). Additionally, the code requires casting int256(i)
to uint256(i)
to use the index i
.
File: contracts/LiquidationPool.sol
119: function consolidatePendingStakes() private {
120: uint256 deadline = block.timestamp - 1 days;
121: for (int256 i = 0; uint256(i) < pendingStakes.length; i++) {
122: PendingStake memory _stake = pendingStakes[uint256(i)];
123: if (_stake.createdAt < deadline) {
124: positions[_stake.holder].holder = _stake.holder;
125: positions[_stake.holder].TST += _stake.TST;
126: positions[_stake.holder].EUROs += _stake.EUROs;
127: deletePendingStake(uint256(i));
128:
129: @> i--;
130: }
131: }
132: }
https://github.com/Cyfrin/2023-12-the-standard/blob/91132936cb09ef9bf82f38ab1106346e2ad60f91/contracts/LiquidationPool.sol#L119C1-L132C6
Tools Used
Manual Review
Recommendations
This unnecessary casting can be removed by adding an else block, as shown in the code below.
function consolidatePendingStakes() private {
uint256 deadline = block.timestamp - 1 days;
- for (int256 i = 0; uint256(i) < pendingStakes.length; i++) {
+ for (uint256 i = 0; i < pendingStakes.length;) { // @audit no increment here
- PendingStake memory _stake = pendingStakes[uint256(i)];
+ PendingStake memory _stake = pendingStakes[i];
if (_stake.createdAt < deadline) {
positions[_stake.holder].holder = _stake.holder;
positions[_stake.holder].TST += _stake.TST;
positions[_stake.holder].EUROs += _stake.EUROs;
- deletePendingStake(uint256(i));
- // pause iterating on loop because there has been a deletion. "next" item has same index
- i--;
+ deletePendingStake(i);
+ // @audit The loop variable 'i' is not incremented here because deletePendingStake shifts the indexes.
+ } else {
+ i++; // @audit Only increment 'i' if no deletion occurs.
}
}
}
The loop variable i is only incremented if no deletion occurs. If a PendingStake
is deleted, the loop continues without incrementing i, ensuring that the next item is not skipped. This approach maintains the correct iteration over the pendingStakes
array even as items are removed.