Boost _ Folks Finance 33533 - [Smart Contract - Critical] depositDatainterestRate is not correct
Submitted on Mon Jul 22 2024 16:32:36 GMT-0400 (Atlantic Standard Time) by @ethprotector for Boost | Folks Finance
Report ID: #33533
Report type: Smart Contract
Report severity: Critical
Target: https://testnet.snowtrace.io/address/0x96e957bF63B5361C5A2F45C97C46B8090f2745C2
Impacts:
Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
Description
Brief/Intro
In HubPoolLogic.updateInterestRates function depositData.interestRate is not calculated correctly.
Vulnerability Details
function updateInterestRates(HubPoolState.PoolData storage poolData) internal {
HubPoolState.PoolAmountDataCache memory poolAmountDataCache = getPoolAmountDataCache(poolData);
uint256 totalDebt = poolAmountDataCache.variableBorrowTotalAmount + poolAmountDataCache.stableBorrowTotalAmount;
uint256 utilisationRatio = MathUtils.calcUtilisationRatio(totalDebt, poolData.depositData.totalAmount);
uint32 vr1 = poolData.variableBorrowData.vr1;
// calculate new interest rates
uint256 variableBorrowInterestRate = MathUtils.calcVariableBorrowInterestRate(
poolData.variableBorrowData.vr0,
vr1,
poolData.variableBorrowData.vr2,
utilisationRatio,
poolData.depositData.optimalUtilisationRatio
);
uint256 stableBorrowInterestRate = MathUtils.calcStableBorrowInterestRate(
vr1,
poolData.stableBorrowData.sr0,
poolData.stableBorrowData.sr1,
poolData.stableBorrowData.sr2,
poolData.stableBorrowData.sr3,
utilisationRatio,
poolData.depositData.optimalUtilisationRatio,
MathUtils.calcStableDebtToTotalDebtRatio(poolAmountDataCache.stableBorrowTotalAmount, totalDebt),
poolData.stableBorrowData.optimalStableToTotalDebtRatio
);
uint256 depositInterestRate = MathUtils.calcDepositInterestRate(
utilisationRatio,
MathUtils.calcOverallBorrowInterestRate(
poolAmountDataCache.variableBorrowTotalAmount,
poolAmountDataCache.stableBorrowTotalAmount,
poolData.variableBorrowData.interestRate,
poolData.stableBorrowData.averageInterestRate
),
poolData.feeData.retentionRate
);
// update interest rates
poolData.variableBorrowData.interestRate = variableBorrowInterestRate;
poolData.stableBorrowData.interestRate = stableBorrowInterestRate;
poolData.depositData.interestRate = depositInterestRate;
emit InterestRatesUpdated(variableBorrowInterestRate, stableBorrowInterestRate, depositInterestRate);
}poolData.variableBorrowData.interestRate is not current value. That is for last updates. So if the attacker uses flashloan, when the tx is complated, depositData.interestRate is changed.
Impact Details
Attacker can make the depositData.interestRate more than actual value. So when users (and the attacker) can get more collateral tokens than expected and others loss the money.
Attacker can make the depositData.interestRate smaller than actual value and liquidate some loans.
To fix it
use variableBorrowInterestRate instead of poolData.variableBorrowData.interestRate,
Proof of concept
Proof of Concept
In this PoC, I am going to show the first case (make the value more).
Create oracleManager.sol
oracleManager.solAfter a year, the contract is break in the testnet. So I used fixed price oracleManager for this test.
Create FlashloanContract.sol
FlashloanContract.solTest contract
Output
Last updated
Was this helpful?