diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index c6da3c32..83e40cd9 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -4,6 +4,7 @@ pragma solidity ^0.6.8; import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol'; import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; +import {ILendingPoolAddressesProvider} from './ILendingPoolAddressesProvider.sol'; pragma experimental ABIEncoderV2; @@ -368,6 +369,8 @@ interface ILendingPool { function getReservesList() external view returns (address[] memory); + function getAddressesProvider() external view returns (ILendingPoolAddressesProvider); + /** * @dev Set the _pause state * @param val the boolean value to set the current pause state of LendingPool diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 23bf3e94..cb7f3682 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -753,7 +753,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage /** * @dev returns the addresses provider **/ - function getAddressesProvider() external view returns (ILendingPoolAddressesProvider) { + function getAddressesProvider() external override view returns (ILendingPoolAddressesProvider) { return _addressesProvider; } diff --git a/contracts/lendingpool/LendingPoolConfigurator.sol b/contracts/lendingpool/LendingPoolConfigurator.sol index 8f9c28dd..b336ed51 100644 --- a/contracts/lendingpool/LendingPoolConfigurator.sol +++ b/contracts/lendingpool/LendingPoolConfigurator.sol @@ -188,10 +188,10 @@ contract LendingPoolConfigurator is VersionedInitializable { 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 { - require(addressesProvider.getAaveAdmin() == msg.sender, Errors.LPC_CALLER_NOT_AAVE_ADMIN); + require(addressesProvider.getAaveAdmin() == msg.sender, Errors.CALLER_NOT_AAVE_ADMIN); _; } diff --git a/contracts/libraries/helpers/Errors.sol b/contracts/libraries/helpers/Errors.sol index 3b37e91a..a0a65762 100644 --- a/contracts/libraries/helpers/Errors.sol +++ b/contracts/libraries/helpers/Errors.sol @@ -17,6 +17,10 @@ pragma solidity ^0.6.8; * - P = Pausable */ 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_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' @@ -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_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 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_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' diff --git a/contracts/tokenization/DelegationAwareAToken.sol b/contracts/tokenization/DelegationAwareAToken.sol new file mode 100644 index 00000000..69cd1942 --- /dev/null +++ b/contracts/tokenization/DelegationAwareAToken.sol @@ -0,0 +1,76 @@ +// 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 underlying assets + * that are compatible with the Compound 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 getRevision() internal override pure returns (uint256) { + return 0x1; + } + + 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); + } +}