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:
David Racero 2020-11-02 16:54:22 +01:00
commit a4a02e761b
15 changed files with 281 additions and 54 deletions

View File

@ -4,6 +4,7 @@ pragma solidity ^0.6.8;
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol'; import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
import {ILendingPoolAddressesProvider} from './ILendingPoolAddressesProvider.sol';
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
@ -368,6 +369,8 @@ interface ILendingPool {
function getReservesList() external view returns (address[] memory); function getReservesList() external view returns (address[] memory);
function getAddressesProvider() external view returns (ILendingPoolAddressesProvider);
/** /**
* @dev Set the _pause state * @dev Set the _pause state
* @param val the boolean value to set the current pause state of LendingPool * @param val the boolean value to set the current pause state of LendingPool

View File

@ -753,7 +753,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
/** /**
* @dev returns the addresses provider * @dev returns the addresses provider
**/ **/
function getAddressesProvider() external view returns (ILendingPoolAddressesProvider) { function getAddressesProvider() external override view returns (ILendingPoolAddressesProvider) {
return _addressesProvider; return _addressesProvider;
} }

View File

@ -188,10 +188,10 @@ contract LendingPoolConfigurator is VersionedInitializable {
ILendingPool internal pool; ILendingPool internal pool;
/** /**
* @dev only the lending pool manager can call functions affected by this modifier * @dev only the aave admin can call functions affected by this modifier
**/ **/
modifier onlyAaveAdmin { modifier onlyAaveAdmin {
require(addressesProvider.getAaveAdmin() == msg.sender, Errors.LPC_CALLER_NOT_AAVE_ADMIN); require(addressesProvider.getAaveAdmin() == msg.sender, Errors.CALLER_NOT_AAVE_ADMIN);
_; _;
} }

View File

@ -17,6 +17,10 @@ pragma solidity ^0.6.8;
* - P = Pausable * - P = Pausable
*/ */
library Errors { library Errors {
//common errors
string public constant CALLER_NOT_AAVE_ADMIN = '33'; // 'The caller must be the aave admin'
//contract specific errors
string public constant VL_AMOUNT_NOT_GREATER_THAN_0 = '1'; // 'Amount must be greater than 0' string public constant VL_AMOUNT_NOT_GREATER_THAN_0 = '1'; // 'Amount must be greater than 0'
string public constant VL_NO_ACTIVE_RESERVE = '2'; // 'Action requires an active reserve' string public constant VL_NO_ACTIVE_RESERVE = '2'; // 'Action requires an active reserve'
string public constant VL_RESERVE_FROZEN = '3'; // 'Action cannot be performed because the reserve is frozen' string public constant VL_RESERVE_FROZEN = '3'; // 'Action cannot be performed because the reserve is frozen'
@ -49,7 +53,6 @@ library Errors {
string public constant AT_CANNOT_GIVE_ALLVWANCE_TO_HIMSELF = '30'; // 'User cannot give allowance to himself' string public constant AT_CANNOT_GIVE_ALLVWANCE_TO_HIMSELF = '30'; // 'User cannot give allowance to himself'
string public constant AT_TRANSFER_AMOUNT_NOT_GT_0 = '31'; // 'Transferred amount needs to be greater than zero' string public constant AT_TRANSFER_AMOUNT_NOT_GT_0 = '31'; // 'Transferred amount needs to be greater than zero'
string public constant RL_RESERVE_ALREADY_INITIALIZED = '32'; // 'Reserve has already been initialized' string public constant RL_RESERVE_ALREADY_INITIALIZED = '32'; // 'Reserve has already been initialized'
string public constant LPC_CALLER_NOT_AAVE_ADMIN = '33'; // 'The caller must be the aave admin'
string public constant LPC_RESERVE_LIQUIDITY_NOT_0 = '34'; // 'The liquidity of the reserve needs to be 0' string public constant LPC_RESERVE_LIQUIDITY_NOT_0 = '34'; // 'The liquidity of the reserve needs to be 0'
string public constant LPC_INVALID_ATOKEN_POOL_ADDRESS = '35'; // 'The liquidity of the reserve needs to be 0' string public constant LPC_INVALID_ATOKEN_POOL_ADDRESS = '35'; // 'The liquidity of the reserve needs to be 0'
string public constant LPC_INVALID_STABLE_DEBT_TOKEN_POOL_ADDRESS = '36'; // 'The liquidity of the reserve needs to be 0' string public constant LPC_INVALID_STABLE_DEBT_TOKEN_POOL_ADDRESS = '36'; // 'The liquidity of the reserve needs to be 0'

View File

@ -0,0 +1,34 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import {ERC20} from '../../dependencies/openzeppelin/contracts/ERC20.sol';
/**
* @title ERC20Mintable
* @dev ERC20 minting logic
*/
contract MintableDelegationERC20 is ERC20 {
address public delegatee;
constructor(
string memory name,
string memory symbol,
uint8 decimals
) public ERC20(name, symbol) {
_setupDecimals(decimals);
}
/**
* @dev Function to mint tokensp
* @param value The amount of tokens to mint.
* @return A boolean that indicates if the operation was successful.
*/
function mint(uint256 value) public returns (bool) {
_mint(msg.sender, value);
return true;
}
function delegate(address delegateeAddress) external {
delegatee = delegateeAddress;
}
}

View File

@ -108,7 +108,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
//transfer event to track balances //transfer event to track balances
emit Transfer(user, address(0), amount); emit Transfer(user, address(0), amount);
emit Burn(_msgSender(), receiverOfUnderlying, amount, index); emit Burn(user, receiverOfUnderlying, amount, index);
} }
/** /**

View File

@ -0,0 +1,72 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import {AToken} from './AToken.sol';
import {ILendingPool} from '../interfaces/ILendingPool.sol';
import {Errors} from '../libraries/helpers/Errors.sol';
/**
* @title IDelegationToken
* @dev implements an interface for tokens that have a delegation function
**/
interface IDelegationToken {
function delegate(address delegatee) external;
}
/**
* @title Aave AToken with delegation capabilities
*
* @dev Implementation of the interest bearing token for the Aave protocol. This version of the aToken
* adds a function which gives the Aave protocol the ability to delegate voting power of the underlying asset.
* The underlying asset needs to be compatible with the COMP delegation interface
* @author Aave
*/
contract DelegationAwareAToken is AToken {
/**
* @dev only the aave admin can call this function
**/
modifier onlyAaveAdmin {
require(
_msgSender() == ILendingPool(POOL).getAddressesProvider().getAaveAdmin(),
Errors.CALLER_NOT_AAVE_ADMIN
);
_;
}
constructor(
ILendingPool pool,
address underlyingAssetAddress,
address reserveTreasury,
string memory tokenName,
string memory tokenSymbol,
address incentivesController
)
public
AToken(
pool,
underlyingAssetAddress,
reserveTreasury,
tokenName,
tokenSymbol,
incentivesController
)
{}
function initialize(
uint8 _underlyingAssetDecimals,
string calldata _tokenName,
string calldata _tokenSymbol
) external virtual override initializer {
_setName(_tokenName);
_setSymbol(_tokenSymbol);
_setDecimals(_underlyingAssetDecimals);
}
/**
* @dev delegates voting power of the underlying asset to a specific address
* @param delegatee the address that will receive the delegation
**/
function delegateUnderlyingTo(address delegatee) external onlyAaveAdmin {
IDelegationToken(UNDERLYING_ASSET_ADDRESS).delegate(delegatee);
}
}

View File

@ -142,11 +142,11 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
emit Mint( emit Mint(
user, user,
amount, amount,
previousBalance,
currentBalance, currentBalance,
balanceIncrease, balanceIncrease,
vars.newStableRate, vars.newStableRate,
vars.currentAvgStableRate vars.currentAvgStableRate,
vars.nextSupply
); );
return currentBalance == 0; return currentBalance == 0;
@ -166,16 +166,17 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
uint256 previousSupply = totalSupply(); uint256 previousSupply = totalSupply();
uint256 newStableRate = 0; uint256 newStableRate = 0;
uint256 nextSupply = 0;
//since the total supply and each single user debt accrue separately, //since the total supply and each single user debt accrue separately,
//there might be accumulation errors so that the last borrower repaying //there might be accumulation errors so that the last borrower repaying
//might actually try to repay more than the available debt supply. //might actually try to repay more than the available debt supply.
//in this case we simply set the total supply and the avg stable rate to 0 //in this case we simply set the total supply and the avg stable rate to 0
if (previousSupply <= amount) { if (previousSupply <= amount) {
newStableRate = _avgStableRate = 0; _avgStableRate = 0;
_totalSupply = 0; _totalSupply = 0;
} else { } else {
uint256 nextSupply = _totalSupply = previousSupply.sub(amount); nextSupply = _totalSupply = previousSupply.sub(amount);
newStableRate = _avgStableRate = _avgStableRate newStableRate = _avgStableRate = _avgStableRate
.rayMul(previousSupply.wadToRay()) .rayMul(previousSupply.wadToRay())
.sub(_usersData[user].rayMul(amount.wadToRay())) .sub(_usersData[user].rayMul(amount.wadToRay()))
@ -201,7 +202,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
// transfer event to track balances // transfer event to track balances
emit Transfer(user, address(0), amount); emit Transfer(user, address(0), amount);
emit Burn(user, amount, previousBalance, currentBalance, balanceIncrease, newStableRate); emit Burn(user, amount, currentBalance, balanceIncrease, newStableRate, nextSupply);
} }
/** /**

View File

@ -17,38 +17,38 @@ interface IStableDebtToken {
* @dev emitted when new stable debt is minted * @dev emitted when new stable debt is minted
* @param user the address of the user * @param user the address of the user
* @param amount the amount minted * @param amount the amount minted
* @param previousBalance the previous balance of the user
* @param currentBalance the current balance of the user * @param currentBalance the current balance of the user
* @param balanceIncrease the debt increase since the last update * @param balanceIncrease the the increase in balance since the last action of the user
* @param newRate the rate of the debt after the minting * @param newRate the rate of the debt after the minting
* @param avgStableRate the new average stable rate after the minting * @param avgStableRate the new average stable rate after the minting
* @param newTotalSupply the new total supply of the stable debt token after the action
**/ **/
event Mint( event Mint(
address indexed user, address indexed user,
uint256 amount, uint256 amount,
uint256 previousBalance,
uint256 currentBalance, uint256 currentBalance,
uint256 balanceIncrease, uint256 balanceIncrease,
uint256 newRate, uint256 newRate,
uint256 avgStableRate uint256 avgStableRate,
uint256 newTotalSupply
); );
/** /**
* @dev emitted when new stable debt is burned * @dev emitted when new stable debt is burned
* @param user the address of the user * @param user the address of the user
* @param amount the amount minted * @param amount the amount minted
* @param previousBalance the previous balance of the user
* @param currentBalance the current balance of the user * @param currentBalance the current balance of the user
* @param balanceIncrease the debt increase since the last update * @param balanceIncrease the the increase in balance since the last action of the user
* @param avgStableRate the new average stable rate after the minting * @param avgStableRate the new average stable rate after the minting
* @param newTotalSupply the new total supply of the stable debt token after the action
**/ **/
event Burn( event Burn(
address indexed user, address indexed user,
uint256 amount, uint256 amount,
uint256 previousBalance,
uint256 currentBalance, uint256 currentBalance,
uint256 balanceIncrease, uint256 balanceIncrease,
uint256 avgStableRate uint256 avgStableRate,
uint256 newTotalSupply
); );
/** /**

View File

@ -276,5 +276,17 @@
"address": "0xf784709d2317D872237C4bC22f867d1BAe2913AB", "address": "0xf784709d2317D872237C4bC22f867d1BAe2913AB",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
} }
},
"MintableDelegationERC20": {
"buidlerevm": {
"address": "0x77B0b5636fEA30eA79BB65AeCCdb599997A849A8",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"AToken": {
"buidlerevm": {
"address": "0x78Ee8Fb9fE5abD5e347Fc94c2fb85596d1f60e3c",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
} }
} }

View File

@ -23,6 +23,7 @@ import {
ATokensAndRatesHelperFactory, ATokensAndRatesHelperFactory,
ChainlinkProxyPriceProviderFactory, ChainlinkProxyPriceProviderFactory,
DefaultReserveInterestRateStrategyFactory, DefaultReserveInterestRateStrategyFactory,
DelegationAwareATokenFactory,
InitializableAdminUpgradeabilityProxyFactory, InitializableAdminUpgradeabilityProxyFactory,
LendingPoolAddressesProviderFactory, LendingPoolAddressesProviderFactory,
LendingPoolAddressesProviderRegistryFactory, LendingPoolAddressesProviderRegistryFactory,
@ -31,6 +32,7 @@ import {
LendingPoolFactory, LendingPoolFactory,
LendingPoolLibraryAddresses, LendingPoolLibraryAddresses,
LendingRateOracleFactory, LendingRateOracleFactory,
MintableDelegationErc20Factory,
MintableErc20Factory, MintableErc20Factory,
MockAggregatorFactory, MockAggregatorFactory,
MockATokenFactory, MockATokenFactory,
@ -50,6 +52,7 @@ import {withSaveAndVerify, registerContractInJsonDb, linkBytecode} from './contr
import {StableAndVariableTokensHelperFactory} from '../types/StableAndVariableTokensHelperFactory'; import {StableAndVariableTokensHelperFactory} from '../types/StableAndVariableTokensHelperFactory';
import {MockStableDebtToken} from '../types/MockStableDebtToken'; import {MockStableDebtToken} from '../types/MockStableDebtToken';
import {MockVariableDebtToken} from '../types/MockVariableDebtToken'; import {MockVariableDebtToken} from '../types/MockVariableDebtToken';
import {MintableDelegationErc20} from '../types/MintableDelegationErc20';
export const deployLendingPoolAddressesProvider = async (verify?: boolean) => export const deployLendingPoolAddressesProvider = async (verify?: boolean) =>
withSaveAndVerify( withSaveAndVerify(
@ -257,6 +260,16 @@ export const deployMintableERC20 = async (
verify verify
); );
export const deployMintableDelegationERC20 = async (
args: [string, string, string],
verify?: boolean
): Promise<MintableDelegationErc20> =>
withSaveAndVerify(
await new MintableDelegationErc20Factory(await getFirstSigner()).deploy(...args),
eContractid.MintableDelegationERC20,
args,
verify
);
export const deployDefaultReserveInterestRateStrategy = async ( export const deployDefaultReserveInterestRateStrategy = async (
args: [tEthereumAddress, string, string, string, string, string], args: [tEthereumAddress, string, string, string, string, string],
verify: boolean verify: boolean
@ -316,6 +329,32 @@ export const deployGenericAToken = async (
); );
}; };
export const deployDelegationAwareAToken = async (
[poolAddress, underlyingAssetAddress, name, symbol, incentivesController]: [
tEthereumAddress,
tEthereumAddress,
string,
string,
tEthereumAddress
],
verify: boolean
) => {
const args: [
tEthereumAddress,
tEthereumAddress,
tEthereumAddress,
string,
string,
tEthereumAddress
] = [poolAddress, underlyingAssetAddress, ZERO_ADDRESS, name, symbol, incentivesController];
return withSaveAndVerify(
await new DelegationAwareATokenFactory(await getFirstSigner()).deploy(...args),
eContractid.AToken,
args,
verify
);
};
export const deployAllMockTokens = async (verify?: boolean) => { export const deployAllMockTokens = async (verify?: boolean) => {
const tokens: {[symbol: string]: MockContract | MintableERC20} = {}; const tokens: {[symbol: string]: MockContract | MintableERC20} = {};

View File

@ -28,6 +28,7 @@ export enum eContractid {
Example = 'Example', Example = 'Example',
LendingPoolAddressesProvider = 'LendingPoolAddressesProvider', LendingPoolAddressesProvider = 'LendingPoolAddressesProvider',
MintableERC20 = 'MintableERC20', MintableERC20 = 'MintableERC20',
MintableDelegationERC20 = 'MintableDelegationERC20',
LendingPoolAddressesProviderRegistry = 'LendingPoolAddressesProviderRegistry', LendingPoolAddressesProviderRegistry = 'LendingPoolAddressesProviderRegistry',
LendingPoolParametersProvider = 'LendingPoolParametersProvider', LendingPoolParametersProvider = 'LendingPoolParametersProvider',
LendingPoolConfigurator = 'LendingPoolConfigurator', LendingPoolConfigurator = 'LendingPoolConfigurator',
@ -47,6 +48,7 @@ export enum eContractid {
WalletBalanceProvider = 'WalletBalanceProvider', WalletBalanceProvider = 'WalletBalanceProvider',
AToken = 'AToken', AToken = 'AToken',
MockAToken = 'MockAToken', MockAToken = 'MockAToken',
DelegationAwareAToken = 'DelegationAwareAToken',
MockStableDebtToken = 'MockStableDebtToken', MockStableDebtToken = 'MockStableDebtToken',
MockVariableDebtToken = 'MockVariableDebtToken', MockVariableDebtToken = 'MockVariableDebtToken',
AaveProtocolTestHelpers = 'AaveProtocolTestHelpers', AaveProtocolTestHelpers = 'AaveProtocolTestHelpers',
@ -75,6 +77,10 @@ export enum eContractid {
* - P = Pausable * - P = Pausable
*/ */
export enum ProtocolErrors { export enum ProtocolErrors {
//common errors
CALLER_NOT_AAVE_ADMIN = '33', // 'The caller must be the aave admin'
//contract specific errors
VL_AMOUNT_NOT_GREATER_THAN_0 = '1', // 'Amount must be greater than 0' VL_AMOUNT_NOT_GREATER_THAN_0 = '1', // 'Amount must be greater than 0'
VL_NO_ACTIVE_RESERVE = '2', // 'Action requires an active reserve' VL_NO_ACTIVE_RESERVE = '2', // 'Action requires an active reserve'
VL_RESERVE_FROZEN = '3', // 'Action requires an unfrozen reserve' VL_RESERVE_FROZEN = '3', // 'Action requires an unfrozen reserve'
@ -107,7 +113,6 @@ export enum ProtocolErrors {
AT_CANNOT_GIVE_ALLVWANCE_TO_HIMSELF = '30', // 'User cannot give allowance to himself' AT_CANNOT_GIVE_ALLVWANCE_TO_HIMSELF = '30', // 'User cannot give allowance to himself'
AT_TRANSFER_AMOUNT_NOT_GT_0 = '31', // 'Transferred amount needs to be greater than zero' AT_TRANSFER_AMOUNT_NOT_GT_0 = '31', // 'Transferred amount needs to be greater than zero'
RL_RESERVE_ALREADY_INITIALIZED = '32', // 'Reserve has already been initialized' RL_RESERVE_ALREADY_INITIALIZED = '32', // 'Reserve has already been initialized'
LPC_CALLER_NOT_AAVE_ADMIN = '33', // 'The caller must be the aave admin'
LPC_RESERVE_LIQUIDITY_NOT_0 = '34', // 'The liquidity of the reserve needs to be 0' LPC_RESERVE_LIQUIDITY_NOT_0 = '34', // 'The liquidity of the reserve needs to be 0'
LPC_INVALID_ATOKEN_POOL_ADDRESS = '35', // 'The liquidity of the reserve needs to be 0' LPC_INVALID_ATOKEN_POOL_ADDRESS = '35', // 'The liquidity of the reserve needs to be 0'
LPC_INVALID_STABLE_DEBT_TOKEN_POOL_ADDRESS = '36', // 'The liquidity of the reserve needs to be 0' LPC_INVALID_STABLE_DEBT_TOKEN_POOL_ADDRESS = '36', // 'The liquidity of the reserve needs to be 0'

View File

@ -11,7 +11,7 @@ const {expect} = require('chai');
makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
const { const {
LPC_CALLER_NOT_AAVE_ADMIN, CALLER_NOT_AAVE_ADMIN,
LPC_RESERVE_LIQUIDITY_NOT_0, LPC_RESERVE_LIQUIDITY_NOT_0,
RC_INVALID_LTV, RC_INVALID_LTV,
RC_INVALID_LIQ_THRESHOLD, RC_INVALID_LIQ_THRESHOLD,
@ -87,16 +87,16 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
const {configurator, users, weth} = testEnv; const {configurator, users, weth} = testEnv;
await expect( await expect(
configurator.connect(users[2].signer).deactivateReserve(weth.address), configurator.connect(users[2].signer).deactivateReserve(weth.address),
LPC_CALLER_NOT_AAVE_ADMIN CALLER_NOT_AAVE_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_AAVE_ADMIN); ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN);
}); });
it('Check the onlyAaveAdmin on activateReserve ', async () => { it('Check the onlyAaveAdmin on activateReserve ', async () => {
const {configurator, users, weth} = testEnv; const {configurator, users, weth} = testEnv;
await expect( await expect(
configurator.connect(users[2].signer).activateReserve(weth.address), configurator.connect(users[2].signer).activateReserve(weth.address),
LPC_CALLER_NOT_AAVE_ADMIN CALLER_NOT_AAVE_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_AAVE_ADMIN); ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN);
}); });
it('Freezes the ETH reserve', async () => { it('Freezes the ETH reserve', async () => {
@ -156,16 +156,16 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
const {configurator, users, weth} = testEnv; const {configurator, users, weth} = testEnv;
await expect( await expect(
configurator.connect(users[2].signer).freezeReserve(weth.address), configurator.connect(users[2].signer).freezeReserve(weth.address),
LPC_CALLER_NOT_AAVE_ADMIN CALLER_NOT_AAVE_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_AAVE_ADMIN); ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN);
}); });
it('Check the onlyAaveAdmin on unfreezeReserve ', async () => { it('Check the onlyAaveAdmin on unfreezeReserve ', async () => {
const {configurator, users, weth} = testEnv; const {configurator, users, weth} = testEnv;
await expect( await expect(
configurator.connect(users[2].signer).unfreezeReserve(weth.address), configurator.connect(users[2].signer).unfreezeReserve(weth.address),
LPC_CALLER_NOT_AAVE_ADMIN CALLER_NOT_AAVE_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_AAVE_ADMIN); ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN);
}); });
it('Deactivates the ETH reserve for borrowing', async () => { it('Deactivates the ETH reserve for borrowing', async () => {
@ -228,16 +228,16 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
const {configurator, users, weth} = testEnv; const {configurator, users, weth} = testEnv;
await expect( await expect(
configurator.connect(users[2].signer).disableBorrowingOnReserve(weth.address), configurator.connect(users[2].signer).disableBorrowingOnReserve(weth.address),
LPC_CALLER_NOT_AAVE_ADMIN CALLER_NOT_AAVE_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_AAVE_ADMIN); ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN);
}); });
it('Check the onlyAaveAdmin on enableBorrowingOnReserve ', async () => { it('Check the onlyAaveAdmin on enableBorrowingOnReserve ', async () => {
const {configurator, users, weth} = testEnv; const {configurator, users, weth} = testEnv;
await expect( await expect(
configurator.connect(users[2].signer).enableBorrowingOnReserve(weth.address, true), configurator.connect(users[2].signer).enableBorrowingOnReserve(weth.address, true),
LPC_CALLER_NOT_AAVE_ADMIN CALLER_NOT_AAVE_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_AAVE_ADMIN); ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN);
}); });
it('Deactivates the ETH reserve as collateral', async () => { it('Deactivates the ETH reserve as collateral', async () => {
@ -300,8 +300,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
configurator configurator
.connect(users[2].signer) .connect(users[2].signer)
.configureReserveAsCollateral(weth.address, '7500', '8000', '10500'), .configureReserveAsCollateral(weth.address, '7500', '8000', '10500'),
LPC_CALLER_NOT_AAVE_ADMIN CALLER_NOT_AAVE_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_AAVE_ADMIN); ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN);
}); });
it('Disable stable borrow rate on the ETH reserve', async () => { it('Disable stable borrow rate on the ETH reserve', async () => {
@ -360,16 +360,16 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
const {configurator, users, weth} = testEnv; const {configurator, users, weth} = testEnv;
await expect( await expect(
configurator.connect(users[2].signer).disableReserveStableRate(weth.address), configurator.connect(users[2].signer).disableReserveStableRate(weth.address),
LPC_CALLER_NOT_AAVE_ADMIN CALLER_NOT_AAVE_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_AAVE_ADMIN); ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN);
}); });
it('Check the onlyAaveAdmin on enableReserveStableRate', async () => { it('Check the onlyAaveAdmin on enableReserveStableRate', async () => {
const {configurator, users, weth} = testEnv; const {configurator, users, weth} = testEnv;
await expect( await expect(
configurator.connect(users[2].signer).enableReserveStableRate(weth.address), configurator.connect(users[2].signer).enableReserveStableRate(weth.address),
LPC_CALLER_NOT_AAVE_ADMIN CALLER_NOT_AAVE_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_AAVE_ADMIN); ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN);
}); });
it('Changes LTV of the reserve', async () => { it('Changes LTV of the reserve', async () => {
@ -402,8 +402,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
const {configurator, users, weth} = testEnv; const {configurator, users, weth} = testEnv;
await expect( await expect(
configurator.connect(users[2].signer).setLtv(weth.address, '75'), configurator.connect(users[2].signer).setLtv(weth.address, '75'),
LPC_CALLER_NOT_AAVE_ADMIN CALLER_NOT_AAVE_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_AAVE_ADMIN); ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN);
}); });
it('Changes the reserve factor of the reserve', async () => { it('Changes the reserve factor of the reserve', async () => {
@ -436,8 +436,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
const {configurator, users, weth} = testEnv; const {configurator, users, weth} = testEnv;
await expect( await expect(
configurator.connect(users[2].signer).setReserveFactor(weth.address, '2000'), configurator.connect(users[2].signer).setReserveFactor(weth.address, '2000'),
LPC_CALLER_NOT_AAVE_ADMIN CALLER_NOT_AAVE_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_AAVE_ADMIN); ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN);
}); });
it('Changes liquidation threshold of the reserve', async () => { it('Changes liquidation threshold of the reserve', async () => {
@ -470,8 +470,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
const {configurator, users, weth} = testEnv; const {configurator, users, weth} = testEnv;
await expect( await expect(
configurator.connect(users[2].signer).setLiquidationThreshold(weth.address, '80'), configurator.connect(users[2].signer).setLiquidationThreshold(weth.address, '80'),
LPC_CALLER_NOT_AAVE_ADMIN CALLER_NOT_AAVE_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_AAVE_ADMIN); ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN);
}); });
it('Changes liquidation bonus of the reserve', async () => { it('Changes liquidation bonus of the reserve', async () => {
@ -504,24 +504,24 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
const {configurator, users, weth} = testEnv; const {configurator, users, weth} = testEnv;
await expect( await expect(
configurator.connect(users[2].signer).setLiquidationBonus(weth.address, '80'), configurator.connect(users[2].signer).setLiquidationBonus(weth.address, '80'),
LPC_CALLER_NOT_AAVE_ADMIN CALLER_NOT_AAVE_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_AAVE_ADMIN); ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN);
}); });
it('Check the onlyAaveAdmin on setReserveDecimals', async () => { it('Check the onlyAaveAdmin on setReserveDecimals', async () => {
const {configurator, users, weth} = testEnv; const {configurator, users, weth} = testEnv;
await expect( await expect(
configurator.connect(users[2].signer).setReserveDecimals(weth.address, '80'), configurator.connect(users[2].signer).setReserveDecimals(weth.address, '80'),
LPC_CALLER_NOT_AAVE_ADMIN CALLER_NOT_AAVE_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_AAVE_ADMIN); ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN);
}); });
it('Check the onlyAaveAdmin on setLiquidationBonus', async () => { it('Check the onlyAaveAdmin on setLiquidationBonus', async () => {
const {configurator, users, weth} = testEnv; const {configurator, users, weth} = testEnv;
await expect( await expect(
configurator.connect(users[2].signer).setLiquidationBonus(weth.address, '80'), configurator.connect(users[2].signer).setLiquidationBonus(weth.address, '80'),
LPC_CALLER_NOT_AAVE_ADMIN CALLER_NOT_AAVE_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_AAVE_ADMIN); ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN);
}); });
it('Reverts when trying to disable the DAI reserve with liquidity on it', async () => { it('Reverts when trying to disable the DAI reserve with liquidity on it', async () => {

View File

@ -0,0 +1,58 @@
import {MAX_UINT_AMOUNT, ZERO_ADDRESS} from '../helpers/constants';
import {BUIDLEREVM_CHAINID} from '../helpers/buidler-constants';
import {buildPermitParams, getSignatureFromTypedData} from '../helpers/contracts-helpers';
import {expect} from 'chai';
import {ethers} from 'ethers';
import {eEthereumNetwork, ProtocolErrors} from '../helpers/types';
import {makeSuite, TestEnv} from './helpers/make-suite';
import {BRE} from '../helpers/misc-utils';
import {
ConfigNames,
getATokenDomainSeparatorPerNetwork,
loadPoolConfig,
} from '../helpers/configuration';
import {waitForTx} from '../helpers/misc-utils';
import {
deployDelegationAwareAToken,
deployMintableDelegationERC20,
} from '../helpers/contracts-deployments';
import {DelegationAwareATokenFactory} from '../types';
import {DelegationAwareAToken} from '../types/DelegationAwareAToken';
import {MintableDelegationErc20} from '../types/MintableDelegationErc20';
const {parseEther} = ethers.utils;
makeSuite('AToken: underlying delegation', (testEnv: TestEnv) => {
const poolConfig = loadPoolConfig(ConfigNames.Commons);
let delegationAToken = <DelegationAwareAToken>{};
let delegationERC20 = <MintableDelegationErc20>{};
it('Deploys a new MintableDelegationERC20 and a DelegationAwareAToken', async () => {
const {pool} = testEnv;
delegationERC20 = await deployMintableDelegationERC20(['DEL', 'DEL', '18']);
delegationAToken = await deployDelegationAwareAToken(
[pool.address, delegationERC20.address, 'aDEL', 'aDEL', ZERO_ADDRESS],
false
);
});
it('Tries to delegate with the caller not being the Aave admin', async () => {
const {users} = testEnv;
await expect(
delegationAToken.connect(users[1].signer).delegateUnderlyingTo(users[2].address)
).to.be.revertedWith(ProtocolErrors.CALLER_NOT_AAVE_ADMIN);
});
it('Tries to delegate to user 2', async () => {
const {users} = testEnv;
await delegationAToken.delegateUnderlyingTo(users[2].address);
const delegateeAddress = await delegationERC20.delegatee();
expect(delegateeAddress).to.be.equal(users[2].address);
});
});

View File

@ -19,7 +19,7 @@ import {
} from '../helpers/contracts-deployments'; } from '../helpers/contracts-deployments';
makeSuite('Upgradeability', (testEnv: TestEnv) => { makeSuite('Upgradeability', (testEnv: TestEnv) => {
const {LPC_CALLER_NOT_AAVE_ADMIN} = ProtocolErrors; const {CALLER_NOT_AAVE_ADMIN} = ProtocolErrors;
let newATokenAddress: string; let newATokenAddress: string;
let newStableTokenAddress: string; let newStableTokenAddress: string;
let newVariableTokenAddress: string; let newVariableTokenAddress: string;
@ -61,7 +61,7 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
await expect( await expect(
configurator.connect(users[1].signer).updateAToken(dai.address, newATokenAddress) configurator.connect(users[1].signer).updateAToken(dai.address, newATokenAddress)
).to.be.revertedWith(LPC_CALLER_NOT_AAVE_ADMIN); ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN);
}); });
it('Upgrades the DAI Atoken implementation ', async () => { it('Upgrades the DAI Atoken implementation ', async () => {
@ -83,7 +83,7 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
configurator configurator
.connect(users[1].signer) .connect(users[1].signer)
.updateStableDebtToken(dai.address, newStableTokenAddress) .updateStableDebtToken(dai.address, newStableTokenAddress)
).to.be.revertedWith(LPC_CALLER_NOT_AAVE_ADMIN); ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN);
}); });
it('Upgrades the DAI stable debt token implementation ', async () => { it('Upgrades the DAI stable debt token implementation ', async () => {
@ -109,7 +109,7 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
configurator configurator
.connect(users[1].signer) .connect(users[1].signer)
.updateVariableDebtToken(dai.address, newVariableTokenAddress) .updateVariableDebtToken(dai.address, newVariableTokenAddress)
).to.be.revertedWith(LPC_CALLER_NOT_AAVE_ADMIN); ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN);
}); });
it('Upgrades the DAI variable debt token implementation ', async () => { it('Upgrades the DAI variable debt token implementation ', async () => {