The RToken and DebtToken contracts include functions (updateLiquidityIndex and updateUsageIndex) that are responsible for updating key indices used in calculating accrued interest. Both functions are guarded by an onlyReservePool modifier, ensuring that only the designated reserve pool can call them. However, in practice, these functions are intended to be invoked by the LendingPool or ReserveLibrary. Due to the strict access control, if neither the LendingPool nor ReserveLibrary is set as the Reserve Pool, these functions become locked and effectively unusable, which may prevent the proper updating of liquidity and debt accrual data.
Function Implementations:
The updateLiquidityIndex function in the RToken contract:
The updateUsageIndex function in the DebtToken contract:
Access Control:
Both functions are protected by the onlyReservePool modifier:
The Issue:
In the current system configuration, the LendingPool or ReserveLibrary is expected to call these functions to update the reserve’s liquidity and usage indices. However, because these contracts are not assigned as the Reserve Pool (i.e., they do not match the _reservePool address), any call from them will revert. Consequently, the critical functions for updating interest and debt accrual remain inaccessible, which can lead to stale index values and erroneous calculations across the protocol.
Intended Operation:
The LendingPool or ReserveLibrary should call updateLiquidityIndex and updateUsageIndex during operations such as deposits, withdrawals, or borrowings to adjust the interest-bearing token values and debt calculations.
Misconfiguration Impact:
If the _reservePool variable is not set to the address of the LendingPool or ReserveLibrary, any attempt to update the indices will trigger the onlyReservePool check:
This prevents the function from executing and leaves the indices unmodified, resulting in inaccurate interest calculations and potential imbalances in the protocol’s accounting.
Demonstration:
A test scenario where LendingPool (or ReserveLibrary) attempts to update the liquidity or usage index will fail with an OnlyReservePool() error, highlighting that the functions are effectively locked due to the misconfiguration of the _reservePool address.
Stale Reserve Data:
Without the ability to update liquidity and usage indices, the protocol cannot accurately track accrued interest or debt, which can lead to mispriced borrow rates and incorrect deposit yields.
Systematic Accounting Errors:
Over time, the failure to update these indices can compound, leading to significant discrepancies in user balances and overall reserve health.
Operational Risk:
The inability to adjust these critical parameters may affect risk management and the stability of the protocol, potentially undermining user trust and leading to financial losses.
Manual Code Review
Foundry (Forge) for testing access control scenarios
Reconfigure Access Control:
Ensure that the _reservePool variable is correctly set to the address of the LendingPool or ReserveLibrary (whichever is intended to invoke these functions). This may involve:
Updating the constructor or initialization logic in the RToken and DebtToken contracts.
Adding administrative functions to update the _reservePool address securely if necessary.
Alternative Approach:
If the design requires that multiple contracts call these update functions, consider using a more flexible access control mechanism (e.g., AccessControl from OpenZeppelin) that permits a defined set of authorized callers instead of a single fixed address.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.