diff --git a/contracts/deployments/RateOracleSetupHelper.sol b/contracts/deployments/RateOracleSetupHelper.sol deleted file mode 100644 index 155919d1f..000000000 --- a/contracts/deployments/RateOracleSetupHelper.sol +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.7; - -import {RateOracle} from '../mocks/oracle/RateOracle.sol'; -import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol'; - -/** - * @title RateOracleSetupHelper - * @author Aave - * @notice Deployment helper to setup initial borrow rates of multiple assets in one transaction. - * @dev The RateOracle owner must transfer the ownership to RateOracleSetupHelper before calling to setOracleBorrowRates. - * @dev The RateOracleSetupHelper is an Ownable contract, so only the deployer or future owners can call this contract. - */ -contract RateOracleSetupHelper is Ownable { - /** - * @notice External function called by the owner account to set the initial borrow rates of the assets - * @param assets The addresses of the assets - * @param rates The interest rates of each asset - * @param oracle The address of the RateOracle contract - */ - function setOracleBorrowRates( - address[] calldata assets, - uint256[] calldata rates, - address oracle - ) external onlyOwner { - require(assets.length == rates.length, 'Arrays not same length'); - - for (uint256 i = 0; i < assets.length; i++) { - // RateOracle owner must be this contract - RateOracle(oracle).setMarketBorrowRate(assets[i], rates[i]); - } - } - - /** - * @notice External function called by the deployer account to give ownership of the RateOracle back to the corresponding owner address. - * @param oracle The address of the RateOracle contract - * @param admin The corresponding owner address - */ - function setOracleOwnership(address oracle, address admin) external onlyOwner { - require(admin != address(0), 'owner can not be zero'); - require(RateOracle(oracle).owner() == address(this), 'helper is not owner'); - RateOracle(oracle).transferOwnership(admin); - } -} diff --git a/contracts/interfaces/IPoolAddressesProvider.sol b/contracts/interfaces/IPoolAddressesProvider.sol index 36d983940..78e72abd5 100644 --- a/contracts/interfaces/IPoolAddressesProvider.sol +++ b/contracts/interfaces/IPoolAddressesProvider.sol @@ -11,7 +11,6 @@ interface IPoolAddressesProvider { event PoolUpdated(address indexed newAddress); event PoolConfiguratorUpdated(address indexed newAddress); event PriceOracleUpdated(address indexed newAddress); - event RateOracleUpdated(address indexed newAddress); event ACLManagerUpdated(address indexed newAddress); event ACLAdminUpdated(address indexed newAddress); event ProxyCreated(bytes32 id, address indexed newAddress); @@ -85,10 +84,6 @@ interface IPoolAddressesProvider { function setPriceOracle(address priceOracle) external; - function getRateOracle() external view returns (address); - - function setRateOracle(address rateOracle) external; - /** * @notice Returns the address of the ACL manager proxy * @return The ACLManager proxy address diff --git a/contracts/interfaces/IRateOracle.sol b/contracts/interfaces/IRateOracle.sol deleted file mode 100644 index 94950d0d5..000000000 --- a/contracts/interfaces/IRateOracle.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.7; - -/** - * @title IRateOracle - * @author Aave - * @notice Interface for the Aave borrow rate oracle. Provides the average market borrow rate to be used as a base for the stable borrow rate calculations - **/ - -interface IRateOracle { - /** - * @notice Returns the market borrow rate in ray - * @param asset The asset to retrieve borrow rate for - * @return The borrow rate for the given asset - **/ - function getMarketBorrowRate(address asset) external view returns (uint256); - - /** - * @notice Sets the market borrow rate. Rate value must be in ray - * @param asset The asset to set borrow rate for - * @param rate The rate to use - **/ - function setMarketBorrowRate(address asset, uint256 rate) external; -} diff --git a/contracts/misc/AaveProtocolDataProvider.sol b/contracts/misc/AaveProtocolDataProvider.sol index 1fd079138..8cfd68fed 100644 --- a/contracts/misc/AaveProtocolDataProvider.sol +++ b/contracts/misc/AaveProtocolDataProvider.sol @@ -303,4 +303,25 @@ contract AaveProtocolDataProvider { reserve.variableDebtTokenAddress ); } + + /** + * @notice Returns the address of the IR strategy + * @param asset The address of the underlying asset of the reserve + * @return irStrategyAddress The address of the IR strategy + */ + function getIRStrategyAddress(address asset) + external + view + returns ( + address irStrategyAddress + ) + { + DataTypes.ReserveData memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData( + asset + ); + + return ( + reserve.interestRateStrategyAddress + ); + } } diff --git a/contracts/mocks/oracle/RateOracle.sol b/contracts/mocks/oracle/RateOracle.sol deleted file mode 100644 index 6ba9fde05..000000000 --- a/contracts/mocks/oracle/RateOracle.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.7; - -import {IRateOracle} from '../../interfaces/IRateOracle.sol'; -import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol'; - -contract RateOracle is IRateOracle, Ownable { - mapping(address => uint256) borrowRates; - mapping(address => uint256) liquidityRates; - - function getMarketBorrowRate(address _asset) external view override returns (uint256) { - return borrowRates[_asset]; - } - - function setMarketBorrowRate(address _asset, uint256 _rate) external override onlyOwner { - borrowRates[_asset] = _rate; - } - - function getMarketLiquidityRate(address _asset) external view returns (uint256) { - return liquidityRates[_asset]; - } - - function setMarketLiquidityRate(address _asset, uint256 _rate) external onlyOwner { - liquidityRates[_asset] = _rate; - } -} diff --git a/contracts/protocol/configuration/PoolAddressesProvider.sol b/contracts/protocol/configuration/PoolAddressesProvider.sol index 7482985db..e69113da0 100644 --- a/contracts/protocol/configuration/PoolAddressesProvider.sol +++ b/contracts/protocol/configuration/PoolAddressesProvider.sol @@ -19,7 +19,6 @@ contract PoolAddressesProvider is Ownable, IPoolAddressesProvider { bytes32 private constant POOL = 'POOL'; bytes32 private constant POOL_CONFIGURATOR = 'POOL_CONFIGURATOR'; bytes32 private constant PRICE_ORACLE = 'PRICE_ORACLE'; - bytes32 private constant RATE_ORACLE = 'RATE_ORACLE'; bytes32 private constant ACL_MANAGER = 'ACL_MANAGER'; bytes32 private constant ACL_ADMIN = 'ACL_ADMIN'; @@ -89,15 +88,6 @@ contract PoolAddressesProvider is Ownable, IPoolAddressesProvider { emit PriceOracleUpdated(priceOracle); } - function getRateOracle() external view override returns (address) { - return getAddress(RATE_ORACLE); - } - - function setRateOracle(address rateOracle) external override onlyOwner { - _addresses[RATE_ORACLE] = rateOracle; - emit RateOracleUpdated(rateOracle); - } - /// @inheritdoc IPoolAddressesProvider function getACLManager() external view override returns (address) { return getAddress(ACL_MANAGER); diff --git a/contracts/protocol/libraries/logic/BorrowLogic.sol b/contracts/protocol/libraries/logic/BorrowLogic.sol index d0cbcfebb..f922050fd 100644 --- a/contracts/protocol/libraries/logic/BorrowLogic.sol +++ b/contracts/protocol/libraries/logic/BorrowLogic.sol @@ -15,6 +15,7 @@ import {PercentageMath} from '../math/PercentageMath.sol'; import {DataTypes} from '../types/DataTypes.sol'; import {ValidationLogic} from './ValidationLogic.sol'; import {ReserveLogic} from './ReserveLogic.sol'; +import 'hardhat/console.sol'; /** * @title BorrowLogic library @@ -164,6 +165,8 @@ library BorrowLogic { ? stableDebt : variableDebt; + console.log('Payback amount: ', paybackAmount); + if (params.amount < paybackAmount) { paybackAmount = params.amount; } diff --git a/contracts/protocol/libraries/types/DataTypes.sol b/contracts/protocol/libraries/types/DataTypes.sol index 8726f53b4..ec5a176aa 100644 --- a/contracts/protocol/libraries/types/DataTypes.sol +++ b/contracts/protocol/libraries/types/DataTypes.sol @@ -8,10 +8,10 @@ library DataTypes { ReserveConfigurationMap configuration; //the liquidity index. Expressed in ray uint128 liquidityIndex; - //variable borrow index. Expressed in ray - uint128 variableBorrowIndex; //the current supply rate. Expressed in ray uint128 currentLiquidityRate; + //variable borrow index. Expressed in ray + uint128 variableBorrowIndex; //the current variable borrow rate. Expressed in ray uint128 currentVariableBorrowRate; //the current stable borrow rate. Expressed in ray diff --git a/contracts/protocol/pool/DefaultReserveInterestRateStrategy.sol b/contracts/protocol/pool/DefaultReserveInterestRateStrategy.sol index 68ab21f60..353944577 100644 --- a/contracts/protocol/pool/DefaultReserveInterestRateStrategy.sol +++ b/contracts/protocol/pool/DefaultReserveInterestRateStrategy.sol @@ -6,9 +6,9 @@ import {WadRayMath} from '../libraries/math/WadRayMath.sol'; import {PercentageMath} from '../libraries/math/PercentageMath.sol'; import {IReserveInterestRateStrategy} from '../../interfaces/IReserveInterestRateStrategy.sol'; import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {IRateOracle} from '../../interfaces/IRateOracle.sol'; import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; import {DataTypes} from '../libraries/types/DataTypes.sol'; +import "hardhat/console.sol"; /** * @title DefaultReserveInterestRateStrategy contract @@ -54,6 +54,10 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { // Slope of the stable interest curve when utilization rate > OPTIMAL_UTILIZATION_RATE. Expressed in ray uint256 internal immutable _stableRateSlope2; + uint256 internal immutable _baseStableRateOffset; + + uint256 internal immutable _stableRateExcessOffset; + constructor( IPoolAddressesProvider provider, uint256 optimalUtilizationRate, @@ -61,7 +65,9 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { uint256 variableRateSlope1, uint256 variableRateSlope2, uint256 stableRateSlope1, - uint256 stableRateSlope2 + uint256 stableRateSlope2, + uint256 baseStableRateOffset, + uint256 stableRateExcessOffset ) { OPTIMAL_UTILIZATION_RATE = optimalUtilizationRate; EXCESS_UTILIZATION_RATE = WadRayMath.RAY - optimalUtilizationRate; @@ -71,6 +77,8 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { _variableRateSlope2 = variableRateSlope2; _stableRateSlope1 = stableRateSlope1; _stableRateSlope2 = stableRateSlope2; + _baseStableRateOffset = baseStableRateOffset; + _stableRateExcessOffset = stableRateExcessOffset; } function getVariableRateSlope1() external view returns (uint256) { @@ -89,6 +97,10 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { return _stableRateSlope2; } + function getBaseStableBorrowRate() public view returns(uint256) { + return _variableRateSlope1 + _baseStableRateOffset; + } + /// @inheritdoc IReserveInterestRateStrategy function getBaseVariableBorrowRate() external view override returns (uint256) { return _baseVariableBorrowRate; @@ -140,8 +152,7 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { ? 0 : vars.totalDebt.rayDiv(vars.availableLiquidity + params.unbacked + vars.totalDebt); - vars.currentStableBorrowRate = IRateOracle(addressesProvider.getRateOracle()) - .getMarketBorrowRate(params.reserve); + vars.currentStableBorrowRate = getBaseStableBorrowRate(); if (vars.borrowUtilizationRate > OPTIMAL_UTILIZATION_RATE) { uint256 excessUtilizationRateRatio = (vars.borrowUtilizationRate - OPTIMAL_UTILIZATION_RATE) diff --git a/helpers/contracts-deployments.ts b/helpers/contracts-deployments.ts index 6f9599b46..9186d26b1 100644 --- a/helpers/contracts-deployments.ts +++ b/helpers/contracts-deployments.ts @@ -14,7 +14,6 @@ import { PoolAddressesProviderRegistryFactory, PoolConfiguratorFactory, PoolFactory, - RateOracleFactory, MintableDelegationERC20Factory, MintableERC20Factory, MockAggregatorFactory, @@ -45,7 +44,6 @@ import { linkBytecode, insertContractAddressInDb, } from './contracts-helpers'; -import { RateOracleSetupHelperFactory } from '../types/RateOracleSetupHelperFactory'; import { MintableDelegationERC20 } from '../types/MintableDelegationERC20'; import { HardhatRuntimeEnvironment } from 'hardhat/types'; import { PoolLibraryAddresses } from '../types/PoolFactory'; @@ -197,9 +195,6 @@ export const deployPool = async () => { export const deployPriceOracle = async () => withSave(await new PriceOracleFactory(await getFirstSigner()).deploy(), eContractid.PriceOracle); -export const deployRateOracle = async () => - withSave(await new RateOracleFactory(await getFirstSigner()).deploy(), eContractid.RateOracle); - export const deployMockAggregator = async (price: tStringTokenSmallUnits) => withSave( await new MockAggregatorFactory(await getFirstSigner()).deploy(price), @@ -241,7 +236,7 @@ export const deployMintableDelegationERC20 = async ( ); export const deployDefaultReserveInterestRateStrategy = async ( - args: [tEthereumAddress, string, string, string, string, string, string] + args: [tEthereumAddress, string, string, string, string, string, string, string, string] ) => withSave( await new DefaultReserveInterestRateStrategyFactory(await getFirstSigner()).deploy(...args), @@ -353,12 +348,6 @@ export const deployAllMockTokens = async () => { return tokens; }; -export const deployRateOracleSetupHelper = async () => - withSave( - await new RateOracleSetupHelperFactory(await getFirstSigner()).deploy(), - eContractid.RateOracleSetupHelper - ); - export const deployReservesSetupHelper = async () => withSave( await new ReservesSetupHelperFactory(await getFirstSigner()).deploy(), diff --git a/helpers/contracts-getters.ts b/helpers/contracts-getters.ts index 2948fa985..03c564516 100644 --- a/helpers/contracts-getters.ts +++ b/helpers/contracts-getters.ts @@ -6,13 +6,11 @@ import { PoolAddressesProviderRegistryFactory, PoolConfiguratorFactory, PoolFactory, - RateOracleFactory, MintableERC20Factory, MockFlashLoanReceiverFactory, MockStableDebtTokenFactory, MockVariableDebtTokenFactory, PriceOracleFactory, - RateOracleSetupHelperFactory, StableDebtTokenFactory, VariableDebtTokenFactory, WETH9MockedFactory, @@ -26,6 +24,8 @@ import { BridgeLogicFactory, ACLManagerFactory, EModeLogicFactory, + DefaultReserveInterestRateStrategy, + DefaultReserveInterestRateStrategyFactory, } from '../types'; import { IERC20DetailedFactory } from '../types/IERC20DetailedFactory'; import { getEthersSigners, MockTokenMap } from './contracts-helpers'; @@ -130,6 +130,15 @@ export const getVariableDebtToken = async (address?: tEthereumAddress) => await getFirstSigner() ); + export const getIRStrategy = async (address?: tEthereumAddress) => + await DefaultReserveInterestRateStrategyFactory.connect( + address || + ( + await getDb().get(`${eContractid.DefaultReserveInterestRateStrategy}.${DRE.network.name}`).value() + ).address, + await getFirstSigner() + ); + export const getMintableERC20 = async (address: tEthereumAddress) => await MintableERC20Factory.connect( address || @@ -172,12 +181,6 @@ export const getMockFlashLoanReceiver = async (address?: tEthereumAddress) => await getFirstSigner() ); -export const getRateOracle = async (address?: tEthereumAddress) => - await RateOracleFactory.connect( - address || (await getDb().get(`${eContractid.RateOracle}.${DRE.network.name}`).value()).address, - await getFirstSigner() - ); - export const getAllMockedTokens = async () => { const db = getDb(); const tokens: MockTokenMap = await Object.keys(TokenContractId).reduce>( @@ -230,15 +233,6 @@ export const getPoolAddressesProviderRegistry = async (address?: tEthereumAddres await getFirstSigner() ); -export const getRateOracleSetupHelper = async (address?: tEthereumAddress) => - await RateOracleSetupHelperFactory.connect( - address || - ( - await getDb().get(`${eContractid.RateOracleSetupHelper}.${DRE.network.name}`).value() - ).address, - await getFirstSigner() - ); - export const getReservesSetupHelper = async (address?: tEthereumAddress) => await ReservesSetupHelperFactory.connect( address || diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts index f4db15b13..e819679df 100644 --- a/helpers/init-helpers.ts +++ b/helpers/init-helpers.ts @@ -6,7 +6,6 @@ import { getReservesSetupHelper, getPoolAddressesProvider, getPoolConfiguratorProxy, - getRateOracleSetupHelper, } from './contracts-getters'; import { rawInsertContractAddressInDb } from './contracts-helpers'; import { BigNumber, BigNumberish } from 'ethers'; @@ -67,6 +66,8 @@ export const initReservesByHelper = async ( string, string, string, + string, + string, string ]; let rateStrategies: Record = {}; @@ -128,6 +129,8 @@ export const initReservesByHelper = async ( variableRateSlope2, stableRateSlope1, stableRateSlope2, + baseStableRateOffset, + stableRateExcessOffset } = strategy; if (!strategyAddresses[strategy.name]) { // Strategy does not exist, create a new one @@ -139,6 +142,8 @@ export const initReservesByHelper = async ( variableRateSlope2, stableRateSlope1, stableRateSlope2, + baseStableRateOffset, + stableRateExcessOffset ]; strategyAddresses[strategy.name] = ( await deployDefaultReserveInterestRateStrategy(rateStrategies[strategy.name]) diff --git a/helpers/oracles-helpers.ts b/helpers/oracles-helpers.ts index deb842ced..f2c51a936 100644 --- a/helpers/oracles-helpers.ts +++ b/helpers/oracles-helpers.ts @@ -5,62 +5,10 @@ import { iAssetBase, iAssetAggregatorBase, } from './types'; -import { RateOracle } from '../types/RateOracle'; import { PriceOracle } from '../types/PriceOracle'; import { MockAggregator } from '../types/MockAggregator'; import { deployMockAggregator } from './contracts-deployments'; import { chunk, waitForTx } from './misc-utils'; -import { getRateOracleSetupHelper } from './contracts-getters'; - -export const setInitialMarketRatesInRatesOracleByHelper = async ( - marketRates: iMultiPoolsAssets, - assetsAddresses: { [x: string]: tEthereumAddress }, - rateOracleInstance: RateOracle, - admin: tEthereumAddress -) => { - const rateOracleSetupHelper = await getRateOracleSetupHelper(); - const assetAddresses: string[] = []; - const borrowRates: string[] = []; - const symbols: string[] = []; - for (const [assetSymbol, { borrowRate }] of Object.entries(marketRates) as [ - string, - IMarketRates - ][]) { - const assetAddressIndex = Object.keys(assetsAddresses).findIndex( - (value) => value === assetSymbol - ); - const [, assetAddress] = (Object.entries(assetsAddresses) as [string, string][])[ - assetAddressIndex - ]; - assetAddresses.push(assetAddress); - borrowRates.push(borrowRate); - symbols.push(assetSymbol); - } - // Set borrow rates per chunks - const ratesChunks = 20; - const chunkedTokens = chunk(assetAddresses, ratesChunks); - const chunkedRates = chunk(borrowRates, ratesChunks); - const chunkedSymbols = chunk(symbols, ratesChunks); - - // Set helper as owner - await waitForTx(await rateOracleInstance.transferOwnership(rateOracleSetupHelper.address)); - - console.log(`- Oracle borrow initalization in ${chunkedTokens.length} txs`); - for (let chunkIndex = 0; chunkIndex < chunkedTokens.length; chunkIndex++) { - const tx3 = await waitForTx( - await rateOracleSetupHelper.setOracleBorrowRates( - chunkedTokens[chunkIndex], - chunkedRates[chunkIndex], - rateOracleInstance.address - ) - ); - console.log(` - Setted Oracle Borrow Rates for: ${chunkedSymbols[chunkIndex].join(', ')}`); - } - // Set back ownership - await waitForTx( - await rateOracleSetupHelper.setOracleOwnership(rateOracleInstance.address, admin) - ); -}; export const setInitialAssetPricesInOracle = async ( prices: iAssetBase, diff --git a/helpers/types.ts b/helpers/types.ts index 8fe3e5238..53f30183b 100644 --- a/helpers/types.ts +++ b/helpers/types.ts @@ -37,7 +37,6 @@ export enum eContractid { PriceOracle = 'PriceOracle', Proxy = 'Proxy', MockAggregator = 'MockAggregator', - RateOracle = 'RateOracle', AaveOracle = 'AaveOracle', DefaultReserveInterestRateStrategy = 'DefaultReserveInterestRateStrategy', InitializableImmutableAdminUpgradeabilityProxy = 'InitializableImmutableAdminUpgradeabilityProxy', @@ -53,7 +52,6 @@ export enum eContractid { VariableDebtToken = 'VariableDebtToken', FeeProvider = 'FeeProvider', TokenDistributor = 'TokenDistributor', - RateOracleSetupHelper = 'RateOracleSetupHelper', ReservesSetupHelper = 'ReservesSetupHelper', WETH = 'WETH', WETHMocked = 'WETHMocked', @@ -326,6 +324,8 @@ export interface IInterestRateStrategyParams { variableRateSlope2: string; stableRateSlope1: string; stableRateSlope2: string; + baseStableRateOffset: string; + stableRateExcessOffset: string; } export interface IReserveBorrowParams { @@ -382,10 +382,6 @@ export interface IMocksConfig { AllAssetsInitialPrices: iAssetBase; } -export interface IRateOracleRatesCommon { - [token: string]: IRate; -} - export interface IRate { borrowRate: string; } @@ -403,8 +399,6 @@ export interface ICommonConfiguration { ProviderRegistryOwner: tEthereumAddress | undefined; PoolConfigurator: tEthereumAddress | undefined; Pool: tEthereumAddress | undefined; - RateOracleRatesCommon: iMultiPoolsAssets; - RateOracle: tEthereumAddress | undefined; TokenDistributor: tEthereumAddress | undefined; AaveOracle: tEthereumAddress | undefined; FallbackOracle: tEthereumAddress | undefined; diff --git a/market-config/index.ts b/market-config/index.ts index 7153f1308..ee622c05c 100644 --- a/market-config/index.ts +++ b/market-config/index.ts @@ -50,7 +50,6 @@ export const AaveConfig: IAaveConfiguration = { EmergencyAdminIndex: 1, ProviderRegistry: undefined, ProviderRegistryOwner: undefined, - RateOracle: undefined, PoolConfigurator: undefined, Pool: undefined, TokenDistributor: undefined, @@ -99,68 +98,6 @@ export const AaveConfig: IAaveConfiguration = { [eEthereumNetwork.coverage]: undefined, [eEthereumNetwork.tenderlyMain]: undefined, }, - RateOracleRatesCommon: { - AAVE: { - borrowRate: utils.parseUnits('0.03', 27).toString(), - }, - BAT: { - borrowRate: utils.parseUnits('0.03', 27).toString(), - }, - BUSD: { - borrowRate: utils.parseUnits('0.05', 27).toString(), - }, - DAI: { - borrowRate: utils.parseUnits('0.039', 27).toString(), - }, - ENJ: { - borrowRate: utils.parseUnits('0.03', 27).toString(), - }, - KNC: { - borrowRate: utils.parseUnits('0.03', 27).toString(), - }, - LINK: { - borrowRate: utils.parseUnits('0.03', 27).toString(), - }, - MANA: { - borrowRate: utils.parseUnits('0.03', 27).toString(), - }, - MKR: { - borrowRate: utils.parseUnits('0.03', 27).toString(), - }, - REN: { - borrowRate: utils.parseUnits('0.03', 27).toString(), - }, - SNX: { - borrowRate: utils.parseUnits('0.03', 27).toString(), - }, - SUSD: { - borrowRate: utils.parseUnits('0.035', 27).toString(), - }, - TUSD: { - borrowRate: utils.parseUnits('0.035', 27).toString(), - }, - UNI: { - borrowRate: utils.parseUnits('0.03', 27).toString(), - }, - USDC: { - borrowRate: utils.parseUnits('0.039', 27).toString(), - }, - USDT: { - borrowRate: utils.parseUnits('0.035', 27).toString(), - }, - WBTC: { - borrowRate: utils.parseUnits('0.03', 27).toString(), - }, - WETH: { - borrowRate: utils.parseUnits('0.03', 27).toString(), - }, - YFI: { - borrowRate: utils.parseUnits('0.03', 27).toString(), - }, - ZRX: { - borrowRate: utils.parseUnits('0.03', 27).toString(), - }, - }, }; export default AaveConfig; diff --git a/market-config/rateStrategies.ts b/market-config/rateStrategies.ts index 104379823..68defc2d4 100644 --- a/market-config/rateStrategies.ts +++ b/market-config/rateStrategies.ts @@ -10,6 +10,8 @@ export const rateStrategyStableOne: IInterestRateStrategyParams = { variableRateSlope2: utils.parseUnits('1', 27).toString(), stableRateSlope1: '0', stableRateSlope2: '0', + baseStableRateOffset: utils.parseUnits('0.02', 27).toString(), + stableRateExcessOffset: utils.parseUnits('0.05', 27).toString() }; // DAI TUSD @@ -21,6 +23,8 @@ export const rateStrategyStableTwo: IInterestRateStrategyParams = { variableRateSlope2: utils.parseUnits('0.75', 27).toString(), stableRateSlope1: utils.parseUnits('0.02', 27).toString(), stableRateSlope2: utils.parseUnits('0.75', 27).toString(), + baseStableRateOffset: utils.parseUnits('0.02', 27).toString(), + stableRateExcessOffset: utils.parseUnits('0.05', 27).toString() }; // USDC USDT @@ -32,6 +36,8 @@ export const rateStrategyStableThree: IInterestRateStrategyParams = { variableRateSlope2: utils.parseUnits('0.6', 27).toString(), stableRateSlope1: utils.parseUnits('0.02', 27).toString(), stableRateSlope2: utils.parseUnits('0.6', 27).toString(), + baseStableRateOffset: utils.parseUnits('0.02', 27).toString(), + stableRateExcessOffset: utils.parseUnits('0.05', 27).toString() }; // WETH @@ -43,6 +49,8 @@ export const rateStrategyWETH: IInterestRateStrategyParams = { variableRateSlope2: utils.parseUnits('1', 27).toString(), stableRateSlope1: utils.parseUnits('0.1', 27).toString(), stableRateSlope2: utils.parseUnits('1', 27).toString(), + baseStableRateOffset: utils.parseUnits('0.02', 27).toString(), + stableRateExcessOffset: utils.parseUnits('0.05', 27).toString() }; // AAVE @@ -54,6 +62,8 @@ export const rateStrategyAAVE: IInterestRateStrategyParams = { variableRateSlope2: '0', stableRateSlope1: '0', stableRateSlope2: '0', + baseStableRateOffset: utils.parseUnits('0.02', 27).toString(), + stableRateExcessOffset: utils.parseUnits('0.05', 27).toString() }; // BAT ENJ LINK MANA MKR REN YFI ZRX @@ -65,6 +75,8 @@ export const rateStrategyVolatileOne: IInterestRateStrategyParams = { variableRateSlope2: utils.parseUnits('3', 27).toString(), stableRateSlope1: utils.parseUnits('0.1', 27).toString(), stableRateSlope2: utils.parseUnits('0.3', 27).toString(), + baseStableRateOffset: utils.parseUnits('0.02', 27).toString(), + stableRateExcessOffset: utils.parseUnits('0.05', 27).toString() }; // KNC WBTC @@ -76,6 +88,8 @@ export const rateStrategyVolatileTwo: IInterestRateStrategyParams = { variableRateSlope2: utils.parseUnits('3', 27).toString(), stableRateSlope1: utils.parseUnits('0.1', 27).toString(), stableRateSlope2: utils.parseUnits('0.3', 27).toString(), + baseStableRateOffset: utils.parseUnits('0.02', 27).toString(), + stableRateExcessOffset: utils.parseUnits('0.05', 27).toString() }; // SNX @@ -87,6 +101,8 @@ export const rateStrategyVolatileThree: IInterestRateStrategyParams = { variableRateSlope2: utils.parseUnits('3', 27).toString(), stableRateSlope1: utils.parseUnits('0.1', 27).toString(), stableRateSlope2: utils.parseUnits('3', 27).toString(), + baseStableRateOffset: utils.parseUnits('0.02', 27).toString(), + stableRateExcessOffset: utils.parseUnits('0.05', 27).toString() }; export const rateStrategyVolatileFour: IInterestRateStrategyParams = { @@ -97,4 +113,6 @@ export const rateStrategyVolatileFour: IInterestRateStrategyParams = { variableRateSlope2: utils.parseUnits('3', 27).toString(), stableRateSlope1: '0', stableRateSlope2: '0', + baseStableRateOffset: utils.parseUnits('0.02', 27).toString(), + stableRateExcessOffset: utils.parseUnits('0.05', 27).toString() }; diff --git a/test-suites/__setup.spec.ts b/test-suites/__setup.spec.ts index b35842f86..569c7c5d3 100644 --- a/test-suites/__setup.spec.ts +++ b/test-suites/__setup.spec.ts @@ -14,8 +14,6 @@ import { deployAaveOracle, deployMockFlashLoanReceiver, deployAaveProtocolDataProvider, - deployRateOracle, - deployRateOracleSetupHelper, deployReservesSetupHelper, deployAllMockTokens, deployACLManager, @@ -25,7 +23,6 @@ import { eContractid, tEthereumAddress } from '../helpers/types'; import { setInitialAssetPricesInOracle, deployAllMockAggregators, - setInitialMarketRatesInRatesOracleByHelper, } from '../helpers/oracles-helpers'; import { waitForTx } from '../helpers/misc-utils'; import { initReservesByHelper, configureReservesByHelper } from '../helpers/init-helpers'; @@ -42,7 +39,6 @@ const MOCK_USD_PRICE_IN_WEI = AaveConfig.ProtocolGlobalParams.MockUsdPriceInWei; const ALL_ASSETS_INITIAL_PRICES = AaveConfig.Mocks.AllAssetsInitialPrices; const USD_ADDRESS = AaveConfig.ProtocolGlobalParams.UsdAddress; const MOCK_CHAINLINK_AGGREGATORS_PRICES = AaveConfig.Mocks.AllAssetsInitialPrices; -const RATE_ORACLE_RATES_COMMON = AaveConfig.RateOracleRatesCommon; const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => { console.time('setup'); @@ -90,7 +86,6 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => { await waitForTx(await aclManager.addRiskAdmin(addressList[3])); // Deploy deployment helpers - await deployRateOracleSetupHelper(); await deployReservesSetupHelper(); const fallbackOracle = await deployPriceOracle(); @@ -175,19 +170,11 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => { ]); await waitForTx(await addressesProvider.setPriceOracle(fallbackOracle.address)); - const rateOracle = await deployRateOracle(); - await waitForTx(await addressesProvider.setRateOracle(rateOracle.address)); const { USD, ...tokensAddressesWithoutUsd } = allTokenAddresses; const allReservesAddresses = { ...tokensAddressesWithoutUsd, }; - await setInitialMarketRatesInRatesOracleByHelper( - RATE_ORACLE_RATES_COMMON, - allReservesAddresses, - rateOracle, - aaveAdmin - ); const reservesParams = AaveConfig.ReservesConfig; diff --git a/test-suites/deployment-token-helper.spec.ts b/test-suites/deployment-token-helper.spec.ts deleted file mode 100644 index 62790e4dd..000000000 --- a/test-suites/deployment-token-helper.spec.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { expect } from 'chai'; -import { utils } from 'ethers'; -import { ONE_ADDRESS, ZERO_ADDRESS } from '../helpers/constants'; -import { evmRevert, evmSnapshot } from '../helpers/misc-utils'; -import { deployMintableERC20 } from '../helpers/contracts-deployments'; -import { MintableERC20, RateOracle, RateOracleFactory, RateOracleSetupHelper } from '../types'; -import { getFirstSigner, getRateOracleSetupHelper } from '../helpers/contracts-getters'; -import { ProtocolErrors } from '../helpers/types'; -import { makeSuite, TestEnv } from './helpers/make-suite'; - -makeSuite('StableAndVariableTokenHelper', (testEnv: TestEnv) => { - let snap: string; - - beforeEach(async () => { - snap = await evmSnapshot(); - }); - afterEach(async () => { - await evmRevert(snap); - }); - - const BORROW_RATE = utils.parseUnits('0.03', 27).toString(); - - let tokenHelper: RateOracleSetupHelper; - let rateOracle: RateOracle; - let mockToken: MintableERC20; - - before(async () => { - tokenHelper = await getRateOracleSetupHelper(); - rateOracle = await (await new RateOracleFactory(await getFirstSigner()).deploy()).deployed(); - mockToken = await deployMintableERC20(['MOCK', 'MOCK', '18']); - - // Transfer ownership to tokenHelper - await rateOracle.transferOwnership(tokenHelper.address); - }); - - it('Owner set new borrow rates for an asset', async () => { - const { poolAdmin } = testEnv; - - expect(await rateOracle.getMarketBorrowRate(mockToken.address)).to.be.eq(0); - expect( - await tokenHelper - .connect(poolAdmin.signer) - .setOracleBorrowRates([mockToken.address], [BORROW_RATE], rateOracle.address) - ); - expect(await rateOracle.getMarketBorrowRate(mockToken.address)).to.be.eq(BORROW_RATE); - }); - - it('A non-owner user tries to set a new borrow rate (revert expected)', async () => { - const { users } = testEnv; - - const { INVALID_OWNER_REVERT_MSG } = ProtocolErrors; - - expect(await rateOracle.getMarketBorrowRate(mockToken.address)).to.be.eq(0); - await expect( - tokenHelper - .connect(users[0].signer) - .setOracleBorrowRates([mockToken.address], [BORROW_RATE], rateOracle.address) - ).to.be.revertedWith(INVALID_OWNER_REVERT_MSG); - expect(await rateOracle.getMarketBorrowRate(mockToken.address)).to.be.eq(0); - }); - - it('Owner tries to set new borrow rates with wrong input (revert expected)', async () => { - const { poolAdmin } = testEnv; - - expect(await rateOracle.getMarketBorrowRate(mockToken.address)).to.be.eq(0); - expect( - tokenHelper - .connect(poolAdmin.signer) - .setOracleBorrowRates([mockToken.address], [], rateOracle.address) - ).to.be.revertedWith('Arrays not same length'); - expect(await rateOracle.getMarketBorrowRate(mockToken.address)).to.be.eq(0); - }); - - it('Owner transfers ownership to another user', async () => { - const { poolAdmin, users } = testEnv; - - expect(await rateOracle.owner()).to.be.eq(tokenHelper.address); - expect( - await tokenHelper - .connect(poolAdmin.signer) - .setOracleOwnership(rateOracle.address, users[1].address) - ) - .to.emit(rateOracle, 'OwnershipTransferred') - .withArgs(tokenHelper.address, users[1].address); - expect(await rateOracle.owner()).to.be.eq(users[1].address); - }); - - it('Owner tries to transfer ownership to ZERO address (revert expected)', async () => { - const { poolAdmin } = testEnv; - - expect(await rateOracle.owner()).to.be.eq(tokenHelper.address); - expect( - tokenHelper.connect(poolAdmin.signer).setOracleOwnership(rateOracle.address, ZERO_ADDRESS) - ).to.be.revertedWith('owner can not be zero'); - expect(await rateOracle.owner()).to.be.eq(tokenHelper.address); - }); - - it('Owner tries to transfer ownership but helper is not the owner of RateOracle (revert expected)', async () => { - const { poolAdmin, users } = testEnv; - - // Transfer ownership of RateOracle to another address - expect( - await tokenHelper - .connect(poolAdmin.signer) - .setOracleOwnership(rateOracle.address, ONE_ADDRESS) - ) - .to.emit(rateOracle, 'OwnershipTransferred') - .withArgs(tokenHelper.address, ONE_ADDRESS); - - expect(await rateOracle.owner()).to.be.not.eq(tokenHelper.address); - expect( - tokenHelper.connect(poolAdmin.signer).setOracleOwnership(rateOracle.address, users[1].address) - ).to.be.revertedWith('helper is not owner'); - }); -}); diff --git a/test-suites/helpers/actions.ts b/test-suites/helpers/actions.ts index ebffec718..c2f0b8d51 100644 --- a/test-suites/helpers/actions.ts +++ b/test-suites/helpers/actions.ts @@ -443,6 +443,9 @@ export const repay = async ( testEnv ); + console.log("Repaying user ", user.address); + console.log("Repay amount ", amount); + let amountToRepay = '0'; if (amount !== '-1') { diff --git a/test-suites/helpers/scenario-engine.ts b/test-suites/helpers/scenario-engine.ts index 2c14acef4..ca8dac0c2 100644 --- a/test-suites/helpers/scenario-engine.ts +++ b/test-suites/helpers/scenario-engine.ts @@ -59,6 +59,8 @@ const executeAction = async (action: Action, users: SignerWithAddress[], testEnv throw `An expected resut for action ${name} is required`; } + console.log(`Executing action ${name}, user ${userIndex}`); + let rateMode: string = RateMode.None; if (borrowRateMode) { @@ -202,7 +204,7 @@ const executeAction = async (action: Action, users: SignerWithAddress[], testEnv case 'repay': { - const { amount, timeTravel, borrowRateMode, sendValue } = action.args; + const { amount, timeTravel, sendValue } = action.args; let { onBehalfOf: onBehalfOfIndex } = action.args; if (!amount || amount === '') { diff --git a/test-suites/helpers/scenarios/borrow-repay-stable.json b/test-suites/helpers/scenarios/borrow-repay-stable.json index 51a7a5ead..dfeb81fbd 100644 --- a/test-suites/helpers/scenarios/borrow-repay-stable.json +++ b/test-suites/helpers/scenarios/borrow-repay-stable.json @@ -399,10 +399,10 @@ }, { "name": "mint", - "description": "Mint 15 DAI to cover the interest", + "description": "Mint 100 DAI to cover the interest", "args": { "reserve": "DAI", - "amount": "15", + "amount": "100", "user": "1" }, "expected": "success" @@ -428,10 +428,10 @@ }, { "name": "mint", - "description": "Mint 20 DAI to cover the interest", + "description": "Mint 100 DAI to cover the interest", "args": { "reserve": "DAI", - "amount": "20", + "amount": "100", "user": "2" }, "expected": "success" @@ -457,10 +457,10 @@ }, { "name": "mint", - "description": "Mint 30 DAI to cover the interest", + "description": "Mint 100 DAI to cover the interest", "args": { "reserve": "DAI", - "amount": "30", + "amount": "100", "user": "3" }, "expected": "success" @@ -486,10 +486,10 @@ }, { "name": "mint", - "description": "Mint 30 DAI to cover the interest", + "description": "Mint 100 DAI to cover the interest", "args": { "reserve": "DAI", - "amount": "30", + "amount": "100", "user": "4" }, "expected": "success" diff --git a/test-suites/helpers/utils/helpers.ts b/test-suites/helpers/utils/helpers.ts index 1ad12f9de..8ac27a7e9 100644 --- a/test-suites/helpers/utils/helpers.ts +++ b/test-suites/helpers/utils/helpers.ts @@ -1,12 +1,12 @@ import { Pool } from '../../../types/Pool'; import { ReserveData, UserReserveData } from './interfaces'; import { - getRateOracle, getIErc20Detailed, getMintableERC20, getAToken, getStableDebtToken, getVariableDebtToken, + getIRStrategy, } from '../../../helpers/contracts-getters'; import { tEthereumAddress } from '../../../helpers/types'; import { getDb, DRE } from '../../../helpers/misc-utils'; @@ -18,23 +18,25 @@ export const getReserveData = async ( helper: AaveProtocolDataProvider, reserve: tEthereumAddress ): Promise => { - const [reserveData, tokenAddresses, reserveConfiguration, rateOracle, token] = await Promise.all([ + const [reserveData, tokenAddresses, irStrategyAddress, reserveConfiguration, token] = await Promise.all([ helper.getReserveData(reserve), helper.getReserveTokensAddresses(reserve), + helper.getIRStrategyAddress(reserve), helper.getReserveConfigurationData(reserve), - getRateOracle(), getIErc20Detailed(reserve), ]); const stableDebtToken = await getStableDebtToken(tokenAddresses.stableDebtTokenAddress); const variableDebtToken = await getVariableDebtToken(tokenAddresses.variableDebtTokenAddress); + const irStrategy = await getIRStrategy(irStrategyAddress); + + const baseStableRate = await irStrategy.getBaseStableBorrowRate(); const { 0: principalStableDebt } = await stableDebtToken.getSupplyData(); const totalStableDebtLastUpdated = await stableDebtToken.getTotalSupplyLastUpdated(); const scaledVariableDebt = await variableDebtToken.scaledTotalSupply(); - const rate = (await rateOracle.getMarketBorrowRate(reserve)).toString(); const symbol = await token.symbol(); const decimals = BigNumber.from(await token.decimals()); @@ -86,7 +88,7 @@ export const getReserveData = async ( aTokenAddress: tokenAddresses.aTokenAddress, symbol, decimals, - marketStableRate: BigNumber.from(rate), + marketStableRate: BigNumber.from(baseStableRate), }; }; diff --git a/test-suites/no-incentives-controller.spec.ts b/test-suites/no-incentives-controller.spec.ts index 2d8436b74..09e082711 100644 --- a/test-suites/no-incentives-controller.spec.ts +++ b/test-suites/no-incentives-controller.spec.ts @@ -14,6 +14,7 @@ import { getFirstSigner } from '../helpers/contracts-getters'; import { deployMintableERC20 } from '../helpers/contracts-deployments'; import { makeSuite } from './helpers/make-suite'; import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; +import { setBlocktime, timeLatest } from '../helpers/misc-utils'; makeSuite('Reserve Without Incentives Controller', (testEnv) => { let mockToken: MintableERC20; @@ -233,27 +234,35 @@ makeSuite('Reserve Without Incentives Controller', (testEnv) => { users: [, , user], } = testEnv; - expect(await aMockToken.balanceOf(user.address)).to.be.eq(0); - expect(await mockToken.balanceOf(user.address)).to.be.eq( + const mintAmount = await convertToCurrencyDecimals(mockToken.address, '100'); + await mockToken.connect(user.signer).mint(mintAmount); + + const expectedMockTokenBalance = mintAmount.add( await convertToCurrencyDecimals(mockToken.address, '100') ); + + + expect(await aMockToken.balanceOf(user.address)).to.be.eq(0); + expect(await mockToken.balanceOf(user.address)).to.be.eq(expectedMockTokenBalance); expect(await mockVariableDebt.balanceOf(user.address)).to.be.eq(0); - expect(await mockStableDebt.balanceOf(user.address)).to.be.eq( - await convertToCurrencyDecimals(mockStableDebt.address, '100') - ); + await mockToken.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); + + const time = await timeLatest(); + + await setBlocktime(time.add(1).toNumber()); + + const stableDebtBefore = await mockStableDebt.balanceOf(user.address, { blockTag: 'pending' }); + await pool .connect(user.signer) - .repay( - mockToken.address, - await convertToCurrencyDecimals(mockToken.address, '100'), - RateMode.Stable, - user.address - ); + .repay(mockToken.address, stableDebtBefore, RateMode.Stable, user.address); expect(await aMockToken.balanceOf(user.address)).to.be.eq(0); - expect(await mockToken.balanceOf(user.address)).to.be.eq(0); + expect(await mockToken.balanceOf(user.address)).to.be.eq( + expectedMockTokenBalance.sub(stableDebtBefore) + ); expect(await mockVariableDebt.balanceOf(user.address)).to.be.eq(0); expect(await mockStableDebt.balanceOf(user.address)).to.be.eq(0); }); @@ -264,23 +273,18 @@ makeSuite('Reserve Without Incentives Controller', (testEnv) => { users: [, user], } = testEnv; - expect(await aMockToken.balanceOf(user.address)).to.be.eq( - await convertToCurrencyDecimals(aMockToken.address, '1000') - ); expect(await mockToken.balanceOf(user.address)).to.be.eq(0); + const aMockTokenBalanceBefore = await aMockToken.balanceOf(user.address, { + blockTag: 'pending', + }); + await aMockToken.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); await pool .connect(user.signer) - .withdraw( - mockToken.address, - await convertToCurrencyDecimals(mockToken.address, '1000'), - user.address - ); + .withdraw(mockToken.address, aMockTokenBalanceBefore, user.address); expect(await aMockToken.balanceOf(user.address)).to.be.eq(0); - expect(await mockToken.balanceOf(user.address)).to.be.eq( - await convertToCurrencyDecimals(mockToken.address, '1000') - ); + expect(await mockToken.balanceOf(user.address)).to.be.eq(aMockTokenBalanceBefore); }); }); diff --git a/test-suites/pool-addresses-provider.spec.ts b/test-suites/pool-addresses-provider.spec.ts index 99740cd1a..5cf98210b 100644 --- a/test-suites/pool-addresses-provider.spec.ts +++ b/test-suites/pool-addresses-provider.spec.ts @@ -21,8 +21,7 @@ makeSuite('PoolAddressesProvider', (testEnv: TestEnv) => { addressesProvider.setMarketId, addressesProvider.setPoolImpl, addressesProvider.setPoolConfiguratorImpl, - addressesProvider.setPriceOracle, - addressesProvider.setRateOracle, + addressesProvider.setPriceOracle ]) { await expect(contractFunction(mockAddress)).to.be.revertedWith(INVALID_OWNER_REVERT_MSG); } diff --git a/test-suites/rate-strategy.spec.ts b/test-suites/rate-strategy.spec.ts index cc1bd39b0..9b5ddbe06 100644 --- a/test-suites/rate-strategy.spec.ts +++ b/test-suites/rate-strategy.spec.ts @@ -27,6 +27,9 @@ makeSuite('InterestRateStrategy', (testEnv: TestEnv) => { let strategyInstance: DefaultReserveInterestRateStrategy; let dai: MintableERC20; let aDai: AToken; + const baseStableRate = BigNumber.from(rateStrategyStableTwo.variableRateSlope1).add( + rateStrategyStableTwo.baseStableRateOffset + ); before(async () => { dai = testEnv.dai; @@ -42,6 +45,8 @@ makeSuite('InterestRateStrategy', (testEnv: TestEnv) => { rateStrategyStableTwo.variableRateSlope2, rateStrategyStableTwo.stableRateSlope1, rateStrategyStableTwo.stableRateSlope2, + rateStrategyStableTwo.baseStableRateOffset, + rateStrategyStableTwo.stableRateExcessOffset ]); }); @@ -65,10 +70,7 @@ makeSuite('InterestRateStrategy', (testEnv: TestEnv) => { } = await strategyInstance.calculateInterestRates(params); expect(currentLiquidityRate).to.be.equal(0, 'Invalid liquidity rate'); - expect(currentStableBorrowRate).to.be.equal( - utils.parseUnits('0.039', 27), - 'Invalid stable rate' - ); + expect(currentStableBorrowRate).to.be.equal(baseStableRate, 'Invalid stable rate'); expect(currentVariableBorrowRate).to.be.equal( rateStrategyStableTwo.baseVariableBorrowRate, 'Invalid variable rate' @@ -108,7 +110,7 @@ makeSuite('InterestRateStrategy', (testEnv: TestEnv) => { expect(currentVariableBorrowRate).to.be.equal(expectedVariableRate, 'Invalid variable rate'); expect(currentStableBorrowRate).to.be.equal( - utils.parseUnits('0.039', 27).add(rateStrategyStableTwo.stableRateSlope1), + baseStableRate.add(rateStrategyStableTwo.stableRateSlope1), 'Invalid stable rate' ); @@ -120,9 +122,7 @@ makeSuite('InterestRateStrategy', (testEnv: TestEnv) => { }); it('Checks rates at 100% utilization rate', async () => { - - let params : CalculateInterestRatesParams = - { + let params: CalculateInterestRatesParams = { unbacked: 0, liquidityAdded: '0', liquidityTaken: 0, @@ -131,9 +131,9 @@ makeSuite('InterestRateStrategy', (testEnv: TestEnv) => { averageStableBorrowRate: 0, reserveFactor: strategyDAI.reserveFactor, reserve: dai.address, - aToken: aDai.address, - } - + aToken: aDai.address, + }; + const { 0: currentLiquidityRate, 1: currentStableBorrowRate, @@ -154,8 +154,7 @@ makeSuite('InterestRateStrategy', (testEnv: TestEnv) => { expect(currentVariableBorrowRate).to.be.equal(expectedVariableRate, 'Invalid variable rate'); expect(currentStableBorrowRate).to.be.equal( - utils - .parseUnits('0.039', 27) + baseStableRate .add(rateStrategyStableTwo.stableRateSlope1) .add(rateStrategyStableTwo.stableRateSlope2), 'Invalid stable rate' @@ -169,20 +168,18 @@ makeSuite('InterestRateStrategy', (testEnv: TestEnv) => { }); it('Checks rates at 100% utilization rate, 50% stable debt and 50% variable debt, with a 10% avg stable rate', async () => { - - let params : CalculateInterestRatesParams = - { + let params: CalculateInterestRatesParams = { unbacked: 0, liquidityAdded: '0', liquidityTaken: 0, totalStableDebt: '400000000000000000', totalVariableDebt: '400000000000000000', - averageStableBorrowRate: '100000000000000000000000000', + averageStableBorrowRate: '100000000000000000000000000', reserveFactor: strategyDAI.reserveFactor, reserve: dai.address, - aToken: aDai.address, - } - + aToken: aDai.address, + }; + const { 0: currentLiquidityRate, 1: currentStableBorrowRate, @@ -201,8 +198,7 @@ makeSuite('InterestRateStrategy', (testEnv: TestEnv) => { expect(currentVariableBorrowRate).to.be.equal(expectedVariableRate, 'Invalid variable rate'); expect(currentLiquidityRate).to.be.equal(expectedLiquidityRate, 'Invalid liquidity rate'); expect(currentStableBorrowRate).to.be.equal( - utils - .parseUnits('0.039', 27) + baseStableRate .add(rateStrategyStableTwo.stableRateSlope1) .add(rateStrategyStableTwo.stableRateSlope2), 'Invalid stable rate' @@ -210,20 +206,18 @@ makeSuite('InterestRateStrategy', (testEnv: TestEnv) => { }); it('Checks rates at 80% borrow utilization rate and 50% supply utilization due to minted tokens', async () => { - - let params : CalculateInterestRatesParams = - { + let params: CalculateInterestRatesParams = { unbacked: '600000000000000000', liquidityAdded: '200000000000000000', liquidityTaken: 0, totalStableDebt: '0', totalVariableDebt: '800000000000000000', - averageStableBorrowRate: '0', + averageStableBorrowRate: '0', reserveFactor: strategyDAI.reserveFactor, reserve: dai.address, - aToken: aDai.address, - } - + aToken: aDai.address, + }; + const { 0: currentLiquidityRate, 1: currentStableBorrowRate, @@ -244,7 +238,7 @@ makeSuite('InterestRateStrategy', (testEnv: TestEnv) => { expect(currentVariableBorrowRate).to.be.equal(expectedVariableRate, 'Invalid variable rate'); expect(currentStableBorrowRate).to.be.equal( - utils.parseUnits('0.039', 27).add(rateStrategyStableTwo.stableRateSlope1), + baseStableRate.add(rateStrategyStableTwo.stableRateSlope1), 'Invalid stable rate' ); }); @@ -253,18 +247,17 @@ makeSuite('InterestRateStrategy', (testEnv: TestEnv) => { const availableLiquidity = BigNumber.from('200000000000000000'); const totalVariableDebt = BigNumber.from('800000000000000000'); - let params : CalculateInterestRatesParams = - { + let params: CalculateInterestRatesParams = { unbacked: totalVariableDebt.mul('124').sub(availableLiquidity), liquidityAdded: availableLiquidity, liquidityTaken: 0, totalStableDebt: '0', totalVariableDebt: totalVariableDebt, - averageStableBorrowRate: '0', + averageStableBorrowRate: '0', reserveFactor: strategyDAI.reserveFactor, reserve: dai.address, - aToken: aDai.address, - } + aToken: aDai.address, + }; const { 0: currentLiquidityRate, @@ -285,7 +278,7 @@ makeSuite('InterestRateStrategy', (testEnv: TestEnv) => { expect(currentVariableBorrowRate).to.be.equal(expectedVariableRate, 'Invalid variable rate'); expect(currentStableBorrowRate).to.be.equal( - utils.parseUnits('0.039', 27).add(rateStrategyStableTwo.stableRateSlope1), + baseStableRate.add(rateStrategyStableTwo.stableRateSlope1), 'Invalid stable rate' ); @@ -297,19 +290,17 @@ makeSuite('InterestRateStrategy', (testEnv: TestEnv) => { }); it('Checks rates at 0.8% utilization', async () => { - - let params : CalculateInterestRatesParams = - { + let params: CalculateInterestRatesParams = { unbacked: 0, liquidityAdded: '9920000000000000000000', liquidityTaken: 0, totalStableDebt: '0', totalVariableDebt: '80000000000000000000', - averageStableBorrowRate: '0', + averageStableBorrowRate: '0', reserveFactor: strategyDAI.reserveFactor, reserve: dai.address, - aToken: aDai.address, - } + aToken: aDai.address, + }; const { 0: currentLiquidityRate, @@ -334,13 +325,9 @@ makeSuite('InterestRateStrategy', (testEnv: TestEnv) => { expect(currentVariableBorrowRate).to.be.equal(expectedVariableRate, 'Invalid variable rate'); expect(currentStableBorrowRate).to.be.equal( - utils - .parseUnits('0.039', 27) - .add( - BigNumber.from(rateStrategyStableTwo.stableRateSlope1).rayMul( - utilRate.rayDiv(optimalRate) - ) - ), + baseStableRate.add( + BigNumber.from(rateStrategyStableTwo.stableRateSlope1).rayMul(utilRate.rayDiv(optimalRate)) + ), 'Invalid stable rate' );