PanopticPool._validatePositionList can be tricked by overflowing position counter #465
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
downgraded by judge
Judge downgraded the risk level of this issue
duplicate-498
🤖_178_group
AI based duplicate group recommendation
satisfactory
satisfies C4 submission criteria; eligible for awards
Lines of code
https://github.com/code-423n4/2024-04-panoptic/blob/833312ebd600665b577fbd9c03ffa0daf250ed24/contracts/libraries/PanopticMath.sol#L100-L109
https://github.com/code-423n4/2024-04-panoptic/blob/833312ebd600665b577fbd9c03ffa0daf250ed24/contracts/PanopticPool.sol#L1367
Vulnerability details
Impact
A malicious actor can forge the currently held positions list and trick the system into believing that, for example, their overall position is solvent.
Proof of Concept
The user's currently held positions list is not stored on-chain, instead, it is provided with each
mintOptions
/burnOptions
call, hashed, and then compared to the stored hash (fingerprint) in_validatePositionList
.updatePositionsHash
XORes keccak of each token in right 248 bits and stores positions count in left 8 bit.This validation can be bypassed when addFlag=true by overflowing the counter and hiding tokens by doubling (x ^ x = 0, x ^ 0 = x). For example, assuming counter has only 2 bits:
[x, x, x, x, a] => x ^ x ^ x ^ x ^ a | 1 + 1 + 1 + 1 + 1 => a | 1
.For coded PoC make the following changes in, for example,
test_Success_mintOptions_OTMShortCall
:Validating position list will pass meaning we successfully "hide" 256 tokens from the validator, but they still counted in
_validateSolvency
and other functions.Tools Used
Manual review
Recommended Mitigation Steps
Enforce
MAX_POSITIONS
limit in_validatePositionList
by adding require:require(positionIdList.length <= MAX_POSITIONS)
Assessed type
Invalid Validation
The text was updated successfully, but these errors were encountered: