Open sherlock-admin2 opened 6 months ago
Low; the assetOracle
is different from the oracle
state var which is represented by the market's collateral. The assetOracle
checks the USDO price against USDC
The protocol team fixed this issue in PR/commit https://github.com/Tapioca-DAO/Tapioca-bar/pull/374.
0xadrii
medium
Variable opening fee will always be wrongly computed if collateral is not a stablecoin
Summary
Borrowing fees will be computed wrongly because of a combination of hardcoded values and a wrongly implemented setter function.
Vulnerability Detail
Tapioca applies a linearly scaling creation fee to open a new CDP in Big Bang markets. This is done via the internal
_computeVariableOpeningFee()
function every time a new borrow is performed.In order to compute the variable fee, the exchange rate will be queried. This rate is important in order to understand the current price of USDO related to the collateral asset.
_exchangeRate >= minMintFeeStart
, thenminMintFee
will be applied._exchangeRate <= maxMintFeeStart
, thenmaxMintFee
will be appliedAs per the comment in the code snippet shows below, Tapioca wrongly assumes that the exchange rate will always be
USDO <> USDC
, when in reality the actual collateral will dictate the exchange rate returned.It is also important to note the fact that contrary to what one would assume,
maxMintFeeStart
is assumed to be smaller thanminMintFeeStart
in order to perform the calculations:It is also important to note that
minMintFeeStart
andmaxMintFeeStart
are hardcoded when being initialized insideBigBang.sol
(as mentioned,maxMintFeeStart
is smaller thanminMintFeeStart
):While the values hardcoded initially to values that are coherent for a USDO <> stablecoin exchange rate, these values won’t make sense if we find ourselves fetching an exchcange rate of an asset not stable.
Let’s say the collateral asset is ETH. If ETH is at 4000$, then the exchange rate will return a value of 0,00025. This will make the computation inside
_computeVariableOpeningFee()
always apply the maximum fee when borrowing because_exchangeRate
is always smaller thanmaxMintFeeStart
by default.Although this has an easy fix (changing the values stored in
maxMintFeeStart
andminMintFeeStart
), this can’t be properly done because thesetMinAndMaxMintRange()
function wrongly assumes thatminMintFeeStart
must be smaller thanmaxMintFeeStart
(against what the actual calculations dictate in the_computeVariableOpeningFee()
):This will make it impossible to properly update the
maxMintFeeStart
andminMintFeeStart
to have proper values because if it is enforced thatmaxMintFeeStart
> thanminMintFeeStart
, then_computeVariableOpeningFee()
will always enter the firstif (_exchangeRate >= minMintFeeStart)
and wrongly return the minimum fee.Impact
Medium. Although this looks like a bug that doesn’t have a big impact in the protocol, it actually does. The fees will always be wrongly applied for collaterals different from stablecoins, and applying these kind of fees when borrowing is one of the core mechanisms to keep USDO peg, as described in Tapioca’s documentation. If this mechanisms doesn’t work properly, users won’t be properly incentivized to borrow/repay considering the different market conditions that might take place and affect USDO’s peg to $1.
Code Snippet
https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/contracts/markets/bigBang/BBLendingCommon.sol#L87-L91
https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/contracts/markets/bigBang/BigBang.sol#L194-L195
Tool used
Manual Review
Recommendation
The mitigation for this is straightforward. Change the
setMinAndMaxMintRange()
function so that_max
is enforced to be smaller than_min
:Also, I would recommend not to hardcode the values of
maxMintFeeStart
andminMintFeeStart
and pass them as parameter instead, inside_initCoreStorage()
, as they should always be different considering the collateral configured for that market.