Skip to content
This repository has been archived by the owner on Nov 26, 2023. It is now read-only.

0xHati - getOwnValuation uses spot price and not the twap #251

Closed
sherlock-admin opened this issue May 23, 2023 · 0 comments
Closed

0xHati - getOwnValuation uses spot price and not the twap #251

sherlock-admin opened this issue May 23, 2023 · 0 comments
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label High A valid High severity issue Reward A payout will be made for this issue

Comments

@sherlock-admin
Copy link
Contributor

sherlock-admin commented May 23, 2023

0xHati

high

getOwnValuation uses spot price and not the twap

Summary

The getOwnValuation uses the spotprice of the uniswap token and not the twap price.

Vulnerability Detail

The getOwnValuation gets the price of USSD according to the price of the USSD/DAI pool. However it uses the spotprice like this:

      (uint160 sqrtPriceX96,,,,,,) =  uniPool.slot0();

It does some more calculations to get the price as USSD/DAI.
The getOwnValuation function is called in rebalance and SellUSSDBuyCollateral. Depending on the output rebalance will either buy or sell USSD.
This makes it possible for anyone to flashloan and influence the output of getOwnValuation and call rebalance. The protocol will now buy or sell USSD when it's not warranted, bringing it in a unstable state and making it even possible for the attacker to profit.
The attack would happen like this:

  1. attacker deposits dai and gets ussd via mintForToken
  2. attacker flashloans a sufficient amount of dai to destabilize the pool
  3. Call rebalance
  4. Protocol will call BuyUSSDSellCollateral because getOwnValuation uses spot price. Ussd is < 1e6, since there's more ussd than dai in the pool.
  5. Protocol will sell dai and buy ussd to bring the pool in balance
  6. Repay the flashloan, the pool now has a lot more dai than ussd, so 1 ussd will be worth more than 1 dai
  7. Sell the ussd into the pool for profit and receive more than the unit price that was paid for in the deposit

Impact

Anyone can make the protocol buy or sell USSD by executing a flashloan and make profit of it by selling the received ussd for more than it's worth.

Code Snippet

Link to code

function getOwnValuation() public view returns (uint256 price) {
      (uint160 sqrtPriceX96,,,,,,) =  uniPool.slot0();
      if(uniPool.token0() == USSD) {
        price = uint(sqrtPriceX96)*(uint(sqrtPriceX96))/(1e6) >> (96 * 2);
      } else {
        price = uint(sqrtPriceX96)*(uint(sqrtPriceX96))*(1e18 /* 1e12 + 1e6 decimal representation */) >> (96 * 2);
        // flip the fraction
        price = (1e24 / price) / 1e12;
      }
    }

Tool used

Manual Review

Recommendation

Use the TWAP price and don't use spot price as it's easy to manipulate.
Medium article explaining in detail

Duplicate of #451

@github-actions github-actions bot closed this as completed Jun 5, 2023
@github-actions github-actions bot added High A valid High severity issue Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label labels Jun 5, 2023
@sherlock-admin sherlock-admin added the Reward A payout will be made for this issue label Jun 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label High A valid High severity issue Reward A payout will be made for this issue
Projects
None yet
Development

No branches or pull requests

1 participant