mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
Merge branch 'fix/45' into 'master'
Resolve "Update rebalance conditions" Closes #45 See merge request aave-tech/protocol-v2!54
This commit is contained in:
commit
f756f44a8d
|
@ -10,9 +10,13 @@ interface IReserveInterestRateStrategy {
|
|||
/**
|
||||
* @dev returns the base variable borrow rate, in rays
|
||||
*/
|
||||
|
||||
function baseVariableBorrowRate() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev returns the maximum variable borrow rate
|
||||
*/
|
||||
function getMaxVariableBorrowRate() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev calculates the liquidity, stable, and variable rates depending on the current utilization rate
|
||||
* and the base parameters
|
||||
|
|
|
@ -91,6 +91,10 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
|||
return _baseVariableBorrowRate;
|
||||
}
|
||||
|
||||
function getMaxVariableBorrowRate() external override view returns (uint256) {
|
||||
return _baseVariableBorrowRate.add(_variableRateSlope1).add(_variableRateSlope2);
|
||||
}
|
||||
|
||||
struct CalcInterestRatesLocalVars {
|
||||
|
||||
uint256 totalBorrows;
|
||||
|
|
|
@ -28,21 +28,22 @@ import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
|||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
||||
import {LendingPoolStorage} from './LendingPoolStorage.sol';
|
||||
|
||||
import {IReserveInterestRateStrategy} from '../interfaces/IReserveInterestRateStrategy.sol';
|
||||
/**
|
||||
* @title LendingPool contract
|
||||
* @notice Implements the actions of the LendingPool, and exposes accessory methods to fetch the users and reserve data
|
||||
* @author Aave
|
||||
**/
|
||||
|
||||
contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage {
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
using PercentageMath for uint256;
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
//main configuration parameters
|
||||
uint256 public constant REBALANCE_DOWN_RATE_DELTA = (1e27) / 5;
|
||||
uint256 public constant MAX_STABLE_RATE_BORROW_SIZE_PERCENT = 25;
|
||||
uint256 public constant REBALANCE_UP_LIQUIDITY_RATE_THRESHOLD = 4000;
|
||||
uint256 public constant REBALANCE_UP_USAGE_RATIO_THRESHOLD = 0.95 * 1e27; //usage ratio of 95%
|
||||
uint256 public constant MAX_STABLE_RATE_BORROW_SIZE_PERCENT = 2500;
|
||||
uint256 public constant FLASHLOAN_PREMIUM_TOTAL = 9;
|
||||
uint256 public constant MAX_NUMBER_RESERVES = 128;
|
||||
uint256 public constant LENDINGPOOL_REVISION = 0x2;
|
||||
|
@ -50,13 +51,12 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
/**
|
||||
* @dev only lending pools configurator can use functions affected by this modifier
|
||||
**/
|
||||
function onlyLendingPoolConfigurator() internal view {
|
||||
function _onlyLendingPoolConfigurator() internal view {
|
||||
require(
|
||||
_addressesProvider.getLendingPoolConfigurator() == msg.sender,
|
||||
Errors.CALLER_NOT_LENDING_POOL_CONFIGURATOR
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Function to make a function callable only when the contract is not paused.
|
||||
*
|
||||
|
@ -64,7 +64,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
*
|
||||
* - The contract must not be paused.
|
||||
*/
|
||||
function whenNotPaused() internal view {
|
||||
function _whenNotPaused() internal view {
|
||||
require(!_paused, Errors.IS_PAUSED);
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
address onBehalfOf,
|
||||
uint16 referralCode
|
||||
) external override {
|
||||
whenNotPaused();
|
||||
_whenNotPaused();
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
ValidationLogic.validateDeposit(reserve, amount);
|
||||
|
@ -123,7 +123,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
* @param amount the underlying amount to be redeemed
|
||||
**/
|
||||
function withdraw(address asset, uint256 amount) external override {
|
||||
whenNotPaused();
|
||||
_whenNotPaused();
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
address aToken = reserve.aTokenAddress;
|
||||
|
@ -139,7 +139,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
|
||||
ValidationLogic.validateWithdraw(
|
||||
asset,
|
||||
aToken,
|
||||
amountToWithdraw,
|
||||
userBalance,
|
||||
_reserves,
|
||||
|
@ -161,6 +160,14 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
emit Withdraw(asset, msg.sender, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev returns the borrow allowance of the user
|
||||
* @param asset The underlying asset of the debt token
|
||||
* @param fromUser The user to giving allowance
|
||||
* @param toUser The user to give allowance to
|
||||
* @param interestRateMode Type of debt: 1 for stable, 2 for variable
|
||||
* @return the current allowance of toUser
|
||||
**/
|
||||
function getBorrowAllowance(
|
||||
address fromUser,
|
||||
address toUser,
|
||||
|
@ -184,7 +191,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
uint256 interestRateMode,
|
||||
uint256 amount
|
||||
) external override {
|
||||
whenNotPaused();
|
||||
_whenNotPaused();
|
||||
address debtToken = _reserves[asset].getDebtTokenAddress(interestRateMode);
|
||||
|
||||
_borrowAllowance[debtToken][msg.sender][user] = amount;
|
||||
|
@ -207,7 +214,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
uint16 referralCode,
|
||||
address onBehalfOf
|
||||
) external override {
|
||||
whenNotPaused();
|
||||
_whenNotPaused();
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
if (onBehalfOf != msg.sender) {
|
||||
|
@ -247,7 +254,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
uint256 rateMode,
|
||||
address onBehalfOf
|
||||
) external override {
|
||||
whenNotPaused();
|
||||
_whenNotPaused();
|
||||
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
|
@ -304,7 +311,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
* @param rateMode the rate mode that the user wants to swap
|
||||
**/
|
||||
function swapBorrowRateMode(address asset, uint256 rateMode) external override {
|
||||
whenNotPaused();
|
||||
_whenNotPaused();
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
(uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(msg.sender, reserve);
|
||||
|
@ -356,43 +363,50 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
* @param user the address of the user to be rebalanced
|
||||
**/
|
||||
function rebalanceStableBorrowRate(address asset, address user) external override {
|
||||
whenNotPaused();
|
||||
|
||||
_whenNotPaused();
|
||||
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
IStableDebtToken stableDebtToken = IStableDebtToken(reserve.stableDebtTokenAddress);
|
||||
IERC20 stableDebtToken = IERC20(reserve.stableDebtTokenAddress);
|
||||
IERC20 variableDebtToken = IERC20(reserve.variableDebtTokenAddress);
|
||||
address aTokenAddress = reserve.aTokenAddress;
|
||||
|
||||
uint256 stableBorrowBalance = IERC20(address(stableDebtToken)).balanceOf(user);
|
||||
uint256 stableBorrowBalance = IERC20(stableDebtToken).balanceOf(user);
|
||||
|
||||
// user must be borrowing on asset at a stable rate
|
||||
require(stableBorrowBalance > 0, Errors.NOT_ENOUGH_STABLE_BORROW_BALANCE);
|
||||
//if the utilization rate is below 95%, no rebalances are needed
|
||||
uint256 totalBorrows = stableDebtToken.totalSupply().add(variableDebtToken.totalSupply()).wadToRay();
|
||||
uint256 availableLiquidity = IERC20(asset).balanceOf(aTokenAddress).wadToRay();
|
||||
uint256 usageRatio = totalBorrows == 0
|
||||
? 0
|
||||
: totalBorrows.rayDiv(availableLiquidity.add(totalBorrows));
|
||||
|
||||
uint256 rebalanceDownRateThreshold = WadRayMath.ray().add(REBALANCE_DOWN_RATE_DELTA).rayMul(
|
||||
reserve.currentStableBorrowRate
|
||||
);
|
||||
//if the liquidity rate is below REBALANCE_UP_THRESHOLD of the max variable APR at 95% usage,
|
||||
//then we allow rebalancing of the stable rate positions.
|
||||
|
||||
//1. user stable borrow rate is below the current liquidity rate. The loan needs to be rebalanced,
|
||||
//as this situation can be abused (user putting back the borrowed liquidity in the same reserve to earn on it)
|
||||
//2. user stable rate is above the market avg borrow rate of a certain delta, and utilization rate is low.
|
||||
//In this case, the user is paying an interest that is too high, and needs to be rescaled down.
|
||||
|
||||
uint256 userStableRate = stableDebtToken.getUserStableRate(user);
|
||||
uint256 currentLiquidityRate = reserve.currentLiquidityRate;
|
||||
uint256 maxVariableBorrowRate = IReserveInterestRateStrategy(
|
||||
reserve
|
||||
.interestRateStrategyAddress
|
||||
)
|
||||
.getMaxVariableBorrowRate();
|
||||
|
||||
require(
|
||||
userStableRate < reserve.currentLiquidityRate || userStableRate > rebalanceDownRateThreshold,
|
||||
usageRatio >= REBALANCE_UP_USAGE_RATIO_THRESHOLD &&
|
||||
currentLiquidityRate <=
|
||||
maxVariableBorrowRate.percentMul(REBALANCE_UP_LIQUIDITY_RATE_THRESHOLD),
|
||||
Errors.INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET
|
||||
);
|
||||
|
||||
reserve.updateState();
|
||||
|
||||
//burn old debt tokens, mint new ones
|
||||
stableDebtToken.burn(user, stableBorrowBalance);
|
||||
stableDebtToken.mint(user, stableBorrowBalance, reserve.currentStableBorrowRate);
|
||||
IStableDebtToken(address(stableDebtToken)).burn(user, stableBorrowBalance);
|
||||
IStableDebtToken(address(stableDebtToken)).mint(user, stableBorrowBalance, reserve.currentStableBorrowRate);
|
||||
|
||||
reserve.updateInterestRates(asset, reserve.aTokenAddress, 0, 0);
|
||||
reserve.updateInterestRates(asset, aTokenAddress, 0, 0);
|
||||
|
||||
emit RebalanceStableBorrowRate(asset, user);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -401,7 +415,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
* @param useAsCollateral true if the user wants to user the deposit as collateral, false otherwise.
|
||||
**/
|
||||
function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external override {
|
||||
whenNotPaused();
|
||||
_whenNotPaused();
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
ValidationLogic.validateSetUseReserveAsCollateral(
|
||||
|
@ -438,7 +452,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
uint256 purchaseAmount,
|
||||
bool receiveAToken
|
||||
) external override {
|
||||
whenNotPaused();
|
||||
_whenNotPaused();
|
||||
address collateralManager = _addressesProvider.getLendingPoolCollateralManager();
|
||||
|
||||
//solium-disable-next-line
|
||||
|
@ -482,7 +496,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
address receiver,
|
||||
bytes calldata params
|
||||
) external override {
|
||||
whenNotPaused();
|
||||
_whenNotPaused();
|
||||
require(!_flashLiquidationLocked, Errors.REENTRANCY_NOT_ALLOWED);
|
||||
_flashLiquidationLocked = true;
|
||||
|
||||
|
@ -538,7 +552,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
bytes calldata params,
|
||||
uint16 referralCode
|
||||
) external override {
|
||||
whenNotPaused();
|
||||
_whenNotPaused();
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
FlashLoanLocalVars memory vars;
|
||||
|
||||
|
@ -600,7 +614,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
uint256 amountToSwap,
|
||||
bytes calldata params
|
||||
) external override {
|
||||
whenNotPaused();
|
||||
_whenNotPaused();
|
||||
address collateralManager = _addressesProvider.getLendingPoolCollateralManager();
|
||||
|
||||
//solium-disable-next-line
|
||||
|
@ -740,7 +754,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
_reservesList,
|
||||
_addressesProvider.getPriceOracle()
|
||||
);
|
||||
|
||||
|
||||
availableBorrowsETH = GenericLogic.calculateAvailableBorrowsETH(
|
||||
totalCollateralETH,
|
||||
totalBorrowsETH,
|
||||
|
@ -799,7 +813,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
address variableDebtAddress,
|
||||
address interestRateStrategyAddress
|
||||
) external override {
|
||||
onlyLendingPoolConfigurator();
|
||||
_onlyLendingPoolConfigurator();
|
||||
_reserves[asset].init(
|
||||
aTokenAddress,
|
||||
stableDebtAddress,
|
||||
|
@ -819,12 +833,12 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
external
|
||||
override
|
||||
{
|
||||
onlyLendingPoolConfigurator();
|
||||
_onlyLendingPoolConfigurator();
|
||||
_reserves[asset].interestRateStrategyAddress = rateStrategyAddress;
|
||||
}
|
||||
|
||||
function setConfiguration(address asset, uint256 configuration) external override {
|
||||
onlyLendingPoolConfigurator();
|
||||
_onlyLendingPoolConfigurator();
|
||||
_reserves[asset].configuration.data = configuration;
|
||||
}
|
||||
|
||||
|
@ -980,7 +994,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
address user,
|
||||
uint256 amount
|
||||
) external override view returns (bool) {
|
||||
whenNotPaused();
|
||||
_whenNotPaused();
|
||||
return
|
||||
GenericLogic.balanceDecreaseAllowed(
|
||||
asset,
|
||||
|
@ -998,7 +1012,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
* @param val the boolean value to set the current pause state of LendingPool
|
||||
*/
|
||||
function setPause(bool val) external override {
|
||||
onlyLendingPoolConfigurator();
|
||||
_onlyLendingPoolConfigurator();
|
||||
|
||||
_paused = val;
|
||||
if (_paused) {
|
||||
|
|
|
@ -6,7 +6,6 @@ import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
|||
import {ReserveLogic} from '../logic/ReserveLogic.sol';
|
||||
import {WadRayMath} from '../math/WadRayMath.sol';
|
||||
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
|
||||
import "@nomiclabs/buidler/console.sol";
|
||||
|
||||
/**
|
||||
* @title ReserveConfiguration library
|
||||
|
@ -143,7 +142,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @param active the active state
|
||||
**/
|
||||
function setActive(ReserveConfiguration.Map memory self, bool active) internal {
|
||||
function setActive(ReserveConfiguration.Map memory self, bool active) internal pure {
|
||||
self.data = (self.data & ACTIVE_MASK) | (uint256(active ? 1 : 0) << 56);
|
||||
}
|
||||
|
||||
|
|
|
@ -254,7 +254,7 @@ library GenericLogic {
|
|||
return (collateralBalanceETH.percentMul(liquidationThreshold)).wadDiv(borrowBalanceETH);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @dev calculates the equivalent amount in ETH that an user can borrow, depending on the available collateral and the
|
||||
* average Loan To Value.
|
||||
* @param collateralBalanceETH the total collateral balance
|
||||
|
|
|
@ -127,7 +127,7 @@ library ReserveLogic {
|
|||
* @return an address of the corresponding debt token from reserve configuration
|
||||
**/
|
||||
function getDebtTokenAddress(ReserveLogic.ReserveData storage reserve, uint256 interestRateMode)
|
||||
internal
|
||||
external
|
||||
view
|
||||
returns (address)
|
||||
{
|
||||
|
@ -297,7 +297,7 @@ library ReserveLogic {
|
|||
uint40 stableSupplyUpdatedTimestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @dev mints part of the repaid interest to the reserve treasury, depending on the reserveFactor for the
|
||||
* specific asset.
|
||||
* @param reserve the reserve reserve to be updated
|
||||
|
@ -358,7 +358,7 @@ library ReserveLogic {
|
|||
IAToken(reserve.aTokenAddress).mintToTreasury(vars.amountToMint, newLiquidityIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @dev updates the reserve indexes and the timestamp of the update
|
||||
* @param reserve the reserve reserve to be updated
|
||||
* @param variableDebtToken the debt token address
|
||||
|
@ -371,7 +371,6 @@ library ReserveLogic {
|
|||
uint256 liquidityIndex,
|
||||
uint256 variableBorrowIndex
|
||||
) internal returns (uint256, uint256) {
|
||||
|
||||
uint40 timestamp = reserve.lastUpdateTimestamp;
|
||||
|
||||
uint256 currentLiquidityRate = reserve.currentLiquidityRate;
|
||||
|
|
|
@ -34,7 +34,7 @@ library ValidationLogic {
|
|||
* @param reserve the reserve state on which the user is depositing
|
||||
* @param amount the amount to be deposited
|
||||
*/
|
||||
function validateDeposit(ReserveLogic.ReserveData storage reserve, uint256 amount) internal view {
|
||||
function validateDeposit(ReserveLogic.ReserveData storage reserve, uint256 amount) external view {
|
||||
(bool isActive, bool isFreezed, , ) = reserve.configuration.getFlags();
|
||||
|
||||
require(amount > 0, Errors.AMOUNT_NOT_GREATER_THAN_0);
|
||||
|
@ -45,13 +45,11 @@ library ValidationLogic {
|
|||
/**
|
||||
* @dev validates a withdraw action.
|
||||
* @param reserveAddress the address of the reserve
|
||||
* @param aTokenAddress the address of the aToken for the reserve
|
||||
* @param amount the amount to be withdrawn
|
||||
* @param userBalance the balance of the user
|
||||
*/
|
||||
function validateWithdraw(
|
||||
address reserveAddress,
|
||||
address aTokenAddress,
|
||||
uint256 amount,
|
||||
uint256 userBalance,
|
||||
mapping(address => ReserveLogic.ReserveData) storage reservesData,
|
||||
|
|
|
@ -8,7 +8,6 @@ import {DebtTokenBase} from './base/DebtTokenBase.sol';
|
|||
import {MathUtils} from '../libraries/math/MathUtils.sol';
|
||||
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
||||
import {IStableDebtToken} from './interfaces/IStableDebtToken.sol';
|
||||
import "@nomiclabs/buidler/console.sol";
|
||||
|
||||
/**
|
||||
* @title contract StableDebtToken
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"description": "User 0 deposits 1000 DAI, user 1 deposits 1 ETH, borrows 100 DAI at a variable rate, user 0 rebalances user 1 (revert expected)",
|
||||
"description": "User 0 deposits 1000 DAI, user 1 deposits 5 ETH, borrows 600 DAI at a variable rate, user 0 rebalances user 1 (revert expected)",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
|
@ -51,7 +51,7 @@
|
|||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"amount": "5",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
|
@ -69,7 +69,7 @@
|
|||
"args": {
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "1",
|
||||
"amount": "5",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
|
@ -78,8 +78,8 @@
|
|||
"name": "borrow",
|
||||
"args": {
|
||||
"reserve": "DAI",
|
||||
"amount": "100",
|
||||
"borrowRateMode": "variable",
|
||||
"amount": "250",
|
||||
"borrowRateMode": "stable",
|
||||
"user": "1",
|
||||
"timeTravel": "365"
|
||||
},
|
||||
|
@ -98,14 +98,16 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"description": "User 1 swaps to stable, user 0 tries to rebalance but the conditions are not met (revert expected)",
|
||||
"description": "User 1 borrows another 200 at stable, user 0 tries to rebalance but the conditions are not met (revert expected)",
|
||||
"actions": [
|
||||
{
|
||||
"name": "swapBorrowRateMode",
|
||||
"name": "borrow",
|
||||
"args": {
|
||||
"reserve": "DAI",
|
||||
"amount": "200",
|
||||
"borrowRateMode": "stable",
|
||||
"user": "1",
|
||||
"borrowRateMode": "variable"
|
||||
"timeTravel": "365"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
@ -122,7 +124,59 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"description": "User 2 deposits ETH and borrows the remaining DAI, causing the stable rates to rise (liquidity rate < user 1 borrow rate). User 0 tries to rebalance user 1 (revert expected)",
|
||||
"description": "User 1 borrows another 200 at stable, user 0 tries to rebalance but the conditions are not met (revert expected)",
|
||||
"actions": [
|
||||
{
|
||||
"name": "borrow",
|
||||
"args": {
|
||||
"reserve": "DAI",
|
||||
"amount": "200",
|
||||
"borrowRateMode": "stable",
|
||||
"user": "1",
|
||||
"timeTravel": "365"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "rebalanceStableBorrowRate",
|
||||
"args": {
|
||||
"reserve": "DAI",
|
||||
"user": "0",
|
||||
"target": "1"
|
||||
},
|
||||
"expected": "revert",
|
||||
"revertMessage": "Interest rate rebalance conditions were not met"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "User 1 borrows another 100 at stable, user 0 tries to rebalance but the conditions are not met (revert expected)",
|
||||
"actions": [
|
||||
{
|
||||
"name": "borrow",
|
||||
"args": {
|
||||
"reserve": "DAI",
|
||||
"amount": "100",
|
||||
"borrowRateMode": "stable",
|
||||
"user": "1",
|
||||
"timeTravel": "365"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "rebalanceStableBorrowRate",
|
||||
"args": {
|
||||
"reserve": "DAI",
|
||||
"user": "0",
|
||||
"target": "1"
|
||||
},
|
||||
"expected": "revert",
|
||||
"revertMessage": "Interest rate rebalance conditions were not met"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "User 2 deposits ETH and borrows the remaining DAI, causing the stable rates to rise (usage ratio = 94%). User 0 tries to rebalance user 1 (revert expected)",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
|
@ -155,7 +209,7 @@
|
|||
"name": "borrow",
|
||||
"args": {
|
||||
"reserve": "DAI",
|
||||
"amount": "100",
|
||||
"amount": "190",
|
||||
"borrowRateMode": "variable",
|
||||
"user": "2"
|
||||
},
|
||||
|
@ -174,40 +228,13 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"description": "User 2 borrows more DAI, causing the liquidity rate to rise above user 1 stable borrow rate User 0 rebalances user 1",
|
||||
"description": "User 2 borrows the remaining DAI (usage ratio = 100%). User 0 rebalances user 1",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "3",
|
||||
"user": "2"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "2"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "3",
|
||||
"user": "2"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "borrow",
|
||||
"args": {
|
||||
"reserve": "DAI",
|
||||
"amount": "700",
|
||||
"amount": "60",
|
||||
"borrowRateMode": "variable",
|
||||
"user": "2"
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue
Block a user