mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
Merge branch 'master' of gitlab.com:aave-tech/protocol-v2 into 97-create-a-utility-contract-to-deposit-withdraw-repay-with-eth
This commit is contained in:
commit
e6d913d251
|
@ -349,11 +349,14 @@ interface ILendingPool {
|
|||
|
||||
function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory);
|
||||
|
||||
function balanceDecreaseAllowed(
|
||||
address reserve,
|
||||
address user,
|
||||
uint256 amount
|
||||
) external view returns (bool);
|
||||
function finalizeTransfer(
|
||||
address asset,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount,
|
||||
uint256 balanceFromAfter,
|
||||
uint256 balanceToBefore
|
||||
) external;
|
||||
|
||||
function getReservesList() external view returns (address[] memory);
|
||||
|
||||
|
|
|
@ -724,29 +724,48 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev validate if a balance decrease for an asset is allowed
|
||||
* @dev validates and finalizes an aToken transfer
|
||||
* @param asset the address of the reserve
|
||||
* @param user the user related to the balance decrease
|
||||
* @param from the user from which the aTokens are transferred
|
||||
* @param to the user receiving the aTokens
|
||||
* @param amount the amount being transferred/redeemed
|
||||
* @return true if the balance decrease can be allowed, false otherwise
|
||||
* @param balanceFromBefore the balance of the from user before the transfer
|
||||
* @param balanceToBefore the balance of the to user before the transfer
|
||||
*/
|
||||
function balanceDecreaseAllowed(
|
||||
function finalizeTransfer(
|
||||
address asset,
|
||||
address user,
|
||||
uint256 amount
|
||||
) external override view returns (bool) {
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount,
|
||||
uint256 balanceFromBefore,
|
||||
uint256 balanceToBefore
|
||||
) external override {
|
||||
_whenNotPaused();
|
||||
return
|
||||
GenericLogic.balanceDecreaseAllowed(
|
||||
asset,
|
||||
user,
|
||||
amount,
|
||||
_reserves,
|
||||
_usersConfig[user],
|
||||
_reservesList,
|
||||
_reservesCount,
|
||||
_addressesProvider.getPriceOracle()
|
||||
);
|
||||
|
||||
require(msg.sender == _reserves[asset].aTokenAddress, Errors.CALLER_MUST_BE_AN_ATOKEN);
|
||||
|
||||
ValidationLogic.validateTransfer(
|
||||
from,
|
||||
_reserves,
|
||||
_usersConfig[from],
|
||||
_reservesList,
|
||||
_reservesCount,
|
||||
_addressesProvider.getPriceOracle()
|
||||
);
|
||||
|
||||
uint256 reserveId = _reserves[asset].id;
|
||||
|
||||
if (from != to) {
|
||||
if (balanceFromBefore.sub(amount) == 0) {
|
||||
UserConfiguration.Map storage fromConfig = _usersConfig[from];
|
||||
fromConfig.setUsingAsCollateral(reserveId, false);
|
||||
}
|
||||
|
||||
if (balanceToBefore == 0 && amount != 0) {
|
||||
UserConfiguration.Map storage toConfig = _usersConfig[to];
|
||||
toConfig.setUsingAsCollateral(reserveId, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
|
||||
import {Errors} from '../helpers/Errors.sol';
|
||||
|
||||
/**
|
||||
* @title ReserveConfiguration library
|
||||
* @author Aave
|
||||
* @notice Implements the bitmap logic to handle the reserve configuration
|
||||
*/
|
||||
library ReserveConfiguration {
|
||||
uint256 constant LTV_MASK = 0xFFFFFFFFFFFFFFFF0000;
|
||||
uint256 constant LIQUIDATION_THRESHOLD_MASK = 0xFFFFFFFFFFFF0000FFFF;
|
||||
uint256 constant LIQUIDATION_BONUS_MASK = 0xFFFFFFFF0000FFFFFFFF;
|
||||
uint256 constant DECIMALS_MASK = 0xFFFFFF00FFFFFFFFFFFF;
|
||||
uint256 constant ACTIVE_MASK = 0xFFFFFEFFFFFFFFFFFFFF;
|
||||
uint256 constant FROZEN_MASK = 0xFFFFFDFFFFFFFFFFFFFF;
|
||||
uint256 constant BORROWING_MASK = 0xFFFFFBFFFFFFFFFFFFFF;
|
||||
uint256 constant STABLE_BORROWING_MASK = 0xFFFFF7FFFFFFFFFFFFFF;
|
||||
uint256 constant RESERVE_FACTOR_MASK = 0xFFFFFFFFFFFFFFFF;
|
||||
uint256 constant LTV_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000; // prettier-ignore
|
||||
uint256 constant LIQUIDATION_THRESHOLD_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFF; // prettier-ignore
|
||||
uint256 constant LIQUIDATION_BONUS_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF; // prettier-ignore
|
||||
uint256 constant DECIMALS_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF; // prettier-ignore
|
||||
uint256 constant ACTIVE_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFF; // prettier-ignore
|
||||
uint256 constant FROZEN_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFF; // prettier-ignore
|
||||
uint256 constant BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFF; // prettier-ignore
|
||||
uint256 constant STABLE_BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFF; // prettier-ignore
|
||||
uint256 constant RESERVE_FACTOR_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF; // prettier-ignore
|
||||
|
||||
/// @dev For the LTV, the start bit is 0 (up to 15), but we don't declare it as for 0 no bit movement is needed
|
||||
uint256 constant LIQUIDATION_THRESHOLD_START_BIT_POSITION = 16;
|
||||
|
@ -27,6 +29,12 @@ library ReserveConfiguration {
|
|||
uint256 constant STABLE_BORROWING_ENABLED_START_BIT_POSITION = 59;
|
||||
uint256 constant RESERVE_FACTOR_START_BIT_POSITION = 64;
|
||||
|
||||
uint256 constant MAX_VALID_LTV = 65535;
|
||||
uint256 constant MAX_VALID_LIQUIDATION_THRESHOLD = 65535;
|
||||
uint256 constant MAX_VALID_LIQUIDATION_BONUS = 65535;
|
||||
uint256 constant MAX_VALID_DECIMALS = 255;
|
||||
uint256 constant MAX_VALID_RESERVE_FACTOR = 65535;
|
||||
|
||||
struct Map {
|
||||
//bit 0-15: LTV
|
||||
//bit 16-31: Liq. threshold
|
||||
|
@ -47,6 +55,8 @@ library ReserveConfiguration {
|
|||
* @param ltv the new ltv
|
||||
**/
|
||||
function setLtv(ReserveConfiguration.Map memory self, uint256 ltv) internal pure {
|
||||
require(ltv <= MAX_VALID_LTV, Errors.INVALID_LTV);
|
||||
|
||||
self.data = (self.data & LTV_MASK) | ltv;
|
||||
}
|
||||
|
||||
|
@ -68,6 +78,8 @@ library ReserveConfiguration {
|
|||
internal
|
||||
pure
|
||||
{
|
||||
require(threshold <= MAX_VALID_LIQUIDATION_THRESHOLD, Errors.INVALID_LIQ_THRESHOLD);
|
||||
|
||||
self.data =
|
||||
(self.data & LIQUIDATION_THRESHOLD_MASK) |
|
||||
(threshold << LIQUIDATION_THRESHOLD_START_BIT_POSITION);
|
||||
|
@ -92,6 +104,8 @@ library ReserveConfiguration {
|
|||
* @param bonus the new liquidation bonus
|
||||
**/
|
||||
function setLiquidationBonus(ReserveConfiguration.Map memory self, uint256 bonus) internal pure {
|
||||
require(bonus <= MAX_VALID_LIQUIDATION_BONUS, Errors.INVALID_LIQ_BONUS);
|
||||
|
||||
self.data =
|
||||
(self.data & LIQUIDATION_BONUS_MASK) |
|
||||
(bonus << LIQUIDATION_BONUS_START_BIT_POSITION);
|
||||
|
@ -116,6 +130,8 @@ library ReserveConfiguration {
|
|||
* @param decimals the decimals
|
||||
**/
|
||||
function setDecimals(ReserveConfiguration.Map memory self, uint256 decimals) internal pure {
|
||||
require(decimals <= MAX_VALID_DECIMALS, Errors.INVALID_DECIMALS);
|
||||
|
||||
self.data = (self.data & DECIMALS_MASK) | (decimals << RESERVE_DECIMALS_START_BIT_POSITION);
|
||||
}
|
||||
|
||||
|
@ -145,7 +161,7 @@ library ReserveConfiguration {
|
|||
* @return the active state
|
||||
**/
|
||||
function getActive(ReserveConfiguration.Map storage self) internal view returns (bool) {
|
||||
return ((self.data & ~ACTIVE_MASK) >> IS_ACTIVE_START_BIT_POSITION) != 0;
|
||||
return (self.data & ~ACTIVE_MASK) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -165,7 +181,7 @@ library ReserveConfiguration {
|
|||
* @return the frozen state
|
||||
**/
|
||||
function getFrozen(ReserveConfiguration.Map storage self) internal view returns (bool) {
|
||||
return ((self.data & ~FROZEN_MASK) >> IS_FROZEN_START_BIT_POSITION) != 0;
|
||||
return (self.data & ~FROZEN_MASK) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,7 +201,7 @@ library ReserveConfiguration {
|
|||
* @return the borrowing state
|
||||
**/
|
||||
function getBorrowingEnabled(ReserveConfiguration.Map storage self) internal view returns (bool) {
|
||||
return ((self.data & ~BORROWING_MASK) >> BORROWING_ENABLED_START_BIT_POSITION) != 0;
|
||||
return (self.data & ~BORROWING_MASK) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -212,8 +228,7 @@ library ReserveConfiguration {
|
|||
view
|
||||
returns (bool)
|
||||
{
|
||||
return
|
||||
((self.data & ~STABLE_BORROWING_MASK) >> STABLE_BORROWING_ENABLED_START_BIT_POSITION) != 0;
|
||||
return (self.data & ~STABLE_BORROWING_MASK) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -225,6 +240,8 @@ library ReserveConfiguration {
|
|||
internal
|
||||
pure
|
||||
{
|
||||
require(reserveFactor <= MAX_VALID_RESERVE_FACTOR, Errors.INVALID_RESERVE_FACTOR);
|
||||
|
||||
self.data =
|
||||
(self.data & RESERVE_FACTOR_MASK) |
|
||||
(reserveFactor << RESERVE_FACTOR_START_BIT_POSITION);
|
||||
|
@ -257,10 +274,10 @@ library ReserveConfiguration {
|
|||
uint256 dataLocal = self.data;
|
||||
|
||||
return (
|
||||
(dataLocal & ~ACTIVE_MASK) >> IS_ACTIVE_START_BIT_POSITION != 0,
|
||||
(dataLocal & ~FROZEN_MASK) >> IS_FROZEN_START_BIT_POSITION != 0,
|
||||
(dataLocal & ~BORROWING_MASK) >> BORROWING_ENABLED_START_BIT_POSITION != 0,
|
||||
(dataLocal & ~STABLE_BORROWING_MASK) >> STABLE_BORROWING_ENABLED_START_BIT_POSITION != 0
|
||||
(dataLocal & ~ACTIVE_MASK) != 0,
|
||||
(dataLocal & ~FROZEN_MASK) != 0,
|
||||
(dataLocal & ~BORROWING_MASK) != 0,
|
||||
(dataLocal & ~STABLE_BORROWING_MASK) != 0
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -316,8 +333,7 @@ library ReserveConfiguration {
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* @dev gets the configuration flags of the reserve from a memory object
|
||||
* @param self the reserve configuration
|
||||
* @return the state flags representing active, freezed, borrowing enabled, stableRateBorrowing enabled
|
||||
|
@ -333,10 +349,10 @@ library ReserveConfiguration {
|
|||
)
|
||||
{
|
||||
return (
|
||||
(self.data & ~ACTIVE_MASK) >> IS_ACTIVE_START_BIT_POSITION != 0,
|
||||
(self.data & ~FROZEN_MASK) >> IS_FROZEN_START_BIT_POSITION != 0,
|
||||
(self.data & ~BORROWING_MASK) >> BORROWING_ENABLED_START_BIT_POSITION != 0,
|
||||
(self.data & ~STABLE_BORROWING_MASK) >> STABLE_BORROWING_ENABLED_START_BIT_POSITION != 0
|
||||
(self.data & ~ACTIVE_MASK) != 0,
|
||||
(self.data & ~FROZEN_MASK) != 0,
|
||||
(self.data & ~BORROWING_MASK) != 0,
|
||||
(self.data & ~STABLE_BORROWING_MASK) != 0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ library Errors {
|
|||
string public constant NO_MORE_RESERVES_ALLOWED = '59';
|
||||
string public constant INVALID_FLASH_LOAN_EXECUTOR_RETURN = '60';
|
||||
string public constant INCONSISTENT_FLASHLOAN_PARAMS = '69';
|
||||
string public constant CALLER_MUST_BE_AN_ATOKEN = '76';
|
||||
|
||||
// require error messages - aToken - DebtTokens
|
||||
string public constant CALLER_MUST_BE_LENDING_POOL = '28'; // 'The caller of this function must be a lending pool'
|
||||
|
@ -89,6 +90,15 @@ library Errors {
|
|||
|
||||
// pausable error message
|
||||
string public constant IS_PAUSED = '58'; // 'Pool is paused'
|
||||
|
||||
// Reserve configuration
|
||||
string public constant INVALID_LTV = '70';
|
||||
string public constant INVALID_LIQ_THRESHOLD = '71';
|
||||
string public constant INVALID_LIQ_BONUS = '72';
|
||||
string public constant INVALID_DECIMALS = '73';
|
||||
string public constant INVALID_RESERVE_FACTOR = '74';
|
||||
|
||||
|
||||
enum CollateralManagerErrors {
|
||||
NO_ERROR,
|
||||
NO_COLLATERAL_AVAILABLE,
|
||||
|
|
|
@ -46,6 +46,11 @@ library ValidationLogic {
|
|||
* @param reserveAddress the address of the reserve
|
||||
* @param amount the amount to be withdrawn
|
||||
* @param userBalance the balance of the user
|
||||
* @param reservesData the reserves state
|
||||
* @param userConfig the user configuration
|
||||
* @param reserves the addresses of the reserves
|
||||
* @param reservesCount the number of reserves
|
||||
* @param oracle the price oracle
|
||||
*/
|
||||
function validateWithdraw(
|
||||
address reserveAddress,
|
||||
|
@ -389,4 +394,35 @@ library ValidationLogic {
|
|||
|
||||
return (uint256(Errors.CollateralManagerErrors.NO_ERROR), Errors.NO_ERRORS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev validates an aToken transfer.
|
||||
* @param from the user from which the aTokens are being transferred
|
||||
* @param reservesData the state of all the reserves
|
||||
* @param userConfig the state of the user for the specific reserve
|
||||
* @param reserves the addresses of all the active reserves
|
||||
* @param oracle the price oracle
|
||||
*/
|
||||
function validateTransfer(
|
||||
address from,
|
||||
mapping(address => ReserveLogic.ReserveData) storage reservesData,
|
||||
UserConfiguration.Map storage userConfig,
|
||||
mapping(uint256 => address) storage reserves,
|
||||
uint256 reservesCount,
|
||||
address oracle
|
||||
) internal view {
|
||||
(, , , , uint256 healthFactor) = GenericLogic.calculateUserAccountData(
|
||||
from,
|
||||
reservesData,
|
||||
userConfig,
|
||||
reserves,
|
||||
reservesCount,
|
||||
oracle
|
||||
);
|
||||
|
||||
require(
|
||||
healthFactor >= GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD,
|
||||
Errors.TRANSFER_NOT_ALLOWED
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -241,16 +241,6 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
return super.totalSupply();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Used to validate transfers before actually executing them.
|
||||
* @param user address of the user to check
|
||||
* @param amount the amount to check
|
||||
* @return true if the user can transfer amount, false otherwise
|
||||
**/
|
||||
function isTransferAllowed(address user, uint256 amount) public override view returns (bool) {
|
||||
return POOL.balanceDecreaseAllowed(UNDERLYING_ASSET_ADDRESS, user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev transfers the underlying asset to the target. Used by the lendingpool to transfer
|
||||
* assets in borrow(), redeem() and flashLoan()
|
||||
|
@ -317,14 +307,24 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
uint256 amount,
|
||||
bool validate
|
||||
) internal {
|
||||
if (validate) {
|
||||
require(isTransferAllowed(from, amount), Errors.TRANSFER_NOT_ALLOWED);
|
||||
}
|
||||
|
||||
uint256 index = POOL.getReserveNormalizedIncome(UNDERLYING_ASSET_ADDRESS);
|
||||
|
||||
uint256 fromBalanceBefore = super.balanceOf(from).rayMul(index);
|
||||
uint256 toBalanceBefore = super.balanceOf(to).rayMul(index);
|
||||
|
||||
super._transfer(from, to, amount.rayDiv(index));
|
||||
|
||||
if (validate) {
|
||||
POOL.finalizeTransfer(
|
||||
UNDERLYING_ASSET_ADDRESS,
|
||||
from,
|
||||
to,
|
||||
amount,
|
||||
fromBalanceBefore,
|
||||
toBalanceBefore
|
||||
);
|
||||
}
|
||||
|
||||
emit BalanceTransfer(from, to, amount, index);
|
||||
}
|
||||
|
||||
|
|
|
@ -54,8 +54,6 @@ interface IAToken is IERC20, IScaledBalanceToken {
|
|||
uint256 value
|
||||
) external;
|
||||
|
||||
function isTransferAllowed(address user, uint256 amount) external view returns (bool);
|
||||
|
||||
/**
|
||||
* @dev transfer the amount of the underlying asset to the user
|
||||
* @param user address of the user
|
||||
|
|
|
@ -122,6 +122,12 @@ export enum ProtocolErrors {
|
|||
|
||||
IS_PAUSED = '58', // Pool is paused
|
||||
|
||||
INVALID_LTV = '70',
|
||||
INVALID_LIQ_THRESHOLD = '71',
|
||||
INVALID_LIQ_BONUS = '72',
|
||||
INVALID_DECIMALS = '73',
|
||||
INVALID_RESERVE_FACTOR = '74',
|
||||
|
||||
// old
|
||||
|
||||
INVALID_FROM_BALANCE_AFTER_TRANSFER = 'Invalid from balance after transfer',
|
||||
|
|
|
@ -50,8 +50,8 @@ makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
|
|||
);
|
||||
});
|
||||
|
||||
it('User 0 deposits 1 WETH and user 1 tries to borrow, but the aTokens received as a transfer are not available as collateral (revert expected)', async () => {
|
||||
const {users, pool, weth} = testEnv;
|
||||
it('User 0 deposits 1 WETH and user 1 tries to borrow the WETH with the received DAI as collateral', async () => {
|
||||
const {users, pool, weth, helpersContract} = testEnv;
|
||||
const userAddress = await pool.signer.getAddress();
|
||||
|
||||
await weth.connect(users[0].signer).mint(await convertToCurrencyDecimals(weth.address, '1'));
|
||||
|
@ -61,26 +61,6 @@ makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
|
|||
await pool
|
||||
.connect(users[0].signer)
|
||||
.deposit(weth.address, ethers.utils.parseEther('1.0'), userAddress, '0');
|
||||
await expect(
|
||||
pool
|
||||
.connect(users[1].signer)
|
||||
.borrow(
|
||||
weth.address,
|
||||
ethers.utils.parseEther('0.1'),
|
||||
RateMode.Stable,
|
||||
AAVE_REFERRAL,
|
||||
users[1].address
|
||||
),
|
||||
COLLATERAL_BALANCE_IS_0
|
||||
).to.be.revertedWith(COLLATERAL_BALANCE_IS_0);
|
||||
});
|
||||
|
||||
it('User 1 sets the DAI as collateral and borrows, tries to transfer everything back to user 0 (revert expected)', async () => {
|
||||
const {users, pool, aDai, dai, weth} = testEnv;
|
||||
await pool.connect(users[1].signer).setUserUseReserveAsCollateral(dai.address, true);
|
||||
|
||||
const aDAItoTransfer = await convertToCurrencyDecimals(dai.address, '1000');
|
||||
|
||||
await pool
|
||||
.connect(users[1].signer)
|
||||
.borrow(
|
||||
|
@ -91,9 +71,32 @@ makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
|
|||
users[1].address
|
||||
);
|
||||
|
||||
const userReserveData = await helpersContract.getUserReserveData(weth.address, users[1].address);
|
||||
|
||||
expect(userReserveData.currentStableDebt.toString()).to.be.eq(ethers.utils.parseEther('0.1'));
|
||||
});
|
||||
|
||||
it('User 1 tries to transfer all the DAI used as collateral back to user 0 (revert expected)', async () => {
|
||||
const {users, pool, aDai, dai, weth} = testEnv;
|
||||
|
||||
const aDAItoTransfer = await convertToCurrencyDecimals(dai.address, '1000');
|
||||
|
||||
await expect(
|
||||
aDai.connect(users[1].signer).transfer(users[0].address, aDAItoTransfer),
|
||||
TRANSFER_NOT_ALLOWED
|
||||
).to.be.revertedWith(TRANSFER_NOT_ALLOWED);
|
||||
});
|
||||
|
||||
it('User 1 tries to transfer a small amount of DAI used as collateral back to user 0', async () => {
|
||||
|
||||
const {users, pool, aDai, dai, weth} = testEnv;
|
||||
|
||||
const aDAItoTransfer = await convertToCurrencyDecimals(dai.address, '100');
|
||||
|
||||
await aDai.connect(users[1].signer).transfer(users[0].address, aDAItoTransfer);
|
||||
|
||||
const user0Balance = await aDai.balanceOf(users[0].address);
|
||||
|
||||
expect(user0Balance.toString()).to.be.eq(aDAItoTransfer.toString());
|
||||
});
|
||||
});
|
||||
|
|
|
@ -10,7 +10,63 @@ const APPROVAL_AMOUNT_LENDING_POOL =
|
|||
const {expect} = require('chai');
|
||||
|
||||
makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||
const {CALLER_NOT_AAVE_ADMIN, RESERVE_LIQUIDITY_NOT_0} = ProtocolErrors;
|
||||
const {
|
||||
CALLER_NOT_AAVE_ADMIN,
|
||||
RESERVE_LIQUIDITY_NOT_0,
|
||||
INVALID_LTV,
|
||||
INVALID_LIQ_THRESHOLD,
|
||||
INVALID_LIQ_BONUS,
|
||||
INVALID_DECIMALS,
|
||||
INVALID_RESERVE_FACTOR,
|
||||
} = ProtocolErrors;
|
||||
|
||||
it('Reverts trying to set an invalid LTV', async () => {
|
||||
const {configurator, weth} = testEnv;
|
||||
|
||||
const invalidLtv = 65536;
|
||||
|
||||
await expect(configurator.setLtv(weth.address, invalidLtv)).to.be.revertedWith(INVALID_LTV);
|
||||
});
|
||||
|
||||
it('Reverts trying to set an invalid liquidation threshold', async () => {
|
||||
const {configurator, weth} = testEnv;
|
||||
|
||||
const invalidLiqThreshold = 65536;
|
||||
|
||||
await expect(
|
||||
configurator.setLiquidationThreshold(weth.address, invalidLiqThreshold)
|
||||
).to.be.revertedWith(INVALID_LIQ_THRESHOLD);
|
||||
});
|
||||
|
||||
it('Reverts trying to set an invalid liquidation bonus', async () => {
|
||||
const {configurator, weth} = testEnv;
|
||||
|
||||
const invalidLiqBonus = 65536;
|
||||
|
||||
await expect(
|
||||
configurator.setLiquidationBonus(weth.address, invalidLiqBonus)
|
||||
).to.be.revertedWith(INVALID_LIQ_BONUS);
|
||||
});
|
||||
|
||||
it('Reverts trying to set an invalid reserve decimals', async () => {
|
||||
const {configurator, weth} = testEnv;
|
||||
|
||||
const invalidDecimals = 256;
|
||||
|
||||
await expect(configurator.setReserveDecimals(weth.address, invalidDecimals)).to.be.revertedWith(
|
||||
INVALID_DECIMALS
|
||||
);
|
||||
});
|
||||
|
||||
it('Reverts trying to set an invalid reserve factor', async () => {
|
||||
const {configurator, weth} = testEnv;
|
||||
|
||||
const invalidReserveFactor = 65536;
|
||||
|
||||
await expect(
|
||||
configurator.setReserveFactor(weth.address, invalidReserveFactor)
|
||||
).to.be.revertedWith(INVALID_RESERVE_FACTOR);
|
||||
});
|
||||
|
||||
it('Deactivates the ETH reserve', async () => {
|
||||
const {configurator, weth, helpersContract} = testEnv;
|
||||
|
|
Loading…
Reference in New Issue
Block a user