The original calculateTVL function in the RestakeManager contract passes the wrong parameter to renzoOracle.lookupTokenValue when calculating the TVLs.
It incorrectly uses collateralTokens[i] (outer loop's counter) inside the inner loop instead of collateralTokens[j] (inner loop's counter), causing the same collateral token to be used for all iterations. This results in an incorrect totalWithdrawalQueueValue calculation, as the same collateral token is used throughout the inner loop with different collateral token balances.
for (uint256 i = 0; i < odLength; ) {
...
// Iterate through the tokens and get the value of each
uint256 tokenLength = collateralTokens.length;
for (uint256 j = 0; j < tokenLength; ) {
...
// record token value of withdraw queue
if (!withdrawQueueTokenBalanceRecorded) {
totalWithdrawalQueueValue += renzoOracle.lookupTokenValue(
collateralTokens[i],
collateralTokens[j].balanceOf(withdrawQueue)
);
}
unchecked {
++j;
}
}
...
unchecked {
++i;
}
}
The fix replaces collateralTokens[i] with collateralTokens[j] inside the inner loop, ensuring accurate calculation of the total withdrawal queue value by using the correct token for each iteration.
// record token value of withdraw queue
if (!withdrawQueueTokenBalanceRecorded) {
totalWithdrawalQueueValue += renzoOracle.lookupTokenValue(
collateralTokens[j],
collateralTokens[j].balanceOf(withdrawQueue)
);
}
Test
New test cases have been added to verify that the calculateTVL function accurately calculates the TVL by using the correct collateral token for each iteration. All tests have passed, confirming the fix.
Contract: RestakeManagerForkTest
Tests:
test_TVLConfiguration
Conclusion
By replacing collateralTokens[i] with collateralTokens[j], the calculateTVL function now correctly calculates the withdraw queue balance, leading to an accurate TVL calculation.
Lines of code
Vulnerability details
H-08: Incorrect withdraw queue balance in TVL calculation
Link to issue
Comments
The original
calculateTVL
function in theRestakeManager
contract passes the wrong parameter torenzoOracle.lookupTokenValue
when calculating the TVLs.It incorrectly uses
collateralTokens[i]
(outer loop's counter) inside the inner loop instead ofcollateralTokens[j]
(inner loop's counter), causing the same collateral token to be used for all iterations. This results in an incorrecttotalWithdrawalQueueValue
calculation, as the same collateral token is used throughout the inner loop with different collateral token balances.Mitigation
PR: Pull Request 87 - H08FIX
The fix replaces
collateralTokens[i]
withcollateralTokens[j]
inside the inner loop, ensuring accurate calculation of the total withdrawal queue value by using the correct token for each iteration.Test
New test cases have been added to verify that the calculateTVL function accurately calculates the TVL by using the correct collateral token for each iteration. All tests have passed, confirming the fix.
Contract: RestakeManagerForkTest
Tests:
Conclusion
By replacing
collateralTokens[i]
withcollateralTokens[j]
, thecalculateTVL
function now correctly calculates the withdraw queue balance, leading to an accurate TVL calculation.