sherlock-audit / 2023-12-ubiquity-judging

2 stars 2 forks source link

FastTiger - If a user predicts that the ChainLinkPrice price will fall, he or she may preserve the value of his collateral and the protocol may suffer damages. #224

Closed sherlock-admin2 closed 6 months ago

sherlock-admin2 commented 6 months ago

FastTiger

high

If a user predicts that the ChainLinkPrice price will fall, he or she may preserve the value of his collateral and the protocol may suffer damages.

Summary

If the user predicts that the price of the collateral will fall in ChainLink, mintDollar() is performed before the price falls, and redeemDollar() is performed after the price falls.

Users can preserve the value of their collateral by spending only GAT and fees. This can cause damage to the protocol.

Vulnerability Detail

In the protocol, the updateChainLinkCollateralPrice() function is called within the mintDollar() and redeemDollar() functions to fetch the current collateral price.

The user currently predicts that the price of collateral will fluctuate on ChainLink in collateralPriceFeedAddresses[collateralIndex]. Users perform the following operations to reduce damage caused by price fluctuations (for example, collateral is DAI).

Example.

Attacker estimate that the price of DAI is to be decreased from 0.13 to 0.12.

Attacker already holds 10,000 of DAI tokens.

  1. Mint 10,000 DAI and receive 1,300 Ubiquity Dollar Token.
  2. The price of DAI is decreased from 0.13 to 0.12
  3. Attacker soon redeems 1,300 Ubiquity Dollar Token to 10,833 DAI. (should receive: 1,300/0.12=10,833)

The attacker just made 833 DAI profit and the protocol will deduct the collateral by this amount.

Impact

Attacker can gain profit and the protocol can lose collateral.

Code Snippet

ubiquity-dollar/packages/contracts/src/dollar/LibUbiquityPool.sol:L326 ubiquity-dollar/packages/contracts/src/dollar/LibUbiquityPool.sol:L399

Tool used

Manual Review

Recommendation

  1. The source retrieves prices from one place, that is, the ChainLink Price feed, but the values must be retrieved from multiple places and averaged.

  2. Add the following structure to LibUbiquityPool.sol. struct MintInfo{ uint256 price; uint256 mintTime; }

Add the following variables to struct UbiquityPoolStorage.

function redeemDollar( uint256 collateralIndex, uint256 dollarAmount, uint256 collateralOutMin ){ ... require(collateralOut>=collateralOutMin, "Collateral slippage");

function toggleMintRedeemBorrow( uint256 collateralIndex, uint8 toggleIndex ) internal { ... else if(toggleIndex==2) poolStorage.isBorrowPaused[collateralIndex]=!poolStorage.isBorrowPaused[collateralIndex];

Duplicate of #72

sherlock-admin2 commented 6 months ago

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

auditsea commented:

REF #080

sherlock-admin2 commented 6 months ago

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

auditsea commented:

REF #080