When Burning a Tokenized Position validate
should be done before flipping the isLong
bits in _validateAndForwardToAMM()
#459
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
M-07
🤖_97_group
AI based duplicate group recommendation
satisfactory
satisfies C4 submission criteria; eligible for awards
selected for report
This submission will be included/highlighted in the audit report
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Lines of code
https://github.com/code-423n4/2024-04-panoptic/blob/833312ebd600665b577fbd9c03ffa0daf250ed24/contracts/types/TokenId.sol#L535-L571
https://github.com/code-423n4/2024-04-panoptic/blob/833312ebd600665b577fbd9c03ffa0daf250ed24/contracts/SemiFungiblePositionManager.sol#L673-L702
Vulnerability details
Each leg in a
tokenid
has a risk partner which is usually its own index but in some cases, it could be another leg (Partner in defined risk position).In the function
validate()
if the risk partner of a specific leg isnot
its own index then some additional checks are done to ensure that they are compatible likeisLong
value compared to that of its risk partner.In
burnTokenizedPosition()
the internal function_validateAndForwardToAMM()
is called, this function calls Tokenid.flipToBurnToken() which simplyflips
the isLong bits of all active legs of the tokenid. thenvalidate()
is called which validates a position tokenId and its legs.The issue here is that if a leg in the tokenid has its
risk partner
as another leg (that is, it is not its own risk partner), then flipping theisLong
bits may cause one of the checksin
validate()
to fail and revert as theisLong
bits of its risk partner arenot
changed as well.Remember that flipping changes the value of the bit from what it was to an opposite value (from 0 to 1 or from 1 to 0).
For example;
Let's say a leg with a different risk partner has
isLong()
values that are the same but theirtokenType()
is different, this would easily pass these checks below fromvalidate()
but after a flip is done to its
isLong
bits using flipToBurnToken() it will fail and revert in the second check below.Impact
This will result in a continuous revert of the function leading to an inability to Burn a Tokenized Position.
Tools Used
Manual Review
Recommended Mitigation Steps
This whole issue results from the simple fact the risk partners, if different are not flipped as well, I recommend validating the
tokenid
before flipping theisLong
bits, to ensure any changes caused by flipping will not affect the execution of the function.Assessed type
Other
The text was updated successfully, but these errors were encountered: