Skip to content

Latest commit

 

History

History
57 lines (32 loc) · 2.37 KB

077.md

File metadata and controls

57 lines (32 loc) · 2.37 KB

Late Flaxen Sparrow

Medium

SolidlyV3AMO tick bounds cannot be changed without loss of yield

Summary

The SolidlyV3AMO implementation allows chancing the lower and upper tick bounds for the underlying Solidly V3 LP pools. However, when this is changed, the previous position existing fees are not retrieved. This results in a loss of yield (fees) through the simple action of changing tick bounds.

Root Cause

As SolidlyV3AMO deposits into a Solidly V3 LP, a concentrated liquidity AMM, each position, defined by the lower-upper tick bounds, generates fees individually. In order to collect said fees the burnAndCollect is called, as acknowledged by the protocol team.

ClaimFees: the claimFee function/implementation differs across Dexes, but in all/most Dexes fees can be collected with the standardised burnandcollect() function

However, the burnAndCollect function is only called in the _unfarmBuyBurn function, an action taken when handling the un-farming, buying, and burning of BOOST when it's under the peg.

Because of this design choice, changing the ticks via a SolidlyV3AMO::setTickBounds call will leave any yield (collected fees) stranded in the previous position.

function setTickBounds(int24 tickLower_, int24 tickUpper_) public override onlyRole(SETTER_ROLE) {
    tickLower = tickLower_;
    tickUpper = tickUpper_;
    emit TickBoundsSet(tickLower, tickUpper);
}

Internal pre-conditions

No response

External pre-conditions

BOOST-USD-pegged-token prices has deviated outside the existing, pre-set [tickLower, tickUpper] bounds.

Attack Path

SETTER_ROLE calls SolidlyV3AMO::setTickBounds.

Impact

Any existing yield (fees) on the previous tick position cannot be retrieved without going back to the same tick and waiting to trigger a unfarmBuyBurn action (which is done when it's under the peg only).

Even in that case, then the second position, will not have unclaimed fees and so forth.

Overall, protocol looses the yield maintaining that position.

PoC

No response

Mitigation

No response