Jovial Ocean Elk
High
The maintained()
and margin()
functions wrongly handle negative collateral values making a path for undercollateralized positions to appear solvent.
https://github.com/sherlock-audit/2025-01-perennial-v2-4-update/blob/main/perennial-v2/packages/core/contracts/types/Position.sol#L211-L217
https://github.com/sherlock-audit/2025-01-perennial-v2-4-update/blob/main/perennial-v2/packages/core/contracts/types/Position.sol#L242-L250
maintained()
and margin()
functions
collateral is stored as Fixed6
which is signed
but later converted to UFIXED6
which is unsigned
using UFixed6Lib.unsafeFrom(collateral)
.
The negative values are wrapped around to large set of numbers due to two representation -100
→ 2^256 - 100
which will cause the check to return true for negative collateral.
Malicious users can maintain positions with negative collaterals bypassing solvency checks. Malicious actors can also borrow funds without collateralizing.
Manual review.
Revert or return false if collateral is negative unless position is empty.