mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
Merge branch 'master' into feat/add-compile-prior-tests
This commit is contained in:
commit
6c0bbadacb
37
.github/workflows/node.js.yml
vendored
Normal file
37
.github/workflows/node.js.yml
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Test
|
||||
run: npm run ci:test
|
||||
# - name: Coverage
|
||||
# run: npm run coverage
|
||||
# - uses: codecov/codecov-action@v1
|
||||
# with:
|
||||
# fail_ci_if_error: true
|
|
@ -1,5 +1,22 @@
|
|||
stages:
|
||||
- checks
|
||||
- prepare
|
||||
- publish
|
||||
|
||||
variables:
|
||||
IMAGE: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHA}
|
||||
|
||||
lint:
|
||||
stage: checks
|
||||
tags:
|
||||
- aave-build-runner
|
||||
before_script:
|
||||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml build
|
||||
script:
|
||||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml run contracts-env npm run prettier:check
|
||||
after_script:
|
||||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml run contracts-env npm run ci:clean
|
||||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml down
|
||||
|
||||
test:
|
||||
stage: checks
|
||||
|
@ -12,7 +29,9 @@ test:
|
|||
after_script:
|
||||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml run contracts-env npm run ci:clean
|
||||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml down
|
||||
|
||||
only:
|
||||
- master
|
||||
- merge_requests
|
||||
deploy-mainnet-fork:
|
||||
tags:
|
||||
- aave-build-runner
|
||||
|
@ -24,6 +43,9 @@ deploy-mainnet-fork:
|
|||
after_script:
|
||||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml run contracts-env npm run ci:clean
|
||||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml down
|
||||
only:
|
||||
- master
|
||||
- merge_requests
|
||||
|
||||
certora-test:
|
||||
stage: checks
|
||||
|
@ -40,3 +62,31 @@ certora-test:
|
|||
- certoraRun specs/harness/StableDebtTokenHarness.sol:StableDebtTokenHarness --solc_args "['--optimize']" --verify StableDebtTokenHarness:specs/StableDebtToken.spec --settings -assumeUnwindCond,-b=4 --cache StableDebtToken --cloud
|
||||
- certoraRun specs/harness/UserConfigurationHarness.sol --verify UserConfigurationHarness:specs/UserConfiguration.spec --solc_args "['--optimize']" --settings -useBitVectorTheory --cache UserConfiguration --cloud
|
||||
- certoraRun contracts/protocol/tokenization/VariableDebtToken.sol:VariableDebtToken specs/harness/LendingPoolHarnessForVariableDebtToken.sol --solc_args "['--optimize']" --link VariableDebtToken:POOL=LendingPoolHarnessForVariableDebtToken --verify VariableDebtToken:specs/VariableDebtToken.spec --settings -assumeUnwindCond,-useNonLinearArithmetic,-b=4 --cache VariableDebtToken --cloud
|
||||
only:
|
||||
- master
|
||||
- merge_requests
|
||||
|
||||
prepare:
|
||||
stage: prepare
|
||||
tags:
|
||||
- docker-builder
|
||||
script:
|
||||
- docker build -t ${IMAGE} .
|
||||
- docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY
|
||||
- docker push ${IMAGE}
|
||||
only:
|
||||
- master
|
||||
|
||||
publish:
|
||||
image: ${IMAGE}
|
||||
tags:
|
||||
- docker
|
||||
stage: publish
|
||||
script:
|
||||
- npm ci
|
||||
- echo //registry.npmjs.org/:_authToken=${NPM_V2_PACKAGES_TOKEN} > .npmrc
|
||||
- npm run compile
|
||||
- ${VERSION}
|
||||
- npm publish --access public
|
||||
only:
|
||||
- master
|
||||
|
|
33
README.md
33
README.md
|
@ -1,3 +1,5 @@
|
|||
[](https://www.gnu.org/licenses/agpl-3.0)
|
||||
[](https://github.com/aave/protocol-v2/actions/workflows/node.js.yml)
|
||||
```
|
||||
.///. .///. //. .// `/////////////-
|
||||
`++:++` .++:++` :++` `++: `++:......---.`
|
||||
|
@ -40,6 +42,37 @@ A more detailed and technical description of the protocol can be found in this r
|
|||
|
||||
You can join at the [Discord](http://aave.com/discord) channel or at the [Governance Forum](https://governance.aave.com/) for asking questions about the protocol or talk about Aave with other peers.
|
||||
|
||||
## Getting Started
|
||||
|
||||
You can install `@aave/protocol-v2` as an NPM package in your Hardhat, Buidler or Truffle project to import the contracts and interfaces:
|
||||
|
||||
`npm install @aave/protocol-v2`
|
||||
|
||||
Import at Solidity files:
|
||||
|
||||
```
|
||||
import {ILendingPool} from "@aave/protocol-v2/contracts/interfaces/ILendingPool.sol";
|
||||
|
||||
contract Misc {
|
||||
|
||||
function deposit(address pool, address token, address user, uint256 amount) public {
|
||||
ILendingPool(pool).deposit(token, amount, user, 0);
|
||||
{...}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The JSON artifacts with the ABI and Bytecode are also included into the bundled NPM package at `artifacts/` directory.
|
||||
|
||||
Import JSON file via Node JS `require`:
|
||||
|
||||
```
|
||||
const LendingPoolV2Artifact = require('@aave/protocol-v2/artifacts/contracts/protocol/lendingpool/LendingPool.sol/LendingPool.json');
|
||||
|
||||
// Log the ABI into console
|
||||
console.log(LendingPoolV2Artifact.abi)
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
The repository uses Docker Compose to manage sensitive keys and load the configuration. Prior any action like test or deploy, you must run `docker-compose up` to start the `contracts-env` container, and then connect to the container console via `docker-compose exec contracts-env bash`.
|
||||
|
|
Binary file not shown.
|
@ -24,7 +24,6 @@ import {IBaseUniswapAdapter} from './interfaces/IBaseUniswapAdapter.sol';
|
|||
abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapter, Ownable {
|
||||
using SafeMath for uint256;
|
||||
using PercentageMath for uint256;
|
||||
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
// Max slippage percent allowed
|
||||
|
@ -349,13 +348,16 @@ abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapt
|
|||
|
||||
if (reserveIn == reserveOut) {
|
||||
uint256 reserveDecimals = _getDecimals(reserveIn);
|
||||
address[] memory path = new address[](1);
|
||||
path[0] = reserveIn;
|
||||
|
||||
return
|
||||
AmountCalc(
|
||||
finalAmountIn,
|
||||
finalAmountIn.mul(10**18).div(amountIn),
|
||||
_calcUsdValue(reserveIn, amountIn, reserveDecimals),
|
||||
_calcUsdValue(reserveIn, finalAmountIn, reserveDecimals),
|
||||
[reserveIn]
|
||||
path
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -437,13 +439,16 @@ abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapt
|
|||
// Add flash loan fee
|
||||
uint256 amountIn = amountOut.add(amountOut.mul(FLASHLOAN_PREMIUM_TOTAL).div(10000));
|
||||
uint256 reserveDecimals = _getDecimals(reserveIn);
|
||||
address[] memory path = new address[](1);
|
||||
path[0] = reserveIn;
|
||||
|
||||
return
|
||||
AmountCalc(
|
||||
amountIn,
|
||||
amountOut.mul(10**18).div(amountIn),
|
||||
_calcUsdValue(reserveIn, amountIn, reserveDecimals),
|
||||
_calcUsdValue(reserveIn, amountOut, reserveDecimals),
|
||||
[reserveIn]
|
||||
path
|
||||
);
|
||||
}
|
||||
|
||||
|
|
184
contracts/adapters/FlashLiquidationAdapter.sol
Normal file
184
contracts/adapters/FlashLiquidationAdapter.sol
Normal file
|
@ -0,0 +1,184 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.12;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {BaseUniswapAdapter} from './BaseUniswapAdapter.sol';
|
||||
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {IUniswapV2Router02} from '../interfaces/IUniswapV2Router02.sol';
|
||||
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
|
||||
import {Helpers} from '../protocol/libraries/helpers/Helpers.sol';
|
||||
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
||||
import {IAToken} from '../interfaces/IAToken.sol';
|
||||
import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
|
||||
|
||||
/**
|
||||
* @title UniswapLiquiditySwapAdapter
|
||||
* @notice Uniswap V2 Adapter to swap liquidity.
|
||||
* @author Aave
|
||||
**/
|
||||
contract FlashLiquidationAdapter is BaseUniswapAdapter {
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
uint256 internal constant LIQUIDATION_CLOSE_FACTOR_PERCENT = 5000;
|
||||
|
||||
struct LiquidationParams {
|
||||
address collateralAsset;
|
||||
address borrowedAsset;
|
||||
address user;
|
||||
uint256 debtToCover;
|
||||
bool useEthPath;
|
||||
}
|
||||
|
||||
struct LiquidationCallLocalVars {
|
||||
uint256 initFlashBorrowedBalance;
|
||||
uint256 diffFlashBorrowedBalance;
|
||||
uint256 initCollateralBalance;
|
||||
uint256 diffCollateralBalance;
|
||||
uint256 flashLoanDebt;
|
||||
uint256 soldAmount;
|
||||
uint256 remainingTokens;
|
||||
uint256 borrowedAssetLeftovers;
|
||||
}
|
||||
|
||||
constructor(
|
||||
ILendingPoolAddressesProvider addressesProvider,
|
||||
IUniswapV2Router02 uniswapRouter,
|
||||
address wethAddress
|
||||
) public BaseUniswapAdapter(addressesProvider, uniswapRouter, wethAddress) {}
|
||||
|
||||
/**
|
||||
* @dev Liquidate a non-healthy position collateral-wise, with a Health Factor below 1, using Flash Loan and Uniswap to repay flash loan premium.
|
||||
* - The caller (liquidator) with a flash loan covers `debtToCover` amount of debt of the user getting liquidated, and receives
|
||||
* a proportionally amount of the `collateralAsset` plus a bonus to cover market risk minus the flash loan premium.
|
||||
* @param assets Address of asset to be swapped
|
||||
* @param amounts Amount of the asset to be swapped
|
||||
* @param premiums Fee of the flash loan
|
||||
* @param initiator Address of the caller
|
||||
* @param params Additional variadic field to include extra params. Expected parameters:
|
||||
* address collateralAsset The collateral asset to release and will be exchanged to pay the flash loan premium
|
||||
* address borrowedAsset The asset that must be covered
|
||||
* address user The user address with a Health Factor below 1
|
||||
* uint256 debtToCover The amount of debt to cover
|
||||
* bool useEthPath Use WETH as connector path between the collateralAsset and borrowedAsset at Uniswap
|
||||
*/
|
||||
function executeOperation(
|
||||
address[] calldata assets,
|
||||
uint256[] calldata amounts,
|
||||
uint256[] calldata premiums,
|
||||
address initiator,
|
||||
bytes calldata params
|
||||
) external override returns (bool) {
|
||||
require(msg.sender == address(LENDING_POOL), 'CALLER_MUST_BE_LENDING_POOL');
|
||||
|
||||
LiquidationParams memory decodedParams = _decodeParams(params);
|
||||
|
||||
require(assets.length == 1 && assets[0] == decodedParams.borrowedAsset, 'INCONSISTENT_PARAMS');
|
||||
|
||||
_liquidateAndSwap(
|
||||
decodedParams.collateralAsset,
|
||||
decodedParams.borrowedAsset,
|
||||
decodedParams.user,
|
||||
decodedParams.debtToCover,
|
||||
decodedParams.useEthPath,
|
||||
amounts[0],
|
||||
premiums[0],
|
||||
initiator
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev
|
||||
* @param collateralAsset The collateral asset to release and will be exchanged to pay the flash loan premium
|
||||
* @param borrowedAsset The asset that must be covered
|
||||
* @param user The user address with a Health Factor below 1
|
||||
* @param debtToCover The amount of debt to coverage, can be max(-1) to liquidate all possible debt
|
||||
* @param useEthPath true if the swap needs to occur using ETH in the routing, false otherwise
|
||||
* @param flashBorrowedAmount Amount of asset requested at the flash loan to liquidate the user position
|
||||
* @param premium Fee of the requested flash loan
|
||||
* @param initiator Address of the caller
|
||||
*/
|
||||
function _liquidateAndSwap(
|
||||
address collateralAsset,
|
||||
address borrowedAsset,
|
||||
address user,
|
||||
uint256 debtToCover,
|
||||
bool useEthPath,
|
||||
uint256 flashBorrowedAmount,
|
||||
uint256 premium,
|
||||
address initiator
|
||||
) internal {
|
||||
LiquidationCallLocalVars memory vars;
|
||||
vars.initCollateralBalance = IERC20(collateralAsset).balanceOf(address(this));
|
||||
if (collateralAsset != borrowedAsset) {
|
||||
vars.initFlashBorrowedBalance = IERC20(borrowedAsset).balanceOf(address(this));
|
||||
|
||||
// Track leftover balance to rescue funds in case of external transfers into this contract
|
||||
vars.borrowedAssetLeftovers = vars.initFlashBorrowedBalance.sub(flashBorrowedAmount);
|
||||
}
|
||||
vars.flashLoanDebt = flashBorrowedAmount.add(premium);
|
||||
|
||||
// Approve LendingPool to use debt token for liquidation
|
||||
IERC20(borrowedAsset).approve(address(LENDING_POOL), debtToCover);
|
||||
|
||||
// Liquidate the user position and release the underlying collateral
|
||||
LENDING_POOL.liquidationCall(collateralAsset, borrowedAsset, user, debtToCover, false);
|
||||
|
||||
// Discover the liquidated tokens
|
||||
uint256 collateralBalanceAfter = IERC20(collateralAsset).balanceOf(address(this));
|
||||
|
||||
// Track only collateral released, not current asset balance of the contract
|
||||
vars.diffCollateralBalance = collateralBalanceAfter.sub(vars.initCollateralBalance);
|
||||
|
||||
if (collateralAsset != borrowedAsset) {
|
||||
// Discover flash loan balance after the liquidation
|
||||
uint256 flashBorrowedAssetAfter = IERC20(borrowedAsset).balanceOf(address(this));
|
||||
|
||||
// Use only flash loan borrowed assets, not current asset balance of the contract
|
||||
vars.diffFlashBorrowedBalance = flashBorrowedAssetAfter.sub(vars.borrowedAssetLeftovers);
|
||||
|
||||
// Swap released collateral into the debt asset, to repay the flash loan
|
||||
vars.soldAmount = _swapTokensForExactTokens(
|
||||
collateralAsset,
|
||||
borrowedAsset,
|
||||
vars.diffCollateralBalance,
|
||||
vars.flashLoanDebt.sub(vars.diffFlashBorrowedBalance),
|
||||
useEthPath
|
||||
);
|
||||
vars.remainingTokens = vars.diffCollateralBalance.sub(vars.soldAmount);
|
||||
} else {
|
||||
vars.remainingTokens = vars.diffCollateralBalance.sub(premium);
|
||||
}
|
||||
|
||||
// Allow repay of flash loan
|
||||
IERC20(borrowedAsset).approve(address(LENDING_POOL), vars.flashLoanDebt);
|
||||
|
||||
// Transfer remaining tokens to initiator
|
||||
if (vars.remainingTokens > 0) {
|
||||
IERC20(collateralAsset).transfer(initiator, vars.remainingTokens);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Decodes the information encoded in the flash loan params
|
||||
* @param params Additional variadic field to include extra params. Expected parameters:
|
||||
* address collateralAsset The collateral asset to claim
|
||||
* address borrowedAsset The asset that must be covered and will be exchanged to pay the flash loan premium
|
||||
* address user The user address with a Health Factor below 1
|
||||
* uint256 debtToCover The amount of debt to cover
|
||||
* bool useEthPath Use WETH as connector path between the collateralAsset and borrowedAsset at Uniswap
|
||||
* @return LiquidationParams struct containing decoded params
|
||||
*/
|
||||
function _decodeParams(bytes memory params) internal pure returns (LiquidationParams memory) {
|
||||
(
|
||||
address collateralAsset,
|
||||
address borrowedAsset,
|
||||
address user,
|
||||
uint256 debtToCover,
|
||||
bool useEthPath
|
||||
) = abi.decode(params, (address, address, address, uint256, bool));
|
||||
|
||||
return LiquidationParams(collateralAsset, borrowedAsset, user, debtToCover, useEthPath);
|
||||
}
|
||||
}
|
|
@ -234,6 +234,7 @@ contract UniswapRepayAdapter is BaseUniswapAdapter {
|
|||
* uint8 v V param for the permit signature
|
||||
* bytes32 r R param for the permit signature
|
||||
* bytes32 s S param for the permit signature
|
||||
* bool useEthPath use WETH path route
|
||||
* @return RepayParams struct containing decoded params
|
||||
*/
|
||||
function _decodeParams(bytes memory params) internal pure returns (RepayParams memory) {
|
||||
|
|
|
@ -12,11 +12,11 @@ pragma solidity 0.6.12;
|
|||
* This contract is only required for intermediate, library-like contracts.
|
||||
*/
|
||||
abstract contract Context {
|
||||
function _msgSender() internal virtual view returns (address payable) {
|
||||
function _msgSender() internal view virtual returns (address payable) {
|
||||
return msg.sender;
|
||||
}
|
||||
|
||||
function _msgData() internal virtual view returns (bytes memory) {
|
||||
function _msgData() internal view virtual returns (bytes memory) {
|
||||
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
|
||||
return msg.data;
|
||||
}
|
||||
|
|
|
@ -95,14 +95,14 @@ contract ERC20 is Context, IERC20 {
|
|||
/**
|
||||
* @dev See {IERC20-totalSupply}.
|
||||
*/
|
||||
function totalSupply() public override view returns (uint256) {
|
||||
function totalSupply() public view override returns (uint256) {
|
||||
return _totalSupply;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC20-balanceOf}.
|
||||
*/
|
||||
function balanceOf(address account) public override view returns (uint256) {
|
||||
function balanceOf(address account) public view override returns (uint256) {
|
||||
return _balances[account];
|
||||
}
|
||||
|
||||
|
@ -124,9 +124,9 @@ contract ERC20 is Context, IERC20 {
|
|||
*/
|
||||
function allowance(address owner, address spender)
|
||||
public
|
||||
view
|
||||
virtual
|
||||
override
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _allowances[owner][spender];
|
||||
|
|
|
@ -24,7 +24,8 @@ contract BaseAdminUpgradeabilityProxy is BaseUpgradeabilityProxy {
|
|||
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
|
||||
* validated in the constructor.
|
||||
*/
|
||||
bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
|
||||
bytes32 internal constant ADMIN_SLOT =
|
||||
0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
|
||||
|
||||
/**
|
||||
* @dev Modifier to check whether the `msg.sender` is the admin.
|
||||
|
|
|
@ -22,13 +22,14 @@ contract BaseUpgradeabilityProxy is Proxy {
|
|||
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
|
||||
* validated in the constructor.
|
||||
*/
|
||||
bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
|
||||
bytes32 internal constant IMPLEMENTATION_SLOT =
|
||||
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
|
||||
|
||||
/**
|
||||
* @dev Returns the current implementation.
|
||||
* @return impl Address of the current implementation
|
||||
*/
|
||||
function _implementation() internal override view returns (address impl) {
|
||||
function _implementation() internal view override returns (address impl) {
|
||||
bytes32 slot = IMPLEMENTATION_SLOT;
|
||||
//solium-disable-next-line
|
||||
assembly {
|
||||
|
|
|
@ -20,7 +20,7 @@ abstract contract Proxy {
|
|||
/**
|
||||
* @return The Address of the implementation.
|
||||
*/
|
||||
function _implementation() internal virtual view returns (address);
|
||||
function _implementation() internal view virtual returns (address);
|
||||
|
||||
/**
|
||||
* @dev Delegates execution to an implementation contract.
|
||||
|
|
|
@ -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
|
||||
|
@ -80,9 +82,26 @@ interface IAToken is IERC20, IScaledBalanceToken {
|
|||
/**
|
||||
* @dev Transfers the underlying asset to `target`. Used by the LendingPool to transfer
|
||||
* assets in borrow(), withdraw() and flashLoan()
|
||||
* @param user The recipient of the aTokens
|
||||
* @param user The recipient of the underlying
|
||||
* @param amount The amount getting transferred
|
||||
* @return The amount transferred
|
||||
**/
|
||||
function transferUnderlyingTo(address user, uint256 amount) external returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Invoked to execute actions on the aToken side after a repayment.
|
||||
* @param user The user executing the repayment
|
||||
* @param amount The amount getting repaid
|
||||
**/
|
||||
function handleRepayment(address user, uint256 amount) external;
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the incentives controller contract
|
||||
**/
|
||||
function getIncentivesController() external view returns (IAaveIncentivesController);
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH)
|
||||
**/
|
||||
function UNDERLYING_ASSET_ADDRESS() external view returns (address);
|
||||
}
|
||||
|
|
|
@ -3,9 +3,126 @@ pragma solidity 0.6.12;
|
|||
pragma experimental ABIEncoderV2;
|
||||
|
||||
interface IAaveIncentivesController {
|
||||
event RewardsAccrued(address indexed user, uint256 amount);
|
||||
|
||||
event RewardsClaimed(address indexed user, address indexed to, uint256 amount);
|
||||
|
||||
event RewardsClaimed(
|
||||
address indexed user,
|
||||
address indexed to,
|
||||
address indexed claimer,
|
||||
uint256 amount
|
||||
);
|
||||
|
||||
event ClaimerSet(address indexed user, address indexed claimer);
|
||||
|
||||
/*
|
||||
* @dev Returns the configuration of the distribution for a certain asset
|
||||
* @param asset The address of the reference asset of the distribution
|
||||
* @return The asset index, the emission per second and the last updated timestamp
|
||||
**/
|
||||
function getAssetData(address asset)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
uint256,
|
||||
uint256,
|
||||
uint256
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev Whitelists an address to claim the rewards on behalf of another address
|
||||
* @param user The address of the user
|
||||
* @param claimer The address of the claimer
|
||||
*/
|
||||
function setClaimer(address user, address claimer) external;
|
||||
|
||||
/**
|
||||
* @dev Returns the whitelisted claimer for a certain address (0x0 if not set)
|
||||
* @param user The address of the user
|
||||
* @return The claimer address
|
||||
*/
|
||||
function getClaimer(address user) external view returns (address);
|
||||
|
||||
/**
|
||||
* @dev Configure assets for a certain rewards emission
|
||||
* @param assets The assets to incentivize
|
||||
* @param emissionsPerSecond The emission for each asset
|
||||
*/
|
||||
function configureAssets(address[] calldata assets, uint256[] calldata emissionsPerSecond)
|
||||
external;
|
||||
|
||||
/**
|
||||
* @dev Called by the corresponding asset on any update that affects the rewards distribution
|
||||
* @param asset The address of the user
|
||||
* @param userBalance The balance of the user of the asset in the lending pool
|
||||
* @param totalSupply The total supply of the asset in the lending pool
|
||||
**/
|
||||
function handleAction(
|
||||
address user,
|
||||
address asset,
|
||||
uint256 userBalance,
|
||||
uint256 totalSupply
|
||||
) external;
|
||||
|
||||
/**
|
||||
* @dev Returns the total of rewards of an user, already accrued + not yet accrued
|
||||
* @param user The address of the user
|
||||
* @return The rewards
|
||||
**/
|
||||
function getRewardsBalance(address[] calldata assets, address user)
|
||||
external
|
||||
view
|
||||
returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Claims reward for an user, on all the assets of the lending pool, accumulating the pending rewards
|
||||
* @param amount Amount of rewards to claim
|
||||
* @param to Address that will be receiving the rewards
|
||||
* @return Rewards claimed
|
||||
**/
|
||||
function claimRewards(
|
||||
address[] calldata assets,
|
||||
uint256 amount,
|
||||
address to
|
||||
) external returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Claims reward for an user on behalf, on all the assets of the lending pool, accumulating the pending rewards. The caller must
|
||||
* be whitelisted via "allowClaimOnBehalf" function by the RewardsAdmin role manager
|
||||
* @param amount Amount of rewards to claim
|
||||
* @param user Address to check and claim rewards
|
||||
* @param to Address that will be receiving the rewards
|
||||
* @return Rewards claimed
|
||||
**/
|
||||
function claimRewardsOnBehalf(
|
||||
address[] calldata assets,
|
||||
uint256 amount,
|
||||
address user,
|
||||
address to
|
||||
) external returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev returns the unclaimed rewards of the user
|
||||
* @param user the address of the user
|
||||
* @return the unclaimed user rewards
|
||||
*/
|
||||
function getUserUnclaimedRewards(address user) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev returns the unclaimed rewards of the user
|
||||
* @param user the address of the user
|
||||
* @param asset The asset to incentivize
|
||||
* @return the user index for the asset
|
||||
*/
|
||||
function getUserAssetData(address user, address asset) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev for backward compatibility with previous implementation of the Incentives controller
|
||||
*/
|
||||
function REWARD_TOKEN() external view returns (address);
|
||||
|
||||
/**
|
||||
* @dev for backward compatibility with previous implementation of the Incentives controller
|
||||
*/
|
||||
function PRECISION() external view returns (uint8);
|
||||
}
|
||||
|
|
55
contracts/interfaces/IInitializableAToken.sol
Normal file
55
contracts/interfaces/IInitializableAToken.sol
Normal file
|
@ -0,0 +1,55 @@
|
|||
// 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 Emitted when an aToken is initialized
|
||||
* @param underlyingAsset The address of the underlying asset
|
||||
* @param pool The address of the associated lending pool
|
||||
* @param treasury The address of the treasury
|
||||
* @param incentivesController The address of the incentives controller for this aToken
|
||||
* @param aTokenDecimals the decimals of the underlying
|
||||
* @param aTokenName the name of the aToken
|
||||
* @param aTokenSymbol the symbol of the aToken
|
||||
* @param params A set of encoded parameters for additional initialization
|
||||
**/
|
||||
event Initialized(
|
||||
address indexed underlyingAsset,
|
||||
address indexed pool,
|
||||
address treasury,
|
||||
address incentivesController,
|
||||
uint8 aTokenDecimals,
|
||||
string aTokenName,
|
||||
string aTokenSymbol,
|
||||
bytes params
|
||||
);
|
||||
|
||||
/**
|
||||
* @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,
|
||||
bytes calldata params
|
||||
) external;
|
||||
}
|
51
contracts/interfaces/IInitializableDebtToken.sol
Normal file
51
contracts/interfaces/IInitializableDebtToken.sol
Normal file
|
@ -0,0 +1,51 @@
|
|||
// 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 Emitted when a debt token is initialized
|
||||
* @param underlyingAsset The address of the underlying asset
|
||||
* @param pool The address of the associated lending pool
|
||||
* @param incentivesController The address of the incentives controller for this aToken
|
||||
* @param debtTokenDecimals the decimals of the debt token
|
||||
* @param debtTokenName the name of the debt token
|
||||
* @param debtTokenSymbol the symbol of the debt token
|
||||
* @param params A set of encoded parameters for additional initialization
|
||||
**/
|
||||
event Initialized(
|
||||
address indexed underlyingAsset,
|
||||
address indexed pool,
|
||||
address incentivesController,
|
||||
uint8 debtTokenDecimals,
|
||||
string debtTokenName,
|
||||
string debtTokenSymbol,
|
||||
bytes params
|
||||
);
|
||||
|
||||
/**
|
||||
* @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,
|
||||
bytes calldata params
|
||||
) external;
|
||||
}
|
179
contracts/interfaces/ILendingPoolConfigurator.sol
Normal file
179
contracts/interfaces/ILendingPoolConfigurator.sol
Normal file
|
@ -0,0 +1,179 @@
|
|||
// 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;
|
||||
bytes params;
|
||||
}
|
||||
|
||||
struct UpdateATokenInput {
|
||||
address asset;
|
||||
address treasury;
|
||||
address incentivesController;
|
||||
string name;
|
||||
string symbol;
|
||||
address implementation;
|
||||
bytes params;
|
||||
}
|
||||
|
||||
struct UpdateDebtTokenInput {
|
||||
address asset;
|
||||
address incentivesController;
|
||||
string name;
|
||||
string symbol;
|
||||
address implementation;
|
||||
bytes params;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
);
|
||||
}
|
|
@ -13,7 +13,25 @@ interface IReserveInterestRateStrategy {
|
|||
|
||||
function calculateInterestRates(
|
||||
address reserve,
|
||||
uint256 utilizationRate,
|
||||
uint256 availableLiquidity,
|
||||
uint256 totalStableDebt,
|
||||
uint256 totalVariableDebt,
|
||||
uint256 averageStableBorrowRate,
|
||||
uint256 reserveFactor
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
uint256,
|
||||
uint256,
|
||||
uint256
|
||||
);
|
||||
|
||||
function calculateInterestRates(
|
||||
address reserve,
|
||||
address aToken,
|
||||
uint256 liquidityAdded,
|
||||
uint256 liquidityTaken,
|
||||
uint256 totalStableDebt,
|
||||
uint256 totalVariableDebt,
|
||||
uint256 averageStableBorrowRate,
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -11,14 +11,20 @@ interface IUniswapV2Router02 {
|
|||
) external returns (uint256[] memory amounts);
|
||||
|
||||
function swapTokensForExactTokens(
|
||||
uint amountOut,
|
||||
uint amountInMax,
|
||||
uint256 amountOut,
|
||||
uint256 amountInMax,
|
||||
address[] calldata path,
|
||||
address to,
|
||||
uint deadline
|
||||
uint256 deadline
|
||||
) external returns (uint256[] memory amounts);
|
||||
|
||||
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
|
||||
function getAmountsOut(uint256 amountIn, address[] calldata path)
|
||||
external
|
||||
view
|
||||
returns (uint256[] memory amounts);
|
||||
|
||||
function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
|
||||
function getAmountsIn(uint256 amountOut, address[] calldata path)
|
||||
external
|
||||
view
|
||||
returns (uint256[] memory amounts);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ contract AaveOracle is IPriceOracleGetter, Ownable {
|
|||
|
||||
/// @notice Gets an asset price by address
|
||||
/// @param asset The asset address
|
||||
function getAssetPrice(address asset) public override view returns (uint256) {
|
||||
function getAssetPrice(address asset) public view override returns (uint256) {
|
||||
IChainlinkAggregator source = assetsSources[asset];
|
||||
|
||||
if (asset == WETH) {
|
||||
|
|
|
@ -4,6 +4,7 @@ pragma experimental ABIEncoderV2;
|
|||
|
||||
import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
|
||||
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {IAaveIncentivesController} from '../interfaces/IAaveIncentivesController.sol';
|
||||
import {IUiPoolDataProvider} from './interfaces/IUiPoolDataProvider.sol';
|
||||
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
||||
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
||||
|
@ -24,6 +25,13 @@ contract UiPoolDataProvider is IUiPoolDataProvider {
|
|||
using UserConfiguration for DataTypes.UserConfigurationMap;
|
||||
|
||||
address public constant MOCK_USD_ADDRESS = 0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96;
|
||||
IAaveIncentivesController public immutable incentivesController;
|
||||
IPriceOracleGetter public immutable oracle;
|
||||
|
||||
constructor(IAaveIncentivesController _incentivesController, IPriceOracleGetter _oracle) public {
|
||||
incentivesController = _incentivesController;
|
||||
oracle = _oracle;
|
||||
}
|
||||
|
||||
function getInterestRateStrategySlopes(DefaultReserveInterestRateStrategy interestRateStrategy)
|
||||
internal
|
||||
|
@ -50,11 +58,11 @@ contract UiPoolDataProvider is IUiPoolDataProvider {
|
|||
returns (
|
||||
AggregatedReserveData[] memory,
|
||||
UserReserveData[] memory,
|
||||
uint256,
|
||||
uint256
|
||||
)
|
||||
{
|
||||
ILendingPool lendingPool = ILendingPool(provider.getLendingPool());
|
||||
IPriceOracleGetter oracle = IPriceOracleGetter(provider.getPriceOracle());
|
||||
address[] memory reserves = lendingPool.getReservesList();
|
||||
DataTypes.UserConfigurationMap memory userConfig = lendingPool.getUserConfiguration(user);
|
||||
|
||||
|
@ -122,7 +130,43 @@ contract UiPoolDataProvider is IUiPoolDataProvider {
|
|||
DefaultReserveInterestRateStrategy(reserveData.interestRateStrategyAddress)
|
||||
);
|
||||
|
||||
// incentives
|
||||
if (address(0) != address(incentivesController)) {
|
||||
(
|
||||
reserveData.aEmissionPerSecond,
|
||||
reserveData.aIncentivesLastUpdateTimestamp,
|
||||
reserveData.aTokenIncentivesIndex
|
||||
) = incentivesController.getAssetData(reserveData.aTokenAddress);
|
||||
|
||||
(
|
||||
reserveData.sEmissionPerSecond,
|
||||
reserveData.sIncentivesLastUpdateTimestamp,
|
||||
reserveData.sTokenIncentivesIndex
|
||||
) = incentivesController.getAssetData(reserveData.stableDebtTokenAddress);
|
||||
|
||||
(
|
||||
reserveData.vEmissionPerSecond,
|
||||
reserveData.vIncentivesLastUpdateTimestamp,
|
||||
reserveData.vTokenIncentivesIndex
|
||||
) = incentivesController.getAssetData(reserveData.variableDebtTokenAddress);
|
||||
}
|
||||
|
||||
if (user != address(0)) {
|
||||
// incentives
|
||||
if (address(0) != address(incentivesController)) {
|
||||
userReservesData[i].aTokenincentivesUserIndex = incentivesController.getUserAssetData(
|
||||
user,
|
||||
reserveData.aTokenAddress
|
||||
);
|
||||
userReservesData[i].vTokenincentivesUserIndex = incentivesController.getUserAssetData(
|
||||
user,
|
||||
reserveData.variableDebtTokenAddress
|
||||
);
|
||||
userReservesData[i].sTokenincentivesUserIndex = incentivesController.getUserAssetData(
|
||||
user,
|
||||
reserveData.stableDebtTokenAddress
|
||||
);
|
||||
}
|
||||
// user reserve data
|
||||
userReservesData[i].underlyingAsset = reserveData.underlyingAsset;
|
||||
userReservesData[i].scaledATokenBalance = IAToken(reserveData.aTokenAddress)
|
||||
|
@ -155,6 +199,12 @@ contract UiPoolDataProvider is IUiPoolDataProvider {
|
|||
}
|
||||
}
|
||||
}
|
||||
return (reservesData, userReservesData, oracle.getAssetPrice(MOCK_USD_ADDRESS));
|
||||
|
||||
return (
|
||||
reservesData,
|
||||
userReservesData,
|
||||
oracle.getAssetPrice(MOCK_USD_ADDRESS),
|
||||
incentivesController.getUserUnclaimedRewards(user)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,39 +18,47 @@ contract WETHGateway is IWETHGateway, Ownable {
|
|||
using UserConfiguration for DataTypes.UserConfigurationMap;
|
||||
|
||||
IWETH internal immutable WETH;
|
||||
ILendingPool internal immutable POOL;
|
||||
IAToken internal immutable aWETH;
|
||||
|
||||
/**
|
||||
* @dev Sets the WETH address and the LendingPoolAddressesProvider address. Infinite approves lending pool.
|
||||
* @param weth Address of the Wrapped Ether contract
|
||||
* @param pool Address of the LendingPool contract
|
||||
**/
|
||||
constructor(address weth, address pool) public {
|
||||
ILendingPool poolInstance = ILendingPool(pool);
|
||||
constructor(address weth) public {
|
||||
WETH = IWETH(weth);
|
||||
POOL = poolInstance;
|
||||
aWETH = IAToken(poolInstance.getReserveData(weth).aTokenAddress);
|
||||
IWETH(weth).approve(pool, uint256(-1));
|
||||
}
|
||||
|
||||
function authorizeLendingPool(address lendingPool) external onlyOwner {
|
||||
WETH.approve(lendingPool, uint256(-1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev deposits WETH into the reserve, using native ETH. A corresponding amount of the overlying asset (aTokens)
|
||||
* is minted.
|
||||
* @param lendingPool address of the targeted underlying lending pool
|
||||
* @param onBehalfOf address of the user who will receive the aTokens representing the deposit
|
||||
* @param referralCode integrators are assigned a referral code and can potentially receive rewards.
|
||||
**/
|
||||
function depositETH(address onBehalfOf, uint16 referralCode) external payable override {
|
||||
function depositETH(
|
||||
address lendingPool,
|
||||
address onBehalfOf,
|
||||
uint16 referralCode
|
||||
) external payable override {
|
||||
WETH.deposit{value: msg.value}();
|
||||
POOL.deposit(address(WETH), msg.value, onBehalfOf, referralCode);
|
||||
ILendingPool(lendingPool).deposit(address(WETH), msg.value, onBehalfOf, referralCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev withdraws the WETH _reserves of msg.sender.
|
||||
* @param lendingPool address of the targeted underlying lending pool
|
||||
* @param amount amount of aWETH to withdraw and receive native ETH
|
||||
* @param to address of the user who will receive native ETH
|
||||
*/
|
||||
function withdrawETH(uint256 amount, address to) external override {
|
||||
function withdrawETH(
|
||||
address lendingPool,
|
||||
uint256 amount,
|
||||
address to
|
||||
) external override {
|
||||
IAToken aWETH = IAToken(ILendingPool(lendingPool).getReserveData(address(WETH)).aTokenAddress);
|
||||
uint256 userBalance = aWETH.balanceOf(msg.sender);
|
||||
uint256 amountToWithdraw = amount;
|
||||
|
||||
|
@ -59,24 +67,29 @@ contract WETHGateway is IWETHGateway, Ownable {
|
|||
amountToWithdraw = userBalance;
|
||||
}
|
||||
aWETH.transferFrom(msg.sender, address(this), amountToWithdraw);
|
||||
POOL.withdraw(address(WETH), amountToWithdraw, address(this));
|
||||
ILendingPool(lendingPool).withdraw(address(WETH), amountToWithdraw, address(this));
|
||||
WETH.withdraw(amountToWithdraw);
|
||||
_safeTransferETH(to, amountToWithdraw);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev repays a borrow on the WETH reserve, for the specified amount (or for the whole amount, if uint256(-1) is specified).
|
||||
* @param lendingPool address of the targeted underlying lending pool
|
||||
* @param amount the amount to repay, or uint256(-1) if the user wants to repay everything
|
||||
* @param rateMode the rate mode to repay
|
||||
* @param onBehalfOf the address for which msg.sender is repaying
|
||||
*/
|
||||
function repayETH(
|
||||
address lendingPool,
|
||||
uint256 amount,
|
||||
uint256 rateMode,
|
||||
address onBehalfOf
|
||||
) external payable override {
|
||||
(uint256 stableDebt, uint256 variableDebt) =
|
||||
Helpers.getUserCurrentDebtMemory(onBehalfOf, POOL.getReserveData(address(WETH)));
|
||||
Helpers.getUserCurrentDebtMemory(
|
||||
onBehalfOf,
|
||||
ILendingPool(lendingPool).getReserveData(address(WETH))
|
||||
);
|
||||
|
||||
uint256 paybackAmount =
|
||||
DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.STABLE
|
||||
|
@ -88,7 +101,7 @@ contract WETHGateway is IWETHGateway, Ownable {
|
|||
}
|
||||
require(msg.value >= paybackAmount, 'msg.value is less than repayment amount');
|
||||
WETH.deposit{value: paybackAmount}();
|
||||
POOL.repay(address(WETH), msg.value, rateMode, onBehalfOf);
|
||||
ILendingPool(lendingPool).repay(address(WETH), msg.value, rateMode, onBehalfOf);
|
||||
|
||||
// refund remaining dust eth
|
||||
if (msg.value > paybackAmount) _safeTransferETH(msg.sender, msg.value - paybackAmount);
|
||||
|
@ -96,16 +109,24 @@ contract WETHGateway is IWETHGateway, Ownable {
|
|||
|
||||
/**
|
||||
* @dev borrow WETH, unwraps to ETH and send both the ETH and DebtTokens to msg.sender, via `approveDelegation` and onBehalf argument in `LendingPool.borrow`.
|
||||
* @param lendingPool address of the targeted underlying lending pool
|
||||
* @param amount the amount of ETH to borrow
|
||||
* @param interesRateMode the interest rate mode
|
||||
* @param referralCode integrators are assigned a referral code and can potentially receive rewards
|
||||
*/
|
||||
function borrowETH(
|
||||
address lendingPool,
|
||||
uint256 amount,
|
||||
uint256 interesRateMode,
|
||||
uint16 referralCode
|
||||
) external override {
|
||||
POOL.borrow(address(WETH), amount, interesRateMode, referralCode, msg.sender);
|
||||
ILendingPool(lendingPool).borrow(
|
||||
address(WETH),
|
||||
amount,
|
||||
interesRateMode,
|
||||
referralCode,
|
||||
msg.sender
|
||||
);
|
||||
WETH.withdraw(amount);
|
||||
_safeTransferETH(msg.sender, amount);
|
||||
}
|
||||
|
@ -152,20 +173,6 @@ contract WETHGateway is IWETHGateway, Ownable {
|
|||
return address(WETH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Get aWETH address used by WETHGateway
|
||||
*/
|
||||
function getAWETHAddress() external view returns (address) {
|
||||
return address(aWETH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Get LendingPool address used by WETHGateway
|
||||
*/
|
||||
function getLendingPoolAddress() external view returns (address) {
|
||||
return address(POOL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Only WETH contract is allowed to transfer ETH here. Prevent other addresses to send Ether to this contract.
|
||||
*/
|
||||
|
|
|
@ -93,7 +93,8 @@ contract WalletBalanceProvider {
|
|||
uint256[] memory balances = new uint256[](reservesWithEth.length);
|
||||
|
||||
for (uint256 j = 0; j < reserves.length; j++) {
|
||||
DataTypes.ReserveConfigurationMap memory configuration = pool.getConfiguration(reservesWithEth[j]);
|
||||
DataTypes.ReserveConfigurationMap memory configuration =
|
||||
pool.getConfiguration(reservesWithEth[j]);
|
||||
|
||||
(bool isActive, , , ) = configuration.getFlagsMemory();
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ pragma solidity 0.6.12;
|
|||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol';
|
||||
|
||||
interface IUiPoolDataProvider {
|
||||
struct AggregatedReserveData {
|
||||
|
@ -41,12 +42,17 @@ interface IUiPoolDataProvider {
|
|||
uint256 variableRateSlope2;
|
||||
uint256 stableRateSlope1;
|
||||
uint256 stableRateSlope2;
|
||||
// incentives
|
||||
uint256 aEmissionPerSecond;
|
||||
uint256 vEmissionPerSecond;
|
||||
uint256 sEmissionPerSecond;
|
||||
uint256 aIncentivesLastUpdateTimestamp;
|
||||
uint256 vIncentivesLastUpdateTimestamp;
|
||||
uint256 sIncentivesLastUpdateTimestamp;
|
||||
uint256 aTokenIncentivesIndex;
|
||||
uint256 vTokenIncentivesIndex;
|
||||
uint256 sTokenIncentivesIndex;
|
||||
}
|
||||
//
|
||||
// struct ReserveData {
|
||||
// uint256 averageStableBorrowRate;
|
||||
// uint256 totalLiquidity;
|
||||
// }
|
||||
|
||||
struct UserReserveData {
|
||||
address underlyingAsset;
|
||||
|
@ -56,38 +62,19 @@ interface IUiPoolDataProvider {
|
|||
uint256 scaledVariableDebt;
|
||||
uint256 principalStableDebt;
|
||||
uint256 stableBorrowLastUpdateTimestamp;
|
||||
// incentives
|
||||
uint256 aTokenincentivesUserIndex;
|
||||
uint256 vTokenincentivesUserIndex;
|
||||
uint256 sTokenincentivesUserIndex;
|
||||
}
|
||||
|
||||
//
|
||||
// struct ATokenSupplyData {
|
||||
// string name;
|
||||
// string symbol;
|
||||
// uint8 decimals;
|
||||
// uint256 totalSupply;
|
||||
// address aTokenAddress;
|
||||
// }
|
||||
|
||||
function getReservesData(ILendingPoolAddressesProvider provider, address user)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
AggregatedReserveData[] memory,
|
||||
UserReserveData[] memory,
|
||||
uint256,
|
||||
uint256
|
||||
);
|
||||
|
||||
// function getUserReservesData(ILendingPoolAddressesProvider provider, address user)
|
||||
// external
|
||||
// view
|
||||
// returns (UserReserveData[] memory);
|
||||
//
|
||||
// function getAllATokenSupply(ILendingPoolAddressesProvider provider)
|
||||
// external
|
||||
// view
|
||||
// returns (ATokenSupplyData[] memory);
|
||||
//
|
||||
// function getATokenSupply(address[] calldata aTokens)
|
||||
// external
|
||||
// view
|
||||
// returns (ATokenSupplyData[] memory);
|
||||
}
|
||||
|
|
|
@ -2,17 +2,27 @@
|
|||
pragma solidity 0.6.12;
|
||||
|
||||
interface IWETHGateway {
|
||||
function depositETH(address onBehalfOf, uint16 referralCode) external payable;
|
||||
function depositETH(
|
||||
address lendingPool,
|
||||
address onBehalfOf,
|
||||
uint16 referralCode
|
||||
) external payable;
|
||||
|
||||
function withdrawETH(uint256 amount, address onBehalfOf) external;
|
||||
function withdrawETH(
|
||||
address lendingPool,
|
||||
uint256 amount,
|
||||
address onBehalfOf
|
||||
) external;
|
||||
|
||||
function repayETH(
|
||||
address lendingPool,
|
||||
uint256 amount,
|
||||
uint256 rateMode,
|
||||
address onBehalfOf
|
||||
) external payable;
|
||||
|
||||
function borrowETH(
|
||||
address lendingPool,
|
||||
uint256 amount,
|
||||
uint256 interesRateMode,
|
||||
uint16 referralCode
|
||||
|
|
|
@ -68,9 +68,8 @@ contract MockFlashLoanReceiver is FlashLoanReceiverBase {
|
|||
'Invalid balance for the contract'
|
||||
);
|
||||
|
||||
uint256 amountToReturn = (_amountToApprove != 0)
|
||||
? _amountToApprove
|
||||
: amounts[i].add(premiums[i]);
|
||||
uint256 amountToReturn =
|
||||
(_amountToApprove != 0) ? _amountToApprove : amounts[i].add(premiums[i]);
|
||||
//execution does not fail - mint tokens and return them to the _destination
|
||||
|
||||
token.mint(premiums[i]);
|
||||
|
|
|
@ -8,7 +8,7 @@ contract LendingRateOracle is ILendingRateOracle, Ownable {
|
|||
mapping(address => uint256) borrowRates;
|
||||
mapping(address => uint256) liquidityRates;
|
||||
|
||||
function getMarketBorrowRate(address _asset) external override view returns (uint256) {
|
||||
function getMarketBorrowRate(address _asset) external view override returns (uint256) {
|
||||
return borrowRates[_asset];
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ contract PriceOracle is IPriceOracle {
|
|||
event AssetPriceUpdated(address _asset, uint256 _price, uint256 timestamp);
|
||||
event EthPriceUpdated(uint256 _price, uint256 timestamp);
|
||||
|
||||
function getAssetPrice(address _asset) external override view returns (uint256) {
|
||||
function getAssetPrice(address _asset) external view override returns (uint256) {
|
||||
return prices[_asset];
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
|||
import {PercentageMath} from '../libraries/math/PercentageMath.sol';
|
||||
import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {ILendingRateOracle} from '../../interfaces/ILendingRateOracle.sol';
|
||||
import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
|
||||
/**
|
||||
* @title DefaultReserveInterestRateStrategy contract
|
||||
|
@ -96,6 +97,51 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
|||
return _baseVariableBorrowRate.add(_variableRateSlope1).add(_variableRateSlope2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Calculates the interest rates depending on the reserve's state and configurations
|
||||
* @param reserve The address of the reserve
|
||||
* @param liquidityAdded The liquidity added during the operation
|
||||
* @param liquidityTaken The liquidity taken during the operation
|
||||
* @param totalStableDebt The total borrowed from the reserve a stable rate
|
||||
* @param totalVariableDebt The total borrowed from the reserve at a variable rate
|
||||
* @param averageStableBorrowRate The weighted average of all the stable rate loans
|
||||
* @param reserveFactor The reserve portion of the interest that goes to the treasury of the market
|
||||
* @return The liquidity rate, the stable borrow rate and the variable borrow rate
|
||||
**/
|
||||
function calculateInterestRates(
|
||||
address reserve,
|
||||
address aToken,
|
||||
uint256 liquidityAdded,
|
||||
uint256 liquidityTaken,
|
||||
uint256 totalStableDebt,
|
||||
uint256 totalVariableDebt,
|
||||
uint256 averageStableBorrowRate,
|
||||
uint256 reserveFactor
|
||||
)
|
||||
external
|
||||
view
|
||||
override
|
||||
returns (
|
||||
uint256,
|
||||
uint256,
|
||||
uint256
|
||||
)
|
||||
{
|
||||
uint256 availableLiquidity = IERC20(reserve).balanceOf(aToken);
|
||||
//avoid stack too deep
|
||||
availableLiquidity = availableLiquidity.add(liquidityAdded).sub(liquidityTaken);
|
||||
|
||||
return
|
||||
calculateInterestRates(
|
||||
reserve,
|
||||
availableLiquidity,
|
||||
totalStableDebt,
|
||||
totalVariableDebt,
|
||||
averageStableBorrowRate,
|
||||
reserveFactor
|
||||
);
|
||||
}
|
||||
|
||||
struct CalcInterestRatesLocalVars {
|
||||
uint256 totalDebt;
|
||||
uint256 currentVariableBorrowRate;
|
||||
|
@ -105,9 +151,11 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev Calculates the interest rates depending on the reserve's state and configurations
|
||||
* @dev Calculates the interest rates depending on the reserve's state and configurations.
|
||||
* NOTE This function is kept for compatibility with the previous DefaultInterestRateStrategy interface.
|
||||
* New protocol implementation uses the new calculateInterestRates() interface
|
||||
* @param reserve The address of the reserve
|
||||
* @param availableLiquidity The liquidity available in the reserve
|
||||
* @param availableLiquidity The liquidity available in the corresponding aToken
|
||||
* @param totalStableDebt The total borrowed from the reserve a stable rate
|
||||
* @param totalVariableDebt The total borrowed from the reserve at a variable rate
|
||||
* @param averageStableBorrowRate The weighted average of all the stable rate loans
|
||||
|
@ -122,7 +170,7 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
|||
uint256 averageStableBorrowRate,
|
||||
uint256 reserveFactor
|
||||
)
|
||||
external
|
||||
public
|
||||
view
|
||||
override
|
||||
returns (
|
||||
|
@ -138,17 +186,16 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
|||
vars.currentStableBorrowRate = 0;
|
||||
vars.currentLiquidityRate = 0;
|
||||
|
||||
uint256 utilizationRate =
|
||||
vars.totalDebt == 0
|
||||
? 0
|
||||
: vars.totalDebt.rayDiv(availableLiquidity.add(vars.totalDebt));
|
||||
vars.utilizationRate = vars.totalDebt == 0
|
||||
? 0
|
||||
: vars.totalDebt.rayDiv(availableLiquidity.add(vars.totalDebt));
|
||||
|
||||
vars.currentStableBorrowRate = ILendingRateOracle(addressesProvider.getLendingRateOracle())
|
||||
.getMarketBorrowRate(reserve);
|
||||
|
||||
if (utilizationRate > OPTIMAL_UTILIZATION_RATE) {
|
||||
if (vars.utilizationRate > OPTIMAL_UTILIZATION_RATE) {
|
||||
uint256 excessUtilizationRateRatio =
|
||||
utilizationRate.sub(OPTIMAL_UTILIZATION_RATE).rayDiv(EXCESS_UTILIZATION_RATE);
|
||||
vars.utilizationRate.sub(OPTIMAL_UTILIZATION_RATE).rayDiv(EXCESS_UTILIZATION_RATE);
|
||||
|
||||
vars.currentStableBorrowRate = vars.currentStableBorrowRate.add(_stableRateSlope1).add(
|
||||
_stableRateSlope2.rayMul(excessUtilizationRateRatio)
|
||||
|
@ -159,10 +206,10 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
|||
);
|
||||
} else {
|
||||
vars.currentStableBorrowRate = vars.currentStableBorrowRate.add(
|
||||
_stableRateSlope1.rayMul(utilizationRate.rayDiv(OPTIMAL_UTILIZATION_RATE))
|
||||
_stableRateSlope1.rayMul(vars.utilizationRate.rayDiv(OPTIMAL_UTILIZATION_RATE))
|
||||
);
|
||||
vars.currentVariableBorrowRate = _baseVariableBorrowRate.add(
|
||||
utilizationRate.rayMul(_variableRateSlope1).rayDiv(OPTIMAL_UTILIZATION_RATE)
|
||||
vars.utilizationRate.rayMul(_variableRateSlope1).rayDiv(OPTIMAL_UTILIZATION_RATE)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -173,7 +220,7 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
|||
.currentVariableBorrowRate,
|
||||
averageStableBorrowRate
|
||||
)
|
||||
.rayMul(utilizationRate)
|
||||
.rayMul(vars.utilizationRate)
|
||||
.percentMul(PercentageMath.PERCENTAGE_FACTOR.sub(reserveFactor));
|
||||
|
||||
return (
|
||||
|
|
|
@ -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() {
|
||||
|
@ -89,6 +85,9 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
**/
|
||||
function initialize(ILendingPoolAddressesProvider provider) public initializer {
|
||||
_addressesProvider = provider;
|
||||
_maxStableRateBorrowSizePercent = 2500;
|
||||
_flashLoanPremiumTotal = 9;
|
||||
_maxNumberOfReserves = 128;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -144,7 +143,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;
|
||||
|
@ -283,6 +282,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
|
||||
IERC20(asset).safeTransferFrom(msg.sender, aToken, paybackAmount);
|
||||
|
||||
IAToken(aToken).handleRepayment(msg.sender, paybackAmount);
|
||||
|
||||
emit Repay(asset, onBehalfOf, msg.sender, paybackAmount);
|
||||
|
||||
return paybackAmount;
|
||||
|
@ -442,6 +443,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
receiveAToken
|
||||
)
|
||||
);
|
||||
|
||||
require(success, Errors.LP_LIQUIDATION_CALL_FAILED);
|
||||
|
||||
(uint256 returnCode, string memory returnMessage) = abi.decode(result, (uint256, string));
|
||||
|
@ -499,7 +501,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 +705,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 +870,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
vars.amount,
|
||||
amountInETH,
|
||||
vars.interestRateMode,
|
||||
MAX_STABLE_RATE_BORROW_SIZE_PERCENT,
|
||||
_maxStableRateBorrowSizePercent,
|
||||
_reserves,
|
||||
userConfig,
|
||||
_reservesList,
|
||||
|
@ -909,7 +932,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,189 @@ 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 input) external onlyPoolAdmin {
|
||||
ILendingPool cachedPool = pool;
|
||||
for (uint256 i = 0; i < input.length; i++) {
|
||||
_initReserve(cachedPool, input[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 input) internal {
|
||||
address aTokenProxyAddress =
|
||||
_initTokenWithProxy(
|
||||
input.aTokenImpl,
|
||||
abi.encodeWithSelector(
|
||||
IInitializableAToken.initialize.selector,
|
||||
pool,
|
||||
input.treasury,
|
||||
input.underlyingAsset,
|
||||
IAaveIncentivesController(input.incentivesController),
|
||||
input.underlyingAssetDecimals,
|
||||
input.aTokenName,
|
||||
input.aTokenSymbol,
|
||||
input.params
|
||||
)
|
||||
);
|
||||
|
||||
address stableDebtTokenProxyAddress =
|
||||
_initTokenWithProxy(stableDebtTokenImpl, underlyingAssetDecimals);
|
||||
_initTokenWithProxy(
|
||||
input.stableDebtTokenImpl,
|
||||
abi.encodeWithSelector(
|
||||
IInitializableDebtToken.initialize.selector,
|
||||
pool,
|
||||
input.underlyingAsset,
|
||||
IAaveIncentivesController(input.incentivesController),
|
||||
input.underlyingAssetDecimals,
|
||||
input.stableDebtTokenName,
|
||||
input.stableDebtTokenSymbol,
|
||||
input.params
|
||||
)
|
||||
);
|
||||
|
||||
address variableDebtTokenProxyAddress =
|
||||
_initTokenWithProxy(variableDebtTokenImpl, underlyingAssetDecimals);
|
||||
_initTokenWithProxy(
|
||||
input.variableDebtTokenImpl,
|
||||
abi.encodeWithSelector(
|
||||
IInitializableDebtToken.initialize.selector,
|
||||
pool,
|
||||
input.underlyingAsset,
|
||||
IAaveIncentivesController(input.incentivesController),
|
||||
input.underlyingAssetDecimals,
|
||||
input.variableDebtTokenName,
|
||||
input.variableDebtTokenSymbol,
|
||||
input.params
|
||||
)
|
||||
);
|
||||
|
||||
pool.initReserve(
|
||||
asset,
|
||||
input.underlyingAsset,
|
||||
aTokenProxyAddress,
|
||||
stableDebtTokenProxyAddress,
|
||||
variableDebtTokenProxyAddress,
|
||||
interestRateStrategyAddress
|
||||
input.interestRateStrategyAddress
|
||||
);
|
||||
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig =
|
||||
pool.getConfiguration(input.underlyingAsset);
|
||||
|
||||
currentConfig.setDecimals(underlyingAssetDecimals);
|
||||
currentConfig.setDecimals(input.underlyingAssetDecimals);
|
||||
|
||||
currentConfig.setActive(true);
|
||||
currentConfig.setFrozen(false);
|
||||
|
||||
pool.setConfiguration(asset, currentConfig.data);
|
||||
pool.setConfiguration(input.underlyingAsset, currentConfig.data);
|
||||
|
||||
emit ReserveInitialized(
|
||||
asset,
|
||||
input.underlyingAsset,
|
||||
aTokenProxyAddress,
|
||||
stableDebtTokenProxyAddress,
|
||||
variableDebtTokenProxyAddress,
|
||||
interestRateStrategyAddress
|
||||
input.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 input) external onlyPoolAdmin {
|
||||
ILendingPool cachedPool = pool;
|
||||
|
||||
_upgradeTokenImplementation(asset, reserveData.aTokenAddress, implementation);
|
||||
DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(input.asset);
|
||||
|
||||
emit ATokenUpgraded(asset, reserveData.aTokenAddress, implementation);
|
||||
(, , , uint256 decimals, ) = cachedPool.getConfiguration(input.asset).getParamsMemory();
|
||||
|
||||
bytes memory encodedCall = abi.encodeWithSelector(
|
||||
IInitializableAToken.initialize.selector,
|
||||
cachedPool,
|
||||
input.treasury,
|
||||
input.asset,
|
||||
input.incentivesController,
|
||||
decimals,
|
||||
input.name,
|
||||
input.symbol,
|
||||
input.params
|
||||
);
|
||||
|
||||
_upgradeTokenImplementation(
|
||||
reserveData.aTokenAddress,
|
||||
input.implementation,
|
||||
encodedCall
|
||||
);
|
||||
|
||||
emit ATokenUpgraded(input.asset, reserveData.aTokenAddress, input.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 input) external onlyPoolAdmin {
|
||||
ILendingPool cachedPool = pool;
|
||||
|
||||
_upgradeTokenImplementation(asset, reserveData.stableDebtTokenAddress, implementation);
|
||||
DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(input.asset);
|
||||
|
||||
(, , , uint256 decimals, ) = cachedPool.getConfiguration(input.asset).getParamsMemory();
|
||||
|
||||
emit StableDebtTokenUpgraded(asset, reserveData.stableDebtTokenAddress, implementation);
|
||||
bytes memory encodedCall = abi.encodeWithSelector(
|
||||
IInitializableDebtToken.initialize.selector,
|
||||
cachedPool,
|
||||
input.asset,
|
||||
input.incentivesController,
|
||||
decimals,
|
||||
input.name,
|
||||
input.symbol,
|
||||
input.params
|
||||
);
|
||||
|
||||
_upgradeTokenImplementation(
|
||||
reserveData.stableDebtTokenAddress,
|
||||
input.implementation,
|
||||
encodedCall
|
||||
);
|
||||
|
||||
emit StableDebtTokenUpgraded(
|
||||
input.asset,
|
||||
reserveData.stableDebtTokenAddress,
|
||||
input.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 input)
|
||||
external
|
||||
onlyPoolAdmin
|
||||
{
|
||||
ILendingPool cachedPool = pool;
|
||||
|
||||
_upgradeTokenImplementation(asset, reserveData.variableDebtTokenAddress, implementation);
|
||||
DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(input.asset);
|
||||
|
||||
emit VariableDebtTokenUpgraded(asset, reserveData.variableDebtTokenAddress, implementation);
|
||||
(, , , uint256 decimals, ) = cachedPool.getConfiguration(input.asset).getParamsMemory();
|
||||
|
||||
bytes memory encodedCall = abi.encodeWithSelector(
|
||||
IInitializableDebtToken.initialize.selector,
|
||||
cachedPool,
|
||||
input.asset,
|
||||
input.incentivesController,
|
||||
decimals,
|
||||
input.name,
|
||||
input.symbol,
|
||||
input.params
|
||||
);
|
||||
|
||||
_upgradeTokenImplementation(
|
||||
reserveData.variableDebtTokenAddress,
|
||||
input.implementation,
|
||||
encodedCall
|
||||
);
|
||||
|
||||
emit VariableDebtTokenUpgraded(
|
||||
input.asset,
|
||||
reserveData.variableDebtTokenAddress,
|
||||
input.implementation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -509,44 +451,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;
|
||||
}
|
||||
|
|
|
@ -50,14 +50,14 @@ abstract contract VersionedInitializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev returns the revision number of the contract
|
||||
* Needs to be defined in the inherited class as a constant.
|
||||
**/
|
||||
* @dev returns the revision number of the contract
|
||||
* Needs to be defined in the inherited class as a constant.
|
||||
**/
|
||||
function getRevision() internal pure virtual returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Returns true if and only if the function is running in the constructor
|
||||
**/
|
||||
* @dev Returns true if and only if the function is running in the constructor
|
||||
**/
|
||||
function isConstructor() private view returns (bool) {
|
||||
// extcodesize checks the size of the code stored in an address, and
|
||||
// address returns the current address. Since the code is still not
|
||||
|
|
|
@ -90,7 +90,10 @@ library ReserveConfiguration {
|
|||
* @param self The reserve configuration
|
||||
* @param bonus The new liquidation bonus
|
||||
**/
|
||||
function setLiquidationBonus(DataTypes.ReserveConfigurationMap memory self, uint256 bonus) internal pure {
|
||||
function setLiquidationBonus(DataTypes.ReserveConfigurationMap memory self, uint256 bonus)
|
||||
internal
|
||||
pure
|
||||
{
|
||||
require(bonus <= MAX_VALID_LIQUIDATION_BONUS, Errors.RC_INVALID_LIQ_BONUS);
|
||||
|
||||
self.data =
|
||||
|
@ -116,7 +119,10 @@ library ReserveConfiguration {
|
|||
* @param self The reserve configuration
|
||||
* @param decimals The decimals
|
||||
**/
|
||||
function setDecimals(DataTypes.ReserveConfigurationMap memory self, uint256 decimals) internal pure {
|
||||
function setDecimals(DataTypes.ReserveConfigurationMap memory self, uint256 decimals)
|
||||
internal
|
||||
pure
|
||||
{
|
||||
require(decimals <= MAX_VALID_DECIMALS, Errors.RC_INVALID_DECIMALS);
|
||||
|
||||
self.data = (self.data & DECIMALS_MASK) | (decimals << RESERVE_DECIMALS_START_BIT_POSITION);
|
||||
|
@ -127,7 +133,11 @@ library ReserveConfiguration {
|
|||
* @param self The reserve configuration
|
||||
* @return The decimals of the asset
|
||||
**/
|
||||
function getDecimals(DataTypes.ReserveConfigurationMap storage self) internal view returns (uint256) {
|
||||
function getDecimals(DataTypes.ReserveConfigurationMap storage self)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return (self.data & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION;
|
||||
}
|
||||
|
||||
|
@ -176,7 +186,10 @@ library ReserveConfiguration {
|
|||
* @param self The reserve configuration
|
||||
* @param enabled True if the borrowing needs to be enabled, false otherwise
|
||||
**/
|
||||
function setBorrowingEnabled(DataTypes.ReserveConfigurationMap memory self, bool enabled) internal pure {
|
||||
function setBorrowingEnabled(DataTypes.ReserveConfigurationMap memory self, bool enabled)
|
||||
internal
|
||||
pure
|
||||
{
|
||||
self.data =
|
||||
(self.data & BORROWING_MASK) |
|
||||
(uint256(enabled ? 1 : 0) << BORROWING_ENABLED_START_BIT_POSITION);
|
||||
|
@ -187,7 +200,11 @@ library ReserveConfiguration {
|
|||
* @param self The reserve configuration
|
||||
* @return The borrowing state
|
||||
**/
|
||||
function getBorrowingEnabled(DataTypes.ReserveConfigurationMap storage self) internal view returns (bool) {
|
||||
function getBorrowingEnabled(DataTypes.ReserveConfigurationMap storage self)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return (self.data & ~BORROWING_MASK) != 0;
|
||||
}
|
||||
|
||||
|
@ -196,10 +213,10 @@ library ReserveConfiguration {
|
|||
* @param self The reserve configuration
|
||||
* @param enabled True if the stable rate borrowing needs to be enabled, false otherwise
|
||||
**/
|
||||
function setStableRateBorrowingEnabled(DataTypes.ReserveConfigurationMap memory self, bool enabled)
|
||||
internal
|
||||
pure
|
||||
{
|
||||
function setStableRateBorrowingEnabled(
|
||||
DataTypes.ReserveConfigurationMap memory self,
|
||||
bool enabled
|
||||
) internal pure {
|
||||
self.data =
|
||||
(self.data & STABLE_BORROWING_MASK) |
|
||||
(uint256(enabled ? 1 : 0) << STABLE_BORROWING_ENABLED_START_BIT_POSITION);
|
||||
|
@ -239,7 +256,11 @@ library ReserveConfiguration {
|
|||
* @param self The reserve configuration
|
||||
* @return The reserve factor
|
||||
**/
|
||||
function getReserveFactor(DataTypes.ReserveConfigurationMap storage self) internal view returns (uint256) {
|
||||
function getReserveFactor(DataTypes.ReserveConfigurationMap storage self)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return (self.data & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,11 +53,10 @@ library UserConfiguration {
|
|||
* @param reserveIndex The index of the reserve in the bitmap
|
||||
* @return True if the user has been using a reserve for borrowing or as collateral, false otherwise
|
||||
**/
|
||||
function isUsingAsCollateralOrBorrowing(DataTypes.UserConfigurationMap memory self, uint256 reserveIndex)
|
||||
internal
|
||||
pure
|
||||
returns (bool)
|
||||
{
|
||||
function isUsingAsCollateralOrBorrowing(
|
||||
DataTypes.UserConfigurationMap memory self,
|
||||
uint256 reserveIndex
|
||||
) internal pure returns (bool) {
|
||||
require(reserveIndex < 128, Errors.UL_INVALID_INDEX);
|
||||
return (self.data >> (reserveIndex * 2)) & 3 != 0;
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ library GenericLogic {
|
|||
if (!userConfig.isBorrowingAny() || !userConfig.isUsingAsCollateral(reservesData[asset].id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
balanceDecreaseAllowedLocalVars memory vars;
|
||||
|
||||
(, vars.liquidationThreshold, , vars.decimals, ) = reservesData[asset]
|
||||
|
@ -73,7 +73,7 @@ library GenericLogic {
|
|||
.getParams();
|
||||
|
||||
if (vars.liquidationThreshold == 0) {
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
(
|
||||
|
@ -213,9 +213,7 @@ library GenericLogic {
|
|||
}
|
||||
}
|
||||
|
||||
vars.avgLtv = vars.totalCollateralInETH > 0
|
||||
? vars.avgLtv.div(vars.totalCollateralInETH)
|
||||
: 0;
|
||||
vars.avgLtv = vars.totalCollateralInETH > 0 ? vars.avgLtv.div(vars.totalCollateralInETH) : 0;
|
||||
vars.avgLiquidationThreshold = vars.totalCollateralInETH > 0
|
||||
? vars.avgLiquidationThreshold.div(vars.totalCollateralInETH)
|
||||
: 0;
|
||||
|
@ -265,8 +263,7 @@ library GenericLogic {
|
|||
uint256 totalDebtInETH,
|
||||
uint256 ltv
|
||||
) internal pure returns (uint256) {
|
||||
|
||||
uint256 availableBorrowsETH = totalCollateralInETH.percentMul(ltv);
|
||||
uint256 availableBorrowsETH = totalCollateralInETH.percentMul(ltv);
|
||||
|
||||
if (availableBorrowsETH < totalDebtInETH) {
|
||||
return 0;
|
||||
|
|
|
@ -216,15 +216,15 @@ library ReserveLogic {
|
|||
.scaledTotalSupply()
|
||||
.rayMul(reserve.variableBorrowIndex);
|
||||
|
||||
vars.availableLiquidity = IERC20(reserveAddress).balanceOf(aTokenAddress);
|
||||
|
||||
(
|
||||
vars.newLiquidityRate,
|
||||
vars.newStableRate,
|
||||
vars.newVariableRate
|
||||
) = IReserveInterestRateStrategy(reserve.interestRateStrategyAddress).calculateInterestRates(
|
||||
reserveAddress,
|
||||
vars.availableLiquidity.add(liquidityAdded).sub(liquidityTaken),
|
||||
aTokenAddress,
|
||||
liquidityAdded,
|
||||
liquidityTaken,
|
||||
vars.totalStableDebt,
|
||||
vars.totalVariableDebt,
|
||||
vars.avgStableRate,
|
||||
|
|
|
@ -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,47 @@ 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,
|
||||
bytes calldata params
|
||||
) external override initializer {
|
||||
uint256 chainId;
|
||||
|
||||
//solium-disable-next-line
|
||||
|
@ -73,16 +81,32 @@ 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;
|
||||
|
||||
emit Initialized(
|
||||
underlyingAsset,
|
||||
address(pool),
|
||||
treasury,
|
||||
address(incentivesController),
|
||||
aTokenDecimals,
|
||||
aTokenName,
|
||||
aTokenSymbol,
|
||||
params
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,7 +127,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 +169,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 +211,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 +252,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 +263,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 override 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,10 +311,17 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
onlyLendingPool
|
||||
returns (uint256)
|
||||
{
|
||||
IERC20(UNDERLYING_ASSET_ADDRESS).safeTransfer(target, amount);
|
||||
IERC20(_underlyingAsset).safeTransfer(target, amount);
|
||||
return amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Invoked to execute actions on the aToken side after a repayment.
|
||||
* @param user The user executing the repayment
|
||||
* @param amount The amount getting repaid
|
||||
**/
|
||||
function handleRepayment(address user, uint256 amount) external override onlyLendingPool {}
|
||||
|
||||
/**
|
||||
* @dev implements the permit function as for
|
||||
* https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md
|
||||
|
@ -305,7 +373,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 +384,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,46 @@ 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,
|
||||
bytes calldata params
|
||||
) public override initializer {
|
||||
_setName(debtTokenName);
|
||||
_setSymbol(debtTokenSymbol);
|
||||
_setDecimals(debtTokenDecimals);
|
||||
|
||||
_pool = pool;
|
||||
_underlyingAsset = underlyingAsset;
|
||||
_incentivesController = incentivesController;
|
||||
|
||||
emit Initialized(
|
||||
underlyingAsset,
|
||||
address(pool),
|
||||
address(incentivesController),
|
||||
debtTokenDecimals,
|
||||
debtTokenName,
|
||||
debtTokenSymbol,
|
||||
params
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Gets the revision of the stable debt token implementation
|
||||
|
@ -300,6 +335,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,46 @@ 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,
|
||||
bytes calldata params
|
||||
) public override initializer {
|
||||
_setName(debtTokenName);
|
||||
_setSymbol(debtTokenSymbol);
|
||||
_setDecimals(debtTokenDecimals);
|
||||
|
||||
_pool = pool;
|
||||
_underlyingAsset = underlyingAsset;
|
||||
_incentivesController = incentivesController;
|
||||
|
||||
emit Initialized(
|
||||
underlyingAsset,
|
||||
address(pool),
|
||||
address(incentivesController),
|
||||
debtTokenDecimals,
|
||||
debtTokenName,
|
||||
debtTokenSymbol,
|
||||
params
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Gets the revision of the stable debt token implementation
|
||||
|
@ -44,7 +79,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
|||
return 0;
|
||||
}
|
||||
|
||||
return scaledBalance.rayMul(POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET_ADDRESS));
|
||||
return scaledBalance.rayMul(_pool.getReserveNormalizedVariableDebt(_underlyingAsset));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -113,8 +148,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 +173,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);
|
||||
}
|
||||
|
|
|
@ -19,3 +19,5 @@ services:
|
|||
TENDERLY_PROJECT: ${TENDERLY_PROJECT}
|
||||
TENDERLY_USERNAME: ${TENDERLY_USERNAME}
|
||||
ALCHEMY_KEY: ${ALCHEMY_KEY}
|
||||
TENDERLY_FORK_ID: ${TENDERLY_FORK_ID}
|
||||
TENDERLY_HEAD_ID: ${TENDERLY_HEAD_ID}
|
||||
|
|
|
@ -3,8 +3,9 @@ import fs from 'fs';
|
|||
import { HardhatUserConfig } from 'hardhat/types';
|
||||
// @ts-ignore
|
||||
import { accounts } from './test-wallets.js';
|
||||
import { eEthereumNetwork } from './helpers/types';
|
||||
import { eEthereumNetwork, eNetwork, ePolygonNetwork, eXDaiNetwork } from './helpers/types';
|
||||
import { BUIDLEREVM_CHAINID, COVERAGE_CHAINID } from './helpers/buidler-constants';
|
||||
import { NETWORKS_RPC_URL, NETWORKS_DEFAULT_GAS } from './helper-hardhat-config';
|
||||
|
||||
require('dotenv').config();
|
||||
|
||||
|
@ -14,14 +15,12 @@ import 'temp-hardhat-etherscan';
|
|||
import 'hardhat-gas-reporter';
|
||||
import 'hardhat-typechain';
|
||||
import '@tenderly/hardhat-tenderly';
|
||||
import 'solidity-coverage';
|
||||
|
||||
const SKIP_LOAD = process.env.SKIP_LOAD === 'true';
|
||||
const DEFAULT_BLOCK_GAS_LIMIT = 12450000;
|
||||
const DEFAULT_GAS_MUL = 5;
|
||||
const DEFAULT_GAS_PRICE = 65000000000;
|
||||
const HARDFORK = 'istanbul';
|
||||
const INFURA_KEY = process.env.INFURA_KEY || '';
|
||||
const ALCHEMY_KEY = process.env.ALCHEMY_KEY || '';
|
||||
const ETHERSCAN_KEY = process.env.ETHERSCAN_KEY || '';
|
||||
const MNEMONIC_PATH = "m/44'/60'/0'/0";
|
||||
const MNEMONIC = process.env.MNEMONIC || '';
|
||||
|
@ -43,32 +42,25 @@ if (!SKIP_LOAD) {
|
|||
|
||||
require(`${path.join(__dirname, 'tasks/misc')}/set-bre.ts`);
|
||||
|
||||
const getCommonNetworkConfig = (networkName: eEthereumNetwork, networkId: number) => {
|
||||
const net = networkName === 'main' ? 'mainnet' : networkName;
|
||||
return {
|
||||
url: ALCHEMY_KEY
|
||||
? `https://eth-${net}.alchemyapi.io/v2/${ALCHEMY_KEY}`
|
||||
: `https://${net}.infura.io/v3/${INFURA_KEY}`,
|
||||
hardfork: HARDFORK,
|
||||
blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT,
|
||||
gasMultiplier: DEFAULT_GAS_MUL,
|
||||
gasPrice: DEFAULT_GAS_PRICE,
|
||||
chainId: networkId,
|
||||
accounts: {
|
||||
mnemonic: MNEMONIC,
|
||||
path: MNEMONIC_PATH,
|
||||
initialIndex: 0,
|
||||
count: 20,
|
||||
},
|
||||
};
|
||||
};
|
||||
const getCommonNetworkConfig = (networkName: eNetwork, networkId: number) => ({
|
||||
url: NETWORKS_RPC_URL[networkName],
|
||||
hardfork: HARDFORK,
|
||||
blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT,
|
||||
gasMultiplier: DEFAULT_GAS_MUL,
|
||||
gasPrice: NETWORKS_DEFAULT_GAS[networkName],
|
||||
chainId: networkId,
|
||||
accounts: {
|
||||
mnemonic: MNEMONIC,
|
||||
path: MNEMONIC_PATH,
|
||||
initialIndex: 0,
|
||||
count: 20,
|
||||
},
|
||||
});
|
||||
|
||||
const mainnetFork = MAINNET_FORK
|
||||
? {
|
||||
blockNumber: 11608298,
|
||||
url: ALCHEMY_KEY
|
||||
? `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_KEY}`
|
||||
: `https://mainnet.infura.io/v3/${INFURA_KEY}`,
|
||||
blockNumber: 12012081,
|
||||
url: NETWORKS_RPC_URL['main'],
|
||||
}
|
||||
: undefined;
|
||||
|
||||
|
@ -103,9 +95,12 @@ const buidlerConfig: HardhatUserConfig = {
|
|||
kovan: getCommonNetworkConfig(eEthereumNetwork.kovan, 42),
|
||||
ropsten: getCommonNetworkConfig(eEthereumNetwork.ropsten, 3),
|
||||
main: getCommonNetworkConfig(eEthereumNetwork.main, 1),
|
||||
tenderlyMain: getCommonNetworkConfig(eEthereumNetwork.main, 1),
|
||||
tenderlyMain: getCommonNetworkConfig(eEthereumNetwork.tenderlyMain, 3030),
|
||||
matic: getCommonNetworkConfig(ePolygonNetwork.matic, 137),
|
||||
mumbai: getCommonNetworkConfig(ePolygonNetwork.mumbai, 80001),
|
||||
xdai: getCommonNetworkConfig(eXDaiNetwork.xdai, 100),
|
||||
hardhat: {
|
||||
hardfork: 'istanbul',
|
||||
hardfork: 'berlin',
|
||||
blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT,
|
||||
gas: DEFAULT_BLOCK_GAS_LIMIT,
|
||||
gasPrice: 8000000000,
|
||||
|
@ -119,7 +114,7 @@ const buidlerConfig: HardhatUserConfig = {
|
|||
forking: mainnetFork,
|
||||
},
|
||||
buidlerevm_docker: {
|
||||
hardfork: 'istanbul',
|
||||
hardfork: 'berlin',
|
||||
blockGasLimit: 9500000,
|
||||
gas: 9500000,
|
||||
gasPrice: 8000000000,
|
||||
|
|
47
helper-hardhat-config.ts
Normal file
47
helper-hardhat-config.ts
Normal file
|
@ -0,0 +1,47 @@
|
|||
// @ts-ignore
|
||||
import {
|
||||
eEthereumNetwork,
|
||||
ePolygonNetwork,
|
||||
eXDaiNetwork,
|
||||
iParamsPerNetwork,
|
||||
} from './helpers/types';
|
||||
|
||||
require('dotenv').config();
|
||||
|
||||
const INFURA_KEY = process.env.INFURA_KEY || '';
|
||||
const ALCHEMY_KEY = process.env.ALCHEMY_KEY || '';
|
||||
const TENDERLY_FORK_ID = process.env.TENDERLY_FORK_ID || '';
|
||||
|
||||
const GWEI = 1000 * 1000 * 1000;
|
||||
|
||||
export const NETWORKS_RPC_URL: iParamsPerNetwork<string> = {
|
||||
[eEthereumNetwork.kovan]: ALCHEMY_KEY
|
||||
? `https://eth-kovan.alchemyapi.io/v2/${ALCHEMY_KEY}`
|
||||
: `https://kovan.infura.io/v3/${INFURA_KEY}`,
|
||||
[eEthereumNetwork.ropsten]: ALCHEMY_KEY
|
||||
? `https://eth-ropsten.alchemyapi.io/v2/${ALCHEMY_KEY}`
|
||||
: `https://ropsten.infura.io/v3/${INFURA_KEY}`,
|
||||
[eEthereumNetwork.main]: ALCHEMY_KEY
|
||||
? `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_KEY}`
|
||||
: `https://mainnet.infura.io/v3/${INFURA_KEY}`,
|
||||
[eEthereumNetwork.coverage]: 'http://localhost:8555',
|
||||
[eEthereumNetwork.hardhat]: 'http://localhost:8545',
|
||||
[eEthereumNetwork.buidlerevm]: 'http://localhost:8545',
|
||||
[eEthereumNetwork.tenderlyMain]: `https://rpc.tenderly.co/fork/${TENDERLY_FORK_ID}`,
|
||||
[ePolygonNetwork.mumbai]: 'https://rpc-mumbai.maticvigil.com',
|
||||
[ePolygonNetwork.matic]: 'https://rpc-mainnet.matic.network',
|
||||
[eXDaiNetwork.xdai]: 'https://rpc.xdaichain.com/',
|
||||
};
|
||||
|
||||
export const NETWORKS_DEFAULT_GAS: iParamsPerNetwork<number> = {
|
||||
[eEthereumNetwork.kovan]: 65 * GWEI,
|
||||
[eEthereumNetwork.ropsten]: 65 * GWEI,
|
||||
[eEthereumNetwork.main]: 65 * GWEI,
|
||||
[eEthereumNetwork.coverage]: 65 * GWEI,
|
||||
[eEthereumNetwork.hardhat]: 65 * GWEI,
|
||||
[eEthereumNetwork.buidlerevm]: 65 * GWEI,
|
||||
[eEthereumNetwork.tenderlyMain]: 0.01 * GWEI,
|
||||
[ePolygonNetwork.mumbai]: 1 * GWEI,
|
||||
[ePolygonNetwork.matic]: 2 * GWEI,
|
||||
[eXDaiNetwork.xdai]: 1 * GWEI,
|
||||
};
|
|
@ -4,10 +4,12 @@ import {
|
|||
IReserveParams,
|
||||
PoolConfiguration,
|
||||
ICommonConfiguration,
|
||||
eEthereumNetwork,
|
||||
eNetwork,
|
||||
} from './types';
|
||||
import { getParamPerPool } from './contracts-helpers';
|
||||
import AaveConfig from '../markets/aave';
|
||||
import MaticConfig from '../markets/matic';
|
||||
import AmmConfig from '../markets/amm';
|
||||
import { CommonsConfig } from '../markets/aave/commons';
|
||||
import { DRE, filterMapBy } from './misc-utils';
|
||||
import { tEthereumAddress } from './types';
|
||||
|
@ -17,13 +19,18 @@ import { deployWETHMocked } from './contracts-deployments';
|
|||
export enum ConfigNames {
|
||||
Commons = 'Commons',
|
||||
Aave = 'Aave',
|
||||
Uniswap = 'Uniswap',
|
||||
Matic = 'Matic',
|
||||
Amm = 'Amm',
|
||||
}
|
||||
|
||||
export const loadPoolConfig = (configName: ConfigNames): PoolConfiguration => {
|
||||
switch (configName) {
|
||||
case ConfigNames.Aave:
|
||||
return AaveConfig;
|
||||
case ConfigNames.Matic:
|
||||
return MaticConfig;
|
||||
case ConfigNames.Amm:
|
||||
return AmmConfig;
|
||||
case ConfigNames.Commons:
|
||||
return CommonsConfig;
|
||||
default:
|
||||
|
@ -41,6 +48,12 @@ export const getReservesConfigByPool = (pool: AavePools): iMultiPoolsAssets<IRes
|
|||
[AavePools.proto]: {
|
||||
...AaveConfig.ReservesConfig,
|
||||
},
|
||||
[AavePools.amm]: {
|
||||
...AmmConfig.ReservesConfig,
|
||||
},
|
||||
[AavePools.matic]: {
|
||||
...MaticConfig.ReservesConfig,
|
||||
},
|
||||
},
|
||||
pool
|
||||
);
|
||||
|
@ -49,7 +62,7 @@ export const getGenesisPoolAdmin = async (
|
|||
config: ICommonConfiguration
|
||||
): Promise<tEthereumAddress> => {
|
||||
const currentNetwork = process.env.MAINNET_FORK === 'true' ? 'main' : DRE.network.name;
|
||||
const targetAddress = getParamPerNetwork(config.PoolAdmin, <eEthereumNetwork>currentNetwork);
|
||||
const targetAddress = getParamPerNetwork(config.PoolAdmin, <eNetwork>currentNetwork);
|
||||
if (targetAddress) {
|
||||
return targetAddress;
|
||||
}
|
||||
|
@ -64,7 +77,7 @@ export const getEmergencyAdmin = async (
|
|||
config: ICommonConfiguration
|
||||
): Promise<tEthereumAddress> => {
|
||||
const currentNetwork = process.env.MAINNET_FORK === 'true' ? 'main' : DRE.network.name;
|
||||
const targetAddress = getParamPerNetwork(config.EmergencyAdmin, <eEthereumNetwork>currentNetwork);
|
||||
const targetAddress = getParamPerNetwork(config.EmergencyAdmin, <eNetwork>currentNetwork);
|
||||
if (targetAddress) {
|
||||
return targetAddress;
|
||||
}
|
||||
|
@ -79,17 +92,17 @@ export const getTreasuryAddress = async (
|
|||
config: ICommonConfiguration
|
||||
): Promise<tEthereumAddress> => {
|
||||
const currentNetwork = process.env.MAINNET_FORK === 'true' ? 'main' : DRE.network.name;
|
||||
return getParamPerNetwork(config.ReserveFactorTreasuryAddress, <eEthereumNetwork>currentNetwork);
|
||||
return getParamPerNetwork(config.ReserveFactorTreasuryAddress, <eNetwork>currentNetwork);
|
||||
};
|
||||
|
||||
export const getATokenDomainSeparatorPerNetwork = (
|
||||
network: eEthereumNetwork,
|
||||
network: eNetwork,
|
||||
config: ICommonConfiguration
|
||||
): tEthereumAddress => getParamPerNetwork<tEthereumAddress>(config.ATokenDomainSeparator, network);
|
||||
|
||||
export const getWethAddress = async (config: ICommonConfiguration) => {
|
||||
const currentNetwork = process.env.MAINNET_FORK === 'true' ? 'main' : DRE.network.name;
|
||||
const wethAddress = getParamPerNetwork(config.WETH, <eEthereumNetwork>currentNetwork);
|
||||
const wethAddress = getParamPerNetwork(config.WETH, <eNetwork>currentNetwork);
|
||||
if (wethAddress) {
|
||||
return wethAddress;
|
||||
}
|
||||
|
|
|
@ -28,3 +28,46 @@ export const TOKEN_DISTRIBUTOR_PERCENTAGE_BASE = '10000';
|
|||
export const MOCK_USD_PRICE_IN_WEI = '5848466240000000';
|
||||
export const USD_ADDRESS = '0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96';
|
||||
export const AAVE_REFERRAL = '0';
|
||||
|
||||
export const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
|
||||
AAVE: oneEther.multipliedBy('0.003620948469').toFixed(),
|
||||
BAT: oneEther.multipliedBy('0.00137893825230').toFixed(),
|
||||
BUSD: oneEther.multipliedBy('0.00736484').toFixed(),
|
||||
DAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
|
||||
ENJ: oneEther.multipliedBy('0.00029560').toFixed(),
|
||||
KNC: oneEther.multipliedBy('0.001072').toFixed(),
|
||||
LINK: oneEther.multipliedBy('0.009955').toFixed(),
|
||||
MANA: oneEther.multipliedBy('0.000158').toFixed(),
|
||||
MKR: oneEther.multipliedBy('2.508581').toFixed(),
|
||||
REN: oneEther.multipliedBy('0.00065133').toFixed(),
|
||||
SNX: oneEther.multipliedBy('0.00442616').toFixed(),
|
||||
SUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
|
||||
TUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
|
||||
UNI: oneEther.multipliedBy('0.00536479').toFixed(),
|
||||
USDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
|
||||
USDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
|
||||
WETH: oneEther.toFixed(),
|
||||
WBTC: oneEther.multipliedBy('47.332685').toFixed(),
|
||||
YFI: oneEther.multipliedBy('22.407436').toFixed(),
|
||||
ZRX: oneEther.multipliedBy('0.001151').toFixed(),
|
||||
UniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
|
||||
UniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
|
||||
UniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
|
||||
UniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
|
||||
UniDAIUSDC: oneEther.multipliedBy('22.407436').toFixed(),
|
||||
UniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
|
||||
UniLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
|
||||
UniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
|
||||
UniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
|
||||
UniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
|
||||
UniUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
|
||||
UniUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
|
||||
UniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
|
||||
UniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
|
||||
BptWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
|
||||
BptBALWETH: oneEther.multipliedBy('22.407436').toFixed(),
|
||||
WMATIC: oneEther.multipliedBy('0.003620948469').toFixed(),
|
||||
STAKE: oneEther.multipliedBy('0.003620948469').toFixed(),
|
||||
xSUSHI: oneEther.multipliedBy('0.00913428586').toFixed(),
|
||||
USD: '5848466240000000',
|
||||
};
|
||||
|
|
|
@ -11,7 +11,6 @@ import {
|
|||
PoolConfiguration,
|
||||
eEthereumNetwork,
|
||||
} from './types';
|
||||
|
||||
import { MintableERC20 } from '../types/MintableERC20';
|
||||
import { MockContract } from 'ethereum-waffle';
|
||||
import { getReservesConfigByPool } from './configuration';
|
||||
|
@ -49,18 +48,35 @@ import {
|
|||
WalletBalanceProviderFactory,
|
||||
WETH9MockedFactory,
|
||||
WETHGatewayFactory,
|
||||
FlashLiquidationAdapterFactory,
|
||||
} from '../types';
|
||||
import {
|
||||
withSaveAndVerify,
|
||||
registerContractInJsonDb,
|
||||
linkBytecode,
|
||||
insertContractAddressInDb,
|
||||
deployContract,
|
||||
} from './contracts-helpers';
|
||||
import { StableAndVariableTokensHelperFactory } from '../types/StableAndVariableTokensHelperFactory';
|
||||
import { MintableDelegationERC20 } from '../types/MintableDelegationERC20';
|
||||
import { readArtifact as buidlerReadArtifact } from '@nomiclabs/buidler/plugins';
|
||||
import { HardhatRuntimeEnvironment } from 'hardhat/types';
|
||||
import { LendingPoolLibraryAddresses } from '../types/LendingPoolFactory';
|
||||
import { UiPoolDataProvider } from '../types';
|
||||
import { verifyContract } from './etherscan-verification';
|
||||
|
||||
export const deployUiPoolDataProvider = async (
|
||||
[incentivesController, aaveOracle]: [tEthereumAddress, tEthereumAddress],
|
||||
verify?: boolean
|
||||
) => {
|
||||
const id = eContractid.UiPoolDataProvider;
|
||||
const args: string[] = [incentivesController, aaveOracle];
|
||||
const instance = await deployContract<UiPoolDataProvider>(id, args);
|
||||
if (verify) {
|
||||
await verifyContract(instance.address, args);
|
||||
}
|
||||
return instance;
|
||||
};
|
||||
|
||||
const readArtifact = async (id: string) => {
|
||||
if (DRE.network.name === eEthereumNetwork.buidlerevm) {
|
||||
|
@ -68,6 +84,7 @@ const readArtifact = async (id: string) => {
|
|||
}
|
||||
return (DRE as HardhatRuntimeEnvironment).artifacts.readArtifact(id);
|
||||
};
|
||||
|
||||
export const deployLendingPoolAddressesProvider = async (marketId: string, verify?: boolean) =>
|
||||
withSaveAndVerify(
|
||||
await new LendingPoolAddressesProviderFactory(await getFirstSigner()).deploy(marketId),
|
||||
|
@ -299,82 +316,133 @@ export const deployDefaultReserveInterestRateStrategy = async (
|
|||
);
|
||||
|
||||
export const deployStableDebtToken = async (
|
||||
args: [tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress],
|
||||
args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string],
|
||||
verify: boolean
|
||||
) =>
|
||||
withSaveAndVerify(
|
||||
await new StableDebtTokenFactory(await getFirstSigner()).deploy(...args),
|
||||
) => {
|
||||
const instance = await withSaveAndVerify(
|
||||
await new StableDebtTokenFactory(await getFirstSigner()).deploy(),
|
||||
eContractid.StableDebtToken,
|
||||
args,
|
||||
[],
|
||||
verify
|
||||
);
|
||||
|
||||
await instance.initialize(args[0], args[1], args[2], '18', args[3], args[4], '0x10');
|
||||
|
||||
return instance;
|
||||
};
|
||||
|
||||
export const deployVariableDebtToken = async (
|
||||
args: [tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress],
|
||||
args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string],
|
||||
verify: boolean
|
||||
) =>
|
||||
withSaveAndVerify(
|
||||
await new VariableDebtTokenFactory(await getFirstSigner()).deploy(...args),
|
||||
) => {
|
||||
const instance = await withSaveAndVerify(
|
||||
await new VariableDebtTokenFactory(await getFirstSigner()).deploy(),
|
||||
eContractid.VariableDebtToken,
|
||||
args,
|
||||
[],
|
||||
verify
|
||||
);
|
||||
|
||||
await instance.initialize(args[0], args[1], args[2], '18', args[3], args[4], '0x10');
|
||||
|
||||
return instance;
|
||||
};
|
||||
|
||||
export const deployGenericStableDebtToken = async () =>
|
||||
withSaveAndVerify(
|
||||
await new StableDebtTokenFactory(await getFirstSigner()).deploy(),
|
||||
eContractid.StableDebtToken,
|
||||
[],
|
||||
false
|
||||
);
|
||||
|
||||
export const deployGenericVariableDebtToken = async () =>
|
||||
withSaveAndVerify(
|
||||
await new VariableDebtTokenFactory(await getFirstSigner()).deploy(),
|
||||
eContractid.VariableDebtToken,
|
||||
[],
|
||||
false
|
||||
);
|
||||
|
||||
export const deployGenericAToken = async (
|
||||
[poolAddress, underlyingAssetAddress, treasuryAddress, name, symbol, incentivesController]: [
|
||||
[poolAddress, underlyingAssetAddress, treasuryAddress, incentivesController, name, symbol]: [
|
||||
tEthereumAddress,
|
||||
tEthereumAddress,
|
||||
tEthereumAddress,
|
||||
tEthereumAddress,
|
||||
string,
|
||||
string,
|
||||
tEthereumAddress
|
||||
string
|
||||
],
|
||||
verify: boolean
|
||||
) => {
|
||||
const args: [
|
||||
tEthereumAddress,
|
||||
tEthereumAddress,
|
||||
string,
|
||||
string,
|
||||
tEthereumAddress,
|
||||
tEthereumAddress
|
||||
] = [poolAddress, underlyingAssetAddress, treasuryAddress, name, symbol, incentivesController];
|
||||
return withSaveAndVerify(
|
||||
await new ATokenFactory(await getFirstSigner()).deploy(...args),
|
||||
const instance = await withSaveAndVerify(
|
||||
await new ATokenFactory(await getFirstSigner()).deploy(),
|
||||
eContractid.AToken,
|
||||
args,
|
||||
[],
|
||||
verify
|
||||
);
|
||||
|
||||
await instance.initialize(
|
||||
poolAddress,
|
||||
treasuryAddress,
|
||||
underlyingAssetAddress,
|
||||
incentivesController,
|
||||
'18',
|
||||
name,
|
||||
symbol,
|
||||
'0x10'
|
||||
);
|
||||
|
||||
return instance;
|
||||
};
|
||||
|
||||
export const deployGenericATokenImpl = async (verify: boolean) =>
|
||||
withSaveAndVerify(
|
||||
await new ATokenFactory(await getFirstSigner()).deploy(),
|
||||
eContractid.AToken,
|
||||
[],
|
||||
verify
|
||||
);
|
||||
|
||||
export const deployDelegationAwareAToken = async (
|
||||
[poolAddress, underlyingAssetAddress, treasuryAddress, name, symbol, incentivesController]: [
|
||||
[pool, underlyingAssetAddress, treasuryAddress, incentivesController, name, symbol]: [
|
||||
tEthereumAddress,
|
||||
tEthereumAddress,
|
||||
tEthereumAddress,
|
||||
tEthereumAddress,
|
||||
string,
|
||||
string,
|
||||
tEthereumAddress
|
||||
string
|
||||
],
|
||||
verify: boolean
|
||||
) => {
|
||||
const args: [
|
||||
tEthereumAddress,
|
||||
tEthereumAddress,
|
||||
string,
|
||||
string,
|
||||
tEthereumAddress,
|
||||
tEthereumAddress
|
||||
] = [poolAddress, underlyingAssetAddress, treasuryAddress, name, symbol, incentivesController];
|
||||
|
||||
return withSaveAndVerify(
|
||||
await new DelegationAwareATokenFactory(await getFirstSigner()).deploy(...args),
|
||||
const instance = await withSaveAndVerify(
|
||||
await new DelegationAwareATokenFactory(await getFirstSigner()).deploy(),
|
||||
eContractid.DelegationAwareAToken,
|
||||
args,
|
||||
[],
|
||||
verify
|
||||
);
|
||||
|
||||
await instance.initialize(
|
||||
pool,
|
||||
treasuryAddress,
|
||||
underlyingAssetAddress,
|
||||
incentivesController,
|
||||
'18',
|
||||
name,
|
||||
symbol,
|
||||
'0x10'
|
||||
);
|
||||
|
||||
return instance;
|
||||
};
|
||||
|
||||
export const deployDelegationAwareATokenImpl = async (verify: boolean) =>
|
||||
withSaveAndVerify(
|
||||
await new DelegationAwareATokenFactory(await getFirstSigner()).deploy(),
|
||||
eContractid.DelegationAwareAToken,
|
||||
[],
|
||||
verify
|
||||
);
|
||||
|
||||
export const deployAllMockTokens = async (verify?: boolean) => {
|
||||
const tokens: { [symbol: string]: MockContract | MintableERC20 } = {};
|
||||
|
||||
|
@ -389,6 +457,7 @@ export const deployAllMockTokens = async (verify?: boolean) => {
|
|||
[tokenSymbol, tokenSymbol, configData ? configData.reserveDecimals : decimals],
|
||||
verify
|
||||
);
|
||||
await registerContractInJsonDb(tokenSymbol.toUpperCase(), tokens[tokenSymbol]);
|
||||
}
|
||||
return tokens;
|
||||
};
|
||||
|
@ -436,10 +505,7 @@ export const deployATokensAndRatesHelper = async (
|
|||
verify
|
||||
);
|
||||
|
||||
export const deployWETHGateway = async (
|
||||
args: [tEthereumAddress, tEthereumAddress],
|
||||
verify?: boolean
|
||||
) =>
|
||||
export const deployWETHGateway = async (args: [tEthereumAddress], verify?: boolean) =>
|
||||
withSaveAndVerify(
|
||||
await new WETHGatewayFactory(await getFirstSigner()).deploy(...args),
|
||||
eContractid.WETHGateway,
|
||||
|
@ -447,17 +513,30 @@ export const deployWETHGateway = async (
|
|||
verify
|
||||
);
|
||||
|
||||
export const deployMockStableDebtToken = async (
|
||||
args: [tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress],
|
||||
verify?: boolean
|
||||
export const authorizeWETHGateway = async (
|
||||
wethGateWay: tEthereumAddress,
|
||||
lendingPool: tEthereumAddress
|
||||
) =>
|
||||
withSaveAndVerify(
|
||||
await new MockStableDebtTokenFactory(await getFirstSigner()).deploy(...args),
|
||||
await new WETHGatewayFactory(await getFirstSigner())
|
||||
.attach(wethGateWay)
|
||||
.authorizeLendingPool(lendingPool);
|
||||
|
||||
export const deployMockStableDebtToken = async (
|
||||
args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string, string],
|
||||
verify?: boolean
|
||||
) => {
|
||||
const instance = await withSaveAndVerify(
|
||||
await new MockStableDebtTokenFactory(await getFirstSigner()).deploy(),
|
||||
eContractid.MockStableDebtToken,
|
||||
args,
|
||||
[],
|
||||
verify
|
||||
);
|
||||
|
||||
await instance.initialize(args[0], args[1], args[2], '18', args[3], args[4], args[5]);
|
||||
|
||||
return instance;
|
||||
};
|
||||
|
||||
export const deployWETHMocked = async (verify?: boolean) =>
|
||||
withSaveAndVerify(
|
||||
await new WETH9MockedFactory(await getFirstSigner()).deploy(),
|
||||
|
@ -467,27 +546,45 @@ export const deployWETHMocked = async (verify?: boolean) =>
|
|||
);
|
||||
|
||||
export const deployMockVariableDebtToken = async (
|
||||
args: [tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress],
|
||||
args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string, string],
|
||||
verify?: boolean
|
||||
) =>
|
||||
withSaveAndVerify(
|
||||
await new MockVariableDebtTokenFactory(await getFirstSigner()).deploy(...args),
|
||||
) => {
|
||||
const instance = await withSaveAndVerify(
|
||||
await new MockVariableDebtTokenFactory(await getFirstSigner()).deploy(),
|
||||
eContractid.MockVariableDebtToken,
|
||||
args,
|
||||
[],
|
||||
verify
|
||||
);
|
||||
|
||||
await instance.initialize(args[0], args[1], args[2], '18', args[3], args[4], args[5]);
|
||||
|
||||
return instance;
|
||||
};
|
||||
|
||||
export const deployMockAToken = async (
|
||||
args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress],
|
||||
args: [
|
||||
tEthereumAddress,
|
||||
tEthereumAddress,
|
||||
tEthereumAddress,
|
||||
tEthereumAddress,
|
||||
string,
|
||||
string,
|
||||
string
|
||||
],
|
||||
verify?: boolean
|
||||
) =>
|
||||
withSaveAndVerify(
|
||||
await new MockATokenFactory(await getFirstSigner()).deploy(...args),
|
||||
) => {
|
||||
const instance = await withSaveAndVerify(
|
||||
await new MockATokenFactory(await getFirstSigner()).deploy(),
|
||||
eContractid.MockAToken,
|
||||
args,
|
||||
[],
|
||||
verify
|
||||
);
|
||||
|
||||
await instance.initialize(args[0], args[2], args[1], args[3], '18', args[4], args[5], args[6]);
|
||||
|
||||
return instance;
|
||||
};
|
||||
|
||||
export const deploySelfdestructTransferMock = async (verify?: boolean) =>
|
||||
withSaveAndVerify(
|
||||
await new SelfdestructTransferFactory(await getFirstSigner()).deploy(),
|
||||
|
@ -525,3 +622,14 @@ export const deployUniswapRepayAdapter = async (
|
|||
args,
|
||||
verify
|
||||
);
|
||||
|
||||
export const deployFlashLiquidationAdapter = async (
|
||||
args: [tEthereumAddress, tEthereumAddress, tEthereumAddress],
|
||||
verify?: boolean
|
||||
) =>
|
||||
withSaveAndVerify(
|
||||
await new FlashLiquidationAdapterFactory(await getFirstSigner()).deploy(...args),
|
||||
eContractid.FlashLiquidationAdapter,
|
||||
args,
|
||||
verify
|
||||
);
|
||||
|
|
|
@ -29,6 +29,7 @@ import {
|
|||
WalletBalanceProviderFactory,
|
||||
WETH9MockedFactory,
|
||||
WETHGatewayFactory,
|
||||
FlashLiquidationAdapterFactory,
|
||||
} from '../types';
|
||||
import { IERC20DetailedFactory } from '../types/IERC20DetailedFactory';
|
||||
import { MockTokenMap } from './contracts-helpers';
|
||||
|
@ -174,16 +175,16 @@ export const getPairsTokenAggregator = (
|
|||
const { ETH, USD, WETH, ...assetsAddressesWithoutEth } = allAssetsAddresses;
|
||||
|
||||
const pairs = Object.entries(assetsAddressesWithoutEth).map(([tokenSymbol, tokenAddress]) => {
|
||||
if (tokenSymbol !== 'WETH' && tokenSymbol !== 'ETH') {
|
||||
const aggregatorAddressIndex = Object.keys(aggregatorsAddresses).findIndex(
|
||||
(value) => value === tokenSymbol
|
||||
);
|
||||
const [, aggregatorAddress] = (Object.entries(aggregatorsAddresses) as [
|
||||
string,
|
||||
tEthereumAddress
|
||||
][])[aggregatorAddressIndex];
|
||||
return [tokenAddress, aggregatorAddress];
|
||||
}
|
||||
//if (true/*tokenSymbol !== 'WETH' && tokenSymbol !== 'ETH' && tokenSymbol !== 'LpWETH'*/) {
|
||||
const aggregatorAddressIndex = Object.keys(aggregatorsAddresses).findIndex(
|
||||
(value) => value === tokenSymbol
|
||||
);
|
||||
const [, aggregatorAddress] = (Object.entries(aggregatorsAddresses) as [
|
||||
string,
|
||||
tEthereumAddress
|
||||
][])[aggregatorAddressIndex];
|
||||
return [tokenAddress, aggregatorAddress];
|
||||
//}
|
||||
}) as [string, string][];
|
||||
|
||||
const mappedPairs = pairs.map(([asset]) => asset);
|
||||
|
@ -354,3 +355,11 @@ export const getUniswapRepayAdapter = async (address?: tEthereumAddress) =>
|
|||
(await getDb().get(`${eContractid.UniswapRepayAdapter}.${DRE.network.name}`).value()).address,
|
||||
await getFirstSigner()
|
||||
);
|
||||
|
||||
export const getFlashLiquidationAdapter = async (address?: tEthereumAddress) =>
|
||||
await FlashLiquidationAdapterFactory.connect(
|
||||
address ||
|
||||
(await getDb().get(`${eContractid.FlashLiquidationAdapter}.${DRE.network.name}`).value())
|
||||
.address,
|
||||
await getFirstSigner()
|
||||
);
|
||||
|
|
|
@ -11,12 +11,20 @@ import {
|
|||
AavePools,
|
||||
iParamsPerNetwork,
|
||||
iParamsPerPool,
|
||||
ePolygonNetwork,
|
||||
eXDaiNetwork,
|
||||
eNetwork,
|
||||
iParamsPerNetworkAll,
|
||||
iEthereumParamsPerNetwork,
|
||||
iPolygonParamsPerNetwork,
|
||||
iXDaiParamsPerNetwork,
|
||||
} from './types';
|
||||
import { MintableERC20 } from '../types/MintableERC20';
|
||||
import { Artifact } from 'hardhat/types';
|
||||
import { Artifact as BuidlerArtifact } from '@nomiclabs/buidler/types';
|
||||
import { verifyContract } from './etherscan-verification';
|
||||
import { getIErc20Detailed } from './contracts-getters';
|
||||
import { usingTenderly } from './tenderly-utils';
|
||||
|
||||
export type MockTokenMap = { [symbol: string]: MintableERC20 };
|
||||
|
||||
|
@ -90,11 +98,15 @@ export const withSaveAndVerify = async <ContractType extends Contract>(
|
|||
): Promise<ContractType> => {
|
||||
await waitForTx(instance.deployTransaction);
|
||||
await registerContractInJsonDb(id, instance);
|
||||
if (DRE.network.name.includes('tenderly')) {
|
||||
if (usingTenderly()) {
|
||||
console.log();
|
||||
console.log('Doing Tenderly contract verification of', id);
|
||||
await (DRE as any).tenderlyRPC.verify({
|
||||
name: id,
|
||||
address: instance.address,
|
||||
});
|
||||
console.log(`Verified ${id} at Tenderly!`);
|
||||
console.log();
|
||||
}
|
||||
if (verify) {
|
||||
await verifyContract(instance.address, args);
|
||||
|
@ -130,10 +142,17 @@ export const linkBytecode = (artifact: BuidlerArtifact | Artifact, libraries: an
|
|||
return bytecode;
|
||||
};
|
||||
|
||||
export const getParamPerNetwork = <T>(
|
||||
{ kovan, ropsten, main, buidlerevm, coverage, tenderlyMain }: iParamsPerNetwork<T>,
|
||||
network: eEthereumNetwork
|
||||
) => {
|
||||
export const getParamPerNetwork = <T>(param: iParamsPerNetwork<T>, network: eNetwork) => {
|
||||
const {
|
||||
main,
|
||||
ropsten,
|
||||
kovan,
|
||||
coverage,
|
||||
buidlerevm,
|
||||
tenderlyMain,
|
||||
} = param as iEthereumParamsPerNetwork<T>;
|
||||
const { matic, mumbai } = param as iPolygonParamsPerNetwork<T>;
|
||||
const { xdai } = param as iXDaiParamsPerNetwork<T>;
|
||||
const MAINNET_FORK = process.env.MAINNET_FORK === 'true';
|
||||
if (MAINNET_FORK) {
|
||||
return main;
|
||||
|
@ -154,13 +173,23 @@ export const getParamPerNetwork = <T>(
|
|||
return main;
|
||||
case eEthereumNetwork.tenderlyMain:
|
||||
return tenderlyMain;
|
||||
case ePolygonNetwork.matic:
|
||||
return matic;
|
||||
case ePolygonNetwork.mumbai:
|
||||
return mumbai;
|
||||
case eXDaiNetwork.xdai:
|
||||
return xdai;
|
||||
}
|
||||
};
|
||||
|
||||
export const getParamPerPool = <T>({ proto }: iParamsPerPool<T>, pool: AavePools) => {
|
||||
export const getParamPerPool = <T>({ proto, amm, matic }: iParamsPerPool<T>, pool: AavePools) => {
|
||||
switch (pool) {
|
||||
case AavePools.proto:
|
||||
return proto;
|
||||
case AavePools.amm:
|
||||
return amm;
|
||||
case AavePools.matic:
|
||||
return matic;
|
||||
default:
|
||||
return proto;
|
||||
}
|
||||
|
@ -286,3 +315,16 @@ export const buildRepayAdapterParams = (
|
|||
[collateralAsset, collateralAmount, rateMode, permitAmount, deadline, v, r, s, useEthPath]
|
||||
);
|
||||
};
|
||||
|
||||
export const buildFlashLiquidationAdapterParams = (
|
||||
collateralAsset: tEthereumAddress,
|
||||
debtAsset: tEthereumAddress,
|
||||
user: tEthereumAddress,
|
||||
debtToCover: BigNumberish,
|
||||
useEthPath: boolean
|
||||
) => {
|
||||
return ethers.utils.defaultAbiCoder.encode(
|
||||
['address', 'address', 'address', 'uint256', 'bool'],
|
||||
[collateralAsset, debtAsset, user, debtToCover, useEthPath]
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {exit} from 'process';
|
||||
import { exit } from 'process';
|
||||
import fs from 'fs';
|
||||
import {file} from 'tmp-promise';
|
||||
import {DRE} from './misc-utils';
|
||||
import { file } from 'tmp-promise';
|
||||
import { DRE } from './misc-utils';
|
||||
|
||||
const fatalErrors = [
|
||||
`The address provided as argument contains a contract, but its bytecode`,
|
||||
|
@ -43,7 +43,7 @@ export const verifyContract = async (
|
|||
const msDelay = 3000;
|
||||
const times = 4;
|
||||
// Write a temporal file to host complex parameters for buidler-etherscan https://github.com/nomiclabs/buidler/tree/development/packages/buidler-etherscan#complex-arguments
|
||||
const {fd, path, cleanup} = await file({
|
||||
const { fd, path, cleanup } = await file({
|
||||
prefix: 'verify-params-',
|
||||
postfix: '.js',
|
||||
});
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import {
|
||||
eContractid,
|
||||
eEthereumNetwork,
|
||||
eNetwork,
|
||||
iMultiPoolsAssets,
|
||||
IReserveParams,
|
||||
tEthereumAddress,
|
||||
|
@ -12,6 +13,7 @@ import {
|
|||
getAToken,
|
||||
getATokensAndRatesHelper,
|
||||
getLendingPoolAddressesProvider,
|
||||
getLendingPoolConfiguratorProxy,
|
||||
getStableAndVariableTokensHelper,
|
||||
} from './contracts-getters';
|
||||
import { rawInsertContractAddressInDb } from './contracts-helpers';
|
||||
|
@ -19,12 +21,17 @@ import { BigNumber, BigNumberish, Signer } from 'ethers';
|
|||
import {
|
||||
deployDefaultReserveInterestRateStrategy,
|
||||
deployDelegationAwareAToken,
|
||||
deployDelegationAwareATokenImpl,
|
||||
deployGenericAToken,
|
||||
deployGenericATokenImpl,
|
||||
deployGenericStableDebtToken,
|
||||
deployGenericVariableDebtToken,
|
||||
deployStableDebtToken,
|
||||
deployVariableDebtToken,
|
||||
} from './contracts-deployments';
|
||||
import { ZERO_ADDRESS } from './constants';
|
||||
import { isZeroAddress } from 'ethereumjs-util';
|
||||
import { DefaultReserveInterestRateStrategy, DelegationAwareAToken } from '../types';
|
||||
|
||||
export const chooseATokenDeployment = (id: eContractid) => {
|
||||
switch (id) {
|
||||
|
@ -40,6 +47,10 @@ export const chooseATokenDeployment = (id: eContractid) => {
|
|||
export const initReservesByHelper = async (
|
||||
reservesParams: iMultiPoolsAssets<IReserveParams>,
|
||||
tokenAddresses: { [symbol: string]: tEthereumAddress },
|
||||
aTokenNamePrefix: string,
|
||||
stableDebtTokenNamePrefix: string,
|
||||
variableDebtTokenNamePrefix: string,
|
||||
symbolPrefix: string,
|
||||
admin: tEthereumAddress,
|
||||
treasuryAddress: tEthereumAddress,
|
||||
incentivesController: tEthereumAddress,
|
||||
|
@ -47,139 +58,93 @@ export const initReservesByHelper = async (
|
|||
): Promise<BigNumber> => {
|
||||
let gasUsage = BigNumber.from('0');
|
||||
const stableAndVariableDeployer = await getStableAndVariableTokensHelper();
|
||||
const atokenAndRatesDeployer = await getATokensAndRatesHelper();
|
||||
|
||||
const addressProvider = await getLendingPoolAddressesProvider();
|
||||
const poolAddress = await addressProvider.getLendingPool();
|
||||
|
||||
// Set aTokenAndRatesDeployer as temporal admin
|
||||
await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
|
||||
|
||||
// CHUNK CONFIGURATION
|
||||
const tokensChunks = 2;
|
||||
const initChunks = 4;
|
||||
|
||||
// Deploy tokens and rates that uses common aToken in chunks
|
||||
const reservesChunks = chunk(
|
||||
Object.entries(reservesParams).filter(
|
||||
([_, { aTokenImpl }]) => aTokenImpl === eContractid.AToken
|
||||
) as [string, IReserveParams][],
|
||||
tokensChunks
|
||||
);
|
||||
// Initialize variables for future reserves initialization
|
||||
let deployedStableTokens: string[] = [];
|
||||
let deployedVariableTokens: string[] = [];
|
||||
let deployedATokens: string[] = [];
|
||||
let deployedRates: string[] = [];
|
||||
let reserveTokens: string[] = [];
|
||||
let reserveInitDecimals: string[] = [];
|
||||
let reserveSymbols: string[] = [];
|
||||
|
||||
console.log(
|
||||
`- Token deployments in ${reservesChunks.length * 2} txs instead of ${
|
||||
Object.entries(reservesParams).length * 4
|
||||
} txs`
|
||||
);
|
||||
for (let reservesChunk of reservesChunks) {
|
||||
// Prepare data
|
||||
const tokens: string[] = [];
|
||||
const symbols: string[] = [];
|
||||
const strategyRates: [
|
||||
BigNumberish,
|
||||
BigNumberish,
|
||||
BigNumberish,
|
||||
BigNumberish,
|
||||
BigNumberish,
|
||||
BigNumberish
|
||||
][] = [];
|
||||
const reservesDecimals: string[] = [];
|
||||
let initInputParams: {
|
||||
aTokenImpl: string;
|
||||
stableDebtTokenImpl: string;
|
||||
variableDebtTokenImpl: string;
|
||||
underlyingAssetDecimals: BigNumberish;
|
||||
interestRateStrategyAddress: string;
|
||||
underlyingAsset: string;
|
||||
treasury: string;
|
||||
incentivesController: string;
|
||||
underlyingAssetName: string;
|
||||
aTokenName: string;
|
||||
aTokenSymbol: string;
|
||||
variableDebtTokenName: string;
|
||||
variableDebtTokenSymbol: string;
|
||||
stableDebtTokenName: string;
|
||||
stableDebtTokenSymbol: string;
|
||||
params: string;
|
||||
}[] = [];
|
||||
|
||||
for (let [assetSymbol, { reserveDecimals }] of reservesChunk) {
|
||||
const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
|
||||
(value) => value === assetSymbol
|
||||
);
|
||||
const [, tokenAddress] = (Object.entries(tokenAddresses) as [string, string][])[
|
||||
assetAddressIndex
|
||||
];
|
||||
let strategyRates: [
|
||||
string, // addresses provider
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
string
|
||||
];
|
||||
let rateStrategies: Record<string, typeof strategyRates> = {};
|
||||
let strategyAddresses: Record<string, tEthereumAddress> = {};
|
||||
let strategyAddressPerAsset: Record<string, string> = {};
|
||||
let aTokenType: Record<string, string> = {};
|
||||
let delegationAwareATokenImplementationAddress = '';
|
||||
let aTokenImplementationAddress = '';
|
||||
let stableDebtTokenImplementationAddress = '';
|
||||
let variableDebtTokenImplementationAddress = '';
|
||||
|
||||
const reserveParamIndex = Object.keys(reservesParams).findIndex(
|
||||
(value) => value === assetSymbol
|
||||
);
|
||||
const [
|
||||
,
|
||||
{
|
||||
optimalUtilizationRate,
|
||||
baseVariableBorrowRate,
|
||||
variableRateSlope1,
|
||||
variableRateSlope2,
|
||||
stableRateSlope1,
|
||||
stableRateSlope2,
|
||||
},
|
||||
] = (Object.entries(reservesParams) as [string, IReserveParams][])[reserveParamIndex];
|
||||
// Add to lists
|
||||
tokens.push(tokenAddress);
|
||||
symbols.push(assetSymbol);
|
||||
strategyRates.push([
|
||||
optimalUtilizationRate,
|
||||
baseVariableBorrowRate,
|
||||
variableRateSlope1,
|
||||
variableRateSlope2,
|
||||
stableRateSlope1,
|
||||
stableRateSlope2,
|
||||
]);
|
||||
reservesDecimals.push(reserveDecimals);
|
||||
}
|
||||
// NOT WORKING ON MATIC, DEPLOYING INDIVIDUAL IMPLs INSTEAD
|
||||
// const tx1 = await waitForTx(
|
||||
// await stableAndVariableDeployer.initDeployment([ZERO_ADDRESS], ["1"])
|
||||
// );
|
||||
// console.log(tx1.events);
|
||||
// tx1.events?.forEach((event, index) => {
|
||||
// stableDebtTokenImplementationAddress = event?.args?.stableToken;
|
||||
// variableDebtTokenImplementationAddress = event?.args?.variableToken;
|
||||
// rawInsertContractAddressInDb(`stableDebtTokenImpl`, stableDebtTokenImplementationAddress);
|
||||
// rawInsertContractAddressInDb(`variableDebtTokenImpl`, variableDebtTokenImplementationAddress);
|
||||
// });
|
||||
//gasUsage = gasUsage.add(tx1.gasUsed);
|
||||
stableDebtTokenImplementationAddress = await (await deployGenericStableDebtToken()).address;
|
||||
variableDebtTokenImplementationAddress = await (await deployGenericVariableDebtToken()).address;
|
||||
|
||||
// Deploy stable and variable deployers and save implementations
|
||||
const tx1 = await waitForTx(
|
||||
await stableAndVariableDeployer.initDeployment(tokens, symbols, incentivesController)
|
||||
);
|
||||
tx1.events?.forEach((event, index) => {
|
||||
rawInsertContractAddressInDb(`stableDebt${symbols[index]}`, event?.args?.stableToken);
|
||||
rawInsertContractAddressInDb(`variableDebt${symbols[index]}`, event?.args?.variableToken);
|
||||
});
|
||||
const aTokenImplementation = await deployGenericATokenImpl(verify);
|
||||
aTokenImplementationAddress = aTokenImplementation.address;
|
||||
rawInsertContractAddressInDb(`aTokenImpl`, aTokenImplementationAddress);
|
||||
|
||||
// Deploy atokens and rate strategies and save implementations
|
||||
const tx2 = await waitForTx(
|
||||
await atokenAndRatesDeployer.initDeployment(
|
||||
tokens,
|
||||
symbols,
|
||||
strategyRates,
|
||||
treasuryAddress,
|
||||
incentivesController
|
||||
)
|
||||
);
|
||||
tx2.events?.forEach((event, index) => {
|
||||
rawInsertContractAddressInDb(`a${symbols[index]}`, event?.args?.aToken);
|
||||
rawInsertContractAddressInDb(`strategy${symbols[index]}`, event?.args?.strategy);
|
||||
});
|
||||
|
||||
console.log(` - Deployed aToken, DebtTokens and Strategy for: ${symbols.join(', ')} `);
|
||||
console.log(' * gasUsed: debtTokens batch', tx1.gasUsed.toString());
|
||||
console.log(' * gasUsed: aTokens and Strategy batch', tx2.gasUsed.toString());
|
||||
gasUsage = gasUsage.add(tx1.gasUsed).add(tx2.gasUsed);
|
||||
|
||||
const stableTokens: string[] = tx1.events?.map((e) => e.args?.stableToken) || [];
|
||||
const variableTokens: string[] = tx1.events?.map((e) => e.args?.variableToken) || [];
|
||||
const aTokens: string[] = tx2.events?.map((e) => e.args?.aToken) || [];
|
||||
const strategies: string[] = tx2.events?.map((e) => e.args?.strategy) || [];
|
||||
|
||||
deployedStableTokens = [...deployedStableTokens, ...stableTokens];
|
||||
deployedVariableTokens = [...deployedVariableTokens, ...variableTokens];
|
||||
deployedATokens = [...deployedATokens, ...aTokens];
|
||||
deployedRates = [...deployedRates, ...strategies];
|
||||
reserveInitDecimals = [...reserveInitDecimals, ...reservesDecimals];
|
||||
reserveTokens = [...reserveTokens, ...tokens];
|
||||
reserveSymbols = [...reserveSymbols, ...symbols];
|
||||
}
|
||||
|
||||
// Deploy delegated aware reserves tokens
|
||||
const delegatedAwareReserves = Object.entries(reservesParams).filter(
|
||||
([_, { aTokenImpl }]) => aTokenImpl === eContractid.DelegationAwareAToken
|
||||
) as [string, IReserveParams][];
|
||||
|
||||
for (let [symbol, params] of delegatedAwareReserves) {
|
||||
console.log(` - Deploy ${symbol} delegation aware aToken, debts tokens, and strategy`);
|
||||
if (delegatedAwareReserves.length > 0) {
|
||||
const delegationAwareATokenImplementation = await deployDelegationAwareATokenImpl(verify);
|
||||
delegationAwareATokenImplementationAddress = delegationAwareATokenImplementation.address;
|
||||
rawInsertContractAddressInDb(
|
||||
`delegationAwareATokenImpl`,
|
||||
delegationAwareATokenImplementationAddress
|
||||
);
|
||||
}
|
||||
|
||||
const reserves = Object.entries(reservesParams).filter(
|
||||
([_, { aTokenImpl }]) =>
|
||||
aTokenImpl === eContractid.DelegationAwareAToken || aTokenImpl === eContractid.AToken
|
||||
) as [string, IReserveParams][];
|
||||
|
||||
for (let [symbol, params] of reserves) {
|
||||
const { strategy, aTokenImpl, reserveDecimals } = params;
|
||||
const {
|
||||
optimalUtilizationRate,
|
||||
baseVariableBorrowRate,
|
||||
|
@ -187,89 +152,86 @@ export const initReservesByHelper = async (
|
|||
variableRateSlope2,
|
||||
stableRateSlope1,
|
||||
stableRateSlope2,
|
||||
} = params;
|
||||
const deployCustomAToken = chooseATokenDeployment(params.aTokenImpl);
|
||||
const aToken = await deployCustomAToken(
|
||||
[
|
||||
poolAddress,
|
||||
tokenAddresses[symbol],
|
||||
treasuryAddress,
|
||||
`Aave interest bearing ${symbol}`,
|
||||
`a${symbol}`,
|
||||
ZERO_ADDRESS,
|
||||
],
|
||||
verify
|
||||
);
|
||||
const stableDebt = await deployStableDebtToken(
|
||||
[
|
||||
poolAddress,
|
||||
tokenAddresses[symbol],
|
||||
`Aave stable debt bearing ${symbol}`,
|
||||
`stableDebt${symbol}`,
|
||||
ZERO_ADDRESS,
|
||||
],
|
||||
verify
|
||||
);
|
||||
const variableDebt = await deployVariableDebtToken(
|
||||
[
|
||||
poolAddress,
|
||||
tokenAddresses[symbol],
|
||||
`Aave variable debt bearing ${symbol}`,
|
||||
`variableDebt${symbol}`,
|
||||
ZERO_ADDRESS,
|
||||
],
|
||||
verify
|
||||
);
|
||||
const rates = await deployDefaultReserveInterestRateStrategy(
|
||||
[
|
||||
tokenAddresses[symbol],
|
||||
} = strategy;
|
||||
if (!strategyAddresses[strategy.name]) {
|
||||
// Strategy does not exist, create a new one
|
||||
rateStrategies[strategy.name] = [
|
||||
addressProvider.address,
|
||||
optimalUtilizationRate,
|
||||
baseVariableBorrowRate,
|
||||
variableRateSlope1,
|
||||
variableRateSlope2,
|
||||
stableRateSlope1,
|
||||
stableRateSlope2,
|
||||
],
|
||||
verify
|
||||
);
|
||||
];
|
||||
strategyAddresses[strategy.name] = (
|
||||
await deployDefaultReserveInterestRateStrategy(rateStrategies[strategy.name], verify)
|
||||
).address;
|
||||
// This causes the last strategy to be printed twice, once under "DefaultReserveInterestRateStrategy"
|
||||
// and once under the actual `strategyASSET` key.
|
||||
rawInsertContractAddressInDb(strategy.name, strategyAddresses[strategy.name]);
|
||||
}
|
||||
strategyAddressPerAsset[symbol] = strategyAddresses[strategy.name];
|
||||
console.log('Strategy address for asset %s: %s', symbol, strategyAddressPerAsset[symbol]);
|
||||
|
||||
deployedStableTokens.push(stableDebt.address);
|
||||
deployedVariableTokens.push(variableDebt.address);
|
||||
deployedATokens.push(aToken.address);
|
||||
deployedRates.push(rates.address);
|
||||
reserveInitDecimals.push(params.reserveDecimals);
|
||||
if (aTokenImpl === eContractid.AToken) {
|
||||
aTokenType[symbol] = 'generic';
|
||||
} else if (aTokenImpl === eContractid.DelegationAwareAToken) {
|
||||
aTokenType[symbol] = 'delegation aware';
|
||||
}
|
||||
|
||||
reserveInitDecimals.push(reserveDecimals);
|
||||
reserveTokens.push(tokenAddresses[symbol]);
|
||||
reserveSymbols.push(symbol);
|
||||
}
|
||||
|
||||
// Deploy init reserves per chunks
|
||||
const chunkedStableTokens = chunk(deployedStableTokens, initChunks);
|
||||
const chunkedVariableTokens = chunk(deployedVariableTokens, initChunks);
|
||||
const chunkedAtokens = chunk(deployedATokens, initChunks);
|
||||
const chunkedRates = chunk(deployedRates, initChunks);
|
||||
const chunkedDecimals = chunk(reserveInitDecimals, initChunks);
|
||||
const chunkedSymbols = chunk(reserveSymbols, initChunks);
|
||||
for (let i = 0; i < reserveSymbols.length; i++) {
|
||||
let aTokenToUse: string;
|
||||
if (aTokenType[reserveSymbols[i]] === 'generic') {
|
||||
aTokenToUse = aTokenImplementationAddress;
|
||||
} else {
|
||||
aTokenToUse = delegationAwareATokenImplementationAddress;
|
||||
}
|
||||
|
||||
console.log(`- Reserves initialization in ${chunkedStableTokens.length} txs`);
|
||||
for (let chunkIndex = 0; chunkIndex < chunkedDecimals.length; chunkIndex++) {
|
||||
initInputParams.push({
|
||||
aTokenImpl: aTokenToUse,
|
||||
stableDebtTokenImpl: stableDebtTokenImplementationAddress,
|
||||
variableDebtTokenImpl: variableDebtTokenImplementationAddress,
|
||||
underlyingAssetDecimals: reserveInitDecimals[i],
|
||||
interestRateStrategyAddress: strategyAddressPerAsset[reserveSymbols[i]],
|
||||
underlyingAsset: reserveTokens[i],
|
||||
treasury: treasuryAddress,
|
||||
incentivesController: ZERO_ADDRESS,
|
||||
underlyingAssetName: reserveSymbols[i],
|
||||
aTokenName: `${aTokenNamePrefix} ${reserveSymbols[i]}`,
|
||||
aTokenSymbol: `a${symbolPrefix}${reserveSymbols[i]}`,
|
||||
variableDebtTokenName: `${variableDebtTokenNamePrefix} ${symbolPrefix}${reserveSymbols[i]}`,
|
||||
variableDebtTokenSymbol: `variableDebt${symbolPrefix}${reserveSymbols[i]}`,
|
||||
stableDebtTokenName: `${stableDebtTokenNamePrefix} ${reserveSymbols[i]}`,
|
||||
stableDebtTokenSymbol: `stableDebt${symbolPrefix}${reserveSymbols[i]}`,
|
||||
params: '0x10'
|
||||
});
|
||||
}
|
||||
|
||||
// Deploy init reserves per chunks
|
||||
const chunkedSymbols = chunk(reserveSymbols, initChunks);
|
||||
const chunkedInitInputParams = chunk(initInputParams, initChunks);
|
||||
|
||||
const configurator = await getLendingPoolConfiguratorProxy();
|
||||
//await waitForTx(await addressProvider.setPoolAdmin(admin));
|
||||
|
||||
console.log(`- Reserves initialization in ${chunkedInitInputParams.length} txs`);
|
||||
for (let chunkIndex = 0; chunkIndex < chunkedInitInputParams.length; chunkIndex++) {
|
||||
const tx3 = await waitForTx(
|
||||
await atokenAndRatesDeployer.initReserve(
|
||||
chunkedStableTokens[chunkIndex],
|
||||
chunkedVariableTokens[chunkIndex],
|
||||
chunkedAtokens[chunkIndex],
|
||||
chunkedRates[chunkIndex],
|
||||
chunkedDecimals[chunkIndex]
|
||||
)
|
||||
await configurator.batchInitReserve(chunkedInitInputParams[chunkIndex])
|
||||
);
|
||||
|
||||
console.log(` - Reserve ready for: ${chunkedSymbols[chunkIndex].join(', ')}`);
|
||||
console.log(' * gasUsed', tx3.gasUsed.toString());
|
||||
gasUsage = gasUsage.add(tx3.gasUsed);
|
||||
//gasUsage = gasUsage.add(tx3.gasUsed);
|
||||
}
|
||||
|
||||
// Set deployer back as admin
|
||||
await waitForTx(await addressProvider.setPoolAdmin(admin));
|
||||
return gasUsage;
|
||||
return gasUsage; // Deprecated
|
||||
};
|
||||
|
||||
export const getPairsTokenAggregator = (
|
||||
|
@ -315,6 +277,15 @@ export const configureReservesByHelper = async (
|
|||
const reserveFactors: string[] = [];
|
||||
const stableRatesEnabled: boolean[] = [];
|
||||
|
||||
const inputParams: {
|
||||
asset: string;
|
||||
baseLTV: BigNumberish;
|
||||
liquidationThreshold: BigNumberish;
|
||||
liquidationBonus: BigNumberish;
|
||||
reserveFactor: BigNumberish;
|
||||
stableBorrowingEnabled: boolean;
|
||||
}[] = [];
|
||||
|
||||
for (const [
|
||||
assetSymbol,
|
||||
{
|
||||
|
@ -342,6 +313,16 @@ export const configureReservesByHelper = async (
|
|||
continue;
|
||||
}
|
||||
// Push data
|
||||
|
||||
inputParams.push({
|
||||
asset: tokenAddress,
|
||||
baseLTV: baseLTVAsCollateral,
|
||||
liquidationThreshold: liquidationThreshold,
|
||||
liquidationBonus: liquidationBonus,
|
||||
reserveFactor: reserveFactor,
|
||||
stableBorrowingEnabled: stableBorrowRateEnabled,
|
||||
});
|
||||
|
||||
tokens.push(tokenAddress);
|
||||
symbols.push(assetSymbol);
|
||||
baseLTVA.push(baseLTVAsCollateral);
|
||||
|
@ -356,26 +337,15 @@ export const configureReservesByHelper = async (
|
|||
|
||||
// Deploy init per chunks
|
||||
const enableChunks = 20;
|
||||
const chunkedTokens = chunk(tokens, enableChunks);
|
||||
const chunkedSymbols = chunk(symbols, enableChunks);
|
||||
const chunkedBase = chunk(baseLTVA, enableChunks);
|
||||
const chunkedliquidationThresholds = chunk(liquidationThresholds, enableChunks);
|
||||
const chunkedliquidationBonuses = chunk(liquidationBonuses, enableChunks);
|
||||
const chunkedReserveFactors = chunk(reserveFactors, enableChunks);
|
||||
const chunkedStableRatesEnabled = chunk(stableRatesEnabled, enableChunks);
|
||||
const chunkedInputParams = chunk(inputParams, enableChunks);
|
||||
|
||||
console.log(`- Configure reserves in ${chunkedTokens.length} txs`);
|
||||
for (let chunkIndex = 0; chunkIndex < chunkedTokens.length; chunkIndex++) {
|
||||
console.log(`- Configure reserves in ${chunkedInputParams.length} txs`);
|
||||
for (let chunkIndex = 0; chunkIndex < chunkedInputParams.length; chunkIndex++) {
|
||||
await waitForTx(
|
||||
await atokenAndRatesDeployer.configureReserves(
|
||||
chunkedTokens[chunkIndex],
|
||||
chunkedBase[chunkIndex],
|
||||
chunkedliquidationThresholds[chunkIndex],
|
||||
chunkedliquidationBonuses[chunkIndex],
|
||||
chunkedReserveFactors[chunkIndex],
|
||||
chunkedStableRatesEnabled[chunkIndex],
|
||||
{ gasLimit: 12000000 }
|
||||
)
|
||||
await atokenAndRatesDeployer.configureReserves(chunkedInputParams[chunkIndex], {
|
||||
gasLimit: 12000000,
|
||||
})
|
||||
);
|
||||
console.log(` - Init for: ${chunkedSymbols[chunkIndex].join(', ')}`);
|
||||
}
|
||||
|
@ -386,10 +356,13 @@ export const configureReservesByHelper = async (
|
|||
|
||||
const getAddressById = async (
|
||||
id: string,
|
||||
network: eEthereumNetwork
|
||||
network: eNetwork
|
||||
): Promise<tEthereumAddress | undefined> =>
|
||||
(await getDb().get(`${id}.${network}`).value())?.address || undefined;
|
||||
|
||||
// Function deprecated? Updated but untested, script is not updated on package.json.
|
||||
// This is not called during regular deployment, only in the "full:initialize-tokens"
|
||||
// hardhat task.
|
||||
export const initTokenReservesByHelper = async (
|
||||
reservesParams: iMultiPoolsAssets<IReserveParams>,
|
||||
tokenAddresses: { [symbol: string]: tEthereumAddress },
|
||||
|
@ -415,7 +388,7 @@ export const initTokenReservesByHelper = async (
|
|||
const poolAddress = await addressProvider.getLendingPool();
|
||||
|
||||
// Set aTokenAndRatesDeployer as temporal admin
|
||||
await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
|
||||
//await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
|
||||
|
||||
// CHUNK CONFIGURATION
|
||||
const initChunks = 4;
|
||||
|
@ -425,12 +398,31 @@ export const initTokenReservesByHelper = async (
|
|||
let deployedVariableTokens: string[] = [];
|
||||
let deployedATokens: string[] = [];
|
||||
let deployedRates: string[] = [];
|
||||
//let reserveTokens: string[] = [];
|
||||
let reserveInitDecimals: string[] = [];
|
||||
let reserveSymbols: string[] = [];
|
||||
|
||||
let initInputParams: {
|
||||
aTokenImpl: string;
|
||||
stableDebtTokenImpl: string;
|
||||
variableDebtTokenImpl: string;
|
||||
underlyingAssetDecimals: BigNumberish;
|
||||
interestRateStrategyAddress: string;
|
||||
underlyingAsset: string;
|
||||
treasury: string;
|
||||
incentivesController: string;
|
||||
underlyingAssetName: string;
|
||||
aTokenName: string;
|
||||
aTokenSymbol: string;
|
||||
variableDebtTokenName: string;
|
||||
variableDebtTokenSymbol: string;
|
||||
stableDebtTokenName: string;
|
||||
stableDebtTokenSymbol: string;
|
||||
params: string;
|
||||
}[] = [];
|
||||
|
||||
const network =
|
||||
process.env.MAINNET_FORK === 'true'
|
||||
? eEthereumNetwork.main
|
||||
: (DRE.network.name as eEthereumNetwork);
|
||||
process.env.MAINNET_FORK === 'true' ? eEthereumNetwork.main : (DRE.network.name as eNetwork);
|
||||
// Grab config from DB
|
||||
for (const [symbol, address] of Object.entries(tokenAddresses)) {
|
||||
const { aTokenAddress } = await protocolDataProvider.getReserveTokensAddresses(address);
|
||||
|
@ -444,19 +436,29 @@ export const initTokenReservesByHelper = async (
|
|||
console.log(`- Skipping ${symbol} due already initialized`);
|
||||
continue;
|
||||
}
|
||||
let stableTokenImpl = await getAddressById(`stableDebt${symbol}`, network);
|
||||
let variableTokenImpl = await getAddressById(`variableDebt${symbol}`, network);
|
||||
let aTokenImplementation = await getAddressById(`a${symbol}`, network);
|
||||
let strategyImpl = await getAddressById(`strategy${symbol}`, network);
|
||||
let stableTokenImpl = await getAddressById(`stableDebtTokenImpl`, network);
|
||||
let variableTokenImpl = await getAddressById(`variableDebtTokenImpl`, network);
|
||||
let aTokenImplementation: string | undefined = '';
|
||||
const [, { aTokenImpl, strategy }] = (Object.entries(reservesParams) as [
|
||||
string,
|
||||
IReserveParams
|
||||
][])[reserveParamIndex];
|
||||
if (aTokenImpl === eContractid.AToken) {
|
||||
aTokenImplementation = await getAddressById(`aTokenImpl`, network);
|
||||
} else if (aTokenImpl === eContractid.DelegationAwareAToken) {
|
||||
aTokenImplementation = await getAddressById(`delegationAwareATokenImpl`, network);
|
||||
}
|
||||
|
||||
let strategyImpl = await getAddressById(strategy.name, network);
|
||||
|
||||
if (!stableTokenImpl) {
|
||||
const stableDebt = await deployStableDebtToken(
|
||||
[
|
||||
poolAddress,
|
||||
tokenAddresses[symbol],
|
||||
ZERO_ADDRESS, // Incentives controller
|
||||
`Aave stable debt bearing ${symbol}`,
|
||||
`stableDebt${symbol}`,
|
||||
ZERO_ADDRESS,
|
||||
],
|
||||
verify
|
||||
);
|
||||
|
@ -467,9 +469,9 @@ export const initTokenReservesByHelper = async (
|
|||
[
|
||||
poolAddress,
|
||||
tokenAddresses[symbol],
|
||||
ZERO_ADDRESS, // Incentives Controller
|
||||
`Aave variable debt bearing ${symbol}`,
|
||||
`variableDebt${symbol}`,
|
||||
ZERO_ADDRESS,
|
||||
],
|
||||
verify
|
||||
);
|
||||
|
@ -485,26 +487,26 @@ export const initTokenReservesByHelper = async (
|
|||
poolAddress,
|
||||
tokenAddresses[symbol],
|
||||
treasuryAddress,
|
||||
ZERO_ADDRESS,
|
||||
`Aave interest bearing ${symbol}`,
|
||||
`a${symbol}`,
|
||||
ZERO_ADDRESS,
|
||||
],
|
||||
verify
|
||||
);
|
||||
aTokenImplementation = aToken.address;
|
||||
}
|
||||
if (!strategyImpl) {
|
||||
const [
|
||||
,
|
||||
{
|
||||
optimalUtilizationRate,
|
||||
baseVariableBorrowRate,
|
||||
variableRateSlope1,
|
||||
variableRateSlope2,
|
||||
stableRateSlope1,
|
||||
stableRateSlope2,
|
||||
},
|
||||
] = (Object.entries(reservesParams) as [string, IReserveParams][])[reserveParamIndex];
|
||||
const [, { strategy }] = (Object.entries(reservesParams) as [string, IReserveParams][])[
|
||||
reserveParamIndex
|
||||
];
|
||||
const {
|
||||
optimalUtilizationRate,
|
||||
baseVariableBorrowRate,
|
||||
variableRateSlope1,
|
||||
variableRateSlope2,
|
||||
stableRateSlope1,
|
||||
stableRateSlope2,
|
||||
} = strategy;
|
||||
const rates = await deployDefaultReserveInterestRateStrategy(
|
||||
[
|
||||
tokenAddresses[symbol],
|
||||
|
@ -519,53 +521,69 @@ export const initTokenReservesByHelper = async (
|
|||
);
|
||||
strategyImpl = rates.address;
|
||||
}
|
||||
const symbols = [`a${symbol}`, `variableDebt${symbol}`, `stableDebt${symbol}`];
|
||||
const tokens = [aTokenImplementation, variableTokenImpl, stableTokenImpl];
|
||||
for (let index = 0; index < symbols.length; index++) {
|
||||
if (!(await isErc20SymbolCorrect(tokens[index], symbols[index]))) {
|
||||
console.error(`${symbol} and implementation does not match: ${tokens[index]}`);
|
||||
throw Error('Symbol does not match implementation.');
|
||||
}
|
||||
}
|
||||
// --- REMOVED BECAUSE WE NOW USE THE SAME IMPLEMENTATIONS ---
|
||||
// const symbols = [`a${symbol}`, `variableDebt${symbol}`, `stableDebt${symbol}`];
|
||||
// const tokens = [aTokenImplementation, variableTokenImpl, stableTokenImpl];
|
||||
// for (let index = 0; index < symbols.length; index++) {
|
||||
// if (!(await isErc20SymbolCorrect(tokens[index], symbols[index]))) {
|
||||
// console.error(`${symbol} and implementation does not match: ${tokens[index]}`);
|
||||
// throw Error('Symbol does not match implementation.');
|
||||
// }
|
||||
// }
|
||||
console.log(`- Added ${symbol} to the initialize batch`);
|
||||
deployedStableTokens.push(stableTokenImpl);
|
||||
deployedVariableTokens.push(variableTokenImpl);
|
||||
deployedATokens.push(aTokenImplementation);
|
||||
//reserveTokens.push();
|
||||
deployedRates.push(strategyImpl);
|
||||
reserveInitDecimals.push(decimals.toString());
|
||||
reserveSymbols.push(symbol);
|
||||
}
|
||||
|
||||
// Deploy init reserves per chunks
|
||||
const chunkedStableTokens = chunk(deployedStableTokens, initChunks);
|
||||
const chunkedVariableTokens = chunk(deployedVariableTokens, initChunks);
|
||||
const chunkedAtokens = chunk(deployedATokens, initChunks);
|
||||
const chunkedRates = chunk(deployedRates, initChunks);
|
||||
const chunkedDecimals = chunk(reserveInitDecimals, initChunks);
|
||||
const chunkedSymbols = chunk(reserveSymbols, initChunks);
|
||||
for (let i = 0; i < deployedATokens.length; i++) {
|
||||
initInputParams.push({
|
||||
aTokenImpl: deployedATokens[i],
|
||||
stableDebtTokenImpl: deployedStableTokens[i],
|
||||
variableDebtTokenImpl: deployedVariableTokens[i],
|
||||
underlyingAssetDecimals: reserveInitDecimals[i],
|
||||
interestRateStrategyAddress: deployedRates[i],
|
||||
underlyingAsset: tokenAddresses[reserveSymbols[i]],
|
||||
treasury: treasuryAddress,
|
||||
incentivesController: ZERO_ADDRESS,
|
||||
underlyingAssetName: reserveSymbols[i],
|
||||
aTokenName: `Aave interest bearing ${reserveSymbols[i]}`,
|
||||
aTokenSymbol: `a${reserveSymbols[i]}`,
|
||||
variableDebtTokenName: `Aave variable debt bearing ${reserveSymbols[i]}`,
|
||||
variableDebtTokenSymbol: `variableDebt${reserveSymbols[i]}`,
|
||||
stableDebtTokenName: `Aave stable debt bearing ${reserveSymbols[i]}`,
|
||||
stableDebtTokenSymbol: `stableDebt${reserveSymbols[i]}`,
|
||||
params: '0x10'
|
||||
});
|
||||
}
|
||||
|
||||
console.log(`- Reserves initialization in ${chunkedStableTokens.length} txs`);
|
||||
for (let chunkIndex = 0; chunkIndex < chunkedDecimals.length; chunkIndex++) {
|
||||
// Deploy init reserves per chunks
|
||||
const chunkedSymbols = chunk(reserveSymbols, initChunks);
|
||||
const chunkedInitInputParams = chunk(initInputParams, initChunks);
|
||||
|
||||
const configurator = await getLendingPoolConfiguratorProxy();
|
||||
//await waitForTx(await addressProvider.setPoolAdmin(admin));
|
||||
|
||||
console.log(`- Reserves initialization in ${chunkedInitInputParams.length} txs`);
|
||||
for (let chunkIndex = 0; chunkIndex < chunkedInitInputParams.length; chunkIndex++) {
|
||||
const tx3 = await waitForTx(
|
||||
await atokenAndRatesDeployer.initReserve(
|
||||
chunkedStableTokens[chunkIndex],
|
||||
chunkedVariableTokens[chunkIndex],
|
||||
chunkedAtokens[chunkIndex],
|
||||
chunkedRates[chunkIndex],
|
||||
chunkedDecimals[chunkIndex]
|
||||
)
|
||||
await configurator.batchInitReserve(chunkedInitInputParams[chunkIndex])
|
||||
);
|
||||
|
||||
console.log(` - Reserve ready for: ${chunkedSymbols[chunkIndex].join(', ')}`);
|
||||
console.log(' * gasUsed', tx3.gasUsed.toString());
|
||||
gasUsage = gasUsage.add(tx3.gasUsed);
|
||||
}
|
||||
|
||||
// Set deployer back as admin
|
||||
await waitForTx(await addressProvider.setPoolAdmin(admin));
|
||||
return gasUsage;
|
||||
//await waitForTx(await addressProvider.setPoolAdmin(admin));
|
||||
return gasUsage; // No longer relevant
|
||||
};
|
||||
|
||||
// Function deprecated
|
||||
const isErc20SymbolCorrect = async (token: tEthereumAddress, symbol: string) => {
|
||||
const erc20 = await getAToken(token); // using aToken for ERC20 interface
|
||||
const erc20Symbol = await erc20.symbol();
|
||||
|
|
|
@ -2,13 +2,13 @@ import BigNumber from 'bignumber.js';
|
|||
import BN = require('bn.js');
|
||||
import low from 'lowdb';
|
||||
import FileSync from 'lowdb/adapters/FileSync';
|
||||
import {WAD} from './constants';
|
||||
import {Wallet, ContractTransaction} from 'ethers';
|
||||
import {HardhatRuntimeEnvironment} from 'hardhat/types';
|
||||
import {BuidlerRuntimeEnvironment} from '@nomiclabs/buidler/types';
|
||||
import {tEthereumAddress} from './types';
|
||||
import {isAddress} from 'ethers/lib/utils';
|
||||
import {isZeroAddress} from 'ethereumjs-util';
|
||||
import { WAD } from './constants';
|
||||
import { Wallet, ContractTransaction } from 'ethers';
|
||||
import { HardhatRuntimeEnvironment } from 'hardhat/types';
|
||||
import { BuidlerRuntimeEnvironment } from '@nomiclabs/buidler/types';
|
||||
import { tEthereumAddress } from './types';
|
||||
import { isAddress } from 'ethers/lib/utils';
|
||||
import { isZeroAddress } from 'ethereumjs-util';
|
||||
|
||||
export const toWad = (value: string | number) => new BigNumber(value).times(WAD).toFixed();
|
||||
|
||||
|
@ -17,9 +17,8 @@ export const stringToBigNumber = (amount: string): BigNumber => new BigNumber(am
|
|||
|
||||
export const getDb = () => low(new FileSync('./deployed-contracts.json'));
|
||||
|
||||
export let DRE:
|
||||
| HardhatRuntimeEnvironment
|
||||
| BuidlerRuntimeEnvironment = {} as HardhatRuntimeEnvironment;
|
||||
export let DRE: HardhatRuntimeEnvironment | BuidlerRuntimeEnvironment;
|
||||
|
||||
export const setDRE = (_DRE: HardhatRuntimeEnvironment | BuidlerRuntimeEnvironment) => {
|
||||
DRE = _DRE;
|
||||
};
|
||||
|
@ -47,12 +46,32 @@ export const increaseTime = async (secondsToIncrease: number) => {
|
|||
await DRE.ethers.provider.send('evm_mine', []);
|
||||
};
|
||||
|
||||
// Workaround for time travel tests bug: https://github.com/Tonyhaenn/hh-time-travel/blob/0161d993065a0b7585ec5a043af2eb4b654498b8/test/test.js#L12
|
||||
export const advanceTimeAndBlock = async function (forwardTime: number) {
|
||||
const currentBlockNumber = await DRE.ethers.provider.getBlockNumber();
|
||||
const currentBlock = await DRE.ethers.provider.getBlock(currentBlockNumber);
|
||||
|
||||
if (currentBlock === null) {
|
||||
/* Workaround for https://github.com/nomiclabs/hardhat/issues/1183
|
||||
*/
|
||||
await DRE.ethers.provider.send('evm_increaseTime', [forwardTime]);
|
||||
await DRE.ethers.provider.send('evm_mine', []);
|
||||
//Set the next blocktime back to 15 seconds
|
||||
await DRE.ethers.provider.send('evm_increaseTime', [15]);
|
||||
return;
|
||||
}
|
||||
const currentTime = currentBlock.timestamp;
|
||||
const futureTime = currentTime + forwardTime;
|
||||
await DRE.ethers.provider.send('evm_setNextBlockTimestamp', [futureTime]);
|
||||
await DRE.ethers.provider.send('evm_mine', []);
|
||||
};
|
||||
|
||||
export const waitForTx = async (tx: ContractTransaction) => await tx.wait(1);
|
||||
|
||||
export const filterMapBy = (raw: {[key: string]: any}, fn: (key: string) => boolean) =>
|
||||
export const filterMapBy = (raw: { [key: string]: any }, fn: (key: string) => boolean) =>
|
||||
Object.keys(raw)
|
||||
.filter(fn)
|
||||
.reduce<{[key: string]: any}>((obj, key) => {
|
||||
.reduce<{ [key: string]: any }>((obj, key) => {
|
||||
obj[key] = raw[key];
|
||||
return obj;
|
||||
}, {});
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import {tEthereumAddress} from './types';
|
||||
import {MockAggregator} from '../types/MockAggregator';
|
||||
import {MockTokenMap} from './contracts-helpers';
|
||||
import { tEthereumAddress } from './types';
|
||||
import { MockAggregator } from '../types/MockAggregator';
|
||||
import { MockTokenMap } from './contracts-helpers';
|
||||
|
||||
export const getAllTokenAddresses = (mockTokens: MockTokenMap) =>
|
||||
Object.entries(mockTokens).reduce(
|
||||
(accum: {[tokenSymbol: string]: tEthereumAddress}, [tokenSymbol, tokenContract]) => ({
|
||||
(accum: { [tokenSymbol: string]: tEthereumAddress }, [tokenSymbol, tokenContract]) => ({
|
||||
...accum,
|
||||
[tokenSymbol]: tokenContract.address,
|
||||
}),
|
||||
|
@ -14,7 +14,7 @@ export const getAllAggregatorsAddresses = (mockAggregators: {
|
|||
[tokenSymbol: string]: MockAggregator;
|
||||
}) =>
|
||||
Object.entries(mockAggregators).reduce(
|
||||
(accum: {[tokenSymbol: string]: tEthereumAddress}, [tokenSymbol, aggregator]) => ({
|
||||
(accum: { [tokenSymbol: string]: tEthereumAddress }, [tokenSymbol, aggregator]) => ({
|
||||
...accum,
|
||||
[tokenSymbol]: aggregator.address,
|
||||
}),
|
||||
|
|
|
@ -7,16 +7,16 @@ import {
|
|||
SymbolMap,
|
||||
} from './types';
|
||||
|
||||
import {LendingRateOracle} from '../types/LendingRateOracle';
|
||||
import {PriceOracle} from '../types/PriceOracle';
|
||||
import {MockAggregator} from '../types/MockAggregator';
|
||||
import {deployMockAggregator} from './contracts-deployments';
|
||||
import {chunk, waitForTx} from './misc-utils';
|
||||
import {getStableAndVariableTokensHelper} from './contracts-getters';
|
||||
import { LendingRateOracle } from '../types/LendingRateOracle';
|
||||
import { PriceOracle } from '../types/PriceOracle';
|
||||
import { MockAggregator } from '../types/MockAggregator';
|
||||
import { deployMockAggregator } from './contracts-deployments';
|
||||
import { chunk, waitForTx } from './misc-utils';
|
||||
import { getStableAndVariableTokensHelper } from './contracts-getters';
|
||||
|
||||
export const setInitialMarketRatesInRatesOracleByHelper = async (
|
||||
marketRates: iMultiPoolsAssets<IMarketRates>,
|
||||
assetsAddresses: {[x: string]: tEthereumAddress},
|
||||
assetsAddresses: { [x: string]: tEthereumAddress },
|
||||
lendingRateOracleInstance: LendingRateOracle,
|
||||
admin: tEthereumAddress
|
||||
) => {
|
||||
|
@ -24,7 +24,7 @@ export const setInitialMarketRatesInRatesOracleByHelper = async (
|
|||
const assetAddresses: string[] = [];
|
||||
const borrowRates: string[] = [];
|
||||
const symbols: string[] = [];
|
||||
for (const [assetSymbol, {borrowRate}] of Object.entries(marketRates) as [
|
||||
for (const [assetSymbol, { borrowRate }] of Object.entries(marketRates) as [
|
||||
string,
|
||||
IMarketRates
|
||||
][]) {
|
||||
|
@ -72,6 +72,9 @@ export const setInitialAssetPricesInOracle = async (
|
|||
priceOracleInstance: PriceOracle
|
||||
) => {
|
||||
for (const [assetSymbol, price] of Object.entries(prices) as [string, string][]) {
|
||||
|
||||
console.log("Trying for ", assetsAddresses, assetSymbol);
|
||||
|
||||
const assetAddressIndex = Object.keys(assetsAddresses).findIndex(
|
||||
(value) => value === assetSymbol
|
||||
);
|
||||
|
@ -99,7 +102,7 @@ export const setAssetPricesInOracle = async (
|
|||
};
|
||||
|
||||
export const deployMockAggregators = async (initialPrices: SymbolMap<string>, verify?: boolean) => {
|
||||
const aggregators: {[tokenSymbol: string]: MockAggregator} = {};
|
||||
const aggregators: { [tokenSymbol: string]: MockAggregator } = {};
|
||||
for (const tokenContractName of Object.keys(initialPrices)) {
|
||||
if (tokenContractName !== 'ETH') {
|
||||
const priceIndex = Object.keys(initialPrices).findIndex(
|
||||
|
@ -116,7 +119,7 @@ export const deployAllMockAggregators = async (
|
|||
initialPrices: iAssetAggregatorBase<string>,
|
||||
verify?: boolean
|
||||
) => {
|
||||
const aggregators: {[tokenSymbol: string]: MockAggregator} = {};
|
||||
const aggregators: { [tokenSymbol: string]: MockAggregator } = {};
|
||||
for (const tokenContractName of Object.keys(initialPrices)) {
|
||||
if (tokenContractName !== 'ETH') {
|
||||
const priceIndex = Object.keys(initialPrices).findIndex(
|
||||
|
|
7
helpers/tenderly-utils.ts
Normal file
7
helpers/tenderly-utils.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { HardhatRuntimeEnvironment } from 'hardhat/types';
|
||||
import { DRE } from './misc-utils';
|
||||
|
||||
export const usingTenderly = () =>
|
||||
DRE &&
|
||||
((DRE as HardhatRuntimeEnvironment).network.name.includes('tenderly') ||
|
||||
process.env.TENDERLY === 'true');
|
157
helpers/types.ts
157
helpers/types.ts
|
@ -4,6 +4,8 @@ export interface SymbolMap<T> {
|
|||
[symbol: string]: T;
|
||||
}
|
||||
|
||||
export type eNetwork = eEthereumNetwork | ePolygonNetwork | eXDaiNetwork;
|
||||
|
||||
export enum eEthereumNetwork {
|
||||
buidlerevm = 'buidlerevm',
|
||||
kovan = 'kovan',
|
||||
|
@ -14,14 +16,28 @@ export enum eEthereumNetwork {
|
|||
tenderlyMain = 'tenderlyMain',
|
||||
}
|
||||
|
||||
export enum ePolygonNetwork {
|
||||
matic = 'matic',
|
||||
mumbai = 'mumbai',
|
||||
}
|
||||
|
||||
export enum eXDaiNetwork {
|
||||
xdai = 'xdai',
|
||||
}
|
||||
|
||||
export enum EthereumNetworkNames {
|
||||
kovan = 'kovan',
|
||||
ropsten = 'ropsten',
|
||||
main = 'main',
|
||||
matic = 'matic',
|
||||
mumbai = 'mumbai',
|
||||
xdai = 'xdai',
|
||||
}
|
||||
|
||||
export enum AavePools {
|
||||
proto = 'proto',
|
||||
matic = 'matic',
|
||||
amm = 'amm',
|
||||
}
|
||||
|
||||
export enum eContractid {
|
||||
|
@ -70,6 +86,7 @@ export enum eContractid {
|
|||
MockUniswapV2Router02 = 'MockUniswapV2Router02',
|
||||
UniswapLiquiditySwapAdapter = 'UniswapLiquiditySwapAdapter',
|
||||
UniswapRepayAdapter = 'UniswapRepayAdapter',
|
||||
FlashLiquidationAdapter = 'FlashLiquidationAdapter',
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -203,6 +220,25 @@ export interface iAssetBase<T> {
|
|||
USD: T;
|
||||
REN: T;
|
||||
ENJ: T;
|
||||
UniDAIWETH: T;
|
||||
UniWBTCWETH: T;
|
||||
UniAAVEWETH: T;
|
||||
UniBATWETH: T;
|
||||
UniDAIUSDC: T;
|
||||
UniCRVWETH: T;
|
||||
UniLINKWETH: T;
|
||||
UniMKRWETH: T;
|
||||
UniRENWETH: T;
|
||||
UniSNXWETH: T;
|
||||
UniUNIWETH: T;
|
||||
UniUSDCWETH: T;
|
||||
UniWBTCUSDC: T;
|
||||
UniYFIWETH: T;
|
||||
BptWBTCWETH: T;
|
||||
BptBALWETH: T;
|
||||
WMATIC: T;
|
||||
STAKE: T;
|
||||
xSUSHI: T;
|
||||
}
|
||||
|
||||
export type iAssetsWithoutETH<T> = Omit<iAssetBase<T>, 'ETH'>;
|
||||
|
@ -231,6 +267,42 @@ export type iAavePoolAssets<T> = Pick<
|
|||
| 'UNI'
|
||||
| 'REN'
|
||||
| 'ENJ'
|
||||
| 'xSUSHI'
|
||||
>;
|
||||
|
||||
export type iLpPoolAssets<T> = Pick<
|
||||
iAssetsWithoutUSD<T>,
|
||||
| 'DAI'
|
||||
| 'USDC'
|
||||
| 'USDT'
|
||||
| 'WBTC'
|
||||
| 'WETH'
|
||||
| 'UniDAIWETH'
|
||||
| 'UniWBTCWETH'
|
||||
| 'UniAAVEWETH'
|
||||
| 'UniBATWETH'
|
||||
| 'UniDAIUSDC'
|
||||
| 'UniCRVWETH'
|
||||
| 'UniLINKWETH'
|
||||
| 'UniMKRWETH'
|
||||
| 'UniRENWETH'
|
||||
| 'UniSNXWETH'
|
||||
| 'UniUNIWETH'
|
||||
| 'UniUSDCWETH'
|
||||
| 'UniWBTCUSDC'
|
||||
| 'UniYFIWETH'
|
||||
| 'BptWBTCWETH'
|
||||
| 'BptBALWETH'
|
||||
>;
|
||||
|
||||
export type iMaticPoolAssets<T> = Pick<
|
||||
iAssetsWithoutUSD<T>,
|
||||
'DAI' | 'USDC' | 'USDT' | 'WBTC' | 'WETH' | 'WMATIC'
|
||||
>;
|
||||
|
||||
export type iXDAIPoolAssets<T> = Pick<
|
||||
iAssetsWithoutUSD<T>,
|
||||
'DAI' | 'USDC' | 'USDT' | 'WBTC' | 'WETH' | 'STAKE'
|
||||
>;
|
||||
|
||||
export type iMultiPoolsAssets<T> = iAssetCommon<T> | iAavePoolAssets<T>;
|
||||
|
@ -261,20 +333,50 @@ export enum TokenContractId {
|
|||
YFI = 'YFI',
|
||||
UNI = 'UNI',
|
||||
ENJ = 'ENJ',
|
||||
UniDAIWETH = 'UniDAIWETH',
|
||||
UniWBTCWETH = 'UniWBTCWETH',
|
||||
UniAAVEWETH = 'UniAAVEWETH',
|
||||
UniBATWETH = 'UniBATWETH',
|
||||
UniDAIUSDC = 'UniDAIUSDC',
|
||||
UniCRVWETH = 'UniCRVWETH',
|
||||
UniLINKWETH = 'UniLINKWETH',
|
||||
UniMKRWETH = 'UniMKRWETH',
|
||||
UniRENWETH = 'UniRENWETH',
|
||||
UniSNXWETH = 'UniSNXWETH',
|
||||
UniUNIWETH = 'UniUNIWETH',
|
||||
UniUSDCWETH = 'UniUSDCWETH',
|
||||
UniWBTCUSDC = 'UniWBTCUSDC',
|
||||
UniYFIWETH = 'UniYFIWETH',
|
||||
BptWBTCWETH = 'BptWBTCWETH',
|
||||
BptBALWETH = 'BptBALWETH',
|
||||
WMATIC = 'WMATIC',
|
||||
STAKE = 'STAKE',
|
||||
xSUSHI = 'xSUSHI'
|
||||
}
|
||||
|
||||
export interface IReserveParams extends IReserveBorrowParams, IReserveCollateralParams {
|
||||
aTokenImpl: eContractid;
|
||||
reserveFactor: string;
|
||||
strategy: IInterestRateStrategyParams;
|
||||
}
|
||||
|
||||
export interface IReserveBorrowParams {
|
||||
export interface IInterestRateStrategyParams {
|
||||
name: string;
|
||||
optimalUtilizationRate: string;
|
||||
baseVariableBorrowRate: string;
|
||||
variableRateSlope1: string;
|
||||
variableRateSlope2: string;
|
||||
stableRateSlope1: string;
|
||||
stableRateSlope2: string;
|
||||
}
|
||||
|
||||
export interface IReserveBorrowParams {
|
||||
// optimalUtilizationRate: string;
|
||||
// baseVariableBorrowRate: string;
|
||||
// variableRateSlope1: string;
|
||||
// variableRateSlope2: string;
|
||||
// stableRateSlope1: string;
|
||||
// stableRateSlope2: string;
|
||||
borrowingEnabled: boolean;
|
||||
stableBorrowRateEnabled: boolean;
|
||||
reserveDecimals: string;
|
||||
|
@ -289,7 +391,17 @@ export interface IMarketRates {
|
|||
borrowRate: string;
|
||||
}
|
||||
|
||||
export interface iParamsPerNetwork<T> {
|
||||
export type iParamsPerNetwork<T> =
|
||||
| iEthereumParamsPerNetwork<T>
|
||||
| iPolygonParamsPerNetwork<T>
|
||||
| iXDaiParamsPerNetwork<T>;
|
||||
|
||||
export interface iParamsPerNetworkAll<T>
|
||||
extends iEthereumParamsPerNetwork<T>,
|
||||
iPolygonParamsPerNetwork<T>,
|
||||
iXDaiParamsPerNetwork<T> {}
|
||||
|
||||
export interface iEthereumParamsPerNetwork<T> {
|
||||
[eEthereumNetwork.coverage]: T;
|
||||
[eEthereumNetwork.buidlerevm]: T;
|
||||
[eEthereumNetwork.kovan]: T;
|
||||
|
@ -299,8 +411,19 @@ export interface iParamsPerNetwork<T> {
|
|||
[eEthereumNetwork.tenderlyMain]: T;
|
||||
}
|
||||
|
||||
export interface iPolygonParamsPerNetwork<T> {
|
||||
[ePolygonNetwork.matic]: T;
|
||||
[ePolygonNetwork.mumbai]: T;
|
||||
}
|
||||
|
||||
export interface iXDaiParamsPerNetwork<T> {
|
||||
[eXDaiNetwork.xdai]: T;
|
||||
}
|
||||
|
||||
export interface iParamsPerPool<T> {
|
||||
[AavePools.proto]: T;
|
||||
[AavePools.matic]: T;
|
||||
[AavePools.amm]: T;
|
||||
}
|
||||
|
||||
export interface iBasicDistributionParams {
|
||||
|
@ -318,15 +441,6 @@ export interface ObjectString {
|
|||
[key: string]: string;
|
||||
}
|
||||
|
||||
export enum EthereumNetwork {
|
||||
kovan = 'kovan',
|
||||
ropsten = 'ropsten',
|
||||
development = 'development',
|
||||
main = 'main',
|
||||
coverage = 'soliditycoverage',
|
||||
tenderlyMain = 'tenderlyMain',
|
||||
}
|
||||
|
||||
export interface IProtocolGlobalConfig {
|
||||
TokenDistributorPercentageBase: string;
|
||||
MockUsdPriceInWei: string;
|
||||
|
@ -350,11 +464,18 @@ export interface ILendingRate {
|
|||
|
||||
export interface ICommonConfiguration {
|
||||
MarketId: string;
|
||||
ATokenNamePrefix: string;
|
||||
StableDebtTokenNamePrefix: string;
|
||||
VariableDebtTokenNamePrefix: string;
|
||||
SymbolPrefix: string;
|
||||
ProviderId: number;
|
||||
ProtocolGlobalParams: IProtocolGlobalConfig;
|
||||
Mocks: IMocksConfig;
|
||||
ProviderRegistry: iParamsPerNetwork<tEthereumAddress | undefined>;
|
||||
ProviderRegistryOwner: iParamsPerNetwork<tEthereumAddress | undefined>;
|
||||
LendingPoolCollateralManager: iParamsPerNetwork<tEthereumAddress>;
|
||||
LendingPoolConfigurator: iParamsPerNetwork<tEthereumAddress>;
|
||||
LendingPool: iParamsPerNetwork<tEthereumAddress>;
|
||||
LendingRateOracleRatesCommon: iMultiPoolsAssets<IMarketRates>;
|
||||
LendingRateOracle: iParamsPerNetwork<tEthereumAddress>;
|
||||
TokenDistributor: iParamsPerNetwork<tEthereumAddress>;
|
||||
|
@ -369,12 +490,26 @@ export interface ICommonConfiguration {
|
|||
ReservesConfig: iMultiPoolsAssets<IReserveParams>;
|
||||
ATokenDomainSeparator: iParamsPerNetwork<string>;
|
||||
WETH: iParamsPerNetwork<tEthereumAddress>;
|
||||
WethGateway: iParamsPerNetwork<tEthereumAddress>;
|
||||
ReserveFactorTreasuryAddress: iParamsPerNetwork<tEthereumAddress>;
|
||||
}
|
||||
|
||||
export interface IAaveConfiguration extends ICommonConfiguration {
|
||||
ReservesConfig: iAavePoolAssets<IReserveParams>;
|
||||
}
|
||||
|
||||
export interface IAmmConfiguration extends ICommonConfiguration {
|
||||
ReservesConfig: iLpPoolAssets<IReserveParams>;
|
||||
}
|
||||
|
||||
export interface IMaticConfiguration extends ICommonConfiguration {
|
||||
ReservesConfig: iMaticPoolAssets<IReserveParams>;
|
||||
}
|
||||
|
||||
export interface IXDAIConfiguration extends ICommonConfiguration {
|
||||
ReservesConfig: iXDAIPoolAssets<IReserveParams>;
|
||||
}
|
||||
|
||||
export interface ITokenAddress {
|
||||
[token: string]: tEthereumAddress;
|
||||
}
|
||||
|
|
|
@ -1,37 +1,18 @@
|
|||
import BigNumber from 'bignumber.js';
|
||||
import { oneEther, oneRay, RAY, ZERO_ADDRESS } from '../../helpers/constants';
|
||||
import { ICommonConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
|
||||
import { oneEther, oneRay, RAY, ZERO_ADDRESS, MOCK_CHAINLINK_AGGREGATORS_PRICES } from '../../helpers/constants';
|
||||
import { ICommonConfiguration, eEthereumNetwork } from '../../helpers/types';
|
||||
|
||||
const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
|
||||
AAVE: oneEther.multipliedBy('0.003620948469').toFixed(),
|
||||
BAT: oneEther.multipliedBy('0.00137893825230').toFixed(),
|
||||
BUSD: oneEther.multipliedBy('0.00736484').toFixed(),
|
||||
DAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
|
||||
ENJ: oneEther.multipliedBy('0.00029560').toFixed(),
|
||||
KNC: oneEther.multipliedBy('0.001072').toFixed(),
|
||||
LINK: oneEther.multipliedBy('0.009955').toFixed(),
|
||||
MANA: oneEther.multipliedBy('0.000158').toFixed(),
|
||||
MKR: oneEther.multipliedBy('2.508581').toFixed(),
|
||||
REN: oneEther.multipliedBy('0.00065133').toFixed(),
|
||||
SNX: oneEther.multipliedBy('0.00442616').toFixed(),
|
||||
SUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
|
||||
TUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
|
||||
UNI: oneEther.multipliedBy('0.00536479').toFixed(),
|
||||
USDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
|
||||
USDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
|
||||
WETH: oneEther.toFixed(),
|
||||
WBTC: oneEther.multipliedBy('47.332685').toFixed(),
|
||||
YFI: oneEther.multipliedBy('22.407436').toFixed(),
|
||||
ZRX: oneEther.multipliedBy('0.001151').toFixed(),
|
||||
USD: '5848466240000000',
|
||||
};
|
||||
// ----------------
|
||||
// PROTOCOL GLOBAL PARAMS
|
||||
// ----------------
|
||||
|
||||
export const CommonsConfig: ICommonConfiguration = {
|
||||
MarketId: 'Commons',
|
||||
ProviderId: 0,
|
||||
ATokenNamePrefix: 'Aave interest bearing',
|
||||
StableDebtTokenNamePrefix: 'Aave stable debt bearing',
|
||||
VariableDebtTokenNamePrefix: 'Aave variable debt bearing',
|
||||
SymbolPrefix: '',
|
||||
ProviderId: 0, // Overriden in index.ts
|
||||
ProtocolGlobalParams: {
|
||||
TokenDistributorPercentageBase: '10000',
|
||||
MockUsdPriceInWei: '5848466240000000',
|
||||
|
@ -158,43 +139,79 @@ export const CommonsConfig: ICommonConfiguration = {
|
|||
[eEthereumNetwork.coverage]: '',
|
||||
[eEthereumNetwork.hardhat]: '',
|
||||
[eEthereumNetwork.buidlerevm]: '',
|
||||
[eEthereumNetwork.kovan]: '0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a',
|
||||
[eEthereumNetwork.kovan]: '',//'0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a',
|
||||
[eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b',
|
||||
[eEthereumNetwork.main]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
|
||||
[eEthereumNetwork.main]: '',//'0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
|
||||
[eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
|
||||
},
|
||||
LendingPoolCollateralManager: {
|
||||
[eEthereumNetwork.coverage]: '',
|
||||
[eEthereumNetwork.hardhat]: '',
|
||||
[eEthereumNetwork.buidlerevm]: '',
|
||||
[eEthereumNetwork.kovan]: '0x9269b6453d0d75370c4c85e5a42977a53efdb72a',
|
||||
[eEthereumNetwork.ropsten]: '',
|
||||
[eEthereumNetwork.main]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
|
||||
[eEthereumNetwork.tenderlyMain]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
|
||||
},
|
||||
LendingPoolConfigurator: {
|
||||
[eEthereumNetwork.coverage]: '',
|
||||
[eEthereumNetwork.hardhat]: '',
|
||||
[eEthereumNetwork.buidlerevm]: '',
|
||||
[eEthereumNetwork.kovan]: '',
|
||||
[eEthereumNetwork.ropsten]: '',
|
||||
[eEthereumNetwork.main]: '',
|
||||
[eEthereumNetwork.tenderlyMain]: '',
|
||||
},
|
||||
LendingPool: {
|
||||
[eEthereumNetwork.coverage]: '',
|
||||
[eEthereumNetwork.hardhat]: '',
|
||||
[eEthereumNetwork.buidlerevm]: '',
|
||||
[eEthereumNetwork.kovan]: '',
|
||||
[eEthereumNetwork.ropsten]: '',
|
||||
[eEthereumNetwork.main]: '',
|
||||
[eEthereumNetwork.tenderlyMain]: '',
|
||||
},
|
||||
WethGateway: {
|
||||
[eEthereumNetwork.coverage]: '',
|
||||
[eEthereumNetwork.hardhat]: '',
|
||||
[eEthereumNetwork.buidlerevm]: '',
|
||||
[eEthereumNetwork.kovan]: '0xf99b8E67a0E044734B01EC4586D1c88C9a869718',
|
||||
[eEthereumNetwork.ropsten]: '',
|
||||
[eEthereumNetwork.main]: '',
|
||||
[eEthereumNetwork.tenderlyMain]: '',
|
||||
},
|
||||
TokenDistributor: {
|
||||
[eEthereumNetwork.coverage]: '',
|
||||
[eEthereumNetwork.buidlerevm]: '',
|
||||
[eEthereumNetwork.hardhat]: '',
|
||||
[EthereumNetwork.kovan]: '0x971efe90088f21dc6a36f610ffed77fc19710708',
|
||||
[EthereumNetwork.ropsten]: '0xeba2ea67942b8250d870b12750b594696d02fc9c',
|
||||
[EthereumNetwork.main]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
|
||||
[EthereumNetwork.tenderlyMain]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
|
||||
[eEthereumNetwork.kovan]: '0x971efe90088f21dc6a36f610ffed77fc19710708',
|
||||
[eEthereumNetwork.ropsten]: '0xeba2ea67942b8250d870b12750b594696d02fc9c',
|
||||
[eEthereumNetwork.main]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
|
||||
[eEthereumNetwork.tenderlyMain]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
|
||||
},
|
||||
AaveOracle: {
|
||||
[eEthereumNetwork.coverage]: '',
|
||||
[eEthereumNetwork.hardhat]: '',
|
||||
[eEthereumNetwork.buidlerevm]: '',
|
||||
[EthereumNetwork.kovan]: '0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1',
|
||||
[EthereumNetwork.ropsten]: ZERO_ADDRESS,
|
||||
[EthereumNetwork.main]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
|
||||
[EthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
|
||||
[eEthereumNetwork.kovan]: '',//'0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1',
|
||||
[eEthereumNetwork.ropsten]: ZERO_ADDRESS,
|
||||
[eEthereumNetwork.main]: '',//'0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
|
||||
[eEthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
|
||||
},
|
||||
FallbackOracle: {
|
||||
[eEthereumNetwork.coverage]: '',
|
||||
[eEthereumNetwork.hardhat]: '',
|
||||
[eEthereumNetwork.buidlerevm]: '',
|
||||
[EthereumNetwork.kovan]: '0x50913E8E1c650E790F8a1E741FF9B1B1bB251dfe',
|
||||
[EthereumNetwork.ropsten]: '0xAD1a978cdbb8175b2eaeC47B01404f8AEC5f4F0d',
|
||||
[EthereumNetwork.main]: ZERO_ADDRESS,
|
||||
[EthereumNetwork.tenderlyMain]: ZERO_ADDRESS,
|
||||
[eEthereumNetwork.kovan]: '0x50913E8E1c650E790F8a1E741FF9B1B1bB251dfe',
|
||||
[eEthereumNetwork.ropsten]: '0xAD1a978cdbb8175b2eaeC47B01404f8AEC5f4F0d',
|
||||
[eEthereumNetwork.main]: ZERO_ADDRESS,
|
||||
[eEthereumNetwork.tenderlyMain]: ZERO_ADDRESS,
|
||||
},
|
||||
ChainlinkAggregator: {
|
||||
[eEthereumNetwork.coverage]: {},
|
||||
[eEthereumNetwork.hardhat]: {},
|
||||
[eEthereumNetwork.buidlerevm]: {},
|
||||
[EthereumNetwork.kovan]: {
|
||||
[eEthereumNetwork.kovan]: {
|
||||
AAVE: '0xd04647B7CB523bb9f26730E9B6dE1174db7591Ad',
|
||||
BAT: '0x0e4fcEC26c9f85c3D714370c98f43C4E02Fc35Ae',
|
||||
BUSD: '0xbF7A18ea5DE0501f7559144e702b29c55b055CcB',
|
||||
|
@ -216,7 +233,7 @@ export const CommonsConfig: ICommonConfiguration = {
|
|||
ZRX: '0xBc3f28Ccc21E9b5856E81E6372aFf57307E2E883',
|
||||
USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
|
||||
},
|
||||
[EthereumNetwork.ropsten]: {
|
||||
[eEthereumNetwork.ropsten]: {
|
||||
AAVE: ZERO_ADDRESS,
|
||||
BAT: '0xafd8186c962daf599f171b8600f3e19af7b52c92',
|
||||
BUSD: '0x0A32D96Ff131cd5c3E0E5AAB645BF009Eda61564',
|
||||
|
@ -238,7 +255,7 @@ export const CommonsConfig: ICommonConfiguration = {
|
|||
ZRX: '0x1d0052e4ae5b4ae4563cbac50edc3627ca0460d7',
|
||||
USD: '0x8468b2bDCE073A157E560AA4D9CcF6dB1DB98507',
|
||||
},
|
||||
[EthereumNetwork.main]: {
|
||||
[eEthereumNetwork.main]: {
|
||||
AAVE: '0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012',
|
||||
BAT: '0x0d16d4528239e9ee52fa531af613AcdB23D88c94',
|
||||
BUSD: '0x614715d2Af89E6EC99A233818275142cE88d1Cfd',
|
||||
|
@ -260,7 +277,7 @@ export const CommonsConfig: ICommonConfiguration = {
|
|||
ZRX: '0x2Da4983a622a8498bb1a21FaE9D8F6C664939962',
|
||||
USD: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419',
|
||||
},
|
||||
[EthereumNetwork.tenderlyMain]: {
|
||||
[eEthereumNetwork.tenderlyMain]: {
|
||||
AAVE: '0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012',
|
||||
BAT: '0x0d16d4528239e9ee52fa531af613AcdB23D88c94',
|
||||
BUSD: '0x614715d2Af89E6EC99A233818275142cE88d1Cfd',
|
||||
|
@ -287,10 +304,10 @@ export const CommonsConfig: ICommonConfiguration = {
|
|||
[eEthereumNetwork.coverage]: {},
|
||||
[eEthereumNetwork.hardhat]: {},
|
||||
[eEthereumNetwork.buidlerevm]: {},
|
||||
[EthereumNetwork.main]: {},
|
||||
[EthereumNetwork.kovan]: {},
|
||||
[EthereumNetwork.ropsten]: {},
|
||||
[EthereumNetwork.tenderlyMain]: {},
|
||||
[eEthereumNetwork.main]: {},
|
||||
[eEthereumNetwork.kovan]: {},
|
||||
[eEthereumNetwork.ropsten]: {},
|
||||
[eEthereumNetwork.tenderlyMain]: {},
|
||||
},
|
||||
ReservesConfig: {},
|
||||
ATokenDomainSeparator: {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { oneRay, ZERO_ADDRESS } from '../../helpers/constants';
|
||||
import { IAaveConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
|
||||
import { IAaveConfiguration, eEthereumNetwork } from '../../helpers/types';
|
||||
|
||||
import { CommonsConfig } from './commons';
|
||||
import {
|
||||
|
@ -22,6 +22,7 @@ import {
|
|||
strategyWBTC,
|
||||
strategyWETH,
|
||||
strategyYFI,
|
||||
strategyXSUSHI,
|
||||
} from './reservesConfigs';
|
||||
|
||||
// ----------------
|
||||
|
@ -53,12 +54,13 @@ export const AaveConfig: IAaveConfiguration = {
|
|||
WETH: strategyWETH,
|
||||
YFI: strategyYFI,
|
||||
ZRX: strategyZRX,
|
||||
xSUSHI: strategyXSUSHI,
|
||||
},
|
||||
ReserveAssets: {
|
||||
[eEthereumNetwork.buidlerevm]: {},
|
||||
[eEthereumNetwork.hardhat]: {},
|
||||
[eEthereumNetwork.coverage]: {},
|
||||
[EthereumNetwork.kovan]: {
|
||||
[eEthereumNetwork.kovan]: {
|
||||
AAVE: '0xB597cd8D3217ea6477232F9217fa70837ff667Af',
|
||||
BAT: '0x2d12186Fbb9f9a8C28B3FfdD4c42920f8539D738',
|
||||
BUSD: '0x4c6E1EFC12FDfD568186b7BAEc0A43fFfb4bCcCf',
|
||||
|
@ -80,7 +82,7 @@ export const AaveConfig: IAaveConfiguration = {
|
|||
YFI: '0xb7c325266ec274fEb1354021D27FA3E3379D840d',
|
||||
ZRX: '0xD0d76886cF8D952ca26177EB7CfDf83bad08C00C',
|
||||
},
|
||||
[EthereumNetwork.ropsten]: {
|
||||
[eEthereumNetwork.ropsten]: {
|
||||
AAVE: '',
|
||||
BAT: '0x85B24b3517E3aC7bf72a14516160541A60cFF19d',
|
||||
BUSD: '0xFA6adcFf6A90c11f31Bc9bb59eC0a6efB38381C6',
|
||||
|
@ -102,7 +104,7 @@ export const AaveConfig: IAaveConfiguration = {
|
|||
YFI: ZERO_ADDRESS,
|
||||
ZRX: '0x02d7055704EfF050323A2E5ee4ba05DB2A588959',
|
||||
},
|
||||
[EthereumNetwork.main]: {
|
||||
[eEthereumNetwork.main]: {
|
||||
AAVE: '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9',
|
||||
BAT: '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
|
||||
BUSD: '0x4Fabb145d64652a948d72533023f6E7A623C7C53',
|
||||
|
@ -123,8 +125,9 @@ export const AaveConfig: IAaveConfiguration = {
|
|||
WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
|
||||
YFI: '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e',
|
||||
ZRX: '0xE41d2489571d322189246DaFA5ebDe1F4699F498',
|
||||
xSUSHI: '0x8798249c2E607446EfB7Ad49eC89dD1865Ff4272',
|
||||
},
|
||||
[EthereumNetwork.tenderlyMain]: {
|
||||
[eEthereumNetwork.tenderlyMain]: {
|
||||
AAVE: '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9',
|
||||
BAT: '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
|
||||
BUSD: '0x4Fabb145d64652a948d72533023f6E7A623C7C53',
|
||||
|
@ -145,6 +148,7 @@ export const AaveConfig: IAaveConfiguration = {
|
|||
WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
|
||||
YFI: '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e',
|
||||
ZRX: '0xE41d2489571d322189246DaFA5ebDe1F4699F498',
|
||||
xSUSHI: '0x8798249c2E607446EfB7Ad49eC89dD1865Ff4272',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
105
markets/aave/rateStrategies.ts
Normal file
105
markets/aave/rateStrategies.ts
Normal file
|
@ -0,0 +1,105 @@
|
|||
import BigNumber from 'bignumber.js';
|
||||
import { oneRay } from '../../helpers/constants';
|
||||
import { IInterestRateStrategyParams } from '../../helpers/types';
|
||||
|
||||
// BUSD SUSD
|
||||
export const rateStrategyStableOne: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyStableOne",
|
||||
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: '0',
|
||||
stableRateSlope2: '0',
|
||||
};
|
||||
|
||||
// DAI TUSD
|
||||
export const rateStrategyStableTwo: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyStableTwo",
|
||||
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
|
||||
}
|
||||
|
||||
// USDC USDT
|
||||
export const rateStrategyStableThree: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyStableThree",
|
||||
optimalUtilizationRate: new BigNumber(0.9).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
|
||||
}
|
||||
|
||||
// WETH
|
||||
export const rateStrategyWETH: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyWETH",
|
||||
optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
|
||||
}
|
||||
|
||||
// AAVE
|
||||
export const rateStrategyAAVE: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyAAVE",
|
||||
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: '0',
|
||||
variableRateSlope1: '0',
|
||||
variableRateSlope2: '0',
|
||||
stableRateSlope1: '0',
|
||||
stableRateSlope2: '0',
|
||||
}
|
||||
|
||||
// BAT ENJ LINK MANA MKR REN YFI ZRX
|
||||
export const rateStrategyVolatileOne: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyVolatileOne",
|
||||
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
}
|
||||
|
||||
// KNC WBTC
|
||||
export const rateStrategyVolatileTwo: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyVolatileTwo",
|
||||
optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
}
|
||||
|
||||
// SNX
|
||||
export const rateStrategyVolatileThree: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyVolatileThree",
|
||||
optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
}
|
||||
|
||||
|
||||
export const rateStrategyVolatileFour: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyVolatileFour",
|
||||
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: '0',
|
||||
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: '0',
|
||||
stableRateSlope2: '0',
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,14 +1,19 @@
|
|||
import BigNumber from 'bignumber.js';
|
||||
import { oneRay } from '../../helpers/constants';
|
||||
import { eContractid, IReserveParams } from '../../helpers/types';
|
||||
|
||||
import {
|
||||
rateStrategyStableOne,
|
||||
rateStrategyStableTwo,
|
||||
rateStrategyStableThree,
|
||||
rateStrategyWETH,
|
||||
rateStrategyAAVE,
|
||||
rateStrategyVolatileOne,
|
||||
rateStrategyVolatileTwo,
|
||||
rateStrategyVolatileThree,
|
||||
rateStrategyVolatileFour,
|
||||
} from './rateStrategies';
|
||||
|
||||
export const strategyBUSD: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: '0',
|
||||
stableRateSlope2: '0',
|
||||
strategy: rateStrategyStableOne,
|
||||
baseLTVAsCollateral: '0',
|
||||
liquidationThreshold: '0',
|
||||
liquidationBonus: '0',
|
||||
|
@ -20,12 +25,7 @@ export const strategyBUSD: IReserveParams = {
|
|||
};
|
||||
|
||||
export const strategyDAI: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
|
||||
strategy: rateStrategyStableTwo,
|
||||
baseLTVAsCollateral: '7500',
|
||||
liquidationThreshold: '8000',
|
||||
liquidationBonus: '10500',
|
||||
|
@ -37,12 +37,7 @@ export const strategyDAI: IReserveParams = {
|
|||
};
|
||||
|
||||
export const strategySUSD: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: '0',
|
||||
stableRateSlope2: '0',
|
||||
strategy: rateStrategyStableOne,
|
||||
baseLTVAsCollateral: '0',
|
||||
liquidationThreshold: '0',
|
||||
liquidationBonus: '0',
|
||||
|
@ -54,12 +49,7 @@ export const strategySUSD: IReserveParams = {
|
|||
};
|
||||
|
||||
export const strategyTUSD: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
|
||||
strategy: rateStrategyStableTwo,
|
||||
baseLTVAsCollateral: '7500',
|
||||
liquidationThreshold: '8000',
|
||||
liquidationBonus: '10500',
|
||||
|
@ -71,12 +61,7 @@ export const strategyTUSD: IReserveParams = {
|
|||
};
|
||||
|
||||
export const strategyUSDC: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.9).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
|
||||
strategy: rateStrategyStableThree,
|
||||
baseLTVAsCollateral: '8000',
|
||||
liquidationThreshold: '8500',
|
||||
liquidationBonus: '10500',
|
||||
|
@ -88,12 +73,7 @@ export const strategyUSDC: IReserveParams = {
|
|||
};
|
||||
|
||||
export const strategyUSDT: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.9).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
|
||||
strategy: rateStrategyStableThree,
|
||||
baseLTVAsCollateral: '8000',
|
||||
liquidationThreshold: '8500',
|
||||
liquidationBonus: '10500',
|
||||
|
@ -105,12 +85,7 @@ export const strategyUSDT: IReserveParams = {
|
|||
};
|
||||
|
||||
export const strategyAAVE: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: '0',
|
||||
variableRateSlope1: '0',
|
||||
variableRateSlope2: '0',
|
||||
stableRateSlope1: '0',
|
||||
stableRateSlope2: '0',
|
||||
strategy: rateStrategyAAVE,
|
||||
baseLTVAsCollateral: '5000',
|
||||
liquidationThreshold: '6500',
|
||||
liquidationBonus: '11000',
|
||||
|
@ -122,12 +97,7 @@ export const strategyAAVE: IReserveParams = {
|
|||
};
|
||||
|
||||
export const strategyBAT: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
strategy: rateStrategyVolatileOne,
|
||||
baseLTVAsCollateral: '7000',
|
||||
liquidationThreshold: '7500',
|
||||
liquidationBonus: '11000',
|
||||
|
@ -139,12 +109,7 @@ export const strategyBAT: IReserveParams = {
|
|||
};
|
||||
|
||||
export const strategyENJ: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
strategy: rateStrategyVolatileOne,
|
||||
baseLTVAsCollateral: '5500',
|
||||
liquidationThreshold: '6000',
|
||||
liquidationBonus: '11000',
|
||||
|
@ -156,12 +121,7 @@ export const strategyENJ: IReserveParams = {
|
|||
};
|
||||
|
||||
export const strategyWETH: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
|
||||
strategy: rateStrategyWETH,
|
||||
baseLTVAsCollateral: '8000',
|
||||
liquidationThreshold: '8250',
|
||||
liquidationBonus: '10500',
|
||||
|
@ -173,12 +133,7 @@ export const strategyWETH: IReserveParams = {
|
|||
};
|
||||
|
||||
export const strategyKNC: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
strategy: rateStrategyVolatileTwo,
|
||||
baseLTVAsCollateral: '6000',
|
||||
liquidationThreshold: '6500',
|
||||
liquidationBonus: '11000',
|
||||
|
@ -190,12 +145,7 @@ export const strategyKNC: IReserveParams = {
|
|||
};
|
||||
|
||||
export const strategyLINK: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
strategy: rateStrategyVolatileOne,
|
||||
baseLTVAsCollateral: '7000',
|
||||
liquidationThreshold: '7500',
|
||||
liquidationBonus: '11000',
|
||||
|
@ -207,12 +157,7 @@ export const strategyLINK: IReserveParams = {
|
|||
};
|
||||
|
||||
export const strategyMANA: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
strategy: rateStrategyVolatileOne,
|
||||
baseLTVAsCollateral: '6000',
|
||||
liquidationThreshold: '6500',
|
||||
liquidationBonus: '11000',
|
||||
|
@ -224,12 +169,7 @@ export const strategyMANA: IReserveParams = {
|
|||
};
|
||||
|
||||
export const strategyMKR: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
strategy: rateStrategyVolatileOne,
|
||||
baseLTVAsCollateral: '6000',
|
||||
liquidationThreshold: '6500',
|
||||
liquidationBonus: '11000',
|
||||
|
@ -241,12 +181,7 @@ export const strategyMKR: IReserveParams = {
|
|||
};
|
||||
|
||||
export const strategyREN: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
strategy: rateStrategyVolatileOne,
|
||||
baseLTVAsCollateral: '5500',
|
||||
liquidationThreshold: '6000',
|
||||
liquidationBonus: '11000',
|
||||
|
@ -258,12 +193,7 @@ export const strategyREN: IReserveParams = {
|
|||
};
|
||||
|
||||
export const strategySNX: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.12).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: '0',
|
||||
stableRateSlope2: '0',
|
||||
strategy: rateStrategyVolatileThree,
|
||||
baseLTVAsCollateral: '1500',
|
||||
liquidationThreshold: '4000',
|
||||
liquidationBonus: '11000',
|
||||
|
@ -274,13 +204,9 @@ export const strategySNX: IReserveParams = {
|
|||
reserveFactor: '3500'
|
||||
};
|
||||
|
||||
// Invalid borrow rates in params currently, replaced with snx params
|
||||
export const strategyUNI: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: '0',
|
||||
variableRateSlope1: '0',
|
||||
variableRateSlope2: '0',
|
||||
stableRateSlope1: '0',
|
||||
stableRateSlope2: '0',
|
||||
strategy: rateStrategyVolatileThree,
|
||||
baseLTVAsCollateral: '6000',
|
||||
liquidationThreshold: '6500',
|
||||
liquidationBonus: '11000',
|
||||
|
@ -292,12 +218,7 @@ export const strategyUNI: IReserveParams = {
|
|||
};
|
||||
|
||||
export const strategyWBTC: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: '0',
|
||||
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
strategy: rateStrategyVolatileTwo,
|
||||
baseLTVAsCollateral: '7000',
|
||||
liquidationThreshold: '7500',
|
||||
liquidationBonus: '11000',
|
||||
|
@ -309,12 +230,7 @@ export const strategyWBTC: IReserveParams = {
|
|||
};
|
||||
|
||||
export const strategyYFI: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: '0',
|
||||
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
strategy: rateStrategyVolatileOne,
|
||||
baseLTVAsCollateral: '4000',
|
||||
liquidationThreshold: '5500',
|
||||
liquidationBonus: '11500',
|
||||
|
@ -326,12 +242,7 @@ export const strategyYFI: IReserveParams = {
|
|||
};
|
||||
|
||||
export const strategyZRX: IReserveParams = {
|
||||
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: '0',
|
||||
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
strategy: rateStrategyVolatileOne,
|
||||
baseLTVAsCollateral: '6000',
|
||||
liquidationThreshold: '6500',
|
||||
liquidationBonus: '11000',
|
||||
|
@ -340,4 +251,16 @@ export const strategyZRX: IReserveParams = {
|
|||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '2000'
|
||||
};
|
||||
|
||||
export const strategyXSUSHI: IReserveParams = {
|
||||
strategy: rateStrategyVolatileFour,
|
||||
baseLTVAsCollateral: '2500',
|
||||
liquidationThreshold: '4500',
|
||||
liquidationBonus: '11500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '3500',
|
||||
};
|
338
markets/amm/commons.ts
Normal file
338
markets/amm/commons.ts
Normal file
|
@ -0,0 +1,338 @@
|
|||
import BigNumber from 'bignumber.js';
|
||||
import {
|
||||
oneEther,
|
||||
oneRay,
|
||||
RAY,
|
||||
ZERO_ADDRESS,
|
||||
MOCK_CHAINLINK_AGGREGATORS_PRICES,
|
||||
} from '../../helpers/constants';
|
||||
import { ICommonConfiguration, eEthereumNetwork } from '../../helpers/types';
|
||||
|
||||
// ----------------
|
||||
// PROTOCOL GLOBAL PARAMS
|
||||
// ----------------
|
||||
|
||||
export const CommonsConfig: ICommonConfiguration = {
|
||||
MarketId: 'Commons',
|
||||
ATokenNamePrefix: 'Aave AMM Market',
|
||||
StableDebtTokenNamePrefix: 'Aave AMM Market stable debt',
|
||||
VariableDebtTokenNamePrefix: 'Aave AMM Market variable debt',
|
||||
SymbolPrefix: 'Amm',
|
||||
ProviderId: 0, // Overriden in index.ts
|
||||
ProtocolGlobalParams: {
|
||||
TokenDistributorPercentageBase: '10000',
|
||||
MockUsdPriceInWei: '5848466240000000',
|
||||
UsdAddress: '0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96',
|
||||
NilAddress: '0x0000000000000000000000000000000000000000',
|
||||
OneAddress: '0x0000000000000000000000000000000000000001',
|
||||
AaveReferral: '0',
|
||||
},
|
||||
|
||||
// ----------------
|
||||
// COMMON PROTOCOL PARAMS ACROSS POOLS AND NETWORKS
|
||||
// ----------------
|
||||
|
||||
Mocks: {
|
||||
AllAssetsInitialPrices: {
|
||||
...MOCK_CHAINLINK_AGGREGATORS_PRICES,
|
||||
},
|
||||
},
|
||||
// TODO: reorg alphabetically, checking the reason of tests failing
|
||||
LendingRateOracleRatesCommon: {
|
||||
WETH: {
|
||||
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
|
||||
},
|
||||
DAI: {
|
||||
borrowRate: oneRay.multipliedBy(0.039).toFixed(),
|
||||
},
|
||||
USDC: {
|
||||
borrowRate: oneRay.multipliedBy(0.039).toFixed(),
|
||||
},
|
||||
USDT: {
|
||||
borrowRate: oneRay.multipliedBy(0.035).toFixed(),
|
||||
},
|
||||
WBTC: {
|
||||
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
|
||||
},
|
||||
UniDAIWETH: {
|
||||
borrowRate: oneRay.multipliedBy(0.05).toFixed(),
|
||||
},
|
||||
UniWBTCWETH: {
|
||||
borrowRate: oneRay.multipliedBy(0.05).toFixed(),
|
||||
},
|
||||
UniAAVEWETH: {
|
||||
borrowRate: oneRay.multipliedBy(0.05).toFixed(),
|
||||
},
|
||||
UniBATWETH: {
|
||||
borrowRate: oneRay.multipliedBy(0.05).toFixed(),
|
||||
},
|
||||
UniDAIUSDC: {
|
||||
borrowRate: oneRay.multipliedBy(0.05).toFixed(),
|
||||
},
|
||||
UniCRVWETH: {
|
||||
borrowRate: oneRay.multipliedBy(0.05).toFixed(),
|
||||
},
|
||||
UniLINKWETH: {
|
||||
borrowRate: oneRay.multipliedBy(0.05).toFixed(),
|
||||
},
|
||||
UniMKRWETH: {
|
||||
borrowRate: oneRay.multipliedBy(0.05).toFixed(),
|
||||
},
|
||||
UniRENWETH: {
|
||||
borrowRate: oneRay.multipliedBy(0.05).toFixed(),
|
||||
},
|
||||
UniSNXWETH: {
|
||||
borrowRate: oneRay.multipliedBy(0.05).toFixed(),
|
||||
},
|
||||
UniUNIWETH: {
|
||||
borrowRate: oneRay.multipliedBy(0.05).toFixed(),
|
||||
},
|
||||
UniUSDCWETH: {
|
||||
borrowRate: oneRay.multipliedBy(0.05).toFixed(),
|
||||
},
|
||||
UniWBTCUSDC: {
|
||||
borrowRate: oneRay.multipliedBy(0.05).toFixed(),
|
||||
},
|
||||
UniYFIWETH: {
|
||||
borrowRate: oneRay.multipliedBy(0.05).toFixed(),
|
||||
},
|
||||
BptWBTCWETH: {
|
||||
borrowRate: oneRay.multipliedBy(0.05).toFixed(),
|
||||
},
|
||||
BptBALWETH: {
|
||||
borrowRate: oneRay.multipliedBy(0.05).toFixed(),
|
||||
},
|
||||
},
|
||||
// ----------------
|
||||
// COMMON PROTOCOL ADDRESSES ACROSS POOLS
|
||||
// ----------------
|
||||
|
||||
// If PoolAdmin/emergencyAdmin is set, will take priority over PoolAdminIndex/emergencyAdminIndex
|
||||
PoolAdmin: {
|
||||
[eEthereumNetwork.coverage]: undefined,
|
||||
[eEthereumNetwork.buidlerevm]: undefined,
|
||||
[eEthereumNetwork.coverage]: undefined,
|
||||
[eEthereumNetwork.hardhat]: undefined,
|
||||
[eEthereumNetwork.kovan]: undefined,
|
||||
[eEthereumNetwork.ropsten]: undefined,
|
||||
[eEthereumNetwork.main]: undefined,
|
||||
[eEthereumNetwork.tenderlyMain]: undefined,
|
||||
},
|
||||
PoolAdminIndex: 0,
|
||||
EmergencyAdmin: {
|
||||
[eEthereumNetwork.hardhat]: undefined,
|
||||
[eEthereumNetwork.coverage]: undefined,
|
||||
[eEthereumNetwork.buidlerevm]: undefined,
|
||||
[eEthereumNetwork.kovan]: undefined,
|
||||
[eEthereumNetwork.ropsten]: undefined,
|
||||
[eEthereumNetwork.main]: undefined,
|
||||
[eEthereumNetwork.tenderlyMain]: undefined,
|
||||
},
|
||||
EmergencyAdminIndex: 1,
|
||||
ProviderRegistry: {
|
||||
[eEthereumNetwork.kovan]: '0x1E40B561EC587036f9789aF83236f057D1ed2A90',
|
||||
[eEthereumNetwork.ropsten]: '',
|
||||
[eEthereumNetwork.main]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413',
|
||||
[eEthereumNetwork.coverage]: '',
|
||||
[eEthereumNetwork.hardhat]: '',
|
||||
[eEthereumNetwork.buidlerevm]: '',
|
||||
[eEthereumNetwork.tenderlyMain]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413',
|
||||
},
|
||||
ProviderRegistryOwner: {
|
||||
// DEPLOYED WITH CORRECT ADDRESS
|
||||
[eEthereumNetwork.kovan]: '0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F',
|
||||
[eEthereumNetwork.ropsten]: '',
|
||||
[eEthereumNetwork.main]: '0xbd723fc4f1d737dcfc48a07fe7336766d34cad5f',
|
||||
[eEthereumNetwork.coverage]: '',
|
||||
[eEthereumNetwork.hardhat]: '',
|
||||
[eEthereumNetwork.buidlerevm]: '',
|
||||
[eEthereumNetwork.tenderlyMain]: '0xbd723fc4f1d737dcfc48a07fe7336766d34cad5f',
|
||||
},
|
||||
LendingRateOracle: {
|
||||
[eEthereumNetwork.coverage]: '',
|
||||
[eEthereumNetwork.hardhat]: '',
|
||||
[eEthereumNetwork.buidlerevm]: '', // Updated to match Kovan deployment
|
||||
[eEthereumNetwork.kovan]: '0xd00Bd28FAdDa9d5658D1D4e0c151973146C7A533', //'0xE48F95873855bfd97BF89572DDf5cBC44D9c545b'
|
||||
[eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b',
|
||||
[eEthereumNetwork.main]: '', //'0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D', // Need to re-deploy because of onlyOwner
|
||||
[eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
|
||||
},
|
||||
LendingPoolCollateralManager: {
|
||||
[eEthereumNetwork.coverage]: '',
|
||||
[eEthereumNetwork.hardhat]: '',
|
||||
[eEthereumNetwork.buidlerevm]: '',
|
||||
[eEthereumNetwork.kovan]: '0x9269b6453d0d75370c4c85e5a42977a53efdb72a',
|
||||
[eEthereumNetwork.ropsten]: '',
|
||||
[eEthereumNetwork.main]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
|
||||
[eEthereumNetwork.tenderlyMain]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
|
||||
},
|
||||
LendingPoolConfigurator: {
|
||||
[eEthereumNetwork.coverage]: '',
|
||||
[eEthereumNetwork.hardhat]: '',
|
||||
[eEthereumNetwork.buidlerevm]: '',
|
||||
[eEthereumNetwork.kovan]: '0x36eB31800aa67a9c50df1d56EE01981A6E14Cce5',
|
||||
[eEthereumNetwork.ropsten]: '',
|
||||
[eEthereumNetwork.main]: '',
|
||||
[eEthereumNetwork.tenderlyMain]: '',
|
||||
},
|
||||
LendingPool: {
|
||||
[eEthereumNetwork.coverage]: '',
|
||||
[eEthereumNetwork.hardhat]: '',
|
||||
[eEthereumNetwork.buidlerevm]: '',
|
||||
[eEthereumNetwork.kovan]: '0x78142De7a1930412E9e50dEB3b80dB284c2dFa3A',
|
||||
[eEthereumNetwork.ropsten]: '',
|
||||
[eEthereumNetwork.main]: '',
|
||||
[eEthereumNetwork.tenderlyMain]: '',
|
||||
},
|
||||
WethGateway: {
|
||||
[eEthereumNetwork.coverage]: '',
|
||||
[eEthereumNetwork.hardhat]: '',
|
||||
[eEthereumNetwork.buidlerevm]: '',
|
||||
[eEthereumNetwork.kovan]: '0x1c4A1cC35A477aa1cF35DF671d93ACc04d8131E0',
|
||||
[eEthereumNetwork.ropsten]: '',
|
||||
[eEthereumNetwork.main]: '',
|
||||
[eEthereumNetwork.tenderlyMain]: '',
|
||||
},
|
||||
TokenDistributor: {
|
||||
[eEthereumNetwork.coverage]: '',
|
||||
[eEthereumNetwork.buidlerevm]: '',
|
||||
[eEthereumNetwork.hardhat]: '',
|
||||
[eEthereumNetwork.kovan]: '0x971efe90088f21dc6a36f610ffed77fc19710708',
|
||||
[eEthereumNetwork.ropsten]: '0xeba2ea67942b8250d870b12750b594696d02fc9c',
|
||||
[eEthereumNetwork.main]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
|
||||
[eEthereumNetwork.tenderlyMain]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
|
||||
},
|
||||
AaveOracle: {
|
||||
[eEthereumNetwork.coverage]: '',
|
||||
[eEthereumNetwork.hardhat]: '',
|
||||
[eEthereumNetwork.buidlerevm]: '',
|
||||
[eEthereumNetwork.kovan]: '0x8fb777d67e9945e2c01936e319057f9d41d559e6', // Need to re-deploy because of onlyOwner
|
||||
[eEthereumNetwork.ropsten]: ZERO_ADDRESS,
|
||||
[eEthereumNetwork.main]: '', //'0xA50ba011c48153De246E5192C8f9258A2ba79Ca9', // Need to re-deploy because of onlyOwner
|
||||
[eEthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
|
||||
},
|
||||
FallbackOracle: {
|
||||
[eEthereumNetwork.coverage]: '',
|
||||
[eEthereumNetwork.hardhat]: '',
|
||||
[eEthereumNetwork.buidlerevm]: '',
|
||||
[eEthereumNetwork.kovan]: '0x50913E8E1c650E790F8a1E741FF9B1B1bB251dfe',
|
||||
[eEthereumNetwork.ropsten]: '0xAD1a978cdbb8175b2eaeC47B01404f8AEC5f4F0d',
|
||||
[eEthereumNetwork.main]: ZERO_ADDRESS,
|
||||
[eEthereumNetwork.tenderlyMain]: ZERO_ADDRESS,
|
||||
},
|
||||
ChainlinkAggregator: {
|
||||
[eEthereumNetwork.coverage]: {},
|
||||
[eEthereumNetwork.hardhat]: {},
|
||||
[eEthereumNetwork.buidlerevm]: {},
|
||||
[eEthereumNetwork.kovan]: {
|
||||
USDT: '0x0bF499444525a23E7Bb61997539725cA2e928138',
|
||||
WBTC: '0xF7904a295A029a3aBDFFB6F12755974a958C7C25',
|
||||
USDC: '0x64EaC61A2DFda2c3Fa04eED49AA33D021AeC8838',
|
||||
DAI: '0x22B58f1EbEDfCA50feF632bD73368b2FdA96D541',
|
||||
UniDAIWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F', // Mock oracles
|
||||
UniWBTCWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
|
||||
UniAAVEWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
|
||||
UniBATWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
|
||||
UniDAIUSDC: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
|
||||
UniCRVWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
|
||||
UniLINKWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
|
||||
UniMKRWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
|
||||
UniRENWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
|
||||
UniSNXWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
|
||||
UniUNIWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
|
||||
UniUSDCWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
|
||||
UniWBTCUSDC: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
|
||||
UniYFIWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
|
||||
BptWBTCWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
|
||||
BptBALWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
|
||||
USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
|
||||
},
|
||||
[eEthereumNetwork.ropsten]: {},
|
||||
[eEthereumNetwork.main]: {
|
||||
USDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
|
||||
WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
|
||||
USDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
|
||||
DAI: '0x773616E4d11A78F511299002da57A0a94577F1f4',
|
||||
UniDAIWETH: '0x66a6b87a18db78086acda75b7720dc47cdabcc05',
|
||||
UniWBTCWETH: '0x7004BB6F2013F13C54899309cCa029B49707E547',
|
||||
UniAAVEWETH: '0xB525547968610395B60085bDc8033FFeaEaa5F64',
|
||||
UniBATWETH: '0xB394D8a1CE721630Cbea8Ec110DCEf0D283EDE3a',
|
||||
UniDAIUSDC: '0x3B148Fa5E8297DB64262442052b227328730EA81',
|
||||
UniCRVWETH: '0x10F7078e2f29802D2AC78045F61A69aE0883535A',
|
||||
UniLINKWETH: '0x30adCEfA5d483284FD79E1eFd54ED3e0A8eaA632',
|
||||
UniMKRWETH: '0xEBF4A448ff3D835F8FA883941a3E9D5E74B40B5E',
|
||||
UniRENWETH: '0xe2f7C06906A9dB063C28EB5c71B6Ab454e5222dD',
|
||||
UniSNXWETH: '0x29bfee7E90572Abf1088a58a145a10D051b78E46',
|
||||
UniUNIWETH: '0xC2E93e8121237A885A00627975eB06C7BF9808d6',
|
||||
UniUSDCWETH: '0x71c4a2173CE3620982DC8A7D870297533360Da4E',
|
||||
UniWBTCUSDC: '0x11f4ba2227F21Dc2A9F0b0e6Ea740369d580a212',
|
||||
UniYFIWETH: '0x664223b8Bb0934aE0970e601F452f75AaCe9Aa2A',
|
||||
BptWBTCWETH: '0x4CA8D8fC2b4fCe8A2dcB71Da884bba042d48E067',
|
||||
BptBALWETH: '0x2e4e78936b100be6Ef85BCEf7FB25bC770B02B85',
|
||||
USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
|
||||
},
|
||||
[eEthereumNetwork.tenderlyMain]: {
|
||||
USDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
|
||||
WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
|
||||
USDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
|
||||
DAI: '0x773616E4d11A78F511299002da57A0a94577F1f4',
|
||||
UniDAIWETH: '0x66a6b87a18db78086acda75b7720dc47cdabcc05',
|
||||
UniWBTCWETH: '0x7004BB6F2013F13C54899309cCa029B49707E547',
|
||||
UniAAVEWETH: '0xB525547968610395B60085bDc8033FFeaEaa5F64',
|
||||
UniBATWETH: '0xB394D8a1CE721630Cbea8Ec110DCEf0D283EDE3a',
|
||||
UniDAIUSDC: '0x3B148Fa5E8297DB64262442052b227328730EA81',
|
||||
UniCRVWETH: '0x10F7078e2f29802D2AC78045F61A69aE0883535A',
|
||||
UniLINKWETH: '0x30adCEfA5d483284FD79E1eFd54ED3e0A8eaA632',
|
||||
UniMKRWETH: '0xEBF4A448ff3D835F8FA883941a3E9D5E74B40B5E',
|
||||
UniRENWETH: '0xe2f7C06906A9dB063C28EB5c71B6Ab454e5222dD',
|
||||
UniSNXWETH: '0x29bfee7E90572Abf1088a58a145a10D051b78E46',
|
||||
UniUNIWETH: '0xC2E93e8121237A885A00627975eB06C7BF9808d6',
|
||||
UniUSDCWETH: '0x71c4a2173CE3620982DC8A7D870297533360Da4E',
|
||||
UniWBTCUSDC: '0x11f4ba2227F21Dc2A9F0b0e6Ea740369d580a212',
|
||||
UniYFIWETH: '0x664223b8Bb0934aE0970e601F452f75AaCe9Aa2A',
|
||||
BptWBTCWETH: '0x4CA8D8fC2b4fCe8A2dcB71Da884bba042d48E067',
|
||||
BptBALWETH: '0x2e4e78936b100be6Ef85BCEf7FB25bC770B02B85',
|
||||
USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
|
||||
},
|
||||
},
|
||||
ReserveAssets: {
|
||||
[eEthereumNetwork.coverage]: {},
|
||||
[eEthereumNetwork.hardhat]: {},
|
||||
[eEthereumNetwork.buidlerevm]: {},
|
||||
[eEthereumNetwork.main]: {},
|
||||
[eEthereumNetwork.kovan]: {},
|
||||
[eEthereumNetwork.ropsten]: {},
|
||||
[eEthereumNetwork.tenderlyMain]: {},
|
||||
},
|
||||
ReservesConfig: {},
|
||||
ATokenDomainSeparator: {
|
||||
[eEthereumNetwork.coverage]:
|
||||
'0x95b73a72c6ecf4ccbbba5178800023260bad8e75cdccdb8e4827a2977a37c820',
|
||||
[eEthereumNetwork.hardhat]:
|
||||
'0xbae024d959c6a022dc5ed37294cd39c141034b2ae5f02a955cce75c930a81bf5',
|
||||
[eEthereumNetwork.buidlerevm]:
|
||||
'0xbae024d959c6a022dc5ed37294cd39c141034b2ae5f02a955cce75c930a81bf5',
|
||||
[eEthereumNetwork.kovan]: '',
|
||||
[eEthereumNetwork.ropsten]: '',
|
||||
[eEthereumNetwork.main]: '',
|
||||
[eEthereumNetwork.tenderlyMain]: '',
|
||||
},
|
||||
WETH: {
|
||||
[eEthereumNetwork.coverage]: '', // deployed in local evm
|
||||
[eEthereumNetwork.hardhat]: '', // deployed in local evm
|
||||
[eEthereumNetwork.buidlerevm]: '', // deployed in local evm
|
||||
[eEthereumNetwork.kovan]: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
|
||||
[eEthereumNetwork.ropsten]: '0xc778417e063141139fce010982780140aa0cd5ab',
|
||||
[eEthereumNetwork.main]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
|
||||
[eEthereumNetwork.tenderlyMain]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
|
||||
},
|
||||
ReserveFactorTreasuryAddress: {
|
||||
[eEthereumNetwork.coverage]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
|
||||
[eEthereumNetwork.hardhat]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
|
||||
[eEthereumNetwork.buidlerevm]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
|
||||
[eEthereumNetwork.kovan]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
|
||||
[eEthereumNetwork.ropsten]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
|
||||
[eEthereumNetwork.main]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
|
||||
[eEthereumNetwork.tenderlyMain]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
|
||||
},
|
||||
};
|
137
markets/amm/index.ts
Normal file
137
markets/amm/index.ts
Normal file
|
@ -0,0 +1,137 @@
|
|||
import { oneRay, ZERO_ADDRESS } from '../../helpers/constants';
|
||||
import { IAmmConfiguration, eEthereumNetwork } from '../../helpers/types';
|
||||
|
||||
import { CommonsConfig } from './commons';
|
||||
import {
|
||||
strategyDAI,
|
||||
strategyUSDC,
|
||||
strategyUSDT,
|
||||
strategyWETH,
|
||||
strategyWBTC,
|
||||
strategyWBTCWETH,
|
||||
strategyDAIWETH,
|
||||
strategyAAVEWETH,
|
||||
strategyBATWETH,
|
||||
strategyDAIUSDC,
|
||||
strategyCRVWETH,
|
||||
strategyLINKWETH,
|
||||
strategyMKRWETH,
|
||||
strategyRENWETH,
|
||||
strategySNXWETH,
|
||||
strategyUNIWETH,
|
||||
strategyUSDCWETH,
|
||||
strategyWBTCUSDC,
|
||||
strategyYFIWETH,
|
||||
strategyBALWETH,
|
||||
} from './reservesConfigs';
|
||||
|
||||
// ----------------
|
||||
// POOL--SPECIFIC PARAMS
|
||||
// ----------------
|
||||
|
||||
export const AmmConfig: IAmmConfiguration = {
|
||||
...CommonsConfig,
|
||||
MarketId: 'Aave AMM market',
|
||||
ProviderId: 2,
|
||||
ReservesConfig: {
|
||||
WETH: strategyWETH,
|
||||
DAI: strategyDAI,
|
||||
USDC: strategyUSDC,
|
||||
USDT: strategyUSDT,
|
||||
WBTC: strategyWBTC,
|
||||
UniDAIWETH: strategyDAIWETH,
|
||||
UniWBTCWETH: strategyWBTCWETH,
|
||||
UniAAVEWETH: strategyAAVEWETH,
|
||||
UniBATWETH: strategyBATWETH,
|
||||
UniDAIUSDC: strategyDAIUSDC,
|
||||
UniCRVWETH: strategyCRVWETH,
|
||||
UniLINKWETH: strategyLINKWETH,
|
||||
UniMKRWETH: strategyMKRWETH,
|
||||
UniRENWETH: strategyRENWETH,
|
||||
UniSNXWETH: strategySNXWETH,
|
||||
UniUNIWETH: strategyUNIWETH,
|
||||
UniUSDCWETH: strategyUSDCWETH,
|
||||
UniWBTCUSDC: strategyWBTCUSDC,
|
||||
UniYFIWETH: strategyYFIWETH,
|
||||
BptWBTCWETH: strategyWBTCWETH,
|
||||
BptBALWETH: strategyBALWETH,
|
||||
},
|
||||
ReserveAssets: {
|
||||
[eEthereumNetwork.buidlerevm]: {},
|
||||
[eEthereumNetwork.hardhat]: {},
|
||||
[eEthereumNetwork.coverage]: {},
|
||||
[eEthereumNetwork.kovan]: {
|
||||
DAI: '0xFf795577d9AC8bD7D90Ee22b6C1703490b6512FD',
|
||||
USDC: '0xe22da380ee6B445bb8273C81944ADEB6E8450422',
|
||||
USDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
|
||||
WBTC: '0xD1B98B6607330172f1D991521145A22BCe793277',
|
||||
WETH: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
|
||||
UniDAIWETH: '0x0C652EeEA3d7D35759ba1E16183F1D89C386C9ea',
|
||||
UniWBTCWETH: '0x796d562B1dF5b9dc85A4612187B6f29Ed213d960',
|
||||
UniAAVEWETH: '0x657A7B8b46F35C5C6583AEF43824744B236EF826',
|
||||
UniBATWETH: '0xf8CEBA8b16579956B3aE4B5D09002a30f873F783',
|
||||
UniDAIUSDC: '0x8e80b7a7531c276dD1dBEC2f1Cc281c11c859e62',
|
||||
UniCRVWETH: '0x9c31b7538467bF0b01e6d5fA789e66Ce540a521e',
|
||||
UniLINKWETH: '0x5Acab7f8B79620ec7127A96E5D8837d2124D5D7c',
|
||||
UniMKRWETH: '0xB0C6EC5d58ddbF4cd1e419A56a19924E9904e4Dd',
|
||||
UniRENWETH: '0xcF428637A9f8Af21920Bc0A94fd81071bc790105',
|
||||
UniSNXWETH: '0xc8F2a0d698f675Ece74042e9fB06ea52b9517521',
|
||||
UniUNIWETH: '0xcC99A5f95a86d30e3DeF113bCf22f00ecF90D050',
|
||||
UniUSDCWETH: '0x8C00D2428ed1857E61652aca663323A85E6e76a9',
|
||||
UniWBTCUSDC: '0x3d35B5F289f55A580e6F85eE22E6a8f57053b966',
|
||||
UniYFIWETH: '0x5af95ddFACC150a1695A3Fc606459fd0dE57b91f',
|
||||
BptWBTCWETH: '0x110569E3261bC0934dA637b019f6f1b6F50ec574',
|
||||
BptBALWETH: '0xad01D8e0Fa9EAA8Fe76dA30CFb1BCe12707aE6c5',
|
||||
},
|
||||
[eEthereumNetwork.ropsten]: {
|
||||
},
|
||||
[eEthereumNetwork.main]: {
|
||||
DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
|
||||
USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
|
||||
USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
|
||||
WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
|
||||
WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
|
||||
UniDAIWETH: '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11',
|
||||
UniWBTCWETH: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
|
||||
UniAAVEWETH: '0xDFC14d2Af169B0D36C4EFF567Ada9b2E0CAE044f',
|
||||
UniBATWETH: '0xB6909B960DbbE7392D405429eB2b3649752b4838',
|
||||
UniDAIUSDC: '0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5',
|
||||
UniCRVWETH: '0x3dA1313aE46132A397D90d95B1424A9A7e3e0fCE',
|
||||
UniLINKWETH: '0xa2107FA5B38d9bbd2C461D6EDf11B11A50F6b974',
|
||||
UniMKRWETH: '0xC2aDdA861F89bBB333c90c492cB837741916A225',
|
||||
UniRENWETH: '0x8Bd1661Da98EBDd3BD080F0bE4e6d9bE8cE9858c',
|
||||
UniSNXWETH: '0x43AE24960e5534731Fc831386c07755A2dc33D47',
|
||||
UniUNIWETH: '0xd3d2E2692501A5c9Ca623199D38826e513033a17',
|
||||
UniUSDCWETH: '0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc',
|
||||
UniWBTCUSDC: '0x004375Dff511095CC5A197A54140a24eFEF3A416',
|
||||
UniYFIWETH: '0x2fDbAdf3C4D5A8666Bc06645B8358ab803996E28',
|
||||
BptWBTCWETH: '0x1efF8aF5D577060BA4ac8A29A13525bb0Ee2A3D5',
|
||||
BptBALWETH: '0x59A19D8c652FA0284f44113D0ff9aBa70bd46fB4',
|
||||
},
|
||||
[eEthereumNetwork.tenderlyMain]: {
|
||||
DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
|
||||
USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
|
||||
USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
|
||||
WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
|
||||
WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
|
||||
UniDAIWETH: '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11',
|
||||
UniWBTCWETH: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
|
||||
UniAAVEWETH: '0xDFC14d2Af169B0D36C4EFF567Ada9b2E0CAE044f',
|
||||
UniBATWETH: '0xB6909B960DbbE7392D405429eB2b3649752b4838',
|
||||
UniDAIUSDC: '0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5',
|
||||
UniCRVWETH: '0x3dA1313aE46132A397D90d95B1424A9A7e3e0fCE',
|
||||
UniLINKWETH: '0xa2107FA5B38d9bbd2C461D6EDf11B11A50F6b974',
|
||||
UniMKRWETH: '0xC2aDdA861F89bBB333c90c492cB837741916A225',
|
||||
UniRENWETH: '0x8Bd1661Da98EBDd3BD080F0bE4e6d9bE8cE9858c',
|
||||
UniSNXWETH: '0x43AE24960e5534731Fc831386c07755A2dc33D47',
|
||||
UniUNIWETH: '0xd3d2E2692501A5c9Ca623199D38826e513033a17',
|
||||
UniUSDCWETH: '0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc',
|
||||
UniWBTCUSDC: '0x004375Dff511095CC5A197A54140a24eFEF3A416',
|
||||
UniYFIWETH: '0x2fDbAdf3C4D5A8666Bc06645B8358ab803996E28',
|
||||
BptWBTCWETH: '0x1efF8aF5D577060BA4ac8A29A13525bb0Ee2A3D5',
|
||||
BptBALWETH: '0x59A19D8c652FA0284f44113D0ff9aBa70bd46fB4',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default AmmConfig;
|
36
markets/amm/rateStrategies.ts
Normal file
36
markets/amm/rateStrategies.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
import BigNumber from 'bignumber.js';
|
||||
import { oneRay } from '../../helpers/constants';
|
||||
import { IInterestRateStrategyParams } from '../../helpers/types';
|
||||
|
||||
// DAIWETH WBTCWETH AAVEWETH BATWETH DAIUSDC CRVWETH LINKWETH MKRWETH RENWETH SNXWETH UNIWETH USDCWETH WBTCUSDC YFIWETH
|
||||
export const rateStrategyAmmBase: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyAmmBase",
|
||||
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
}
|
||||
|
||||
// WETH WBTC
|
||||
export const rateStrategyBaseOne: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyBaseOne",
|
||||
optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
|
||||
}
|
||||
|
||||
// DAI USDC USDT
|
||||
export const rateStrategyStable: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyStable",
|
||||
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
|
||||
}
|
247
markets/amm/reservesConfigs.ts
Normal file
247
markets/amm/reservesConfigs.ts
Normal file
|
@ -0,0 +1,247 @@
|
|||
import { eContractid, IReserveParams} from '../../helpers/types';
|
||||
import {
|
||||
rateStrategyAmmBase,
|
||||
rateStrategyStable,
|
||||
rateStrategyBaseOne,
|
||||
} from './rateStrategies';
|
||||
|
||||
|
||||
export const strategyWETH: IReserveParams = {
|
||||
strategy: rateStrategyBaseOne,
|
||||
baseLTVAsCollateral: '8000',
|
||||
liquidationThreshold: '8250',
|
||||
liquidationBonus: '10500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1000'
|
||||
};
|
||||
|
||||
export const strategyWBTC: IReserveParams = {
|
||||
strategy: rateStrategyBaseOne,
|
||||
baseLTVAsCollateral: '7000',
|
||||
liquidationThreshold: '7500',
|
||||
liquidationBonus: '11000',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '8',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '2000'
|
||||
};
|
||||
|
||||
export const strategyDAI: IReserveParams = {
|
||||
strategy: rateStrategyStable,
|
||||
baseLTVAsCollateral: '7500',
|
||||
liquidationThreshold: '8000',
|
||||
liquidationBonus: '10500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1000'
|
||||
};
|
||||
|
||||
export const strategyUSDC: IReserveParams = {
|
||||
strategy: rateStrategyStable,
|
||||
baseLTVAsCollateral: '8000',
|
||||
liquidationThreshold: '8500',
|
||||
liquidationBonus: '10500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '6',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1000'
|
||||
};
|
||||
|
||||
export const strategyUSDT: IReserveParams = {
|
||||
strategy: rateStrategyStable,
|
||||
baseLTVAsCollateral: '-1',
|
||||
liquidationThreshold: '8500',
|
||||
liquidationBonus: '10500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '6',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1000'
|
||||
};
|
||||
|
||||
export const strategyDAIWETH: IReserveParams = {
|
||||
strategy: rateStrategyAmmBase,
|
||||
baseLTVAsCollateral: '6000',
|
||||
liquidationThreshold: '7000',
|
||||
liquidationBonus: '11500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1000'
|
||||
};
|
||||
|
||||
export const strategyWBTCWETH: IReserveParams = {
|
||||
strategy: rateStrategyAmmBase,
|
||||
baseLTVAsCollateral: '6000',
|
||||
liquidationThreshold: '7000',
|
||||
liquidationBonus: '11500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1500'
|
||||
};
|
||||
|
||||
export const strategyAAVEWETH: IReserveParams = {
|
||||
strategy: rateStrategyAmmBase,
|
||||
baseLTVAsCollateral: '6000',
|
||||
liquidationThreshold: '7000',
|
||||
liquidationBonus: '11500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '500'
|
||||
};
|
||||
|
||||
export const strategyBATWETH: IReserveParams = {
|
||||
strategy: rateStrategyAmmBase,
|
||||
baseLTVAsCollateral: '6000',
|
||||
liquidationThreshold: '7000',
|
||||
liquidationBonus: '11500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1500'
|
||||
};
|
||||
|
||||
export const strategyDAIUSDC: IReserveParams = {
|
||||
strategy: rateStrategyAmmBase,
|
||||
baseLTVAsCollateral: '6000',
|
||||
liquidationThreshold: '7000',
|
||||
liquidationBonus: '11500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1000'
|
||||
};
|
||||
|
||||
export const strategyCRVWETH: IReserveParams = {
|
||||
strategy: rateStrategyAmmBase,
|
||||
baseLTVAsCollateral: '5000',
|
||||
liquidationThreshold: '6000',
|
||||
liquidationBonus: '11500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1500'
|
||||
};
|
||||
|
||||
export const strategyLINKWETH: IReserveParams = {
|
||||
strategy: rateStrategyAmmBase,
|
||||
baseLTVAsCollateral: '6000',
|
||||
liquidationThreshold: '7000',
|
||||
liquidationBonus: '11500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1500'
|
||||
};
|
||||
|
||||
export const strategyMKRWETH: IReserveParams = {
|
||||
strategy: rateStrategyAmmBase,
|
||||
baseLTVAsCollateral: '6000',
|
||||
liquidationThreshold: '7000',
|
||||
liquidationBonus: '11500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1500'
|
||||
};
|
||||
|
||||
export const strategyRENWETH: IReserveParams = {
|
||||
strategy: rateStrategyAmmBase,
|
||||
baseLTVAsCollateral: '6000',
|
||||
liquidationThreshold: '7000',
|
||||
liquidationBonus: '11500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1500'
|
||||
};
|
||||
|
||||
export const strategySNXWETH: IReserveParams = {
|
||||
strategy: rateStrategyAmmBase,
|
||||
baseLTVAsCollateral: '4000',
|
||||
liquidationThreshold: '6000',
|
||||
liquidationBonus: '11500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '2000'
|
||||
};
|
||||
|
||||
export const strategyUNIWETH: IReserveParams = {
|
||||
strategy: rateStrategyAmmBase,
|
||||
baseLTVAsCollateral: '6000',
|
||||
liquidationThreshold: '7000',
|
||||
liquidationBonus: '11500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1500'
|
||||
};
|
||||
|
||||
export const strategyUSDCWETH: IReserveParams = {
|
||||
strategy: rateStrategyAmmBase,
|
||||
baseLTVAsCollateral: '6000',
|
||||
liquidationThreshold: '7000',
|
||||
liquidationBonus: '11500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1000'
|
||||
};
|
||||
|
||||
export const strategyWBTCUSDC: IReserveParams = {
|
||||
strategy: rateStrategyAmmBase,
|
||||
baseLTVAsCollateral: '6000',
|
||||
liquidationThreshold: '7000',
|
||||
liquidationBonus: '11500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1500'
|
||||
};
|
||||
|
||||
export const strategyYFIWETH: IReserveParams = {
|
||||
strategy: rateStrategyAmmBase,
|
||||
baseLTVAsCollateral: '5000',
|
||||
liquidationThreshold: '6000',
|
||||
liquidationBonus: '11500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1500'
|
||||
};
|
||||
|
||||
export const strategyBALWETH: IReserveParams = {
|
||||
strategy: rateStrategyAmmBase,
|
||||
baseLTVAsCollateral: '6000',
|
||||
liquidationThreshold: '7000',
|
||||
liquidationBonus: '11500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: false,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1500'
|
||||
}
|
0
markets/arbitrum/commons.ts
Normal file
0
markets/arbitrum/commons.ts
Normal file
1
markets/arbitrum/index.ts
Normal file
1
markets/arbitrum/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
|
0
markets/arbitrum/rateStrategies.ts
Normal file
0
markets/arbitrum/rateStrategies.ts
Normal file
0
markets/arbitrum/reservesConfigs.ts
Normal file
0
markets/arbitrum/reservesConfigs.ts
Normal file
0
markets/bsc/commons.ts
Normal file
0
markets/bsc/commons.ts
Normal file
1
markets/bsc/index.ts
Normal file
1
markets/bsc/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
|
0
markets/bsc/rateStrategies.ts
Normal file
0
markets/bsc/rateStrategies.ts
Normal file
0
markets/bsc/reservesConfigs.ts
Normal file
0
markets/bsc/reservesConfigs.ts
Normal file
144
markets/matic/commons.ts
Normal file
144
markets/matic/commons.ts
Normal file
|
@ -0,0 +1,144 @@
|
|||
import BigNumber from 'bignumber.js';
|
||||
import { oneEther, oneRay, RAY, ZERO_ADDRESS, MOCK_CHAINLINK_AGGREGATORS_PRICES } from '../../helpers/constants';
|
||||
import { ICommonConfiguration, ePolygonNetwork } from '../../helpers/types';
|
||||
|
||||
// ----------------
|
||||
// PROTOCOL GLOBAL PARAMS
|
||||
// ----------------
|
||||
|
||||
export const CommonsConfig: ICommonConfiguration = {
|
||||
MarketId: 'Commons',
|
||||
ATokenNamePrefix: 'Aave Matic Market',
|
||||
StableDebtTokenNamePrefix: 'Aave Matic Market stable debt',
|
||||
VariableDebtTokenNamePrefix: 'Aave Matic Market variable debt',
|
||||
SymbolPrefix: 'm',
|
||||
ProviderId: 0, // Overriden in index.ts
|
||||
ProtocolGlobalParams: {
|
||||
TokenDistributorPercentageBase: '10000',
|
||||
MockUsdPriceInWei: '5848466240000000',
|
||||
UsdAddress: '0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96',
|
||||
NilAddress: '0x0000000000000000000000000000000000000000',
|
||||
OneAddress: '0x0000000000000000000000000000000000000001',
|
||||
AaveReferral: '0',
|
||||
},
|
||||
|
||||
// ----------------
|
||||
// COMMON PROTOCOL PARAMS ACROSS POOLS AND NETWORKS
|
||||
// ----------------
|
||||
|
||||
Mocks: {
|
||||
AllAssetsInitialPrices: {
|
||||
...MOCK_CHAINLINK_AGGREGATORS_PRICES,
|
||||
},
|
||||
},
|
||||
// TODO: reorg alphabetically, checking the reason of tests failing
|
||||
LendingRateOracleRatesCommon: {
|
||||
WETH: {
|
||||
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
|
||||
},
|
||||
DAI: {
|
||||
borrowRate: oneRay.multipliedBy(0.039).toFixed(),
|
||||
},
|
||||
USDC: {
|
||||
borrowRate: oneRay.multipliedBy(0.039).toFixed(),
|
||||
},
|
||||
USDT: {
|
||||
borrowRate: oneRay.multipliedBy(0.035).toFixed(),
|
||||
},
|
||||
WBTC: {
|
||||
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
|
||||
},
|
||||
WMATIC: {
|
||||
borrowRate: oneRay.multipliedBy(0.05).toFixed(), // TEMP
|
||||
},
|
||||
},
|
||||
// ----------------
|
||||
// COMMON PROTOCOL ADDRESSES ACROSS POOLS
|
||||
// ----------------
|
||||
|
||||
// If PoolAdmin/emergencyAdmin is set, will take priority over PoolAdminIndex/emergencyAdminIndex
|
||||
PoolAdmin: {
|
||||
[ePolygonNetwork.mumbai]: undefined,
|
||||
[ePolygonNetwork.matic]: undefined,
|
||||
},
|
||||
PoolAdminIndex: 0,
|
||||
EmergencyAdmin: {
|
||||
[ePolygonNetwork.mumbai]: undefined,
|
||||
[ePolygonNetwork.matic]: undefined,
|
||||
},
|
||||
LendingPool: {
|
||||
[ePolygonNetwork.mumbai]: '',
|
||||
[ePolygonNetwork.matic]: '0xABdC61Cd16e5111f335f4135B7A0e65Cc7F86327',
|
||||
},
|
||||
LendingPoolConfigurator: {
|
||||
[ePolygonNetwork.mumbai]: '',
|
||||
[ePolygonNetwork.matic]: '0x17c4A170FFF882862F656597889016D3a6073534',
|
||||
},
|
||||
EmergencyAdminIndex: 1,
|
||||
ProviderRegistry: {
|
||||
[ePolygonNetwork.mumbai]: '0x569859d41499B4dDC28bfaA43915051FF0A38a6F', // TEMP
|
||||
[ePolygonNetwork.matic]: '0x28334e4791860a0c1eCF89a62B973ba04a5d643F', // TEMP
|
||||
},
|
||||
ProviderRegistryOwner: {
|
||||
[ePolygonNetwork.mumbai]: '0x18d9bA2baEfBdE0FF137C4ad031427EF205f1Fd9', // TEMP
|
||||
[ePolygonNetwork.matic]: '0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F', // TEMP
|
||||
},
|
||||
LendingRateOracle: {
|
||||
[ePolygonNetwork.mumbai]: '',
|
||||
[ePolygonNetwork.matic]: '',
|
||||
},
|
||||
LendingPoolCollateralManager: {
|
||||
[ePolygonNetwork.mumbai]: '',
|
||||
[ePolygonNetwork.matic]: '0x9Af76e0575D139570D3B4c821567Fe935E8c25C5',
|
||||
},
|
||||
TokenDistributor: {
|
||||
[ePolygonNetwork.mumbai]: '',
|
||||
[ePolygonNetwork.matic]: '',
|
||||
},
|
||||
WethGateway: {
|
||||
[ePolygonNetwork.mumbai]: '',
|
||||
[ePolygonNetwork.matic]: '0x15A46f5073789b7D16F6F46632aE50Bae838d938',
|
||||
},
|
||||
AaveOracle: {
|
||||
[ePolygonNetwork.mumbai]: '',
|
||||
[ePolygonNetwork.matic]: '0x1B38fa90596F2C25bCf1B193A6c6a718349AFDfC',
|
||||
},
|
||||
FallbackOracle: {
|
||||
[ePolygonNetwork.mumbai]: ZERO_ADDRESS,
|
||||
[ePolygonNetwork.matic]: ZERO_ADDRESS,
|
||||
},
|
||||
ChainlinkAggregator: {
|
||||
[ePolygonNetwork.matic]: {
|
||||
DAI: '0x4746DeC9e833A82EC7C2C1356372CcF2cfcD2F3D',
|
||||
USDC: '0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7',
|
||||
USDT: '0x0A6513e40db6EB1b165753AD52E80663aeA50545',
|
||||
WBTC: '0xc907E116054Ad103354f2D350FD2514433D57F6f',
|
||||
WETH: '0xF9680D99D6C9589e2a93a78A04A279e509205945',
|
||||
WMATIC: '0xAB594600376Ec9fD91F8e885dADF0CE036862dE0',
|
||||
},
|
||||
[ePolygonNetwork.mumbai]: {
|
||||
DAI: ZERO_ADDRESS,
|
||||
USDC: ZERO_ADDRESS,
|
||||
USDT: ZERO_ADDRESS,
|
||||
WBTC: ZERO_ADDRESS,
|
||||
WMATIC: ZERO_ADDRESS,
|
||||
},
|
||||
},
|
||||
ReserveAssets: {
|
||||
[ePolygonNetwork.matic]: {},
|
||||
[ePolygonNetwork.mumbai]: {},
|
||||
},
|
||||
ReservesConfig: {},
|
||||
ATokenDomainSeparator: {
|
||||
[ePolygonNetwork.mumbai]: '',
|
||||
[ePolygonNetwork.matic]: '',
|
||||
},
|
||||
WETH: {
|
||||
[ePolygonNetwork.mumbai]: '0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889', // WMATIC address (untested)
|
||||
[ePolygonNetwork.matic]: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270', // WMATIC address
|
||||
},
|
||||
ReserveFactorTreasuryAddress: {
|
||||
[ePolygonNetwork.mumbai]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', // TEMP
|
||||
[ePolygonNetwork.matic]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', // TEMP
|
||||
},
|
||||
};
|
50
markets/matic/index.ts
Normal file
50
markets/matic/index.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
import { oneRay, ZERO_ADDRESS } from '../../helpers/constants';
|
||||
import { IMaticConfiguration, ePolygonNetwork } from '../../helpers/types';
|
||||
|
||||
import { CommonsConfig } from './commons';
|
||||
import {
|
||||
strategyDAI,
|
||||
strategyUSDC,
|
||||
strategyUSDT,
|
||||
strategyWBTC,
|
||||
strategyWETH,
|
||||
strategyMATIC,
|
||||
} from './reservesConfigs';
|
||||
|
||||
// ----------------
|
||||
// POOL--SPECIFIC PARAMS
|
||||
// ----------------
|
||||
|
||||
export const MaticConfig: IMaticConfiguration = {
|
||||
...CommonsConfig,
|
||||
MarketId: 'Matic Market',
|
||||
ProviderId: 3, // Unknown?
|
||||
ReservesConfig: {
|
||||
DAI: strategyDAI,
|
||||
USDC: strategyUSDC,
|
||||
USDT: strategyUSDT,
|
||||
WBTC: strategyWBTC,
|
||||
WETH: strategyWETH,
|
||||
WMATIC: strategyMATIC,
|
||||
},
|
||||
ReserveAssets: {
|
||||
[ePolygonNetwork.matic]: {
|
||||
DAI: '0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063',
|
||||
USDC: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174',
|
||||
USDT: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F',
|
||||
WBTC: '0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6',
|
||||
WETH: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',
|
||||
WMATIC: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270',
|
||||
},
|
||||
[ePolygonNetwork.mumbai]: { // Mock tokens with a simple "mint" external function, except wmatic
|
||||
DAI: '0x13b3fda609C1eeb23b4F4b69257840760dCa6C4a',
|
||||
USDC: '0x52b63223994433FdE2F1350Ba69Dfd2779f06ABA',
|
||||
USDT: '0xB3abd1912F586fDFFa13606882c28E27913853d2',
|
||||
WBTC: '0x393E3512d45a956A628124665672312ea86930Ba',
|
||||
WETH: '0x53CDb16B8C031B779e996406546614E5F05BC4Bf',
|
||||
WMATIC: '0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default MaticConfig;
|
91
markets/matic/rateStrategies.ts
Normal file
91
markets/matic/rateStrategies.ts
Normal file
|
@ -0,0 +1,91 @@
|
|||
import BigNumber from 'bignumber.js';
|
||||
import { oneRay } from '../../helpers/constants';
|
||||
import { IInterestRateStrategyParams } from '../../helpers/types';
|
||||
|
||||
// BUSD SUSD
|
||||
export const rateStrategyStableOne: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyStableOne",
|
||||
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: '0',
|
||||
stableRateSlope2: '0',
|
||||
};
|
||||
|
||||
// DAI TUSD
|
||||
export const rateStrategyStableTwo: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyStableTwo",
|
||||
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
|
||||
}
|
||||
|
||||
// USDC USDT
|
||||
export const rateStrategyStableThree: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyStableThree",
|
||||
optimalUtilizationRate: new BigNumber(0.9).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
|
||||
}
|
||||
|
||||
// WETH
|
||||
export const rateStrategyWETH: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyWETH",
|
||||
optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
|
||||
}
|
||||
|
||||
// AAVE
|
||||
export const rateStrategyAAVE: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyAAVE",
|
||||
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: '0',
|
||||
variableRateSlope1: '0',
|
||||
variableRateSlope2: '0',
|
||||
stableRateSlope1: '0',
|
||||
stableRateSlope2: '0',
|
||||
}
|
||||
|
||||
// BAT ENJ LINK MANA MKR REN YFI ZRX
|
||||
export const rateStrategyVolatileOne: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyVolatileOne",
|
||||
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
}
|
||||
|
||||
// KNC WBTC
|
||||
export const rateStrategyVolatileTwo: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyVolatileTwo",
|
||||
optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
}
|
||||
|
||||
// SNX
|
||||
export const rateStrategyVolatileThree: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyVolatileThree",
|
||||
optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
}
|
85
markets/matic/reservesConfigs.ts
Normal file
85
markets/matic/reservesConfigs.ts
Normal file
|
@ -0,0 +1,85 @@
|
|||
// import BigNumber from 'bignumber.js';
|
||||
// import { oneRay } from '../../helpers/constants';
|
||||
import { eContractid, IReserveParams } from '../../helpers/types';
|
||||
import {
|
||||
rateStrategyStableOne,
|
||||
rateStrategyStableTwo,
|
||||
rateStrategyStableThree,
|
||||
rateStrategyWETH,
|
||||
rateStrategyAAVE,
|
||||
rateStrategyVolatileOne,
|
||||
rateStrategyVolatileTwo,
|
||||
rateStrategyVolatileThree,
|
||||
} from './rateStrategies';
|
||||
|
||||
export const strategyDAI: IReserveParams = {
|
||||
strategy: rateStrategyStableTwo,
|
||||
baseLTVAsCollateral: '7500',
|
||||
liquidationThreshold: '8000',
|
||||
liquidationBonus: '10500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: true,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1000'
|
||||
};
|
||||
|
||||
export const strategyUSDC: IReserveParams = {
|
||||
strategy: rateStrategyStableThree,
|
||||
baseLTVAsCollateral: '8000',
|
||||
liquidationThreshold: '8500',
|
||||
liquidationBonus: '10500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: true,
|
||||
reserveDecimals: '6',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1000'
|
||||
};
|
||||
|
||||
export const strategyUSDT: IReserveParams = {
|
||||
strategy: rateStrategyStableThree,
|
||||
baseLTVAsCollateral: '8000',
|
||||
liquidationThreshold: '8500',
|
||||
liquidationBonus: '10500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: true,
|
||||
reserveDecimals: '6',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1000'
|
||||
};
|
||||
|
||||
export const strategyWETH: IReserveParams = {
|
||||
strategy: rateStrategyWETH,
|
||||
baseLTVAsCollateral: '8000',
|
||||
liquidationThreshold: '8250',
|
||||
liquidationBonus: '10500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: true,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1000'
|
||||
};
|
||||
|
||||
export const strategyWBTC: IReserveParams = {
|
||||
strategy: rateStrategyVolatileTwo,
|
||||
baseLTVAsCollateral: '7000',
|
||||
liquidationThreshold: '7500',
|
||||
liquidationBonus: '11000',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: true,
|
||||
reserveDecimals: '8',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '2000'
|
||||
};
|
||||
|
||||
export const strategyMATIC: IReserveParams = {
|
||||
strategy: rateStrategyVolatileOne, //Temp?
|
||||
baseLTVAsCollateral: '5000',
|
||||
liquidationThreshold: '6500',
|
||||
liquidationBonus: '11000',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: true,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '2000'
|
||||
};
|
0
markets/ovm/commons.ts
Normal file
0
markets/ovm/commons.ts
Normal file
1
markets/ovm/index.ts
Normal file
1
markets/ovm/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
|
0
markets/ovm/rateStrategies.ts
Normal file
0
markets/ovm/rateStrategies.ts
Normal file
0
markets/ovm/reservesConfigs.ts
Normal file
0
markets/ovm/reservesConfigs.ts
Normal file
0
markets/solana/commons.ts
Normal file
0
markets/solana/commons.ts
Normal file
1
markets/solana/index.ts
Normal file
1
markets/solana/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
|
0
markets/solana/rateStrategies.ts
Normal file
0
markets/solana/rateStrategies.ts
Normal file
0
markets/solana/reservesConfigs.ts
Normal file
0
markets/solana/reservesConfigs.ts
Normal file
120
markets/xdai/commons.ts
Normal file
120
markets/xdai/commons.ts
Normal file
|
@ -0,0 +1,120 @@
|
|||
import BigNumber from 'bignumber.js';
|
||||
import { oneEther, oneRay, RAY, ZERO_ADDRESS, MOCK_CHAINLINK_AGGREGATORS_PRICES } from '../../helpers/constants';
|
||||
import { ICommonConfiguration, eXDaiNetwork } from '../../helpers/types';
|
||||
|
||||
// ----------------
|
||||
// PROTOCOL GLOBAL PARAMS
|
||||
// ----------------
|
||||
|
||||
export const CommonsConfig: ICommonConfiguration = {
|
||||
MarketId: 'Commons',
|
||||
ATokenNamePrefix: 'Aave XDAI Market',
|
||||
StableDebtTokenNamePrefix: 'Aave XDAI Market stable debt',
|
||||
VariableDebtTokenNamePrefix: 'Aave XDAI Market variable debt',
|
||||
SymbolPrefix: 'm',
|
||||
ProviderId: 0, // Overriden in index.ts
|
||||
ProtocolGlobalParams: {
|
||||
TokenDistributorPercentageBase: '10000',
|
||||
MockUsdPriceInWei: '5848466240000000',
|
||||
UsdAddress: '0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96',
|
||||
NilAddress: '0x0000000000000000000000000000000000000000',
|
||||
OneAddress: '0x0000000000000000000000000000000000000001',
|
||||
AaveReferral: '0',
|
||||
},
|
||||
|
||||
// ----------------
|
||||
// COMMON PROTOCOL PARAMS ACROSS POOLS AND NETWORKS
|
||||
// ----------------
|
||||
|
||||
Mocks: {
|
||||
AllAssetsInitialPrices: {
|
||||
...MOCK_CHAINLINK_AGGREGATORS_PRICES,
|
||||
},
|
||||
},
|
||||
// TODO: reorg alphabetically, checking the reason of tests failing
|
||||
LendingRateOracleRatesCommon: {
|
||||
WETH: {
|
||||
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
|
||||
},
|
||||
DAI: {
|
||||
borrowRate: oneRay.multipliedBy(0.039).toFixed(),
|
||||
},
|
||||
USDC: {
|
||||
borrowRate: oneRay.multipliedBy(0.039).toFixed(),
|
||||
},
|
||||
USDT: {
|
||||
borrowRate: oneRay.multipliedBy(0.035).toFixed(),
|
||||
},
|
||||
WBTC: {
|
||||
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
|
||||
},
|
||||
STAKE: {
|
||||
borrowRate: oneRay.multipliedBy(0.05).toFixed(), // TEMP
|
||||
},
|
||||
},
|
||||
// ----------------
|
||||
// COMMON PROTOCOL ADDRESSES ACROSS POOLS
|
||||
// ----------------
|
||||
|
||||
// If PoolAdmin/emergencyAdmin is set, will take priority over PoolAdminIndex/emergencyAdminIndex
|
||||
PoolAdmin: {
|
||||
[eXDaiNetwork.xdai]: undefined,
|
||||
},
|
||||
PoolAdminIndex: 0,
|
||||
EmergencyAdmin: {
|
||||
[eXDaiNetwork.xdai]: undefined,
|
||||
},
|
||||
EmergencyAdminIndex: 1,
|
||||
ProviderRegistry: {
|
||||
[eXDaiNetwork.xdai]: '',
|
||||
},
|
||||
ProviderRegistryOwner: {
|
||||
[eXDaiNetwork.xdai]: '',
|
||||
},
|
||||
LendingPoolConfigurator: {
|
||||
[eXDaiNetwork.xdai]: '0',
|
||||
},
|
||||
LendingPool: {
|
||||
[eXDaiNetwork.xdai]: '0',
|
||||
},
|
||||
LendingRateOracle: {
|
||||
[eXDaiNetwork.xdai]: '',
|
||||
},
|
||||
LendingPoolCollateralManager: {
|
||||
[eXDaiNetwork.xdai]: '',
|
||||
},
|
||||
TokenDistributor: {
|
||||
[eXDaiNetwork.xdai]: '',
|
||||
},
|
||||
WethGateway: {
|
||||
[eXDaiNetwork.xdai]: '',
|
||||
},
|
||||
AaveOracle: {
|
||||
[eXDaiNetwork.xdai]: '',
|
||||
},
|
||||
FallbackOracle: {
|
||||
[eXDaiNetwork.xdai]: ZERO_ADDRESS,
|
||||
},
|
||||
ChainlinkAggregator: {
|
||||
[eXDaiNetwork.xdai]: {
|
||||
DAI: ZERO_ADDRESS,
|
||||
USDC: ZERO_ADDRESS,
|
||||
USDT: ZERO_ADDRESS,
|
||||
WBTC: ZERO_ADDRESS,
|
||||
STAKE: ZERO_ADDRESS,
|
||||
},
|
||||
},
|
||||
ReserveAssets: {
|
||||
[eXDaiNetwork.xdai]: {},
|
||||
},
|
||||
ReservesConfig: {},
|
||||
ATokenDomainSeparator: {
|
||||
[eXDaiNetwork.xdai]: '',
|
||||
},
|
||||
WETH: {
|
||||
[eXDaiNetwork.xdai]: '', // DAI: xDAI is the base token, DAI is also there, We need WXDAI
|
||||
},
|
||||
ReserveFactorTreasuryAddress: {
|
||||
[eXDaiNetwork.xdai]: '', // TEMP
|
||||
},
|
||||
};
|
42
markets/xdai/index.ts
Normal file
42
markets/xdai/index.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
import { oneRay, ZERO_ADDRESS } from '../../helpers/constants';
|
||||
import { IXDAIConfiguration, eXDaiNetwork } from '../../helpers/types';
|
||||
|
||||
import { CommonsConfig } from './commons';
|
||||
import {
|
||||
strategyDAI,
|
||||
strategyUSDC,
|
||||
strategyUSDT,
|
||||
strategyWBTC,
|
||||
strategyWETH,
|
||||
strategySTAKE,
|
||||
} from './reservesConfigs';
|
||||
|
||||
// ----------------
|
||||
// POOL--SPECIFIC PARAMS
|
||||
// ----------------
|
||||
|
||||
export const XDAIConfig: IXDAIConfiguration = {
|
||||
...CommonsConfig,
|
||||
MarketId: 'XDAI Market',
|
||||
ProviderId: 4, // Unknown?
|
||||
ReservesConfig: {
|
||||
DAI: strategyDAI,
|
||||
USDC: strategyUSDC,
|
||||
USDT: strategyUSDT,
|
||||
WBTC: strategyWBTC,
|
||||
WETH: strategyWETH,
|
||||
STAKE: strategySTAKE,
|
||||
},
|
||||
ReserveAssets: {
|
||||
[eXDaiNetwork.xdai]: {
|
||||
DAI: '0x44fA8E6f47987339850636F88629646662444217',
|
||||
USDC: '0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83',
|
||||
USDT: '0x4ECaBa5870353805a9F068101A40E0f32ed605C6',
|
||||
WBTC: '0x8e5bBbb09Ed1ebdE8674Cda39A0c169401db4252',
|
||||
WETH: '0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1',
|
||||
STAKE: '0xb7D311E2Eb55F2f68a9440da38e7989210b9A05e'
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default XDAIConfig;
|
91
markets/xdai/rateStrategies.ts
Normal file
91
markets/xdai/rateStrategies.ts
Normal file
|
@ -0,0 +1,91 @@
|
|||
import BigNumber from 'bignumber.js';
|
||||
import { oneRay } from '../../helpers/constants';
|
||||
import { IInterestRateStrategyParams } from '../../helpers/types';
|
||||
|
||||
// BUSD SUSD
|
||||
export const rateStrategyStableOne: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyStableOne",
|
||||
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: '0',
|
||||
stableRateSlope2: '0',
|
||||
};
|
||||
|
||||
// DAI TUSD
|
||||
export const rateStrategyStableTwo: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyStableTwo",
|
||||
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
|
||||
}
|
||||
|
||||
// USDC USDT
|
||||
export const rateStrategyStableThree: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyStableThree",
|
||||
optimalUtilizationRate: new BigNumber(0.9).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
|
||||
}
|
||||
|
||||
// WETH
|
||||
export const rateStrategyWETH: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyWETH",
|
||||
optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
|
||||
}
|
||||
|
||||
// AAVE
|
||||
export const rateStrategyAAVE: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyAAVE",
|
||||
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: '0',
|
||||
variableRateSlope1: '0',
|
||||
variableRateSlope2: '0',
|
||||
stableRateSlope1: '0',
|
||||
stableRateSlope2: '0',
|
||||
}
|
||||
|
||||
// BAT ENJ LINK MANA MKR REN YFI ZRX
|
||||
export const rateStrategyVolatileOne: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyVolatileOne",
|
||||
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
}
|
||||
|
||||
// KNC WBTC
|
||||
export const rateStrategyVolatileTwo: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyVolatileTwo",
|
||||
optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
}
|
||||
|
||||
// SNX
|
||||
export const rateStrategyVolatileThree: IInterestRateStrategyParams = {
|
||||
name: "rateStrategyVolatileThree",
|
||||
optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
|
||||
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
|
||||
}
|
85
markets/xdai/reservesConfigs.ts
Normal file
85
markets/xdai/reservesConfigs.ts
Normal file
|
@ -0,0 +1,85 @@
|
|||
// import BigNumber from 'bignumber.js';
|
||||
// import { oneRay } from '../../helpers/constants';
|
||||
import { eContractid, IReserveParams } from '../../helpers/types';
|
||||
import {
|
||||
rateStrategyStableOne,
|
||||
rateStrategyStableTwo,
|
||||
rateStrategyStableThree,
|
||||
rateStrategyWETH,
|
||||
rateStrategyAAVE,
|
||||
rateStrategyVolatileOne,
|
||||
rateStrategyVolatileTwo,
|
||||
rateStrategyVolatileThree,
|
||||
} from './rateStrategies';
|
||||
|
||||
export const strategyDAI: IReserveParams = {
|
||||
strategy: rateStrategyStableTwo,
|
||||
baseLTVAsCollateral: '7500',
|
||||
liquidationThreshold: '8000',
|
||||
liquidationBonus: '10500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: true,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1000'
|
||||
};
|
||||
|
||||
export const strategyUSDC: IReserveParams = {
|
||||
strategy: rateStrategyStableThree,
|
||||
baseLTVAsCollateral: '8000',
|
||||
liquidationThreshold: '8500',
|
||||
liquidationBonus: '10500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: true,
|
||||
reserveDecimals: '6',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1000'
|
||||
};
|
||||
|
||||
export const strategyUSDT: IReserveParams = {
|
||||
strategy: rateStrategyStableThree,
|
||||
baseLTVAsCollateral: '8000',
|
||||
liquidationThreshold: '8500',
|
||||
liquidationBonus: '10500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: true,
|
||||
reserveDecimals: '6',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1000'
|
||||
};
|
||||
|
||||
export const strategyWETH: IReserveParams = {
|
||||
strategy: rateStrategyWETH,
|
||||
baseLTVAsCollateral: '8000',
|
||||
liquidationThreshold: '8250',
|
||||
liquidationBonus: '10500',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: true,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '1000'
|
||||
};
|
||||
|
||||
export const strategyWBTC: IReserveParams = {
|
||||
strategy: rateStrategyVolatileTwo,
|
||||
baseLTVAsCollateral: '7000',
|
||||
liquidationThreshold: '7500',
|
||||
liquidationBonus: '11000',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: true,
|
||||
reserveDecimals: '8',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '2000'
|
||||
};
|
||||
|
||||
export const strategySTAKE: IReserveParams = {
|
||||
strategy: rateStrategyVolatileOne, //Temp?
|
||||
baseLTVAsCollateral: '5000',
|
||||
liquidationThreshold: '6500',
|
||||
liquidationBonus: '11000',
|
||||
borrowingEnabled: true,
|
||||
stableBorrowRateEnabled: true,
|
||||
reserveDecimals: '18',
|
||||
aTokenImpl: eContractid.AToken,
|
||||
reserveFactor: '2000'
|
||||
};
|
0
markets/zksync/commons.ts
Normal file
0
markets/zksync/commons.ts
Normal file
1
markets/zksync/index.ts
Normal file
1
markets/zksync/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user