Panoptic - radin100's results

Permissionless, perpetual options trading on any token, any strike, any size.

General Information

Platform: Code4rena

Start Date: 01/04/2024

Pot Size: $120,000 USDC

Total HM: 11

Participants: 55

Period: 21 days

Judge: Picodes

Total Solo HM: 6

Id: 354

League: ETH

Panoptic

Findings Distribution

Researcher Performance

Rank: 28/55

Findings: 1

Award: $212.89

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

212.8863 USDC - $212.89

Labels

bug
downgraded by judge
grade-a
QA (Quality Assurance)
edited-by-warden
:robot:_31_group
duplicate-421
Q-36

External Links

Lines of code

https://github.com/code-423n4/2024-04-panoptic/blob/833312ebd600665b577fbd9c03ffa0daf250ed24/contracts/libraries/PanopticMath.sol#L241-L268 https://github.com/code-423n4/2024-04-panoptic/blob/833312ebd600665b577fbd9c03ffa0daf250ed24/contracts/PanopticPool.sol#L1450-L1452 https://github.com/code-423n4/2024-04-panoptic/blob/833312ebd600665b577fbd9c03ffa0daf250ed24/contracts/PanopticPool.sol#L1017-L1171

Vulnerability details

Impact

Available possibility for loss of funds, due to unexpected liquidation DoS

Proof of Concept

At the end of PanopticMath::twapFilter, the tick at sortedTicks[10] is returned, which isn't at the median of sortedTicks with 19 length, which leads to permanent returning of higher tick than actual.

There are 2 main scenarios which could occur due to bad indexation:

  1. When liquidator executes PanopticPool::liquidate, the function could revert unexpectedly due to (Math.abs(currentTick - twapTick) > MAX_TWAP_DELTA_LIQUIDATION) won't pass, because of currentTick - twapTick is going to be higher than it is supposed to be (if actualTwapTick > currentTick).
  2. During the execution of PanopticPool::liquidate, PanopticPool::_getSolvencyBalances is called to compute the balanceCross and thresholdCross.
function _getSolvencyBalances(
        LeftRightUnsigned tokenData0,
        LeftRightUnsigned tokenData1,
        uint160 sqrtPriceX96
    ) internal pure returns (uint256 balanceCross, uint256 thresholdCross){
        unchecked {
            // the cross-collateral balance, computed in terms of liquidity X*√P + Y/√P
            // We use mulDiv to compute Y/√P + X*√P while correctly handling overflows, round down
            balanceCross =
                Math.mulDiv(uint256(tokenData1.rightSlot()), 2 ** 96, sqrtPriceX96) +
                Math.mulDiv96(tokenData0.rightSlot(), sqrtPriceX96);
            // the amount of cross-collateral balance needed for the account to be solvent, computed in terms of liquidity
            // overstimate by rounding up
            thresholdCross =
                Math.mulDivRoundingUp(uint256(tokenData1.leftSlot()), 2 ** 96, sqrtPriceX96) +
                Math.mulDiv96RoundingUp(tokenData0.leftSlot(), sqrtPriceX96);
        }
    }

The third parameter from the input is the sqrtPrice at the twapTick. Due to the logic error the sqrtPrice is permanently going to be higher than actual, because of this the chases of (balanceCross >= thresholdCross) check to revert are permanently increased (if tokenData0.rightSlot() > tokenData0.leftSlot()).

Tools Used

Rewrite the end of the function to get the median value from 9th index instead of 10th

function twapFilter(IUniswapV3Pool univ3pool, uint32 twapWindow) external view returns (int24) {
        ...
        ...
        ...
            // Get the median value
+++         return int24(sortedTicks[9]);
---         return int24(sortedTicks[10]);
        }
    }

Assessed type

Other

#0 - c4-judge

2024-04-26T18:57:34Z

Picodes marked the issue as duplicate of #239

#1 - c4-judge

2024-04-26T18:59:32Z

Picodes marked the issue as not a duplicate

#2 - c4-judge

2024-04-26T18:59:49Z

Picodes marked the issue as duplicate of #421

#3 - c4-judge

2024-04-29T21:47:32Z

Picodes changed the severity to QA (Quality Assurance)

#4 - c4-judge

2024-04-29T21:47:48Z

Picodes marked the issue as grade-a

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter