Lucene search

K
code423n4Code4renaCODE423N4:2022-09-Y2K-FINANCE-FINDINGS-ISSUES-419
HistorySep 19, 2022 - 12:00 a.m.

PegOracle reported fraction price is constructed to favor the depeg

2022-09-1900:00:00
Code4rena
github.com
8

Lines of code

Vulnerability details

Depeg event is defined as linked asset price being below the strike price in the terms of the underlying asset. However, the PegOracle aimed to report the fraction of the pegged asset to the underlying always reports the number below 1, no matter how prices are staked against each other, the lesser one is divided by the bigger one.

There is no indicator whether price2 / price1 or price1 / price2 is used, so < 1 fraction is always reported.

Say if stETH was 0.99, then flipped ETH for any reason, becoming 1.1 (say an additional reward program was announced by Lido and the market priced the present value of these rewards to be 10%). PegOracle will report the stETH/ETH fraction as 1 / 1.1 = 0.909.

This, for example, can allow triggerDepeg() to be run if strikePrice were set as 0.91.

Setting the severity to be high as that’s the violation of core logic with substantial fund loss for all hedge users.

Proof of Concept

PegOracle’s latestRoundData() do not separate linked and underlying price feeds, reporting the fraction of the currently smaller one to the bigger:

<https://github.com/code-423n4/2022-09-y2k-finance/blob/2175c044af98509261e4147edeb48e1036773771/src/oracles/PegOracle.sol#L63-L71&gt;

        ) = priceFeed1.latestRoundData();

        int256 price2 = getOracle2_Price();

        if (price1 &gt; price2) {
            nowPrice = (price2 * 10000) / price1;
        } else {
            nowPrice = (price1 * 10000) / price2;
        }

Recommended Mitigation Steps

Consider fixing the order of the price feeds and always report linked asset price divided by the underlying asset price.

For example:

<https://github.com/code-423n4/2022-09-y2k-finance/blob/2175c044af98509261e4147edeb48e1036773771/src/oracles/PegOracle.sol#L18-L24&gt;

    /** @notice Contract constructor
-     * @param _oracle1 First oracle address
-     * @param _oracle2 Second oracle address
+     * @param _oracle1 Linked oracle address
+     * @param _oracle2 Underlying oracle address
      */
    constructor(address _oracle1, address _oracle2) {
-       require(_oracle1 != address(0), "oracle1 cannot be the zero address");
-       require(_oracle2 != address(0), "oracle2 cannot be the zero address");
+       require(_oracle1 != address(0), "Linked Oracle is zero address");
+       require(_oracle2 != address(0), "Underlying Oracle is zero address");

<https://github.com/code-423n4/2022-09-y2k-finance/blob/2175c044af98509261e4147edeb48e1036773771/src/oracles/PegOracle.sol#L67-L71&gt;

-       if (price1 &gt; price2) {
-           nowPrice = (price2 * 10000) / price1;
-       } else {
-           nowPrice = (price1 * 10000) / price2;
-       }
+	nowPrice = (price1 * 10000) / price2;  

The text was updated successfully, but these errors were encountered:

All reactions