Fast Khaki Raccoon
Medium
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.
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.
No response
No response
- User calls
previewRedeem()
for his 100 shares and we preview a 20 asset interest, thus the function returns100 * (150 + 20) / 150 = 113,3333333333
assets (simplifying the asset conversion formula a bit) - 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);
}
- Adding interest through
addInterest()
might be skipped if the utilisation ratio change is not big enough, thus we might skip the 20 asset accrual - User will only receive 100 assets, ~13 assets less than what the preview function returned
ERC4626 incompliance
No response
Upon calling the preview functions, only add accrued interest if the interest would actually be accrued