Obedient Lava Monkey
High
A failure to account for interest rate accruals on variable debt will cause borrow cap violations for the protocol as the total debt calculation underestimates the true borrow balance, allowing users to exceed the configured borrow cap.
In ValidationLogic.validateBorrow
, the total borrow balance (vars.totalDebt
) is computed as:
vars.totalSupplyVariableDebt = params.reserveCache.currScaledVariableDebt.rayMul(
params.reserveCache.nextVariableBorrowIndex
);
vars.totalDebt = vars.totalSupplyVariableDebt + params.amount;
The root cause lies in the dependency on the nextVariableBorrowIndex
to accurately reflect accrued interest when performing the borrow cap validation. If the index is not updated prior to the borrow validation due to a missed or skipped update (e.g. another function partially executed but didn't finalize the reserve's state), the protocol underestimates the current debt.
In ValidationLogic.validateBorrow
, the calculation:
vars.totalSupplyVariableDebt = params.reserveCache.currScaledVariableDebt.rayMul(
params.reserveCache.nextVariableBorrowIndex
);
relies on nextVariableBorrowIndex
being up-to-date with accrued interest. However:
- If a state-changing action (e.g., repay or flash loan) fails to update the index, the protocol uses stale values.
- This results in an underestimation of
vars.totalSupplyVariableDebt
, bypassing the borrow cap checks. - Borrowers can continue borrowing even when the true total debt exceeds the configured borrow cap.
This issue can occur due to race conditions, skipped updates, or execution sequences where the index isn't updated in time.
- Protocol Admin needs to set a non-zero borrow cap for a reserve.
- Borrow Reserve Index Update is not triggered due to missed or delayed state updates.
- Borrow transactions must occur across multiple blocks without an intermediate reserve index update.
- Borrow cap utilization is near the configured maximum.
- User A borrows from a reserve with a non-zero borrow cap, incrementing the variable debt.
- User B borrows before the nextVariableBorrowIndex is updated to reflect accumulated interest on previous borrowings.
- The borrow cap is violated as the protocol approves the borrow without correctly calculating the true total debt (due to underestimated accrual).
The protocol suffers a breach of its borrow cap policy, which may lead to liquidity exhaustion in the reserve. This can destabilize lending operations and increase insolvency risks.
Enforce a proactive update to nextVariableBorrowIndex
in all functions impacting the borrow state before computing vars.totalDebt
.