Skip to content

Latest commit

 

History

History
74 lines (55 loc) · 2.98 KB

File metadata and controls

74 lines (55 loc) · 2.98 KB

Fast Khaki Raccoon

Medium

LendingAssetVault is not ERC4626 compliant

Summary

LendingAssetVault is not ERC4626 compliant which is expected as seen in the README:

Is the codebase expected to comply with any specific EIPs?

Many of our contracts implement ERC20 and ERC4626 which we attempt to comply with in the entirety of those standards for contracts that implement them.

Root Cause

Upon calling LendingAssetVault::previewRedeem(), we simply return _previewConvertToAssets() which uses the following formula to compute the assets the user would receive:

_assets = (_shares * _previewCbr()) / PRECISION;

_previewCbr() looks like this:

    function _previewCbr() internal view returns (uint256) {
        uint256 _supply = totalSupply();
        uint256 _previewTotalAssets = _previewAddInterestAndMdInAllVaults();
        return _supply == 0 ? PRECISION : (PRECISION * _previewTotalAssets) / _supply;
    }

_previewAddInterestAndMdInAllVaults() has these 2 important lines and then has its usual utilization changes calculations:

(, , , , VaultAccount memory _totalAsset, ) = IFraxlendPair(_vault).previewAddInterest();
uint256 _newVaultCbr = _totalAsset.toAmount(PRECISION, false);

FraxlendPair::previewAddInterest() calculates the interest without factoring in an important condition that exists upon actually adding interest through FraxlendPair::addInterest():

if (_currentUtilizationRate != 0 && _rateChange < (_currentUtilizationRate * minURChangeForExternalAddInterest) / UTIL_PREC) {
            emit SkipAddingInterest(_rateChange);
} else {
            (, _interestEarned, _feesAmount, _feesShare, _currentRateInfo) = _addInterest();
}

This results in the preview function accruing interest even though we might not accrue interest upon an actual redeem causing the preview function to return more assets than the actual amount, this is incompliant based on the ERC4626 standard.

Internal Pre-conditions

No response

External Pre-conditions

No response

Attack Path

  1. User calls previewRedeem() for his 100 shares and we preview a 20 asset interest, thus the function returns 100 * (150 + 20) / 150 = 113,3333333333 assets (simplifying the asset conversion formula a bit)
  2. This is incorrect as upon actually redeeming and trying to update the vault metadata, we have this code:
(uint256 _interestEarned, , , , , ) = IFraxlendPair(_vault).addInterest(false);
if (_interestEarned > 0) {
          _updateAssetMetadataFromVault(_vault);
}
  1. Adding interest through addInterest() might be skipped if the utilisation ratio change is not big enough, thus we might skip the 20 asset accrual
  2. User will only receive 100 assets, ~13 assets less than what the preview function returned

Impact

ERC4626 incompliance

PoC

No response

Mitigation

Upon calling the preview functions, only add accrued interest if the interest would actually be accrued