xiaoming90 - Incorrect valuation of vault share #60
Labels
Has Duplicates
A valid issue with 1+ other issues describing the same vulnerability
High
A valid High severity issue
Reward
A payout will be made for this issue
Sponsor Confirmed
The sponsor acknowledged this issue is valid
Will Fix
The sponsor confirmed this issue will be fixed
xiaoming90
High
Incorrect valuation of vault share
Summary
The code for computing the valuation of the vault shares was found to be incorrect. As a result, the account's collateral will be overinflated, allowing malicious users to borrow significantly more than the actual collateral value, draining assets from the protocol.
Vulnerability Detail
Let$BT$ be the borrowed token with 6 decimal precision, and $RT$ be the redemption token with 18 decimal precision.
When a withdraw request has split and is finalized, the following$BT$ ).
_getValueOfSplitFinalizedWithdrawRequest
function will be used to calculate the value of a withdraw request in terms of the borrowed token (In Line 77 below, the$RT$ ) and borrowed token ($BT$ ).
Deployments.TRADING_MODULE.getOraclePrice
function will be called to fetch the exchange rate of the redemption token (https://github.com/sherlock-audit/2024-06-leveraged-vaults/blob/main/leveraged-vaults-private/contracts/vaults/common/WithdrawRequestBase.sol#L77
Within the$RT$ is the base, while the $BT$ is the quote here.
Deployments.TRADING_MODULE.getOraclePrice
function, chainlink oracle will be used. Refer to the source code's comment on Lines 255-257 below for more details. Note that theAssume that one$BT$ is worth 1 USD, so the $RT$ is worth 10 USD, so the
quotePrice
will be 1e8. Assume that onebasePrice
will be 10e18. Note that Chainlink oracle's price is always denominated in 8 decimals for USD price feed.This function will always return the exchange rate is$RT$ is worth 10 units of $BT$ .
RATE_DECIMALS
(18 decimals - Hardcoded). Thus, based on the calculation in Lines 283-285, the exchange rate returned will be 10e18, which is equivalent to one unit ofhttps://github.com/sherlock-audit/2024-06-leveraged-vaults/blob/main/leveraged-vaults-private/contracts/trading/TradingModule.sol#L283
The
rate
at Line 77 below will be 10e18 based on our earlier calculation. Note the following:s.totalWithdraw
is the totals.totalWithdraw=100e18 RT
was claimed.w.vaultShares
ands.totalVaultShares
are the number of vault shares and is denominated in 8 decimals (INTERNAL_TOKEN_PRECISION
). Assume thatw.vaultShares=5e8
ands.totalVaultShares=10e8
Constants.EXCHANGE_RATE_PRECISION
is 1e18Intuitively, the split's total withdraw ($RT$ . In terms of the borrowed token ($BT$ ), it will be 1000 units of $BT$ since the price is (1:10). Since the withdraw request owns 50% of the vault shares in the split withdraw request, it is entitled to 500 units of $BT$ .
s.totalWithdraw
) is 100 units ofhttps://github.com/sherlock-audit/2024-06-leveraged-vaults/blob/main/leveraged-vaults-private/contracts/vaults/common/WithdrawRequestBase.sol#L77
To calculate the value of a withdraw request in terms of the borrowed token ($BT$ ), the following formula at Line 79 above will be used:
However, the code above indicates that the withdraw request is entitled to 500000000000000 units of$BT$ instead of 500 units of $BT$ , which is overly inflated. As a result, the account's collateral will be overly inflated.
Impact
The account's collateral will be overinflated, allowing malicious users to borrow significantly more than the actual collateral value, stealing assets from the protocol.
Code Snippet
https://github.com/sherlock-audit/2024-06-leveraged-vaults/blob/main/leveraged-vaults-private/contracts/vaults/common/WithdrawRequestBase.sol#L77
https://github.com/sherlock-audit/2024-06-leveraged-vaults/blob/main/leveraged-vaults-private/contracts/trading/TradingModule.sol#L283
Tool used
Manual Review
Recommendation
Update the formula to as follows:
BORROW_PRECISION
= 1e6 andREDEMPTION_PRECISION
= 1e18.Let's redo the calculation to verify that the new formula works as intended:
The new formula returned 500 units of$BT$ , which is correct.
The text was updated successfully, but these errors were encountered: