mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
- Implemented protocol changes to enable re-usage of implementations.
This commit is contained in:
parent
29448c19c1
commit
80fd095723
contracts
deployments
interfaces
IAToken.solIInitializableAToken.solIInitializableDebtToken.solILendingPoolConfigurator.solIStableDebtToken.solITokenConfiguration.solIVariableDebtToken.sol
mocks/upgradeability
protocol
|
@ -20,6 +20,20 @@ contract ATokensAndRatesHelper is Ownable {
|
|||
address private poolConfigurator;
|
||||
event deployedContracts(address aToken, address strategy);
|
||||
|
||||
struct InitDeploymentInput {
|
||||
address asset;
|
||||
uint256[6] rates;
|
||||
}
|
||||
|
||||
struct ConfigureReserveInput {
|
||||
address asset;
|
||||
uint256 baseLTV;
|
||||
uint256 liquidationThreshold;
|
||||
uint256 liquidationBonus;
|
||||
uint256 reserveFactor;
|
||||
bool stableBorrowingEnabled;
|
||||
}
|
||||
|
||||
constructor(
|
||||
address payable _pool,
|
||||
address _addressesProvider,
|
||||
|
@ -30,93 +44,40 @@ contract ATokensAndRatesHelper is Ownable {
|
|||
poolConfigurator = _poolConfigurator;
|
||||
}
|
||||
|
||||
function initDeployment(
|
||||
address[] calldata assets,
|
||||
string[] calldata symbols,
|
||||
uint256[6][] calldata rates,
|
||||
address treasuryAddress,
|
||||
address incentivesController
|
||||
) external onlyOwner {
|
||||
require(assets.length == symbols.length, 't Arrays not same length');
|
||||
require(rates.length == symbols.length, 'r Arrays not same length');
|
||||
for (uint256 i = 0; i < assets.length; i++) {
|
||||
function initDeployment(InitDeploymentInput[] calldata inputParams) external onlyOwner {
|
||||
for (uint256 i = 0; i < inputParams.length; i++) {
|
||||
emit deployedContracts(
|
||||
address(
|
||||
new AToken(
|
||||
LendingPool(pool),
|
||||
assets[i],
|
||||
treasuryAddress,
|
||||
StringLib.concat('Aave interest bearing ', symbols[i]),
|
||||
StringLib.concat('a', symbols[i]),
|
||||
incentivesController
|
||||
)
|
||||
),
|
||||
address(new AToken()),
|
||||
address(
|
||||
new DefaultReserveInterestRateStrategy(
|
||||
LendingPoolAddressesProvider(addressesProvider),
|
||||
rates[i][0],
|
||||
rates[i][1],
|
||||
rates[i][2],
|
||||
rates[i][3],
|
||||
rates[i][4],
|
||||
rates[i][5]
|
||||
inputParams[i].rates[0],
|
||||
inputParams[i].rates[1],
|
||||
inputParams[i].rates[2],
|
||||
inputParams[i].rates[3],
|
||||
inputParams[i].rates[4],
|
||||
inputParams[i].rates[5]
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function initReserve(
|
||||
address[] calldata stables,
|
||||
address[] calldata variables,
|
||||
address[] calldata aTokens,
|
||||
address[] calldata strategies,
|
||||
uint8[] calldata reserveDecimals
|
||||
) external onlyOwner {
|
||||
require(variables.length == stables.length);
|
||||
require(aTokens.length == stables.length);
|
||||
require(strategies.length == stables.length);
|
||||
require(reserveDecimals.length == stables.length);
|
||||
|
||||
for (uint256 i = 0; i < stables.length; i++) {
|
||||
LendingPoolConfigurator(poolConfigurator).initReserve(
|
||||
aTokens[i],
|
||||
stables[i],
|
||||
variables[i],
|
||||
reserveDecimals[i],
|
||||
strategies[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function configureReserves(
|
||||
address[] calldata assets,
|
||||
uint256[] calldata baseLTVs,
|
||||
uint256[] calldata liquidationThresholds,
|
||||
uint256[] calldata liquidationBonuses,
|
||||
uint256[] calldata reserveFactors,
|
||||
bool[] calldata stableBorrowingEnabled
|
||||
) external onlyOwner {
|
||||
require(baseLTVs.length == assets.length);
|
||||
require(liquidationThresholds.length == assets.length);
|
||||
require(liquidationBonuses.length == assets.length);
|
||||
require(stableBorrowingEnabled.length == assets.length);
|
||||
require(reserveFactors.length == assets.length);
|
||||
|
||||
function configureReserves(ConfigureReserveInput[] calldata inputParams) external onlyOwner {
|
||||
LendingPoolConfigurator configurator = LendingPoolConfigurator(poolConfigurator);
|
||||
for (uint256 i = 0; i < assets.length; i++) {
|
||||
for (uint256 i = 0; i < inputParams.length; i++) {
|
||||
configurator.configureReserveAsCollateral(
|
||||
assets[i],
|
||||
baseLTVs[i],
|
||||
liquidationThresholds[i],
|
||||
liquidationBonuses[i]
|
||||
inputParams[i].asset,
|
||||
inputParams[i].baseLTV,
|
||||
inputParams[i].liquidationThreshold,
|
||||
inputParams[i].liquidationBonus
|
||||
);
|
||||
|
||||
configurator.enableBorrowingOnReserve(
|
||||
assets[i],
|
||||
stableBorrowingEnabled[i]
|
||||
inputParams[i].asset,
|
||||
inputParams[i].stableBorrowingEnabled
|
||||
);
|
||||
configurator.setReserveFactor(assets[i], reserveFactors[i]);
|
||||
configurator.setReserveFactor(inputParams[i].asset, inputParams[i].reserveFactor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,34 +18,11 @@ contract StableAndVariableTokensHelper is Ownable {
|
|||
addressesProvider = _addressesProvider;
|
||||
}
|
||||
|
||||
function initDeployment(
|
||||
address[] calldata tokens,
|
||||
string[] calldata symbols,
|
||||
address incentivesController
|
||||
) external onlyOwner {
|
||||
function initDeployment(address[] calldata tokens, string[] calldata symbols) external onlyOwner {
|
||||
require(tokens.length == symbols.length, 'Arrays not same length');
|
||||
require(pool != address(0), 'Pool can not be zero address');
|
||||
for (uint256 i = 0; i < tokens.length; i++) {
|
||||
emit deployedContracts(
|
||||
address(
|
||||
new StableDebtToken(
|
||||
pool,
|
||||
tokens[i],
|
||||
StringLib.concat('Aave stable debt bearing ', symbols[i]),
|
||||
StringLib.concat('stableDebt', symbols[i]),
|
||||
incentivesController
|
||||
)
|
||||
),
|
||||
address(
|
||||
new VariableDebtToken(
|
||||
pool,
|
||||
tokens[i],
|
||||
StringLib.concat('Aave variable debt bearing ', symbols[i]),
|
||||
StringLib.concat('variableDebt', symbols[i]),
|
||||
incentivesController
|
||||
)
|
||||
)
|
||||
);
|
||||
emit deployedContracts(address(new StableDebtToken()), address(new VariableDebtToken()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,10 @@ pragma solidity 0.6.12;
|
|||
|
||||
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {IScaledBalanceToken} from './IScaledBalanceToken.sol';
|
||||
import {IInitializableAToken} from './IInitializableAToken.sol';
|
||||
import {IAaveIncentivesController} from './IAaveIncentivesController.sol';
|
||||
|
||||
interface IAToken is IERC20, IScaledBalanceToken {
|
||||
interface IAToken is IERC20, IScaledBalanceToken, IInitializableAToken {
|
||||
/**
|
||||
* @dev Emitted after the mint action
|
||||
* @param from The address performing the mint
|
||||
|
@ -85,4 +87,9 @@ interface IAToken is IERC20, IScaledBalanceToken {
|
|||
* @return The amount transferred
|
||||
**/
|
||||
function transferUnderlyingTo(address user, uint256 amount) external returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the incentives controller contract
|
||||
**/
|
||||
function getIncentivesController() external view returns (IAaveIncentivesController);
|
||||
}
|
||||
|
|
32
contracts/interfaces/IInitializableAToken.sol
Normal file
32
contracts/interfaces/IInitializableAToken.sol
Normal file
|
@ -0,0 +1,32 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {ILendingPool} from './ILendingPool.sol';
|
||||
import {IAaveIncentivesController} from './IAaveIncentivesController.sol';
|
||||
|
||||
/**
|
||||
* @title IInitializableAToken
|
||||
* @notice Interface for the initialize function on AToken
|
||||
* @author Aave
|
||||
**/
|
||||
interface IInitializableAToken {
|
||||
/**
|
||||
* @dev Initializes the aToken
|
||||
* @param pool The address of the lending pool where this aToken will be used
|
||||
* @param treasury The address of the Aave treasury, receiving the fees on this aToken
|
||||
* @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH)
|
||||
* @param incentivesController The smart contract managing potential incentives distribution
|
||||
* @param aTokenDecimals The decimals of the aToken, same as the underlying asset's
|
||||
* @param aTokenName The name of the aToken
|
||||
* @param aTokenSymbol The symbol of the aToken
|
||||
*/
|
||||
function initialize(
|
||||
ILendingPool pool,
|
||||
address treasury,
|
||||
address underlyingAsset,
|
||||
IAaveIncentivesController incentivesController,
|
||||
uint8 aTokenDecimals,
|
||||
string calldata aTokenName,
|
||||
string calldata aTokenSymbol
|
||||
) external;
|
||||
}
|
30
contracts/interfaces/IInitializableDebtToken.sol
Normal file
30
contracts/interfaces/IInitializableDebtToken.sol
Normal file
|
@ -0,0 +1,30 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {ILendingPool} from './ILendingPool.sol';
|
||||
import {IAaveIncentivesController} from './IAaveIncentivesController.sol';
|
||||
|
||||
/**
|
||||
* @title IInitializableDebtToken
|
||||
* @notice Interface for the initialize function common between debt tokens
|
||||
* @author Aave
|
||||
**/
|
||||
interface IInitializableDebtToken {
|
||||
/**
|
||||
* @dev Initializes the debt token.
|
||||
* @param pool The address of the lending pool where this aToken will be used
|
||||
* @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH)
|
||||
* @param incentivesController The smart contract managing potential incentives distribution
|
||||
* @param debtTokenDecimals The decimals of the debtToken, same as the underlying asset's
|
||||
* @param debtTokenName The name of the token
|
||||
* @param debtTokenSymbol The symbol of the token
|
||||
*/
|
||||
function initialize(
|
||||
ILendingPool pool,
|
||||
address underlyingAsset,
|
||||
IAaveIncentivesController incentivesController,
|
||||
uint8 debtTokenDecimals,
|
||||
string memory debtTokenName,
|
||||
string memory debtTokenSymbol
|
||||
) external;
|
||||
}
|
176
contracts/interfaces/ILendingPoolConfigurator.sol
Normal file
176
contracts/interfaces/ILendingPoolConfigurator.sol
Normal file
|
@ -0,0 +1,176 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.12;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
interface ILendingPoolConfigurator {
|
||||
struct InitReserveInput {
|
||||
address aTokenImpl;
|
||||
address stableDebtTokenImpl;
|
||||
address variableDebtTokenImpl;
|
||||
uint8 underlyingAssetDecimals;
|
||||
address interestRateStrategyAddress;
|
||||
address underlyingAsset;
|
||||
address treasury;
|
||||
address incentivesController;
|
||||
string underlyingAssetName;
|
||||
string aTokenName;
|
||||
string aTokenSymbol;
|
||||
string variableDebtTokenName;
|
||||
string variableDebtTokenSymbol;
|
||||
string stableDebtTokenName;
|
||||
string stableDebtTokenSymbol;
|
||||
}
|
||||
|
||||
struct UpdateATokenInput {
|
||||
address asset;
|
||||
address treasury;
|
||||
address incentivesController;
|
||||
string name;
|
||||
string symbol;
|
||||
address implementation;
|
||||
}
|
||||
|
||||
struct UpdateDebtTokenInput {
|
||||
address asset;
|
||||
address incentivesController;
|
||||
string name;
|
||||
string symbol;
|
||||
address implementation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Emitted when a reserve is initialized.
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param aToken The address of the associated aToken contract
|
||||
* @param stableDebtToken The address of the associated stable rate debt token
|
||||
* @param variableDebtToken The address of the associated variable rate debt token
|
||||
* @param interestRateStrategyAddress The address of the interest rate strategy for the reserve
|
||||
**/
|
||||
event ReserveInitialized(
|
||||
address indexed asset,
|
||||
address indexed aToken,
|
||||
address stableDebtToken,
|
||||
address variableDebtToken,
|
||||
address interestRateStrategyAddress
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev Emitted when borrowing is enabled on a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param stableRateEnabled True if stable rate borrowing is enabled, false otherwise
|
||||
**/
|
||||
event BorrowingEnabledOnReserve(address indexed asset, bool stableRateEnabled);
|
||||
|
||||
/**
|
||||
* @dev Emitted when borrowing is disabled on a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event BorrowingDisabledOnReserve(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev Emitted when the collateralization risk parameters for the specified asset are updated.
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param ltv The loan to value of the asset when used as collateral
|
||||
* @param liquidationThreshold The threshold at which loans using this asset as collateral will be considered undercollateralized
|
||||
* @param liquidationBonus The bonus liquidators receive to liquidate this asset
|
||||
**/
|
||||
event CollateralConfigurationChanged(
|
||||
address indexed asset,
|
||||
uint256 ltv,
|
||||
uint256 liquidationThreshold,
|
||||
uint256 liquidationBonus
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev Emitted when stable rate borrowing is enabled on a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event StableRateEnabledOnReserve(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev Emitted when stable rate borrowing is disabled on a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event StableRateDisabledOnReserve(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev Emitted when a reserve is activated
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event ReserveActivated(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev Emitted when a reserve is deactivated
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event ReserveDeactivated(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev Emitted when a reserve is frozen
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event ReserveFrozen(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev Emitted when a reserve is unfrozen
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event ReserveUnfrozen(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev Emitted when a reserve factor is updated
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param factor The new reserve factor
|
||||
**/
|
||||
event ReserveFactorChanged(address indexed asset, uint256 factor);
|
||||
|
||||
/**
|
||||
* @dev Emitted when the reserve decimals are updated
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param decimals The new decimals
|
||||
**/
|
||||
event ReserveDecimalsChanged(address indexed asset, uint256 decimals);
|
||||
|
||||
/**
|
||||
* @dev Emitted when a reserve interest strategy contract is updated
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param strategy The new address of the interest strategy contract
|
||||
**/
|
||||
event ReserveInterestRateStrategyChanged(address indexed asset, address strategy);
|
||||
|
||||
/**
|
||||
* @dev Emitted when an aToken implementation is upgraded
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param proxy The aToken proxy address
|
||||
* @param implementation The new aToken implementation
|
||||
**/
|
||||
event ATokenUpgraded(
|
||||
address indexed asset,
|
||||
address indexed proxy,
|
||||
address indexed implementation
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev Emitted when the implementation of a stable debt token is upgraded
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param proxy The stable debt token proxy address
|
||||
* @param implementation The new aToken implementation
|
||||
**/
|
||||
event StableDebtTokenUpgraded(
|
||||
address indexed asset,
|
||||
address indexed proxy,
|
||||
address indexed implementation
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev Emitted when the implementation of a variable debt token is upgraded
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param proxy The variable debt token proxy address
|
||||
* @param implementation The new aToken implementation
|
||||
**/
|
||||
event VariableDebtTokenUpgraded(
|
||||
address indexed asset,
|
||||
address indexed proxy,
|
||||
address indexed implementation
|
||||
);
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {IInitializableDebtToken} from './IInitializableDebtToken.sol';
|
||||
import {IAaveIncentivesController} from './IAaveIncentivesController.sol';
|
||||
|
||||
/**
|
||||
* @title IStableDebtToken
|
||||
* @notice Defines the interface for the stable debt token
|
||||
|
@ -8,7 +11,7 @@ pragma solidity 0.6.12;
|
|||
* @author Aave
|
||||
**/
|
||||
|
||||
interface IStableDebtToken {
|
||||
interface IStableDebtToken is IInitializableDebtToken {
|
||||
/**
|
||||
* @dev Emitted when new stable debt is minted
|
||||
* @param user The address of the user who triggered the minting
|
||||
|
@ -122,4 +125,9 @@ interface IStableDebtToken {
|
|||
* @return The debt balance of the user since the last burn/mint action
|
||||
**/
|
||||
function principalBalanceOf(address user) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the incentives controller contract
|
||||
**/
|
||||
function getIncentivesController() external view returns (IAaveIncentivesController);
|
||||
}
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.12;
|
||||
|
||||
/**
|
||||
* @title ITokenConfiguration
|
||||
* @author Aave
|
||||
* @dev Common interface between aTokens and debt tokens to fetch the
|
||||
* token configuration
|
||||
**/
|
||||
interface ITokenConfiguration {
|
||||
function UNDERLYING_ASSET_ADDRESS() external view returns (address);
|
||||
|
||||
function POOL() external view returns (address);
|
||||
}
|
|
@ -2,13 +2,15 @@
|
|||
pragma solidity 0.6.12;
|
||||
|
||||
import {IScaledBalanceToken} from './IScaledBalanceToken.sol';
|
||||
import {IInitializableDebtToken} from './IInitializableDebtToken.sol';
|
||||
import {IAaveIncentivesController} from './IAaveIncentivesController.sol';
|
||||
|
||||
/**
|
||||
* @title IVariableDebtToken
|
||||
* @author Aave
|
||||
* @notice Defines the basic interface for a variable debt token.
|
||||
**/
|
||||
interface IVariableDebtToken is IScaledBalanceToken {
|
||||
interface IVariableDebtToken is IScaledBalanceToken, IInitializableDebtToken {
|
||||
/**
|
||||
* @dev Emitted after the mint action
|
||||
* @param from The address performing the mint
|
||||
|
@ -52,4 +54,9 @@ interface IVariableDebtToken is IScaledBalanceToken {
|
|||
uint256 amount,
|
||||
uint256 index
|
||||
) external;
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the incentives controller contract
|
||||
**/
|
||||
function getIncentivesController() external view returns (IAaveIncentivesController);
|
||||
}
|
||||
|
|
|
@ -2,39 +2,11 @@
|
|||
pragma solidity 0.6.12;
|
||||
|
||||
import {AToken} from '../../protocol/tokenization/AToken.sol';
|
||||
import {LendingPool} from '../../protocol/lendingpool/LendingPool.sol';
|
||||
import {ILendingPool} from '../../interfaces/ILendingPool.sol';
|
||||
import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol';
|
||||
|
||||
contract MockAToken is AToken {
|
||||
constructor(
|
||||
LendingPool pool,
|
||||
address underlyingAssetAddress,
|
||||
address reserveTreasury,
|
||||
string memory tokenName,
|
||||
string memory tokenSymbol,
|
||||
address incentivesController
|
||||
)
|
||||
public
|
||||
AToken(
|
||||
pool,
|
||||
underlyingAssetAddress,
|
||||
reserveTreasury,
|
||||
tokenName,
|
||||
tokenSymbol,
|
||||
incentivesController
|
||||
)
|
||||
{}
|
||||
|
||||
function getRevision() internal pure override returns (uint256) {
|
||||
return 0x2;
|
||||
}
|
||||
|
||||
function initialize(
|
||||
uint8 _underlyingAssetDecimals,
|
||||
string calldata _tokenName,
|
||||
string calldata _tokenSymbol
|
||||
) external virtual override initializer {
|
||||
_setName(_tokenName);
|
||||
_setSymbol(_tokenSymbol);
|
||||
_setDecimals(_underlyingAssetDecimals);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,17 +4,6 @@ pragma solidity 0.6.12;
|
|||
import {StableDebtToken} from '../../protocol/tokenization/StableDebtToken.sol';
|
||||
|
||||
contract MockStableDebtToken is StableDebtToken {
|
||||
constructor(
|
||||
address _pool,
|
||||
address _underlyingAssetAddress,
|
||||
string memory _tokenName,
|
||||
string memory _tokenSymbol,
|
||||
address incentivesController
|
||||
)
|
||||
public
|
||||
StableDebtToken(_pool, _underlyingAssetAddress, _tokenName, _tokenSymbol, incentivesController)
|
||||
{}
|
||||
|
||||
function getRevision() internal pure override returns (uint256) {
|
||||
return 0x2;
|
||||
}
|
||||
|
|
|
@ -4,23 +4,6 @@ pragma solidity 0.6.12;
|
|||
import {VariableDebtToken} from '../../protocol/tokenization/VariableDebtToken.sol';
|
||||
|
||||
contract MockVariableDebtToken is VariableDebtToken {
|
||||
constructor(
|
||||
address _pool,
|
||||
address _underlyingAssetAddress,
|
||||
string memory _tokenName,
|
||||
string memory _tokenSymbol,
|
||||
address incentivesController
|
||||
)
|
||||
public
|
||||
VariableDebtToken(
|
||||
_pool,
|
||||
_underlyingAssetAddress,
|
||||
_tokenName,
|
||||
_tokenSymbol,
|
||||
incentivesController
|
||||
)
|
||||
{}
|
||||
|
||||
function getRevision() internal pure override returns (uint256) {
|
||||
return 0x2;
|
||||
}
|
||||
|
|
|
@ -49,10 +49,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
using PercentageMath for uint256;
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
//main configuration parameters
|
||||
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;
|
||||
|
||||
modifier whenNotPaused() {
|
||||
|
@ -86,9 +82,20 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
* - Caching the address of the LendingPoolAddressesProvider in order to reduce gas consumption
|
||||
* on subsequent operations
|
||||
* @param provider The address of the LendingPoolAddressesProvider
|
||||
* @param maxStableRateBorrowSizePercent The percentage of available liquidity that can be borrowed at once at stable rate
|
||||
* @param flashLoanPremiumTotal The fee on flash loans
|
||||
* @param maxNumberOfReserves Maximum number of reserves supported to be listed in this LendingPool
|
||||
**/
|
||||
function initialize(ILendingPoolAddressesProvider provider) public initializer {
|
||||
function initialize(
|
||||
ILendingPoolAddressesProvider provider,
|
||||
uint256 maxStableRateBorrowSizePercent,
|
||||
uint256 flashLoanPremiumTotal,
|
||||
uint256 maxNumberOfReserves
|
||||
) public initializer {
|
||||
_addressesProvider = provider;
|
||||
_maxStableRateBorrowSizePercent = maxStableRateBorrowSizePercent;
|
||||
_flashLoanPremiumTotal = flashLoanPremiumTotal;
|
||||
_maxNumberOfReserves = maxNumberOfReserves;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -144,7 +151,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
address asset,
|
||||
uint256 amount,
|
||||
address to
|
||||
) external override whenNotPaused returns (uint256) {
|
||||
) external override whenNotPaused returns (uint256) {
|
||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
address aToken = reserve.aTokenAddress;
|
||||
|
@ -499,7 +506,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
for (vars.i = 0; vars.i < assets.length; vars.i++) {
|
||||
aTokenAddresses[vars.i] = _reserves[assets[vars.i]].aTokenAddress;
|
||||
|
||||
premiums[vars.i] = amounts[vars.i].mul(FLASHLOAN_PREMIUM_TOTAL).div(10000);
|
||||
premiums[vars.i] = amounts[vars.i].mul(_flashLoanPremiumTotal).div(10000);
|
||||
|
||||
IAToken(aTokenAddresses[vars.i]).transferUnderlyingTo(receiverAddress, amounts[vars.i]);
|
||||
}
|
||||
|
@ -703,6 +710,27 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
return _addressesProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the percentage of available liquidity that can be borrowed at once at stable rate
|
||||
*/
|
||||
function MAX_STABLE_RATE_BORROW_SIZE_PERCENT() public view returns (uint256) {
|
||||
return _maxStableRateBorrowSizePercent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the fee on flash loans
|
||||
*/
|
||||
function FLASHLOAN_PREMIUM_TOTAL() public view returns (uint256) {
|
||||
return _flashLoanPremiumTotal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the maximum number of reserves supported to be listed in this LendingPool
|
||||
*/
|
||||
function MAX_NUMBER_RESERVES() public view returns (uint256) {
|
||||
return _maxNumberOfReserves;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Validates and finalizes an aToken transfer
|
||||
* - Only callable by the overlying aToken of the `asset`
|
||||
|
@ -847,7 +875,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
vars.amount,
|
||||
amountInETH,
|
||||
vars.interestRateMode,
|
||||
MAX_STABLE_RATE_BORROW_SIZE_PERCENT,
|
||||
_maxStableRateBorrowSizePercent,
|
||||
_reserves,
|
||||
userConfig,
|
||||
_reservesList,
|
||||
|
@ -909,7 +937,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
function _addReserveToList(address asset) internal {
|
||||
uint256 reservesCount = _reservesCount;
|
||||
|
||||
require(reservesCount < MAX_NUMBER_RESERVES, Errors.LP_NO_MORE_RESERVES_ALLOWED);
|
||||
require(reservesCount < _maxNumberOfReserves, Errors.LP_NO_MORE_RESERVES_ALLOWED);
|
||||
|
||||
bool reserveAlreadyAdded = _reserves[asset].id != 0 || _reservesList[0] == asset;
|
||||
|
||||
|
|
|
@ -10,11 +10,14 @@ import {
|
|||
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
|
||||
import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {ILendingPool} from '../../interfaces/ILendingPool.sol';
|
||||
import {ITokenConfiguration} from '../../interfaces/ITokenConfiguration.sol';
|
||||
import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
|
||||
import {Errors} from '../libraries/helpers/Errors.sol';
|
||||
import {PercentageMath} from '../libraries/math/PercentageMath.sol';
|
||||
import {DataTypes} from '../libraries/types/DataTypes.sol';
|
||||
import {IInitializableDebtToken} from '../../interfaces/IInitializableDebtToken.sol';
|
||||
import {IInitializableAToken} from '../../interfaces/IInitializableAToken.sol';
|
||||
import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol';
|
||||
import {ILendingPoolConfigurator} from '../../interfaces/ILendingPoolConfigurator.sol';
|
||||
|
||||
/**
|
||||
* @title LendingPoolConfigurator contract
|
||||
|
@ -22,147 +25,11 @@ import {DataTypes} from '../libraries/types/DataTypes.sol';
|
|||
* @dev Implements the configuration methods for the Aave protocol
|
||||
**/
|
||||
|
||||
contract LendingPoolConfigurator is VersionedInitializable {
|
||||
contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigurator {
|
||||
using SafeMath for uint256;
|
||||
using PercentageMath for uint256;
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
|
||||
/**
|
||||
* @dev Emitted when a reserve is initialized.
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param aToken The address of the associated aToken contract
|
||||
* @param stableDebtToken The address of the associated stable rate debt token
|
||||
* @param variableDebtToken The address of the associated variable rate debt token
|
||||
* @param interestRateStrategyAddress The address of the interest rate strategy for the reserve
|
||||
**/
|
||||
event ReserveInitialized(
|
||||
address indexed asset,
|
||||
address indexed aToken,
|
||||
address stableDebtToken,
|
||||
address variableDebtToken,
|
||||
address interestRateStrategyAddress
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev Emitted when borrowing is enabled on a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param stableRateEnabled True if stable rate borrowing is enabled, false otherwise
|
||||
**/
|
||||
event BorrowingEnabledOnReserve(address indexed asset, bool stableRateEnabled);
|
||||
|
||||
/**
|
||||
* @dev Emitted when borrowing is disabled on a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event BorrowingDisabledOnReserve(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev Emitted when the collateralization risk parameters for the specified asset are updated.
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param ltv The loan to value of the asset when used as collateral
|
||||
* @param liquidationThreshold The threshold at which loans using this asset as collateral will be considered undercollateralized
|
||||
* @param liquidationBonus The bonus liquidators receive to liquidate this asset
|
||||
**/
|
||||
event CollateralConfigurationChanged(
|
||||
address indexed asset,
|
||||
uint256 ltv,
|
||||
uint256 liquidationThreshold,
|
||||
uint256 liquidationBonus
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev Emitted when stable rate borrowing is enabled on a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event StableRateEnabledOnReserve(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev Emitted when stable rate borrowing is disabled on a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event StableRateDisabledOnReserve(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev Emitted when a reserve is activated
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event ReserveActivated(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev Emitted when a reserve is deactivated
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event ReserveDeactivated(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev Emitted when a reserve is frozen
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event ReserveFrozen(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev Emitted when a reserve is unfrozen
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event ReserveUnfrozen(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev Emitted when a reserve factor is updated
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param factor The new reserve factor
|
||||
**/
|
||||
event ReserveFactorChanged(address indexed asset, uint256 factor);
|
||||
|
||||
/**
|
||||
* @dev Emitted when the reserve decimals are updated
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param decimals The new decimals
|
||||
**/
|
||||
event ReserveDecimalsChanged(address indexed asset, uint256 decimals);
|
||||
|
||||
/**
|
||||
* @dev Emitted when a reserve interest strategy contract is updated
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param strategy The new address of the interest strategy contract
|
||||
**/
|
||||
event ReserveInterestRateStrategyChanged(address indexed asset, address strategy);
|
||||
|
||||
/**
|
||||
* @dev Emitted when an aToken implementation is upgraded
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param proxy The aToken proxy address
|
||||
* @param implementation The new aToken implementation
|
||||
**/
|
||||
event ATokenUpgraded(
|
||||
address indexed asset,
|
||||
address indexed proxy,
|
||||
address indexed implementation
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev Emitted when the implementation of a stable debt token is upgraded
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param proxy The stable debt token proxy address
|
||||
* @param implementation The new aToken implementation
|
||||
**/
|
||||
event StableDebtTokenUpgraded(
|
||||
address indexed asset,
|
||||
address indexed proxy,
|
||||
address indexed implementation
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev Emitted when the implementation of a variable debt token is upgraded
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param proxy The variable debt token proxy address
|
||||
* @param implementation The new aToken implementation
|
||||
**/
|
||||
event VariableDebtTokenUpgraded(
|
||||
address indexed asset,
|
||||
address indexed proxy,
|
||||
address indexed implementation
|
||||
);
|
||||
|
||||
ILendingPoolAddressesProvider internal addressesProvider;
|
||||
ILendingPool internal pool;
|
||||
|
||||
|
@ -191,114 +58,186 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev Initializes a reserve
|
||||
* @param aTokenImpl The address of the aToken contract implementation
|
||||
* @param stableDebtTokenImpl The address of the stable debt token contract
|
||||
* @param variableDebtTokenImpl The address of the variable debt token contract
|
||||
* @param underlyingAssetDecimals The decimals of the reserve underlying asset
|
||||
* @param interestRateStrategyAddress The address of the interest rate strategy contract for this reserve
|
||||
* @dev Initializes reserves in batch
|
||||
**/
|
||||
function initReserve(
|
||||
address aTokenImpl,
|
||||
address stableDebtTokenImpl,
|
||||
address variableDebtTokenImpl,
|
||||
uint8 underlyingAssetDecimals,
|
||||
address interestRateStrategyAddress
|
||||
) public onlyPoolAdmin {
|
||||
address asset = ITokenConfiguration(aTokenImpl).UNDERLYING_ASSET_ADDRESS();
|
||||
function batchInitReserve(InitReserveInput[] calldata inputParams) public onlyPoolAdmin {
|
||||
ILendingPool cachedPool = pool;
|
||||
for (uint256 i = 0; i < inputParams.length; i++) {
|
||||
_initReserve(cachedPool, inputParams[i]);
|
||||
}
|
||||
}
|
||||
|
||||
require(
|
||||
address(pool) == ITokenConfiguration(aTokenImpl).POOL(),
|
||||
Errors.LPC_INVALID_ATOKEN_POOL_ADDRESS
|
||||
);
|
||||
require(
|
||||
address(pool) == ITokenConfiguration(stableDebtTokenImpl).POOL(),
|
||||
Errors.LPC_INVALID_STABLE_DEBT_TOKEN_POOL_ADDRESS
|
||||
);
|
||||
require(
|
||||
address(pool) == ITokenConfiguration(variableDebtTokenImpl).POOL(),
|
||||
Errors.LPC_INVALID_VARIABLE_DEBT_TOKEN_POOL_ADDRESS
|
||||
);
|
||||
require(
|
||||
asset == ITokenConfiguration(stableDebtTokenImpl).UNDERLYING_ASSET_ADDRESS(),
|
||||
Errors.LPC_INVALID_STABLE_DEBT_TOKEN_UNDERLYING_ADDRESS
|
||||
);
|
||||
require(
|
||||
asset == ITokenConfiguration(variableDebtTokenImpl).UNDERLYING_ASSET_ADDRESS(),
|
||||
Errors.LPC_INVALID_VARIABLE_DEBT_TOKEN_UNDERLYING_ADDRESS
|
||||
);
|
||||
|
||||
address aTokenProxyAddress = _initTokenWithProxy(aTokenImpl, underlyingAssetDecimals);
|
||||
function _initReserve(ILendingPool pool, InitReserveInput calldata inputParams) internal {
|
||||
address aTokenProxyAddress =
|
||||
_initTokenWithProxy(
|
||||
inputParams.aTokenImpl,
|
||||
abi.encodeWithSelector(
|
||||
IInitializableAToken.initialize.selector,
|
||||
pool,
|
||||
inputParams.treasury,
|
||||
inputParams.underlyingAsset,
|
||||
IAaveIncentivesController(inputParams.incentivesController),
|
||||
inputParams.underlyingAssetDecimals,
|
||||
inputParams.aTokenName,
|
||||
inputParams.aTokenSymbol
|
||||
)
|
||||
);
|
||||
|
||||
address stableDebtTokenProxyAddress =
|
||||
_initTokenWithProxy(stableDebtTokenImpl, underlyingAssetDecimals);
|
||||
_initTokenWithProxy(
|
||||
inputParams.stableDebtTokenImpl,
|
||||
abi.encodeWithSelector(
|
||||
IInitializableDebtToken.initialize.selector,
|
||||
pool,
|
||||
inputParams.underlyingAsset,
|
||||
IAaveIncentivesController(inputParams.incentivesController),
|
||||
inputParams.underlyingAssetDecimals,
|
||||
inputParams.stableDebtTokenName,
|
||||
inputParams.stableDebtTokenSymbol
|
||||
)
|
||||
);
|
||||
|
||||
address variableDebtTokenProxyAddress =
|
||||
_initTokenWithProxy(variableDebtTokenImpl, underlyingAssetDecimals);
|
||||
_initTokenWithProxy(
|
||||
inputParams.variableDebtTokenImpl,
|
||||
abi.encodeWithSelector(
|
||||
IInitializableDebtToken.initialize.selector,
|
||||
pool,
|
||||
inputParams.underlyingAsset,
|
||||
IAaveIncentivesController(inputParams.incentivesController),
|
||||
inputParams.underlyingAssetDecimals,
|
||||
inputParams.variableDebtTokenName,
|
||||
inputParams.variableDebtTokenSymbol
|
||||
)
|
||||
);
|
||||
|
||||
pool.initReserve(
|
||||
asset,
|
||||
inputParams.underlyingAsset,
|
||||
aTokenProxyAddress,
|
||||
stableDebtTokenProxyAddress,
|
||||
variableDebtTokenProxyAddress,
|
||||
interestRateStrategyAddress
|
||||
inputParams.interestRateStrategyAddress
|
||||
);
|
||||
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig =
|
||||
pool.getConfiguration(inputParams.underlyingAsset);
|
||||
|
||||
currentConfig.setDecimals(underlyingAssetDecimals);
|
||||
currentConfig.setDecimals(inputParams.underlyingAssetDecimals);
|
||||
|
||||
currentConfig.setActive(true);
|
||||
currentConfig.setFrozen(false);
|
||||
|
||||
pool.setConfiguration(asset, currentConfig.data);
|
||||
pool.setConfiguration(inputParams.underlyingAsset, currentConfig.data);
|
||||
|
||||
emit ReserveInitialized(
|
||||
asset,
|
||||
inputParams.underlyingAsset,
|
||||
aTokenProxyAddress,
|
||||
stableDebtTokenProxyAddress,
|
||||
variableDebtTokenProxyAddress,
|
||||
interestRateStrategyAddress
|
||||
inputParams.interestRateStrategyAddress
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Updates the aToken implementation for the reserve
|
||||
* @param asset The address of the underlying asset of the reserve to be updated
|
||||
* @param implementation The address of the new aToken implementation
|
||||
**/
|
||||
function updateAToken(address asset, address implementation) external onlyPoolAdmin {
|
||||
DataTypes.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||
function updateAToken(UpdateATokenInput calldata inputParams) external onlyPoolAdmin {
|
||||
ILendingPool cachedPool = pool;
|
||||
|
||||
_upgradeTokenImplementation(asset, reserveData.aTokenAddress, implementation);
|
||||
DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(inputParams.asset);
|
||||
|
||||
emit ATokenUpgraded(asset, reserveData.aTokenAddress, implementation);
|
||||
DataTypes.ReserveConfigurationMap memory configuration =
|
||||
cachedPool.getConfiguration(inputParams.asset);
|
||||
|
||||
(, , , uint256 decimals, ) = configuration.getParamsMemory();
|
||||
|
||||
_upgradeTokenImplementation(
|
||||
reserveData.aTokenAddress,
|
||||
inputParams.implementation,
|
||||
abi.encodeWithSelector(
|
||||
IInitializableAToken.initialize.selector,
|
||||
cachedPool,
|
||||
inputParams.treasury,
|
||||
inputParams.asset,
|
||||
inputParams.incentivesController,
|
||||
decimals,
|
||||
inputParams.name,
|
||||
inputParams.symbol
|
||||
)
|
||||
);
|
||||
|
||||
emit ATokenUpgraded(inputParams.asset, reserveData.aTokenAddress, inputParams.implementation);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Updates the stable debt token implementation for the reserve
|
||||
* @param asset The address of the underlying asset of the reserve to be updated
|
||||
* @param implementation The address of the new aToken implementation
|
||||
**/
|
||||
function updateStableDebtToken(address asset, address implementation) external onlyPoolAdmin {
|
||||
DataTypes.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||
function updateStableDebtToken(UpdateDebtTokenInput calldata inputParams) external onlyPoolAdmin {
|
||||
ILendingPool cachedPool = pool;
|
||||
|
||||
_upgradeTokenImplementation(asset, reserveData.stableDebtTokenAddress, implementation);
|
||||
DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(inputParams.asset);
|
||||
|
||||
emit StableDebtTokenUpgraded(asset, reserveData.stableDebtTokenAddress, implementation);
|
||||
DataTypes.ReserveConfigurationMap memory configuration =
|
||||
cachedPool.getConfiguration(inputParams.asset);
|
||||
|
||||
(, , , uint256 decimals, ) = configuration.getParamsMemory();
|
||||
|
||||
_upgradeTokenImplementation(
|
||||
reserveData.stableDebtTokenAddress,
|
||||
inputParams.implementation,
|
||||
abi.encodeWithSelector(
|
||||
IInitializableDebtToken.initialize.selector,
|
||||
cachedPool,
|
||||
inputParams.asset,
|
||||
inputParams.incentivesController,
|
||||
decimals,
|
||||
inputParams.name,
|
||||
inputParams.symbol
|
||||
)
|
||||
);
|
||||
|
||||
emit StableDebtTokenUpgraded(
|
||||
inputParams.asset,
|
||||
reserveData.stableDebtTokenAddress,
|
||||
inputParams.implementation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Updates the variable debt token implementation for the asset
|
||||
* @param asset The address of the underlying asset of the reserve to be updated
|
||||
* @param implementation The address of the new aToken implementation
|
||||
**/
|
||||
function updateVariableDebtToken(address asset, address implementation) external onlyPoolAdmin {
|
||||
DataTypes.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||
function updateVariableDebtToken(UpdateDebtTokenInput calldata inputParams)
|
||||
external
|
||||
onlyPoolAdmin
|
||||
{
|
||||
ILendingPool cachedPool = pool;
|
||||
|
||||
_upgradeTokenImplementation(asset, reserveData.variableDebtTokenAddress, implementation);
|
||||
DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(inputParams.asset);
|
||||
|
||||
emit VariableDebtTokenUpgraded(asset, reserveData.variableDebtTokenAddress, implementation);
|
||||
DataTypes.ReserveConfigurationMap memory configuration =
|
||||
cachedPool.getConfiguration(inputParams.asset);
|
||||
|
||||
(, , , uint256 decimals, ) = configuration.getParamsMemory();
|
||||
|
||||
_upgradeTokenImplementation(
|
||||
reserveData.variableDebtTokenAddress,
|
||||
inputParams.implementation,
|
||||
abi.encodeWithSelector(
|
||||
IInitializableDebtToken.initialize.selector,
|
||||
cachedPool,
|
||||
inputParams.asset,
|
||||
inputParams.incentivesController,
|
||||
decimals,
|
||||
inputParams.name,
|
||||
inputParams.symbol
|
||||
)
|
||||
);
|
||||
|
||||
emit VariableDebtTokenUpgraded(
|
||||
inputParams.asset,
|
||||
reserveData.variableDebtTokenAddress,
|
||||
inputParams.implementation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -509,44 +448,27 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
pool.setPause(val);
|
||||
}
|
||||
|
||||
function _initTokenWithProxy(address implementation, uint8 decimals) internal returns (address) {
|
||||
function _initTokenWithProxy(address implementation, bytes memory initParams)
|
||||
internal
|
||||
returns (address)
|
||||
{
|
||||
InitializableImmutableAdminUpgradeabilityProxy proxy =
|
||||
new InitializableImmutableAdminUpgradeabilityProxy(address(this));
|
||||
|
||||
bytes memory params =
|
||||
abi.encodeWithSignature(
|
||||
'initialize(uint8,string,string)',
|
||||
decimals,
|
||||
IERC20Detailed(implementation).name(),
|
||||
IERC20Detailed(implementation).symbol()
|
||||
);
|
||||
|
||||
proxy.initialize(implementation, params);
|
||||
proxy.initialize(implementation, initParams);
|
||||
|
||||
return address(proxy);
|
||||
}
|
||||
|
||||
function _upgradeTokenImplementation(
|
||||
address asset,
|
||||
address proxyAddress,
|
||||
address implementation
|
||||
address implementation,
|
||||
bytes memory initParams
|
||||
) internal {
|
||||
InitializableImmutableAdminUpgradeabilityProxy proxy =
|
||||
InitializableImmutableAdminUpgradeabilityProxy(payable(proxyAddress));
|
||||
|
||||
DataTypes.ReserveConfigurationMap memory configuration = pool.getConfiguration(asset);
|
||||
|
||||
(, , , uint256 decimals, ) = configuration.getParamsMemory();
|
||||
|
||||
bytes memory params =
|
||||
abi.encodeWithSignature(
|
||||
'initialize(uint8,string,string)',
|
||||
uint8(decimals),
|
||||
IERC20Detailed(implementation).name(),
|
||||
IERC20Detailed(implementation).symbol()
|
||||
);
|
||||
|
||||
proxy.upgradeToAndCall(implementation, params);
|
||||
proxy.upgradeToAndCall(implementation, initParams);
|
||||
}
|
||||
|
||||
function _checkNoLiquidity(address asset) internal view {
|
||||
|
|
|
@ -23,4 +23,10 @@ contract LendingPoolStorage {
|
|||
uint256 internal _reservesCount;
|
||||
|
||||
bool internal _paused;
|
||||
|
||||
uint256 internal _maxStableRateBorrowSizePercent;
|
||||
|
||||
uint256 internal _flashLoanPremiumTotal;
|
||||
|
||||
uint256 internal _maxNumberOfReserves;
|
||||
}
|
||||
|
|
|
@ -9,13 +9,18 @@ import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
|||
import {Errors} from '../libraries/helpers/Errors.sol';
|
||||
import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol';
|
||||
import {IncentivizedERC20} from './IncentivizedERC20.sol';
|
||||
import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol';
|
||||
|
||||
/**
|
||||
* @title Aave ERC20 AToken
|
||||
* @dev Implementation of the interest bearing token for the Aave protocol
|
||||
* @author Aave
|
||||
*/
|
||||
contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
||||
contract AToken is
|
||||
VersionedInitializable,
|
||||
IncentivizedERC20('ATOKEN_IMPL', 'ATOKEN_IMPL', 0),
|
||||
IAToken
|
||||
{
|
||||
using WadRayMath for uint256;
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
|
@ -25,44 +30,46 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
bytes32 public constant PERMIT_TYPEHASH =
|
||||
keccak256('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)');
|
||||
|
||||
uint256 public constant UINT_MAX_VALUE = uint256(-1);
|
||||
uint256 public constant ATOKEN_REVISION = 0x1;
|
||||
address public immutable UNDERLYING_ASSET_ADDRESS;
|
||||
address public immutable RESERVE_TREASURY_ADDRESS;
|
||||
ILendingPool public immutable POOL;
|
||||
|
||||
/// @dev owner => next valid nonce to submit with permit()
|
||||
mapping(address => uint256) public _nonces;
|
||||
|
||||
bytes32 public DOMAIN_SEPARATOR;
|
||||
|
||||
modifier onlyLendingPool {
|
||||
require(_msgSender() == address(POOL), Errors.CT_CALLER_MUST_BE_LENDING_POOL);
|
||||
_;
|
||||
}
|
||||
ILendingPool internal _pool;
|
||||
address internal _treasury;
|
||||
address internal _underlyingAsset;
|
||||
IAaveIncentivesController internal _incentivesController;
|
||||
|
||||
constructor(
|
||||
ILendingPool pool,
|
||||
address underlyingAssetAddress,
|
||||
address reserveTreasuryAddress,
|
||||
string memory tokenName,
|
||||
string memory tokenSymbol,
|
||||
address incentivesController
|
||||
) public IncentivizedERC20(tokenName, tokenSymbol, 18, incentivesController) {
|
||||
POOL = pool;
|
||||
UNDERLYING_ASSET_ADDRESS = underlyingAssetAddress;
|
||||
RESERVE_TREASURY_ADDRESS = reserveTreasuryAddress;
|
||||
modifier onlyLendingPool {
|
||||
require(_msgSender() == address(_pool), Errors.CT_CALLER_MUST_BE_LENDING_POOL);
|
||||
_;
|
||||
}
|
||||
|
||||
function getRevision() internal pure virtual override returns (uint256) {
|
||||
return ATOKEN_REVISION;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Initializes the aToken
|
||||
* @param pool The address of the lending pool where this aToken will be used
|
||||
* @param treasury The address of the Aave treasury, receiving the fees on this aToken
|
||||
* @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH)
|
||||
* @param incentivesController The smart contract managing potential incentives distribution
|
||||
* @param aTokenDecimals The decimals of the aToken, same as the underlying asset's
|
||||
* @param aTokenName The name of the aToken
|
||||
* @param aTokenSymbol The symbol of the aToken
|
||||
*/
|
||||
function initialize(
|
||||
uint8 underlyingAssetDecimals,
|
||||
string calldata tokenName,
|
||||
string calldata tokenSymbol
|
||||
) external virtual initializer {
|
||||
ILendingPool pool,
|
||||
address treasury,
|
||||
address underlyingAsset,
|
||||
IAaveIncentivesController incentivesController,
|
||||
uint8 aTokenDecimals,
|
||||
string calldata aTokenName,
|
||||
string calldata aTokenSymbol
|
||||
) external override initializer {
|
||||
uint256 chainId;
|
||||
|
||||
//solium-disable-next-line
|
||||
|
@ -73,16 +80,21 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
DOMAIN_SEPARATOR = keccak256(
|
||||
abi.encode(
|
||||
EIP712_DOMAIN,
|
||||
keccak256(bytes(tokenName)),
|
||||
keccak256(bytes(aTokenName)),
|
||||
keccak256(EIP712_REVISION),
|
||||
chainId,
|
||||
address(this)
|
||||
)
|
||||
);
|
||||
|
||||
_setName(tokenName);
|
||||
_setSymbol(tokenSymbol);
|
||||
_setDecimals(underlyingAssetDecimals);
|
||||
_setName(aTokenName);
|
||||
_setSymbol(aTokenSymbol);
|
||||
_setDecimals(aTokenDecimals);
|
||||
|
||||
_pool = pool;
|
||||
_treasury = treasury;
|
||||
_underlyingAsset = underlyingAsset;
|
||||
_incentivesController = incentivesController;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,7 +115,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
require(amountScaled != 0, Errors.CT_INVALID_BURN_AMOUNT);
|
||||
_burn(user, amountScaled);
|
||||
|
||||
IERC20(UNDERLYING_ASSET_ADDRESS).safeTransfer(receiverOfUnderlying, amount);
|
||||
IERC20(_underlyingAsset).safeTransfer(receiverOfUnderlying, amount);
|
||||
|
||||
emit Transfer(user, address(0), amount);
|
||||
emit Burn(user, receiverOfUnderlying, amount, index);
|
||||
|
@ -145,14 +157,16 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
return;
|
||||
}
|
||||
|
||||
address treasury = _treasury;
|
||||
|
||||
// Compared to the normal mint, we don't check for rounding errors.
|
||||
// The amount to mint can easily be very small since it is a fraction of the interest ccrued.
|
||||
// In that case, the treasury will experience a (very small) loss, but it
|
||||
// wont cause potentially valid transactions to fail.
|
||||
_mint(RESERVE_TREASURY_ADDRESS, amount.rayDiv(index));
|
||||
_mint(treasury, amount.rayDiv(index));
|
||||
|
||||
emit Transfer(address(0), RESERVE_TREASURY_ADDRESS, amount);
|
||||
emit Mint(RESERVE_TREASURY_ADDRESS, amount, index);
|
||||
emit Transfer(address(0), treasury, amount);
|
||||
emit Mint(treasury, amount, index);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,7 +199,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
override(IncentivizedERC20, IERC20)
|
||||
returns (uint256)
|
||||
{
|
||||
return super.balanceOf(user).rayMul(POOL.getReserveNormalizedIncome(UNDERLYING_ASSET_ADDRESS));
|
||||
return super.balanceOf(user).rayMul(_pool.getReserveNormalizedIncome(_underlyingAsset));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -226,7 +240,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
return 0;
|
||||
}
|
||||
|
||||
return currentSupplyScaled.rayMul(POOL.getReserveNormalizedIncome(UNDERLYING_ASSET_ADDRESS));
|
||||
return currentSupplyScaled.rayMul(_pool.getReserveNormalizedIncome(_underlyingAsset));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -237,6 +251,41 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
return super.totalSupply();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the Aave treasury, receiving the fees on this aToken
|
||||
**/
|
||||
function RESERVE_TREASURY_ADDRESS() public view returns (address) {
|
||||
return _treasury;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH)
|
||||
**/
|
||||
function UNDERLYING_ASSET_ADDRESS() public view returns (address) {
|
||||
return _underlyingAsset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the lending pool where this aToken is used
|
||||
**/
|
||||
function POOL() public view returns (ILendingPool) {
|
||||
return _pool;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev For internal usage in the logic of the parent contract IncentivizedERC20
|
||||
**/
|
||||
function _getIncentivesController() internal view override returns (IAaveIncentivesController) {
|
||||
return _incentivesController;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the incentives controller contract
|
||||
**/
|
||||
function getIncentivesController() external view override returns (IAaveIncentivesController) {
|
||||
return _getIncentivesController();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfers the underlying asset to `target`. Used by the LendingPool to transfer
|
||||
* assets in borrow(), withdraw() and flashLoan()
|
||||
|
@ -250,7 +299,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
onlyLendingPool
|
||||
returns (uint256)
|
||||
{
|
||||
IERC20(UNDERLYING_ASSET_ADDRESS).safeTransfer(target, amount);
|
||||
IERC20(_underlyingAsset).safeTransfer(target, amount);
|
||||
return amount;
|
||||
}
|
||||
|
||||
|
@ -305,7 +354,10 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
uint256 amount,
|
||||
bool validate
|
||||
) internal {
|
||||
uint256 index = POOL.getReserveNormalizedIncome(UNDERLYING_ASSET_ADDRESS);
|
||||
address underlyingAsset = _underlyingAsset;
|
||||
ILendingPool pool = _pool;
|
||||
|
||||
uint256 index = pool.getReserveNormalizedIncome(underlyingAsset);
|
||||
|
||||
uint256 fromBalanceBefore = super.balanceOf(from).rayMul(index);
|
||||
uint256 toBalanceBefore = super.balanceOf(to).rayMul(index);
|
||||
|
@ -313,14 +365,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
super._transfer(from, to, amount.rayDiv(index));
|
||||
|
||||
if (validate) {
|
||||
POOL.finalizeTransfer(
|
||||
UNDERLYING_ASSET_ADDRESS,
|
||||
from,
|
||||
to,
|
||||
amount,
|
||||
fromBalanceBefore,
|
||||
toBalanceBefore
|
||||
);
|
||||
pool.finalizeTransfer(underlyingAsset, from, to, amount, fromBalanceBefore, toBalanceBefore);
|
||||
}
|
||||
|
||||
emit BalanceTransfer(from, to, amount, index);
|
||||
|
|
|
@ -14,36 +14,17 @@ import {AToken} from './AToken.sol';
|
|||
contract DelegationAwareAToken is AToken {
|
||||
modifier onlyPoolAdmin {
|
||||
require(
|
||||
_msgSender() == ILendingPool(POOL).getAddressesProvider().getPoolAdmin(),
|
||||
_msgSender() == ILendingPool(_pool).getAddressesProvider().getPoolAdmin(),
|
||||
Errors.CALLER_NOT_POOL_ADMIN
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
constructor(
|
||||
ILendingPool pool,
|
||||
address underlyingAssetAddress,
|
||||
address reserveTreasury,
|
||||
string memory tokenName,
|
||||
string memory tokenSymbol,
|
||||
address incentivesController
|
||||
)
|
||||
public
|
||||
AToken(
|
||||
pool,
|
||||
underlyingAssetAddress,
|
||||
reserveTreasury,
|
||||
tokenName,
|
||||
tokenSymbol,
|
||||
incentivesController
|
||||
)
|
||||
{}
|
||||
|
||||
/**
|
||||
* @dev Delegates voting power of the underlying asset to a `delegatee` address
|
||||
* @param delegatee The address that will receive the delegation
|
||||
**/
|
||||
function delegateUnderlyingTo(address delegatee) external onlyPoolAdmin {
|
||||
IDelegationToken(UNDERLYING_ASSET_ADDRESS).delegate(delegatee);
|
||||
IDelegationToken(_underlyingAsset).delegate(delegatee);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,9 @@ import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesControl
|
|||
* @notice Basic ERC20 implementation
|
||||
* @author Aave, inspired by the Openzeppelin ERC20 implementation
|
||||
**/
|
||||
contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
|
||||
abstract contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
|
||||
using SafeMath for uint256;
|
||||
|
||||
IAaveIncentivesController internal immutable _incentivesController;
|
||||
|
||||
mapping(address => uint256) internal _balances;
|
||||
|
||||
mapping(address => mapping(address => uint256)) private _allowances;
|
||||
|
@ -28,13 +26,11 @@ contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
|
|||
constructor(
|
||||
string memory name,
|
||||
string memory symbol,
|
||||
uint8 decimals,
|
||||
address incentivesController
|
||||
uint8 decimals
|
||||
) public {
|
||||
_name = name;
|
||||
_symbol = symbol;
|
||||
_decimals = decimals;
|
||||
_incentivesController = IAaveIncentivesController(incentivesController);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,6 +68,12 @@ contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
|
|||
return _balances[account];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Abstract function implemented by the child aToken/debtToken.
|
||||
* Done this way in order to not break compatibility with previous versions of aTokens/debtTokens
|
||||
**/
|
||||
function _getIncentivesController() internal view virtual returns(IAaveIncentivesController);
|
||||
|
||||
/**
|
||||
* @dev Executes a transfer of tokens from _msgSender() to recipient
|
||||
* @param recipient The recipient of the tokens
|
||||
|
@ -180,11 +182,11 @@ contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
|
|||
uint256 oldRecipientBalance = _balances[recipient];
|
||||
_balances[recipient] = _balances[recipient].add(amount);
|
||||
|
||||
if (address(_incentivesController) != address(0)) {
|
||||
if (address(_getIncentivesController()) != address(0)) {
|
||||
uint256 currentTotalSupply = _totalSupply;
|
||||
_incentivesController.handleAction(sender, currentTotalSupply, oldSenderBalance);
|
||||
_getIncentivesController().handleAction(sender, currentTotalSupply, oldSenderBalance);
|
||||
if (sender != recipient) {
|
||||
_incentivesController.handleAction(recipient, currentTotalSupply, oldRecipientBalance);
|
||||
_getIncentivesController().handleAction(recipient, currentTotalSupply, oldRecipientBalance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,8 +202,8 @@ contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
|
|||
uint256 oldAccountBalance = _balances[account];
|
||||
_balances[account] = oldAccountBalance.add(amount);
|
||||
|
||||
if (address(_incentivesController) != address(0)) {
|
||||
_incentivesController.handleAction(account, oldTotalSupply, oldAccountBalance);
|
||||
if (address(_getIncentivesController()) != address(0)) {
|
||||
_getIncentivesController().handleAction(account, oldTotalSupply, oldAccountBalance);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -216,8 +218,8 @@ contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
|
|||
uint256 oldAccountBalance = _balances[account];
|
||||
_balances[account] = oldAccountBalance.sub(amount, 'ERC20: burn amount exceeds balance');
|
||||
|
||||
if (address(_incentivesController) != address(0)) {
|
||||
_incentivesController.handleAction(account, oldTotalSupply, oldAccountBalance);
|
||||
if (address(_getIncentivesController()) != address(0)) {
|
||||
_getIncentivesController().handleAction(account, oldTotalSupply, oldAccountBalance);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ 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 {ILendingPool} from '../../interfaces/ILendingPool.sol';
|
||||
import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol';
|
||||
import {Errors} from '../libraries/helpers/Errors.sol';
|
||||
|
||||
/**
|
||||
|
@ -23,13 +25,35 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
mapping(address => uint256) internal _usersStableRate;
|
||||
uint40 internal _totalSupplyTimestamp;
|
||||
|
||||
constructor(
|
||||
address pool,
|
||||
ILendingPool internal _pool;
|
||||
address internal _underlyingAsset;
|
||||
IAaveIncentivesController internal _incentivesController;
|
||||
|
||||
/**
|
||||
* @dev Initializes the debt token.
|
||||
* @param pool The address of the lending pool where this aToken will be used
|
||||
* @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH)
|
||||
* @param incentivesController The smart contract managing potential incentives distribution
|
||||
* @param debtTokenDecimals The decimals of the debtToken, same as the underlying asset's
|
||||
* @param debtTokenName The name of the token
|
||||
* @param debtTokenSymbol The symbol of the token
|
||||
*/
|
||||
function initialize(
|
||||
ILendingPool pool,
|
||||
address underlyingAsset,
|
||||
string memory name,
|
||||
string memory symbol,
|
||||
address incentivesController
|
||||
) public DebtTokenBase(pool, underlyingAsset, name, symbol, incentivesController) {}
|
||||
IAaveIncentivesController incentivesController,
|
||||
uint8 debtTokenDecimals,
|
||||
string memory debtTokenName,
|
||||
string memory debtTokenSymbol
|
||||
) public override initializer {
|
||||
_setName(debtTokenName);
|
||||
_setSymbol(debtTokenSymbol);
|
||||
_setDecimals(debtTokenDecimals);
|
||||
|
||||
_pool = pool;
|
||||
_underlyingAsset = underlyingAsset;
|
||||
_incentivesController = incentivesController;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Gets the revision of the stable debt token implementation
|
||||
|
@ -300,6 +324,48 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
return super.balanceOf(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH)
|
||||
**/
|
||||
function UNDERLYING_ASSET_ADDRESS() public view returns (address) {
|
||||
return _underlyingAsset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the lending pool where this aToken is used
|
||||
**/
|
||||
function POOL() public view returns (ILendingPool) {
|
||||
return _pool;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the incentives controller contract
|
||||
**/
|
||||
function getIncentivesController() external view override returns (IAaveIncentivesController) {
|
||||
return _getIncentivesController();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev For internal usage in the logic of the parent contracts
|
||||
**/
|
||||
function _getIncentivesController() internal view override returns (IAaveIncentivesController) {
|
||||
return _incentivesController;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev For internal usage in the logic of the parent contracts
|
||||
**/
|
||||
function _getUnderlyingAssetAddress() internal view override returns (address) {
|
||||
return _underlyingAsset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev For internal usage in the logic of the parent contracts
|
||||
**/
|
||||
function _getLendingPool() internal view override returns (ILendingPool) {
|
||||
return _pool;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Calculates the total supply
|
||||
* @param avgRate The average rate at which the total supply increases
|
||||
|
|
|
@ -5,6 +5,8 @@ import {IVariableDebtToken} from '../../interfaces/IVariableDebtToken.sol';
|
|||
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
||||
import {Errors} from '../libraries/helpers/Errors.sol';
|
||||
import {DebtTokenBase} from './base/DebtTokenBase.sol';
|
||||
import {ILendingPool} from '../../interfaces/ILendingPool.sol';
|
||||
import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol';
|
||||
|
||||
/**
|
||||
* @title VariableDebtToken
|
||||
|
@ -17,13 +19,35 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
|||
|
||||
uint256 public constant DEBT_TOKEN_REVISION = 0x1;
|
||||
|
||||
constructor(
|
||||
address pool,
|
||||
ILendingPool internal _pool;
|
||||
address internal _underlyingAsset;
|
||||
IAaveIncentivesController internal _incentivesController;
|
||||
|
||||
/**
|
||||
* @dev Initializes the debt token.
|
||||
* @param pool The address of the lending pool where this aToken will be used
|
||||
* @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH)
|
||||
* @param incentivesController The smart contract managing potential incentives distribution
|
||||
* @param debtTokenDecimals The decimals of the debtToken, same as the underlying asset's
|
||||
* @param debtTokenName The name of the token
|
||||
* @param debtTokenSymbol The symbol of the token
|
||||
*/
|
||||
function initialize(
|
||||
ILendingPool pool,
|
||||
address underlyingAsset,
|
||||
string memory name,
|
||||
string memory symbol,
|
||||
address incentivesController
|
||||
) public DebtTokenBase(pool, underlyingAsset, name, symbol, incentivesController) {}
|
||||
IAaveIncentivesController incentivesController,
|
||||
uint8 debtTokenDecimals,
|
||||
string memory debtTokenName,
|
||||
string memory debtTokenSymbol
|
||||
) public override initializer {
|
||||
_setName(debtTokenName);
|
||||
_setSymbol(debtTokenSymbol);
|
||||
_setDecimals(debtTokenDecimals);
|
||||
|
||||
_pool = pool;
|
||||
_underlyingAsset = underlyingAsset;
|
||||
_incentivesController = incentivesController;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Gets the revision of the stable debt token implementation
|
||||
|
@ -44,7 +68,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
|||
return 0;
|
||||
}
|
||||
|
||||
return scaledBalance.rayMul(POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET_ADDRESS));
|
||||
return scaledBalance.rayMul(_pool.getReserveNormalizedVariableDebt(_underlyingAsset));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -113,8 +137,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
|||
* @return The total supply
|
||||
**/
|
||||
function totalSupply() public view virtual override returns (uint256) {
|
||||
return
|
||||
super.totalSupply().rayMul(POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET_ADDRESS));
|
||||
return super.totalSupply().rayMul(_pool.getReserveNormalizedVariableDebt(_underlyingAsset));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -139,4 +162,37 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
|||
{
|
||||
return (super.balanceOf(user), super.totalSupply());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH)
|
||||
**/
|
||||
function UNDERLYING_ASSET_ADDRESS() public view returns (address) {
|
||||
return _underlyingAsset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the incentives controller contract
|
||||
**/
|
||||
function getIncentivesController() external view override returns (IAaveIncentivesController) {
|
||||
return _getIncentivesController();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the lending pool where this aToken is used
|
||||
**/
|
||||
function POOL() public view returns (ILendingPool) {
|
||||
return _pool;
|
||||
}
|
||||
|
||||
function _getIncentivesController() internal view override returns (IAaveIncentivesController) {
|
||||
return _incentivesController;
|
||||
}
|
||||
|
||||
function _getUnderlyingAssetAddress() internal view override returns (address) {
|
||||
return _underlyingAsset;
|
||||
}
|
||||
|
||||
function _getLendingPool() internal view override returns (ILendingPool) {
|
||||
return _pool;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,54 +16,20 @@ import {Errors} from '../../libraries/helpers/Errors.sol';
|
|||
*/
|
||||
|
||||
abstract contract DebtTokenBase is
|
||||
IncentivizedERC20,
|
||||
IncentivizedERC20('DEBTTOKEN_IMPL', 'DEBTTOKEN_IMPL', 0),
|
||||
VersionedInitializable,
|
||||
ICreditDelegationToken
|
||||
{
|
||||
address public immutable UNDERLYING_ASSET_ADDRESS;
|
||||
ILendingPool public immutable POOL;
|
||||
|
||||
mapping(address => mapping(address => uint256)) internal _borrowAllowances;
|
||||
|
||||
/**
|
||||
* @dev Only lending pool can call functions marked by this modifier
|
||||
**/
|
||||
modifier onlyLendingPool {
|
||||
require(_msgSender() == address(POOL), Errors.CT_CALLER_MUST_BE_LENDING_POOL);
|
||||
require(_msgSender() == address(_getLendingPool()), Errors.CT_CALLER_MUST_BE_LENDING_POOL);
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev The metadata of the token will be set on the proxy, that the reason of
|
||||
* passing "NULL" and 0 as metadata
|
||||
*/
|
||||
constructor(
|
||||
address pool,
|
||||
address underlyingAssetAddress,
|
||||
string memory name,
|
||||
string memory symbol,
|
||||
address incentivesController
|
||||
) public IncentivizedERC20(name, symbol, 18, incentivesController) {
|
||||
POOL = ILendingPool(pool);
|
||||
UNDERLYING_ASSET_ADDRESS = underlyingAssetAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Initializes the debt token.
|
||||
* @param name The name of the token
|
||||
* @param symbol The symbol of the token
|
||||
* @param decimals The decimals of the token
|
||||
*/
|
||||
function initialize(
|
||||
uint8 decimals,
|
||||
string memory name,
|
||||
string memory symbol
|
||||
) public initializer {
|
||||
_setName(name);
|
||||
_setSymbol(symbol);
|
||||
_setDecimals(decimals);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev delegates borrowing power to a user on the specific debt token
|
||||
* @param delegatee the address receiving the delegated borrowing power
|
||||
|
@ -73,7 +39,7 @@ abstract contract DebtTokenBase is
|
|||
**/
|
||||
function approveDelegation(address delegatee, uint256 amount) external override {
|
||||
_borrowAllowances[_msgSender()][delegatee] = amount;
|
||||
emit BorrowAllowanceDelegated(_msgSender(), delegatee, UNDERLYING_ASSET_ADDRESS, amount);
|
||||
emit BorrowAllowanceDelegated(_msgSender(), delegatee, _getUnderlyingAssetAddress(), amount);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -162,6 +128,10 @@ abstract contract DebtTokenBase is
|
|||
|
||||
_borrowAllowances[delegator][delegatee] = newAllowance;
|
||||
|
||||
emit BorrowAllowanceDelegated(delegator, delegatee, UNDERLYING_ASSET_ADDRESS, newAllowance);
|
||||
emit BorrowAllowanceDelegated(delegator, delegatee, _getUnderlyingAssetAddress(), newAllowance);
|
||||
}
|
||||
|
||||
function _getUnderlyingAssetAddress() internal view virtual returns (address);
|
||||
|
||||
function _getLendingPool() internal view virtual returns (ILendingPool);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user