Open c4-bot-1 opened 11 months ago
0xleastwood marked the issue as primary issue
Dupplicate #50
0xleastwood marked the issue as duplicate of #50
0xleastwood marked the issue as not a duplicate
0xleastwood marked the issue as selected for report
0xleastwood marked the issue as primary issue
wukong-particle (sponsor) confirmed
Lines of code
https://github.com/code-423n4/2023-12-particle/blob/a3af40839b24aa13f5764d4f84933dbfa8bc8134/contracts/protocol/ParticlePositionManager.sol#L160-L167
Vulnerability details
Vulnerability details
When
openPosition()
, we need to record the currentfeeGrowthInside0LastX128/feeGrowthInside1LastX128
. And when closing the position, we useBase.getOwedFee()
to calculate the possible fees generated during the borrowing period, which are used to pay theLP
.openPosition()
->Base.prepareLeverage()
From the above code, we can see that the final value saved to
liens[].feeGrowthInside0LastX128/feeGrowthInside1LastX128
is directly taken fromUNI_POSITION_MANAGER.positions(tokenId)
.The problem is: The value in
UNI_POSITION_MANAGER.positions(tokenId)
is not the latest.Only when executing
UNI_POSITION_MANAGER.increaseLiquidity()/decreaseLiquidity()/collect()
will it synchronize thepool
'sfeeGrowthInside0LastX128/feeGrowthInside1LastX128
.Because of using the stale value, it leads to a smaller value relative to the actual value. When
closePosition()
, the calculated difference will be larger, and theborrower
will pay extra fees.Impact
Due to use stale
feeGrowthInside0LastX128/feeGrowthInside1LastX128
, theborrower
will pay extra fees.Proof of Concept
The following test code demonstrates that after
swap()
,UNI_POSITION_MANAGER.positions(tokenId)
is not the latest unless actively executingUNI_POSITION_MANAGER.collect()
.add to
Swap.t.sol
Recommended Mitigation
After
LiquidityPosition.collectLiquidity()
, executeBase.prepareLeverage()
to ensure the latestfeeGrowthInside0LastX128/feeGrowthInside1LastX128
.Assessed type
Decimal