sherlock-audit / 2023-12-ubiquity-judging

2 stars 2 forks source link

osmanozdemir1 - `LibTWAPOracle::consult()` function should update prices before returning #187

Closed sherlock-admin closed 8 months ago

sherlock-admin commented 9 months ago

osmanozdemir1

high

LibTWAPOracle::consult() function should update prices before returning

Summary

LibTWAPOracle::getTwapPrice() function is used to get DollarToken price and the returned value is used in the major functions like mintDollar() and redeemDollar() in the LibUbiquityPool.sol. However, this function returns average prices without updating.

Vulnerability Detail

Down below, you can see the getTwapPrice(), and the consult() functions.

    function getTwapPrice() internal view returns (uint256) {
        return
            LibTWAPOracle.consult(
                LibAppStorage.appStorage().dollarTokenAddress
            );
    }

//---

    function consult(address token) internal view returns (uint256 amountOut) {
        TWAPOracleStorage memory ts = twapOracleStorage();

        if (token == LibAppStorage.appStorage().dollarTokenAddress) {
            // price to exchange 1 Ubiquity Dollar to 3CRV based on TWAP
            amountOut = ts.price0Average;
        } else {
            require(token == ts.token1, "TWAPOracle: INVALID_TOKEN");
            // price to exchange 1 3CRV to Ubiquity Dollar based on TWAP
            amountOut = ts.price1Average;
        }
    }

The getTwapPrice() function directly calls the consult(), and returns these values. However, the returned average prices in the consult() function is not up to date. It must update the twapOracleStorage first, and then return the average prices.

Impact

The getTwapPrice() function is used in getDollarPriceUsd() function here, which means getDollarPriceUsd() always returns stale prices. The returned value is used in the two most crucial functions: mintDollar and redeemDollar. All of these actions are performed with stale prices.

Code Snippet

https://github.com/sherlock-audit/2023-12-ubiquity/blob/main/ubiquity-dollar/packages/contracts/src/dollar/libraries/LibTWAPOracle.sol#L111C1-L122C6

https://github.com/sherlock-audit/2023-12-ubiquity/blob/main/ubiquity-dollar/packages/contracts/src/dollar/libraries/LibTWAPOracle.sol#L159C1-L164C6

Tool used

Manual Review

Recommendation

    function consult(address token) internal view returns (uint256 amountOut) {
+       // update the price first.
+       update();  
+       // Then return the average prices in the storage.

        TWAPOracleStorage memory ts = twapOracleStorage();

        if (token == LibAppStorage.appStorage().dollarTokenAddress) {
            // price to exchange 1 Ubiquity Dollar to 3CRV based on TWAP
            amountOut = ts.price0Average;
        } else {
            require(token == ts.token1, "TWAPOracle: INVALID_TOKEN");
            // price to exchange 1 3CRV to Ubiquity Dollar based on TWAP
            amountOut = ts.price1Average;
        }
    }

Duplicate of #34

sherlock-admin2 commented 8 months ago

1 comment(s) were left on this issue during the judging contest.

auditsea commented:

REF #034

sherlock-admin2 commented 8 months ago

1 comment(s) were left on this issue during the judging contest.

auditsea commented:

REF #034