Inaccurate Interest Accrual Due to block.number Usage
Closed this issue · 0 comments
Lines of code
Vulnerability details
Vulnerability Details
In the ICDPVault interface, the lastDebtUpdate field is used to store the timestamp of the last update to a user's debt. This timestamp is crucial for calculating accrued interest over time. The system relies on lastDebtUpdate to accurately compute the time elapsed since the last debt update for interest accrual. However, the function _modifyPosition currently uses block.number instead of block.timestamp to update lastDebtUpdate.
The use of block.number introduces inaccuracies in calculating time-based operations such as interest accrual. Since block numbers do not correspond to a consistent passage of real-world time, relying on them can lead to incorrect interest calculations, which could either undercharge or overcharge users.
Code Snippet
function _modifyPosition(
address owner,
Position memory position,
uint256 newDebt,
uint256 newCumulativeIndex,
int256 deltaCollateral,
uint256 totalDebt_
) internal returns (Position memory) {
uint256 currentDebt = position.debt;
// update collateral and debt amounts by the deltas
position.collateral = add(position.collateral, deltaCollateral);
position.debt = newDebt;
position.cumulativeIndexLastUpdate = newCumulativeIndex;
position.lastDebtUpdate = uint64(block.number); // Issue: Incorrect time tracking
}Impact
- Using
block.numberinstead ofblock.timestampmay result in inaccurate interest charges because the system incorrectly estimates the time elapsed. - Users could be unfairly charged more or less interest than they should be, leading to a loss of trust in the system.
Scenario
When a user's debt position is updated, the system calculates interest based on the difference between the current time and lastDebtUpdate. If this difference is based on block.number, which varies in time consistency, the system may incorrectly calculate the interest. For instance, during periods of network congestion or unusually fast block times, the interest accrued may be significantly off from what it should be.
Fix
Replace block.number with block.timestamp to ensure the lastDebtUpdate reflects the actual time:
position.lastDebtUpdate = uint64(block.timestamp);Example Usage:
function calculateAccruedInterest(address owner) public view returns (uint256) {
(, uint256 debt, uint256 lastDebtUpdate, , , ) = positions(owner);
uint256 timeElapsed = block.timestamp - lastDebtUpdate;
uint256 interestRate = annualInterestRate / 365 days; // Simplified daily interest rate calculation
return (debt * interestRate * timeElapsed) / 365 days;
}Assessed type
Context