In the original implementation, sometimes when dailyLendIncreaseLimitLeft/dailyDebtIncreaseLimitLeft changes value, they are not proceeded by a call to _resetDailyLendIncreaseLimit/_resetDailyDebtIncreaseLimit:
Consequently, these changes to dailyLendIncreaseLimitLeft/dailyDebtIncreaseLimitLeft will not be reflected in a new day, because in new day _resetDailyLendIncreaseLimit/_resetDailyDebtIncreaseLimit will just discard these changes.
Mitigation
PR #11
The mitigation code will calls _resetDailyLendIncreaseLimit/_resetDailyDebtIncreaseLimit every time dailyLendIncreaseLimitLeft/dailyDebtIncreaseLimitLeft is updated. For example in _withdraw function:
function _withdraw(address receiver, address owner, uint256 amount, bool isShare)
internal
returns (uint256 assets, uint256 shares)
{
(uint256 newDebtExchangeRateX96, uint256 newLendExchangeRateX96) = _updateGlobalInterest();
_resetDailyLendIncreaseLimit(newLendExchangeRateX96, false);
if (isShare) {
shares = amount;
assets = _convertToAssets(amount, newLendExchangeRateX96, Math.Rounding.Down);
} else {
assets = amount;
shares = _convertToShares(amount, newLendExchangeRateX96, Math.Rounding.Up);
}
uint256 ownerBalance = balanceOf(owner);
if (shares > ownerBalance) {
shares = ownerBalance;
assets = _convertToAssets(amount, newLendExchangeRateX96, Math.Rounding.Down);
}
// if caller has allowance for owners shares - may call withdraw
if (msg.sender != owner) {
_spendAllowance(owner, msg.sender, shares);
}
(uint256 balance,) = _getBalanceAndReserves(newDebtExchangeRateX96, newLendExchangeRateX96);
if (balance < assets) {
revert InsufficientLiquidity();
}
// fails if not enough shares
_burn(owner, shares);
SafeERC20.safeTransfer(IERC20(asset), receiver, assets);
// when amounts are withdrawn - they may be deposited again
dailyLendIncreaseLimitLeft = dailyLendIncreaseLimitLeft + assets;
emit Withdraw(msg.sender, receiver, owner, assets, shares);
}
Lines of code
Vulnerability details
C4 issue
M-08: DailyLendIncreaseLimitLeft and dailyDebtIncreaseLimitLeft are not adjusted accurately
Comment
In the original implementation, sometimes when
dailyLendIncreaseLimitLeft/dailyDebtIncreaseLimitLeft
changes value, they are not proceeded by a call to_resetDailyLendIncreaseLimit/_resetDailyDebtIncreaseLimit
:Consequently, these changes to
dailyLendIncreaseLimitLeft/dailyDebtIncreaseLimitLeft
will not be reflected in a new day, because in new day_resetDailyLendIncreaseLimit/_resetDailyDebtIncreaseLimit
will just discard these changes.Mitigation
PR #11 The mitigation code will calls
_resetDailyLendIncreaseLimit/_resetDailyDebtIncreaseLimit
every timedailyLendIncreaseLimitLeft/dailyDebtIncreaseLimitLeft
is updated. For example in_withdraw
function:The mitigation solved the original issue.
Conclusion
LGTM