Skip to content
This repository has been archived by the owner on Jul 14, 2024. It is now read-only.

ArmedGoose - Lack of staleness check in oracle consult() function #34

Closed
sherlock-admin2 opened this issue Jan 10, 2024 · 2 comments
Closed
Labels
Non-Reward This issue will not receive a payout

Comments

@sherlock-admin2
Copy link
Contributor

sherlock-admin2 commented Jan 10, 2024

ArmedGoose

medium

Lack of staleness check in oracle consult() function

Summary

The function consult() of TWAPOracleDollar3poolFacet.sol allows for getting a price information. However, the price is directly pulled from storage and there is zero guarantee, that the price meets any staleness criteria - there is also no logic that enables such check. Therefore, arbitrageurs may take advantage from stale price to buy assets at premium, at cost of the protocol, wherever the oracle is used further.

Vulnerability Detail

The core of the function, consult() in LibTWAPOracle.sol allows for retrieving the asset price in another token from the pool. However, there is no default or even optional staleness check - the price is retrieved from storage as it is. Due to this, it may be stale, but there is no option to verify it, or even check when the price was updated.

Impact

Arbitrageurs and users may take advantage from stale price to buy assets at premium, at cost of the protocol, wherever the oracle is used further.

Code Snippet

TWAPOracleDollar3poolFacet.sol::consult() calls LibTWAPOracle.sol::consult():

    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;
        }
    }//@audit there is no actual check if the saved price is stale its just pulled from storage

Tool used

Manual Review

Recommendation

It is possible to check ts.pricesBlockTimestampLast value and add a condition to this function - if it doesn't meet a staleness threshold, which may be shared with chainlink staleness threshold or held in a separate variable - then force update.

@github-actions github-actions bot added the Excluded Excluded by the judge without consulting the protocol or the senior label Jan 14, 2024
@sherlock-admin2
Copy link
Contributor Author

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

auditsea commented:

It's view function, and during main logic, it is used only after the value is updated

@github-actions github-actions bot added Medium A valid Medium severity issue Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label and removed Excluded Excluded by the judge without consulting the protocol or the senior labels Jan 16, 2024
@sherlock-admin2
Copy link
Contributor Author

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

auditsea commented:

It's view function, and during main logic, it is used only after the value is updated

@sherlock-admin2 sherlock-admin2 changed the title Swift Rose Spider - Lack of staleness check in oracle consult() function ArmedGoose - Lack of staleness check in oracle consult() function Jan 24, 2024
@sherlock-admin2 sherlock-admin2 added the Reward A payout will be made for this issue label Jan 24, 2024
@Czar102 Czar102 removed the Medium A valid Medium severity issue label Feb 19, 2024
@sherlock-admin sherlock-admin added Non-Reward This issue will not receive a payout and removed Reward A payout will be made for this issue labels Feb 19, 2024
@sherlock-admin2 sherlock-admin2 removed the Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label label Feb 20, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Non-Reward This issue will not receive a payout
Projects
None yet
Development

No branches or pull requests

3 participants