Platform: Code4rena
Start Date: 03/10/2023
Pot Size: $24,500 USDC
Total HM: 6
Participants: 62
Period: 3 days
Judge: LSDan
Total Solo HM: 3
Id: 288
League: ETH
Rank: 13/62
Findings: 1
Award: $359.93
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Banditx0x
Also found by: 0xDING99YA, 0xWaitress, 0xpiken, 3docSec, Banditx0x, adriro, emerald7017, maanas, twicek
359.9307 USDC - $359.93
If a user neither modifies his position nor claims rewards for a very long time, it might become impossible for him to do any action involving the internal functions accrueAmbientPositionTimeWeightedLiquidity
or accrueConcentratedPositionTimeWeightedLiquidity
.
accrueConcentratedPositionTimeWeightedLiquidity
is the more likely to generate this issue:
while (time < block.timestamp && tickTrackingIndex < numTickTracking) { TickTracking memory tickTracking = tickTracking_[poolIdx][i][tickTrackingIndex]; uint32 currWeek = uint32((time / WEEK) * WEEK); uint32 nextWeek = uint32(((time + WEEK) / WEEK) * WEEK); uint32 dt = uint32( nextWeek < block.timestamp ? nextWeek - time : block.timestamp - time ); uint32 tickActiveStart; // Timestamp to use for the liquidity addition uint32 tickActiveEnd; if (tickTracking.enterTimestamp < nextWeek) { // Tick was active before next week, need to add the liquidity if (tickTracking.enterTimestamp < time) { // Tick was already active when last claim happened, only accrue from last claim timestamp tickActiveStart = time; } else { // Tick has become active this week tickActiveStart = tickTracking.enterTimestamp; } if (tickTracking.exitTimestamp == 0) { // Tick still active, do not increase index because we need to continue from here tickActiveEnd = uint32(nextWeek < block.timestamp ? nextWeek : block.timestamp); } else { // Tick is no longer active if (tickTracking.exitTimestamp < nextWeek) { // Exit was in this week, continue with next tick tickActiveEnd = tickTracking.exitTimestamp; tickTrackingIndex++; dt = tickActiveEnd - tickActiveStart; } else { // Exit was in next week, we need to consider the current tick there (i.e. not increase the index) tickActiveEnd = nextWeek; } } timeWeightedWeeklyPositionInRangeConcLiquidity_[poolIdx][posKey][currWeek][i] += (tickActiveEnd - tickActiveStart) * liquidity; } time += dt; }
In this function, a for loop iterates over each tick, and for each tick a while loop is done for each tick tracking index to calculate its contribution. A tick could have a very large amount of tick tracking indexes to loop over in its while loop if it has not been updated for a very long time for the user position.
Each time a tick is crossed it will have a new item in its tickTracking_
array. If a user does not change his position for let's say 1 year, hundreds, if not thousands, of entries could be added to tickTracking_
.
A year later, the user function call might need to do more than 21 (ticks) * 1000 (number of tick tracking items not accrued) = 21000 total iterations for the for + while loop in accrueConcentratedPositionTimeWeightedLiquidity
.
The cost for such a function call could surpass the 30M gas limit.
The user funds will be locked in the contract as he will not be able to call the mint or burn function as well as not being able to claim rewards.
Manual Review
Consider splitting the accrual in several calls with a dedicated function or create an admin function that updates inactive accounts before they surpass the 30M gas limit.
DoS
#0 - c4-pre-sort
2023-10-08T12:07:05Z
141345 marked the issue as duplicate of #114
#1 - c4-pre-sort
2023-10-09T16:41:49Z
141345 marked the issue as sufficient quality report
#2 - c4-judge
2023-10-18T19:27:43Z
dmvt changed the severity to 3 (High Risk)
#3 - c4-judge
2023-10-18T19:29:38Z
dmvt marked the issue as satisfactory
#4 - radeveth
2023-10-21T10:58:27Z
NC-02 and NC-05 issues from QA Report #297, also address potential gas issues and the risk of running out of gas for the accrueAmbientPositionTimeWeightedLiquidity()
function. Therefore, I strongly believe that the NC-02 and NC-05 issues from QA Report #297 should be marked as duplicates of these issues, particularly #114.
Could you please review this?
Note: L-01 from #61 is also marked as duplicate of issue #114.
@dmvt @141345
#5 - dmvt
2023-10-21T22:39:13Z
NC-02 and NC-05 issues from QA Report #297, also address potential gas issues and the risk of running out of gas for the
accrueAmbientPositionTimeWeightedLiquidity()
function. Therefore, I strongly believe that the NC-02 and NC-05 issues from QA Report #297 should be marked as duplicates of these issues, particularly #114.Could you please review this?
Note: L-01 from #61 is also marked as duplicate of issue #114.
@dmvt @141345
NC-2 is a different issue and is actually incorrect. The function in question is protected by governance. N-5 is not of sufficient quality to be upgraded to a high risk issue.