VIS-2 / taobank-04-24

0 stars 0 forks source link

Incorrect borrow rate calculation leads to user funds loss #11

Open DanailYordanov opened 5 months ago

DanailYordanov commented 5 months ago

Impact

Severity: High Likelihood: High

Context

VaultBorrowRate::getBorrowRate()

Description

The VaultBorrowRate::getBorrowRate() function is accountable for calculating the weighted borrow rate, but has a flaw when calculating the collateral value on L37 which arises when there are multiple collateral tokens, including one with less than 18 decimals (e.g., USDC with 6 decimals) and another with 18 decimals (e.g., WETH). The calculation on L35 performs normalization of the collateral amount to 18 decimal places. However, the subsequent calculation on L37 does not appropriately adjust for tokens with fewer decimals, resulting in skewed borrow rate calculations due to having 10 ** _priceFeed.decimals(_collateralAddress) in the denominator instead of 1e18.

Consider this scenario:

  1. Alice deposits 1 USDC (9.9% BR) and 50 WETH (1% BR), worth $1 and $150,000, respectively. It's obvious that WETH's weight is magnitudes bigger than the USDC's.
  2. But due to dividing the collateral value by 1e6 instead of 1e18, the USDC's weight appears to be much bigger, thus leading to the overall borrow rate being ~9.9% rather than ~1%.
  3. Alice borrows stable tokens but receives less than the expected amount as the fee is much bigger now.
    function getBorrowRate(
    address _vaultAddress
    ) external view returns (uint256) {
    // ** code **
        uint256 _normalizedCollateralAmount = _collateralAmount *
            (10 ** (18 - _priceFeed.decimals(_collateralAddress)));
        uint256 _collateralValue = (_normalizedCollateralAmount * _price) /
    @>         (10 ** _priceFeed.decimals(_collateralAddress)); // @audit should divide by 1e18
        uint256 _weightedFee = (_collateralValue * _borrowRate) / 1e18;
    // ** code **
    }

Recommendation

Change the denominator on L37 to be 1e18 as follows:

uint256 _collateralValue = (_normalizedCollateralAmount * _price) / 1e18;

PoC

To verify the issue, follow this guide and include this test in the codebase. This test highlights discrepancies in received funds due to the inaccurate borrowing rate calculation.