Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Underflow in _createLegInAMM #357

Closed
c4-bot-10 opened this issue Dec 9, 2023 · 4 comments
Closed

Underflow in _createLegInAMM #357

c4-bot-10 opened this issue Dec 9, 2023 · 4 comments
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working duplicate-516 partial-25 Incomplete articulation of vulnerability; eligible for partial credit only (25%)

Comments

@c4-bot-10
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2023-11-panoptic/blob/aa86461c9d6e60ef75ed5a1fe36a748b952c8666/contracts/SemiFungiblePositionManager.sol#L979

Vulnerability details

Impact

removedLiquidity -= chunkLiquidity; will underflow when there is no removedLiquidity in a particular leg.

This is a result of the fact that, when a token is being burnt, the tokenId is flipped to change the isLong to from 1 to 0, this happens for all the legs.

The problem with here is that not all legs will be 1, some will retain their zero(0 when no liquidity was previously removed). For this reason, removedLiquidity = 0 for such legs, but it was assumed that once the flag is BURN, removeLiquidity will be positive.

Since the calculation happened in an unchecked block, it won't revert but underflow, increasing removedLiquidity to a very large amount. here

return self ^ ((LONG_MASK >> (48 * (4 - optionRatios))) & CLEAR_POOLID_MASK);

When _createPositionInAMM loops through every leg to create a position in AMM, it calls _createLegInAMM which checks the

Proof of Concept

For a tokenId with two legs for instance, the first leg has isLeg = 1, the second leg has isLong = 0, when flipped, 1 changes to 0, in the first leg, but the second leg remains 0, but removedLiquidity -= chunkLiquidity; is still computed assuming that the zero was as a result of the flipToBurnToken code

/// @dev If the isLong flag is 0=short but the position was burnt, then this is closing a long position
/// @dev so the amount of short liquidity should decrease.
if (_isBurn) {
removedLiquidity -= chunkLiquidity;
}

Tools Used

Manual review.

Recommended Mitigation Steps

Add a check to ensure removedLiquidity >= chunkLiquidity

Assessed type

Math

@c4-bot-10 c4-bot-10 added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working labels Dec 9, 2023
c4-bot-4 added a commit that referenced this issue Dec 9, 2023
@c4-judge
Copy link
Contributor

Picodes marked the issue as duplicate of #516

@c4-judge
Copy link
Contributor

Picodes marked the issue as partial-50

@c4-judge c4-judge added the partial-50 Incomplete articulation of vulnerability; eligible for partial credit only (50%) label Dec 26, 2023
@c4-judge
Copy link
Contributor

Picodes marked the issue as partial-25

@c4-judge c4-judge added partial-25 Incomplete articulation of vulnerability; eligible for partial credit only (25%) and removed partial-50 Incomplete articulation of vulnerability; eligible for partial credit only (50%) labels Dec 26, 2023
@Picodes
Copy link

Picodes commented Dec 26, 2023

No valid scenario or impact are described

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working duplicate-516 partial-25 Incomplete articulation of vulnerability; eligible for partial credit only (25%)
Projects
None yet
Development

No branches or pull requests

3 participants