diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index a7a5e1ca..12119a3a 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -305,7 +305,6 @@ interface ILendingPool { uint256 principalVariableDebt, uint256 stableBorrowRate, uint256 liquidityRate, - uint256 variableBorrowIndex, uint40 stableRateLastUpdated, bool usageAsCollateralEnabled ); diff --git a/contracts/interfaces/IReserveInterestRateStrategy.sol b/contracts/interfaces/IReserveInterestRateStrategy.sol index 48311e70..acc097bf 100644 --- a/contracts/interfaces/IReserveInterestRateStrategy.sol +++ b/contracts/interfaces/IReserveInterestRateStrategy.sol @@ -23,7 +23,8 @@ interface IReserveInterestRateStrategy { uint256 utilizationRate, uint256 totalBorrowsStable, uint256 totalBorrowsVariable, - uint256 averageStableBorrowRate + uint256 averageStableBorrowRate, + uint256 reserveFactor ) external view diff --git a/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol b/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol index c2303254..c93e6c38 100644 --- a/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol +++ b/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol @@ -49,6 +49,7 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { //slope of the stable interest curve when utilization rate > OPTIMAL_UTILIZATION_RATE. Expressed in ray uint256 internal immutable _stableRateSlope2; + constructor( LendingPoolAddressesProvider provider, uint256 baseVariableBorrowRate, @@ -89,6 +90,15 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { return _baseVariableBorrowRate; } + struct CalcInterestRatesLocalVars { + + uint256 totalBorrows; + uint256 currentVariableBorrowRate; + uint256 currentStableBorrowRate; + uint256 currentLiquidityRate; + uint256 utilizationRate; + } + /** * @dev calculates the interest rates depending on the available liquidity and the total borrowed. * @param reserve the address of the reserve @@ -96,6 +106,7 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { * @param totalBorrowsStable the total borrowed from the reserve a stable rate * @param totalBorrowsVariable the total borrowed from the reserve at a variable rate * @param averageStableBorrowRate the weighted average of all the stable rate borrows + * @param reserveFactor the reserve portion of the interest to redirect to the reserve treasury * @return currentLiquidityRate the liquidity rate * @return currentStableBorrowRate stable borrow rate * @return currentVariableBorrowRate variable borrow rate @@ -105,7 +116,8 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { uint256 availableLiquidity, uint256 totalBorrowsStable, uint256 totalBorrowsVariable, - uint256 averageStableBorrowRate + uint256 averageStableBorrowRate, + uint256 reserveFactor ) external override @@ -116,16 +128,19 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { uint256 ) { - uint256 totalBorrows = totalBorrowsStable.add(totalBorrowsVariable); - uint256 currentVariableBorrowRate = 0; - uint256 currentStableBorrowRate = 0; - uint256 currentLiquidityRate = 0; - uint256 utilizationRate = totalBorrows == 0 + CalcInterestRatesLocalVars memory vars; + + vars.totalBorrows = totalBorrowsStable.add(totalBorrowsVariable); + vars.currentVariableBorrowRate = 0; + vars.currentStableBorrowRate = 0; + vars.currentLiquidityRate = 0; + + uint256 utilizationRate = vars.totalBorrows == 0 ? 0 - : totalBorrows.rayDiv(availableLiquidity.add(totalBorrows)); + : vars.totalBorrows.rayDiv(availableLiquidity.add(vars.totalBorrows)); - currentStableBorrowRate = ILendingRateOracle(addressesProvider.getLendingRateOracle()) + vars.currentStableBorrowRate = ILendingRateOracle(addressesProvider.getLendingRateOracle()) .getMarketBorrowRate(reserve); if (utilizationRate > OPTIMAL_UTILIZATION_RATE) { @@ -133,31 +148,32 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { EXCESS_UTILIZATION_RATE ); - currentStableBorrowRate = currentStableBorrowRate.add(_stableRateSlope1).add( + vars.currentStableBorrowRate = vars.currentStableBorrowRate.add(_stableRateSlope1).add( _stableRateSlope2.rayMul(excessUtilizationRateRatio) ); - currentVariableBorrowRate = _baseVariableBorrowRate.add(_variableRateSlope1).add( + vars.currentVariableBorrowRate = _baseVariableBorrowRate.add(_variableRateSlope1).add( _variableRateSlope2.rayMul(excessUtilizationRateRatio) ); } else { - currentStableBorrowRate = currentStableBorrowRate.add( + vars.currentStableBorrowRate = vars.currentStableBorrowRate.add( _stableRateSlope1.rayMul(utilizationRate.rayDiv(OPTIMAL_UTILIZATION_RATE)) ); - currentVariableBorrowRate = _baseVariableBorrowRate.add( + vars.currentVariableBorrowRate = _baseVariableBorrowRate.add( utilizationRate.rayDiv(OPTIMAL_UTILIZATION_RATE).rayMul(_variableRateSlope1) ); } - currentLiquidityRate = _getOverallBorrowRate( + vars.currentLiquidityRate = _getOverallBorrowRate( totalBorrowsStable, totalBorrowsVariable, - currentVariableBorrowRate, + vars.currentVariableBorrowRate, averageStableBorrowRate ) - .rayMul(utilizationRate); + .rayMul(utilizationRate) + .rayMul(WadRayMath.ray().sub(reserveFactor)); - return (currentLiquidityRate, currentStableBorrowRate, currentVariableBorrowRate); + return (vars.currentLiquidityRate, vars.currentStableBorrowRate, vars.currentVariableBorrowRate); } /** diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 9e4e6707..50944f9f 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -12,6 +12,7 @@ import {IAToken} from '../tokenization/interfaces/IAToken.sol'; import {Helpers} from '../libraries/helpers/Helpers.sol'; import {Errors} from '../libraries/helpers/Errors.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol'; +import {PercentageMath} from '../libraries/math/PercentageMath.sol'; import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; import {GenericLogic} from '../libraries/logic/GenericLogic.sol'; import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol'; @@ -19,12 +20,12 @@ import {ReserveConfiguration} from '../libraries/configuration/ReserveConfigurat import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol'; import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol'; import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol'; +import {DebtTokenBase} from '../tokenization/base/DebtTokenBase.sol'; import {IFlashLoanReceiver} from '../flashloan/interfaces/IFlashLoanReceiver.sol'; import {LendingPoolLiquidationManager} from './LendingPoolLiquidationManager.sol'; import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol'; import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol'; - /** * @title LendingPool contract * @notice Implements the actions of the LendingPool, and exposes accessory methods to fetch the users and reserve data @@ -34,6 +35,7 @@ import {ILendingPool} from '../interfaces/ILendingPool.sol'; contract LendingPool is VersionedInitializable, ILendingPool { using SafeMath for uint256; using WadRayMath for uint256; + using PercentageMath for uint256; using ReserveLogic for ReserveLogic.ReserveData; using ReserveConfiguration for ReserveConfiguration.Map; using UserConfiguration for UserConfiguration.Map; @@ -224,6 +226,9 @@ contract LendingPool is VersionedInitializable, ILendingPool { reserve.updateCumulativeIndexesAndTimestamp(); + address debtTokenAddress = interestRateMode == ReserveLogic.InterestRateMode.STABLE ? reserve.stableDebtTokenAddress : reserve.variableDebtTokenAddress; + _mintToReserveTreasury(reserve, onBehalfOf, debtTokenAddress); + //burns an equivalent amount of debt tokens if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) { IStableDebtToken(reserve.stableDebtTokenAddress).burn(onBehalfOf, paybackAmount); @@ -265,6 +270,10 @@ contract LendingPool is VersionedInitializable, ILendingPool { reserve.updateCumulativeIndexesAndTimestamp(); + address debtTokenAddress = interestRateMode == ReserveLogic.InterestRateMode.STABLE ? reserve.stableDebtTokenAddress : reserve.variableDebtTokenAddress; + _mintToReserveTreasury(reserve, msg.sender, debtTokenAddress); + + if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) { //burn stable rate tokens, mint variable rate tokens IStableDebtToken(reserve.stableDebtTokenAddress).burn(msg.sender, stableDebt); @@ -321,6 +330,9 @@ contract LendingPool is VersionedInitializable, ILendingPool { reserve.updateCumulativeIndexesAndTimestamp(); + _mintToReserveTreasury(reserve, user, address(stableDebtToken)); + + stableDebtToken.burn(user, stableBorrowBalance); stableDebtToken.mint(user, stableBorrowBalance, reserve.currentStableBorrowRate); @@ -609,7 +621,6 @@ contract LendingPool is VersionedInitializable, ILendingPool { uint256 principalVariableDebt, uint256 stableBorrowRate, uint256 liquidityRate, - uint256 variableBorrowIndex, uint40 stableRateLastUpdated, bool usageAsCollateralEnabled ) @@ -625,7 +636,6 @@ contract LendingPool is VersionedInitializable, ILendingPool { user ); usageAsCollateralEnabled = _usersConfig[user].isUsingAsCollateral(reserve.index); - variableBorrowIndex = IVariableDebtToken(reserve.variableDebtTokenAddress).getUserIndex(user); } function getReserves() external override view returns (address[] memory) { @@ -706,6 +716,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { * @param vars Input struct for the borrowing action, in order to avoid STD errors **/ function _executeBorrow(ExecuteBorrowParams memory vars) internal { + ReserveLogic.ReserveData storage reserve = _reserves[vars.asset]; UserConfiguration.Map storage userConfig = _usersConfig[msg.sender]; @@ -730,13 +741,21 @@ contract LendingPool is VersionedInitializable, ILendingPool { uint256 reserveIndex = reserve.index; + if (!userConfig.isBorrowing(reserveIndex)) { userConfig.setBorrowing(reserveIndex, true); } + address debtTokenAddress = ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE ? + reserve.stableDebtTokenAddress + : + reserve.variableDebtTokenAddress; + reserve.updateCumulativeIndexesAndTimestamp(); + _mintToReserveTreasury(reserve, vars.user, debtTokenAddress); + //caching the current stable borrow rate uint256 currentStableRate = 0; @@ -745,13 +764,13 @@ contract LendingPool is VersionedInitializable, ILendingPool { ) { currentStableRate = reserve.currentStableBorrowRate; - IStableDebtToken(reserve.stableDebtTokenAddress).mint( + IStableDebtToken(debtTokenAddress).mint( vars.user, vars.amount, currentStableRate ); } else { - IVariableDebtToken(reserve.variableDebtTokenAddress).mint(vars.user, vars.amount); + IVariableDebtToken(debtTokenAddress).mint(vars.user, vars.amount); } reserve.updateInterestRates(vars.asset, vars.aTokenAddress, 0, vars.releaseUnderlying ? vars.amount : 0); @@ -848,4 +867,19 @@ contract LendingPool is VersionedInitializable, ILendingPool { function getAddressesProvider() external view returns (ILendingPoolAddressesProvider) { return _addressesProvider; } + + function _mintToReserveTreasury(ReserveLogic.ReserveData storage reserve, address user, address debtTokenAddress) internal { + + uint256 currentPrincipalBalance = DebtTokenBase(debtTokenAddress).principalBalanceOf(user); + //calculating the interest accrued since the last borrow and minting the equivalent amount to the reserve factor + if(currentPrincipalBalance > 0){ + + uint256 balanceIncrease = IERC20(debtTokenAddress).balanceOf(user).sub(currentPrincipalBalance); + + uint256 amountForReserveFactor = balanceIncrease.percentMul(reserve.configuration.getReserveFactor()); + + IAToken(reserve.aTokenAddress).mintToReserve(amountForReserveFactor); + } + + } } diff --git a/contracts/lendingpool/LendingPoolLiquidationManager.sol b/contracts/lendingpool/LendingPoolLiquidationManager.sol index 12ecf777..dee6d90c 100644 --- a/contracts/lendingpool/LendingPoolLiquidationManager.sol +++ b/contracts/lendingpool/LendingPoolLiquidationManager.sol @@ -10,6 +10,7 @@ import {LendingPoolAddressesProvider} from '../configuration/LendingPoolAddresse import {IAToken} from '../tokenization/interfaces/IAToken.sol'; import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol'; import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol'; +import {DebtTokenBase} from '../tokenization/base/DebtTokenBase.sol'; import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol'; import {GenericLogic} from '../libraries/logic/GenericLogic.sol'; import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; @@ -208,6 +209,9 @@ contract LendingPoolLiquidationManager is VersionedInitializable { //update the principal reserve principalReserve.updateCumulativeIndexesAndTimestamp(); + + + principalReserve.updateInterestRates( principal, principalReserve.aTokenAddress, @@ -216,16 +220,29 @@ contract LendingPoolLiquidationManager is VersionedInitializable { ); if (vars.userVariableDebt >= vars.actualAmountToLiquidate) { - IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn( + + address tokenAddress = principalReserve.variableDebtTokenAddress; + + _mintToReserveTreasury(principalReserve, user, tokenAddress); + + IVariableDebtToken(tokenAddress).burn( user, vars.actualAmountToLiquidate ); } else { - IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn( + + address tokenAddress = principalReserve.variableDebtTokenAddress; + + _mintToReserveTreasury(principalReserve, user, tokenAddress); + + IVariableDebtToken(tokenAddress).burn( user, vars.userVariableDebt ); - IStableDebtToken(principalReserve.stableDebtTokenAddress).burn( + + tokenAddress = principalReserve.stableDebtTokenAddress; + + IStableDebtToken(tokenAddress).burn( user, vars.actualAmountToLiquidate.sub(vars.userVariableDebt) ); @@ -337,4 +354,19 @@ contract LendingPoolLiquidationManager is VersionedInitializable { } return (collateralAmount, principalAmountNeeded); } + + function _mintToReserveTreasury(ReserveLogic.ReserveData storage reserve, address user, address debtTokenAddress) internal { + + uint256 currentPrincipalBalance = DebtTokenBase(debtTokenAddress).principalBalanceOf(user); + //calculating the interest accrued since the last borrow and minting the equivalent amount to the reserve factor + if(currentPrincipalBalance > 0){ + + uint256 balanceIncrease = IERC20(debtTokenAddress).balanceOf(user).sub(currentPrincipalBalance); + + uint256 amountForReserveFactor = balanceIncrease.percentMul(reserve.configuration.getReserveFactor()); + + IAToken(reserve.aTokenAddress).mintToReserve(amountForReserveFactor); + } + + } } diff --git a/contracts/libraries/configuration/ReserveConfiguration.sol b/contracts/libraries/configuration/ReserveConfiguration.sol index 46ad9ba9..96c0024c 100644 --- a/contracts/libraries/configuration/ReserveConfiguration.sol +++ b/contracts/libraries/configuration/ReserveConfiguration.sol @@ -21,6 +21,7 @@ library ReserveConfiguration { uint256 constant FROZEN_MASK = 0xDFFFFFFFFFFFFFF; uint256 constant BORROWING_MASK = 0xBFFFFFFFFFFFFFF; uint256 constant STABLE_BORROWING_MASK = 0x7FFFFFFFFFFFFFF; + uint256 constant RESERVE_FACTOR_MASK = 0xFFFFFFFFFFFFFFFF; struct Map { //bit 0-15: LTV @@ -31,9 +32,27 @@ library ReserveConfiguration { //bit 57: reserve is freezed //bit 58: borrowing is enabled //bit 59: stable rate borrowing enabled + //bit 64-79: reserve factor uint256 data; } + /** + * @dev sets the reserve factor of the reserve + * @param self the reserve configuration + * @param ltv the new ltv + **/ + function setReserveFactor(ReserveConfiguration.Map memory self, uint256 ltv) internal pure { + self.data = (self.data & RESERVE_FACTOR_MASK) | ltv; + } + + /** + * @dev gets the reserve factor of the reserve + * @param self the reserve configuration + * @return the reserve factor + **/ + function getReserveFactor(ReserveConfiguration.Map storage self) internal view returns (uint256) { + return self.data & ~RESERVE_FACTOR_MASK; + } /** * @dev sets the Loan to Value of the reserve * @param self the reserve configuration diff --git a/contracts/libraries/logic/ReserveLogic.sol b/contracts/libraries/logic/ReserveLogic.sol index 607c8c63..90ed10cf 100644 --- a/contracts/libraries/logic/ReserveLogic.sol +++ b/contracts/libraries/logic/ReserveLogic.sol @@ -246,7 +246,8 @@ library ReserveLogic { vars.availableLiquidity.add(liquidityAdded).sub(liquidityTaken), IERC20(vars.stableDebtTokenAddress).totalSupply(), IERC20(reserve.variableDebtTokenAddress).totalSupply(), - vars.currentAvgStableRate + vars.currentAvgStableRate, + reserve.configuration.getReserveFactor() ); require(vars.newLiquidityRate < (1 << 128), "ReserveLogic: Liquidity rate overflow"); require(vars.newStableRate < (1 << 128), "ReserveLogic: Stable borrow rate overflow"); diff --git a/contracts/mocks/upgradeability/MockAToken.sol b/contracts/mocks/upgradeability/MockAToken.sol index 05f0db4e..a0368535 100644 --- a/contracts/mocks/upgradeability/MockAToken.sol +++ b/contracts/mocks/upgradeability/MockAToken.sol @@ -10,7 +10,7 @@ contract MockAToken is AToken { address _underlyingAssetAddress, string memory _tokenName, string memory _tokenSymbol - ) public AToken(_pool, _underlyingAssetAddress, _tokenName, _tokenSymbol) {} + ) public AToken(_pool, _underlyingAssetAddress,address(0), _tokenName, _tokenSymbol) {} function getRevision() internal override pure returns (uint256) { return 0x2; diff --git a/contracts/tokenization/AToken.sol b/contracts/tokenization/AToken.sol index de178819..36ca5ecb 100644 --- a/contracts/tokenization/AToken.sol +++ b/contracts/tokenization/AToken.sol @@ -25,6 +25,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken { uint256 public constant UINT_MAX_VALUE = uint256(-1); address public immutable UNDERLYING_ASSET_ADDRESS; + address public immutable RESERVE_TREASURY_ADDRESS; mapping(address => uint256) private _userIndexes; mapping(address => address) private _interestRedirectionAddresses; @@ -48,11 +49,13 @@ contract AToken is VersionedInitializable, ERC20, IAToken { constructor( LendingPool pool, address underlyingAssetAddress, + address reserveTreasuryAddress, string memory tokenName, string memory tokenSymbol ) public ERC20(tokenName, tokenSymbol, 18) { _pool = pool; UNDERLYING_ASSET_ADDRESS = underlyingAssetAddress; + RESERVE_TREASURY_ADDRESS = reserveTreasuryAddress; } function getRevision() internal virtual override pure returns (uint256) { @@ -183,6 +186,11 @@ contract AToken is VersionedInitializable, ERC20, IAToken { emit Mint(user, amount, balanceIncrease, index); } + function mintToReserve(uint256 amount) external override onlyLendingPool { + uint256 index = _pool.getReserveNormalizedIncome(UNDERLYING_ASSET_ADDRESS); + _mint(RESERVE_TREASURY_ADDRESS, amount.div(index)); + } + /** * @dev transfers tokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken * only lending pools can call this function diff --git a/contracts/tokenization/VariableDebtToken.sol b/contracts/tokenization/VariableDebtToken.sol index 1fcda07a..80f626f9 100644 --- a/contracts/tokenization/VariableDebtToken.sol +++ b/contracts/tokenization/VariableDebtToken.sol @@ -17,6 +17,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { using WadRayMath for uint256; uint256 public constant DEBT_TOKEN_REVISION = 0x1; + mapping(address => uint256) _userIndexes; constructor( address pool, @@ -59,6 +60,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { uint256 index = POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET); _mint(user, amount.rayDiv(index)); + _userIndexes[user] = index; emit MintDebt(user, amount, index); } @@ -71,7 +73,15 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { uint256 index = POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET); _burn(user, amount.rayDiv(index)); - + _userIndexes[user] = index; emit BurnDebt(user, amount, index); } + + /** + * @dev Returns the principal debt balance of the user from + * @return The debt balance of the user since the last burn/mint action + **/ + function principalBalanceOf(address user) public virtual override view returns (uint256) { + return super.balanceOf(user).rayMul(_userIndexes[user]); + } } diff --git a/contracts/tokenization/base/DebtTokenBase.sol b/contracts/tokenization/base/DebtTokenBase.sol index ec021951..21d4dcf6 100644 --- a/contracts/tokenization/base/DebtTokenBase.sol +++ b/contracts/tokenization/base/DebtTokenBase.sol @@ -67,7 +67,7 @@ abstract contract DebtTokenBase is ERC20, VersionedInitializable { * @dev Returns the principal debt balance of the user from * @return The debt balance of the user since the last burn/mint action **/ - function principalBalanceOf(address user) public view returns (uint256) { + function principalBalanceOf(address user) public virtual view returns (uint256) { return super.balanceOf(user); } diff --git a/contracts/tokenization/interfaces/IAToken.sol b/contracts/tokenization/interfaces/IAToken.sol index 65ad0cfa..ec6898fe 100644 --- a/contracts/tokenization/interfaces/IAToken.sol +++ b/contracts/tokenization/interfaces/IAToken.sol @@ -127,6 +127,14 @@ interface IAToken is IERC20 { */ function mint(address user, uint256 amount) external; + /** + * @dev mints aTokens to reserve, based on the reserveFactor value + * only lending pools can call this function + * @param amount the amount of tokens to mint + */ + function mintToReserve(uint256 amount) external; + + /** * @dev transfers tokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken * only lending pools can call this function diff --git a/contracts/tokenization/interfaces/IVariableDebtToken.sol b/contracts/tokenization/interfaces/IVariableDebtToken.sol index e979b4a5..6f58e2d2 100644 --- a/contracts/tokenization/interfaces/IVariableDebtToken.sol +++ b/contracts/tokenization/interfaces/IVariableDebtToken.sol @@ -46,9 +46,4 @@ interface IVariableDebtToken { **/ function burn(address user, uint256 amount) external; - /** - * @dev returns the last index of the user - * @return the index of the user - **/ - function getUserIndex(address user) external view returns (uint256); }