From 579852affe03172ee963cd2ba08835cac01717bc Mon Sep 17 00:00:00 2001 From: cgewecke Date: Thu, 24 Mar 2022 11:48:18 -0700 Subject: [PATCH] feat(deprecation): Consolidate or remove deprecated contracts [SIM-124] (#225) + Deprecate NavIssuanceModule (in favor of CustomOracleNAVIssuanceModule) + Deprecate PerpV2LeverageModule (in favor of PerpV2LeverageModuleV2) + Deprecate AaveGovernanceAdapter (in favor of AaveGovernanceV2Adapter) + Deprecate UniswapYieldHook + Deprecate all AaveV1 contracts, external ABIs and associated fixtures + Deprecate all single use token migration contracts --- contracts/product/UniswapYieldHook.sol | 109 - .../AGIMigrationWrapAdapter.sol | 0 .../AaveGovernanceAdapter.sol | 0 .../AaveMigrationWrapAdapter.sol | 0 .../wrap => deprecated}/AaveWrapAdapter.sol | 0 .../AxieInfinityMigrationWrapAdapter.sol | 0 .../CompoundWrapAdapter.sol | 0 .../DgMigrationWrapAdapter.sol | 0 .../KyberMigrationAdapter.sol | 0 .../NAVIssuanceModule.sol | 0 .../PerpV2LeverageModule.sol | 0 .../wrap => deprecated}/YearnWrapAdapter.sol | 0 external/abi/aave/v1/AToken.json | 8 - .../abi/aave/v1/AavePropositionPower.json | 8 - external/abi/aave/v1/AaveProtoGovernance.json | 8 - .../aave/v1/AssetVotingWeightProvider.json | 8 - external/abi/aave/v1/CoreLibrary.json | 8 - .../DefaultReserveInterestRateStrategy.json | 8 - .../abi/aave/v1/GovernanceParamsProvider.json | 8 - external/abi/aave/v1/LendToAaveMigrator.json | 8 - external/abi/aave/v1/LendingPool.json | 8 - .../aave/v1/LendingPoolAddressesProvider.json | 8 - .../abi/aave/v1/LendingPoolConfigurator.json | 7 - external/abi/aave/v1/LendingPoolCore.json | 9 - .../abi/aave/v1/LendingPoolDataProvider.json | 8 - external/abi/aave/v1/LendingRateOracle.json | 8 - .../abi/aave/{v1 => v2}/AaveGovernanceV2.json | 0 .../aave/{v1 => v2}/AaveTokenV2Mintable.json | 0 external/abi/aave/{v1 => v2}/Executor.json | 0 .../aave/{v1 => v2}/GovernanceStrategy.json | 0 external/abi/axie_infinity/tokenSwap.json | 207 - external/abi/decentral_games/DGLight.json | 382 -- external/abi/decentral_games/dgToken.json | 284 - .../singularityNET/singularityNetToken.json | 5 - test/integration/aaveGovernanceModule.spec.ts | 178 - .../aaveMigrationWrapModule.spec.ts | 179 - test/integration/aaveWrapModule.spec.ts | 191 - .../agiMigrationWrapModule.spec.ts | 137 - test/integration/compoundWrapModule.spec.ts | 205 - .../integration/dgMigrationWrapModule.spec.ts | 172 - .../perpV2LeverageSlippageIssuance.spec.ts | 1325 ---- test/integration/yearnWrapModule.spec.ts | 207 - test/product/assetLimitHook.spec.ts | 26 +- test/product/uniswapYieldHook.spec.ts | 441 -- .../perpV2LeverageModuleViewer.spec.ts | 28 +- .../governance/aaveGovernanceAdapter.spec.ts | 201 - .../aaveGovernanceV2Adapter.spec.ts | 4 +- .../integration/lib/perpV2Positions.spec.ts | 26 +- .../wrap/aaveMigrationWrapAdapter.spec.ts | 168 - .../integration/wrap/aaveWrapAdapter.spec.ts | 239 - .../wrap/agiMigrationWrapAdapter.spec.ts | 167 - .../axieInfinityMigrationWrapAdapter.spec.ts | 229 - .../wrap/compoundWrapAdapter.spec.ts | 165 - .../wrap/dgMigrationWrapAdapter.spec.ts | 152 - .../wrap/kyberMigrationWrapAdapter.spec.ts | 170 - .../modules/navIssuanceModule.spec.ts | 3395 --------- .../modules/perpV2LeverageModule.spec.ts | 6045 ----------------- utils/common/perpV2Utils.ts | 18 +- utils/contracts/aave.ts | 16 - utils/contracts/axieInfinity.ts | 2 - utils/contracts/dg.ts | 2 - utils/contracts/index.ts | 15 - utils/contracts/singularityNet.ts | 2 - utils/deploys/deployAdapters.ts | 76 +- utils/deploys/deployExternal.ts | 179 +- utils/deploys/deployModules.ts | 39 +- utils/deploys/deployProduct.ts | 9 - utils/fixtures/aaveFixture.ts | 151 - utils/fixtures/index.ts | 1 - utils/fixtures/systemFixture.ts | 6 +- utils/test/index.ts | 2 - utils/types.ts | 7 +- 72 files changed, 80 insertions(+), 15594 deletions(-) delete mode 100644 contracts/product/UniswapYieldHook.sol rename {contracts/protocol/integration/wrap => deprecated}/AGIMigrationWrapAdapter.sol (100%) rename {contracts/protocol/integration/governance => deprecated}/AaveGovernanceAdapter.sol (100%) rename {contracts/protocol/integration/wrap => deprecated}/AaveMigrationWrapAdapter.sol (100%) rename {contracts/protocol/integration/wrap => deprecated}/AaveWrapAdapter.sol (100%) rename {contracts/protocol/integration/wrap => deprecated}/AxieInfinityMigrationWrapAdapter.sol (100%) rename {contracts/protocol/integration/wrap => deprecated}/CompoundWrapAdapter.sol (100%) rename {contracts/protocol/integration/wrap => deprecated}/DgMigrationWrapAdapter.sol (100%) rename {contracts/protocol/integration/wrap => deprecated}/KyberMigrationAdapter.sol (100%) rename {contracts/protocol/modules => deprecated}/NAVIssuanceModule.sol (100%) rename {contracts/protocol/modules => deprecated}/PerpV2LeverageModule.sol (100%) rename {contracts/protocol/integration/wrap => deprecated}/YearnWrapAdapter.sol (100%) delete mode 100644 external/abi/aave/v1/AToken.json delete mode 100644 external/abi/aave/v1/AavePropositionPower.json delete mode 100644 external/abi/aave/v1/AaveProtoGovernance.json delete mode 100644 external/abi/aave/v1/AssetVotingWeightProvider.json delete mode 100644 external/abi/aave/v1/CoreLibrary.json delete mode 100644 external/abi/aave/v1/DefaultReserveInterestRateStrategy.json delete mode 100644 external/abi/aave/v1/GovernanceParamsProvider.json delete mode 100644 external/abi/aave/v1/LendToAaveMigrator.json delete mode 100644 external/abi/aave/v1/LendingPool.json delete mode 100644 external/abi/aave/v1/LendingPoolAddressesProvider.json delete mode 100644 external/abi/aave/v1/LendingPoolConfigurator.json delete mode 100644 external/abi/aave/v1/LendingPoolCore.json delete mode 100644 external/abi/aave/v1/LendingPoolDataProvider.json delete mode 100644 external/abi/aave/v1/LendingRateOracle.json rename external/abi/aave/{v1 => v2}/AaveGovernanceV2.json (100%) rename external/abi/aave/{v1 => v2}/AaveTokenV2Mintable.json (100%) rename external/abi/aave/{v1 => v2}/Executor.json (100%) rename external/abi/aave/{v1 => v2}/GovernanceStrategy.json (100%) delete mode 100644 external/abi/axie_infinity/tokenSwap.json delete mode 100644 external/abi/decentral_games/DGLight.json delete mode 100644 external/abi/decentral_games/dgToken.json delete mode 100644 external/abi/singularityNET/singularityNetToken.json delete mode 100644 test/integration/aaveGovernanceModule.spec.ts delete mode 100644 test/integration/aaveMigrationWrapModule.spec.ts delete mode 100644 test/integration/aaveWrapModule.spec.ts delete mode 100644 test/integration/agiMigrationWrapModule.spec.ts delete mode 100644 test/integration/compoundWrapModule.spec.ts delete mode 100644 test/integration/dgMigrationWrapModule.spec.ts delete mode 100644 test/integration/perpV2LeverageSlippageIssuance.spec.ts delete mode 100644 test/integration/yearnWrapModule.spec.ts delete mode 100644 test/product/uniswapYieldHook.spec.ts delete mode 100644 test/protocol/integration/governance/aaveGovernanceAdapter.spec.ts delete mode 100644 test/protocol/integration/wrap/aaveMigrationWrapAdapter.spec.ts delete mode 100644 test/protocol/integration/wrap/aaveWrapAdapter.spec.ts delete mode 100644 test/protocol/integration/wrap/agiMigrationWrapAdapter.spec.ts delete mode 100644 test/protocol/integration/wrap/axieInfinityMigrationWrapAdapter.spec.ts delete mode 100644 test/protocol/integration/wrap/compoundWrapAdapter.spec.ts delete mode 100644 test/protocol/integration/wrap/dgMigrationWrapAdapter.spec.ts delete mode 100644 test/protocol/integration/wrap/kyberMigrationWrapAdapter.spec.ts delete mode 100644 test/protocol/modules/navIssuanceModule.spec.ts delete mode 100644 test/protocol/modules/perpV2LeverageModule.spec.ts delete mode 100644 utils/contracts/aave.ts delete mode 100644 utils/contracts/axieInfinity.ts delete mode 100644 utils/contracts/dg.ts delete mode 100644 utils/contracts/singularityNet.ts delete mode 100644 utils/fixtures/aaveFixture.ts diff --git a/contracts/product/UniswapYieldHook.sol b/contracts/product/UniswapYieldHook.sol deleted file mode 100644 index e48a5bbb6..000000000 --- a/contracts/product/UniswapYieldHook.sol +++ /dev/null @@ -1,109 +0,0 @@ -/* - Copyright 2020 Set Labs Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache License, Version 2.0 -*/ - -pragma solidity 0.6.10; -pragma experimental "ABIEncoderV2"; - -import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; - -import { AddressArrayUtils } from "../lib/AddressArrayUtils.sol"; -import { INAVIssuanceHook } from "../interfaces/INAVIssuanceHook.sol"; -import { ISetToken } from "../interfaces/ISetToken.sol"; - - -contract UniswapYieldHook is INAVIssuanceHook, Ownable { - using AddressArrayUtils for address[]; - - /* ============ State Variables ============ */ - - mapping(address => uint256) public assetLimits; - address[] public assets; - - /* ============ Constructor ============ */ - - constructor(address[] memory _assets, uint256[] memory _limits) public { - require(_assets.length == _limits.length, "Arrays must be equal"); - require(_assets.length != 0, "Array must not be empty"); - - for (uint256 i = 0; i < _assets.length; i++) { - address asset = _assets[i]; - require(assetLimits[asset] == 0, "Asset already added"); - assetLimits[asset] = _limits[i]; - } - - assets = _assets; - } - - /* ============ External Functions ============ */ - - function invokePreIssueHook( - ISetToken /*_setToken*/, - address _reserveAsset, - uint256 _reserveAssetQuantity, - address _sender, - address /*_to*/ - ) - external - override - { - if (_sender != tx.origin) { - require( - _reserveAssetQuantity <= assetLimits[_reserveAsset], - "Issue size too large for call from contract." - ); - } - } - - function invokePreRedeemHook( - ISetToken _setToken, - uint256 _redeemQuantity, - address _sender, - address /*_to*/ - ) - external - override - { - if (_sender != tx.origin) { - require( - _redeemQuantity <= assetLimits[address(_setToken)], - "Redeem size too large for call from contract." - ); - } - } - - function addAssetLimit(address _asset, uint256 _newLimit) external onlyOwner { - require(assetLimits[_asset] == 0, "Asset already added"); - assetLimits[_asset] = _newLimit; - assets.push(_asset); - } - - function editAssetLimit(address _asset, uint256 _newLimit) external onlyOwner { - require(assetLimits[_asset] != 0, "Asset not added"); - assetLimits[_asset] = _newLimit; - } - - function removeAssetLimit(address _asset) external onlyOwner { - require(assetLimits[_asset] != 0, "Asset not added"); - delete assetLimits[_asset]; - assets = assets.remove(_asset); - } - - /* ============ Getters ============ */ - - function getAssets() external view returns(address[] memory) { return assets; } -} \ No newline at end of file diff --git a/contracts/protocol/integration/wrap/AGIMigrationWrapAdapter.sol b/deprecated/AGIMigrationWrapAdapter.sol similarity index 100% rename from contracts/protocol/integration/wrap/AGIMigrationWrapAdapter.sol rename to deprecated/AGIMigrationWrapAdapter.sol diff --git a/contracts/protocol/integration/governance/AaveGovernanceAdapter.sol b/deprecated/AaveGovernanceAdapter.sol similarity index 100% rename from contracts/protocol/integration/governance/AaveGovernanceAdapter.sol rename to deprecated/AaveGovernanceAdapter.sol diff --git a/contracts/protocol/integration/wrap/AaveMigrationWrapAdapter.sol b/deprecated/AaveMigrationWrapAdapter.sol similarity index 100% rename from contracts/protocol/integration/wrap/AaveMigrationWrapAdapter.sol rename to deprecated/AaveMigrationWrapAdapter.sol diff --git a/contracts/protocol/integration/wrap/AaveWrapAdapter.sol b/deprecated/AaveWrapAdapter.sol similarity index 100% rename from contracts/protocol/integration/wrap/AaveWrapAdapter.sol rename to deprecated/AaveWrapAdapter.sol diff --git a/contracts/protocol/integration/wrap/AxieInfinityMigrationWrapAdapter.sol b/deprecated/AxieInfinityMigrationWrapAdapter.sol similarity index 100% rename from contracts/protocol/integration/wrap/AxieInfinityMigrationWrapAdapter.sol rename to deprecated/AxieInfinityMigrationWrapAdapter.sol diff --git a/contracts/protocol/integration/wrap/CompoundWrapAdapter.sol b/deprecated/CompoundWrapAdapter.sol similarity index 100% rename from contracts/protocol/integration/wrap/CompoundWrapAdapter.sol rename to deprecated/CompoundWrapAdapter.sol diff --git a/contracts/protocol/integration/wrap/DgMigrationWrapAdapter.sol b/deprecated/DgMigrationWrapAdapter.sol similarity index 100% rename from contracts/protocol/integration/wrap/DgMigrationWrapAdapter.sol rename to deprecated/DgMigrationWrapAdapter.sol diff --git a/contracts/protocol/integration/wrap/KyberMigrationAdapter.sol b/deprecated/KyberMigrationAdapter.sol similarity index 100% rename from contracts/protocol/integration/wrap/KyberMigrationAdapter.sol rename to deprecated/KyberMigrationAdapter.sol diff --git a/contracts/protocol/modules/NAVIssuanceModule.sol b/deprecated/NAVIssuanceModule.sol similarity index 100% rename from contracts/protocol/modules/NAVIssuanceModule.sol rename to deprecated/NAVIssuanceModule.sol diff --git a/contracts/protocol/modules/PerpV2LeverageModule.sol b/deprecated/PerpV2LeverageModule.sol similarity index 100% rename from contracts/protocol/modules/PerpV2LeverageModule.sol rename to deprecated/PerpV2LeverageModule.sol diff --git a/contracts/protocol/integration/wrap/YearnWrapAdapter.sol b/deprecated/YearnWrapAdapter.sol similarity index 100% rename from contracts/protocol/integration/wrap/YearnWrapAdapter.sol rename to deprecated/YearnWrapAdapter.sol diff --git a/external/abi/aave/v1/AToken.json b/external/abi/aave/v1/AToken.json deleted file mode 100644 index f8833232d..000000000 --- a/external/abi/aave/v1/AToken.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "contractName": "AToken", - "abi": [{"inputs":[{"internalType":"contract LendingPoolAddressesProvider","name":"_addressesProvider","type":"address"},{"internalType":"address","name":"_underlyingAsset","type":"address"},{"internalType":"uint8","name":"_underlyingAssetDecimals","type":"uint8"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fromBalanceIncrease","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_toBalanceIncrease","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fromIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_toIndex","type":"uint256"}],"name":"BalanceTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fromBalanceIncrease","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fromIndex","type":"uint256"}],"name":"BurnOnLiquidation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"}],"name":"InterestRedirectionAllowanceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_redirectedBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fromBalanceIncrease","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fromIndex","type":"uint256"}],"name":"InterestStreamRedirected","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fromBalanceIncrease","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fromIndex","type":"uint256"}],"name":"MintOnDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fromBalanceIncrease","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fromIndex","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_targetAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_targetBalanceIncrease","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_targetIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_redirectedBalanceAdded","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_redirectedBalanceRemoved","type":"uint256"}],"name":"RedirectedBalanceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":true,"inputs":[],"name":"UINT_MAX_VALUE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"underlyingAssetAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"redirectInterestStream","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"}],"name":"redirectInterestStreamOf","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"allowInterestRedirectionTo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"redeem","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintOnDeposit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"burnOnLiquidation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transferOnLiquidation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"principalBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"isTransferAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getInterestRedirectionAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getRedirectedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}], - "bytecode": "0x60806040523480156200001157600080fd5b506040516200240838038062002408833981810160405260a08110156200003757600080fd5b8151602083015160408085015160608601805192519496939591949391820192846401000000008211156200006b57600080fd5b9083019060208201858111156200008157600080fd5b82516401000000008111828201881017156200009c57600080fd5b82525081516020918201929091019080838360005b83811015620000cb578181015183820152602001620000b1565b50505050905090810190601f168015620000f95780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011d57600080fd5b9083019060208201858111156200013357600080fd5b82516401000000008111828201881017156200014e57600080fd5b82525081516020918201929091019080838360005b838110156200017d57818101518382015260200162000163565b50505050905090810190601f168015620001ab5780820380516001836020036101000a031916815260200191505b506040525050508181848260039080519060200190620001cd929190620003da565b508151620001e3906004906020850190620003da565b506005805460ff191660ff929092169190911790555050600a80546001600160a01b0319166001600160a01b0387811691909117918290556040805163076b7fbb60e51b81529051929091169163ed6ff76091600480820192602092909190829003018186803b1580156200025757600080fd5b505afa1580156200026c573d6000803e3d6000fd5b505050506040513d60208110156200028357600080fd5b5051600b80546001600160a01b0319166001600160a01b03928316179055600a5460408051630261bf8b60e01b815290519190921691630261bf8b916004808301926020929190829003018186803b158015620002df57600080fd5b505afa158015620002f4573d6000803e3d6000fd5b505050506040513d60208110156200030b57600080fd5b5051600c80546001600160a01b0319166001600160a01b03928316179055600a5460408051632f58b80d60e01b815290519190921691632f58b80d916004808301926020929190829003018186803b1580156200036757600080fd5b505afa1580156200037c573d6000803e3d6000fd5b505050506040513d60208110156200039357600080fd5b5051600d80546001600160a01b0319166001600160a01b0392831617905560058054610100600160a81b031916610100969092169590950217909355506200047f92505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200041d57805160ff19168380011785556200044d565b828001600101855582156200044d579182015b828111156200044d57825182559160200191906001019062000430565b506200045b9291506200045f565b5090565b6200047c91905b808211156200045b576000815560010162000466565b90565b611f79806200048f6000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80635eae177c116100de578063a9059cbb11610097578063db006a7511610071578063db006a75146104f3578063dd62ed3e14610510578063ee9907a41461053e578063f866c3191461056457610173565b8063a9059cbb14610499578063c634dfaa146104c5578063d0fc81d2146104eb57610173565b80635eae177c146103df57806370a082311461040b57806389d1a0fc1461043157806394362e8b1461043957806395d89b4114610465578063a457c2d71461046d57610173565b806323b872dd1161013057806323b872dd146102c3578063313ce567146102f9578063325a9b131461031757806339509351146103455780633edb7cb814610371578063445e80101461039d57610173565b806306fdde0314610178578063095ea7b3146101f55780630e49072d1461023557806312c87c2d1461025d57806318160ddd146102835780631d51e7cf1461029d575b600080fd5b61018061059a565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101ba5781810151838201526020016101a2565b50505050905090810190601f1680156101e75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102216004803603604081101561020b57600080fd5b506001600160a01b038135169060200135610631565b604080519115158252519081900360200190f35b61025b6004803603602081101561024b57600080fd5b50356001600160a01b0316610648565b005b61025b6004803603602081101561027357600080fd5b50356001600160a01b0316610655565b61028b6106f4565b60408051918252519081900360200190f35b61028b600480360360208110156102b357600080fd5b50356001600160a01b03166107b6565b610221600480360360608110156102d957600080fd5b506001600160a01b038135811691602081013590911690604001356107d5565b61030161082c565b6040805160ff9092168252519081900360200190f35b61025b6004803603604081101561032d57600080fd5b506001600160a01b0381358116916020013516610835565b6102216004803603604081101561035b57600080fd5b506001600160a01b03813516906020013561089b565b61025b6004803603604081101561038757600080fd5b506001600160a01b0381351690602001356108d7565b6103c3600480360360208110156103b357600080fd5b50356001600160a01b03166109cc565b604080516001600160a01b039092168252519081900360200190f35b610221600480360360408110156103f557600080fd5b506001600160a01b0381351690602001356109ea565b61028b6004803603602081101561042157600080fd5b50356001600160a01b0316610a85565b6103c3610b38565b61025b6004803603604081101561044f57600080fd5b506001600160a01b038135169060200135610b4c565b610180610c21565b6102216004803603604081101561048357600080fd5b506001600160a01b038135169060200135610c82565b610221600480360360408110156104af57600080fd5b506001600160a01b038135169060200135610cbe565b61028b600480360360208110156104db57600080fd5b50356001600160a01b0316610ccb565b61028b610cd6565b61025b6004803603602081101561050957600080fd5b5035610cdc565b61028b6004803603604081101561052657600080fd5b506001600160a01b0381358116916020013516610f16565b61028b6004803603602081101561055457600080fd5b50356001600160a01b0316610f41565b61025b6004803603606081101561057a57600080fd5b506001600160a01b03813581169160208101359091169060400135610f5c565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106265780601f106105fb57610100808354040283529160200191610626565b820191906000526020600020905b81548152906001019060200180831161060957829003601f168201915b505050505090505b90565b600061063e338484610fb5565b5060015b92915050565b61065233826110a1565b50565b6001600160a01b03811633141561069d5760405162461bcd60e51b8152600401808060200182810382526025815260200180611d8d6025913960400191505060405180910390fd5b3360008181526009602052604080822080546001600160a01b0319166001600160a01b03861690811790915590519092917fc2d6a42a9d5273283f73009a07aacfb043f2f91173a8d9d33b504afe898db08b91a350565b6000806106ff611290565b90508061071057600091505061062e565b600b546005546040805163d15e005360e01b81526001600160a01b036101009093048316600482015290516107b0936107ab93169163d15e0053916024808301926020929190829003018186803b15801561076a57600080fd5b505afa15801561077e573d6000803e3d6000fd5b505050506040513d602081101561079457600080fd5b505161079f84611296565b9063ffffffff6112ac16565b6112f7565b91505090565b6001600160a01b0381166000908152600860205260409020545b919050565b60006107e2848484611310565b6001600160a01b03841660009081526001602090815260408083203380855292529091205461082291869161081d908663ffffffff61137f16565b610fb5565b5060019392505050565b60055460ff1690565b6001600160a01b0382811660009081526009602052604090205416331461088d5760405162461bcd60e51b815260040180806020018281038252603a815260200180611f0b603a913960400191505060405180910390fd5b61089782826110a1565b5050565b3360008181526001602090815260408083206001600160a01b0387168452909152812054909161063e91859061081d908663ffffffff6113dc16565b600c546001600160a01b031633146109205760405162461bcd60e51b8152600401808060200182810382526032815260200180611ed96032913960400191505060405180910390fd5b600080600061092e85611436565b93509350935050610940858386611527565b61094a858561165e565b600061095c848663ffffffff61137f16565b61096c5761096986611737565b90505b856001600160a01b03167f90e5d3d68ec162d9c7de393037a3ede04dd44f68e051bf2ace4a73c299dbc4db8685846109a457856109a7565b60005b60408051938452602084019290925282820152519081900360600190a2505050505050565b6001600160a01b039081166000908152600760205260409020541690565b600d54600554604080516376e9d61560e01b81526101009092046001600160a01b039081166004840152858116602484015260448301859052905160009391909116916376e9d615916064808301926020929190829003018186803b158015610a5257600080fd5b505afa158015610a66573d6000803e3d6000fd5b505050506040513d6020811015610a7c57600080fd5b50519392505050565b600080610a91836117e9565b6001600160a01b03841660009081526008602052604090205490915081158015610ab9575080155b15610ac9576000925050506107d0565b6001600160a01b0384811660009081526007602052604090205416610b1a57610b1181610b0586610b00868463ffffffff6113dc16565b611804565b9063ffffffff61137f16565b925050506107d0565b610b11610b2b82610b058785611804565b839063ffffffff6113dc16565b60055461010090046001600160a01b031681565b600c546001600160a01b03163314610b955760405162461bcd60e51b8152600401808060200182810382526032815260200180611ed96032913960400191505060405180910390fd5b600080610ba184611436565b935093505050610bc584610bbe85856113dc90919063ffffffff16565b6000611527565b610bcf84846118b9565b604080518481526020810184905280820183905290516001600160a01b038616917fbe7799898ca2d813ff902b487c1b434ab45b47edd8f38b77ad5e99aae8341b7a919081900360600190a250505050565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106265780601f106105fb57610100808354040283529160200191610626565b3360008181526001602090815260408083206001600160a01b0387168452909152812054909161063e91859061081d908663ffffffff61137f16565b600061063e338484611310565b6000610642826117e9565b60001981565b60008111610d31576040805162461bcd60e51b815260206004820181905260248201527f416d6f756e7420746f2072656465656d206e6565647320746f206265203e2030604482015290519081900360640190fd5b6000806000610d3f33611436565b91955093509150849050600019811415610d565750825b83811115610d955760405162461bcd60e51b8152600401808060200182810382526032815260200180611d396032913960400191505060405180910390fd5b610d9f33826109ea565b610df0576040805162461bcd60e51b815260206004820152601b60248201527f5472616e736665722063616e6e6f7420626520616c6c6f7765642e0000000000604482015290519081900360640190fd5b610dfb338483611527565b610e05338261165e565b6000610e17858363ffffffff61137f16565b610e2757610e2433611737565b90505b600c546005546001600160a01b0391821691639895e3d8916101009004163385610e578a8263ffffffff61137f16565b6040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b03168152602001838152602001828152602001945050505050600060405180830381600087803b158015610ec657600080fd5b505af1158015610eda573d6000803e3d6000fd5b50505050336001600160a01b03167fbd5034ffbd47e4e72a94baa2cdb74c6fad73cb3bcdc13036b72ec8306f5a76468386846109a457866109a7565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b031660009081526006602052604090205490565b600c546001600160a01b03163314610fa55760405162461bcd60e51b8152600401808060200182810382526032815260200180611ed96032913960400191505060405180910390fd5b610fb08383836119a9565b505050565b6001600160a01b038316610ffa5760405162461bcd60e51b8152600401808060200182810382526024815260200180611eb56024913960400191505060405180910390fd5b6001600160a01b03821661103f5760405162461bcd60e51b8152600401808060200182810382526022815260200180611d6b6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0380831660009081526007602052604090205481169082168114156110fe5760405162461bcd60e51b815260040180806020018281038252602a815260200180611dd3602a913960400191505060405180910390fd5b60008060008061110d87611436565b9350935093509350600083116111545760405162461bcd60e51b8152600401808060200182810382526042815260200180611dfd6042913960600191505060405180910390fd5b6001600160a01b0385161561116f5761116f87600086611527565b866001600160a01b0316866001600160a01b031614156111fb576001600160a01b038716600081815260076020908152604080832080546001600160a01b03191690558051878152918201869052818101859052519192917f5e3cad45b1fe24159d1cb39788d82d0f69cc15770aa96fba1d3d1a73487355949181900360600190a35050505050610897565b6001600160a01b03878116600090815260076020526040812080546001600160a01b031916928916929092179091556112379088908590611527565b604080518481526020810184905280820183905290516001600160a01b0380891692908a16917f5e3cad45b1fe24159d1cb39788d82d0f69cc15770aa96fba1d3d1a73487355949181900360600190a350505050505050565b60025490565b600061064282633b9aca0063ffffffff611ad816565b60006112f06b033b2e3c9fd0803ce80000006112e46112d1868663ffffffff611ad816565b6b019d971e4fe8401e74000000906113dc565b9063ffffffff611b3116565b9392505050565b6000631dcd65006112f0633b9aca006112e483866113dc565b828161131c82826109ea565b61136d576040805162461bcd60e51b815260206004820152601b60248201527f5472616e736665722063616e6e6f7420626520616c6c6f7765642e0000000000604482015290519081900360640190fd5b6113788585856119a9565b5050505050565b6000828211156113d6576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6000828201838110156112f0576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000806000806000611447866117e9565b9050600061145882610b0589610a85565b905061146487826118b9565b600b546005546040805163d15e005360e01b81526101009092046001600160a01b0390811660048401529051600093919091169163d15e0053916024808301926020929190829003018186803b1580156114bd57600080fd5b505afa1580156114d1573d6000803e3d6000fd5b505050506040513d60208110156114e757600080fd5b50516001600160a01b0389166000908152600660205260409020819055905082611517818463ffffffff6113dc16565b9099909850919650945092505050565b6001600160a01b03808416600090815260076020526040902054168061154d5750610fb0565b60008061155983611436565b6001600160a01b038716600090815260086020526040902054919550935061158f9250869150610b05908863ffffffff6113dc16565b6001600160a01b03808516600090815260086020908152604080832094909455600790529190912054168015611602576001600160a01b0381166000908152600860205260409020546115e8908463ffffffff6113dc16565b6001600160a01b0382166000908152600860205260409020555b60408051848152602081018490528082018890526060810187905290516001600160a01b038616917f70ff8cf632603e2bfd1afb7e4061acce53d95356b1be9726b99fa22ba733b01f919081900360800190a250505050505050565b6001600160a01b0382166116a35760405162461bcd60e51b8152600401808060200182810382526021815260200180611e6f6021913960400191505060405180910390fd5b6002546116b6908263ffffffff61137f16565b6002556001600160a01b0382166000908152602081905260409020546116e2908263ffffffff61137f16565b6001600160a01b038316600081815260208181526040808320949094558351858152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35050565b6001600160a01b038116600081815260076020908152604080832080546001600160a01b03191690558051838152918201839052818101839052519192839290917f5e3cad45b1fe24159d1cb39788d82d0f69cc15770aa96fba1d3d1a7348735594919081900360600190a36001600160a01b0382166000908152600860205260409020546117e157506001600160a01b03811660009081526006602052604081205560016107d0565b5060006107d0565b6001600160a01b031660009081526020819052604090205490565b6001600160a01b03808316600090815260066020908152604080832054600b54600554835163d15e005360e01b815261010090910487166004820152925194956112f0956107ab9593946118ad94939092169263d15e00539260248082019391829003018186803b15801561187857600080fd5b505afa15801561188c573d6000803e3d6000fd5b505050506040513d60208110156118a257600080fd5b505161079f87611296565b9063ffffffff611b9b16565b6001600160a01b038216611914576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b600254611927908263ffffffff6113dc16565b6002556001600160a01b038216600090815260208190526040902054611953908263ffffffff6113dc16565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600081116119e85760405162461bcd60e51b8152600401808060200182810382526030815260200180611e3f6030913960400191505060405180910390fd5b60008060006119f686611436565b93509350935050600080611a0987611436565b935093505050611a1a888588611527565b611a2e87610bbe848963ffffffff6113dc16565b611a39888888611bd3565b6000611a4b868863ffffffff61137f16565b611a5b57611a5889611737565b90505b876001600160a01b0316896001600160a01b03167f89a178eaa27e0cd201bd795ca8ff716ac0df9618494510ca79771cfc66ffcde889888786611a9e5789611aa1565b60005b60408051948552602085019390935283830191909152606083015260808201879052519081900360a00190a3505050505050505050565b600082611ae757506000610642565b82820282848281611af457fe5b04146112f05760405162461bcd60e51b8152600401808060200182810382526021815260200180611db26021913960400191505060405180910390fd5b6000808211611b87576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b6000828481611b9257fe5b04949350505050565b600060028204611bcb836112e4611bbe876b033b2e3c9fd0803ce8000000611ad8565b849063ffffffff6113dc16565b949350505050565b6001600160a01b038316611c185760405162461bcd60e51b8152600401808060200182810382526025815260200180611e906025913960400191505060405180910390fd5b6001600160a01b038216611c5d5760405162461bcd60e51b8152600401808060200182810382526023815260200180611d166023913960400191505060405180910390fd5b6001600160a01b038316600090815260208190526040902054611c86908263ffffffff61137f16565b6001600160a01b038085166000908152602081905260408082209390935590841681522054611cbb908263ffffffff6113dc16565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a350505056fe45524332303a207472616e7366657220746f20746865207a65726f2061646472657373557365722063616e6e6f742072656465656d206d6f7265207468616e2074686520617661696c61626c652062616c616e636545524332303a20617070726f766520746f20746865207a65726f2061646472657373557365722063616e6e6f74206769766520616c6c6f77616e636520746f2068696d73656c66536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77496e74657265737420697320616c7265616479207265646972656374656420746f207468652075736572496e7465726573742073747265616d2063616e206f6e6c79206265207265646972656374656420696620746865726520697320612076616c69642062616c616e63655472616e7366657272656420616d6f756e74206e6565647320746f2062652067726561746572207468616e207a65726f45524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735468652063616c6c6572206f6620746869732066756e6374696f6e206d7573742062652061206c656e64696e6720706f6f6c43616c6c6572206973206e6f7420616c6c6f77656420746f2072656469726563742074686520696e746572657374206f66207468652075736572a265627a7a723158207029b8e2a8a6dcf81be1753ab59bc1690f3f41e58fae43086d4df87ae569744a64736f6c634300050e0032", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/external/abi/aave/v1/AavePropositionPower.json b/external/abi/aave/v1/AavePropositionPower.json deleted file mode 100644 index 0719aae36..000000000 --- a/external/abi/aave/v1/AavePropositionPower.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "contractName": "AavePropositionPower", - "abi": [{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"address[]","name":"council","type":"address[]"},{"internalType":"uint256","name":"cap","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"MinterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"MinterRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}], - "bytecode": "60806040523480156200001157600080fd5b506040516200175838038062001758833981810160405260a08110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b50604081815260208301519201805192949193919284640100000000821115620001c157600080fd5b908301906020820185811115620001d757600080fd5b8251866020820283011164010000000082111715620001f557600080fd5b82525081516020918201928201910280838360005b83811015620002245781810151838201526020016200020a565b5050505091909101604052506020015191508590508484670de0b6b3a764000084026200026c6200025d6001600160e01b036200039716565b6001600160e01b036200039c16565b60008111620002c2576040805162461bcd60e51b815260206004820152601560248201527f45524332304361707065643a2063617020697320300000000000000000000000604482015290519081900360640190fd5b6004558251620002da906005906020860190620006eb565b508151620002f0906006906020850190620006eb565b506007805460ff191660ff92909216919091179055505081518114620003485760405162461bcd60e51b8152600401808060200182810382526021815260200180620017376021913960400191505060405180910390fd5b60005b818110156200038b57620003828382815181106200036557fe5b6020026020010151670de0b6b3a7640000620003ee60201b60201c565b6001016200034b565b5050505050506200078d565b335b90565b620003b78160036200048c60201b62000ce71790919060201c565b6040516001600160a01b038216907f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f690600090a250565b6004546200041d82620004096001600160e01b036200051916565b6200051f60201b62000a231790919060201c565b111562000471576040805162461bcd60e51b815260206004820152601960248201527f45524332304361707065643a2063617020657863656564656400000000000000604482015290519081900360640190fd5b6200048882826200058160201b62000bf71760201c565b5050565b620004a182826001600160e01b036200068216565b15620004f4576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b60025490565b6000828201838110156200057a576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216620005dd576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b620005f9816002546200051f60201b62000a231790919060201c565b6002556001600160a01b038216600090815260208181526040909120546200062c91839062000a236200051f821b17901c565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b60006001600160a01b038216620006cb5760405162461bcd60e51b8152600401808060200182810382526022815260200180620017156022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200072e57805160ff19168380011785556200075e565b828001600101855582156200075e579182015b828111156200075e57825182559160200191906001019062000741565b506200076c92915062000770565b5090565b6200039991905b808211156200076c576000815560010162000777565b610f78806200079d6000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c806370a0823111610097578063a457c2d711610066578063a457c2d7146102ee578063a9059cbb1461031a578063aa271e1a14610346578063dd62ed3e1461036c57610100565b806370a082311461029057806395d89b41146102b6578063983b2d56146102be57806398650275146102e657610100565b8063313ce567116100d3578063313ce56714610212578063355274ea14610230578063395093511461023857806340c10f191461026457610100565b806306fdde0314610105578063095ea7b31461018257806318160ddd146101c257806323b872dd146101dc575b600080fd5b61010d61039a565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561014757818101518382015260200161012f565b50505050905090810190601f1680156101745780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101ae6004803603604081101561019857600080fd5b506001600160a01b038135169060200135610430565b604080519115158252519081900360200190f35b6101ca61044d565b60408051918252519081900360200190f35b6101ae600480360360608110156101f257600080fd5b506001600160a01b03813581169160208101359091169060400135610453565b61021a6104e0565b6040805160ff9092168252519081900360200190f35b6101ca6104e9565b6101ae6004803603604081101561024e57600080fd5b506001600160a01b0381351690602001356104ef565b6101ae6004803603604081101561027a57600080fd5b506001600160a01b038135169060200135610543565b6101ca600480360360208110156102a657600080fd5b50356001600160a01b031661059a565b61010d6105b5565b6102e4600480360360208110156102d457600080fd5b50356001600160a01b0316610616565b005b6102e4610668565b6101ae6004803603604081101561030457600080fd5b506001600160a01b03813516906020013561067a565b6101ae6004803603604081101561033057600080fd5b506001600160a01b0381351690602001356106e8565b6101ae6004803603602081101561035c57600080fd5b50356001600160a01b03166106fc565b6101ca6004803603604081101561038257600080fd5b506001600160a01b0381358116916020013516610715565b60058054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104265780601f106103fb57610100808354040283529160200191610426565b820191906000526020600020905b81548152906001019060200180831161040957829003601f168201915b5050505050905090565b600061044461043d610740565b8484610744565b50600192915050565b60025490565b6000610460848484610830565b6104d68461046c610740565b6104d185604051806060016040528060288152602001610e8c602891396001600160a01b038a166000908152600160205260408120906104aa610740565b6001600160a01b03168152602081019190915260400160002054919063ffffffff61098c16565b610744565b5060019392505050565b60075460ff1690565b60045490565b60006104446104fc610740565b846104d1856001600061050d610740565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff610a2316565b6000610555610550610740565b6106fc565b6105905760405162461bcd60e51b8152600401808060200182810382526030815260200180610e3b6030913960400191505060405180910390fd5b6104448383610a84565b6001600160a01b031660009081526020819052604090205490565b60068054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104265780601f106103fb57610100808354040283529160200191610426565b610621610550610740565b61065c5760405162461bcd60e51b8152600401808060200182810382526030815260200180610e3b6030913960400191505060405180910390fd5b61066581610b00565b50565b610678610673610740565b610b48565b565b6000610444610687610740565b846104d185604051806060016040528060258152602001610f1f60259139600160006106b1610740565b6001600160a01b03908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff61098c16565b60006104446106f5610740565b8484610830565b600061070f60038363ffffffff610b9016565b92915050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b3390565b6001600160a01b0383166107895760405162461bcd60e51b8152600401808060200182810382526024815260200180610efb6024913960400191505060405180910390fd5b6001600160a01b0382166107ce5760405162461bcd60e51b8152600401808060200182810382526022815260200180610df36022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0383166108755760405162461bcd60e51b8152600401808060200182810382526025815260200180610ed66025913960400191505060405180910390fd5b6001600160a01b0382166108ba5760405162461bcd60e51b8152600401808060200182810382526023815260200180610dd06023913960400191505060405180910390fd5b6108fd81604051806060016040528060268152602001610e15602691396001600160a01b038616600090815260208190526040902054919063ffffffff61098c16565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610932908263ffffffff610a2316565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610a1b5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156109e05781810151838201526020016109c8565b50505050905090810190601f168015610a0d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610a7d576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600454610a9f82610a9361044d565b9063ffffffff610a2316565b1115610af2576040805162461bcd60e51b815260206004820152601960248201527f45524332304361707065643a2063617020657863656564656400000000000000604482015290519081900360640190fd5b610afc8282610bf7565b5050565b610b1160038263ffffffff610ce716565b6040516001600160a01b038216907f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f690600090a250565b610b5960038263ffffffff610d6816565b6040516001600160a01b038216907fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb6669290600090a250565b60006001600160a01b038216610bd75760405162461bcd60e51b8152600401808060200182810382526022815260200180610eb46022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b6001600160a01b038216610c52576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b600254610c65908263ffffffff610a2316565b6002556001600160a01b038216600090815260208190526040902054610c91908263ffffffff610a2316565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b610cf18282610b90565b15610d43576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b610d728282610b90565b610dad5760405162461bcd60e51b8152600401808060200182810382526021815260200180610e6b6021913960400191505060405180910390fd5b6001600160a01b0316600090815260209190915260409020805460ff1916905556fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e63654d696e746572526f6c653a2063616c6c657220646f6573206e6f74206861766520746865204d696e74657220726f6c65526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c6545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365526f6c65733a206163636f756e7420697320746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa265627a7a723158207fdc7cf20a29676fb941fbbd2bd5f3d52bbe4c6647593316b5752140e8970d8564736f6c63430005100032526f6c65733a206163636f756e7420697320746865207a65726f2061646472657373494e434f4e53495354454e545f4341505f414e445f434f554e43494c5f53495a45", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/external/abi/aave/v1/AaveProtoGovernance.json b/external/abi/aave/v1/AaveProtoGovernance.json deleted file mode 100644 index a7e61eeb1..000000000 --- a/external/abi/aave/v1/AaveProtoGovernance.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "contractName": "AaveProtoGovernance", - "abi": [{"inputs":[{"internalType":"contract IGovernanceParamsProvider","name":"_govParamsProvider","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"abstainVotingPower","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"yesVotingPower","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"noVotingPower","type":"uint256"}],"name":"AbstainWins","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"abstainVotingPower","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"yesVotingPower","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"noVotingPower","type":"uint256"}],"name":"NoWins","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"ipfsHash","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"proposalType","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"propositionPowerOfCreator","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"threshold","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxMovesToVotingAllowed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"votingBlocksDuration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"validatingBlocksDuration","type":"uint256"},{"indexed":false,"internalType":"address","name":"proposalExecutor","type":"address"}],"name":"ProposalCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"StatusChangeToExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"StatusChangeToValidating","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"movesToVoting","type":"uint256"}],"name":"StatusChangeToVoting","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":true,"internalType":"uint256","name":"vote","type":"uint256"},{"indexed":false,"internalType":"contract IERC20","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"proposalStatusBefore","type":"uint256"}],"name":"VoteCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":true,"internalType":"uint256","name":"vote","type":"uint256"},{"indexed":false,"internalType":"contract IERC20","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"}],"name":"VoteEmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"abstainVotingPower","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"yesVotingPower","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"noVotingPower","type":"uint256"}],"name":"YesWins","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":true,"inputs":[],"name":"COUNT_CHOICES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_MAXMOVESTOVOTINGALLOWED","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MIN_MAXMOVESTOVOTINGALLOWED","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MIN_STATUS_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MIN_THRESHOLD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"},{"internalType":"address","name":"_voter","type":"address"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"bytes32","name":"_paramsHashByVoter","type":"bytes32"}],"name":"cancelVoteByRelayer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"}],"name":"cancelVoteByVoter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"},{"internalType":"address[]","name":"_voters","type":"address[]"}],"name":"challengeVoters","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getGovParamsProvider","outputs":[{"internalType":"address","name":"_govParamsProvider","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"}],"name":"getLeadingChoice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"}],"name":"getLimitBlockOfProposal","outputs":[{"internalType":"uint256","name":"_limitBlockProposal","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"}],"name":"getProposalBasicData","outputs":[{"internalType":"uint256","name":"_totalVotes","type":"uint256"},{"internalType":"uint256","name":"_threshold","type":"uint256"},{"internalType":"uint256","name":"_maxMovesToVotingAllowed","type":"uint256"},{"internalType":"uint256","name":"_movesToVoting","type":"uint256"},{"internalType":"uint256","name":"_votingBlocksDuration","type":"uint256"},{"internalType":"uint256","name":"_validatingBlocksDuration","type":"uint256"},{"internalType":"uint256","name":"_currentStatusInitBlock","type":"uint256"},{"internalType":"uint256","name":"_initProposalBlock","type":"uint256"},{"internalType":"uint256","name":"_proposalStatus","type":"uint256"},{"internalType":"address","name":"_proposalExecutor","type":"address"},{"internalType":"bytes32","name":"_proposalType","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"},{"internalType":"address","name":"_voterAddress","type":"address"}],"name":"getVoterData","outputs":[{"internalType":"uint256","name":"_vote","type":"uint256"},{"internalType":"uint256","name":"_weight","type":"uint256"},{"internalType":"uint256","name":"_balance","type":"uint256"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"contract IERC20","name":"_asset","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"}],"name":"getVotesData","outputs":[{"internalType":"uint256[3]","name":"","type":"uint256[3]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"_proposalType","type":"bytes32"},{"internalType":"bytes32","name":"_ipfsHash","type":"bytes32"},{"internalType":"uint256","name":"_threshold","type":"uint256"},{"internalType":"address","name":"_proposalExecutor","type":"address"},{"internalType":"uint256","name":"_votingBlocksDuration","type":"uint256"},{"internalType":"uint256","name":"_validatingBlocksDuration","type":"uint256"},{"internalType":"uint256","name":"_maxMovesToVotingAllowed","type":"uint256"}],"name":"newProposal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"}],"name":"resolveProposal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"},{"internalType":"uint256","name":"_vote","type":"uint256"},{"internalType":"address","name":"_voter","type":"address"},{"internalType":"contract IERC20","name":"_asset","type":"address"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"bytes32","name":"_paramsHashByVoter","type":"bytes32"}],"name":"submitVoteByRelayer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"},{"internalType":"uint256","name":"_vote","type":"uint256"},{"internalType":"contract IERC20","name":"_asset","type":"address"}],"name":"submitVoteByVoter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"}],"name":"tryToMoveToValidating","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_paramsHashByRelayer","type":"bytes32"},{"internalType":"bytes32","name":"_paramsHashBySigner","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"address","name":"_signer","type":"address"},{"internalType":"uint256","name":"_proposalId","type":"uint256"},{"internalType":"uint256","name":"_relayerNonce","type":"uint256"}],"name":"validateRelayAction","outputs":[],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"},{"internalType":"address","name":"_voter","type":"address"},{"internalType":"uint256","name":"_relayerNonce","type":"uint256"}],"name":"verifyNonce","outputs":[],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_paramsHashByRelayer","type":"bytes32"},{"internalType":"bytes32","name":"_paramsHashBySigner","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"address","name":"_signer","type":"address"}],"name":"verifyParamsConsistencyAndSignature","outputs":[],"payable":false,"stateMutability":"pure","type":"function"}], - "bytecode": "608060405234801561001057600080fd5b5060405161297f38038061297f8339818101604052602081101561003357600080fd5b5051600080546001600160a01b039092166001600160a01b031990921691909117905561291a806100656000396000f3fe6080604052600436106101345760003560e01c806374bdbd65116100ab578063a756dabd1161006f578063a756dabd14610700578063b6378279146106eb578063bd11c4c014610762578063e084548c14610777578063e3225c801461078c578063f50a990d1461083357610134565b806374bdbd65146105315780637f5dfabb146105f957806384cf33701461062a578063930d618f146106c157806395b90e37146106eb57610134565b806321d973b3116100fd57806321d973b3146102c657806335c8d82b146102f0578063413458851461035d5780634ffb44211461042e578063536114d3146104b057806356edd5fc1461050757610134565b806262804e14610181578063041eefb8146101ad5780630af70dc6146101d457806310e4e1ea146101fe578063171d5a0e1461023d575b6040805162461bcd60e51b815260206004820152601860248201527f4554485f5452414e534645525f4e4f545f414c4c4f5745440000000000000000604482015290519081900360640190fd5b34801561018d57600080fd5b506101ab600480360360208110156101a457600080fd5b5035610872565b005b3480156101b957600080fd5b506101c2610c54565b60408051918252519081900360200190f35b3480156101e057600080fd5b506101ab600480360360208110156101f757600080fd5b5035610c5a565b34801561020a57600080fd5b506101ab6004803603606081101561022157600080fd5b508035906001600160a01b036020820135169060400135610d47565b34801561024957600080fd5b506102676004803603602081101561026057600080fd5b5035610de0565b604080519b8c5260208c019a909a528a8a019890985260608a0196909652608089019490945260a088019290925260c087015260e08601526101008501526001600160a01b031661012084015261014083015251908190036101600190f35b3480156102d257600080fd5b506101c2600480360360208110156102e957600080fd5b5035610ee1565b3480156102fc57600080fd5b506103296004803603604081101561031357600080fd5b50803590602001356001600160a01b0316610f54565b6040805195865260208601949094528484019290925260608401526001600160a01b03166080830152519081900360a00190f35b34801561036957600080fd5b506101ab600480360360c081101561038057600080fd5b813591602081013591810190606081016040820135600160201b8111156103a657600080fd5b8201836020820111156103b857600080fd5b803590602001918460018302840111600160201b831117156103d957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550506001600160a01b03833516935050506020810135906040013561100e565b34801561043a57600080fd5b506101ab6004803603604081101561045157600080fd5b81359190810190604081016020820135600160201b81111561047257600080fd5b82018360208201111561048457600080fd5b803590602001918460208302840111600160201b831117156104a557600080fd5b50909250905061102d565b3480156104bc57600080fd5b506101ab600480360360e08110156104d357600080fd5b508035906020810135906040810135906001600160a01b036060820135169060808101359060a08101359060c00135611217565b34801561051357600080fd5b506101c26004803603602081101561052a57600080fd5b503561174e565b34801561053d57600080fd5b506101ab6004803603608081101561055457600080fd5b813591602081013591810190606081016040820135600160201b81111561057a57600080fd5b82018360208201111561058c57600080fd5b803590602001918460018302840111600160201b831117156105ad57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550505090356001600160a01b0316915061186a9050565b34801561060557600080fd5b5061060e611928565b604080516001600160a01b039092168252519081900360200190f35b34801561063657600080fd5b506101ab600480360360a081101561064d57600080fd5b8135916001600160a01b036020820135169160408201359190810190608081016060820135600160201b81111561068357600080fd5b82018360208201111561069557600080fd5b803590602001918460018302840111600160201b831117156106b657600080fd5b919350915035611937565b3480156106cd57600080fd5b506101ab600480360360208110156106e457600080fd5b5035611a63565b3480156106f757600080fd5b506101c2611af5565b34801561070c57600080fd5b5061072a6004803603602081101561072357600080fd5b5035611afa565b6040518082606080838360005b8381101561074f578181015183820152602001610737565b5050505090500191505060405180910390f35b34801561076e57600080fd5b506101c2611bb9565b34801561078357600080fd5b506101c2611bc8565b34801561079857600080fd5b506101ab600480360360e08110156107af57600080fd5b8135916020810135916001600160a01b0360408301358116926060810135909116916080820135919081019060c0810160a0820135600160201b8111156107f557600080fd5b82018360208201111561080757600080fd5b803590602001918460018302840111600160201b8311171561082857600080fd5b919350915035611bcd565b34801561083f57600080fd5b506101ab6004803603606081101561085657600080fd5b50803590602081013590604001356001600160a01b0316611c7a565b60006001828154811061088157fe5b60009182526020909120600c9091020190506002600b820154600160a01b900460ff1660038111156108af57fe5b14610901576040805162461bcd60e51b815260206004820152601a60248201527f56414c49444154494e475f5354415455535f5245515549524544000000000000604482015290519081900360640190fd5b4361091d82600601548360070154611c8690919063ffffffff16565b1115610970576040805162461bcd60e51b815260206004820152601f60248201527f4e4f545f454e4f5547485f424c4f434b535f494e5f56414c49444154494e4700604482015290519081900360640190fd5b4361098e61097d8461174e565b60088401549063ffffffff611c8616565b10156109e1576040805162461bcd60e51b815260206004820152601e60248201527f424c4f434b5f41424f56455f5448455f50524f504f53414c5f4c494d49540000604482015290519081900360640190fd5b60006109ec83610ee1565b90508060011415610b6b57600b82015460408051600481526024810182526020810180516001600160e01b0316631851865560e21b178152915181516000946001600160a01b03169382918083835b60208310610a5a5780518252601f199092019160209182019101610a3b565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d8060008114610aba576040519150601f19603f3d011682016040523d82523d6000602084013e610abf565b606091505b5050905080610aff5760405162461bcd60e51b815260040180806020018281038252602881526020018061285a6028913960400191505060405180910390fd5b60008080526009840160209081526040808320546001845281842054600285529382902054825191825292810193909352828101919091525185917fa65c460aee4c380a62df353a9ed1b66e2102476758bae694409bed898256f6d6919081900360600190a250610c46565b8060021415610bdf5760008080526009830160209081526040808320546001845281842054600285529382902054825191825292810193909352828101919091525184917f4c9e7215c9b6007a281dce14d5f17eccaac0018e27a7794d16bd18e689aea7b8919081900360600190a2610c46565b60008080526009830160209081526040808320546001845281842054600285529382902054825191825292810193909352828101919091525184917f15faeac063b69950ec8db10c98c8a568e9299e16f0597f37a7f97d9f6c9ce275919081900360600190a25b610c4f83611ce9565b505050565b61067c81565b600060018281548110610c6957fe5b60009182526020909120600c9091020190506001600b820154600160a01b900460ff166003811115610c9757fe5b14610ce2576040805162461bcd60e51b81526020600482015260166024820152751593d5125391d7d4d510551554d7d49154555254915160521b604482015290519081900360640190fd5b43610cfe82600501548360070154611c8690919063ffffffff16565b11610d425760005b60028111610c4f57600282015460008281526009840160205260409020541115610d3a57610d3383611d4c565b5050610d44565b600101610d06565b505b50565b600060018481548110610d5657fe5b600091825260208083206001600160a01b0387168452600a600c9093020191820190526040909120600301549091508290610d9890600163ffffffff611c8616565b14610dda576040805162461bcd60e51b815260206004820152600d60248201526c494e56414c49445f4e4f4e434560981b604482015290519081900360640190fd5b50505050565b60008060008060008060008060008060006001805490508c10610e40576040805162461bcd60e51b81526020600482015260136024820152721253959053125117d41493d413d4d05317d251606a1b604482015290519081900360640190fd5b600060018d81548110610e4f57fe5b90600052602060002090600c0201905080600101549b5080600201549a5080600301549950806004015498508060050154975080600601549650806007015495508060080154945080600b0160149054906101000a900460ff166003811115610eb457fe5b600b82015491549c9e9b9d50999b989a9799969895979496956001600160a01b0390911694909350915050565b6001805460009182918291829186908110610ef857fe5b600091825260208220600c9091020191505b60028111610f4a576000818152600983016020526040902054831015610f425760008181526009830160205260409020549093509150825b600101610f0a565b5091949350505050565b60008060008060006001805490508710610fab576040805162461bcd60e51b81526020600482015260136024820152721253959053125117d41493d413d4d05317d251606a1b604482015290519081900360640190fd5b600060018881548110610fba57fe5b600091825260208083206001600160a01b039a8b168452600a600c90930201919091019052604090208054600182015460028301546003840154600490940154929c919b5099929850911695509350505050565b61101a8686868661186a565b611025828483610d47565b505050505050565b60006001848154811061103c57fe5b60009182526020909120600c9091020190506002600b820154600160a01b900460ff16600381111561106a57fe5b146110bc576040805162461bcd60e51b815260206004820152601a60248201527f56414c49444154494e475f5354415455535f5245515549524544000000000000604482015290519081900360640190fd5b60005b828110156111d15760008484838181106110d557fe5b905060200201356001600160a01b031690506110ef612793565b506001600160a01b038082166000818152600a860160209081526040808320815160a08101835281548152600182015481850152600282015481840152600382015460608201526004918201549096166080870181905282516370a0823160e01b81529182019590955290519293926370a0823192602480840193919291829003018186803b15801561118157600080fd5b505afa158015611195573d6000803e3d6000fd5b505050506040513d60208110156111ab57600080fd5b505160408301519091508110156111c6576111c68884611db5565b5050506001016110bf565b5080600301548160040154108015611209575080600201548160090160006111f887610ee1565b815260200190815260200160002054105b15610dda57610dda84611fbf565b60008060009054906101000a90046001600160a01b03166001600160a01b0316635b5dde096040518163ffffffff1660e01b815260040160206040518083038186803b15801561126657600080fd5b505afa15801561127a573d6000803e3d6000fd5b505050506040513d602081101561129057600080fd5b5051604080516370a0823160e01b815233600482015290519192506000916001600160a01b038416916370a08231916024808301926020929190829003018186803b1580156112de57600080fd5b505afa1580156112f2573d6000803e3d6000fd5b505050506040513d602081101561130857600080fd5b5051604080516318160ddd60e01b815290519192506000916001600160a01b038516916318160ddd916004808301926020929190829003018186803b15801561135057600080fd5b505afa158015611364573d6000803e3d6000fd5b505050506040513d602081101561137a57600080fd5b50519050801580159061140b57506000546040805163e34efd1360e01b81529051611407926001600160a01b03169163e34efd13916004808301926020929190829003018186803b1580156113ce57600080fd5b505afa1580156113e2573d6000803e3d6000fd5b505050506040513d60208110156113f857600080fd5b5051829063ffffffff61204216565b8210155b6114465760405162461bcd60e51b81526004018080602001828103825260218152602001806128a46021913960400191505060405180910390fd5b6a0ac0db698068112d00000088101561149a576040805162461bcd60e51b81526020600482015260116024820152701253959053125117d512149154d213d311607a1b604482015290519081900360640190fd5b61067c8610156114f1576040805162461bcd60e51b815260206004820152601e60248201527f494e56414c49445f564f54494e475f424c4f434b535f4455524154494f4e0000604482015290519081900360640190fd5b61067c8510156115325760405162461bcd60e51b81526004018080602001828103825260228152602001806128826022913960400191505060405180910390fd5b60028410158015611544575060068411155b611595576040805162461bcd60e51b815260206004820152601f60248201527f494e56414c49445f4d4158564f544553544f564f54494e47414c4c4f57454400604482015290519081900360640190fd5b5060006116d36001806040518061016001604052808e8152602001600081526020018c8152602001888152602001600081526020018a8152602001898152602001600081526020014381526020018b6001600160a01b03168152602001600060038111156115ff57fe5b90528154600180820180855560009485526020948590208451600c9094020192835593830151908201556040820151600282015560608201516003808301919091556080830151600483015560a0830151600583015560c0830151600683015560e083015160078301556101008301516008830155610120830151600b830180546001600160a01b0319166001600160a01b03909216919091178082556101408501519260ff60a01b1990911690600160a01b9084908111156116be57fe5b0217905550505061208490919063ffffffff16565b90506116de81611fbf565b60408051838152602081018a905280820186905260608101889052608081018790526001600160a01b03891660a082015290518b918b9184917ff68283294f55d335beffa2276101625cd0340307b84533867c183216b136343b919081900360c00190a450505050505050505050565b60006117586127cb565b6001838154811061176557fe5b60009182526020918290206040805161016081018252600c9390930290910180548352600181015493830193909352600283015490820152600380830154606083015260048301546080830152600583015460a0830152600683015460c0830152600783015460e08301526008830154610100830152600b8301546001600160a01b038116610120840152919291610140840191600160a01b90910460ff169081111561180e57fe5b600381111561181957fe5b905250606081015160a082015160c08301519293509091611860611843838363ffffffff611c8616565b61185485600263ffffffff6120c616565b9063ffffffff6120c616565b9695505050505050565b8383146118b4576040805162461bcd60e51b8152602060048201526013602482015272494e434f4e53495354454e545f48415348455360681b604482015290519081900360640190fd5b6118cd826118c18661211f565b9063ffffffff61217016565b6001600160a01b0316816001600160a01b031614610dda576040805162461bcd60e51b815260206004820152601360248201527214d251d3905515549157d393d517d590531251606a1b604482015290519081900360640190fd5b6000546001600160a01b031690565b60006001878154811061194657fe5b60009182526020909120600c9091020190506001600b820154600160a01b900460ff16600381111561197457fe5b146119bf576040805162461bcd60e51b81526020600482015260166024820152751593d5125391d7d4d510551554d7d49154555254915160521b604482015290519081900360640190fd5b611a5087878760405160200180848152602001836001600160a01b03166001600160a01b031660601b81526014018281526020019350505050604051602081830303815290604052805190602001208386868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508d91508b905061100e565b611a5a8787611db5565b50505050505050565b600060018281548110611a7257fe5b60009182526020909120600c9091020190506001600b820154600160a01b900460ff166003811115611aa057fe5b14611aeb576040805162461bcd60e51b81526020600482015260166024820152751593d5125391d7d4d510551554d7d49154555254915160521b604482015290519081900360640190fd5b610d428233611db5565b600281565b611b0261283b565b6001548210611b4e576040805162461bcd60e51b81526020600482015260136024820152721253959053125117d41493d413d4d05317d251606a1b604482015290519081900360640190fd5b600060018381548110611b5d57fe5b90600052602060002090600c02019050611b7561283b565b506040805160608101825260008080526009909301602081815283852054835260018552818152838520548184015260028552529181902054908201529050919050565b6a0ac0db698068112d00000081565b600681565b6040805160208082018b90528183018a90526bffffffffffffffffffffffff1960608a811b82168185015289901b16607483015260888083018890528351808403909101815260a8830180855281519183019190912060c8601f880184900490930284018301909452858152611c6493928592889188918291018382808284376000920191909152508c92508e91508a905061100e565b611c708888888861225e565b5050505050505050565b610c4f8383338461225e565b600082820183811015611ce0576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b600060018281548110611cf857fe5b600091825260208220600c9190910201600b8101805460ff60a01b1916600360a01b17905560405190925083917fecbe1d528d9a7b9ff78109bfe65997ebe88e813b60860e4682c062883cb5779b91a25050565b600060018281548110611d5b57fe5b600091825260208220600c9190910201600b8101805460ff60a01b1916600160a11b17905543600782015560405190925083917f08a373264519a296dfcb116cef45dd6e6fd4422565d846d525924d23a7f6c75891a25050565b600060018381548110611dc457fe5b600091825260208083206001600160a01b0386168452600a600c9093020191820190526040909120909150611df7612793565b506040805160a081018252825481526001830154602082015260028301549181018290526003830154606082015260048301546001600160a01b0316608082015290611e7f576040805162461bcd60e51b8152602060048201526012602482015271564f5445525f574954484f55545f564f544560701b604482015290519081900360640190fd5b611ebc611e9d826020015183604001516120c690919063ffffffff16565b825160009081526009860160205260409020549063ffffffff61208416565b81516000908152600985016020526040902055600180840154611ee49163ffffffff61208416565b60018085019190915560008382018190556002840181905583556004830180546001600160a01b03191690556003830154611f249163ffffffff611c8616565b82600301819055508060000151846001600160a01b0316867ffa0eb68751ea3cd5ba311003baf3c8a48524ee47676479df02a869142cb6003684608001518560200151866040015189600b0160149054906101000a900460ff166003811115611f8957fe5b604080516001600160a01b0390951685526020850193909352838301919091526060830152519081900360800190a45050505050565b600060018281548110611fce57fe5b6000918252602091829020600c9190910201600b8101805460ff60a01b1916600160a01b17905543600782015560048101805460010190819055604080519182525191935084927f6e4d591698545ecee458f7ccfbfbfdeaafe973315c321ad749a92c4e77cc734192918290030190a25050565b6000611ce083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612697565b6000611ce083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612739565b6000826120d557506000611ce3565b828202828482816120e257fe5b0414611ce05760405162461bcd60e51b81526004018080602001828103825260218152602001806128c56021913960400191505060405180910390fd5b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c8083019490945282518083039094018452605c909101909152815191012090565b6000815160411461218357506000611ce3565b60208201516040830151606084015160001a7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08211156121c95760009350505050611ce3565b8060ff16601b141580156121e157508060ff16601c14155b156121f25760009350505050611ce3565b6040805160008152602080820180845289905260ff8416828401526060820186905260808201859052915160019260a0808401939192601f1981019281900390910190855afa158015612249573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b60006001858154811061226d57fe5b60009182526020909120600c9091020190506001600b820154600160a01b900460ff16600381111561229b57fe5b146122e6576040805162461bcd60e51b81526020600482015260166024820152751593d5125391d7d4d510551554d7d49154555254915160521b604482015290519081900360640190fd5b60008060009054906101000a90046001600160a01b03166001600160a01b03166390139aa56040518163ffffffff1660e01b815260040160206040518083038186803b15801561233557600080fd5b505afa158015612349573d6000803e3d6000fd5b505050506040513d602081101561235f57600080fd5b50516040805163d5da24b960e01b81526001600160a01b0386811660048301529151919092169163d5da24b9916024808301926020929190829003018186803b1580156123ab57600080fd5b505afa1580156123bf573d6000803e3d6000fd5b505050506040513d60208110156123d557600080fd5b505190508061241e576040805162461bcd60e51b815260206004820152601060248201526f1054d4d15517d393d517d31254d5115160821b604482015290519081900360640190fd5b6002851115612469576040805162461bcd60e51b8152602060048201526012602482015271494e56414c49445f564f54455f504152414d60701b604482015290519081900360640190fd5b6000836001600160a01b03166370a08231866040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156124c157600080fd5b505afa1580156124d5573d6000803e3d6000fd5b505050506040513d60208110156124eb57600080fd5b5051905080612539576040805162461bcd60e51b8152602060048201526015602482015274494e56414c49445f564f5445525f42414c414e434560581b604482015290519081900360640190fd5b6001600160a01b038581166000908152600a850160205260409020600401541615612568576125688786611db5565b81600061257b838363ffffffff6120c616565b905061259560018660010154611c8690919063ffffffff16565b600186015560008881526009860160205260409020546125bc90829063ffffffff611c8616565b60008981526009870160209081526040808320939093556001600160a01b038a81168352600a89019091529190208981556001808201859055600282018690556004820180546001600160a01b031916938a1693909317909255600381015490916126279190611c86565b60038201556004810154604080516001600160a01b0392831681526020810186905280820187905290518b928b16918d917f22d7233cae586bf1a5a105bb4fce0c4342f59d450b5933aadf5cedceeb608c869181900360600190a461268b8a610c5a565b50505050505050505050565b600081836127235760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156126e85781810151838201526020016126d0565b50505050905090810190601f1680156127155780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161272f57fe5b0495945050505050565b6000818484111561278b5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156126e85781810151838201526020016126d0565b505050900390565b6040518060a001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b031681525090565b60405180610160016040528060008019168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160006001600160a01b031681526020016000600381111561283657fe5b905290565b6040518060600160405280600390602082028038833950919291505056fe7265736f6c766550726f706f73616c28292e2044454c454741544543414c4c5f5245564552544544494e56414c49445f56414c49444154494e475f424c4f434b535f4455524154494f4e494e56414c49445f50524f504f534954494f4e5f504f5745525f42414c414e4345536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a265627a7a723158207a006931ac06a1223364d839e150875a58ab9b25960cb8fa59449d6035a35f0f64736f6c63430005100032", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/external/abi/aave/v1/AssetVotingWeightProvider.json b/external/abi/aave/v1/AssetVotingWeightProvider.json deleted file mode 100644 index 90e0cce55..000000000 --- a/external/abi/aave/v1/AssetVotingWeightProvider.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "contractName": "AssetVotingWeightProvider", - "abi": [{"inputs":[{"internalType":"contract IERC20[]","name":"_assets","type":"address[]"},{"internalType":"uint256[]","name":"_weights","type":"uint256[]"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"}],"name":"AssetWeightSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"constant":true,"inputs":[{"internalType":"contract IERC20","name":"_asset","type":"address"}],"name":"getVotingWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IERC20","name":"_asset","type":"address"},{"internalType":"uint256","name":"_weight","type":"uint256"}],"name":"setVotingWeight","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}], - "bytecode": "608060405234801561001057600080fd5b506040516107103803806107108339818101604052604081101561003357600080fd5b810190808051604051939291908464010000000082111561005357600080fd5b90830190602082018581111561006857600080fd5b825186602082028301116401000000008211171561008557600080fd5b82525081516020918201928201910280838360005b838110156100b257818101518382015260200161009a565b50505050905001604052602001805160405193929190846401000000008211156100db57600080fd5b9083019060208201858111156100f057600080fd5b825186602082028301116401000000008211171561010d57600080fd5b82525081516020918201928201910280838360005b8381101561013a578181015183820152602001610122565b5050505090500160405250505061015561022f60201b60201c565b600080546001600160a01b0319166001600160a01b03928316178082556040519216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a380518251146101dd5760405162461bcd60e51b81526004018080602001828103825260238152602001806106ed6023913960400191505060405180910390fd5b60005b82518110156102275761021f8382815181106101f857fe5b602002602001015183838151811061020c57fe5b602002602001015161023360201b60201c565b6001016101e0565b50505061028d565b3390565b6001600160a01b038216600081815260016020908152604091829020849055815184815291518593339390927fea070de9b64227267bd12bc54ab3d30a654644fda63df67be21d38861f5b5d7d92918290030190a3505050565b6104518061029c6000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c80634289cefe14610067578063715018a6146100955780638da5cb5b1461009d5780638f32d59b146100c1578063d5da24b9146100dd578063f2fde38b14610115575b600080fd5b6100936004803603604081101561007d57600080fd5b506001600160a01b03813516906020013561013b565b005b6100936101a2565b6100a5610245565b604080516001600160a01b039092168252519081900360200190f35b6100c9610254565b604080519115158252519081900360200190f35b610103600480360360208110156100f357600080fd5b50356001600160a01b0316610278565b60408051918252519081900360200190f35b6100936004803603602081101561012b57600080fd5b50356001600160a01b0316610293565b610143610254565b610194576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b61019e82826102f8565b5050565b6101aa610254565b6101fb576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b600080546001600160a01b0316610269610352565b6001600160a01b031614905090565b6001600160a01b031660009081526001602052604090205490565b61029b610254565b6102ec576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6102f581610356565b50565b6001600160a01b038216600081815260016020908152604091829020849055815184815291518593339390927fea070de9b64227267bd12bc54ab3d30a654644fda63df67be21d38861f5b5d7d92918290030190a3505050565b3390565b6001600160a01b03811661039b5760405162461bcd60e51b81526004018080602001828103825260268152602001806103f76026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b039290921691909117905556fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373a265627a7a7231582039a0313f5101d0a478422e1933b4b31b41dfffee8d5f2d2743f8120011913c7464736f6c63430005100032494e434f4e53495354454e545f4153534554535f574549474854535f4c454e47544853", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/external/abi/aave/v1/CoreLibrary.json b/external/abi/aave/v1/CoreLibrary.json deleted file mode 100644 index 045b740f2..000000000 --- a/external/abi/aave/v1/CoreLibrary.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "contractName": "CoreLibrary", - "abi": [{"inputs":[{"internalType":"address","name":"_self","type":"address"},{"internalType":"address","name":"_aTokenAddress","type":"address"},{"internalType":"uint256","name":"_decimals","type":"uint256"},{"internalType":"address","name":"_interestRateStrategyAddress","type":"address"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"}], - "bytecode": "0x610409610026600b82828239805160001a60731461001957fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100615760003560e01c806313769cd41461006657806324ddc4e6146100b157806383c165a0146100ed578063e5df56a614610117578063f63babbe14610141575b600080fd5b81801561007257600080fd5b506100af6004803603608081101561008957600080fd5b508035906001600160a01b03602082013581169160408101359160609091013516610173565b005b8180156100bd57600080fd5b506100af600480360360808110156100d457600080fd5b508035906020810135906040810135906060013561023a565b8180156100f957600080fd5b506100af6004803603602081101561011057600080fd5b50356102c6565b81801561012357600080fd5b506100af6004803603602081101561013a57600080fd5b50356102d6565b81801561014d57600080fd5b506100af6004803603604081101561016457600080fd5b508035906020013515156102e6565b600c8401546001600160a01b0316156101bd5760405162461bcd60e51b81526004018080602001828103825260248152602001806103896024913960400191505060405180910390fd5b83546101ce576101cb610378565b84555b60078401546101e5576101df610378565b60078501555b600c840180546001600160a01b039485166001600160a01b031991821617909155600b850192909255600d909301805460ff60e81b1960ff60e01b199590941692169190911792909216600160e01b17169055565b600d840154600160d01b900460ff16156102855760405162461bcd60e51b81526004018080602001828103825260288152602001806103ad6028913960400191505060405180910390fd5b600d8401805460ff60d01b1916600160d01b1790556008840183905560098401829055600a840181905583546102c0576102bd610378565b84555b50505050565b600d01805460ff60d01b19169055565b600d01805460ff60c81b19169055565b600d820154600160c81b900460ff1615610347576040805162461bcd60e51b815260206004820152601a60248201527f5265736572766520697320616c726561647920656e61626c6564000000000000604482015290519081900360640190fd5b600d9091018054911515600160d81b0260ff60d81b1960ff60c81b19909316600160c81b1792909216919091179055565b6b033b2e3c9fd0803ce80000009056fe526573657276652068617320616c7265616479206265656e20696e697469616c697a65645265736572766520697320616c726561647920656e61626c656420617320636f6c6c61746572616ca265627a7a7231582070416aed08de1fec4e7786e531829a810ea9ac146c0b379887cf25ce8016842264736f6c634300050e0032", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/external/abi/aave/v1/DefaultReserveInterestRateStrategy.json b/external/abi/aave/v1/DefaultReserveInterestRateStrategy.json deleted file mode 100644 index e0a7fc382..000000000 --- a/external/abi/aave/v1/DefaultReserveInterestRateStrategy.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "contractName": "DefaultReserveInterestRateStrategy", - "abi": [{"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"contract LendingPoolAddressesProvider","name":"_provider","type":"address"},{"internalType":"uint256","name":"_baseVariableBorrowRate","type":"uint256"},{"internalType":"uint256","name":"_variableRateSlope1","type":"uint256"},{"internalType":"uint256","name":"_variableRateSlope2","type":"uint256"},{"internalType":"uint256","name":"_stableRateSlope1","type":"uint256"},{"internalType":"uint256","name":"_stableRateSlope2","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"constant":true,"inputs":[],"name":"EXCESS_UTILIZATION_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"OPTIMAL_UTILIZATION_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"addressesProvider","outputs":[{"internalType":"contract LendingPoolAddressesProvider","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"baseVariableBorrowRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"reserve","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"stableRateSlope1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"stableRateSlope2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"variableRateSlope1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"variableRateSlope2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBaseVariableBorrowRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getVariableRateSlope1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getVariableRateSlope2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getStableRateSlope1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getStableRateSlope2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint256","name":"_availableLiquidity","type":"uint256"},{"internalType":"uint256","name":"_totalBorrowsStable","type":"uint256"},{"internalType":"uint256","name":"_totalBorrowsVariable","type":"uint256"},{"internalType":"uint256","name":"_averageStableBorrowRate","type":"uint256"}],"name":"calculateInterestRates","outputs":[{"internalType":"uint256","name":"currentLiquidityRate","type":"uint256"},{"internalType":"uint256","name":"currentStableBorrowRate","type":"uint256"},{"internalType":"uint256","name":"currentVariableBorrowRate","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}], - "bytecode": "0x608060405234801561001057600080fd5b5060405161089e38038061089e833981810160405260e081101561003357600080fd5b508051602082015160408301516060840151608085015160a086015160c090960151600080546001600160a01b039687166001600160a01b031991821617909155600194909455600292909255600355600494909455600593909355600680549190921692169190911790556107f0806100ae6000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80637b832f5811610097578063ccab01a311610066578063ccab01a3146101d4578063cd3293de146101dc578063d5cd7391146101e4578063f4202409146101ec576100f5565b80637b832f5814610198578063a15f30ac146101a0578063b2589544146101a8578063c72c4d10146101b0576100f5565b806317319873116100d3578063173198731461012457806334762ca51461012c57806357e37af01461013457806365614f8114610190576100f5565b80630b3429a2146100fa5780630bdf953f1461011457806314e32da41461011c575b600080fd5b6101026101f4565b60408051918252519081900360200190f35b6101026101fa565b610102610200565b610102610206565b610102610215565b610172600480360360a081101561014a57600080fd5b506001600160a01b03813516906020810135906040810135906060810135906080013561021b565b60408051938452602084019290925282820152519081900360600190f35b6101026104c2565b6101026104c8565b6101026104ce565b6101026104de565b6101b86104e4565b604080516001600160a01b039092168252519081900360200190f35b6101026104f3565b6101b86104f9565b610102610508565b61010261050e565b60025490565b60045481565b60055490565b6aa56fa5b99019a5c800000081565b60015490565b6000808080610230878763ffffffff61051416565b9050600081158015610240575088155b610269576102646102578a8463ffffffff61051416565b839063ffffffff61057716565b61026c565b60005b90506000809054906101000a90046001600160a01b03166001600160a01b0316633618abba6040518163ffffffff1660e01b815260040160206040518083038186803b1580156102bb57600080fd5b505afa1580156102cf573d6000803e3d6000fd5b505050506040513d60208110156102e557600080fd5b50516040805163bb85c0bb60e01b81526001600160a01b038d811660048301529151919092169163bb85c0bb916024808301926020929190829003018186803b15801561033157600080fd5b505afa158015610345573d6000803e3d6000fd5b505050506040513d602081101561035b57600080fd5b505193506b0295be96e64066972000000081111561041d5760006103ac6aa56fa5b99019a5c80000006103a0846b0295be96e64066972000000063ffffffff6105bb16565b9063ffffffff61057716565b90506103e66103c68260055461061890919063ffffffff16565b6004546103da90889063ffffffff61051416565b9063ffffffff61051416565b94506104156104008260035461061890919063ffffffff16565b6002546001546103da9163ffffffff61051416565b9350506104a3565b61045b61044e61043f836b0295be96e64066972000000063ffffffff61057716565b6004549063ffffffff61061816565b859063ffffffff61051416565b93506104a06104916002546104856b0295be96e6406697200000008561057790919063ffffffff16565b9063ffffffff61061816565b6001549063ffffffff61051416565b92505b6104b3816104858a8a878b610650565b94505050955095509592505050565b60035481565b60025481565b6b0295be96e64066972000000081565b60015481565b6000546001600160a01b031681565b60055481565b6006546001600160a01b031681565b60045490565b60035490565b60008282018381101561056e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b6000600282046105b3836105a761059a876b033b2e3c9fd0803ce80000006106c1565b849063ffffffff61051416565b9063ffffffff61071a16565b949350505050565b600082821115610612576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600061056e6b033b2e3c9fd0803ce80000006105a761063d868663ffffffff6106c116565b6b019d971e4fe8401e7400000090610514565b600080610663868663ffffffff61051416565b9050806106745760009150506105b3565b60006106838561048588610784565b90506000610694856104858a610784565b905060006106b46106a485610784565b6103a0858563ffffffff61051416565b9998505050505050505050565b6000826106d057506000610571565b828202828482816106dd57fe5b041461056e5760405162461bcd60e51b815260040180806020018281038252602181526020018061079b6021913960400191505060405180910390fd5b6000808211610770576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b600082848161077b57fe5b04949350505050565b600061057182633b9aca0063ffffffff6106c11656fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a265627a7a723158209a00ba4734293b2ad6598b400aabba3c27d51137f2c71140ffba31ee280f5b3064736f6c634300050e0032", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/external/abi/aave/v1/GovernanceParamsProvider.json b/external/abi/aave/v1/GovernanceParamsProvider.json deleted file mode 100644 index 840b06dd9..000000000 --- a/external/abi/aave/v1/GovernanceParamsProvider.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "contractName": "GovernanceParamsProvider", - "abi": [{"inputs":[{"internalType":"uint256","name":"_propositionPowerThreshold","type":"uint256"},{"internalType":"contract IERC20","name":"_propositionPower","type":"address"},{"internalType":"contract IAssetVotingWeightProvider","name":"_assetVotingWeightProvider","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":false,"internalType":"contract IAssetVotingWeightProvider","name":"assetVotingWeightProvider","type":"address"}],"name":"AssetVotingWeightProviderSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":false,"internalType":"contract IERC20","name":"propositionPower","type":"address"}],"name":"PropositionPowerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":false,"internalType":"uint256","name":"propositionPowerThreshold","type":"uint256"}],"name":"PropositionPowerThresholdSet","type":"event"},{"constant":true,"inputs":[],"name":"getAssetVotingWeightProvider","outputs":[{"internalType":"contract IAssetVotingWeightProvider","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getPropositionPower","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getPropositionPowerThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IAssetVotingWeightProvider","name":"_assetVotingWeightProvider","type":"address"}],"name":"setAssetVotingWeightProvider","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IERC20","name":"_propositionPower","type":"address"}],"name":"setPropositionPower","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_propositionPowerThreshold","type":"uint256"}],"name":"setPropositionPowerThreshold","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}], - "bytecode": "608060405234801561001057600080fd5b506040516107b63803806107b68339818101604052606081101561003357600080fd5b50805160208201516040909201519091906100556001600160e01b036100db16565b600080546001600160a01b0319166001600160a01b03928316178082556040519216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a36100af836001600160e01b036100df16565b6100c1826001600160e01b0361011d16565b6100d3816001600160e01b0361017416565b5050506101cb565b3390565b600281905560408051828152905133917f1017b0bc4a799ec60d107e72dab06a9e572d31446e438fb2b486337d0d5b11bb919081900360200190a250565b600380546001600160a01b0383166001600160a01b03199091168117909155604080519182525133917f52d9b921164120141b4d8c7808be8e2a7a253c8aef2fe33d57713a6736ed9e80919081900360200190a250565b600180546001600160a01b0383166001600160a01b03199091168117909155604080519182525133917f35edaeb30fa0649698eb6fe65394c8b3b8f751e144a069a4fa584b185d465623919081900360200190a250565b6105dc806101da6000396000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c80638f32d59b116100665780638f32d59b1461011c57806390139aa514610138578063e34efd1314610140578063eceea6551461015a578063f2fde38b146101805761009e565b80632d9b8eed146100a35780634069f3f0146100cb5780635b5dde09146100e8578063715018a61461010c5780638da5cb5b14610114575b600080fd5b6100c9600480360360208110156100b957600080fd5b50356001600160a01b03166101a6565b005b6100c9600480360360208110156100e157600080fd5b50356101f9565b6100f0610249565b604080516001600160a01b039092168252519081900360200190f35b6100c9610258565b6100f06102e9565b6101246102f8565b604080519115158252519081900360200190f35b6100f061031c565b61014861032b565b60408051918252519081900360200190f35b6100c96004803603602081101561017057600080fd5b50356001600160a01b0316610331565b6100c96004803603602081101561019657600080fd5b50356001600160a01b0316610381565b6101ae6102f8565b6101ed576040805162461bcd60e51b81526020600482018190526024820152600080516020610588833981519152604482015290519081900360640190fd5b6101f6816103d1565b50565b6102016102f8565b610240576040805162461bcd60e51b81526020600482018190526024820152600080516020610588833981519152604482015290519081900360640190fd5b6101f681610428565b6003546001600160a01b031690565b6102606102f8565b61029f576040805162461bcd60e51b81526020600482018190526024820152600080516020610588833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b600080546001600160a01b031661030d610466565b6001600160a01b031614905090565b6001546001600160a01b031690565b60025490565b6103396102f8565b610378576040805162461bcd60e51b81526020600482018190526024820152600080516020610588833981519152604482015290519081900360640190fd5b6101f68161046a565b6103896102f8565b6103c8576040805162461bcd60e51b81526020600482018190526024820152600080516020610588833981519152604482015290519081900360640190fd5b6101f6816104c1565b600180546001600160a01b0383166001600160a01b03199091168117909155604080519182525133917f35edaeb30fa0649698eb6fe65394c8b3b8f751e144a069a4fa584b185d465623919081900360200190a250565b600281905560408051828152905133917f1017b0bc4a799ec60d107e72dab06a9e572d31446e438fb2b486337d0d5b11bb919081900360200190a250565b3390565b600380546001600160a01b0383166001600160a01b03199091168117909155604080519182525133917f52d9b921164120141b4d8c7808be8e2a7a253c8aef2fe33d57713a6736ed9e80919081900360200190a250565b6001600160a01b0381166105065760405162461bcd60e51b81526004018080602001828103825260268152602001806105626026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b039290921691909117905556fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a265627a7a72315820d9259b74615ba854f5f671b47cb4116f9ccca7e84be3f4eaa16b5dac5adebb4864736f6c63430005100032", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/external/abi/aave/v1/LendToAaveMigrator.json b/external/abi/aave/v1/LendToAaveMigrator.json deleted file mode 100644 index e25f520b9..000000000 --- a/external/abi/aave/v1/LendToAaveMigrator.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "contractName": "LendToAaveMigrator", - "abi": [{"inputs":[{"internalType":"contract IERC20","name":"aave","type":"address"},{"internalType":"contract IERC20","name":"lend","type":"address"},{"internalType":"uint256","name":"lendAaveRatio","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LendMigrated","type":"event"},{"inputs":[],"name":"AAVE","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LEND","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LEND_AAVE_RATIO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REVISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_totalLendMigrated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"migrateFromLEND","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"migrationStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}], - "bytecode": "0x60e06040526000805534801561001457600080fd5b506040516106583803806106588339818101604052606081101561003757600080fd5b50805160208201516040909201516001600160601b0319606092831b81166080529290911b90911660a05260c05260805160601c60a05160601c60c0516105b26100a660003980610283528061035a5250806101d952806103e2525080610128528061025752506105b26000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80638129fc1c1161005b5780638129fc1c14610106578063abb76be81461010e578063dde43cba14610116578063f301e7811461011e57610088565b806348ccda3c1461008d578063682356c0146100b1578063685cda02146100d05780637c6e94e3146100ea575b600080fd5b610095610126565b604080516001600160a01b039092168252519081900360200190f35b6100ce600480360360208110156100c757600080fd5b503561014a565b005b6100d8610358565b60408051918252519081900360200190f35b6100f261037c565b604080519115158252519081900360200190f35b6100ce610384565b6100d86103d5565b6100d86103db565b6100956103e0565b7f000000000000000000000000000000000000000000000000000000000000000081565b600054610196576040805162461bcd60e51b8152602060048201526015602482015274135251d490551253d397d393d517d4d51054951151605a1b604482015290519081900360640190fd5b6033546101a9908263ffffffff61040416565b603355604080516323b872dd60e01b81523360048201523060248201526044810183905290516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916323b872dd9160648083019260209291908290030181600087803b15801561022157600080fd5b505af1158015610235573d6000803e3d6000fd5b505050506040513d602081101561024b57600080fd5b50506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663a9059cbb336102ad847f000000000000000000000000000000000000000000000000000000000000000063ffffffff61046516565b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156102fc57600080fd5b505af1158015610310573d6000803e3d6000fd5b505050506040513d602081101561032657600080fd5b5050604051819033907f5c5c7a8e729fa9bfdd1ecad2e8f7f3db1d29acf43c1e6036f34fd68621d15c8190600090a350565b7f000000000000000000000000000000000000000000000000000000000000000081565b600054151590565b600061038e6104a7565b905060005481116103d05760405162461bcd60e51b815260040180806020018281038252602e81526020018061054f602e913960400191505060405180910390fd5b600055565b60335481565b600181565b7f000000000000000000000000000000000000000000000000000000000000000081565b60008282018381101561045e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600061045e83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506104ac565b600190565b600081836105385760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156104fd5781810151838201526020016104e5565b50505050905090810190601f16801561052a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161054457fe5b049594505050505056fe436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564a2646970667358221220bb6825617f404e1c043bd709a3addce5a8e5b6aa5c223663afb236fdb8e3352a64736f6c634300060a0033", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/external/abi/aave/v1/LendingPool.json b/external/abi/aave/v1/LendingPool.json deleted file mode 100644 index 5e9e2c32f..000000000 --- a/external/abi/aave/v1/LendingPool.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "contractName": "LendingPool", - "abi": [{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reserve","type":"address"},{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_borrowRateMode","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_borrowRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_originationFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_borrowBalanceIncrease","type":"uint256"},{"indexed":true,"internalType":"uint16","name":"_referral","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"Borrow","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reserve","type":"address"},{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":true,"internalType":"uint16","name":"_referral","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_target","type":"address"},{"indexed":true,"internalType":"address","name":"_reserve","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_totalFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_protocolFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"FlashLoan","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_collateral","type":"address"},{"indexed":true,"internalType":"address","name":"_reserve","type":"address"},{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":false,"internalType":"uint256","name":"_purchaseAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_liquidatedCollateralAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_accruedBorrowInterest","type":"uint256"},{"indexed":false,"internalType":"address","name":"_liquidator","type":"address"},{"indexed":false,"internalType":"bool","name":"_receiveAToken","type":"bool"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"LiquidationCall","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_collateral","type":"address"},{"indexed":true,"internalType":"address","name":"_reserve","type":"address"},{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":false,"internalType":"uint256","name":"_feeLiquidated","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_liquidatedCollateralForFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"OriginationFeeLiquidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reserve","type":"address"},{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":false,"internalType":"uint256","name":"_newStableRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_borrowBalanceIncrease","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"RebalanceStableBorrowRate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reserve","type":"address"},{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"RedeemUnderlying","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reserve","type":"address"},{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":true,"internalType":"address","name":"_repayer","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amountMinusFees","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fees","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_borrowBalanceIncrease","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"Repay","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reserve","type":"address"},{"indexed":true,"internalType":"address","name":"_user","type":"address"}],"name":"ReserveUsedAsCollateralDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reserve","type":"address"},{"indexed":true,"internalType":"address","name":"_user","type":"address"}],"name":"ReserveUsedAsCollateralEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reserve","type":"address"},{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":false,"internalType":"uint256","name":"_newRateMode","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_borrowBalanceIncrease","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"Swap","type":"event"},{"constant":true,"inputs":[],"name":"LENDINGPOOL_REVISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UINT_MAX_VALUE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"addressesProvider","outputs":[{"internalType":"contract LendingPoolAddressesProvider","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"core","outputs":[{"internalType":"contract LendingPoolCore","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"dataProvider","outputs":[{"internalType":"contract LendingPoolDataProvider","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"parametersProvider","outputs":[{"internalType":"contract LendingPoolParametersProvider","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract LendingPoolAddressesProvider","name":"_addressesProvider","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint16","name":"_referralCode","type":"uint16"}],"name":"deposit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address payable","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_aTokenBalanceAfterRedeem","type":"uint256"}],"name":"redeemUnderlying","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_interestRateMode","type":"uint256"},{"internalType":"uint16","name":"_referralCode","type":"uint16"}],"name":"borrow","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address payable","name":"_onBehalfOf","type":"address"}],"name":"repay","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"swapBorrowRateMode","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"rebalanceStableBorrowRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"bool","name":"_useAsCollateral","type":"bool"}],"name":"setUserUseReserveAsCollateral","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_collateral","type":"address"},{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_purchaseAmount","type":"uint256"},{"internalType":"bool","name":"_receiveAToken","type":"bool"}],"name":"liquidationCall","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_params","type":"bytes"}],"name":"flashLoan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveConfigurationData","outputs":[{"internalType":"uint256","name":"ltv","type":"uint256"},{"internalType":"uint256","name":"liquidationThreshold","type":"uint256"},{"internalType":"uint256","name":"liquidationBonus","type":"uint256"},{"internalType":"address","name":"interestRateStrategyAddress","type":"address"},{"internalType":"bool","name":"usageAsCollateralEnabled","type":"bool"},{"internalType":"bool","name":"borrowingEnabled","type":"bool"},{"internalType":"bool","name":"stableBorrowRateEnabled","type":"bool"},{"internalType":"bool","name":"isActive","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveData","outputs":[{"internalType":"uint256","name":"totalLiquidity","type":"uint256"},{"internalType":"uint256","name":"availableLiquidity","type":"uint256"},{"internalType":"uint256","name":"totalBorrowsStable","type":"uint256"},{"internalType":"uint256","name":"totalBorrowsVariable","type":"uint256"},{"internalType":"uint256","name":"liquidityRate","type":"uint256"},{"internalType":"uint256","name":"variableBorrowRate","type":"uint256"},{"internalType":"uint256","name":"stableBorrowRate","type":"uint256"},{"internalType":"uint256","name":"averageStableBorrowRate","type":"uint256"},{"internalType":"uint256","name":"utilizationRate","type":"uint256"},{"internalType":"uint256","name":"liquidityIndex","type":"uint256"},{"internalType":"uint256","name":"variableBorrowIndex","type":"uint256"},{"internalType":"address","name":"aTokenAddress","type":"address"},{"internalType":"uint40","name":"lastUpdateTimestamp","type":"uint40"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserAccountData","outputs":[{"internalType":"uint256","name":"totalLiquidityETH","type":"uint256"},{"internalType":"uint256","name":"totalCollateralETH","type":"uint256"},{"internalType":"uint256","name":"totalBorrowsETH","type":"uint256"},{"internalType":"uint256","name":"totalFeesETH","type":"uint256"},{"internalType":"uint256","name":"availableBorrowsETH","type":"uint256"},{"internalType":"uint256","name":"currentLiquidationThreshold","type":"uint256"},{"internalType":"uint256","name":"ltv","type":"uint256"},{"internalType":"uint256","name":"healthFactor","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"getUserReserveData","outputs":[{"internalType":"uint256","name":"currentATokenBalance","type":"uint256"},{"internalType":"uint256","name":"currentBorrowBalance","type":"uint256"},{"internalType":"uint256","name":"principalBorrowBalance","type":"uint256"},{"internalType":"uint256","name":"borrowRateMode","type":"uint256"},{"internalType":"uint256","name":"borrowRate","type":"uint256"},{"internalType":"uint256","name":"liquidityRate","type":"uint256"},{"internalType":"uint256","name":"originationFee","type":"uint256"},{"internalType":"uint256","name":"variableBorrowIndex","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"bool","name":"usageAsCollateralEnabled","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getReserves","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"}], - "bytecode": "0x60806040526000600181815590556146908061001c6000396000f3fe6080604052600436106101295760003560e01c80638afaff02116100ab578063c72c4d101161006f578063c72c4d1014610664578063c858f5f914610679578063cd112382146106c2578063d0fc81d2146106fd578063d2d0e06614610712578063f2f4eb261461074857610129565b80638afaff02146105385780639895e3d81461055f578063b334ed86146105a8578063bf92857c146105bd578063c4d66de81461063157610129565b806348ca1300116100f257806348ca13001461039057806358707e06146103c35780635a3b74b9146103f45780635ceae9c41461042f5780635cffe9de1461046557610129565b8062a718a91461012e5780630902f1ac1461017457806328dd2d01146101d957806335ea6a75146102665780633e1501411461030e575b600080fd5b610172600480360360a081101561014457600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060800135151561075d565b005b34801561018057600080fd5b50610189610b72565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156101c55781810151838201526020016101ad565b505050509050019250505060405180910390f35b3480156101e557600080fd5b50610214600480360360408110156101fc57600080fd5b506001600160a01b0381358116916020013516610c85565b604080519a8b5260208b0199909952898901979097526060890195909552608088019390935260a087019190915260c086015260e0850152610100840152151561012083015251908190036101400190f35b34801561027257600080fd5b506102996004803603602081101561028957600080fd5b50356001600160a01b0316610da6565b604080519d8e5260208e019c909c528c8c019a909a5260608c019890985260808b019690965260a08a019490945260c089019290925260e08801526101008701526101208601526101408501526001600160a01b031661016084015264ffffffffff1661018083015251908190036101a00190f35b34801561031a57600080fd5b506103416004803603602081101561033157600080fd5b50356001600160a01b0316610f05565b604080519889526020890197909752878701959095526001600160a01b0390931660608701529015156080860152151560a0850152151560c0840152151560e083015251908190036101000190f35b34801561039c57600080fd5b50610172600480360360208110156103b357600080fd5b50356001600160a01b0316610fee565b3480156103cf57600080fd5b506103d86113b0565b604080516001600160a01b039092168252519081900360200190f35b34801561040057600080fd5b506101726004803603604081101561041757600080fd5b506001600160a01b03813516906020013515156113bf565b6101726004803603606081101561044557600080fd5b506001600160a01b03813581169160208101359160409091013516611697565b34801561047157600080fd5b506101726004803603608081101561048857600080fd5b6001600160a01b038235811692602081013590911691604082013591908101906080810160608201356401000000008111156104c357600080fd5b8201836020820111156104d557600080fd5b803590602001918460018302840111640100000000831117156104f757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611e92945050505050565b34801561054457600080fd5b5061054d6124af565b60408051918252519081900360200190f35b34801561056b57600080fd5b506101726004803603608081101561058257600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356124b4565b3480156105b457600080fd5b506103d86127d5565b3480156105c957600080fd5b506105f0600480360360208110156105e057600080fd5b50356001600160a01b03166127e4565b604080519889526020890197909752878701959095526060870193909352608086019190915260a085015260c084015260e083015251908190036101000190f35b34801561063d57600080fd5b506101726004803603602081101561065457600080fd5b50356001600160a01b031661285c565b34801561067057600080fd5b506103d8612b30565b34801561068557600080fd5b506101726004803603608081101561069c57600080fd5b5080356001600160a01b0316906020810135906040810135906060013561ffff16612b3f565b3480156106ce57600080fd5b50610172600480360360408110156106e557600080fd5b506001600160a01b038135811691602001351661343a565b34801561070957600080fd5b5061054d613986565b6101726004803603606081101561072857600080fd5b5080356001600160a01b0316906020810135906040013561ffff1661398c565b34801561075457600080fd5b506103d8613c9c565b60008054600101908190558461077281613cab565b8661077c81613cab565b60355460408051632c1a75cd60e11b815290516000926001600160a01b031691635834eb9a916004808301926020929190829003018186803b1580156107c157600080fd5b505afa1580156107d5573d6000803e3d6000fd5b505050506040513d60208110156107eb57600080fd5b5051604080516001600160a01b038c811660248301528b811660448301528a81166064830152608482018a905288151560a4808401919091528351808403909101815260c490920183526020820180516001600160e01b031662a718a960e01b17815292518251949550600094606094928716939282918083835b602083106108855780518252601f199092019160209182019101610866565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d80600081146108e5576040519150601f19603f3d011682016040523d82523d6000602084013e6108ea565b606091505b509150915081610941576040805162461bcd60e51b815260206004820152601760248201527f4c69717569646174696f6e2063616c6c206661696c6564000000000000000000604482015290519081900360640190fd5b6000606082806020019051604081101561095a57600080fd5b81516020830180516040519294929383019291908464010000000082111561098157600080fd5b90830190602082018581111561099657600080fd5b82516401000000008111828201881017156109b057600080fd5b82525081516020918201929091019080838360005b838110156109dd5781810151838201526020016109c5565b50505050905090810190601f168015610a0a5780820380516001836020036101000a031916815260200191505b506040525050509150915081600014610b1f578060405160200180807302634b8bab4b230ba34b7b7103330b4b632b21d160651b81525060140182805190602001908083835b60208310610a6f5780518252601f199092019160209182019101610a50565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f190183529384905262461bcd60e51b84526004840181815282516024860152825192965094508493604401925085019080838360005b83811015610ae4578181015183820152602001610acc565b50505050905090810190601f168015610b115780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050505050506000548114610b6a576040805162461bcd60e51b815260206004820152601f6024820152600080516020614169833981519152604482015290519081900360640190fd5b505050505050565b60365460408051630240bc6b60e21b815290516060926001600160a01b031691630902f1ac916004808301926000929190829003018186803b158015610bb757600080fd5b505afa158015610bcb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610bf457600080fd5b8101908080516040519392919084640100000000821115610c1457600080fd5b908301906020820185811115610c2957600080fd5b8251866020820283011164010000000082111715610c4657600080fd5b82525081516020918201928201910280838360005b83811015610c73578181015183820152602001610c5b565b50505050905001604052505050905090565b603754604080516328dd2d0160e01b81526001600160a01b0385811660048301528481166024830152915160009384938493849384938493849384938493849316916328dd2d0191604480830192610140929190829003018186803b158015610ced57600080fd5b505afa158015610d01573d6000803e3d6000fd5b505050506040513d610140811015610d1857600080fd5b810190808051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919050505099509950995099509950995099509950995099509295989b9194979a5092959850565b6000806000806000806000806000806000806000603760009054906101000a90046001600160a01b03166001600160a01b03166335ea6a758f6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b031681526020019150506101a06040518083038186803b158015610e2657600080fd5b505afa158015610e3a573d6000803e3d6000fd5b505050506040513d6101a0811015610e5157600080fd5b81019080805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291905050509c509c509c509c509c509c509c509c509c509c509c509c509c5091939597999b9d90929496989a9c50565b600080600080600080600080603760009054906101000a90046001600160a01b03166001600160a01b0316633e1501418a6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b031681526020019150506101006040518083038186803b158015610f7d57600080fd5b505afa158015610f91573d6000803e3d6000fd5b505050506040513d610100811015610fa857600080fd5b508051602082015160408301516060840151608085015160a086015160c087015160e090970151959e50939c50919a509850965094509092509050919395975091939597565b60008054600101908190558161100381613cab565b8261100d81613d62565b60365460408051639fb8afcd60e01b81526001600160a01b038781166004830152336024830152915160009384938493911691639fb8afcd91604480820192606092909190829003018186803b15801561106657600080fd5b505afa15801561107a573d6000803e3d6000fd5b505050506040513d606081101561109057600080fd5b50805160208201516040909201519094509092509050816110e25760405162461bcd60e51b815260040180806020018281038252603781526020018061438f6037913960400191505060405180910390fd5b60365460408051631ca19f1960e01b81526001600160a01b038a8116600483015233602483015291516000939290921691631ca19f1991604480820192602092909190829003018186803b15801561113957600080fd5b505afa15801561114d573d6000803e3d6000fd5b505050506040513d602081101561116357600080fd5b50519050600281600281111561117557fe5b141561123c576036546040805163710ba6c360e11b81526001600160a01b038b81166004830152336024830152604482018790529151919092169163e2174d86916064808301926020929190829003018186803b1580156111d557600080fd5b505afa1580156111e9573d6000803e3d6000fd5b505050506040513d60208110156111ff57600080fd5b505161123c5760405162461bcd60e51b81526004018080602001828103825260308152602001806145c46030913960400191505060405180910390fd5b60365460405163f614831160e01b81526001600160a01b038a8116600483019081523360248401819052604484018990526064840188905260848401879052600094859493169263f6148311928e92918b918b918b918b9160a4018260028111156112a357fe5b60ff16815260200196505050505050506040805180830381600087803b1580156112cc57600080fd5b505af11580156112e0573d6000803e3d6000fd5b505050506040513d60408110156112f657600080fd5b5080516020909101519092509050336001600160a01b038b167fb3e2773606abfd36b5bd91394b3a54d1398336c65005baf7bf7a05efeffaf75b84600281111561133c57fe5b6040805191825260208201869052818101899052426060830152519081900360800190a3505050505050505060005481146113ac576040805162461bcd60e51b815260206004820152601f6024820152600080516020614169833981519152604482015290519081900360640190fd5b5050565b6038546001600160a01b031681565b6000805460010190819055826113d481613cab565b836113de81613d62565b60365460408051630c526de560e11b81526001600160a01b038881166004830152336024830152915160009392909216916318a4dbca91604480820192602092909190829003018186803b15801561143557600080fd5b505afa158015611449573d6000803e3d6000fd5b505050506040513d602081101561145f57600080fd5b505190508061149f5760405162461bcd60e51b815260040180806020018281038252602a815260200180614535602a913960400191505060405180910390fd5b603754604080516376e9d61560e01b81526001600160a01b03898116600483015233602483015260448201859052915191909216916376e9d615916064808301926020929190829003018186803b1580156114f957600080fd5b505afa15801561150d573d6000803e3d6000fd5b505050506040513d602081101561152357600080fd5b50516115605760405162461bcd60e51b815260040180806020018281038252603081526020018061422c6030913960400191505060405180910390fd5b60365460408051633e94615360e21b81526001600160a01b03898116600483015233602483015288151560448301529151919092169163fa51854c91606480830192600092919082900301818387803b1580156115bc57600080fd5b505af11580156115d0573d6000803e3d6000fd5b5050505084156116145760405133906001600160a01b038816907e058a56ea94653cdf4f152d227ace22d4c00ad99e2a43f58cb7d9e3feb295f290600090a361164b565b60405133906001600160a01b038816907f44c58d81365b66dd4b1a7f36c25aa97b8c71c361ee4937adc1a00000227db5dd90600090a35b5050506000548114611692576040805162461bcd60e51b815260206004820152601f6024820152600080516020614169833981519152604482015290519081900360640190fd5b505050565b6000805460010190819055836116ac81613cab565b836116b681613e17565b6116be61405a565b60365460408051639fb8afcd60e01b81526001600160a01b038a81166004830152888116602483015291519190921691639fb8afcd916044808301926060929190829003018186803b15801561171357600080fd5b505afa158015611727573d6000803e3d6000fd5b505050506040513d606081101561173d57600080fd5b50805160208083015160409384015185850152848201529083526036548251633faacc6b60e21b81526001600160a01b038b8116600483015289811660248301529351939091169263feab31ac92604480840193919291829003018186803b1580156117a857600080fd5b505afa1580156117bc573d6000803e3d6000fd5b505050506040513d60208110156117d257600080fd5b505160e08201526001600160a01b0387166117eb613e6c565b6001600160a01b0316146060820152602081015161183a5760405162461bcd60e51b815260040180806020018281038252602981526020018061459b6029913960400191505060405180910390fd5b600019861415806118535750336001600160a01b038616145b61188e5760405162461bcd60e51b81526004018080602001828103825260448152602001806145f46044913960600191505060405180910390fd5b60e081015160208201516118a79163ffffffff613e8416565b608082015260001986148015906118c15750806080015186105b156118ce57608081018690525b806060015115806118e3575080608001513410155b61191e5760405162461bcd60e51b81526004018080602001828103825260288152602001806142e56028913960400191505060405180910390fd5b8060e00151816080015111611b49576036546080820151604080840151815163da12d96f60e01b81526001600160a01b038c811660048301528a811660248301526000604483018190526064830195909552608482019290925260a48101849052915193169263da12d96f9260c48084019391929182900301818387803b1580156119a857600080fd5b505af11580156119bc573d6000803e3d6000fd5b505060365460608401516001600160a01b03909116925063c7d1423791506119e55760006119eb565b82608001515b89888560800151603560009054906101000a90046001600160a01b03166001600160a01b031663ee8912966040518163ffffffff1660e01b815260040160206040518083038186803b158015611a4057600080fd5b505afa158015611a54573d6000803e3d6000fd5b505050506040513d6020811015611a6a57600080fd5b5051604080516001600160e01b031960e089901b1681526001600160a01b039586166004820152938516602485015260448401929092529290921660648201529051608480830192600092919082900301818588803b158015611acc57600080fd5b505af1158015611ae0573d6000803e3d6000fd5b505050608080840151604080860151815160008152602081019390935282820152426060830152513394506001600160a01b038a811694508c16927fb718f0b14f03d8c3adf35b15e3da52421b042ac879e5a689011a8b1e0036773d928290030190a450611e46565b60e08101516080820151611b629163ffffffff613ee716565b60a0820181905260365460e08301516040808501516020860151825163da12d96f60e01b81526001600160a01b038e811660048301528c81166024830152604482018890526064820195909552608481019290925290941460a48501525191169163da12d96f9160c480830192600092919082900301818387803b158015611be957600080fd5b505af1158015611bfd573d6000803e3d6000fd5b5050505060e081015115611d315760365460608201516001600160a01b039091169063c7d1423790611c30576000611c36565b8260e001515b89888560e00151603560009054906101000a90046001600160a01b03166001600160a01b031663ee8912966040518163ffffffff1660e01b815260040160206040518083038186803b158015611c8b57600080fd5b505afa158015611c9f573d6000803e3d6000fd5b505050506040513d6020811015611cb557600080fd5b5051604080516001600160e01b031960e089901b1681526001600160a01b039586166004820152938516602485015260448401929092529290921660648201529051608480830192600092919082900301818588803b158015611d1757600080fd5b505af1158015611d2b573d6000803e3d6000fd5b50505050505b60365460608201516001600160a01b03909116906328fcf4d390611d56576000611d6c565b60e0830151611d6c90349063ffffffff613ee716565b60a0840151604080516001600160e01b031960e086901b1681526001600160a01b038d166004820152336024820152604481019290925251606480830192600092919082900301818588803b158015611dc457600080fd5b505af1158015611dd8573d6000803e3d6000fd5b50505060a083015160e08401516040808601518151938452602084019290925282810191909152426060830152513393506001600160a01b0389811693508b16917fb718f0b14f03d8c3adf35b15e3da52421b042ac879e5a689011a8b1e0036773d919081900360800190a4505b50506000548114611e8c576040805162461bcd60e51b815260206004820152601f6024820152600080516020614169833981519152604482015290519081900360640190fd5b50505050565b600080546001019081905583611ea781613cab565b83611eb181613e17565b6000611ebb613e6c565b6001600160a01b0316876001600160a01b031614611f5157603654604080516370a0823160e01b81526001600160a01b0392831660048201529051918916916370a0823191602480820192602092909190829003018186803b158015611f2057600080fd5b505afa158015611f34573d6000803e3d6000fd5b505050506040513d6020811015611f4a57600080fd5b5051611f5f565b6036546001600160a01b0316315b905085811015611fa05760405162461bcd60e51b81526004018080602001828103825260318152602001806141896031913960400191505060405180910390fd5b60385460408051630161bfad60e61b8152815160009384936001600160a01b039091169263586feb409260048083019392829003018186803b158015611fe557600080fd5b505afa158015611ff9573d6000803e3d6000fd5b505050506040513d604081101561200f57600080fd5b508051602090910151909250905060006120416127106120358b8663ffffffff613f4416565b9063ffffffff613f9d16565b9050600061205b612710612035848663ffffffff613f4416565b905060008211801561206d5750600081115b6120a85760405162461bcd60e51b815260040180806020018281038252603281526020018061449c6032913960400191505060405180910390fd5b60008c905060008d9050603660009054906101000a90046001600160a01b03166001600160a01b031663fa93b2a58e838f6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b15801561214157600080fd5b505af1158015612155573d6000803e3d6000fd5b50505050816001600160a01b031663ee8725588e8e878f6040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156121dc5781810151838201526020016121c4565b50505050905090810190601f1680156122095780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b15801561222b57600080fd5b505af115801561223f573d6000803e3d6000fd5b50505050600061224d613e6c565b6001600160a01b03168e6001600160a01b031614612301578d6001600160a01b03166370a08231603660009054906101000a90046001600160a01b03166040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156122d057600080fd5b505afa1580156122e4573d6000803e3d6000fd5b505050506040513d60208110156122fa57600080fd5b505161230f565b6036546001600160a01b0316315b9050612321888663ffffffff613e8416565b811461235e5760405162461bcd60e51b815260040180806020018281038252603281526020018061435d6032913960400191505060405180910390fd5b6036546001600160a01b03166309ac29538f8a612381898963ffffffff613ee716565b886040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b03168152602001848152602001838152602001828152602001945050505050600060405180830381600087803b1580156123df57600080fd5b505af11580156123f3573d6000803e3d6000fd5b505050508d6001600160a01b03168f6001600160a01b03167f5b8f46461c1dd69fb968f1a003acee221ea3e19540e350233b612ddb43433b558f8888426040518085815260200184815260200183815260200182815260200194505050505060405180910390a35050505050505050505060005481146124a8576040805162461bcd60e51b815260206004820152601f6024820152600080516020614169833981519152604482015290519081900360640190fd5b5050505050565b600281565b600080546001019081905560365460408051631a59df7760e11b81526001600160a01b0380891660048301529151889392909216916334b3beee91602480820192602092909190829003018186803b15801561250f57600080fd5b505afa158015612523573d6000803e3d6000fd5b505050506040513d602081101561253957600080fd5b50516001600160a01b031633146125815760405162461bcd60e51b815260040180806020018281038252604b8152602001806143fa604b913960600191505060405180910390fd5b8561258b81613cab565b8461259581613e17565b6036546040805163e240301960e01b81526001600160a01b038b811660048301529151600093929092169163e240301991602480820192602092909190829003018186803b1580156125e657600080fd5b505afa1580156125fa573d6000803e3d6000fd5b505050506040513d602081101561261057600080fd5b50519050868110156126535760405162461bcd60e51b81526004018080602001828103825260318152602001806142806031913960400191505060405180910390fd5b6036546040805163afcdbea360e01b81526001600160a01b038c811660048301528b81166024830152604482018b9052891560648301529151919092169163afcdbea391608480830192600092919082900301818387803b1580156126b757600080fd5b505af11580156126cb573d6000803e3d6000fd5b50506036546040805163fa93b2a560e01b81526001600160a01b038e811660048301528d81166024830152604482018d9052915191909216935063fa93b2a59250606480830192600092919082900301818387803b15801561272c57600080fd5b505af1158015612740573d6000803e3d6000fd5b5050604080518a815242602082015281516001600160a01b03808e1695508e1693507f9c4ed599cd8555b9c1e8cd7643240d7d71eb76b792948c49fcb4d411f7b6b3c6929181900390910190a35050505060005481146124a8576040805162461bcd60e51b815260206004820152601f6024820152600080516020614169833981519152604482015290519081900360640190fd5b6037546001600160a01b031681565b600080600080600080600080603760009054906101000a90046001600160a01b03166001600160a01b031663bf92857c8a6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b031681526020019150506101006040518083038186803b158015610f7d57600080fd5b6000612866614007565b60025490915060ff168061287d575061287d61400c565b80612889575060015481115b6128c45760405162461bcd60e51b815260040180806020018281038252602e8152602001806144ce602e913960400191505060405180910390fd5b60025460ff161580156128e5576002805460ff191660019081179091558290555b603580546001600160a01b0319166001600160a01b0385811691909117918290556040805163076b7fbb60e51b81529051929091169163ed6ff76091600480820192602092909190829003018186803b15801561294157600080fd5b505afa158015612955573d6000803e3d6000fd5b505050506040513d602081101561296b57600080fd5b5051603680546001600160a01b0319166001600160a01b0392831617905560355460408051632f58b80d60e01b815290519190921691632f58b80d916004808301926020929190829003018186803b1580156129c657600080fd5b505afa1580156129da573d6000803e3d6000fd5b505050506040513d60208110156129f057600080fd5b5051603780546001600160a01b0319166001600160a01b03928316179055603554604080516302030ec760e11b8152905191909216916304061d8e916004808301926020929190829003018186803b158015612a4b57600080fd5b505afa158015612a5f573d6000803e3d6000fd5b505050506040513d6020811015612a7557600080fd5b5051603880546001600160a01b0319166001600160a01b0392831617905560355460408051633efbbf0f60e21b81529051919092169163fbeefc3c916004808301926020929190829003018186803b158015612ad057600080fd5b505afa158015612ae4573d6000803e3d6000fd5b505050506040513d6020811015612afa57600080fd5b5051603980546001600160a01b0319166001600160a01b039092169190911790558015611692576002805460ff19169055505050565b6035546001600160a01b031681565b600080546001019081905584612b5481613cab565b85612b5e81613d62565b85612b6881613e17565b612b706140a1565b60365460408051632e79732b60e11b81526001600160a01b038c8116600483015291519190921691635cf2e656916024808301926020929190829003018186803b158015612bbd57600080fd5b505afa158015612bd1573d6000803e3d6000fd5b505050506040513d6020811015612be757600080fd5b5051612c245760405162461bcd60e51b815260040180806020018281038252602481526020018061425c6024913960400191505060405180910390fd5b8660021480612c335750866001145b612c6e5760405162461bcd60e51b81526004018080602001828103825260238152602001806141ba6023913960400191505060405180910390fd5b866002811115612c7a57fe5b816101c001906002811115612c8b57fe5b90816002811115612c9857fe5b9052506036546040805163e240301960e01b81526001600160a01b038c811660048301529151919092169163e2403019916024808301926020929190829003018186803b158015612ce857600080fd5b505afa158015612cfc573d6000803e3d6000fd5b505050506040513d6020811015612d1257600080fd5b50516101608201819052881115612d5a5760405162461bcd60e51b81526004018080602001828103825260368152602001806144666036913960400191505060405180910390fd5b60375460408051632c6d0e9b60e01b815233600482015290516001600160a01b0390921691632c6d0e9b9160248082019261010092909190829003018186803b158015612da657600080fd5b505afa158015612dba573d6000803e3d6000fd5b505050506040513d610100811015612dd157600080fd5b506020808201516040808401516060850151608086015160a087015160e09788015115156101e08a015293880193909352938601919091526101008501929092529183015260c08201819052612e6e576040805162461bcd60e51b815260206004820152601b60248201527f54686520636f6c6c61746572616c2062616c616e636520697320300000000000604482015290519081900360640190fd5b806101e0015115612eb05760405162461bcd60e51b815260040180806020018281038252603f81526020018061412a603f913960400191505060405180910390fd5b60395460408051630e563a7d60e41b8152336004820152602481018b905290516001600160a01b039092169163e563a7d091604480820192602092909190829003018186803b158015612f0257600080fd5b505afa158015612f16573d6000803e3d6000fd5b505050506040513d6020811015612f2c57600080fd5b505160608201819052612f705760405162461bcd60e51b81526004018080602001828103825260218152602001806141dd6021913960400191505060405180910390fd5b603760009054906101000a90046001600160a01b03166001600160a01b03166312737c338a8a84606001518560e0015186610100015187602001516040518763ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001868152602001858152602001848152602001838152602001828152602001965050505050505060206040518083038186803b15801561301457600080fd5b505afa158015613028573d6000803e3d6000fd5b505050506040513d602081101561303e57600080fd5b505160a0820181905260c082015110156130895760405162461bcd60e51b81526004018080602001828103825260348152602001806143c66034913960400191505060405180910390fd5b6001816101c00151600281111561309c57fe5b141561323b576036546040805163710ba6c360e11b81526001600160a01b038c81166004830152336024830152604482018c90529151919092169163e2174d86916064808301926020929190829003018186803b1580156130fc57600080fd5b505afa158015613110573d6000803e3d6000fd5b505050506040513d602081101561312657600080fd5b50516131635760405162461bcd60e51b81526004018080602001828103825260398152602001806144fc6039913960400191505060405180910390fd5b603854604080516335adc96b60e21b815290516000926001600160a01b03169163d6b725ac916004808301926020929190829003018186803b1580156131a857600080fd5b505afa1580156131bc573d6000803e3d6000fd5b505050506040513d60208110156131d257600080fd5b50516101608301519091506000906131f790606490612035908563ffffffff613f4416565b9050808a11156132385760405162461bcd60e51b815260040180806020018281038252603c81526020018061455f603c913960400191505060405180910390fd5b50505b60365460608201516101c0830151604051630deb1bf960e21b81526001600160a01b038d8116600483019081523360248401819052604484018f90526064840186905291909516946337ac6fe4948f9492938f939192906084018260028111156132a157fe5b60ff168152602001955050505050506040805180830381600087803b1580156132c957600080fd5b505af11580156132dd573d6000803e3d6000fd5b505050506040513d60408110156132f357600080fd5b5080516020909101516101208301526101a08201526036546040805163fa93b2a560e01b81526001600160a01b038c81166004830152336024830152604482018c90529151919092169163fa93b2a591606480830192600092919082900301818387803b15801561336357600080fd5b505af1158015613377573d6000803e3d6000fd5b5050506101a0820151606080840151610120850151604080518e8152602081018e9052808201959095529284019190915260808301524260a08301525161ffff8916925033916001600160a01b038d16917f1e77446728e5558aa1b7e81e0cdab9cc1b075ba893b740600c76a315c2caa5539181900360c00190a45050505060005481146124a8576040805162461bcd60e51b815260206004820152601f6024820152600080516020614169833981519152604482015290519081900360640190fd5b60008054600101908190558261344f81613cab565b60365460408051639fb8afcd60e01b81526001600160a01b0387811660048301528681166024830152915160009384931691639fb8afcd916044808301926060929190829003018186803b1580156134a657600080fd5b505afa1580156134ba573d6000803e3d6000fd5b505050506040513d60608110156134d057600080fd5b50602081015160409091015190925090508161351d5760405162461bcd60e51b815260040180806020018281038252602e8152602001806141fe602e913960400191505060405180910390fd5b600160365460408051631ca19f1960e01b81526001600160a01b038a81166004830152898116602483015291519190921691631ca19f19916044808301926020929190829003018186803b15801561357457600080fd5b505afa158015613588573d6000803e3d6000fd5b505050506040513d602081101561359e57600080fd5b505160028111156135ab57fe5b146135e75760405162461bcd60e51b81526004018080602001828103825260348152602001806142b16034913960400191505060405180910390fd5b60365460408051631bffeac360e21b81526001600160a01b038981166004830152888116602483015291516000939290921691636fffab0c91604480820192602092909190829003018186803b15801561364057600080fd5b505afa158015613654573d6000803e3d6000fd5b505050506040513d602081101561366a57600080fd5b5051603654604080516362a00a4760e11b81526001600160a01b038b811660048301529151939450600093919092169163c540148e916024808301926020929190829003018186803b1580156136bf57600080fd5b505afa1580156136d3573d6000803e3d6000fd5b505050506040513d60208110156136e957600080fd5b505160365460408051631100f3b160e31b81526001600160a01b038c81166004830152915193945060009391909216916388079d88916024808301926020929190829003018186803b15801561373e57600080fd5b505afa158015613752573d6000803e3d6000fd5b505050506040513d602081101561376857600080fd5b5051603854604080516346f4f8d160e01b8152905192935060009261380a926137fd926001600160a01b03909116916346f4f8d191600480820192602092909190829003018186803b1580156137bd57600080fd5b505afa1580156137d1573d6000803e3d6000fd5b505050506040513d60208110156137e757600080fd5b50516137f1614012565b9063ffffffff613e8416565b839063ffffffff61402216565b90508284108061381957508084115b1561390a576036546040805163af825b0760e01b81526001600160a01b038d811660048301528c81166024830152604482018990529151600093929092169163af825b079160648082019260209290919082900301818787803b15801561387f57600080fd5b505af1158015613893573d6000803e3d6000fd5b505050506040513d60208110156138a957600080fd5b50516040805182815260208101899052428183015290519192506001600160a01b03808d1692908e16917f5050ad184862424ee0852d1838d355ad65bed1e5e6da67ac9a2dac1922677f60919081900360600190a350505050505050613941565b60405162461bcd60e51b815260040180806020018281038252602f81526020018061432e602f913960400191505060405180910390fd5b506000548114611692576040805162461bcd60e51b815260206004820152601f6024820152600080516020614169833981519152604482015290519081900360640190fd5b60001981565b6000805460010190819055836139a181613cab565b846139ab81613d62565b846139b581613e17565b60365460408051631a59df7760e11b81526001600160a01b038a81166004830152915160009392909216916334b3beee91602480820192602092909190829003018186803b158015613a0657600080fd5b505afa158015613a1a573d6000803e3d6000fd5b505050506040513d6020811015613a3057600080fd5b5051604080516370a0823160e01b815233600482015290519192506000916001600160a01b038416916370a08231916024808301926020929190829003018186803b158015613a7e57600080fd5b505afa158015613a92573d6000803e3d6000fd5b505050506040513d6020811015613aa857600080fd5b505160365460408051632f35bfe960e21b81526001600160a01b038d81166004830152336024830152604482018d90529315606482018190529151919450929091169163bcd6ffa491608480830192600092919082900301818387803b158015613b1157600080fd5b505af1158015613b25573d6000803e3d6000fd5b5050604080516394362e8b60e01b8152336004820152602481018c905290516001600160a01b03861693506394362e8b9250604480830192600092919082900301818387803b158015613b7757600080fd5b505af1158015613b8b573d6000803e3d6000fd5b5050603654604080516328fcf4d360e01b81526001600160a01b038e81166004830152336024830152604482018e905291519190921693506328fcf4d39250349160648082019260009290919082900301818588803b158015613bed57600080fd5b505af1158015613c01573d6000803e3d6000fd5b5050604080518c8152426020820152815161ffff8d1695503394506001600160a01b038f1693507fc12c57b1c73a2c3a2ea4613e9476abb3d8d146857aab7329e24243fb59710c82929181900390910190a450505050506000548114611e8c576040805162461bcd60e51b815260206004820152601f6024820152600080516020614169833981519152604482015290519081900360640190fd5b6036546001600160a01b031681565b60365460408051630283aeb760e11b81526001600160a01b038481166004830152915191909216916305075d6e916024808301926020929190829003018186803b158015613cf857600080fd5b505afa158015613d0c573d6000803e3d6000fd5b505050506040513d6020811015613d2257600080fd5b5051613d5f5760405162461bcd60e51b815260040180806020018281038252602181526020018061430d6021913960400191505060405180910390fd5b50565b60365460408051634a08accb60e01b81526001600160a01b03848116600483015291519190921691634a08accb916024808301926020929190829003018186803b158015613daf57600080fd5b505afa158015613dc3573d6000803e3d6000fd5b505050506040513d6020811015613dd957600080fd5b505115613d5f5760405162461bcd60e51b81526004018080602001828103825260248152602001806146386024913960400191505060405180910390fd5b60008111613d5f576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b600082820183811015613ede576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b600082821115613f3e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600082613f5357506000613ee1565b82820282848281613f6057fe5b0414613ede5760405162461bcd60e51b81526004018080602001828103825260218152602001806144456021913960400191505060405180910390fd5b6000808211613ff3576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b6000828481613ffe57fe5b04949350505050565b600290565b303b1590565b6b033b2e3c9fd0803ce800000090565b6000613ede6b033b2e3c9fd0803ce8000000612035614047868663ffffffff613f4416565b6b019d971e4fe8401e7400000090613e84565b604051806101000160405280600081526020016000815260200160008152602001600015158152602001600081526020016000815260200160008152602001600081525090565b60405180610200016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000600281111561411c57fe5b815260006020909101529056fe54686520626f72726f7765722063616e20616c7265616479206265206c69717569646174656420736f2068652063616e6e6f7420626f72726f77206d6f72655265656e7472616e637947756172643a207265656e7472616e742063616c6c005468657265206973206e6f7420656e6f756768206c697175696469747920617661696c61626c6520746f20626f72726f77496e76616c696420696e7465726573742072617465206d6f64652073656c656374656454686520616d6f756e7420746f20626f72726f7720697320746f6f20736d616c6c5573657220646f6573206e6f74206861766520616e7920626f72726f7720666f722074686973207265736572766555736572206465706f73697420697320616c7265616479206265696e67207573656420617320636f6c6c61746572616c52657365727665206973206e6f7420656e61626c656420666f7220626f72726f77696e675468657265206973206e6f7420656e6f756768206c697175696469747920617661696c61626c6520746f2072656465656d546865207573657220626f72726f77206973207661726961626c6520616e642063616e6e6f7420626520726562616c616e636564496e76616c6964206d73672e76616c75652073656e7420666f72207468652072657061796d656e74416374696f6e20726571756972657320616e206163746976652072657365727665496e746572657374207261746520726562616c616e636520636f6e646974696f6e732077657265206e6f74206d65745468652061637475616c2062616c616e6365206f66207468652070726f746f636f6c20697320696e636f6e73697374656e745573657220646f6573206e6f742068617665206120626f72726f7720696e2070726f6772657373206f6e207468697320726573657276655468657265206973206e6f7420656e6f75676820636f6c6c61746572616c20746f20636f7665722061206e657720626f72726f775468652063616c6c6572206f6620746869732066756e6374696f6e2063616e206f6e6c79206265207468652061546f6b656e20636f6e7472616374206f6620746869732072657365727665536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775468657265206973206e6f7420656e6f756768206c697175696469747920617661696c61626c6520696e2074686520726573657276655468652072657175657374656420616d6f756e7420697320746f6f20736d616c6c20666f72206120666c6173684c6f616e2e436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564557365722063616e6e6f7420626f72726f77207468652073656c656374656420616d6f756e742077697468206120737461626c6520726174655573657220646f6573206e6f74206861766520616e79206c6971756964697479206465706f73697465645573657220697320747279696e6720746f20626f72726f7720746f6f206d756368206c6971756964697479206174206120737461626c652072617465546865207573657220646f6573206e6f74206861766520616e7920626f72726f772070656e64696e67557365722063616e6e6f7420626f72726f77207468652073656c656374656420616d6f756e7420617420737461626c65546f207265706179206f6e20626568616c66206f6620616e207573657220616e206578706c6963697420616d6f756e7420746f207265706179206973206e65656465642e416374696f6e20726571756972657320616e20756e667265657a65642072657365727665a265627a7a72315820ed59692c50e2ec9cac0b8fa26e0d00888d3764d1840be22ed0adc4e0acde245564736f6c634300050e0032", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/external/abi/aave/v1/LendingPoolAddressesProvider.json b/external/abi/aave/v1/LendingPoolAddressesProvider.json deleted file mode 100644 index e1e3afba5..000000000 --- a/external/abi/aave/v1/LendingPoolAddressesProvider.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "contractName": "LendingPoolAddressesProvider", - "abi": [{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"EthereumAddressUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"FeeProviderUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"LendingPoolConfiguratorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"LendingPoolCoreUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"LendingPoolDataProviderUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"LendingPoolLiquidationManagerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"LendingPoolManagerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"LendingPoolParametersProviderUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"LendingPoolUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"LendingRateOracleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"PriceOracleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"ProxyCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"TokenDistributorUpdated","type":"event"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"getAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getLendingPool","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_pool","type":"address"}],"name":"setLendingPoolImpl","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getLendingPoolCore","outputs":[{"internalType":"address payable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_lendingPoolCore","type":"address"}],"name":"setLendingPoolCoreImpl","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getLendingPoolConfigurator","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_configurator","type":"address"}],"name":"setLendingPoolConfiguratorImpl","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getLendingPoolDataProvider","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_provider","type":"address"}],"name":"setLendingPoolDataProviderImpl","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getLendingPoolParametersProvider","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_parametersProvider","type":"address"}],"name":"setLendingPoolParametersProviderImpl","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getFeeProvider","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_feeProvider","type":"address"}],"name":"setFeeProviderImpl","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getLendingPoolLiquidationManager","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_manager","type":"address"}],"name":"setLendingPoolLiquidationManager","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getLendingPoolManager","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_lendingPoolManager","type":"address"}],"name":"setLendingPoolManager","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getPriceOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_priceOracle","type":"address"}],"name":"setPriceOracle","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getLendingRateOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_lendingRateOracle","type":"address"}],"name":"setLendingRateOracle","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getTokenDistributor","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_tokenDistributor","type":"address"}],"name":"setTokenDistributor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}], - "bytecode": "0x60806040819052600080546001600160a01b03191633178082556001600160a01b0316917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3611af0806100576000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c80635aef021f116100f9578063bfedc10311610097578063ee89129611610071578063ee891296146103f7578063f2fde38b146103ff578063fbeefc3c14610425578063fca513a81461042d576101a9565b8063bfedc103146103a3578063c12542df146103c9578063ed6ff760146103ef576101a9565b806385c858b1116100d357806385c858b1146103515780638da5cb5b146103595780638f32d59b14610361578063a5eface21461037d576101a9565b80635aef021f146102fd578063715018a614610323578063820d12741461032b576101a9565b806333128d591161016657806340fdcadc1161014057806340fdcadc1461028357806344ce375b146102a9578063530e784f146102cf5780635834eb9a146102f5576101a9565b806333128d591461024d5780633618abba1461025557806338280e6b1461025d576101a9565b80630261bf8b146101ae57806304061d8e146101d25780631c827204146101da57806321f8a721146102025780632a62c6361461021f5780632f58b80d14610245575b600080fd5b6101b6610435565b604080516001600160a01b039092168252519081900360200190f35b6101b6610454565b610200600480360360208110156101f057600080fd5b50356001600160a01b0316610475565b005b6101b66004803603602081101561021857600080fd5b5035610511565b6102006004803603602081101561023557600080fd5b50356001600160a01b031661052c565b6101b66105c3565b6101b66105de565b6101b6610600565b6102006004803603602081101561027357600080fd5b50356001600160a01b0316610621565b6102006004803603602081101561029957600080fd5b50356001600160a01b03166106bd565b610200600480360360208110156102bf57600080fd5b50356001600160a01b031661075c565b610200600480360360208110156102e557600080fd5b50356001600160a01b03166107fa565b6101b6610891565b6102006004803603602081101561031357600080fd5b50356001600160a01b03166108b2565b610200610949565b6102006004803603602081101561034157600080fd5b50356001600160a01b03166109da565b6101b6610a78565b6101b6610a9f565b610369610aae565b604080519115158252519081900360200190f35b6102006004803603602081101561039357600080fd5b50356001600160a01b0316610abf565b610200600480360360208110156103b957600080fd5b50356001600160a01b0316610b5d565b610200600480360360208110156103df57600080fd5b50356001600160a01b0316610bf5565b6101b6610c99565b6101b6610cbf565b6102006004803603602081101561041557600080fd5b50356001600160a01b0316610cde565b6101b6610d31565b6101b6610d4b565b600061044f6b13115391125391d7d413d3d360a21b610511565b905090565b600061044f722820a920a6a2aa22a929afa82927ab24a222a960691b610511565b61047d610aae565b6104bc576040805162461bcd60e51b81526020600482018190526024820152600080516020611a9c833981519152604482015290519081900360640190fd5b6104da704c454e44494e475f504f4f4c5f434f524560781b82610d65565b6040516001600160a01b038216907f71c226bb2879778ca1298196bf7cc1256baee9d05b496c31ee627d35a471b5b790600090a250565b6000908152600160205260409020546001600160a01b031690565b610534610aae565b610573576040805162461bcd60e51b81526020600482018190526024820152600080516020611a9c833981519152604482015290519081900360640190fd5b61058c6b2322a2afa82927ab24a222a960a11b82610d65565b6040516001600160a01b038216907f18e1a55b8eff9c93921eecfa1462d6a8cbb80b3988db3eb14c039e43fdb2266190600090a250565b600061044f6c2220aa20afa82927ab24a222a960991b610511565b600061044f732622a72224a723afa827a7a62fa6a0a720a3a2a960611b610511565b600061044f724c454e44494e475f524154455f4f5241434c4560681b610511565b610629610aae565b610668576040805162461bcd60e51b81526020600482018190526024820152600080516020611a9c833981519152604482015290519081900360640190fd5b610686702a27a5a2a72fa224a9aa2924a12aaa27a960791b82610ffe565b6040516001600160a01b038216907fa8b48a56ec01f81c3615a21ec43e16b925c26293e0801cf6330427f2a687f05390600090a250565b6106c5610aae565b610704576040805162461bcd60e51b81526020600482018190526024820152600080516020611a9c833981519152604482015290519081900360640190fd5b610725732622a72224a723afa827a7a62fa6a0a720a3a2a960611b82610ffe565b6040516001600160a01b038216907fd5280c51185a38d36f7a0f5e56cac6248312bb70d0974782fa5a595127e0e08e90600090a250565b610764610aae565b6107a3576040805162461bcd60e51b81526020600482018190526024820152600080516020611a9c833981519152604482015290519081900360640190fd5b6107c3722624a8aaa4a220aa24a7a72fa6a0a720a3a2a960691b82610ffe565b6040516001600160a01b038216907f1a76cb769b814bc038223da86932b099b20aae03473683e6d98f5c3554e2606490600090a250565b610802610aae565b610841576040805162461bcd60e51b81526020600482018190526024820152600080516020611a9c833981519152604482015290519081900360640190fd5b61085a6b50524943455f4f5241434c4560a01b82610ffe565b6040516001600160a01b038216907fefe8ab924ca486283a79dc604baa67add51afb82af1db8ac386ebbba643cdffd90600090a250565b600061044f722624a8aaa4a220aa24a7a72fa6a0a720a3a2a960691b610511565b6108ba610aae565b6108f9576040805162461bcd60e51b81526020600482018190526024820152600080516020611a9c833981519152604482015290519081900360640190fd5b6109126b13115391125391d7d413d3d360a21b82610d65565b6040516001600160a01b038216907fc4e6c6cdf28d0edbd8bcf071d724d33cc2e7a30be7d06443925656e9cb492aa490600090a250565b610951610aae565b610990576040805162461bcd60e51b81526020600482018190526024820152600080516020611a9c833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6109e2610aae565b610a21576040805162461bcd60e51b81526020600482018190526024820152600080516020611a9c833981519152604482015290519081900360640190fd5b610a41724c454e44494e475f524154455f4f5241434c4560681b82610ffe565b6040516001600160a01b038216907f5c29179aba6942020a8a2d38f65de02fb6b7f784e7f049ed3a3cab97621859b590600090a250565b600061044f782622a72224a723afa827a7a62fa1a7a72324a3aaa920aa27a960391b610511565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b610ac7610aae565b610b06576040805162461bcd60e51b81526020600482018190526024820152600080516020611a9c833981519152604482015290519081900360640190fd5b610b26722820a920a6a2aa22a929afa82927ab24a222a960691b82610d65565b6040516001600160a01b038216907fce16ea9b2fd7cadddd0f7359971028f50b5ddba33dfae1a9bdea956fabb1e28090600090a250565b610b65610aae565b610ba4576040805162461bcd60e51b81526020600482018190526024820152600080516020611a9c833981519152604482015290519081900360640190fd5b610bbe6c2220aa20afa82927ab24a222a960991b82610d65565b6040516001600160a01b038216907f07890d7d10db37434d76ee4f2928fb2dc66227c3b3391206aced4f7bcb59cdb090600090a250565b610bfd610aae565b610c3c576040805162461bcd60e51b81526020600482018190526024820152600080516020611a9c833981519152604482015290519081900360640190fd5b610c62782622a72224a723afa827a7a62fa1a7a72324a3aaa920aa27a960391b82610d65565b6040516001600160a01b038216907fdfabe479bad36782fb1e77fbfddd4e382671713527e4786cfc93a022ae76372990600090a250565b600080610cb9704c454e44494e475f504f4f4c5f434f524560781b610511565b91505090565b600061044f702a27a5a2a72fa224a9aa2924a12aaa27a960791b610511565b610ce6610aae565b610d25576040805162461bcd60e51b81526020600482018190526024820152600080516020611a9c833981519152604482015290519081900360640190fd5b610d2e8161102c565b50565b600061044f6b2322a2afa82927ab24a222a960a11b610511565b600061044f6b50524943455f4f5241434c4560a01b610511565b6000610d7083610511565b60408051306024808301919091528251808303909101815260449091019091526020810180516001600160e01b031663189acdbd60e31b17905290915081906001600160a01b038216610f2a57604051610dc9906110cc565b604051809103906000f080158015610de5573d6000803e3d6000fd5b509150816001600160a01b031663cf7a1d778530846040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610e76578181015183820152602001610e5e565b50505050905090810190601f168015610ea35780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015610ec457600080fd5b505af1158015610ed8573d6000803e3d6000fd5b50505050610ee68583610ffe565b6040805186815290516001600160a01b038416917f1eb35cb4b5bbb23d152f3b4016a5a46c37a07ae930ed0956aba951e231142438919081900360200190a2610ff7565b6040805163278f794360e11b81526001600160a01b03868116600483019081526024830193845284516044840152845191861693634f1ef2869389938793929160640190602085019080838360005b83811015610f91578181015183820152602001610f79565b50505050905090810190601f168015610fbe5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015610fde57600080fd5b505af1158015610ff2573d6000803e3d6000fd5b505050505b5050505050565b60009182526001602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b6001600160a01b0381166110715760405162461bcd60e51b8152600401808060200182810382526026815260200180611a766026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b61099c806110da8339019056fe608060405234801561001057600080fd5b5061097c806100206000396000f3fe6080604052600436106100705760003560e01c80638f2839701161004e5780638f2839701461015e578063cf7a1d7714610191578063d1f5789414610250578063f851a4401461030657610070565b80633659cfe61461007a5780634f1ef286146100ad5780635c60da1b1461012d575b61007861031b565b005b34801561008657600080fd5b506100786004803603602081101561009d57600080fd5b50356001600160a01b0316610335565b610078600480360360408110156100c357600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156100ee57600080fd5b82018360208201111561010057600080fd5b8035906020019184600183028401116401000000008311171561012257600080fd5b50909250905061036f565b34801561013957600080fd5b5061014261041c565b604080516001600160a01b039092168252519081900360200190f35b34801561016a57600080fd5b506100786004803603602081101561018157600080fd5b50356001600160a01b0316610459565b610078600480360360608110156101a757600080fd5b6001600160a01b0382358116926020810135909116918101906060810160408201356401000000008111156101db57600080fd5b8201836020820111156101ed57600080fd5b8035906020019184600183028401116401000000008311171561020f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610513945050505050565b6100786004803603604081101561026657600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561029157600080fd5b8201836020820111156102a357600080fd5b803590602001918460018302840111640100000000831117156102c557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610599945050505050565b34801561031257600080fd5b506101426106d9565b610323610704565b61033361032e610764565b610789565b565b61033d6107ad565b6001600160a01b0316336001600160a01b031614156103645761035f816107d2565b61036c565b61036c61031b565b50565b6103776107ad565b6001600160a01b0316336001600160a01b0316141561040f57610399836107d2565b6000836001600160a01b031683836040518083838082843760405192019450600093509091505080830381855af49150503d80600081146103f6576040519150601f19603f3d011682016040523d82523d6000602084013e6103fb565b606091505b505090508061040957600080fd5b50610417565b61041761031b565b505050565b60006104266107ad565b6001600160a01b0316336001600160a01b0316141561044e57610447610764565b9050610456565b61045661031b565b90565b6104616107ad565b6001600160a01b0316336001600160a01b03161415610364576001600160a01b0381166104bf5760405162461bcd60e51b81526004018080602001828103825260368152602001806108d76036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104e86107ad565b604080516001600160a01b03928316815291841660208301528051918290030190a161035f81610812565b600061051d610764565b6001600160a01b03161461053057600080fd5b61053a8382610599565b604080517232b4b8189c9b1b97383937bc3c9730b236b4b760691b815290519081900360130190207fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61036000199091011461059057fe5b61041782610812565b60006105a3610764565b6001600160a01b0316146105b657600080fd5b604080517f656970313936372e70726f78792e696d706c656d656e746174696f6e000000008152905190819003601c0190207f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6000199091011461061657fe5b61061f82610836565b8051156106d5576000826001600160a01b0316826040518082805190602001908083835b602083106106625780518252601f199092019160209182019101610643565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d80600081146106c2576040519150601f19603f3d011682016040523d82523d6000602084013e6106c7565b606091505b505090508061041757600080fd5b5050565b60006106e36107ad565b6001600160a01b0316336001600160a01b0316141561044e576104476107ad565b61070c6107ad565b6001600160a01b0316336001600160a01b0316141561075c5760405162461bcd60e51b81526004018080602001828103825260328152602001806108a56032913960400191505060405180910390fd5b610333610333565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e8080156107a8573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6107db81610836565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b61083f8161089e565b61087a5760405162461bcd60e51b815260040180806020018281038252603b81526020018061090d603b913960400191505060405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b3b15159056fe43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e2066726f6d207468652070726f78792061646d696e43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a265627a7a72315820629faf9dcda9b39f83f569b349f535c0c74ed00db40c8bd00c3bd4e4bbc441c264736f6c634300050e00324f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a265627a7a72315820a68f47e5a7fc5e02d607e20754a1be0db6a730b86960b645ce724058aa00b12a64736f6c634300050e0032", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/external/abi/aave/v1/LendingPoolConfigurator.json b/external/abi/aave/v1/LendingPoolConfigurator.json deleted file mode 100644 index 0421cb9f9..000000000 --- a/external/abi/aave/v1/LendingPoolConfigurator.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "contractName": "LendingPoolConfigurator", - "abi": [{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reserve","type":"address"}],"name":"BorrowingDisabledOnReserve","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_reserve","type":"address"},{"indexed":false,"internalType":"bool","name":"_stableRateEnabled","type":"bool"}],"name":"BorrowingEnabledOnReserve","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reserve","type":"address"}],"name":"ReserveActivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_reserve","type":"address"},{"indexed":false,"internalType":"uint256","name":"_ltv","type":"uint256"}],"name":"ReserveBaseLtvChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reserve","type":"address"}],"name":"ReserveDeactivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_reserve","type":"address"},{"indexed":false,"internalType":"uint256","name":"_decimals","type":"uint256"}],"name":"ReserveDecimalsChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reserve","type":"address"}],"name":"ReserveDisabledAsCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reserve","type":"address"},{"indexed":false,"internalType":"uint256","name":"_ltv","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_liquidationThreshold","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_liquidationBonus","type":"uint256"}],"name":"ReserveEnabledAsCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reserve","type":"address"}],"name":"ReserveFreezed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reserve","type":"address"},{"indexed":true,"internalType":"address","name":"_aToken","type":"address"},{"indexed":false,"internalType":"address","name":"_interestRateStrategyAddress","type":"address"}],"name":"ReserveInitialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_reserve","type":"address"},{"indexed":false,"internalType":"address","name":"_strategy","type":"address"}],"name":"ReserveInterestRateStrategyChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_reserve","type":"address"},{"indexed":false,"internalType":"uint256","name":"_bonus","type":"uint256"}],"name":"ReserveLiquidationBonusChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_reserve","type":"address"},{"indexed":false,"internalType":"uint256","name":"_threshold","type":"uint256"}],"name":"ReserveLiquidationThresholdChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reserve","type":"address"}],"name":"ReserveRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reserve","type":"address"}],"name":"ReserveUnfreezed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reserve","type":"address"}],"name":"StableRateDisabledOnReserve","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reserve","type":"address"}],"name":"StableRateEnabledOnReserve","type":"event"},{"constant":true,"inputs":[],"name":"CONFIGURATOR_REVISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"poolAddressesProvider","outputs":[{"internalType":"contract LendingPoolAddressesProvider","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract LendingPoolAddressesProvider","name":"_poolAddressesProvider","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint8","name":"_underlyingAssetDecimals","type":"uint8"},{"internalType":"address","name":"_interestRateStrategyAddress","type":"address"}],"name":"initReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"string","name":"_aTokenName","type":"string"},{"internalType":"string","name":"_aTokenSymbol","type":"string"},{"internalType":"uint8","name":"_underlyingAssetDecimals","type":"uint8"},{"internalType":"address","name":"_interestRateStrategyAddress","type":"address"}],"name":"initReserveWithData","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserveToRemove","type":"address"}],"name":"removeLastAddedReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"bool","name":"_stableBorrowRateEnabled","type":"bool"}],"name":"enableBorrowingOnReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"disableBorrowingOnReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint256","name":"_baseLTVasCollateral","type":"uint256"},{"internalType":"uint256","name":"_liquidationThreshold","type":"uint256"},{"internalType":"uint256","name":"_liquidationBonus","type":"uint256"}],"name":"enableReserveAsCollateral","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"disableReserveAsCollateral","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"enableReserveStableBorrowRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"disableReserveStableBorrowRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"activateReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"deactivateReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"freezeReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"unfreezeReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint256","name":"_ltv","type":"uint256"}],"name":"setReserveBaseLTVasCollateral","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint256","name":"_threshold","type":"uint256"}],"name":"setReserveLiquidationThreshold","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint256","name":"_bonus","type":"uint256"}],"name":"setReserveLiquidationBonus","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint256","name":"_decimals","type":"uint256"}],"name":"setReserveDecimals","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_rateStrategyAddress","type":"address"}],"name":"setReserveInterestRateStrategyAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"refreshLendingPoolCoreConfiguration","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}], - "metadata": "{\"compiler\":{\"version\":\"0.5.14+commit.01f1aaa4\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"}],\"name\":\"BorrowingDisabledOnReserve\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_stableRateEnabled\",\"type\":\"bool\"}],\"name\":\"BorrowingEnabledOnReserve\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"}],\"name\":\"ReserveActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_ltv\",\"type\":\"uint256\"}],\"name\":\"ReserveBaseLtvChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"}],\"name\":\"ReserveDeactivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_decimals\",\"type\":\"uint256\"}],\"name\":\"ReserveDecimalsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"}],\"name\":\"ReserveDisabledAsCollateral\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_ltv\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_liquidationThreshold\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_liquidationBonus\",\"type\":\"uint256\"}],\"name\":\"ReserveEnabledAsCollateral\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"}],\"name\":\"ReserveFreezed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_aToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_interestRateStrategyAddress\",\"type\":\"address\"}],\"name\":\"ReserveInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_strategy\",\"type\":\"address\"}],\"name\":\"ReserveInterestRateStrategyChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_bonus\",\"type\":\"uint256\"}],\"name\":\"ReserveLiquidationBonusChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"ReserveLiquidationThresholdChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"}],\"name\":\"ReserveRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"}],\"name\":\"ReserveUnfreezed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"}],\"name\":\"StableRateDisabledOnReserve\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"}],\"name\":\"StableRateEnabledOnReserve\",\"type\":\"event\"},{\"constant\":true,\"inputs\":[],\"name\":\"CONFIGURATOR_REVISION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"}],\"name\":\"activateReserve\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"}],\"name\":\"deactivateReserve\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"}],\"name\":\"disableBorrowingOnReserve\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"}],\"name\":\"disableReserveAsCollateral\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"}],\"name\":\"disableReserveStableBorrowRate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_stableBorrowRateEnabled\",\"type\":\"bool\"}],\"name\":\"enableBorrowingOnReserve\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_baseLTVasCollateral\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_liquidationThreshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_liquidationBonus\",\"type\":\"uint256\"}],\"name\":\"enableReserveAsCollateral\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"}],\"name\":\"enableReserveStableBorrowRate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"}],\"name\":\"freezeReserve\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"_underlyingAssetDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"_interestRateStrategyAddress\",\"type\":\"address\"}],\"name\":\"initReserve\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_aTokenName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_aTokenSymbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"_underlyingAssetDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"_interestRateStrategyAddress\",\"type\":\"address\"}],\"name\":\"initReserveWithData\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract LendingPoolAddressesProvider\",\"name\":\"_poolAddressesProvider\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"poolAddressesProvider\",\"outputs\":[{\"internalType\":\"contract LendingPoolAddressesProvider\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"refreshLendingPoolCoreConfiguration\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reserveToRemove\",\"type\":\"address\"}],\"name\":\"removeLastAddedReserve\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_ltv\",\"type\":\"uint256\"}],\"name\":\"setReserveBaseLTVasCollateral\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_decimals\",\"type\":\"uint256\"}],\"name\":\"setReserveDecimals\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_rateStrategyAddress\",\"type\":\"address\"}],\"name\":\"setReserveInterestRateStrategyAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_bonus\",\"type\":\"uint256\"}],\"name\":\"setReserveLiquidationBonus\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"setReserveLiquidationThreshold\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reserve\",\"type\":\"address\"}],\"name\":\"unfreezeReserve\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Aave\",\"methods\":{\"activateReserve(address)\":{\"details\":\"activates a reserve\",\"params\":{\"_reserve\":\"the address of the reserve*\"}},\"deactivateReserve(address)\":{\"details\":\"deactivates a reserve\",\"params\":{\"_reserve\":\"the address of the reserve*\"}},\"disableBorrowingOnReserve(address)\":{\"details\":\"disables borrowing on a reserve\",\"params\":{\"_reserve\":\"the address of the reserve*\"}},\"disableReserveAsCollateral(address)\":{\"details\":\"disables a reserve as collateral\",\"params\":{\"_reserve\":\"the address of the reserve*\"}},\"disableReserveStableBorrowRate(address)\":{\"details\":\"disable stable rate borrowing on a reserve\",\"params\":{\"_reserve\":\"the address of the reserve*\"}},\"enableBorrowingOnReserve(address,bool)\":{\"details\":\"enables borrowing on a reserve\",\"params\":{\"_reserve\":\"the address of the reserve\",\"_stableBorrowRateEnabled\":\"true if stable borrow rate needs to be enabled by default on this reserve*\"}},\"enableReserveAsCollateral(address,uint256,uint256,uint256)\":{\"details\":\"enables a reserve to be used as collateral\",\"params\":{\"_baseLTVasCollateral\":\"the loan to value of the asset when used as collateral\",\"_liquidationBonus\":\"the bonus liquidators receive to liquidate this asset*\",\"_liquidationThreshold\":\"the threshold at which loans using this asset as collateral will be considered undercollateralized\",\"_reserve\":\"the address of the reserve\"}},\"enableReserveStableBorrowRate(address)\":{\"details\":\"enable stable rate borrowing on a reserve\",\"params\":{\"_reserve\":\"the address of the reserve*\"}},\"freezeReserve(address)\":{\"details\":\"freezes a reserve. A freezed reserve doesn't accept any new deposit, borrow or rate swap, but can accept repayments, liquidations, rate rebalances and redeems\",\"params\":{\"_reserve\":\"the address of the reserve*\"}},\"initReserve(address,uint8,address)\":{\"details\":\"initializes a reserve\",\"params\":{\"_interestRateStrategyAddress\":\"the address of the interest rate strategy contract for this reserve*\",\"_reserve\":\"the address of the reserve to be initialized\",\"_underlyingAssetDecimals\":\"the decimals of the reserve underlying asset\"}},\"initReserveWithData(address,string,string,uint8,address)\":{\"details\":\"initializes a reserve using aTokenData provided externally (useful if the underlying ERC20 contract doesn't expose name or decimals)\",\"params\":{\"_aTokenName\":\"the name of the aToken contract\",\"_aTokenSymbol\":\"the symbol of the aToken contract\",\"_interestRateStrategyAddress\":\"the address of the interest rate strategy contract for this reserve*\",\"_reserve\":\"the address of the reserve to be initialized\",\"_underlyingAssetDecimals\":\"the decimals of the reserve underlying asset\"}},\"refreshLendingPoolCoreConfiguration()\":{\"details\":\"refreshes the lending pool core configuration to update the cached address*\"},\"removeLastAddedReserve(address)\":{\"details\":\"removes the last added reserve in the list of the reserves\",\"params\":{\"_reserveToRemove\":\"the address of the reserve*\"}},\"setReserveBaseLTVasCollateral(address,uint256)\":{\"details\":\"emitted when a reserve loan to value is updated\",\"params\":{\"_ltv\":\"the new value for the loan to value*\",\"_reserve\":\"the address of the reserve\"}},\"setReserveDecimals(address,uint256)\":{\"details\":\"updates the reserve decimals\",\"params\":{\"_decimals\":\"the new number of decimals*\",\"_reserve\":\"the address of the reserve\"}},\"setReserveInterestRateStrategyAddress(address,address)\":{\"details\":\"sets the interest rate strategy of a reserve\",\"params\":{\"_rateStrategyAddress\":\"the new address of the interest strategy contract*\",\"_reserve\":\"the address of the reserve\"}},\"setReserveLiquidationBonus(address,uint256)\":{\"details\":\"updates the liquidation bonus of a reserve\",\"params\":{\"_bonus\":\"the new value for the liquidation bonus*\",\"_reserve\":\"the address of the reserve\"}},\"setReserveLiquidationThreshold(address,uint256)\":{\"details\":\"updates the liquidation threshold of a reserve.\",\"params\":{\"_reserve\":\"the address of the reserve\",\"_threshold\":\"the new value for the liquidation threshold*\"}},\"unfreezeReserve(address)\":{\"details\":\"unfreezes a reserve\",\"params\":{\"_reserve\":\"the address of the reserve*\"}}},\"title\":\"LendingPoolConfigurator contract\"},\"userdoc\":{\"methods\":{},\"notice\":\"Executes configuration methods on the LendingPoolCore contract. Allows to enable/disable reserves, and set different protocol parameters.*\"}},\"settings\":{\"compilationTarget\":{\"/src/contracts/lendingpool/LendingPoolConfigurator.sol\":\"LendingPoolConfigurator\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"/src/contracts/configuration/AddressStorage.sol\":{\"keccak256\":\"0x079fa4d71c003221d60845732d33079b160e5669d06a61c36127bbfe3845b171\",\"urls\":[\"bzz-raw://ab0a2319a9f2df5c8b2b547786bef5b368ab713a1dfd811293eb92b6451f2d3b\",\"dweb:/ipfs/QmPamCovqkLEK34zW6nKreYToxFeE7R11mojiQegAJxZyM\"]},\"/src/contracts/configuration/LendingPoolAddressesProvider.sol\":{\"keccak256\":\"0x356a58b82ecc5f0076de1809cfb09f6560e9cb49b07ba02c507e157022c04bc9\",\"urls\":[\"bzz-raw://604442728d63c1cf25db9659ce7ad4357be9cdd2cb8e29d27a297fe701a077a9\",\"dweb:/ipfs/QmU8oYLESnuMGTY5ZRQRAvK9Gp2SmXxEXcdtju1ZXQJNry\"]},\"/src/contracts/configuration/LendingPoolParametersProvider.sol\":{\"keccak256\":\"0x031e4238c489c8fce9f6f5133010df47ccbbb3f45c175d11246411f0bdde20be\",\"urls\":[\"bzz-raw://73680439b66d04a661a69fe6e1107c6779723a8bae134252a3f33bb8efa07f8b\",\"dweb:/ipfs/QmZBv3VjSKBAjzdkepa4zKCMs8LUE5LashAAgrUDM12u7X\"]},\"/src/contracts/configuration/UintStorage.sol\":{\"keccak256\":\"0x3f74e899243a66d556c0fa81875ab95ed1e3af1909b0281d03fe89590b95121f\",\"urls\":[\"bzz-raw://be1e401270af075398906fbcaaa7d9d9b3e1a9018ee54617d92b0822eb875b27\",\"dweb:/ipfs/QmVC1qpZKqDb2cWegSpQYHzeraowgqfyryvguU19Qb8tgF\"]},\"/src/contracts/flashloan/interfaces/IFlashLoanReceiver.sol\":{\"keccak256\":\"0xa27643e29a0521cfedde2059c8c558a39b4ce17d20e66970fa6770426e9677c9\",\"urls\":[\"bzz-raw://3eddb6e660e2024a8f85f920261e991014ffd50002868084aba9ac40b5331e2a\",\"dweb:/ipfs/QmZ4DQMGS2WUTeejFdJrMrjyCcjd4PhYrqMgP1ZhTdpTnv\"]},\"/src/contracts/interfaces/IFeeProvider.sol\":{\"keccak256\":\"0xffc3aa98b71f2914098e428d53c56e8a11adc4a3c9c83366ca603e2c900e548e\",\"urls\":[\"bzz-raw://79789a649b7530983bc660033ba1bbf20d6f68dafe6a2a0eb380a2e0a2401c4c\",\"dweb:/ipfs/QmWLyjkjaEBm2awHhXzSNn8pQG9hktDk9HoXSYbP8aN8NA\"]},\"/src/contracts/interfaces/ILendingPoolAddressesProvider.sol\":{\"keccak256\":\"0xff6bbb9e7fa67ac67f807e4986863fae87d623266b2970cd102b892b5ed185af\",\"urls\":[\"bzz-raw://bd3978e384688d2fb0295ab42b3fe74c331b12d63a0d8c8f70b35d2d99c6c0f4\",\"dweb:/ipfs/QmaLfhk99FPfPNfLvJER9QtrpEKeBzgHVGjRNDYvrqXyWN\"]},\"/src/contracts/interfaces/ILendingRateOracle.sol\":{\"keccak256\":\"0xc8b4cdfd6a34c4b8d74b71815cbe861e7d48e692f0684be8d5de0b395b6b705f\",\"urls\":[\"bzz-raw://1c3586b0ed32ed7673b4e2031cb3af6881d21f20a30f395434bc39fa65de737a\",\"dweb:/ipfs/QmWSF386UA1NShQ7Q7WqozqrumnCWXDSxuFTgrnx4BjJcL\"]},\"/src/contracts/interfaces/IPriceOracleGetter.sol\":{\"keccak256\":\"0x58175d019ae6f47b4941461ba27dfe6afcc20d146e9bdb7a949902c7330803f3\",\"urls\":[\"bzz-raw://e118d81569a54c84d66c259d46e481e32cba80f56e99300a6a083b554421be4f\",\"dweb:/ipfs/QmVhbHRHdV8y2XgqznQg4CJGF8anFQctGDSsANGNi8TER9\"]},\"/src/contracts/interfaces/IReserveInterestRateStrategy.sol\":{\"keccak256\":\"0x2cac3923ddccd52d48ec16c12f8542c264b1dba0ceba8ed55dcae6a0ff3ece27\",\"urls\":[\"bzz-raw://6adddcb0f99f6749e3c42b0e36c59c867aba6a537c902d85de8005f37b24e781\",\"dweb:/ipfs/QmeBJBDZaaXrN8793Y4a3YP9VpNLVe3AwmQu163qoAG7Cg\"]},\"/src/contracts/lendingpool/LendingPool.sol\":{\"keccak256\":\"0xef91d23cb64c8dd2de9c744684bd2ed31fd3a33f414fd76df2c8e7382b92f9b0\",\"urls\":[\"bzz-raw://f5634207dc071b4dcd07f9e47895442ecb08bba28adf615b93394ccade34be70\",\"dweb:/ipfs/QmadpwuC5EJddsdPtkDcFfSwTzu1L34scVqtPc38nMXj51\"]},\"/src/contracts/lendingpool/LendingPoolConfigurator.sol\":{\"keccak256\":\"0xcd2aadb971445ce78ce86554af415ad852796a1134a05f8191b57738c25bf2fb\",\"urls\":[\"bzz-raw://6ce0eb60c935d9e10092ca1c2e01984acf303f0122827c3476439e0b2e30d86b\",\"dweb:/ipfs/QmSTmNszqBFoGHuPr5KQc2wrffgmbj1Puyi5odc46hmTwJ\"]},\"/src/contracts/lendingpool/LendingPoolCore.sol\":{\"keccak256\":\"0xd00405f2782adcee9c916bec9259588264676b632b9190f90f6f7ce09f638733\",\"urls\":[\"bzz-raw://9493d06fea985bd499d23b23a826cdb6ba98b6d490366059ae4329fa9cace0a3\",\"dweb:/ipfs/QmcUsbtpTiW7jMVSmeGxbvJ3PeYhQVCkQApNA5qaxjsxpy\"]},\"/src/contracts/lendingpool/LendingPoolDataProvider.sol\":{\"keccak256\":\"0x41fdf7523036ed4426586e3041666a7ffb898395e89e60314b73f0808adb447e\",\"urls\":[\"bzz-raw://669b4d5084057dec439d82004ee3bfcd308bd17be9be24e829e93fcc7e6a65fd\",\"dweb:/ipfs/QmTEaybrFnU9MY8fb9nz1Xs8HK7dfaGwCxuvheT3fgDUbD\"]},\"/src/contracts/lendingpool/LendingPoolLiquidationManager.sol\":{\"keccak256\":\"0xf130f16d2c6e1bed86234cded830078ba127240a938d14c9abcfb0bdc395bedb\",\"urls\":[\"bzz-raw://0d6c49774ad6a4642ce5f9bc01776a1536886e73070de4e1c4755cab43724701\",\"dweb:/ipfs/QmThyRdcJ64usHxzpX7UbSwMRVqYL9nUUVpG5ERDgtCaNR\"]},\"/src/contracts/libraries/CoreLibrary.sol\":{\"keccak256\":\"0x43f37e31a7282e30514500b91d1b903ad1631a629e3dcef39eeff9451b7f1abc\",\"urls\":[\"bzz-raw://79bcdff9122703983fce65a9da94f19c7ac8b2f232b87ca03399fedf1724112d\",\"dweb:/ipfs/QmZesZ1pDGfTKo4UsjEmcfcBpDY6oZ2kxK6hjDxWRM7jZW\"]},\"/src/contracts/libraries/EthAddressLib.sol\":{\"keccak256\":\"0x6d13f10408208ebff44123254f6db03121a8fb5a73d84c2d94f4e9651932b70d\",\"urls\":[\"bzz-raw://50b64d66e1544fcef496cc68e98cee61cfbab58685dfc4d57f73a1308e3aec2a\",\"dweb:/ipfs/QmQwJ5ZpaNjrfREruW7RzppzbEv8Mxxj5Ln87DX1i1iXW5\"]},\"/src/contracts/libraries/WadRayMath.sol\":{\"keccak256\":\"0xeb4c4581bf5809af3759c4793839ad29c36d145cd8fca113de5ebd1e3590ccd6\",\"urls\":[\"bzz-raw://61d6f32727cd51873af3ccbe67eff38e0c947dd7cb77b0a1d0151e8bfb02de0b\",\"dweb:/ipfs/QmPhw2nUfiRBJeeu4yDdVrMqeNC8AEGzniH1TG69gjx3p3\"]},\"/src/contracts/libraries/openzeppelin-upgradeability/BaseAdminUpgradeabilityProxy.sol\":{\"keccak256\":\"0xf2e16a1f8871ef17d0401642558c4f1596f6524859fa01443cfde837c2879544\",\"urls\":[\"bzz-raw://13199ef810b7f2188fbde76096f5e411c35f2ef6b032e82694b9ab2c8eb8810c\",\"dweb:/ipfs/QmSKPwEwbbJ7GAZveoyqAkQzyskN27WeNfTfP2VKED7zGF\"]},\"/src/contracts/libraries/openzeppelin-upgradeability/BaseUpgradeabilityProxy.sol\":{\"keccak256\":\"0x832aa0ecb5fbd8585fe96d96f7ca6417c318fe29f228f8e8c3b4f382602709d0\",\"urls\":[\"bzz-raw://c3fa785c03ca09e4d68d3addde1d5ba97d96d9a402e7c09fc892e1666fdabad2\",\"dweb:/ipfs/Qmbbof1LwgU1cgpW8L3zQeMW6iyjGM24qJBZ7aVVwjqgoC\"]},\"/src/contracts/libraries/openzeppelin-upgradeability/InitializableAdminUpgradeabilityProxy.sol\":{\"keccak256\":\"0x21e6b79157ff2014d20b18a380d9b0bdedc5fcb220d7210ba52e78de288dca28\",\"urls\":[\"bzz-raw://4e49eb1a180bc34c74ca96c9982ff93c2c8f4410dd6d7861ace0959936e1857d\",\"dweb:/ipfs/QmV4HjFmkyx2sMj6Ghda5XNYFKtHL5QG9qbagtHdzPVKAM\"]},\"/src/contracts/libraries/openzeppelin-upgradeability/InitializableUpgradeabilityProxy.sol\":{\"keccak256\":\"0x90dd0f65ee16a11f2c1f413bf13dc8b153b8c41854c8c3965b42f99a2200cd1d\",\"urls\":[\"bzz-raw://3e14953656bbc19d812ee9fc418a4df69100782194ca95bf757f3987a718be66\",\"dweb:/ipfs/QmcTmFcZMbesvtScuRYenfiPdHXbG9sWxPRswHdsFGozRB\"]},\"/src/contracts/libraries/openzeppelin-upgradeability/Proxy.sol\":{\"keccak256\":\"0xd8dcdaaf2f03c606a569d91506958bf78df9adfb41df76727857e5dfe956e872\",\"urls\":[\"bzz-raw://1d780033022b07478621ce08cd4e668603fc899ae3212a883eea23347937e8d5\",\"dweb:/ipfs/QmVZkBHpdDjko87qT4597e3UZ5uYdrEfPYbamEjBep52Se\"]},\"/src/contracts/libraries/openzeppelin-upgradeability/UpgradeabilityProxy.sol\":{\"keccak256\":\"0x5829b59012f64d1ce3ae6b98a61ddf5d6daa6e6f1a54e336ce910c8afd415c69\",\"urls\":[\"bzz-raw://28cba7d1f3d67aab91a4f88df4cb63762b443c31cb62a87e957add0b43dc8e1a\",\"dweb:/ipfs/QmUXzpQDBXA2xGSNRqjn3VMJ3o8RXmpATieU9ovvk6QDAD\"]},\"/src/contracts/libraries/openzeppelin-upgradeability/VersionedInitializable.sol\":{\"keccak256\":\"0x8691eb3d853842f32d3b1e65c788f3db226901ec82c3de52c21eb029dc7f545b\",\"urls\":[\"bzz-raw://c46f6c422db674265552cb12abce67088e23fbec2723a5d1173058e2b0f3378a\",\"dweb:/ipfs/QmXnBcGWAX8wAvZngxxVwvAPKpxnZ8ABdWKaf8cYb25qns\"]},\"/src/contracts/tokenization/AToken.sol\":{\"keccak256\":\"0x53e5167142bfbfe0367f8101996353d718e79bbdd100eae9c4ee4fc3ab503e14\",\"urls\":[\"bzz-raw://806418e40e4bb0a03fcdbb578e77d4fc14464f5a3df348b6f51b83cdaef7db77\",\"dweb:/ipfs/QmSixjXLSHJiWhkPaaiWBxtKxrzwSuhwG7iSFWGMFTY2ah\"]},\"openzeppelin-solidity/contracts/math/SafeMath.sol\":{\"keccak256\":\"0x4ccf2d7b51873db1ccfd54ca2adae5eac3b184f9699911ed4490438419f1c690\",\"urls\":[\"bzz-raw://d62d769b2219d5de39013093412623e624fa887f871826ea3bae6052ee893610\",\"dweb:/ipfs/QmV3yVktya1s617QmuzQR2CfuJgUi3dR2xEZY9ecmqZ2G1\"]},\"openzeppelin-solidity/contracts/ownership/Ownable.sol\":{\"keccak256\":\"0xf79fb10e8235770eb4aea7249034076a3cc9f9119ad944fc48705bae9c9d20dc\",\"urls\":[\"bzz-raw://cd3429aa9a4878dcf6c73faa32c3722f4013d4be012ece543b246faa6b50f55c\",\"dweb:/ipfs/QmS55hgTvNEAKinus19m65CB4wcymN8EiUPFpRx5tYJ1i2\"]},\"openzeppelin-solidity/contracts/token/ERC20/ERC20.sol\":{\"keccak256\":\"0x852793a3c2f86d336a683b30d688ec3dcfc57451af5a2bf5975cda3b7191a901\",\"urls\":[\"bzz-raw://4f5b57664069671648fb81f55b0082faecdf1b2f159eec6b1fa6cef9b7d73bc5\",\"dweb:/ipfs/QmcyytaLs7zFdb4Uu7C5PmQRhQdB3wA3fUdkV6mkYfdDFH\"]},\"openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol\":{\"keccak256\":\"0xc61b3603089b09a730d8ca72e9133a496cc4405da40e9b87c12f073245d774bf\",\"urls\":[\"bzz-raw://de8bb0003d53de236913f0e0102e7a9d015e02098f2495edd000f207fe2be2f4\",\"dweb:/ipfs/QmbtwNwAJEehWWL7yGGyyMoenQvcqtz91pqLgQPpLRoLYC\"]},\"openzeppelin-solidity/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x90e8c2521653bbb1768b05889c5760031e688d9cd361f167489b89215e201b95\",\"urls\":[\"bzz-raw://d0abb99bb8bfc2bc0a89902b8ed1dc0442ad08cc78cee64c291b3df6a27bcccc\",\"dweb:/ipfs/QmP5NaEwZthQeM2ESz4WTT3osrP7jhbvu7ocbttBi2JAw6\"]},\"openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol\":{\"keccak256\":\"0xf6f89424e17870561dc23c5933c55c5726b66a68d51ad2a2c00c569a5f02f507\",\"urls\":[\"bzz-raw://005657a7ffbf6d12726ac0167b55be965dc473d43f061b605f883a54cc00ab4f\",\"dweb:/ipfs/QmaBzyvDQyNnn6DXQYewEtN9Go85orikSnW9PwNWqUGPEX\"]},\"openzeppelin-solidity/contracts/utils/Address.sol\":{\"keccak256\":\"0xf3358e5819ca73357abd6c90bdfffd0474af54364897f6b3e3234c4b71fbe9a1\",\"urls\":[\"bzz-raw://75ae8d04454d1511a2ed986cc8585736f05c5c25280683b3d24712a9f414a4bf\",\"dweb:/ipfs/Qmb3kNCoBUZdah1AgBBD4zMk898j5Qw8ahT1w5cCMYp5Y3\"]},\"openzeppelin-solidity/contracts/utils/ReentrancyGuard.sol\":{\"keccak256\":\"0x0441ff2b36d503f3a29d28d3754291f119064f4973d5c780698143d919037a78\",\"urls\":[\"bzz-raw://af27dd68d2371e68c8ed8cf297ec6d832bf906742d53367b70399ba918060cb7\",\"dweb:/ipfs/QmcMMjZceFepXgRrzSx577oWwt7SCSFzoqZiTF7tTxquF7\"]}},\"version\":1}", - "bytecode": "0x60806040526000805534801561001457600080fd5b50615355806100246000396000f3fe60806040523480156200001157600080fd5b5060043610620001605760003560e01c8063a8dc0f4511620000c9578063d466016f1162000087578063d466016f1462000550578063dae4c4e7146200057f578063e12dcc6c14620005a8578063e8ae2f5b14620005b2578063eede87c114620005db578063ef1f9373146200060c5762000160565b8063a8dc0f451462000483578063b75d6f3414620004ac578063b8c0f74514620004d5578063c4d66de814620004fe578063d06e2ec114620005275762000160565b806366bbd928116200012357806366bbd928146200037f57806370fb84f414620003ae5780637aca76eb14620003dd5780637af635a6146200040657806380e17d871462000422578063a5bc826c14620004485762000160565b8063071033e414620001655780631d2118f914620001a35780633443a14b14620001d457806336805a6214620002035780633e72a4541462000356575b600080fd5b620001a1600480360360608110156200017d57600080fd5b506001600160a01b03813581169160ff602082013516916040909101351662000635565b005b620001a160048036036040811015620001bb57600080fd5b506001600160a01b038135811691602001351662000a6a565b620001a160048036036040811015620001ec57600080fd5b506001600160a01b03813516906020013562000c52565b620001a1600480360360a08110156200021b57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156200024657600080fd5b8201836020820111156200025957600080fd5b803590602001918460018302840111600160201b831117156200027b57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b811115620002ce57600080fd5b820183602082011115620002e157600080fd5b803590602001918460018302840111600160201b831117156200030357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505050813560ff16925050602001356001600160a01b031662000e38565b620001a1600480360360208110156200036e57600080fd5b50356001600160a01b03166200117e565b620001a1600480360360408110156200039757600080fd5b506001600160a01b03813516906020013562001410565b620001a160048036036040811015620003c657600080fd5b506001600160a01b038135169060200135620015f6565b620001a160048036036020811015620003f557600080fd5b50356001600160a01b0316620017dc565b62000410620019aa565b60408051918252519081900360200190f35b6200042c620019af565b604080516001600160a01b039092168252519081900360200190f35b620001a1600480360360808110156200046057600080fd5b506001600160a01b038135169060208101359060408101359060600135620019be565b620001a1600480360360208110156200049b57600080fd5b50356001600160a01b031662001bbc565b620001a160048036036020811015620004c457600080fd5b50356001600160a01b031662001d8a565b620001a160048036036020811015620004ed57600080fd5b50356001600160a01b031662001f58565b620001a1600480360360208110156200051657600080fd5b50356001600160a01b031662002126565b620001a1600480360360208110156200053f57600080fd5b50356001600160a01b0316620021e8565b620001a1600480360360408110156200056857600080fd5b506001600160a01b038135169060200135620023b6565b620001a1600480360360208110156200059757600080fd5b50356001600160a01b03166200259c565b620001a16200276a565b620001a160048036036020811015620005ca57600080fd5b50356001600160a01b0316620028fa565b620001a160048036036040811015620005f357600080fd5b506001600160a01b038135169060200135151562002ac8565b620001a1600480360360208110156200062457600080fd5b50356001600160a01b031662002cb0565b603454604080516333128d5960e01b8152905133926001600160a01b0316916333128d59916004808301926020929190829003018186803b1580156200067a57600080fd5b505afa1580156200068f573d6000803e3d6000fd5b505050506040513d6020811015620006a657600080fd5b50516001600160a01b031614620006ef5760405162461bcd60e51b8152600401808060200182810382526029815260200180620052a06029913960400191505060405180910390fd5b60008390506060816001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200073057600080fd5b505afa15801562000745573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156200076f57600080fd5b8101908080516040519392919084600160201b8211156200078f57600080fd5b908301906020820185811115620007a557600080fd5b8251600160201b811182820188101715620007bf57600080fd5b82525081516020918201929091019080838360005b83811015620007ee578181015183820152602001620007d4565b50505050905090810190601f1680156200081c5780820380516001836020036101000a031916815260200191505b50604052505050604051602001808075020b0bb329024b73a32b932b9ba103132b0b934b733960551b81525060160182805190602001908083835b60208310620008785780518252601f19909201916020918201910162000857565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405290506060826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015620008ea57600080fd5b505afa158015620008ff573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156200092957600080fd5b8101908080516040519392919084600160201b8211156200094957600080fd5b9083019060208201858111156200095f57600080fd5b8251600160201b8111828201881017156200097957600080fd5b82525081516020918201929091019080838360005b83811015620009a85781810151838201526020016200098e565b50505050905090810190601f168015620009d65780820380516001836020036101000a031916815260200191505b506040525050506040516020018080606160f81b81525060010182805190602001908083835b6020831062000a1d5780518252601f199092019160209182019101620009fc565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052905062000a62868383888862000e38565b505050505050565b603454604080516333128d5960e01b8152905133926001600160a01b0316916333128d59916004808301926020929190829003018186803b15801562000aaf57600080fd5b505afa15801562000ac4573d6000803e3d6000fd5b505050506040513d602081101562000adb57600080fd5b50516001600160a01b03161462000b245760405162461bcd60e51b8152600401808060200182810382526029815260200180620052a06029913960400191505060405180910390fd5b6034546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b15801562000b6a57600080fd5b505afa15801562000b7f573d6000803e3d6000fd5b505050506040513d602081101562000b9657600080fd5b505160408051631d2118f960e01b81526001600160a01b0386811660048301528581166024830152915192935090831691631d2118f99160448082019260009290919082900301818387803b15801562000bef57600080fd5b505af115801562000c04573d6000803e3d6000fd5b5050604080516001600160a01b0380881682528616602082015281517f5644b64ebb0ce18c4032248ca52f58355469092ff072866c3dcd8640e817d6a59450908190039091019150a1505050565b603454604080516333128d5960e01b8152905133926001600160a01b0316916333128d59916004808301926020929190829003018186803b15801562000c9757600080fd5b505afa15801562000cac573d6000803e3d6000fd5b505050506040513d602081101562000cc357600080fd5b50516001600160a01b03161462000d0c5760405162461bcd60e51b8152600401808060200182810382526029815260200180620052a06029913960400191505060405180910390fd5b6034546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b15801562000d5257600080fd5b505afa15801562000d67573d6000803e3d6000fd5b505050506040513d602081101562000d7e57600080fd5b505160408051633443a14b60e01b81526001600160a01b03868116600483015260248201869052915192935090831691633443a14b9160448082019260009290919082900301818387803b15801562000dd657600080fd5b505af115801562000deb573d6000803e3d6000fd5b5050604080516001600160a01b03871681526020810186905281517f437dd3b61b7c7eee7fc70515c8846482dfca92e2e1e02af5d638c5d4878d67149450908190039091019150a1505050565b603454604080516333128d5960e01b8152905133926001600160a01b0316916333128d59916004808301926020929190829003018186803b15801562000e7d57600080fd5b505afa15801562000e92573d6000803e3d6000fd5b505050506040513d602081101562000ea957600080fd5b50516001600160a01b03161462000ef25760405162461bcd60e51b8152600401808060200182810382526029815260200180620052a06029913960400191505060405180910390fd5b6034546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b15801562000f3857600080fd5b505afa15801562000f4d573d6000803e3d6000fd5b505050506040513d602081101562000f6457600080fd5b50516034546040519192506000916001600160a01b0390911690889086908990899062000f919062002e89565b6001600160a01b038087168252851660208083019190915260ff8516604083015260a06060830181815285519184019190915284519091608084019160c085019187019080838360005b8381101562000ff557818101518382015260200162000fdb565b50505050905090810190601f168015620010235780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015620010585781810151838201526020016200103e565b50505050905090810190601f168015620010865780820380516001836020036101000a031916815260200191505b50975050505050505050604051809103906000f080158015620010ad573d6000803e3d6000fd5b5060408051630114cc2960e61b81526001600160a01b038a81166004830152808416602483015260ff8816604483015286811660648301529151929350908416916345330a409160848082019260009290919082900301818387803b1580156200111657600080fd5b505af11580156200112b573d6000803e3d6000fd5b5050604080516001600160a01b03878116825291518286169450918b1692507f1d9fcd0dc935b4778d5af97f55c4d7b2553257382f1ef25c412114c8eeebd88e919081900360200190a350505050505050565b603454604080516333128d5960e01b8152905133926001600160a01b0316916333128d59916004808301926020929190829003018186803b158015620011c357600080fd5b505afa158015620011d8573d6000803e3d6000fd5b505050506040513d6020811015620011ef57600080fd5b50516001600160a01b031614620012385760405162461bcd60e51b8152600401808060200182810382526029815260200180620052a06029913960400191505060405180910390fd5b6034546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b1580156200127e57600080fd5b505afa15801562001293573d6000803e3d6000fd5b505050506040513d6020811015620012aa57600080fd5b505160408051630c33cfd960e41b81526001600160a01b03858116600483015291519293509083169163c33cfd9091602480820192602092909190829003018186803b158015620012fa57600080fd5b505afa1580156200130f573d6000803e3d6000fd5b505050506040513d60208110156200132657600080fd5b505115620013665760405162461bcd60e51b815260040180806020018281038252602a815260200180620052f7602a913960400191505060405180910390fd5b806001600160a01b0316633e72a454836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050600060405180830381600087803b158015620013bf57600080fd5b505af1158015620013d4573d6000803e3d6000fd5b50506040516001600160a01b03851692507f6f60cf8bd0f218cabe1ea3150bd07b0b758c35c4cfdf7138017a283e65564d5e9150600090a25050565b603454604080516333128d5960e01b8152905133926001600160a01b0316916333128d59916004808301926020929190829003018186803b1580156200145557600080fd5b505afa1580156200146a573d6000803e3d6000fd5b505050506040513d60208110156200148157600080fd5b50516001600160a01b031614620014ca5760405162461bcd60e51b8152600401808060200182810382526029815260200180620052a06029913960400191505060405180910390fd5b6034546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b1580156200151057600080fd5b505afa15801562001525573d6000803e3d6000fd5b505050506040513d60208110156200153c57600080fd5b505160408051630cd77b2560e31b81526001600160a01b038681166004830152602482018690529151929350908316916366bbd9289160448082019260009290919082900301818387803b1580156200159457600080fd5b505af1158015620015a9573d6000803e3d6000fd5b5050604080516001600160a01b03871681526020810186905281517f2e73b7f1df792712003e6859f940c1e8711c3f1329474771fee71d2ec11631299450908190039091019150a1505050565b603454604080516333128d5960e01b8152905133926001600160a01b0316916333128d59916004808301926020929190829003018186803b1580156200163b57600080fd5b505afa15801562001650573d6000803e3d6000fd5b505050506040513d60208110156200166757600080fd5b50516001600160a01b031614620016b05760405162461bcd60e51b8152600401808060200182810382526029815260200180620052a06029913960400191505060405180910390fd5b6034546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b158015620016f657600080fd5b505afa1580156200170b573d6000803e3d6000fd5b505050506040513d60208110156200172257600080fd5b505160408051631c3ee13d60e21b81526001600160a01b038681166004830152602482018690529151929350908316916370fb84f49160448082019260009290919082900301818387803b1580156200177a57600080fd5b505af11580156200178f573d6000803e3d6000fd5b5050604080516001600160a01b03871681526020810186905281517fe3ba662f7011e701056a43e8cf832242322eeff01453e7a72d01ec2af36d9aec9450908190039091019150a1505050565b603454604080516333128d5960e01b8152905133926001600160a01b0316916333128d59916004808301926020929190829003018186803b1580156200182157600080fd5b505afa15801562001836573d6000803e3d6000fd5b505050506040513d60208110156200184d57600080fd5b50516001600160a01b031614620018965760405162461bcd60e51b8152600401808060200182810382526029815260200180620052a06029913960400191505060405180910390fd5b6034546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b158015620018dc57600080fd5b505afa158015620018f1573d6000803e3d6000fd5b505050506040513d60208110156200190857600080fd5b505160408051637aca76eb60e01b81526001600160a01b038581166004830152915192935090831691637aca76eb9160248082019260009290919082900301818387803b1580156200195957600080fd5b505af11580156200196e573d6000803e3d6000fd5b50506040516001600160a01b03851692507fda5cdb66c77023db6abe5226a4d4a40c3b8e768012f4ff4e446f62f60127fc569150600090a25050565b600381565b6034546001600160a01b031681565b603454604080516333128d5960e01b8152905133926001600160a01b0316916333128d59916004808301926020929190829003018186803b15801562001a0357600080fd5b505afa15801562001a18573d6000803e3d6000fd5b505050506040513d602081101562001a2f57600080fd5b50516001600160a01b03161462001a785760405162461bcd60e51b8152600401808060200182810382526029815260200180620052a06029913960400191505060405180910390fd5b6034546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b15801562001abe57600080fd5b505afa15801562001ad3573d6000803e3d6000fd5b505050506040513d602081101562001aea57600080fd5b50516040805163296f209b60e21b81526001600160a01b03888116600483015260248201889052604482018790526064820186905291519293509083169163a5bc826c9160848082019260009290919082900301818387803b15801562001b5057600080fd5b505af115801562001b65573d6000803e3d6000fd5b5050604080518781526020810187905280820186905290516001600160a01b03891693507fdfe62f53e7707d64f99bca15d2bdf3facc4074bc047e7dec2ea130300e99274492509081900360600190a25050505050565b603454604080516333128d5960e01b8152905133926001600160a01b0316916333128d59916004808301926020929190829003018186803b15801562001c0157600080fd5b505afa15801562001c16573d6000803e3d6000fd5b505050506040513d602081101562001c2d57600080fd5b50516001600160a01b03161462001c765760405162461bcd60e51b8152600401808060200182810382526029815260200180620052a06029913960400191505060405180910390fd5b6034546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b15801562001cbc57600080fd5b505afa15801562001cd1573d6000803e3d6000fd5b505050506040513d602081101562001ce857600080fd5b50516040805163a8dc0f4560e01b81526001600160a01b03858116600483015291519293509083169163a8dc0f459160248082019260009290919082900301818387803b15801562001d3957600080fd5b505af115801562001d4e573d6000803e3d6000fd5b50506040516001600160a01b03851692507fe9a7e5fd4fc8ea18e602350324bf48e8f05d12434af0ce0be05743e6a5fdcb9e9150600090a25050565b603454604080516333128d5960e01b8152905133926001600160a01b0316916333128d59916004808301926020929190829003018186803b15801562001dcf57600080fd5b505afa15801562001de4573d6000803e3d6000fd5b505050506040513d602081101562001dfb57600080fd5b50516001600160a01b03161462001e445760405162461bcd60e51b8152600401808060200182810382526029815260200180620052a06029913960400191505060405180910390fd5b6034546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b15801562001e8a57600080fd5b505afa15801562001e9f573d6000803e3d6000fd5b505050506040513d602081101562001eb657600080fd5b505160408051632dd75bcd60e21b81526001600160a01b03858116600483015291519293509083169163b75d6f349160248082019260009290919082900301818387803b15801562001f0757600080fd5b505af115801562001f1c573d6000803e3d6000fd5b50506040516001600160a01b03851692507f35b80cd8ea3440e9a8454f116fa658b858da1b64c86c48451f4559cefcdfb56c9150600090a25050565b603454604080516333128d5960e01b8152905133926001600160a01b0316916333128d59916004808301926020929190829003018186803b15801562001f9d57600080fd5b505afa15801562001fb2573d6000803e3d6000fd5b505050506040513d602081101562001fc957600080fd5b50516001600160a01b031614620020125760405162461bcd60e51b8152600401808060200182810382526029815260200180620052a06029913960400191505060405180910390fd5b6034546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b1580156200205857600080fd5b505afa1580156200206d573d6000803e3d6000fd5b505050506040513d60208110156200208457600080fd5b50516040805163b8c0f74560e01b81526001600160a01b03858116600483015291519293509083169163b8c0f7459160248082019260009290919082900301818387803b158015620020d557600080fd5b505af1158015620020ea573d6000803e3d6000fd5b50506040516001600160a01b03851692507f8bbf35441ac2c607ddecadd3d8ee58636d32f217fad201fb2655581502dd84e39150600090a25050565b60006200213262002e7e565b60015490915060ff16806200214c57506200214c62002e83565b8062002159575060005481115b620021965760405162461bcd60e51b815260040180806020018281038252602e815260200180620052c9602e913960400191505060405180910390fd5b60015460ff16158015620021b6576001805460ff19168117905560008290555b603480546001600160a01b0319166001600160a01b0385161790558015620021e3576001805460ff191690555b505050565b603454604080516333128d5960e01b8152905133926001600160a01b0316916333128d59916004808301926020929190829003018186803b1580156200222d57600080fd5b505afa15801562002242573d6000803e3d6000fd5b505050506040513d60208110156200225957600080fd5b50516001600160a01b031614620022a25760405162461bcd60e51b8152600401808060200182810382526029815260200180620052a06029913960400191505060405180910390fd5b6034546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b158015620022e857600080fd5b505afa158015620022fd573d6000803e3d6000fd5b505050506040513d60208110156200231457600080fd5b50516040805163d06e2ec160e01b81526001600160a01b03858116600483015291519293509083169163d06e2ec19160248082019260009290919082900301818387803b1580156200236557600080fd5b505af11580156200237a573d6000803e3d6000fd5b50506040516001600160a01b03851692507f19dbf059e4d3a0cb998d4328b7b991bbe312827eeb053d8ff63edf33158e01db9150600090a25050565b603454604080516333128d5960e01b8152905133926001600160a01b0316916333128d59916004808301926020929190829003018186803b158015620023fb57600080fd5b505afa15801562002410573d6000803e3d6000fd5b505050506040513d60208110156200242757600080fd5b50516001600160a01b031614620024705760405162461bcd60e51b8152600401808060200182810382526029815260200180620052a06029913960400191505060405180910390fd5b6034546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b158015620024b657600080fd5b505afa158015620024cb573d6000803e3d6000fd5b505050506040513d6020811015620024e257600080fd5b50516040805163d466016f60e01b81526001600160a01b0386811660048301526024820186905291519293509083169163d466016f9160448082019260009290919082900301818387803b1580156200253a57600080fd5b505af11580156200254f573d6000803e3d6000fd5b5050604080516001600160a01b03871681526020810186905281517fda47540c7f7fd5a68c3285f3bb708f322424f948f41df6f51622fa24b39686649450908190039091019150a1505050565b603454604080516333128d5960e01b8152905133926001600160a01b0316916333128d59916004808301926020929190829003018186803b158015620025e157600080fd5b505afa158015620025f6573d6000803e3d6000fd5b505050506040513d60208110156200260d57600080fd5b50516001600160a01b031614620026565760405162461bcd60e51b8152600401808060200182810382526029815260200180620052a06029913960400191505060405180910390fd5b6034546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b1580156200269c57600080fd5b505afa158015620026b1573d6000803e3d6000fd5b505050506040513d6020811015620026c857600080fd5b50516040805163dae4c4e760e01b81526001600160a01b03858116600483015291519293509083169163dae4c4e79160248082019260009290919082900301818387803b1580156200271957600080fd5b505af11580156200272e573d6000803e3d6000fd5b50506040516001600160a01b03851692507f8dee2b2f3e98319ae6347eda521788f73f4086c9be9a594942b370b137fb8cb19150600090a25050565b603454604080516333128d5960e01b8152905133926001600160a01b0316916333128d59916004808301926020929190829003018186803b158015620027af57600080fd5b505afa158015620027c4573d6000803e3d6000fd5b505050506040513d6020811015620027db57600080fd5b50516001600160a01b031614620028245760405162461bcd60e51b8152600401808060200182810382526029815260200180620052a06029913960400191505060405180910390fd5b6034546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b1580156200286a57600080fd5b505afa1580156200287f573d6000803e3d6000fd5b505050506040513d60208110156200289657600080fd5b505160408051636468108360e01b815290519192506001600160a01b0383169163646810839160048082019260009290919082900301818387803b158015620028de57600080fd5b505af1158015620028f3573d6000803e3d6000fd5b5050505050565b603454604080516333128d5960e01b8152905133926001600160a01b0316916333128d59916004808301926020929190829003018186803b1580156200293f57600080fd5b505afa15801562002954573d6000803e3d6000fd5b505050506040513d60208110156200296b57600080fd5b50516001600160a01b031614620029b45760405162461bcd60e51b8152600401808060200182810382526029815260200180620052a06029913960400191505060405180910390fd5b6034546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b158015620029fa57600080fd5b505afa15801562002a0f573d6000803e3d6000fd5b505050506040513d602081101562002a2657600080fd5b50516040805163e8ae2f5b60e01b81526001600160a01b03858116600483015291519293509083169163e8ae2f5b9160248082019260009290919082900301818387803b15801562002a7757600080fd5b505af115801562002a8c573d6000803e3d6000fd5b50506040516001600160a01b03851692507f9cc75e4cafc9a556a369bc53468649075680eb554d225d5918f199453824796d9150600090a25050565b603454604080516333128d5960e01b8152905133926001600160a01b0316916333128d59916004808301926020929190829003018186803b15801562002b0d57600080fd5b505afa15801562002b22573d6000803e3d6000fd5b505050506040513d602081101562002b3957600080fd5b50516001600160a01b03161462002b825760405162461bcd60e51b8152600401808060200182810382526029815260200180620052a06029913960400191505060405180910390fd5b6034546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b15801562002bc857600080fd5b505afa15801562002bdd573d6000803e3d6000fd5b505050506040513d602081101562002bf457600080fd5b50516040805163eede87c160e01b81526001600160a01b038681166004830152851515602483015291519293509083169163eede87c19160448082019260009290919082900301818387803b15801562002c4d57600080fd5b505af115801562002c62573d6000803e3d6000fd5b5050604080516001600160a01b0387168152851515602082015281517fab2f7f9e5ca2772fafa94f355c1842a80ae6b9e41f83083098d81f67d7a0b5089450908190039091019150a1505050565b603454604080516333128d5960e01b8152905133926001600160a01b0316916333128d59916004808301926020929190829003018186803b15801562002cf557600080fd5b505afa15801562002d0a573d6000803e3d6000fd5b505050506040513d602081101562002d2157600080fd5b50516001600160a01b03161462002d6a5760405162461bcd60e51b8152600401808060200182810382526029815260200180620052a06029913960400191505060405180910390fd5b6034546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b15801562002db057600080fd5b505afa15801562002dc5573d6000803e3d6000fd5b505050506040513d602081101562002ddc57600080fd5b50516040805163ef1f937360e01b81526001600160a01b03858116600483015291519293509083169163ef1f93739160248082019260009290919082900301818387803b15801562002e2d57600080fd5b505af115801562002e42573d6000803e3d6000fd5b50506040516001600160a01b03851692507f995959c2ceab6ce20e8cd89c904e449fd3e21918a0f420c9ec9340595585526b9150600090a25050565b600390565b303b1590565b6124088062002e988339019056fe60806040523480156200001157600080fd5b506040516200240838038062002408833981810160405260a08110156200003757600080fd5b8151602083015160408085015160608601805192519496939591949391820192846401000000008211156200006b57600080fd5b9083019060208201858111156200008157600080fd5b82516401000000008111828201881017156200009c57600080fd5b82525081516020918201929091019080838360005b83811015620000cb578181015183820152602001620000b1565b50505050905090810190601f168015620000f95780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011d57600080fd5b9083019060208201858111156200013357600080fd5b82516401000000008111828201881017156200014e57600080fd5b82525081516020918201929091019080838360005b838110156200017d57818101518382015260200162000163565b50505050905090810190601f168015620001ab5780820380516001836020036101000a031916815260200191505b506040525050508181848260039080519060200190620001cd929190620003da565b508151620001e3906004906020850190620003da565b506005805460ff191660ff929092169190911790555050600a80546001600160a01b0319166001600160a01b0387811691909117918290556040805163076b7fbb60e51b81529051929091169163ed6ff76091600480820192602092909190829003018186803b1580156200025757600080fd5b505afa1580156200026c573d6000803e3d6000fd5b505050506040513d60208110156200028357600080fd5b5051600b80546001600160a01b0319166001600160a01b03928316179055600a5460408051630261bf8b60e01b815290519190921691630261bf8b916004808301926020929190829003018186803b158015620002df57600080fd5b505afa158015620002f4573d6000803e3d6000fd5b505050506040513d60208110156200030b57600080fd5b5051600c80546001600160a01b0319166001600160a01b03928316179055600a5460408051632f58b80d60e01b815290519190921691632f58b80d916004808301926020929190829003018186803b1580156200036757600080fd5b505afa1580156200037c573d6000803e3d6000fd5b505050506040513d60208110156200039357600080fd5b5051600d80546001600160a01b0319166001600160a01b0392831617905560058054610100600160a81b031916610100969092169590950217909355506200047f92505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200041d57805160ff19168380011785556200044d565b828001600101855582156200044d579182015b828111156200044d57825182559160200191906001019062000430565b506200045b9291506200045f565b5090565b6200047c91905b808211156200045b576000815560010162000466565b90565b611f79806200048f6000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80635eae177c116100de578063a9059cbb11610097578063db006a7511610071578063db006a75146104f3578063dd62ed3e14610510578063ee9907a41461053e578063f866c3191461056457610173565b8063a9059cbb14610499578063c634dfaa146104c5578063d0fc81d2146104eb57610173565b80635eae177c146103df57806370a082311461040b57806389d1a0fc1461043157806394362e8b1461043957806395d89b4114610465578063a457c2d71461046d57610173565b806323b872dd1161013057806323b872dd146102c3578063313ce567146102f9578063325a9b131461031757806339509351146103455780633edb7cb814610371578063445e80101461039d57610173565b806306fdde0314610178578063095ea7b3146101f55780630e49072d1461023557806312c87c2d1461025d57806318160ddd146102835780631d51e7cf1461029d575b600080fd5b61018061059a565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101ba5781810151838201526020016101a2565b50505050905090810190601f1680156101e75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102216004803603604081101561020b57600080fd5b506001600160a01b038135169060200135610631565b604080519115158252519081900360200190f35b61025b6004803603602081101561024b57600080fd5b50356001600160a01b0316610648565b005b61025b6004803603602081101561027357600080fd5b50356001600160a01b0316610655565b61028b6106f4565b60408051918252519081900360200190f35b61028b600480360360208110156102b357600080fd5b50356001600160a01b03166107b6565b610221600480360360608110156102d957600080fd5b506001600160a01b038135811691602081013590911690604001356107d5565b61030161082c565b6040805160ff9092168252519081900360200190f35b61025b6004803603604081101561032d57600080fd5b506001600160a01b0381358116916020013516610835565b6102216004803603604081101561035b57600080fd5b506001600160a01b03813516906020013561089b565b61025b6004803603604081101561038757600080fd5b506001600160a01b0381351690602001356108d7565b6103c3600480360360208110156103b357600080fd5b50356001600160a01b03166109cc565b604080516001600160a01b039092168252519081900360200190f35b610221600480360360408110156103f557600080fd5b506001600160a01b0381351690602001356109ea565b61028b6004803603602081101561042157600080fd5b50356001600160a01b0316610a85565b6103c3610b38565b61025b6004803603604081101561044f57600080fd5b506001600160a01b038135169060200135610b4c565b610180610c21565b6102216004803603604081101561048357600080fd5b506001600160a01b038135169060200135610c82565b610221600480360360408110156104af57600080fd5b506001600160a01b038135169060200135610cbe565b61028b600480360360208110156104db57600080fd5b50356001600160a01b0316610ccb565b61028b610cd6565b61025b6004803603602081101561050957600080fd5b5035610cdc565b61028b6004803603604081101561052657600080fd5b506001600160a01b0381358116916020013516610f16565b61028b6004803603602081101561055457600080fd5b50356001600160a01b0316610f41565b61025b6004803603606081101561057a57600080fd5b506001600160a01b03813581169160208101359091169060400135610f5c565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106265780601f106105fb57610100808354040283529160200191610626565b820191906000526020600020905b81548152906001019060200180831161060957829003601f168201915b505050505090505b90565b600061063e338484610fb5565b5060015b92915050565b61065233826110a1565b50565b6001600160a01b03811633141561069d5760405162461bcd60e51b8152600401808060200182810382526025815260200180611d8d6025913960400191505060405180910390fd5b3360008181526009602052604080822080546001600160a01b0319166001600160a01b03861690811790915590519092917fc2d6a42a9d5273283f73009a07aacfb043f2f91173a8d9d33b504afe898db08b91a350565b6000806106ff611290565b90508061071057600091505061062e565b600b546005546040805163d15e005360e01b81526001600160a01b036101009093048316600482015290516107b0936107ab93169163d15e0053916024808301926020929190829003018186803b15801561076a57600080fd5b505afa15801561077e573d6000803e3d6000fd5b505050506040513d602081101561079457600080fd5b505161079f84611296565b9063ffffffff6112ac16565b6112f7565b91505090565b6001600160a01b0381166000908152600860205260409020545b919050565b60006107e2848484611310565b6001600160a01b03841660009081526001602090815260408083203380855292529091205461082291869161081d908663ffffffff61137f16565b610fb5565b5060019392505050565b60055460ff1690565b6001600160a01b0382811660009081526009602052604090205416331461088d5760405162461bcd60e51b815260040180806020018281038252603a815260200180611f0b603a913960400191505060405180910390fd5b61089782826110a1565b5050565b3360008181526001602090815260408083206001600160a01b0387168452909152812054909161063e91859061081d908663ffffffff6113dc16565b600c546001600160a01b031633146109205760405162461bcd60e51b8152600401808060200182810382526032815260200180611ed96032913960400191505060405180910390fd5b600080600061092e85611436565b93509350935050610940858386611527565b61094a858561165e565b600061095c848663ffffffff61137f16565b61096c5761096986611737565b90505b856001600160a01b03167f90e5d3d68ec162d9c7de393037a3ede04dd44f68e051bf2ace4a73c299dbc4db8685846109a457856109a7565b60005b60408051938452602084019290925282820152519081900360600190a2505050505050565b6001600160a01b039081166000908152600760205260409020541690565b600d54600554604080516376e9d61560e01b81526101009092046001600160a01b039081166004840152858116602484015260448301859052905160009391909116916376e9d615916064808301926020929190829003018186803b158015610a5257600080fd5b505afa158015610a66573d6000803e3d6000fd5b505050506040513d6020811015610a7c57600080fd5b50519392505050565b600080610a91836117e9565b6001600160a01b03841660009081526008602052604090205490915081158015610ab9575080155b15610ac9576000925050506107d0565b6001600160a01b0384811660009081526007602052604090205416610b1a57610b1181610b0586610b00868463ffffffff6113dc16565b611804565b9063ffffffff61137f16565b925050506107d0565b610b11610b2b82610b058785611804565b839063ffffffff6113dc16565b60055461010090046001600160a01b031681565b600c546001600160a01b03163314610b955760405162461bcd60e51b8152600401808060200182810382526032815260200180611ed96032913960400191505060405180910390fd5b600080610ba184611436565b935093505050610bc584610bbe85856113dc90919063ffffffff16565b6000611527565b610bcf84846118b9565b604080518481526020810184905280820183905290516001600160a01b038616917fbe7799898ca2d813ff902b487c1b434ab45b47edd8f38b77ad5e99aae8341b7a919081900360600190a250505050565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106265780601f106105fb57610100808354040283529160200191610626565b3360008181526001602090815260408083206001600160a01b0387168452909152812054909161063e91859061081d908663ffffffff61137f16565b600061063e338484611310565b6000610642826117e9565b60001981565b60008111610d31576040805162461bcd60e51b815260206004820181905260248201527f416d6f756e7420746f2072656465656d206e6565647320746f206265203e2030604482015290519081900360640190fd5b6000806000610d3f33611436565b91955093509150849050600019811415610d565750825b83811115610d955760405162461bcd60e51b8152600401808060200182810382526032815260200180611d396032913960400191505060405180910390fd5b610d9f33826109ea565b610df0576040805162461bcd60e51b815260206004820152601b60248201527f5472616e736665722063616e6e6f7420626520616c6c6f7765642e0000000000604482015290519081900360640190fd5b610dfb338483611527565b610e05338261165e565b6000610e17858363ffffffff61137f16565b610e2757610e2433611737565b90505b600c546005546001600160a01b0391821691639895e3d8916101009004163385610e578a8263ffffffff61137f16565b6040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b03168152602001838152602001828152602001945050505050600060405180830381600087803b158015610ec657600080fd5b505af1158015610eda573d6000803e3d6000fd5b50505050336001600160a01b03167fbd5034ffbd47e4e72a94baa2cdb74c6fad73cb3bcdc13036b72ec8306f5a76468386846109a457866109a7565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b031660009081526006602052604090205490565b600c546001600160a01b03163314610fa55760405162461bcd60e51b8152600401808060200182810382526032815260200180611ed96032913960400191505060405180910390fd5b610fb08383836119a9565b505050565b6001600160a01b038316610ffa5760405162461bcd60e51b8152600401808060200182810382526024815260200180611eb56024913960400191505060405180910390fd5b6001600160a01b03821661103f5760405162461bcd60e51b8152600401808060200182810382526022815260200180611d6b6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0380831660009081526007602052604090205481169082168114156110fe5760405162461bcd60e51b815260040180806020018281038252602a815260200180611dd3602a913960400191505060405180910390fd5b60008060008061110d87611436565b9350935093509350600083116111545760405162461bcd60e51b8152600401808060200182810382526042815260200180611dfd6042913960600191505060405180910390fd5b6001600160a01b0385161561116f5761116f87600086611527565b866001600160a01b0316866001600160a01b031614156111fb576001600160a01b038716600081815260076020908152604080832080546001600160a01b03191690558051878152918201869052818101859052519192917f5e3cad45b1fe24159d1cb39788d82d0f69cc15770aa96fba1d3d1a73487355949181900360600190a35050505050610897565b6001600160a01b03878116600090815260076020526040812080546001600160a01b031916928916929092179091556112379088908590611527565b604080518481526020810184905280820183905290516001600160a01b0380891692908a16917f5e3cad45b1fe24159d1cb39788d82d0f69cc15770aa96fba1d3d1a73487355949181900360600190a350505050505050565b60025490565b600061064282633b9aca0063ffffffff611ad816565b60006112f06b033b2e3c9fd0803ce80000006112e46112d1868663ffffffff611ad816565b6b019d971e4fe8401e74000000906113dc565b9063ffffffff611b3116565b9392505050565b6000631dcd65006112f0633b9aca006112e483866113dc565b828161131c82826109ea565b61136d576040805162461bcd60e51b815260206004820152601b60248201527f5472616e736665722063616e6e6f7420626520616c6c6f7765642e0000000000604482015290519081900360640190fd5b6113788585856119a9565b5050505050565b6000828211156113d6576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6000828201838110156112f0576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000806000806000611447866117e9565b9050600061145882610b0589610a85565b905061146487826118b9565b600b546005546040805163d15e005360e01b81526101009092046001600160a01b0390811660048401529051600093919091169163d15e0053916024808301926020929190829003018186803b1580156114bd57600080fd5b505afa1580156114d1573d6000803e3d6000fd5b505050506040513d60208110156114e757600080fd5b50516001600160a01b0389166000908152600660205260409020819055905082611517818463ffffffff6113dc16565b9099909850919650945092505050565b6001600160a01b03808416600090815260076020526040902054168061154d5750610fb0565b60008061155983611436565b6001600160a01b038716600090815260086020526040902054919550935061158f9250869150610b05908863ffffffff6113dc16565b6001600160a01b03808516600090815260086020908152604080832094909455600790529190912054168015611602576001600160a01b0381166000908152600860205260409020546115e8908463ffffffff6113dc16565b6001600160a01b0382166000908152600860205260409020555b60408051848152602081018490528082018890526060810187905290516001600160a01b038616917f70ff8cf632603e2bfd1afb7e4061acce53d95356b1be9726b99fa22ba733b01f919081900360800190a250505050505050565b6001600160a01b0382166116a35760405162461bcd60e51b8152600401808060200182810382526021815260200180611e6f6021913960400191505060405180910390fd5b6002546116b6908263ffffffff61137f16565b6002556001600160a01b0382166000908152602081905260409020546116e2908263ffffffff61137f16565b6001600160a01b038316600081815260208181526040808320949094558351858152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35050565b6001600160a01b038116600081815260076020908152604080832080546001600160a01b03191690558051838152918201839052818101839052519192839290917f5e3cad45b1fe24159d1cb39788d82d0f69cc15770aa96fba1d3d1a7348735594919081900360600190a36001600160a01b0382166000908152600860205260409020546117e157506001600160a01b03811660009081526006602052604081205560016107d0565b5060006107d0565b6001600160a01b031660009081526020819052604090205490565b6001600160a01b03808316600090815260066020908152604080832054600b54600554835163d15e005360e01b815261010090910487166004820152925194956112f0956107ab9593946118ad94939092169263d15e00539260248082019391829003018186803b15801561187857600080fd5b505afa15801561188c573d6000803e3d6000fd5b505050506040513d60208110156118a257600080fd5b505161079f87611296565b9063ffffffff611b9b16565b6001600160a01b038216611914576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b600254611927908263ffffffff6113dc16565b6002556001600160a01b038216600090815260208190526040902054611953908263ffffffff6113dc16565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600081116119e85760405162461bcd60e51b8152600401808060200182810382526030815260200180611e3f6030913960400191505060405180910390fd5b60008060006119f686611436565b93509350935050600080611a0987611436565b935093505050611a1a888588611527565b611a2e87610bbe848963ffffffff6113dc16565b611a39888888611bd3565b6000611a4b868863ffffffff61137f16565b611a5b57611a5889611737565b90505b876001600160a01b0316896001600160a01b03167f89a178eaa27e0cd201bd795ca8ff716ac0df9618494510ca79771cfc66ffcde889888786611a9e5789611aa1565b60005b60408051948552602085019390935283830191909152606083015260808201879052519081900360a00190a3505050505050505050565b600082611ae757506000610642565b82820282848281611af457fe5b04146112f05760405162461bcd60e51b8152600401808060200182810382526021815260200180611db26021913960400191505060405180910390fd5b6000808211611b87576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b6000828481611b9257fe5b04949350505050565b600060028204611bcb836112e4611bbe876b033b2e3c9fd0803ce8000000611ad8565b849063ffffffff6113dc16565b949350505050565b6001600160a01b038316611c185760405162461bcd60e51b8152600401808060200182810382526025815260200180611e906025913960400191505060405180910390fd5b6001600160a01b038216611c5d5760405162461bcd60e51b8152600401808060200182810382526023815260200180611d166023913960400191505060405180910390fd5b6001600160a01b038316600090815260208190526040902054611c86908263ffffffff61137f16565b6001600160a01b038085166000908152602081905260408082209390935590841681522054611cbb908263ffffffff6113dc16565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a350505056fe45524332303a207472616e7366657220746f20746865207a65726f2061646472657373557365722063616e6e6f742072656465656d206d6f7265207468616e2074686520617661696c61626c652062616c616e636545524332303a20617070726f766520746f20746865207a65726f2061646472657373557365722063616e6e6f74206769766520616c6c6f77616e636520746f2068696d73656c66536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77496e74657265737420697320616c7265616479207265646972656374656420746f207468652075736572496e7465726573742073747265616d2063616e206f6e6c79206265207265646972656374656420696620746865726520697320612076616c69642062616c616e63655472616e7366657272656420616d6f756e74206e6565647320746f2062652067726561746572207468616e207a65726f45524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735468652063616c6c6572206f6620746869732066756e6374696f6e206d7573742062652061206c656e64696e6720706f6f6c43616c6c6572206973206e6f7420616c6c6f77656420746f2072656469726563742074686520696e746572657374206f66207468652075736572a265627a7a723158207029b8e2a8a6dcf81be1753ab59bc1690f3f41e58fae43086d4df87ae569744a64736f6c634300050e00325468652063616c6c6572206d7573742062652061206c656e64696e6720706f6f6c206d616e61676572436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564546865206c6971756964697479206f66207468652072657365727665206e6565647320746f2062652030a265627a7a723158204d1ce711fae011c6ec420d2fa7c3b24e8848bb2b27ac9badf545b5cfb599753864736f6c634300050e0032", - "deployedBytecode": "" -} diff --git a/external/abi/aave/v1/LendingPoolCore.json b/external/abi/aave/v1/LendingPoolCore.json deleted file mode 100644 index 193002049..000000000 --- a/external/abi/aave/v1/LendingPoolCore.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "contractName": "LendingPoolCore", - "abi": [{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"reserve","type":"address"},{"indexed":false,"internalType":"uint256","name":"liquidityRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stableBorrowRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"variableBorrowRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidityIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"variableBorrowIndex","type":"uint256"}],"name":"ReserveUpdated","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":true,"inputs":[],"name":"CORE_REVISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"addressesProvider","outputs":[{"internalType":"contract LendingPoolAddressesProvider","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lendingPoolAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"reservesList","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract LendingPoolAddressesProvider","name":"_addressesProvider","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_isFirstDeposit","type":"bool"}],"name":"updateStateOnDeposit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amountRedeemed","type":"uint256"},{"internalType":"bool","name":"_userRedeemedEverything","type":"bool"}],"name":"updateStateOnRedeem","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint256","name":"_availableLiquidityBefore","type":"uint256"},{"internalType":"uint256","name":"_income","type":"uint256"},{"internalType":"uint256","name":"_protocolFee","type":"uint256"}],"name":"updateStateOnFlashLoan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amountBorrowed","type":"uint256"},{"internalType":"uint256","name":"_borrowFee","type":"uint256"},{"internalType":"enum CoreLibrary.InterestRateMode","name":"_rateMode","type":"uint8"}],"name":"updateStateOnBorrow","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_paybackAmountMinusFees","type":"uint256"},{"internalType":"uint256","name":"_originationFeeRepaid","type":"uint256"},{"internalType":"uint256","name":"_balanceIncrease","type":"uint256"},{"internalType":"bool","name":"_repaidWholeLoan","type":"bool"}],"name":"updateStateOnRepay","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_principalBorrowBalance","type":"uint256"},{"internalType":"uint256","name":"_compoundedBorrowBalance","type":"uint256"},{"internalType":"uint256","name":"_balanceIncrease","type":"uint256"},{"internalType":"enum CoreLibrary.InterestRateMode","name":"_currentRateMode","type":"uint8"}],"name":"updateStateOnSwapRate","outputs":[{"internalType":"enum CoreLibrary.InterestRateMode","name":"","type":"uint8"},{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_principalReserve","type":"address"},{"internalType":"address","name":"_collateralReserve","type":"address"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amountToLiquidate","type":"uint256"},{"internalType":"uint256","name":"_collateralToLiquidate","type":"uint256"},{"internalType":"uint256","name":"_feeLiquidated","type":"uint256"},{"internalType":"uint256","name":"_liquidatedCollateralForFee","type":"uint256"},{"internalType":"uint256","name":"_balanceIncrease","type":"uint256"},{"internalType":"bool","name":"_liquidatorReceivesAToken","type":"bool"}],"name":"updateStateOnLiquidation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_balanceIncrease","type":"uint256"}],"name":"updateStateOnRebalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"bool","name":"_useAsCollateral","type":"bool"}],"name":"setUserUseReserveAsCollateral","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address payable","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"transferToUser","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_destination","type":"address"}],"name":"transferToFeeCollectionAddress","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_destination","type":"address"}],"name":"liquidateFee","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address payable","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"transferToReserve","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"getUserBasicReserveData","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"isUserAllowedToBorrowAtStable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"getUserUnderlyingAssetBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveInterestRateStrategyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveATokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveAvailableLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveTotalLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveNormalizedIncome","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveTotalBorrows","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveTotalBorrowsStable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveTotalBorrowsVariable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveLiquidationThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveLiquidationBonus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveCurrentVariableBorrowRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveCurrentStableBorrowRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveCurrentAverageStableBorrowRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveCurrentLiquidityRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveLiquidityCumulativeIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveVariableBorrowsCumulativeIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveConfiguration","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"isReserveBorrowingEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"isReserveUsageAsCollateralEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveIsStableBorrowRateEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveIsFreezed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveLastUpdate","outputs":[{"internalType":"uint40","name":"timestamp","type":"uint40"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveUtilizationRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getReserves","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"isUserUseReserveAsCollateralEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"getUserOriginationFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"getUserCurrentBorrowRateMode","outputs":[{"internalType":"enum CoreLibrary.InterestRateMode","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"getUserCurrentStableBorrowRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"getUserBorrowBalances","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"getUserVariableBorrowCumulativeIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"getUserLastUpdate","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"refreshConfiguration","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_aTokenAddress","type":"address"},{"internalType":"uint256","name":"_decimals","type":"uint256"},{"internalType":"address","name":"_interestRateStrategyAddress","type":"address"}],"name":"initReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserveToRemove","type":"address"}],"name":"removeLastAddedReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_rateStrategyAddress","type":"address"}],"name":"setReserveInterestRateStrategyAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"bool","name":"_stableBorrowRateEnabled","type":"bool"}],"name":"enableBorrowingOnReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"disableBorrowingOnReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint256","name":"_baseLTVasCollateral","type":"uint256"},{"internalType":"uint256","name":"_liquidationThreshold","type":"uint256"},{"internalType":"uint256","name":"_liquidationBonus","type":"uint256"}],"name":"enableReserveAsCollateral","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"disableReserveAsCollateral","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"enableReserveStableBorrowRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"disableReserveStableBorrowRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"activateReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"deactivateReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"freezeReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"unfreezeReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint256","name":"_ltv","type":"uint256"}],"name":"setReserveBaseLTVasCollateral","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint256","name":"_threshold","type":"uint256"}],"name":"setReserveLiquidationThreshold","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint256","name":"_bonus","type":"uint256"}],"name":"setReserveLiquidationBonus","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint256","name":"_decimals","type":"uint256"}],"name":"setReserveDecimals","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}], - "bytecode": "0x60806040526000805534801561001457600080fd5b5061575d806100246000396000f3fe60806040526004361061041b5760003560e01c8063a2353fdc1161021e578063d15e005311610123578063e8ae2f5b116100ab578063f61483111161007a578063f6148311146113bf578063f6ea8d7614611443578063fa51854c1461147e578063fa93b2a5146114c3578063feab31ac146115065761041b565b8063e8ae2f5b146112eb578063eede87c11461131e578063ef1f937314611359578063f054ab461461138c5761041b565b8063dae4c4e7116100f2578063dae4c4e7146111d4578063e10076ad14611207578063e2174d8614611242578063e240301914611285578063e6d18190146112b85761041b565b8063d15e0053146110fc578063d3ae26b31461112f578063d466016f14611144578063da12d96f1461117d5761041b565b8063bd7fd79a116101a6578063c540148e11610175578063c540148e14611012578063c72c4d1014611045578063c76a6c9c1461105a578063c7d142371461108d578063d06e2ec1146110c95761041b565b8063bd7fd79a14610f46578063bfacad8414610f79578063c33cfd9014610fac578063c4d66de814610fdf5761041b565b8063afcdbea3116101ed578063afcdbea314610e17578063b701d09314610e62578063b75d6f3414610e95578063b8c0f74514610ec8578063bcd6ffa414610efb5761041b565b8063a2353fdc14610d29578063a5bc826c14610d5c578063a8dc0f4514610da1578063af825b0714610dd45761041b565b80635cf2e656116103245780637aca76eb116102ac578063906c0a411161027b578063906c0a4114610bfc57806398bd473714610c2f5780639e3c4f3b14610c625780639e67484814610c9d5780639fb8afcd14610cd05761041b565b80637aca76eb14610b2d5780637f90fec514610b6057806388079d8814610b935780638f385c2214610bc65761041b565b806366d103f3116102f357806366d103f3146109e057806368beb4d614610a1b5780636ae1441614610a865780636fffab0c14610ab957806370fb84f414610af45761041b565b80635cf2e656146109045780635fc526ff14610937578063646810831461099257806366bbd928146109a75761041b565b80633443a14b116103a757806345330a401161037657806345330a40146107de57806346bc0f28146108275780634a08accb1461085a5780634f1446091461088d5780634fe7a6e5146108da5761041b565b80633443a14b146106b757806334b3beee146106f057806337ac6fe41461073f5780633e72a454146107ab5761041b565b806318a4dbca116103ee57806318a4dbca1461057957806318f9bbae146105b45780631ca19f19146105e75780631d2118f91461064657806328fcf4d3146106815761041b565b806305075d6e146104615780630902f1ac146104a857806309ac29531461050d5780630c7de4e914610552575b61042433611541565b61045f5760405162461bcd60e51b81526004018080602001828103825260368152602001806154b16036913960400191505060405180910390fd5b005b34801561046d57600080fd5b506104946004803603602081101561048457600080fd5b50356001600160a01b031661154b565b604080519115158252519081900360200190f35b3480156104b457600080fd5b506104bd611573565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156104f95781810151838201526020016104e1565b505050509050019250505060405180910390f35b34801561051957600080fd5b5061045f6004803603608081101561053057600080fd5b506001600160a01b0381351690602081013590604081013590606001356115d5565b34801561055e57600080fd5b506105676116a3565b60408051918252519081900360200190f35b34801561058557600080fd5b506105676004803603604081101561059c57600080fd5b506001600160a01b03813581169160200135166116a8565b3480156105c057600080fd5b50610494600480360360208110156105d757600080fd5b50356001600160a01b031661173b565b3480156105f357600080fd5b506106226004803603604081101561060a57600080fd5b506001600160a01b0381358116916020013516611763565b6040518082600281111561063257fe5b60ff16815260200191505060405180910390f35b34801561065257600080fd5b5061045f6004803603604081101561066957600080fd5b506001600160a01b03813581169160200135166117b8565b61045f6004803603606081101561069757600080fd5b506001600160a01b0381358116916020810135909116906040013561189e565b3480156106c357600080fd5b5061045f600480360360408110156106da57600080fd5b506001600160a01b038135169060200135611a69565b3480156106fc57600080fd5b506107236004803603602081101561071357600080fd5b50356001600160a01b0316611b3d565b604080516001600160a01b039092168252519081900360200190f35b34801561074b57600080fd5b50610792600480360360a081101561076257600080fd5b5080356001600160a01b03908116916020810135909116906040810135906060810135906080013560ff16611b5e565b6040805192835260208301919091528051918290030190f35b3480156107b757600080fd5b5061045f600480360360208110156107ce57600080fd5b50356001600160a01b0316611bfe565b3480156107ea57600080fd5b5061045f6004803603608081101561080157600080fd5b506001600160a01b03813581169160208101358216916040820135916060013516611cda565b34801561083357600080fd5b506105676004803603602081101561084a57600080fd5b50356001600160a01b0316611e34565b34801561086657600080fd5b506104946004803603602081101561087d57600080fd5b50356001600160a01b0316611e52565b34801561089957600080fd5b506108c0600480360360208110156108b057600080fd5b50356001600160a01b0316611e7a565b6040805164ffffffffff9092168252519081900360200190f35b3480156108e657600080fd5b50610723600480360360208110156108fd57600080fd5b5035611ea6565b34801561091057600080fd5b506104946004803603602081101561092757600080fd5b50356001600160a01b0316611ecd565b34801561094357600080fd5b5061096a6004803603602081101561095a57600080fd5b50356001600160a01b0316611ef5565b6040805194855260208501939093528383019190915215156060830152519081900360800190f35b34801561099e57600080fd5b5061045f611f33565b3480156109b357600080fd5b5061045f600480360360408110156109ca57600080fd5b506001600160a01b038135169060200135611ff2565b3480156109ec57600080fd5b5061056760048036036040811015610a0357600080fd5b506001600160a01b03813581169160200135166120c6565b348015610a2757600080fd5b5061045f6004803603610120811015610a3f57600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060808101359060a08101359060c08101359060e081013590610100013515156120fc565b348015610a9257600080fd5b5061072360048036036020811015610aa957600080fd5b50356001600160a01b031661219e565b348015610ac557600080fd5b5061056760048036036040811015610adc57600080fd5b506001600160a01b03813581169160200135166121bf565b348015610b0057600080fd5b5061045f60048036036040811015610b1757600080fd5b506001600160a01b0381351690602001356121ee565b348015610b3957600080fd5b5061045f60048036036020811015610b5057600080fd5b50356001600160a01b03166122c2565b348015610b6c57600080fd5b5061056760048036036020811015610b8357600080fd5b50356001600160a01b03166123a4565b348015610b9f57600080fd5b5061056760048036036020811015610bb657600080fd5b50356001600160a01b03166123c2565b61045f60048036036060811015610bdc57600080fd5b506001600160a01b038135811691602081013591604090910135166124ea565b348015610c0857600080fd5b5061056760048036036020811015610c1f57600080fd5b50356001600160a01b0316612600565b348015610c3b57600080fd5b5061056760048036036020811015610c5257600080fd5b50356001600160a01b03166126b0565b348015610c6e57600080fd5b5061049460048036036040811015610c8557600080fd5b506001600160a01b03813581169160200135166126ce565b348015610ca957600080fd5b5061049460048036036020811015610cc057600080fd5b50356001600160a01b0316612707565b348015610cdc57600080fd5b50610d0b60048036036040811015610cf357600080fd5b506001600160a01b038135811691602001351661272f565b60408051938452602084019290925282820152519081900360600190f35b348015610d3557600080fd5b5061056760048036036020811015610d4c57600080fd5b50356001600160a01b03166127ba565b348015610d6857600080fd5b5061045f60048036036080811015610d7f57600080fd5b506001600160a01b0381351690602081013590604081013590606001356127d8565b348015610dad57600080fd5b5061045f60048036036020811015610dc457600080fd5b50356001600160a01b0316612926565b348015610de057600080fd5b5061056760048036036060811015610df757600080fd5b506001600160a01b03813581169160208101359091169060400135612a55565b348015610e2357600080fd5b5061045f60048036036080811015610e3a57600080fd5b506001600160a01b038135811691602081013590911690604081013590606001351515612af5565b348015610e6e57600080fd5b5061056760048036036020811015610e8557600080fd5b50356001600160a01b0316612b7d565b348015610ea157600080fd5b5061045f60048036036020811015610eb857600080fd5b50356001600160a01b0316612b9b565b348015610ed457600080fd5b5061045f60048036036020811015610eeb57600080fd5b50356001600160a01b0316612cce565b348015610f0757600080fd5b5061045f60048036036080811015610f1e57600080fd5b506001600160a01b038135811691602081013590911690604081013590606001351515612daa565b348015610f5257600080fd5b5061056760048036036020811015610f6957600080fd5b50356001600160a01b0316612e32565b348015610f8557600080fd5b5061056760048036036020811015610f9c57600080fd5b50356001600160a01b0316612e4d565b348015610fb857600080fd5b5061056760048036036020811015610fcf57600080fd5b50356001600160a01b0316612eb7565b348015610feb57600080fd5b5061045f6004803603602081101561100257600080fd5b50356001600160a01b0316612ef0565b34801561101e57600080fd5b506105676004803603602081101561103557600080fd5b50356001600160a01b0316612faf565b34801561105157600080fd5b50610723612fcd565b34801561106657600080fd5b506105676004803603602081101561107d57600080fd5b50356001600160a01b0316612fdc565b61045f600480360360808110156110a357600080fd5b506001600160a01b03813581169160208101358216916040820135916060013516612ffa565b3480156110d557600080fd5b5061045f600480360360208110156110ec57600080fd5b50356001600160a01b03166131ac565b34801561110857600080fd5b506105676004803603602081101561111f57600080fd5b50356001600160a01b03166133b1565b34801561113b57600080fd5b506107236133d2565b34801561115057600080fd5b5061045f6004803603604081101561116757600080fd5b506001600160a01b0381351690602001356133e1565b34801561118957600080fd5b5061045f600480360360c08110156111a057600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060808101359060a0013515156134b5565b3480156111e057600080fd5b5061045f600480360360208110156111f757600080fd5b50356001600160a01b0316613524565b34801561121357600080fd5b5061096a6004803603604081101561122a57600080fd5b506001600160a01b0381358116916020013516613606565b34801561124e57600080fd5b506104946004803603606081101561126557600080fd5b506001600160a01b038135811691602081013590911690604001356136b3565b34801561129157600080fd5b50610567600480360360208110156112a857600080fd5b50356001600160a01b0316613749565b3480156112c457600080fd5b50610567600480360360208110156112db57600080fd5b50356001600160a01b03166137ed565b3480156112f757600080fd5b5061045f6004803603602081101561130e57600080fd5b50356001600160a01b031661380e565b34801561132a57600080fd5b5061045f6004803603604081101561134157600080fd5b506001600160a01b0381351690602001351515613929565b34801561136557600080fd5b5061045f6004803603602081101561137c57600080fd5b50356001600160a01b0316613a60565b34801561139857600080fd5b50610567600480360360208110156113af57600080fd5b50356001600160a01b0316613b3c565b3480156113cb57600080fd5b50611418600480360360c08110156113e257600080fd5b5080356001600160a01b039081169160208101359091169060408101359060608101359060808101359060a0013560ff16613b5a565b6040518083600281111561142857fe5b60ff1681526020018281526020019250505060405180910390f35b34801561144f57600080fd5b506105676004803603604081101561146657600080fd5b506001600160a01b0381358116916020013516613bec565b34801561148a57600080fd5b5061045f600480360360608110156114a157600080fd5b506001600160a01b038135811691602081013590911690604001351515613c1b565b3480156114cf57600080fd5b5061045f600480360360608110156114e657600080fd5b506001600160a01b03813581169160208101359091169060400135613cad565b34801561151257600080fd5b506105676004803603604081101561152957600080fd5b506001600160a01b0381358116916020013516613dd4565b803b15155b919050565b6001600160a01b03166000908152603660205260409020600d0154600160e01b900460ff1690565b606060388054806020026020016040519081016040528092919081815260200182805480156115cb57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116115ad575b5050505050905090565b6034546001600160a01b0316331461161e5760405162461bcd60e51b815260040180806020018281038252602a8152602001806156b2602a913960400191505060405180910390fd5b6116288482613e03565b6001600160a01b038416600090815260366020526040902061164990613ee6565b6000611664611657866137ed565b859063ffffffff613f7e16565b6001600160a01b038616600090815260366020526040902090915061169090828563ffffffff613fd816565b61169c85846000614036565b5050505050565b600481565b6001600160a01b038083166000908152603660209081526040808320600c015481516370a0823160e01b8152868616600482015291519394169283926370a082319260248082019391829003018186803b15801561170557600080fd5b505afa158015611719573d6000803e3d6000fd5b505050506040513d602081101561172f57600080fd5b50519150505b92915050565b6001600160a01b03166000908152603660205260409020600d0154600160d01b900460ff1690565b6001600160a01b0380821660009081526037602090815260408083209386168352929052908120805461179a576000915050611735565b60008160030154116117ad5760026117b0565b60015b949350505050565b603554604080516385c858b160e01b8152905133926001600160a01b0316916385c858b1916004808301926020929190829003018186803b1580156117fc57600080fd5b505afa158015611810573d6000803e3d6000fd5b505050506040513d602081101561182657600080fd5b50516001600160a01b03161461186d5760405162461bcd60e51b81526004018080602001828103825260378152602001806156086037913960400191505060405180910390fd5b6001600160a01b039182166000908152603660205260409020600d0180546001600160a01b03191691909216179055565b6034546001600160a01b031633146118e75760405162461bcd60e51b815260040180806020018281038252602a8152602001806156b2602a913960400191505060405180910390fd5b6118ef6141cf565b6001600160a01b0316836001600160a01b0316146119645734156119445760405162461bcd60e51b81526004018080602001828103825260328152602001806155476032913960400191505060405180910390fd5b61195f6001600160a01b03841683308463ffffffff6141e716565b611a64565b803410156119a35760405162461bcd60e51b815260040180806020018281038252603581526020018061547c6035913960400191505060405180910390fd5b80341115611a645760006119bd348363ffffffff61424116565b6040519091506000906001600160a01b0385169061c35090849084818181858888f193505050503d8060008114611a10576040519150601f19603f3d011682016040523d82523d6000602084013e611a15565b606091505b505090508061169c576040805162461bcd60e51b8152602060048201526016602482015275151c985b9cd9995c881bd9881155120819985a5b195960521b604482015290519081900360640190fd5b505050565b603554604080516385c858b160e01b8152905133926001600160a01b0316916385c858b1916004808301926020929190829003018186803b158015611aad57600080fd5b505afa158015611ac1573d6000803e3d6000fd5b505050506040513d6020811015611ad757600080fd5b50516001600160a01b031614611b1e5760405162461bcd60e51b81526004018080602001828103825260378152602001806156086037913960400191505060405180910390fd5b6001600160a01b03909116600090815260366020526040902060090155565b6001600160a01b039081166000908152603660205260409020600c01541690565b60345460009081906001600160a01b03163314611bac5760405162461bcd60e51b815260040180806020018281038252602a8152602001806156b2602a913960400191505060405180910390fd5b600080611bb9898961272f565b9250509150611bcc898984848b8a61429e565b611bda898989848a8a6142cd565b611be689600089614036565b611bf089896143f2565b999098509650505050505050565b603554604080516385c858b160e01b8152905133926001600160a01b0316916385c858b1916004808301926020929190829003018186803b158015611c4257600080fd5b505afa158015611c56573d6000803e3d6000fd5b505050506040513d6020811015611c6c57600080fd5b50516001600160a01b031614611cb35760405162461bcd60e51b81526004018080602001828103825260378152602001806156086037913960400191505060405180910390fd5b6001600160a01b03166000908152603660205260409020600d01805460ff60e01b19169055565b603554604080516385c858b160e01b8152905133926001600160a01b0316916385c858b1916004808301926020929190829003018186803b158015611d1e57600080fd5b505afa158015611d32573d6000803e3d6000fd5b505050506040513d6020811015611d4857600080fd5b50516001600160a01b031614611d8f5760405162461bcd60e51b81526004018080602001828103825260378152602001806156086037913960400191505060405180910390fd5b6001600160a01b0380851660009081526036602052604080822081516304dda73560e21b8152600481019190915286841660248201526044810186905292841660648401525173__CoreLibrary___________________________926313769cd4926084808301939192829003018186803b158015611e0d57600080fd5b505af4158015611e21573d6000803e3d6000fd5b50505050611e2e84614484565b50505050565b6001600160a01b031660009081526036602052604090206006015490565b6001600160a01b03166000908152603660205260409020600d0154600160e81b900460ff1690565b6001600160a01b03166000908152603660205260409020600d0154600160a01b900464ffffffffff1690565b60388181548110611eb357fe5b6000918252602090912001546001600160a01b0316905081565b6001600160a01b03166000908152603660205260409020600d0154600160c81b900460ff1690565b6001600160a01b03166000908152603660205260409020600b81015460088201546009830154600d909301549193909291600160d01b900460ff1690565b603554604080516385c858b160e01b8152905133926001600160a01b0316916385c858b1916004808301926020929190829003018186803b158015611f7757600080fd5b505afa158015611f8b573d6000803e3d6000fd5b505050506040513d6020811015611fa157600080fd5b50516001600160a01b031614611fe85760405162461bcd60e51b81526004018080602001828103825260378152602001806156086037913960400191505060405180910390fd5b611ff0614528565b565b603554604080516385c858b160e01b8152905133926001600160a01b0316916385c858b1916004808301926020929190829003018186803b15801561203657600080fd5b505afa15801561204a573d6000803e3d6000fd5b505050506040513d602081101561206057600080fd5b50516001600160a01b0316146120a75760405162461bcd60e51b81526004018080602001828103825260378152602001806156086037913960400191505060405180910390fd5b6001600160a01b039091166000908152603660205260409020600b0155565b6001600160a01b0390811660009081526037602090815260408083209490931682529290925290206004015464ffffffffff1690565b6034546001600160a01b031633146121455760405162461bcd60e51b815260040180806020018281038252602a8152602001806156b2602a913960400191505060405180910390fd5b612151898888856145c3565b61215a8861467c565b61216789888887866146a0565b61217389876000614036565b806121935761219388600061218e888763ffffffff613f7e16565b614036565b505050505050505050565b6001600160a01b039081166000908152603660205260409020600d01541690565b6001600160a01b0380821660009081526037602090815260408083209386168352929052206003015492915050565b603554604080516385c858b160e01b8152905133926001600160a01b0316916385c858b1916004808301926020929190829003018186803b15801561223257600080fd5b505afa158015612246573d6000803e3d6000fd5b505050506040513d602081101561225c57600080fd5b50516001600160a01b0316146122a35760405162461bcd60e51b81526004018080602001828103825260378152602001806156086037913960400191505060405180910390fd5b6001600160a01b039091166000908152603660205260409020600a0155565b603554604080516385c858b160e01b8152905133926001600160a01b0316916385c858b1916004808301926020929190829003018186803b15801561230657600080fd5b505afa15801561231a573d6000803e3d6000fd5b505050506040513d602081101561233057600080fd5b50516001600160a01b0316146123775760405162461bcd60e51b81526004018080602001828103825260378152602001806156086037913960400191505060405180910390fd5b6001600160a01b03166000908152603660205260409020600d01805460ff60e81b1916600160e81b179055565b6001600160a01b031660009081526036602052604090206002015490565b6001600160a01b0380821660009081526036602090815260408083206035548251631b0c55dd60e11b815292519495919486949190921692633618abba9260048083019392829003018186803b15801561241b57600080fd5b505afa15801561242f573d6000803e3d6000fd5b505050506040513d602081101561244557600080fd5b505160058301549091506124df57806001600160a01b031663bb85c0bb856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156124a957600080fd5b505afa1580156124bd573d6000803e3d6000fd5b505050506040513d60208110156124d357600080fd5b50519250611546915050565b506005015492915050565b6034546001600160a01b031633146125335760405162461bcd60e51b815260040180806020018281038252602a8152602001806156b2602a913960400191505060405180910390fd5b8034156125715760405162461bcd60e51b81526004018080602001828103825260368152602001806153f66036913960400191505060405180910390fd5b6125796141cf565b6001600160a01b0316846001600160a01b0316146125b0576125ab6001600160a01b038516828563ffffffff61475216565b611e2e565b6040516000906001600160a01b0383169061c35090869084818181858888f193505050503d8060008114611a10576040519150601f19603f3d011682016040523d82523d6000602084013e611a15565b6001600160a01b038116600090815260366020526040812060048101546126a65780600d0160009054906101000a90046001600160a01b03166001600160a01b03166334762ca56040518163ffffffff1660e01b815260040160206040518083038186803b15801561267157600080fd5b505afa158015612685573d6000803e3d6000fd5b505050506040513d602081101561269b57600080fd5b505191506115469050565b6004015492915050565b6001600160a01b031660009081526036602052604090206003015490565b6001600160a01b03908116600090815260376020908152604080832094909316825292909252902060040154600160281b900460ff1690565b6001600160a01b03166000908152603660205260409020600d0154600160d81b900460ff1690565b6001600160a01b03808216600090815260376020908152604080832093861683529290529081208054829182916127705750600092508291508190506127b3565b80546001600160a01b03871660009081526036602052604081206127959084906147a4565b905081816127a9818363ffffffff61424116565b9550955095505050505b9250925092565b6001600160a01b03166000908152603660205260409020600b015490565b603554604080516385c858b160e01b8152905133926001600160a01b0316916385c858b1916004808301926020929190829003018186803b15801561281c57600080fd5b505afa158015612830573d6000803e3d6000fd5b505050506040513d602081101561284657600080fd5b50516001600160a01b03161461288d5760405162461bcd60e51b81526004018080602001828103825260378152602001806156086037913960400191505060405180910390fd5b6001600160a01b038416600090815260366020526040808220815163126ee27360e11b81526004810191909152602481018690526044810185905260648101849052905173__CoreLibrary___________________________926324ddc4e69260848082019391829003018186803b15801561290857600080fd5b505af415801561291c573d6000803e3d6000fd5b5050505050505050565b603554604080516385c858b160e01b8152905133926001600160a01b0316916385c858b1916004808301926020929190829003018186803b15801561296a57600080fd5b505afa15801561297e573d6000803e3d6000fd5b505050506040513d602081101561299457600080fd5b50516001600160a01b0316146129db5760405162461bcd60e51b81526004018080602001828103825260378152602001806156086037913960400191505060405180910390fd5b6001600160a01b03811660009081526036602052604080822081516372efab5360e11b81526004810191909152905173__CoreLibrary___________________________9263e5df56a69260248082019391829003018186803b158015612a4157600080fd5b505af415801561169c573d6000803e3d6000fd5b6034546000906001600160a01b03163314612aa15760405162461bcd60e51b815260040180806020018281038252602a8152602001806156b2602a913960400191505060405180910390fd5b612aac848484614896565b612ab78484846148e6565b612ac384600080614036565b506001600160a01b038083166000908152603760209081526040808320938716835292905220600301545b9392505050565b6034546001600160a01b03163314612b3e5760405162461bcd60e51b815260040180806020018281038252602a8152602001806156b2602a913960400191505060405180910390fd5b6001600160a01b0384166000908152603660205260409020612b5f90613ee6565b612b6b84600084614036565b8015611e2e57611e2e84846000613c1b565b6001600160a01b031660009081526036602052604090206007015490565b603554604080516385c858b160e01b8152905133926001600160a01b0316916385c858b1916004808301926020929190829003018186803b158015612bdf57600080fd5b505afa158015612bf3573d6000803e3d6000fd5b505050506040513d6020811015612c0957600080fd5b50516001600160a01b031614612c505760405162461bcd60e51b81526004018080602001828103825260378152602001806156086037913960400191505060405180910390fd5b6001600160a01b0381166000908152603660205260409020805415801590612c7c575060008160070154115b612cb75760405162461bcd60e51b815260040180806020018281038252602481526020018061563f6024913960400191505060405180910390fd5b600d01805460ff60e01b1916600160e01b17905550565b603554604080516385c858b160e01b8152905133926001600160a01b0316916385c858b1916004808301926020929190829003018186803b158015612d1257600080fd5b505afa158015612d26573d6000803e3d6000fd5b505050506040513d6020811015612d3c57600080fd5b50516001600160a01b031614612d835760405162461bcd60e51b81526004018080602001828103825260378152602001806156086037913960400191505060405180910390fd5b6001600160a01b03166000908152603660205260409020600d01805460ff60d81b19169055565b6034546001600160a01b03163314612df35760405162461bcd60e51b815260040180806020018281038252602a8152602001806156b2602a913960400191505060405180910390fd5b6001600160a01b0384166000908152603660205260409020612e1490613ee6565b612e2084836000614036565b8015611e2e57611e2e84846001613c1b565b6001600160a01b031660009081526036602052604090205490565b6001600160a01b038116600090815260366020526040812081612e6f8261494f565b905080612e8157600092505050611546565b6000612e8c85613749565b9050612eae612ea1828463ffffffff613f7e16565b839063ffffffff61496c16565b95945050505050565b6001600160a01b0381166000908152603660205260408120612aee612edb8261494f565b612ee485613749565b9063ffffffff613f7e16565b6000612efa6149a8565b60015490915060ff1680612f115750612f116149ad565b80612f1d575060005481115b612f585760405162461bcd60e51b815260040180806020018281038252602e815260200180615684602e913960400191505060405180910390fd5b60015460ff16158015612f77576001805460ff19168117905560008290555b603580546001600160a01b0319166001600160a01b038516179055612f9a614528565b8015611a64576001805460ff19169055505050565b6001600160a01b031660009081526036602052604090206001015490565b6035546001600160a01b031681565b6001600160a01b03166000908152603660205260409020600a015490565b6034546001600160a01b031633146130435760405162461bcd60e51b815260040180806020018281038252602a8152602001806156b2602a913960400191505060405180910390fd5b8061304c6141cf565b6001600160a01b0316856001600160a01b0316146130c15734156130a15760405162461bcd60e51b815260040180806020018281038252605f815260200180615579605f913960600191505060405180910390fd5b6130bc6001600160a01b03861685838663ffffffff6141e716565b61169c565b823410156131005760405162461bcd60e51b815260040180806020018281038252603581526020018061547c6035913960400191505060405180910390fd5b6040516000906001600160a01b0383169061c35090869084818181858888f193505050503d8060008114613150576040519150601f19603f3d011682016040523d82523d6000602084013e613155565b606091505b50509050806131a4576040805162461bcd60e51b8152602060048201526016602482015275151c985b9cd9995c881bd9881155120819985a5b195960521b604482015290519081900360640190fd5b505050505050565b603554604080516385c858b160e01b8152905133926001600160a01b0316916385c858b1916004808301926020929190829003018186803b1580156131f057600080fd5b505afa158015613204573d6000803e3d6000fd5b505050506040513d602081101561321a57600080fd5b50516001600160a01b0316146132615760405162461bcd60e51b81526004018080602001828103825260378152602001806156086037913960400191505060405180910390fd5b6038805460009190600019810190811061327757fe5b6000918252602090912001546001600160a01b039081169150821681146132cf5760405162461bcd60e51b815260040180806020018281038252603d81526020018061550a603d913960400191505060405180910390fd5b6132d8816137ed565b156133145760405162461bcd60e51b81526004018080602001828103825260308152602001806155d86030913960400191505060405180910390fd5b6001600160a01b0381166000908152603660205260408120600d81018054600c830180546001600160a01b0319169055600b8301849055838355600783018490556008830184905560098301849055600a90920192909255600168ff00ffff000000000160a01b0319169055603880548061338b57fe5b600082815260209020810160001990810180546001600160a01b03191690550190555050565b6001600160a01b0381166000908152603660205260408120612aee816149b3565b6034546001600160a01b031681565b603554604080516385c858b160e01b8152905133926001600160a01b0316916385c858b1916004808301926020929190829003018186803b15801561342557600080fd5b505afa158015613439573d6000803e3d6000fd5b505050506040513d602081101561344f57600080fd5b50516001600160a01b0316146134965760405162461bcd60e51b81526004018080602001828103825260378152602001806156086037913960400191505060405180910390fd5b6001600160a01b03909116600090815260366020526040902060080155565b6034546001600160a01b031633146134fe5760405162461bcd60e51b815260040180806020018281038252602a8152602001806156b2602a913960400191505060405180910390fd5b61350a868686856149e1565b613518868686868686614a45565b6131a486856000614036565b603554604080516385c858b160e01b8152905133926001600160a01b0316916385c858b1916004808301926020929190829003018186803b15801561356857600080fd5b505afa15801561357c573d6000803e3d6000fd5b505050506040513d602081101561359257600080fd5b50516001600160a01b0316146135d95760405162461bcd60e51b81526004018080602001828103825260378152602001806156086037913960400191505060405180910390fd5b6001600160a01b03166000908152603660205260409020600d01805460ff60d81b1916600160d81b179055565b6001600160a01b03808316600081815260366020908152604080832094861683526037825280832093835292905290812090918291829182918261364a89896116a8565b8254909150613677576004909101549095506000945084935060ff600160281b9091041691506136aa9050565b80613688838563ffffffff6147a416565b6002840154600490940154919850965091945050600160281b900460ff169150505b92959194509250565b6001600160a01b038381166000818152603660209081526040808320948716835260378252808320938352929052908120600d830154919291600160d81b900460ff1661370557600092505050612aee565b6004810154600160281b900460ff16158061372c5750600d820154600160d01b900460ff16155b8061373f575061373c86866116a8565b84115b9695505050505050565b6000806137546141cf565b6001600160a01b0316836001600160a01b03161415613774575047611735565b604080516370a0823160e01b815230600482015290516001600160a01b038516916370a08231916024808301926020929190829003018186803b1580156137ba57600080fd5b505afa1580156137ce573d6000803e3d6000fd5b505050506040513d60208110156137e457600080fd5b50519392505050565b6001600160a01b03811660009081526036602052604081206117359061494f565b603554604080516385c858b160e01b8152905133926001600160a01b0316916385c858b1916004808301926020929190829003018186803b15801561385257600080fd5b505afa158015613866573d6000803e3d6000fd5b505050506040513d602081101561387c57600080fd5b50516001600160a01b0316146138c35760405162461bcd60e51b81526004018080602001828103825260378152602001806156086037913960400191505060405180910390fd5b6001600160a01b038116600090815260366020526040808220815163041e0b2d60e51b81526004810191909152905173__CoreLibrary___________________________926383c165a09260248082019391829003018186803b158015612a4157600080fd5b603554604080516385c858b160e01b8152905133926001600160a01b0316916385c858b1916004808301926020929190829003018186803b15801561396d57600080fd5b505afa158015613981573d6000803e3d6000fd5b505050506040513d602081101561399757600080fd5b50516001600160a01b0316146139de5760405162461bcd60e51b81526004018080602001828103825260378152602001806156086037913960400191505060405180910390fd5b6001600160a01b0382166000908152603660205260408082208151637b1dd5df60e11b815260048101919091528315156024820152905173__CoreLibrary___________________________9263f63babbe9260448082019391829003018186803b158015613a4c57600080fd5b505af41580156131a4573d6000803e3d6000fd5b603554604080516385c858b160e01b8152905133926001600160a01b0316916385c858b1916004808301926020929190829003018186803b158015613aa457600080fd5b505afa158015613ab8573d6000803e3d6000fd5b505050506040513d6020811015613ace57600080fd5b50516001600160a01b031614613b155760405162461bcd60e51b81526004018080602001828103825260378152602001806156086037913960400191505060405180910390fd5b6001600160a01b03166000908152603660205260409020600d01805460ff60e81b19169055565b6001600160a01b031660009081526036602052604090206009015490565b60345460009081906001600160a01b03163314613ba85760405162461bcd60e51b815260040180806020018281038252602a8152602001806156b2602a913960400191505060405180910390fd5b613bb58888888887614ac2565b6000613bc389898787614bc1565b9050613bd189600080614036565b80613bdc8a8a6143f2565b9250925050965096945050505050565b6001600160a01b0380821660009081526037602090815260408083209386168352929052206001015492915050565b6034546001600160a01b03163314613c645760405162461bcd60e51b815260040180806020018281038252602a8152602001806156b2602a913960400191505060405180910390fd5b6001600160a01b0391821660009081526037602090815260408083209590941682529390935291206004018054911515600160281b0265ff000000000019909216919091179055565b6034546001600160a01b03163314613cf65760405162461bcd60e51b815260040180806020018281038252602a8152602001806156b2602a913960400191505060405180910390fd5b613cfe6141cf565b6001600160a01b0316836001600160a01b031614613d305761195f6001600160a01b038416838363ffffffff61475216565b6040516000906001600160a01b0384169061c35090849084818181858888f193505050503d8060008114613d80576040519150601f19603f3d011682016040523d82523d6000602084013e613d85565b606091505b5050905080611e2e576040805162461bcd60e51b8152602060048201526016602482015275151c985b9cd9995c881bd9881155120819985a5b195960521b604482015290519081900360640190fd5b6001600160a01b0380821660009081526037602090815260408083209386168352929052206002015492915050565b60355460408051637744894b60e11b815290516000926001600160a01b03169163ee891296916004808301926020929190829003018186803b158015613e4857600080fd5b505afa158015613e5c573d6000803e3d6000fd5b505050506040513d6020811015613e7257600080fd5b50519050613e7e6141cf565b6001600160a01b0316836001600160a01b031614613eb05761195f6001600160a01b038416828463ffffffff61475216565b6040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015611e2e573d6000803e3d6000fd5b6000613ef18261494f565b90508015613f7a576001820154600d830154600091613f1d91600160a01b900464ffffffffff16614cbf565b8354909150613f3390829063ffffffff614d0a16565b83556004830154600d840154600091613f5991600160a01b900464ffffffffff16614d42565b9050613f72846007015482614d0a90919063ffffffff16565b600785015550505b5050565b600082820183811015612aee576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000613ffb613fe684614d91565b613fef84614d91565b9063ffffffff61496c16565b9050600061401761400a614da7565b839063ffffffff613f7e16565b855490915061402d90829063ffffffff614d0a16565b90945550505050565b6001600160a01b038084166000908152603660205260408120600d810154909282918291166357e37af08861407e886140728b612ee485613749565b9063ffffffff61424116565b8760020154886003015489600601546040518663ffffffff1660e01b815260040180866001600160a01b03166001600160a01b031681526020018581526020018481526020018381526020018281526020019550505050505060606040518083038186803b1580156140ef57600080fd5b505afa158015614103573d6000803e3d6000fd5b505050506040513d606081101561411957600080fd5b508051602080830151604093840151600189018490556005890182905560048901819055600d8901805464ffffffffff4216600160a01b0264ffffffffff60a01b19909116179055885460078a0154865186815294850184905284870183905260608501919091526080840152935192965094509192506001600160a01b038916917f04e4f521f16fcfd987978b05504262c2a2db223844977aab000e5accedb2d725919081900360a00190a250505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611e2e908590614db7565b600082821115614298576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6001600160a01b03861660009081526036602052604090206142bf90613ee6565b6131a4868686868686614f6f565b6001600160a01b038087166000818152603660209081526040808320948a1683526037825280832093835292905220600183600281111561430a57fe5b141561432657600582015460038201556000600182015561439d565b600283600281111561433457fe5b141561435057600060038201556007820154600182015561439d565b6040805162461bcd60e51b815260206004820152601860248201527f496e76616c696420626f72726f772072617465206d6f64650000000000000000604482015290519081900360640190fd5b80546143b5908690612ee4908963ffffffff613f7e16565b815560028101546143cc908563ffffffff613f7e16565b6002820155600401805464ffffffffff19164264ffffffffff1617905550505050505050565b6000806143ff8484611763565b9050600081600281111561440f57fe5b141561441f576000915050611735565b600181600281111561442d57fe5b14614453576001600160a01b0384166000908152603660205260409020600401546117b0565b50506001600160a01b0390811660009081526037602090815260408083209490931682529290925290206003015490565b6000805b6038548110156144d157826001600160a01b0316603882815481106144a957fe5b6000918252602090912001546001600160a01b031614156144c957600191505b600101614488565b5080613f7a57603880546001810182556000919091527f38395c5dceade9603479b177b68959049485df8aa97b39f3533039af5f4561990180546001600160a01b0384166001600160a01b03199091161790555050565b603560009054906101000a90046001600160a01b03166001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561457657600080fd5b505afa15801561458a573d6000803e3d6000fd5b505050506040513d60208110156145a057600080fd5b5051603480546001600160a01b0319166001600160a01b03909216919091179055565b6001600160a01b038085166000818152603660209081526040808320948816835260378252808320938352929052206145fb82613ee6565b60006146078787611763565b905060015b81600281111561461857fe5b1415614653576003820154614636908490869063ffffffff6150cb16565b600382015461464e908490879063ffffffff61513b16565b614673565b614663838563ffffffff61524616565b614673838663ffffffff61526716565b50505050505050565b6001600160a01b038116600090815260366020526040902061469d90613ee6565b50565b6001600160a01b0380851660009081526037602090815260408083209389168352928152828220603690915291902081546146e7908690614072908663ffffffff613f7e16565b825560026146f58888611763565b600281111561470057fe5b141561471157600781015460018301555b831561473257600282015461472c908563ffffffff61424116565b60028301555b50600401805464ffffffffff19164264ffffffffff161790555050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611a64908490614db7565b81546000906147b557506000611735565b60006147c48460000154614d91565b60038501549091506000908190156147f857600386015460048701546147f1919064ffffffffff16614d42565b905061483a565b6148378660010154613fef876007015461482b89600401548a600d0160149054906101000a900464ffffffffff16614d42565b9063ffffffff614d0a16565b90505b61485261484d848363ffffffff614d0a16565b6152bf565b865490925082141561488d57600486015464ffffffffff16421461488d57855461488390600163ffffffff613f7e16565b9350505050611735565b50949350505050565b6001600160a01b038084166000818152603660209081526040808320948716835260378252808320938352929052206148ce82613ee6565b600381015461169c908390859063ffffffff6150cb16565b6001600160a01b038083166000908152603760209081526040808320938716835292815282822060369091529190208154614927908463ffffffff613f7e16565b8255600501546003820155600401805464ffffffffff19164264ffffffffff16179055505050565b600061173582600301548360020154613f7e90919063ffffffff16565b6000600282046117b08361499c61498f876b033b2e3c9fd0803ce80000006152d8565b849063ffffffff613f7e16565b9063ffffffff61533116565b600490565b303b1590565b600080612aee836000015461482b856001015486600d0160149054906101000a900464ffffffffff16614cbf565b6001600160a01b03808516600090815260366020908152604080832060378352818420948816845293909152812090614a1a8787611763565b6001600160a01b0388166000908152603660205260409020909150614a3e90613ee6565b600161460c565b6001600160a01b038087166000818152603660209081526040808320948a16835260378252808320938352929052208054614a8c908790614072908763ffffffff613f7e16565b8155600782015460018201558215614aad5760006003820181905560018201555b60028101546143cc908663ffffffff61424116565b6001600160a01b03808616600081815260366020908152604080832094891683526037825280832093835292905220614afa82613ee6565b6001836002811115614b0857fe5b1415614b3a576003810154614b2483878363ffffffff61513b16565b614b34838663ffffffff61524616565b50614673565b6002836002811115614b4857fe5b1415614b74576005820154614b63838763ffffffff61526716565b614b3483868363ffffffff6150cb16565b6040805162461bcd60e51b815260206004820152601a60248201527f496e76616c69642072617465206d6f6465207265636569766564000000000000604482015290519081900360640190fd5b6001600160a01b03808416600090815260376020908152604080832093881683529281528282206036909152918120909190826002856002811115614c0257fe5b1415614c235750600581015460038301556000600183810191909155614c87565b6001856002811115614c3157fe5b1415614c50575060006003830155600781015460018301556002614c87565b60405162461bcd60e51b81526004018080602001828103825260238152602001806156dc6023913960400191505060405180910390fd5b8254614c99908763ffffffff613f7e16565b83556004909201805464ffffffffff19164264ffffffffff161790555095945050505050565b600080614cd94264ffffffffff851663ffffffff61424116565b90506000614ced613fe66301e13380614d91565b9050612eae614cfa614da7565b612ee4878463ffffffff614d0a16565b6000612aee6b033b2e3c9fd0803ce800000061499c614d2f868663ffffffff6152d816565b6b019d971e4fe8401e7400000090613f7e565b600080614d5c4264ffffffffff851663ffffffff61424116565b90506000614d74856301e1338063ffffffff61533116565b9050612eae82614d8561498f614da7565b9063ffffffff61539b16565b600061173582633b9aca0063ffffffff6152d816565b6b033b2e3c9fd0803ce800000090565b614dc9826001600160a01b0316611541565b614e1a576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310614e585780518252601f199092019160209182019101614e39565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114614eba576040519150601f19603f3d011682016040523d82523d6000602084013e614ebf565b606091505b509150915081614f16576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115611e2e57808060200190516020811015614f3257600080fd5b5051611e2e5760405162461bcd60e51b815260040180806020018281038252602a8152602001806156ff602a913960400191505060405180910390fd5b6000614f7b8787611763565b6001600160a01b03881660009081526036602052604090209091506001826002811115614fa457fe5b1415614fed576001600160a01b038088166000908152603760209081526040808320938c168352929052206003810154614fe7908390899063ffffffff61513b16565b50615011565b6002826002811115614ffb57fe5b141561501157615011818763ffffffff61526716565b600061502785612ee4898963ffffffff613f7e16565b9050600184600281111561503757fe5b141561505a576005820154615055908390839063ffffffff6150cb16565b612193565b600284600281111561506857fe5b141561507e57615055828263ffffffff61524616565b6040805162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206e657720626f72726f772072617465206d6f646500000000604482015290519081900360640190fd5b60028301546150e0818463ffffffff613f7e16565b600285015560006150f48361482b86614d91565b90506000615109866006015461482b85614d91565b905061512b61511b8760020154614d91565b613fef848463ffffffff613f7e16565b8660060181905550505050505050565b8183600201541015615194576040805162461bcd60e51b815260206004820152601a60248201527f496e76616c696420616d6f756e7420746f206465637265617365000000000000604482015290519081900360640190fd5b60028301546151a9818463ffffffff61424116565b600285018190556151c1575060006006840155611a64565b60006151d08361482b86614d91565b905060006151e5866006015461482b85614d91565b9050818110156152265760405162461bcd60e51b81526004018080602001828103825260238152602001806154e76023913960400191505060405180910390fd5b61512b6152368760020154614d91565b613fef838563ffffffff61424116565b600382015461525b908263ffffffff613f7e16565b82600301819055505050565b80826003015410156152aa5760405162461bcd60e51b815260040180806020018281038252605081526020018061542c6050913960600191505060405180910390fd5b600382015461525b908263ffffffff61424116565b6000631dcd6500612aee633b9aca0061499c8386613f7e565b6000826152e757506000611735565b828202828482816152f457fe5b0414612aee5760405162461bcd60e51b81526004018080602001828103825260218152602001806156636021913960400191505060405180910390fd5b6000808211615387576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b600082848161539257fe5b04949350505050565b6000600282066153b7576b033b2e3c9fd0803ce80000006153b9565b825b90506002820491505b8115611735576153d28384614d0a565b925060028206156153ea576153e78184614d0a565b90505b6002820491506153c256fe466565206c69717569646174696f6e20646f6573206e6f74207265717569726520616e79207472616e73666572206f662076616c756554686520616d6f756e742074686174206973206265696e6720737562747261637465642066726f6d20746865207661726961626c6520746f74616c20626f72726f777320697320696e636f727265637454686520616d6f756e7420616e64207468652076616c75652073656e7420746f206465706f73697420646f206e6f74206d617463684f6e6c7920636f6e7472616374732063616e2073656e6420657468657220746f20746865204c656e64696e6720706f6f6c20636f726554686520616d6f756e747320746f20737562747261637420646f6e2774206d6174636852657365727665206265696e672072656d6f76656420697320646966666572656e74207468616e20746865207265736572766520726571756573746564557365722069732073656e64696e672045544820616c6f6e67207769746820746865204552433230207472616e736665722e557365722069732073656e64696e672045544820616c6f6e67207769746820746865204552433230207472616e736665722e20436865636b207468652076616c756520617474726962757465206f6620746865207472616e73616374696f6e43616e6e6f742072656d6f7665206120726573657276652077697468206c6971756964697479206465706f73697465645468652063616c6c6572206d7573742062652061206c656e64696e6720706f6f6c20636f6e666967757261746f7220636f6e74726163745265736572766520686173206e6f74206265656e20696e697469616c697a656420796574536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a65645468652063616c6c6572206d7573742062652061206c656e64696e6720706f6f6c20636f6e7472616374496e76616c696420696e7465726573742072617465206d6f64652072656365697665645361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a72315820b51cb4b2ff2c9220190d7c0e46a463ea830d4e8a62cef6ff7abd8ad427d1ee5364736f6c634300050e0032", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} - diff --git a/external/abi/aave/v1/LendingPoolDataProvider.json b/external/abi/aave/v1/LendingPoolDataProvider.json deleted file mode 100644 index 2d9b1697e..000000000 --- a/external/abi/aave/v1/LendingPoolDataProvider.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "contractName": "LendingPoolDataProvider", - "abi": [{"constant":true,"inputs":[],"name":"DATA_PROVIDER_REVISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"HEALTH_FACTOR_LIQUIDATION_THRESHOLD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"addressesProvider","outputs":[{"internalType":"contract LendingPoolAddressesProvider","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"core","outputs":[{"internalType":"contract LendingPoolCore","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract LendingPoolAddressesProvider","name":"_addressesProvider","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"calculateUserGlobalData","outputs":[{"internalType":"uint256","name":"totalLiquidityBalanceETH","type":"uint256"},{"internalType":"uint256","name":"totalCollateralBalanceETH","type":"uint256"},{"internalType":"uint256","name":"totalBorrowBalanceETH","type":"uint256"},{"internalType":"uint256","name":"totalFeesETH","type":"uint256"},{"internalType":"uint256","name":"currentLtv","type":"uint256"},{"internalType":"uint256","name":"currentLiquidationThreshold","type":"uint256"},{"internalType":"uint256","name":"healthFactor","type":"uint256"},{"internalType":"bool","name":"healthFactorBelowThreshold","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"balanceDecreaseAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"uint256","name":"_userCurrentBorrowBalanceTH","type":"uint256"},{"internalType":"uint256","name":"_userCurrentFeesETH","type":"uint256"},{"internalType":"uint256","name":"_userCurrentLtv","type":"uint256"}],"name":"calculateCollateralNeededInETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getHealthFactorLiquidationThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveConfigurationData","outputs":[{"internalType":"uint256","name":"ltv","type":"uint256"},{"internalType":"uint256","name":"liquidationThreshold","type":"uint256"},{"internalType":"uint256","name":"liquidationBonus","type":"uint256"},{"internalType":"address","name":"rateStrategyAddress","type":"address"},{"internalType":"bool","name":"usageAsCollateralEnabled","type":"bool"},{"internalType":"bool","name":"borrowingEnabled","type":"bool"},{"internalType":"bool","name":"stableBorrowRateEnabled","type":"bool"},{"internalType":"bool","name":"isActive","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"}],"name":"getReserveData","outputs":[{"internalType":"uint256","name":"totalLiquidity","type":"uint256"},{"internalType":"uint256","name":"availableLiquidity","type":"uint256"},{"internalType":"uint256","name":"totalBorrowsStable","type":"uint256"},{"internalType":"uint256","name":"totalBorrowsVariable","type":"uint256"},{"internalType":"uint256","name":"liquidityRate","type":"uint256"},{"internalType":"uint256","name":"variableBorrowRate","type":"uint256"},{"internalType":"uint256","name":"stableBorrowRate","type":"uint256"},{"internalType":"uint256","name":"averageStableBorrowRate","type":"uint256"},{"internalType":"uint256","name":"utilizationRate","type":"uint256"},{"internalType":"uint256","name":"liquidityIndex","type":"uint256"},{"internalType":"uint256","name":"variableBorrowIndex","type":"uint256"},{"internalType":"address","name":"aTokenAddress","type":"address"},{"internalType":"uint40","name":"lastUpdateTimestamp","type":"uint40"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserAccountData","outputs":[{"internalType":"uint256","name":"totalLiquidityETH","type":"uint256"},{"internalType":"uint256","name":"totalCollateralETH","type":"uint256"},{"internalType":"uint256","name":"totalBorrowsETH","type":"uint256"},{"internalType":"uint256","name":"totalFeesETH","type":"uint256"},{"internalType":"uint256","name":"availableBorrowsETH","type":"uint256"},{"internalType":"uint256","name":"currentLiquidationThreshold","type":"uint256"},{"internalType":"uint256","name":"ltv","type":"uint256"},{"internalType":"uint256","name":"healthFactor","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"getUserReserveData","outputs":[{"internalType":"uint256","name":"currentATokenBalance","type":"uint256"},{"internalType":"uint256","name":"currentBorrowBalance","type":"uint256"},{"internalType":"uint256","name":"principalBorrowBalance","type":"uint256"},{"internalType":"uint256","name":"borrowRateMode","type":"uint256"},{"internalType":"uint256","name":"borrowRate","type":"uint256"},{"internalType":"uint256","name":"liquidityRate","type":"uint256"},{"internalType":"uint256","name":"originationFee","type":"uint256"},{"internalType":"uint256","name":"variableBorrowIndex","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"bool","name":"usageAsCollateralEnabled","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"}], - "bytecode": "0x60806040526000805534801561001457600080fd5b50612947806100246000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c806376e9d6151161008c578063c3525c2811610066578063c3525c28146103e4578063c4d66de8146103ec578063c72c4d1014610414578063f2f4eb2614610438576100cf565b806376e9d6151461032b5780638daf609f14610375578063bf92857c1461037d576100cf565b806312737c33146100d457806328dd2d011461012a5780632c6d0e9b146101aa57806335ea6a75146102135780633e150141146102ae5780633e44bee814610323575b600080fd5b610118600480360360c08110156100ea57600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060a00135610440565b60408051918252519081900360200190f35b6101586004803603604081101561014057600080fd5b506001600160a01b0381358116916020013516610633565b604080519a8b5260208b0199909952898901979097526060890195909552608088019390935260a087019190915260c086015260e0850152610100840152151561012083015251908190036101400190f35b6101d0600480360360208110156101c057600080fd5b50356001600160a01b0316610e1e565b604080519889526020890197909752878701959095526060870193909352608086019190915260a085015260c0840152151560e083015251908190036101000190f35b6102396004803603602081101561022957600080fd5b50356001600160a01b03166113c8565b604080519d8e5260208e019c909c528c8c019a909a5260608c019890985260808b019690965260a08a019490945260c089019290925260e08801526101008701526101208601526101408501526001600160a01b031661016084015264ffffffffff1661018083015251908190036101a00190f35b6102d4600480360360208110156102c457600080fd5b50356001600160a01b0316611c6f565b604080519889526020890197909752878701959095526001600160a01b0390931660608701529015156080860152151560a0850152151560c0840152151560e083015251908190036101000190f35b610118611fe2565b6103616004803603606081101561034157600080fd5b506001600160a01b03813581169160208101359091169060400135611fee565b604080519115158252519081900360200190f35b6101186122e9565b6103a36004803603602081101561039357600080fd5b50356001600160a01b03166122ee565b604080519889526020890197909752878701959095526060870193909352608086019190915260a085015260c084015260e083015251908190036101000190f35b61011861232f565b6104126004803603602081101561040257600080fd5b50356001600160a01b031661233b565b005b61041c612477565b604080516001600160a01b039092168252519081900360200190f35b61041c612486565b6034546040805163288d4ff760e21b81526001600160a01b03898116600483015291516000938493169163a2353fdc916024808301926020929190829003018186803b15801561048f57600080fd5b505afa1580156104a3573d6000803e3d6000fd5b505050506040513d60208110156104b957600080fd5b505160355460408051631f94a27560e31b815290519293506000926001600160a01b039092169163fca513a891600480820192602092909190829003018186803b15801561050657600080fd5b505afa15801561051a573d6000803e3d6000fd5b505050506040513d602081101561053057600080fd5b5051905060006105eb600a84900a6105df6105518c8c63ffffffff61249516565b856001600160a01b031663b3596f078f6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156105a757600080fd5b505afa1580156105bb573d6000803e3d6000fd5b505050506040513d60208110156105d157600080fd5b50519063ffffffff6124f816565b9063ffffffff61255116565b90506000610624866105df60646106188661060c8e8e63ffffffff61249516565b9063ffffffff61249516565b9063ffffffff6124f816565b9b9a5050505050505050505050565b600080600080600080600080600080603460009054906101000a90046001600160a01b03166001600160a01b03166334b3beee8d6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156106ad57600080fd5b505afa1580156106c1573d6000803e3d6000fd5b505050506040513d60208110156106d757600080fd5b5051604080516370a0823160e01b81526001600160a01b038e81166004830152915191909216916370a08231916024808301926020929190829003018186803b15801561072357600080fd5b505afa158015610737573d6000803e3d6000fd5b505050506040513d602081101561074d57600080fd5b810190808051906020019092919050505099506000603460009054906101000a90046001600160a01b03166001600160a01b0316631ca19f198e8e6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b1580156107e757600080fd5b505afa1580156107fb573d6000803e3d6000fd5b505050506040513d602081101561081157600080fd5b81019080805190602001909291905050509050603460009054906101000a90046001600160a01b03166001600160a01b0316639fb8afcd8e8e6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060606040518083038186803b1580156108a957600080fd5b505afa1580156108bd573d6000803e3d6000fd5b505050506040513d60608110156108d357600080fd5b5080516020909101519a50985060018160028111156108ee57fe5b14156109ac57603460009054906101000a90046001600160a01b03166001600160a01b0316636fffab0c8e8e6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b15801561097957600080fd5b505afa15801561098d573d6000803e3d6000fd5b505050506040513d60208110156109a357600080fd5b50519650610a5a565b60028160028111156109ba57fe5b1415610a5a57603460009054906101000a90046001600160a01b03166001600160a01b031663906c0a418e6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610a2b57600080fd5b505afa158015610a3f573d6000803e3d6000fd5b505050506040513d6020811015610a5557600080fd5b505196505b806002811115610a6657fe5b9750603460009054906101000a90046001600160a01b03166001600160a01b031663c540148e8e6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610ad357600080fd5b505afa158015610ae7573d6000803e3d6000fd5b505050506040513d6020811015610afd57600080fd5b81019080805190602001909291905050509550603460009054906101000a90046001600160a01b03166001600160a01b031663feab31ac8e8e6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b158015610b9557600080fd5b505afa158015610ba9573d6000803e3d6000fd5b505050506040513d6020811015610bbf57600080fd5b81019080805190602001909291905050509450603460009054906101000a90046001600160a01b03166001600160a01b031663f6ea8d768e8e6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b158015610c5757600080fd5b505afa158015610c6b573d6000803e3d6000fd5b505050506040513d6020811015610c8157600080fd5b81019080805190602001909291905050509350603460009054906101000a90046001600160a01b03166001600160a01b03166366d103f38e8e6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b158015610d1957600080fd5b505afa158015610d2d573d6000803e3d6000fd5b505050506040513d6020811015610d4357600080fd5b81019080805190602001909291905050509250603460009054906101000a90046001600160a01b03166001600160a01b0316639e3c4f3b8e8e6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b158015610ddb57600080fd5b505afa158015610def573d6000803e3d6000fd5b505050506040513d6020811015610e0557600080fd5b50519a9d999c50979a5095989497939650919450929091565b6000806000806000806000806000603560009054906101000a90046001600160a01b03166001600160a01b031663fca513a86040518163ffffffff1660e01b815260040160206040518083038186803b158015610e7a57600080fd5b505afa158015610e8e573d6000803e3d6000fd5b505050506040513d6020811015610ea457600080fd5b50519050610eb0612800565b60345460408051630240bc6b60e21b815290516060926001600160a01b031691630902f1ac916004808301926000929190829003018186803b158015610ef557600080fd5b505afa158015610f09573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610f3257600080fd5b8101908080516040519392919084640100000000821115610f5257600080fd5b908301906020820185811115610f6757600080fd5b8251866020820283011164010000000082111715610f8457600080fd5b82525081516020918201928201910280838360005b83811015610fb1578181015183820152602001610f99565b50505050905001604052505050905060008090505b815181101561135c57818181518110610fdb57fe5b60200260200101518361014001906001600160a01b031690816001600160a01b031681525050603460009054906101000a90046001600160a01b03166001600160a01b031663e10076ad8461014001518f6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060806040518083038186803b15801561108b57600080fd5b505afa15801561109f573d6000803e3d6000fd5b505050506040513d60808110156110b557600080fd5b5080516020820151604080840151606094850151151561012089015260e0880152928601529084018190521580156110ef57506060830151155b156110f957611354565b60345461014084015160408051635fc526ff60e01b81526001600160a01b03928316600482015290519190921691635fc526ff916024808301926080929190829003018186803b15801561114c57600080fd5b505afa158015611160573d6000803e3d6000fd5b505050506040513d608081101561117657600080fd5b508051602080830151604080850151606090950151151561010089015260c088019490945260a087015260808601829052600a9190910a85820152610140850151825163b3596f0760e01b81526001600160a01b03918216600482015292519087169263b3596f07926024808301939192829003018186803b1580156111fb57600080fd5b505afa15801561120f573d6000803e3d6000fd5b505050506040513d602081101561122557600080fd5b505183526040830151156112ec57600061125884602001516105df866040015187600001516124f890919063ffffffff16565b905061126a8d8263ffffffff61249516565b9c50836101000151801561128057508361012001515b156112ea576112958c8263ffffffff61249516565b9b506112be6112b18560a00151836124f890919063ffffffff16565b8a9063ffffffff61249516565b98506112e76112da8560c00151836124f890919063ffffffff16565b899063ffffffff61249516565b97505b505b6060830151156113545761132961131c84602001516105df866060015187600001516124f890919063ffffffff16565b8b9063ffffffff61249516565b99506113516112b184602001516105df86600001518760e001516124f890919063ffffffff16565b98505b600101610fc6565b5060008a1161136c57600061137c565b61137c878b63ffffffff61255116565b965060008a1161138d57600061139d565b61139d868b63ffffffff61255116565b95506113ab8a8a8a896125bb565b9450670de0b6b3a764000085109350505050919395975091939597565b6000806000806000806000806000806000806000603460009054906101000a90046001600160a01b03166001600160a01b031663c33cfd908f6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561144757600080fd5b505afa15801561145b573d6000803e3d6000fd5b505050506040513d602081101561147157600080fd5b81019080805190602001909291905050509c50603460009054906101000a90046001600160a01b03166001600160a01b031663e24030198f6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156114ef57600080fd5b505afa158015611503573d6000803e3d6000fd5b505050506040513d602081101561151957600080fd5b81019080805190602001909291905050509b50603460009054906101000a90046001600160a01b03166001600160a01b0316637f90fec58f6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561159757600080fd5b505afa1580156115ab573d6000803e3d6000fd5b505050506040513d60208110156115c157600080fd5b81019080805190602001909291905050509a50603460009054906101000a90046001600160a01b03166001600160a01b03166398bd47378f6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561163f57600080fd5b505afa158015611653573d6000803e3d6000fd5b505050506040513d602081101561166957600080fd5b81019080805190602001909291905050509950603460009054906101000a90046001600160a01b03166001600160a01b031663c540148e8f6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156116e757600080fd5b505afa1580156116fb573d6000803e3d6000fd5b505050506040513d602081101561171157600080fd5b81019080805190602001909291905050509850603460009054906101000a90046001600160a01b03166001600160a01b031663906c0a418f6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561178f57600080fd5b505afa1580156117a3573d6000803e3d6000fd5b505050506040513d60208110156117b957600080fd5b81019080805190602001909291905050509750603460009054906101000a90046001600160a01b03166001600160a01b03166388079d888f6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561183757600080fd5b505afa15801561184b573d6000803e3d6000fd5b505050506040513d602081101561186157600080fd5b81019080805190602001909291905050509650603460009054906101000a90046001600160a01b03166001600160a01b03166346bc0f288f6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156118df57600080fd5b505afa1580156118f3573d6000803e3d6000fd5b505050506040513d602081101561190957600080fd5b81019080805190602001909291905050509550603460009054906101000a90046001600160a01b03166001600160a01b031663bfacad848f6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561198757600080fd5b505afa15801561199b573d6000803e3d6000fd5b505050506040513d60208110156119b157600080fd5b81019080805190602001909291905050509450603460009054906101000a90046001600160a01b03166001600160a01b031663bd7fd79a8f6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611a2f57600080fd5b505afa158015611a43573d6000803e3d6000fd5b505050506040513d6020811015611a5957600080fd5b81019080805190602001909291905050509350603460009054906101000a90046001600160a01b03166001600160a01b031663b701d0938f6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611ad757600080fd5b505afa158015611aeb573d6000803e3d6000fd5b505050506040513d6020811015611b0157600080fd5b81019080805190602001909291905050509250603460009054906101000a90046001600160a01b03166001600160a01b03166334b3beee8f6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611b7f57600080fd5b505afa158015611b93573d6000803e3d6000fd5b505050506040513d6020811015611ba957600080fd5b81019080805190602001909291905050509150603460009054906101000a90046001600160a01b03166001600160a01b0316634f1446098f6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611c2757600080fd5b505afa158015611c3b573d6000803e3d6000fd5b505050506040513d6020811015611c5157600080fd5b50519c9e9b9d50999b989a9799509597949693959294919390929190565b600080600080600080600080603460009054906101000a90046001600160a01b03166001600160a01b0316635fc526ff8a6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060806040518083038186803b158015611ce657600080fd5b505afa158015611cfa573d6000803e3d6000fd5b505050506040513d6080811015611d1057600080fd5b810190808051906020019092919080519060200190929190805190602001909291908051906020019092919050505090919250809650819950829a50505050603460009054906101000a90046001600160a01b03166001600160a01b0316639e6748488a6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611dba57600080fd5b505afa158015611dce573d6000803e3d6000fd5b505050506040513d6020811015611de457600080fd5b505160345460408051632e79732b60e11b81526001600160a01b038d811660048301529151939550911691635cf2e65691602480820192602092909190829003018186803b158015611e3557600080fd5b505afa158015611e49573d6000803e3d6000fd5b505050506040513d6020811015611e5f57600080fd5b505160345460408051630283aeb760e11b81526001600160a01b038d8116600483015291519396509116916305075d6e91602480820192602092909190829003018186803b158015611eb057600080fd5b505afa158015611ec4573d6000803e3d6000fd5b505050506040513d6020811015611eda57600080fd5b5051603454604080516331da9b2760e21b81526001600160a01b038d81166004830152915193945091169163c76a6c9c91602480820192602092909190829003018186803b158015611f2b57600080fd5b505afa158015611f3f573d6000803e3d6000fd5b505050506040513d6020811015611f5557600080fd5b505160345460408051633570a20b60e11b81526001600160a01b038d811660048301529151939950911691636ae1441691602480820192602092909190829003018186803b158015611fa657600080fd5b505afa158015611fba573d6000803e3d6000fd5b505050506040513d6020811015611fd057600080fd5b50519799969850949695929491935091565b670de0b6b3a764000090565b6000611ff8612867565b60345460408051635fc526ff60e01b81526001600160a01b03888116600483015291519190921691635fc526ff916024808301926080929190829003018186803b15801561204557600080fd5b505afa158015612059573d6000803e3d6000fd5b505050506040513d608081101561206f57600080fd5b508051604082015160609092015115801561014085015260a0840192909252825280612119575060345460408051639e3c4f3b60e01b81526001600160a01b038881166004830152878116602483015291519190921691639e3c4f3b916044808301926020929190829003018186803b1580156120eb57600080fd5b505afa1580156120ff573d6000803e3d6000fd5b505050506040513d602081101561211557600080fd5b5051155b156121285760019150506122e2565b61213184610e1e565b505060808701525060608501526040840181905260208401919091521515905061215f5760019150506122e2565b60355460408051631f94a27560e31b815290516000926001600160a01b03169163fca513a8916004808301926020929190829003018186803b1580156121a457600080fd5b505afa1580156121b8573d6000803e3d6000fd5b505050506040513d60208110156121ce57600080fd5b505182516040805163b3596f0760e01b81526001600160a01b038a81166004830152915193945061223093600a9390930a926105df9289929087169163b3596f0791602480820192602092909190829003018186803b1580156105a757600080fd5b60c08301819052602083015161224b9163ffffffff61260a16565b60e08301819052612261576000925050506122e2565b6122ac8260e001516105df6122878560a001518660c001516124f890919063ffffffff16565b608086015160208701516122a09163ffffffff6124f816565b9063ffffffff61260a16565b610100830181905260e0830151604084015160608501516000936122d2939291906125bb565b670de0b6b3a76400001093505050505b9392505050565b600181565b60008060008060008060008061230389610e1e565b50959d50939b5091995097509094509250905061232287878785612667565b9350919395975091939597565b670de0b6b3a764000081565b60006123456127c9565b60015490915060ff168061235c575061235c6127ce565b80612368575060005481115b6123a35760405162461bcd60e51b815260040180806020018281038252602e8152602001806128e5602e913960400191505060405180910390fd5b60015460ff161580156123c2576001805460ff19168117905560008290555b603580546001600160a01b0319166001600160a01b0385169081179091556040805163076b7fbb60e51b8152905163ed6ff76091600480820192602092909190829003018186803b15801561241657600080fd5b505afa15801561242a573d6000803e3d6000fd5b505050506040513d602081101561244057600080fd5b5051603480546001600160a01b0319166001600160a01b039092169190911790558015612472576001805460ff191690555b505050565b6035546001600160a01b031681565b6034546001600160a01b031681565b6000828201838110156124ef576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b600082612507575060006124f2565b8282028284828161251457fe5b04146124ef5760405162461bcd60e51b81526004018080602001828103825260218152602001806128c46021913960400191505060405180910390fd5b60008082116125a7576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b60008284816125b257fe5b04949350505050565b6000836125cb5750600019612602565b6125ff6125de858563ffffffff61249516565b6125f360646105df898763ffffffff6124f816565b9063ffffffff6127d416565b90505b949350505050565b600082821115612661576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b60008061267f60646105df888663ffffffff6124f816565b905084811015612693576000915050612602565b6126b36126a6868663ffffffff61249516565b829063ffffffff61260a16565b90506000603560009054906101000a90046001600160a01b03166001600160a01b031663fbeefc3c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561270557600080fd5b505afa158015612719573d6000803e3d6000fd5b505050506040513d602081101561272f57600080fd5b505160408051630e563a7d60e41b81523360048201526024810185905290516001600160a01b039092169163e563a7d091604480820192602092909190829003018186803b15801561278057600080fd5b505afa158015612794573d6000803e3d6000fd5b505050506040513d60208110156127aa57600080fd5b505190506127be828263ffffffff61260a16565b979650505050505050565b600190565b303b1590565b600060028204612602836105df6127f387670de0b6b3a76400006124f8565b849063ffffffff61249516565b604051806101600160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160001515815260200160001515815260200160006001600160a01b031681525090565b60405180610160016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600015158152509056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564a265627a7a72315820adc898c6134d3301a904758715b45e2e49d5fe7389a407ad9602cf2edcb3049e64736f6c634300050e0032", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/external/abi/aave/v1/LendingRateOracle.json b/external/abi/aave/v1/LendingRateOracle.json deleted file mode 100644 index 199fa9229..000000000 --- a/external/abi/aave/v1/LendingRateOracle.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "contractName": "LendingRateOracle", - "abi": [{"constant":true,"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"getMarketBorrowRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_rate","type":"uint256"}],"name":"setMarketBorrowRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"getMarketLiquidityRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_rate","type":"uint256"}],"name":"setMarketLiquidityRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}], - "bytecode": "0x608060405234801561001057600080fd5b506101ac806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806372eb293d146100515780639f86a0ee1461007f578063bb85c0bb146100ab578063fbe5ba1e146100e3575b600080fd5b61007d6004803603604081101561006757600080fd5b506001600160a01b038135169060200135610109565b005b61007d6004803603604081101561009557600080fd5b506001600160a01b038135169060200135610125565b6100d1600480360360208110156100c157600080fd5b50356001600160a01b0316610141565b60408051918252519081900360200190f35b6100d1600480360360208110156100f957600080fd5b50356001600160a01b031661015c565b6001600160a01b03909116600090815260208190526040902055565b6001600160a01b03909116600090815260016020526040902055565b6001600160a01b031660009081526020819052604090205490565b6001600160a01b03166000908152600160205260409020549056fea265627a7a72315820e8c5b8ec27cc93d92d2643c271134181005277c91db565661a7174cea6b1b2fb64736f6c634300050e0032", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/external/abi/aave/v1/AaveGovernanceV2.json b/external/abi/aave/v2/AaveGovernanceV2.json similarity index 100% rename from external/abi/aave/v1/AaveGovernanceV2.json rename to external/abi/aave/v2/AaveGovernanceV2.json diff --git a/external/abi/aave/v1/AaveTokenV2Mintable.json b/external/abi/aave/v2/AaveTokenV2Mintable.json similarity index 100% rename from external/abi/aave/v1/AaveTokenV2Mintable.json rename to external/abi/aave/v2/AaveTokenV2Mintable.json diff --git a/external/abi/aave/v1/Executor.json b/external/abi/aave/v2/Executor.json similarity index 100% rename from external/abi/aave/v1/Executor.json rename to external/abi/aave/v2/Executor.json diff --git a/external/abi/aave/v1/GovernanceStrategy.json b/external/abi/aave/v2/GovernanceStrategy.json similarity index 100% rename from external/abi/aave/v1/GovernanceStrategy.json rename to external/abi/aave/v2/GovernanceStrategy.json diff --git a/external/abi/axie_infinity/tokenSwap.json b/external/abi/axie_infinity/tokenSwap.json deleted file mode 100644 index 877dc2ff5..000000000 --- a/external/abi/axie_infinity/tokenSwap.json +++ /dev/null @@ -1,207 +0,0 @@ -{ - "contractName": "TokenSwap", - "abi": [ - { - "inputs": [ - { - "internalType": "contract IERC20", - "name": "_oldToken", - "type": "address" - }, - { - "internalType": "contract IERC20", - "name": "_newToken", - "type": "address" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_oldAdmin", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_oldAdmin", - "type": "address" - } - ], - "name": "AdminRemoved", - "type": "event" - }, - { - "constant": true, - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_newAdmin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "mainchainGateway", - "outputs": [ - { - "internalType": "contract MainchainGateway", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "newToken", - "outputs": [ - { - "internalType": "contract IERC20", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "oldToken", - "outputs": [ - { - "internalType": "contract IERC20", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "removeAdmin", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "contract MainchainGateway", - "name": "_mainchainGateway", - "type": "address" - } - ], - "name": "setGateway", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_recipient", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "swapAndBridge", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_recipient", - "type": "address" - } - ], - "name": "swapAndBridgeAll", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "swapToken", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "withdrawToken", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "608060405234801561001057600080fd5b50604051610d54380380610d548339818101604052604081101561003357600080fd5b508051602090910151600080546001600160a01b03191633178082556040516001600160a01b039190911691907f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f908290a3600180546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055610c94806100c06000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c8063a5a5fdb811610071578063a5a5fdb81461014e578063b31c710a1461017a578063c42bd05a14610182578063ca628c781461018a578063dc73e49c14610192578063f851a4401461019a576100a9565b80635a4ccad8146100ae5780638f283970146100d257806390646b4a146100fa57806391d03dfa146101205780639a202d4714610146575b600080fd5b6100b66101a2565b604080516001600160a01b039092168252519081900360200190f35b6100f8600480360360208110156100e857600080fd5b50356001600160a01b03166101b1565b005b6100f86004803603602081101561011057600080fd5b50356001600160a01b03166102a6565b6100f86004803603602081101561013657600080fd5b50356001600160a01b0316610441565b6100f8610620565b6100f86004803603604081101561016457600080fd5b506001600160a01b0381351690602001356106bd565b6100b6610934565b6100b6610943565b6100f8610952565b6100f8610aa4565b6100b6610c01565b6003546001600160a01b031681565b6000546001600160a01b03163314610206576040805162461bcd60e51b81526020600482015260136024820152722430b9a0b236b4b71d103737ba1030b236b4b760691b604482015290519081900360640190fd5b6001600160a01b03811661024b5760405162461bcd60e51b8152600401808060200182810382526027815260200180610c396027913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f91a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146102fb576040805162461bcd60e51b81526020600482015260136024820152722430b9a0b236b4b71d103737ba1030b236b4b760691b604482015290519081900360640190fd5b6003546001600160a01b03161561039c576002546003546040805163095ea7b360e01b81526001600160a01b0392831660048201526000602482018190529151929093169263095ea7b39260448083019360209383900390910190829087803b15801561036757600080fd5b505af115801561037b573d6000803e3d6000fd5b505050506040513d602081101561039157600080fd5b505161039c57600080fd5b600380546001600160a01b0319166001600160a01b0383811691909117918290556002546040805163095ea7b360e01b8152938316600485015260001960248501525191169163095ea7b39160448083019260209291908290030181600087803b15801561040957600080fd5b505af115801561041d573d6000803e3d6000fd5b505050506040513d602081101561043357600080fd5b505161043e57600080fd5b50565b6001600160a01b0381166104865760405162461bcd60e51b8152600401808060200182810382526028815260200180610c116028913960400191505060405180910390fd5b600154604080516370a0823160e01b815233600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156104d157600080fd5b505afa1580156104e5573d6000803e3d6000fd5b505050506040513d60208110156104fb57600080fd5b5051600154604080516323b872dd60e01b81523360048201523060248201526044810184905290519293506001600160a01b03909116916323b872dd916064808201926020929091908290030181600087803b15801561055a57600080fd5b505af115801561056e573d6000803e3d6000fd5b505050506040513d602081101561058457600080fd5b505161058f57600080fd5b600354600254604080516385eb3a3560e01b81526001600160a01b038681166004830152928316602482015260448101859052905191909216916385eb3a359160648083019260209291908290030181600087803b1580156105f057600080fd5b505af1158015610604573d6000803e3d6000fd5b505050506040513d602081101561061a57600080fd5b50505050565b6000546001600160a01b03163314610675576040805162461bcd60e51b81526020600482015260136024820152722430b9a0b236b4b71d103737ba1030b236b4b760691b604482015290519081900360640190fd5b600080546040516001600160a01b03909116917fa3b62bc36326052d97ea62d63c3d60308ed4c3ea8ac079dd8499f1e9c4f80c0f91a2600080546001600160a01b0319169055565b6001600160a01b0382166107025760405162461bcd60e51b8152600401808060200182810382526028815260200180610c116028913960400191505060405180910390fd5b600154604080516370a0823160e01b815233600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561074d57600080fd5b505afa158015610761573d6000803e3d6000fd5b505050506040513d602081101561077757600080fd5b5051600154604080516323b872dd60e01b81523360048201523060248201526044810184905290519293506001600160a01b03909116916323b872dd916064808201926020929091908290030181600087803b1580156107d657600080fd5b505af11580156107ea573d6000803e3d6000fd5b505050506040513d602081101561080057600080fd5b505161080b57600080fd5b8082111561081857600080fd5b6002546040805163a9059cbb60e01b8152336004820152848403602482015290516001600160a01b039092169163a9059cbb916044808201926020929091908290030181600087803b15801561086d57600080fd5b505af1158015610881573d6000803e3d6000fd5b505050506040513d602081101561089757600080fd5b50516108a257600080fd5b600354600254604080516385eb3a3560e01b81526001600160a01b038781166004830152928316602482015260448101869052905191909216916385eb3a359160648083019260209291908290030181600087803b15801561090357600080fd5b505af1158015610917573d6000803e3d6000fd5b505050506040513d602081101561092d57600080fd5b5050505050565b6001546001600160a01b031681565b6002546001600160a01b031681565b6000546001600160a01b031633146109a7576040805162461bcd60e51b81526020600482015260136024820152722430b9a0b236b4b71d103737ba1030b236b4b760691b604482015290519081900360640190fd5b600254604080516370a0823160e01b815230600482015290516001600160a01b039092169163a9059cbb91339184916370a08231916024808301926020929190829003018186803b1580156109fb57600080fd5b505afa158015610a0f573d6000803e3d6000fd5b505050506040513d6020811015610a2557600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b158015610a7657600080fd5b505af1158015610a8a573d6000803e3d6000fd5b505050506040513d6020811015610aa057600080fd5b5050565b600154604080516370a0823160e01b815233600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015610aef57600080fd5b505afa158015610b03573d6000803e3d6000fd5b505050506040513d6020811015610b1957600080fd5b5051600154604080516323b872dd60e01b81523360048201523060248201526044810184905290519293506001600160a01b03909116916323b872dd916064808201926020929091908290030181600087803b158015610b7857600080fd5b505af1158015610b8c573d6000803e3d6000fd5b505050506040513d6020811015610ba257600080fd5b5051610bad57600080fd5b6002546040805163a9059cbb60e01b81523360048201526024810184905290516001600160a01b039092169163a9059cbb916044808201926020929091908290030181600087803b15801561040957600080fd5b6000546001600160a01b03168156fe546f6b656e537761703a20726563697069656e7420697320746865207a65726f206164647265737348617341646d696e3a206e65772061646d696e20697320746865207a65726f2061646472657373a265627a7a72315820046c95de273744f0ea3e057c4db8b3ad3047c8c01616078bca5204fa7005fc0b64736f6c63430005110032" -} \ No newline at end of file diff --git a/external/abi/decentral_games/DGLight.json b/external/abi/decentral_games/DGLight.json deleted file mode 100644 index 95653a72c..000000000 --- a/external/abi/decentral_games/DGLight.json +++ /dev/null @@ -1,382 +0,0 @@ -{ - "contractName": "DGLight", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_classicDGTokenAddress", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_spender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "_value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "_value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "inputs": [], - "name": "DOMAIN_SEPARATOR", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PERMIT_TYPEHASH", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RATIO", - "outputs": [ - { - "internalType": "uint16", - "name": "", - "type": "uint16" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - }, - { - "internalType": "address", - "name": "_spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_account", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "classicDG", - "outputs": [ - { - "internalType": "contract IClassicDGToken", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "decimals", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_classicAmountToReceive", - "type": "uint256" - } - ], - "name": "goClassic", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_classicAmountToDeposit", - "type": "uint256" - } - ], - "name": "goLight", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "nonces", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - }, - { - "internalType": "address", - "name": "_spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_deadline", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "_v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "_r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_s", - "type": "bytes32" - } - ], - "name": "permit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_recipient", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_sender", - "type": "address" - }, - { - "internalType": "address", - "name": "_recipient", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "60a06040523480156200001157600080fd5b5060405162000f8838038062000f888339810160408190526200003491620002a8565b604080518082018252600f81526e446563656e7472616c2047616d657360881b602080830191825283518085019094526002845261444760f01b908401528151919291620000859160009162000202565b5080516200009b90600190602084019062000202565b50506002805460ff19166012179055506001600160a01b0381166080527f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000e362000168565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160408051601f1981840301815291905280516020909101206007555062000317565b6060600080546200017990620002da565b80601f0160208091040260200160405190810160405280929190818152602001828054620001a790620002da565b8015620001f85780601f10620001cc57610100808354040283529160200191620001f8565b820191906000526020600020905b815481529060010190602001808311620001da57829003601f168201915b5050505050905090565b8280546200021090620002da565b90600052602060002090601f0160209004810192826200023457600085556200027f565b82601f106200024f57805160ff19168380011785556200027f565b828001600101855582156200027f579182015b828111156200027f57825182559160200191906001019062000262565b506200028d92915062000291565b5090565b5b808211156200028d576000815560010162000292565b600060208284031215620002bb57600080fd5b81516001600160a01b0381168114620002d357600080fd5b9392505050565b600181811c90821680620002ef57607f821691505b602082108114156200031157634e487b7160e01b600052602260045260246000fd5b50919050565b608051610c4762000341600039600081816101d50152818161040101526104dc0152610c476000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c80635748f4e9116100a257806395d89b411161007157806395d89b4114610274578063a9059cbb1461027c578063d35ab3f11461028f578063d505accf146102a2578063dd62ed3e146102b557600080fd5b80635748f4e9146101d057806359e741d21461020f57806370a082311461022b5780637ecebe001461025457600080fd5b8063249a7d82116100de578063249a7d821461017657806330adf81f1461018b578063313ce567146101b25780633644e515146101c757600080fd5b806306fdde0314610110578063095ea7b31461012e57806318160ddd1461015157806323b872dd14610163575b600080fd5b6101186102ee565b604051610125919061097d565b60405180910390f35b61014161013c3660046109ee565b610380565b6040519015158152602001610125565b6003545b604051908152602001610125565b610141610171366004610a18565b610396565b610189610184366004610a54565b6103e5565b005b6101557f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60025460405160ff9091168152602001610125565b61015560075481565b6101f77f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610125565b6102186103e881565b60405161ffff9091168152602001610125565b610155610239366004610a6d565b6001600160a01b031660009081526004602052604090205490565b610155610262366004610a6d565b60066020526000908152604090205481565b61011861049e565b61014161028a3660046109ee565b6104ad565b61018961029d366004610a54565b6104ba565b6101896102b0366004610a8f565b610576565b6101556102c3366004610b02565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205490565b6060600080546102fd90610b35565b80601f016020809104026020016040519081016040528092919081815260200182805461032990610b35565b80156103765780601f1061034b57610100808354040283529160200191610376565b820191906000526020600020905b81548152906001019060200180831161035957829003601f168201915b5050505050905090565b600061038d33848461078e565b50600192915050565b6001600160a01b03831660009081526005602090815260408083203380855292528220546103d09186916103cb908690610b86565b61078e565b6103db8484846107f0565b5060019392505050565b60405163a9059cbb60e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb90604401602060405180830381600087803b15801561044d57600080fd5b505af1158015610461573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104859190610b9d565b5061049b336104966103e884610bbf565b610898565b50565b6060600180546102fd90610b35565b600061038d3384846107f0565b6040516323b872dd60e01b8152336004820152306024820152604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906323b872dd90606401602060405180830381600087803b15801561052857600080fd5b505af115801561053c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105609190610b9d565b5061049b336105716103e884610bbf565b61091f565b428410156105cb5760405162461bcd60e51b815260206004820152601a60248201527f45524332303a205045524d49545f43414c4c5f4558504952454400000000000060448201526064015b60405180910390fd5b6007546001600160a01b038816600090815260066020526040812080549192917f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918b918b918b91908761061e83610bde565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e0016040516020818303038152906040528051906020012060405160200161069792919061190160f01b81526002810192909252602282015260420190565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa158015610702573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906107385750886001600160a01b0316816001600160a01b0316145b6107785760405162461bcd60e51b8152602060048201526011602482015270494e56414c49445f5349474e415455524560781b60448201526064016105c2565b61078389898961078e565b505050505050505050565b6001600160a01b0383811660008181526005602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b038316600090815260046020526040902054610814908290610b86565b6001600160a01b038085166000908152600460205260408082209390935590841681522054610844908290610bf9565b6001600160a01b0380841660008181526004602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906107e39085815260200190565b6001600160a01b0382166000908152600460205260409020546108bc908290610b86565b6001600160a01b0383166000818152600460205260408082209390935560038054859003905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906109139085815260200190565b60405180910390a35050565b8060035461092d9190610bf9565b6003556001600160a01b0382166000818152600460209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610913565b600060208083528351808285015260005b818110156109aa5785810183015185820160400152820161098e565b818111156109bc576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b03811681146109e957600080fd5b919050565b60008060408385031215610a0157600080fd5b610a0a836109d2565b946020939093013593505050565b600080600060608486031215610a2d57600080fd5b610a36846109d2565b9250610a44602085016109d2565b9150604084013590509250925092565b600060208284031215610a6657600080fd5b5035919050565b600060208284031215610a7f57600080fd5b610a88826109d2565b9392505050565b600080600080600080600060e0888a031215610aaa57600080fd5b610ab3886109d2565b9650610ac1602089016109d2565b95506040880135945060608801359350608088013560ff81168114610ae557600080fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215610b1557600080fd5b610b1e836109d2565b9150610b2c602084016109d2565b90509250929050565b600181811c90821680610b4957607f821691505b60208210811415610b6a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b600082821015610b9857610b98610b70565b500390565b600060208284031215610baf57600080fd5b81518015158114610a8857600080fd5b6000816000190483118215151615610bd957610bd9610b70565b500290565b6000600019821415610bf257610bf2610b70565b5060010190565b60008219821115610c0c57610c0c610b70565b50019056fea26469706673582212207a3b5b0c330f51eeab5b8ff04f4ca87febbd8f73b5aa2ec84c3d195ab39158d264736f6c63430008090033", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/external/abi/decentral_games/dgToken.json b/external/abi/decentral_games/dgToken.json deleted file mode 100644 index 297abf5c9..000000000 --- a/external/abi/decentral_games/dgToken.json +++ /dev/null @@ -1,284 +0,0 @@ -{ - "contractName": "dgToken", - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "decimals", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "subtractedValue", - "type": "uint256" - } - ], - "name": "decreaseAllowance", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "addedValue", - "type": "uint256" - } - ], - "name": "increaseAllowance", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "608060405234801561001057600080fd5b506040518060400160405280600f81526020016e646563656e7472616c2e67616d657360881b8152506040518060400160405280600381526020016224444760e81b815250816003908051906020019061006b929190610203565b50805161007f906004906020840190610203565b50506005805460ff19166012179055506100a33369d3c21bcecceda10000006100a8565b6102a4565b6001600160a01b038216610103576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b61011c816002546101a260201b6105731790919060201c565b6002556001600160a01b0382166000908152602081815260409091205461014c9183906105736101a2821b17901c565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6000828201838110156101fc576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282610239576000855561027f565b82601f1061025257805160ff191683800117855561027f565b8280016001018555821561027f579182015b8281111561027f578251825591602001919060010190610264565b5061028b92915061028f565b5090565b5b8082111561028b5760008155600101610290565b6109e2806102b36000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c8063395093511161007157806339509351146101d957806370a082311461020557806395d89b411461022b578063a457c2d714610233578063a9059cbb1461025f578063dd62ed3e1461028b576100a9565b806306fdde03146100ae578063095ea7b31461012b57806318160ddd1461016b57806323b872dd14610185578063313ce567146101bb575b600080fd5b6100b66102b9565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100f05781810151838201526020016100d8565b50505050905090810190601f16801561011d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101576004803603604081101561014157600080fd5b506001600160a01b03813516906020013561034f565b604080519115158252519081900360200190f35b61017361036c565b60408051918252519081900360200190f35b6101576004803603606081101561019b57600080fd5b506001600160a01b03813581169160208101359091169060400135610372565b6101c36103f9565b6040805160ff9092168252519081900360200190f35b610157600480360360408110156101ef57600080fd5b506001600160a01b038135169060200135610402565b6101736004803603602081101561021b57600080fd5b50356001600160a01b0316610450565b6100b661046b565b6101576004803603604081101561024957600080fd5b506001600160a01b0381351690602001356104cc565b6101576004803603604081101561027557600080fd5b506001600160a01b038135169060200135610534565b610173600480360360408110156102a157600080fd5b506001600160a01b0381358116916020013516610548565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103455780601f1061031a57610100808354040283529160200191610345565b820191906000526020600020905b81548152906001019060200180831161032857829003601f168201915b5050505050905090565b600061036361035c6105d4565b84846105d8565b50600192915050565b60025490565b600061037f8484846106c4565b6103ef8461038b6105d4565b6103ea85604051806060016040528060288152602001610917602891396001600160a01b038a166000908152600160205260408120906103c96105d4565b6001600160a01b031681526020810191909152604001600020549190610814565b6105d8565b5060019392505050565b60055460ff1690565b600061036361040f6105d4565b846103ea85600160006104206105d4565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610573565b6001600160a01b031660009081526020819052604090205490565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103455780601f1061031a57610100808354040283529160200191610345565b60006103636104d96105d4565b846103ea8560405180606001604052806025815260200161098860259139600160006105036105d4565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610814565b60006103636105416105d4565b84846106c4565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6000828201838110156105cd576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b3390565b6001600160a01b03831661061d5760405162461bcd60e51b81526004018080602001828103825260248152602001806109646024913960400191505060405180910390fd5b6001600160a01b0382166106625760405162461bcd60e51b81526004018080602001828103825260228152602001806108cf6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0383166107095760405162461bcd60e51b815260040180806020018281038252602581526020018061093f6025913960400191505060405180910390fd5b6001600160a01b03821661074e5760405162461bcd60e51b81526004018080602001828103825260238152602001806108ac6023913960400191505060405180910390fd5b61078b816040518060600160405280602681526020016108f1602691396001600160a01b0386166000908152602081905260409020549190610814565b6001600160a01b0380851660009081526020819052604080822093909355908416815220546107ba9082610573565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600081848411156108a35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610868578181015183820152602001610850565b50505050905090810190601f1680156108955780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50505090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220f3181830134f5d22a15260e73e051d6472110ab43bc104e6196db1877536127564736f6c63430007050033", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/external/abi/singularityNET/singularityNetToken.json b/external/abi/singularityNET/singularityNetToken.json deleted file mode 100644 index a7ca2ce61..000000000 --- a/external/abi/singularityNET/singularityNetToken.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "contractName": "SingularityNetToken", - "abi": [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"INITIAL_SUPPLY","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_value","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseApproval","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"},{"name":"amount","type":"uint256"}],"name":"transferTokens","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseApproval","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"burner","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}], - "bytecode": "60606040526000600360146101000a81548160ff021916908315150217905550341561002a57600080fd5b33600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600860ff16600a0a633b9aca0002600081905550600860ff16600a0a633b9aca0002600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611b9b806100df6000396000f300606060405260043610610107576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde031461010c578063095ea7b31461019a57806318160ddd146101f457806323b872dd1461021d5780632ff2e9dc14610296578063313ce567146102bf5780633f4ba83a146102ee57806342966c68146103035780635c975abb14610326578063661884631461035357806370a08231146103ad5780638456cb59146103fa5780638da5cb5b1461040f57806395d89b4114610464578063a9059cbb146104f2578063bec3fa171461054c578063d73dd623146105a6578063dd62ed3e14610600578063f2fde38b1461066c575b600080fd5b341561011757600080fd5b61011f6106a5565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561015f578082015181840152602081019050610144565b50505050905090810190601f16801561018c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156101a557600080fd5b6101da600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506106de565b604051808215151515815260200191505060405180910390f35b34156101ff57600080fd5b61020761070e565b6040518082815260200191505060405180910390f35b341561022857600080fd5b61027c600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610714565b604051808215151515815260200191505060405180910390f35b34156102a157600080fd5b6102a9610746565b6040518082815260200191505060405180910390f35b34156102ca57600080fd5b6102d2610757565b604051808260ff1660ff16815260200191505060405180910390f35b34156102f957600080fd5b61030161075c565b005b341561030e57600080fd5b610324600480803590602001909190505061081c565b005b341561033157600080fd5b61033961097f565b604051808215151515815260200191505060405180910390f35b341561035e57600080fd5b610393600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610992565b604051808215151515815260200191505060405180910390f35b34156103b857600080fd5b6103e4600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506109c2565b6040518082815260200191505060405180910390f35b341561040557600080fd5b61040d610a0b565b005b341561041a57600080fd5b610422610acc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561046f57600080fd5b610477610af2565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156104b757808201518184015260208101905061049c565b50505050905090810190601f1680156104e45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156104fd57600080fd5b610532600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610b2b565b604051808215151515815260200191505060405180910390f35b341561055757600080fd5b61058c600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610b5b565b604051808215151515815260200191505060405180910390f35b34156105b157600080fd5b6105e6600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610dc7565b604051808215151515815260200191505060405180910390f35b341561060b57600080fd5b610656600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610df7565b6040518082815260200191505060405180910390f35b341561067757600080fd5b6106a3600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610e7e565b005b6040805190810160405280601481526020017f53696e67756c61726974794e455420546f6b656e00000000000000000000000081525081565b6000600360149054906101000a900460ff161515156106fc57600080fd5b6107068383610fd6565b905092915050565b60005481565b6000600360149054906101000a900460ff1615151561073257600080fd5b61073d8484846110c8565b90509392505050565b600860ff16600a0a633b9aca000281565b600881565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156107b857600080fd5b600360149054906101000a900460ff1615156107d357600080fd5b6000600360146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b6000808211151561082c57600080fd5b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561087a57600080fd5b3390506108cf82600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461148790919063ffffffff16565b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506109278260005461148790919063ffffffff16565b6000819055508073ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a25050565b600360149054906101000a900460ff1681565b6000600360149054906101000a900460ff161515156109b057600080fd5b6109ba83836114a0565b905092915050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610a6757600080fd5b600360149054906101000a900460ff16151515610a8357600080fd5b6001600360146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040805190810160405280600381526020017f414749000000000000000000000000000000000000000000000000000000000081525081565b6000600360149054906101000a900460ff16151515610b4957600080fd5b610b538383611731565b905092915050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610bb957600080fd5b600082111515610bc857600080fd5b610c3c8260016000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461148790919063ffffffff16565b60016000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610cf382600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461195590919063ffffffff16565b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b6000600360149054906101000a900460ff16151515610de557600080fd5b610def8383611973565b905092915050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610eda57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610f1657600080fd5b8073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415151561110557600080fd5b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561115357600080fd5b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482111515156111de57600080fd5b61123082600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461148790919063ffffffff16565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506112c582600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461195590919063ffffffff16565b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061139782600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461148790919063ffffffff16565b600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b600082821115151561149557fe5b818303905092915050565b600080600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050808311156115b1576000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611645565b6115c4838261148790919063ffffffff16565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a3600191505092915050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415151561176e57600080fd5b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482111515156117bc57600080fd5b61180e82600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461148790919063ffffffff16565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506118a382600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461195590919063ffffffff16565b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b600080828401905083811015151561196957fe5b8091505092915050565b6000611a0482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461195590919063ffffffff16565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a360019050929150505600a165627a7a72305820" -} \ No newline at end of file diff --git a/test/integration/aaveGovernanceModule.spec.ts b/test/integration/aaveGovernanceModule.spec.ts deleted file mode 100644 index 60b4426fd..000000000 --- a/test/integration/aaveGovernanceModule.spec.ts +++ /dev/null @@ -1,178 +0,0 @@ -import "module-alias/register"; -import { utils, BigNumber } from "ethers"; - -import { Address, Bytes } from "@utils/types"; -import { Account } from "@utils/test/types"; -import { ADDRESS_ZERO, EMPTY_BYTES, ONE_DAY_IN_SECONDS, ZERO } from "@utils/constants"; -import { AaveGovernanceAdapter, SetToken, GovernanceModule } from "@utils/contracts"; -import DeployHelper from "@utils/deploys"; -import { - ether, -} from "@utils/index"; -import { - addSnapshotBeforeRestoreAfterEach, - getAccounts, - getWaffleExpect, - getSystemFixture, - getAaveFixture, - getRandomAddress, - increaseTimeAsync, -} from "@utils/test/index"; -import { AaveFixture, SystemFixture } from "@utils/fixtures"; - -const expect = getWaffleExpect(); - -describe("AaveGovernanceModule", () => { - let owner: Account; - let deployer: DeployHelper; - let setup: SystemFixture; - - let aaveSetup: AaveFixture; - - let governanceModule: GovernanceModule; - let aaveGovernanceAdapter: AaveGovernanceAdapter; - - const aaveGovernanceAdapterIntegrationName: string = "AAVE"; - - before(async () => { - [ - owner, - ] = await getAccounts(); - - // System setup - deployer = new DeployHelper(owner.wallet); - setup = getSystemFixture(owner.address); - await setup.initialize(); - - // Aave setup - aaveSetup = getAaveFixture(owner.address); - await aaveSetup.initialize(); - - // GovernanceModule setup - governanceModule = await deployer.modules.deployGovernanceModule(setup.controller.address); - await setup.controller.addModule(governanceModule.address); - - // AaveGovernanceAdapter setup - aaveGovernanceAdapter = await deployer.adapters.deployAaveGovernanceAdapter( - aaveSetup.aaveProtoGovernance.address, - aaveSetup.aaveToken.address, - ); - - await setup.integrationRegistry.addIntegration( - governanceModule.address, - aaveGovernanceAdapterIntegrationName, - aaveGovernanceAdapter.address - ); - }); - - addSnapshotBeforeRestoreAfterEach(); - - context("when a SetToken has been deployed and issued", async () => { - let setToken: SetToken; - let setTokensIssued: BigNumber; - - let componentUnits: BigNumber[]; - - before(async () => { - componentUnits = [ether(1000), ether(100)]; // 1000 AAVE, 100 LEND - setToken = await setup.createSetToken( - [aaveSetup.aaveToken.address, aaveSetup.lendToken.address], - componentUnits, - [setup.issuanceModule.address, governanceModule.address] - ); - - // Initialize modules - await setup.issuanceModule.initialize(setToken.address, ADDRESS_ZERO); - await governanceModule.initialize(setToken.address); - - // Issue some Sets - setTokensIssued = ether(1); - await aaveSetup.aaveToken.approve(setup.issuanceModule.address, componentUnits[0]); - await aaveSetup.lendToken.approve(setup.issuanceModule.address, componentUnits[1]); - await setup.issuanceModule.issue(setToken.address, setTokensIssued, owner.address); - }); - - describe("#vote", async () => { - let subjectSetToken: Address; - let subjectProposalId: BigNumber; - let subjectSupport: boolean; - let subjectData: Bytes; - let subjectIntegrationName: string; - let subjectCaller: Account; - - beforeEach(async () => { - await aaveSetup.aaveProtoGovernance.newProposal( - utils.keccak256(new Buffer("ProposalOne")), - utils.keccak256(new Buffer("RandomIPFSHash")), - ether(13000000), - await getRandomAddress(), - 1660, - 1660, - 5 - ); - - const proposalReviewPeriod = ONE_DAY_IN_SECONDS; - await increaseTimeAsync(proposalReviewPeriod); - - subjectSetToken = setToken.address; - subjectIntegrationName = aaveGovernanceAdapterIntegrationName; - subjectProposalId = ZERO; - subjectSupport = true; - subjectData = EMPTY_BYTES; - subjectCaller = owner; - }); - - async function subject(): Promise { - return governanceModule.connect(subjectCaller.wallet).vote( - subjectSetToken, - subjectIntegrationName, - subjectProposalId, - subjectSupport, - subjectData - ); - } - - it("should vote in Aave", async () => { - await subject(); - - const votesData = await aaveSetup.aaveProtoGovernance.getVotesData(ZERO); - expect(votesData[0]).to.eq(ZERO); - expect(votesData[1]).to.eq(componentUnits[0]); - expect(votesData[2]).to.eq(ZERO); - }); - - describe("when voting with another supported token", () => { - beforeEach(async () => { - subjectData = utils.defaultAbiCoder.encode( - ["address"], - [aaveSetup.lendToken.address] - ); - }); - - it("should vote with LEND token", async () => { - await subject(); - - const votesData = await aaveSetup.aaveProtoGovernance.getVotesData(ZERO); - expect(votesData[0]).to.eq(ZERO); - expect(votesData[1]).to.eq(componentUnits[1]); - expect(votesData[2]).to.eq(ZERO); - }); - }); - - describe("when voting against a proposal", () => { - beforeEach(async () => { - subjectSupport = false; - }); - - it("should vote false", async () => { - await subject(); - - const votesData = await aaveSetup.aaveProtoGovernance.getVotesData(ZERO); - expect(votesData[0]).to.eq(ZERO); - expect(votesData[1]).to.eq(ZERO); - expect(votesData[2]).to.eq(componentUnits[0]); - }); - }); - }); - }); -}); diff --git a/test/integration/aaveMigrationWrapModule.spec.ts b/test/integration/aaveMigrationWrapModule.spec.ts deleted file mode 100644 index 9f6ac43c1..000000000 --- a/test/integration/aaveMigrationWrapModule.spec.ts +++ /dev/null @@ -1,179 +0,0 @@ -import "module-alias/register"; -import { BigNumber } from "ethers"; - -import { Address } from "@utils/types"; -import { Account } from "@utils/test/types"; -import { ADDRESS_ZERO } from "@utils/constants"; -import { AaveMigrationWrapAdapter, SetToken, WrapModule } from "@utils/contracts"; -import DeployHelper from "@utils/deploys"; -import { - ether, -} from "@utils/index"; -import { - addSnapshotBeforeRestoreAfterEach, - getAccounts, - getWaffleExpect, - getSystemFixture, - getAaveFixture, -} from "@utils/test/index"; -import { AaveFixture, SystemFixture } from "@utils/fixtures"; - -const expect = getWaffleExpect(); - -describe("AaveMigrationWrapModule", () => { - let owner: Account; - let deployer: DeployHelper; - let setup: SystemFixture; - - let aaveSetup: AaveFixture; - - let wrapModule: WrapModule; - let aaveMigrationWrapAdapter: AaveMigrationWrapAdapter; - - const aaveMigrationWrapAdapterIntegrationName: string = "AAVE_MIGRATION_WRAPPER"; - - before(async () => { - [ - owner, - ] = await getAccounts(); - - // System setup - deployer = new DeployHelper(owner.wallet); - setup = getSystemFixture(owner.address); - await setup.initialize(); - - // Aave setup - aaveSetup = getAaveFixture(owner.address); - await aaveSetup.initialize(); - - // WrapModule setup - wrapModule = await deployer.modules.deployWrapModule(setup.controller.address, setup.weth.address); - await setup.controller.addModule(wrapModule.address); - - // AaveMigrationWrapAdapter setup - aaveMigrationWrapAdapter = await deployer.adapters.deployAaveMigrationWrapAdapter( - aaveSetup.lendToAaveMigrator.address, - aaveSetup.lendToken.address, - aaveSetup.aaveToken.address - ); - - await setup.integrationRegistry.addIntegration(wrapModule.address, aaveMigrationWrapAdapterIntegrationName, aaveMigrationWrapAdapter.address); - }); - - addSnapshotBeforeRestoreAfterEach(); - - context("when a SetToken has been deployed and issued", async () => { - let setToken: SetToken; - let setTokensIssued: BigNumber; - - before(async () => { - setToken = await setup.createSetToken( - [aaveSetup.lendToken.address], - [ether(1)], - [setup.issuanceModule.address, wrapModule.address] - ); - - // Initialize modules - await setup.issuanceModule.initialize(setToken.address, ADDRESS_ZERO); - await wrapModule.initialize(setToken.address); - - // Issue some Sets - setTokensIssued = ether(10); - const underlyingRequired = setTokensIssued; - await aaveSetup.lendToken.approve(setup.issuanceModule.address, underlyingRequired); - - await setup.issuanceModule.issue(setToken.address, setTokensIssued, owner.address); - }); - - describe("#wrap", async () => { - let subjectSetToken: Address; - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectUnderlyingUnits: BigNumber; - let subjectIntegrationName: string; - let subjectCaller: Account; - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectUnderlyingToken = aaveSetup.lendToken.address; - subjectWrappedToken = aaveSetup.aaveToken.address; - subjectUnderlyingUnits = ether(1); - subjectIntegrationName = aaveMigrationWrapAdapterIntegrationName; - subjectCaller = owner; - }); - - async function subject(): Promise { - return wrapModule.connect(subjectCaller.wallet).wrap( - subjectSetToken, - subjectUnderlyingToken, - subjectWrappedToken, - subjectUnderlyingUnits, - subjectIntegrationName, - ); - } - - it("should reduce the underlying quantity and mint the wrapped asset to the SetToken", async () => { - const previousUnderlyingBalance = await aaveSetup.lendToken.balanceOf(setToken.address); - const previousWrappedBalance = await aaveSetup.aaveToken.balanceOf(setToken.address); - - await subject(); - - const underlyingBalance = await aaveSetup.lendToken.balanceOf(setToken.address); - const wrappedBalance = await aaveSetup.aaveToken.balanceOf(setToken.address); - - const expectedUnderlyingBalance = previousUnderlyingBalance.sub(setTokensIssued); - expect(underlyingBalance).to.eq(expectedUnderlyingBalance); - - const expectedWrappedBalance = previousWrappedBalance.add(setTokensIssued.div(aaveSetup.aaveExchangeRatio)); - expect(wrappedBalance).to.eq(expectedWrappedBalance); - }); - }); - - describe("#unwrap", () => { - let subjectSetToken: Address; - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectWrappedTokenUnits: BigNumber; - let subjectIntegrationName: string; - let subjectCaller: Account; - - let wrappedQuantity: BigNumber; - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectUnderlyingToken = aaveSetup.lendToken.address; - subjectWrappedToken = aaveSetup.aaveToken.address; - subjectWrappedTokenUnits = ether(0.01); - subjectIntegrationName = aaveMigrationWrapAdapterIntegrationName; - subjectCaller = owner; - - wrappedQuantity = ether(1); - - await wrapModule.wrap( - subjectSetToken, - subjectUnderlyingToken, - subjectWrappedToken, - wrappedQuantity, - subjectIntegrationName, - ); - }); - - async function subject(): Promise { - return wrapModule.connect(subjectCaller.wallet).unwrap( - subjectSetToken, - subjectUnderlyingToken, - subjectWrappedToken, - subjectWrappedTokenUnits, - subjectIntegrationName, - { - gasLimit: 5000000, - } - ); - } - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("AAVE migration cannot be reversed"); - }); - }); - }); -}); diff --git a/test/integration/aaveWrapModule.spec.ts b/test/integration/aaveWrapModule.spec.ts deleted file mode 100644 index f54957d30..000000000 --- a/test/integration/aaveWrapModule.spec.ts +++ /dev/null @@ -1,191 +0,0 @@ -import "module-alias/register"; -import { BigNumber } from "ethers"; - -import { Address } from "@utils/types"; -import { Account } from "@utils/test/types"; -import { ADDRESS_ZERO } from "@utils/constants"; -import { AaveWrapAdapter, SetToken, WrapModule } from "@utils/contracts"; -import DeployHelper from "@utils/deploys"; -import { - ether, - preciseMul, -} from "@utils/index"; -import { - getAccounts, - getWaffleExpect, - getSystemFixture, - getAaveFixture, - addSnapshotBeforeRestoreAfterEach, -} from "@utils/test/index"; -import { AaveFixture, SystemFixture } from "@utils/fixtures"; -import { AToken } from "@typechain/AToken"; - -const expect = getWaffleExpect(); - -describe("aaveWrapModule", () => { - let owner: Account; - let deployer: DeployHelper; - let setup: SystemFixture; - - let aaveSetup: AaveFixture; - let aDai: AToken; - - let wrapModule: WrapModule; - let aaveWrapAdapter: AaveWrapAdapter; - - const aaveWrapAdapterIntegrationName: string = "AAVE_WRAPPER"; - - before(async () => { - [ - owner, - ] = await getAccounts(); - - // System setup - deployer = new DeployHelper(owner.wallet); - setup = getSystemFixture(owner.address); - await setup.initialize(); - - // Aave setup - aaveSetup = getAaveFixture(owner.address); - await aaveSetup.initialize(); - aDai = await aaveSetup.deployAToken(setup.dai.address, await setup.dai.decimals()); - - // WrapModule setup - wrapModule = await deployer.modules.deployWrapModule(setup.controller.address, setup.weth.address); - await setup.controller.addModule(wrapModule.address); - - // AaveWrapAdapter setup - aaveWrapAdapter = await deployer.adapters.deployAaveWrapAdapter(aaveSetup.lendingPool.address); - await setup.integrationRegistry.addIntegration(wrapModule.address, aaveWrapAdapterIntegrationName, aaveWrapAdapter.address); - }); - - addSnapshotBeforeRestoreAfterEach(); - - context("when a SetToken has been deployed and issued", async () => { - let setToken: SetToken; - let setTokensIssued: BigNumber; - - before(async () => { - setToken = await setup.createSetToken( - [setup.dai.address], - [ether(1)], - [setup.issuanceModule.address, wrapModule.address] - ); - - // Initialize modules - await setup.issuanceModule.initialize(setToken.address, ADDRESS_ZERO); - await wrapModule.initialize(setToken.address); - - // Issue some Sets - setTokensIssued = ether(10); - const underlyingRequired = setTokensIssued; - await setup.dai.approve(setup.issuanceModule.address, underlyingRequired); - await setup.issuanceModule.issue(setToken.address, setTokensIssued, owner.address); - }); - - describe("#wrap", async () => { - let subjectSetToken: Address; - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectUnderlyingUnits: BigNumber; - let subjectIntegrationName: string; - let subjectCaller: Account; - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectUnderlyingToken = setup.dai.address; - subjectWrappedToken = aDai.address; - subjectUnderlyingUnits = ether(1); - subjectIntegrationName = aaveWrapAdapterIntegrationName; - subjectCaller = owner; - }); - - async function subject(): Promise { - return wrapModule.connect(subjectCaller.wallet).wrap( - subjectSetToken, - subjectUnderlyingToken, - subjectWrappedToken, - subjectUnderlyingUnits, - subjectIntegrationName, - ); - } - - it("should reduce the underlying quantity and mint the wrapped asset to the SetToken", async () => { - const previousUnderlyingBalance = await setup.dai.balanceOf(setToken.address); - const previousWrappedBalance = await aDai.balanceOf(setToken.address); - - await subject(); - - const underlyingBalance = await setup.dai.balanceOf(setToken.address); - const wrappedBalance = await aDai.balanceOf(setToken.address); - - const expectedUnderlyingBalance = previousUnderlyingBalance.sub(setTokensIssued); - expect(underlyingBalance).to.eq(expectedUnderlyingBalance); - - const expectedWrappedBalance = previousWrappedBalance.add(setTokensIssued); - expect(wrappedBalance).to.eq(expectedWrappedBalance); - }); - }); - - describe("#unwrap", () => { - let subjectSetToken: Address; - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectWrappedTokenUnits: BigNumber; - let subjectIntegrationName: string; - let subjectCaller: Account; - - let wrappedQuantity: BigNumber; - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectUnderlyingToken = setup.dai.address; - subjectWrappedToken = aDai.address; - subjectWrappedTokenUnits = ether(0.5); - subjectIntegrationName = aaveWrapAdapterIntegrationName; - subjectCaller = owner; - - wrappedQuantity = ether(1); - - await wrapModule.wrap( - subjectSetToken, - subjectUnderlyingToken, - subjectWrappedToken, - wrappedQuantity, - subjectIntegrationName, - ); - }); - - async function subject(): Promise { - return wrapModule.connect(subjectCaller.wallet).unwrap( - subjectSetToken, - subjectUnderlyingToken, - subjectWrappedToken, - subjectWrappedTokenUnits, - subjectIntegrationName, - { - gasLimit: 5000000, - } - ); - } - - it("should burn the wrapped asset to the SetToken and increase the underlying quantity", async () => { - const previousUnderlyingBalance = await setup.dai.balanceOf(setToken.address); - const previousWrappedBalance = await aDai.balanceOf(setToken.address); - - await subject(); - - const underlyingBalance = await setup.dai.balanceOf(setToken.address); - const wrappedBalance = await aDai.balanceOf(setToken.address); - - const delta = preciseMul(setTokensIssued, wrappedQuantity.sub(subjectWrappedTokenUnits)); - - const expectedUnderlyingBalance = previousUnderlyingBalance.add(delta); - expect(underlyingBalance).to.eq(expectedUnderlyingBalance); - - const expectedWrappedBalance = previousWrappedBalance.sub(delta); - expect(wrappedBalance).to.eq(expectedWrappedBalance); - }); - }); - }); -}); diff --git a/test/integration/agiMigrationWrapModule.spec.ts b/test/integration/agiMigrationWrapModule.spec.ts deleted file mode 100644 index 63bfcbcd4..000000000 --- a/test/integration/agiMigrationWrapModule.spec.ts +++ /dev/null @@ -1,137 +0,0 @@ -import "module-alias/register"; -import { BigNumber } from "ethers"; - -import { Address } from "@utils/types"; -import { Account } from "@utils/test/types"; -import { ADDRESS_ZERO, ZERO } from "@utils/constants"; -import { - AGIMigrationWrapAdapter, - SetToken, - SingularityNetToken, - StandardTokenMock, - WrapModule -} from "@utils/contracts"; -import DeployHelper from "@utils/deploys"; -import { - ether, -} from "@utils/index"; -import { - addSnapshotBeforeRestoreAfterEach, - getAccounts, - getWaffleExpect, - getSystemFixture, -} from "@utils/test/index"; -import { SystemFixture } from "@utils/fixtures"; - -const expect = getWaffleExpect(); - -describe("AGIMigrationWrapModule", () => { - let owner: Account; - let deployer: DeployHelper; - let setup: SystemFixture; - - let wrapModule: WrapModule; - let agiMigrationWrapAdapter: AGIMigrationWrapAdapter; - let agiToken: SingularityNetToken; - let agixToken: StandardTokenMock; - - const agiMigrationWrapAdapterIntegrationName: string = "AGI_MIGRATION_WRAPPER"; - - before(async () => { - [ - owner, - ] = await getAccounts(); - - // System setup - deployer = new DeployHelper(owner.wallet); - setup = getSystemFixture(owner.address); - await setup.initialize(); - - // WrapModule setup - wrapModule = await deployer.modules.deployWrapModule(setup.controller.address, setup.weth.address); - await setup.controller.addModule(wrapModule.address); - - // Deploy AGI and AGIX token - agiToken = await deployer.external.deploySingularityNetToken(); - agixToken = await deployer.mocks.deployTokenMock(owner.address); - - // AaveMigrationWrapAdapter setup - agiMigrationWrapAdapter = await deployer.adapters.deployAGIMigrationWrapAdapter( - agiToken.address, - agixToken.address - ); - - await setup.integrationRegistry.addIntegration(wrapModule.address, agiMigrationWrapAdapterIntegrationName, agiMigrationWrapAdapter.address); - }); - - addSnapshotBeforeRestoreAfterEach(); - - context("when a SetToken has been deployed and issued", async () => { - let setToken: SetToken; - let setTokensIssued: BigNumber; - - before(async () => { - setToken = await setup.createSetToken( - [agiToken.address], - [BigNumber.from(10 ** 8)], - [setup.issuanceModule.address, wrapModule.address] - ); - - // Initialize modules - await setup.issuanceModule.initialize(setToken.address, ADDRESS_ZERO); - await wrapModule.initialize(setToken.address); - - // Issue some Sets - setTokensIssued = ether(10); - const underlyingRequired = setTokensIssued.div(10 ** 10); - await agiToken.approve(setup.issuanceModule.address, underlyingRequired); - - await setup.issuanceModule.issue(setToken.address, setTokensIssued, owner.address); - }); - - describe("#wrap", async () => { - let subjectSetToken: Address; - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectUnderlyingUnits: BigNumber; - let subjectIntegrationName: string; - let subjectCaller: Account; - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectUnderlyingToken = agiToken.address; - subjectWrappedToken = agixToken.address; - subjectUnderlyingUnits = BigNumber.from(10 ** 8); - subjectIntegrationName = agiMigrationWrapAdapterIntegrationName; - subjectCaller = owner; - }); - - async function subject(): Promise { - return wrapModule.connect(subjectCaller.wallet).wrap( - subjectSetToken, - subjectUnderlyingToken, - subjectWrappedToken, - subjectUnderlyingUnits, - subjectIntegrationName, - ); - } - - it("should reduce the zero out the AGI unit and remove token from components", async () => { - const previousUnderlyingBalance = await agiToken.balanceOf(setToken.address); - - await subject(); - - const underlyingBalance = await agiToken.balanceOf(setToken.address); - const agiTokenUnit = await setToken.getDefaultPositionRealUnit(agiToken.address); - const agxTokenUnit = await setToken.getDefaultPositionRealUnit(agixToken.address); - const components = await setToken.getComponents(); - - const expectedUnderlyingBalance = previousUnderlyingBalance.sub(setTokensIssued.div(10 ** 10)); - expect(underlyingBalance).to.eq(expectedUnderlyingBalance); - expect(agiTokenUnit).to.eq(ZERO); - expect(agxTokenUnit).to.eq(ZERO); - expect(components.length).to.eq(ZERO); - }); - }); - }); -}); diff --git a/test/integration/compoundWrapModule.spec.ts b/test/integration/compoundWrapModule.spec.ts deleted file mode 100644 index aabab5080..000000000 --- a/test/integration/compoundWrapModule.spec.ts +++ /dev/null @@ -1,205 +0,0 @@ -import "module-alias/register"; -import { BigNumber } from "ethers"; - -import { Address } from "@utils/types"; -import { Account } from "@utils/test/types"; -import { ADDRESS_ZERO } from "@utils/constants"; -import { SetToken, WrapModule } from "@utils/contracts"; -import { CERc20 } from "@utils/contracts/compound"; -import DeployHelper from "@utils/deploys"; -import { - ether, - preciseMul, - preciseDiv -} from "@utils/index"; -import { - getAccounts, - getWaffleExpect, - getSystemFixture, - getCompoundFixture, - addSnapshotBeforeRestoreAfterEach, -} from "@utils/test/index"; -import { CompoundFixture, SystemFixture } from "@utils/fixtures"; - -const expect = getWaffleExpect(); - -describe("compoundWrapModule", () => { - let owner: Account; - let deployer: DeployHelper; - let setup: SystemFixture; - - let compoundSetup: CompoundFixture; - let cDai: CERc20; - let exchangeRate: BigNumber; - - let wrapModule: WrapModule; - - const compoundWrapAdapterIntegrationName: string = "COMPOUND_WRAPPER"; - - before(async () => { - [ - owner, - ] = await getAccounts(); - - // System setup - deployer = new DeployHelper(owner.wallet); - setup = getSystemFixture(owner.address); - await setup.initialize(); - - // Compound setup - compoundSetup = getCompoundFixture(owner.address); - await compoundSetup.initialize(); - - exchangeRate = ether(0.5); - cDai = await compoundSetup.createAndEnableCToken( - setup.dai.address, - exchangeRate, - compoundSetup.comptroller.address, - compoundSetup.interestRateModel.address, - "Compound DAI", - "cDAI", - 8, - ether(0.75), // 75% collateral factor - ether(1) - ); - - - // WrapModule setup - wrapModule = await deployer.modules.deployWrapModule(setup.controller.address, setup.weth.address); - await setup.controller.addModule(wrapModule.address); - - // compoundWrapAdapter setup - const compoundLibrary = await deployer.libraries.deployCompound(); - const compoundWrapAdapter = await deployer.adapters.deployCompoundWrapAdapter( - "contracts/protocol/integration/lib/Compound.sol:Compound", - compoundLibrary.address - ); - await setup.integrationRegistry.addIntegration(wrapModule.address, compoundWrapAdapterIntegrationName, compoundWrapAdapter.address); - }); - - addSnapshotBeforeRestoreAfterEach(); - - context("when a SetToken has been deployed and issued", async () => { - let setToken: SetToken; - let setTokensIssued: BigNumber; - - beforeEach(async () => { - setToken = await setup.createSetToken( - [setup.dai.address], - [ether(1)], - [setup.issuanceModule.address, wrapModule.address] - ); - - // Initialize modules - await setup.issuanceModule.initialize(setToken.address, ADDRESS_ZERO); - await wrapModule.initialize(setToken.address); - - // Issue some Sets - setTokensIssued = ether(10); - const underlyingRequired = setTokensIssued; - await setup.dai.approve(setup.issuanceModule.address, underlyingRequired); - await setup.issuanceModule.issue(setToken.address, setTokensIssued, owner.address); - }); - - describe("#wrap", async () => { - let subjectSetToken: Address; - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectUnderlyingUnits: BigNumber; - let subjectIntegrationName: string; - let subjectCaller: Account; - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectUnderlyingToken = setup.dai.address; - subjectWrappedToken = cDai.address; - subjectUnderlyingUnits = ether(1); - subjectIntegrationName = compoundWrapAdapterIntegrationName; - subjectCaller = owner; - }); - - async function subject(): Promise { - return wrapModule.connect(subjectCaller.wallet).wrap( - subjectSetToken, - subjectUnderlyingToken, - subjectWrappedToken, - subjectUnderlyingUnits, - subjectIntegrationName, - ); - } - - it("should reduce the underlying quantity and mint the wrapped asset to the SetToken", async () => { - const previousUnderlyingBalance = await setup.dai.balanceOf(setToken.address); - - await subject(); - - const underlyingBalance = await setup.dai.balanceOf(setToken.address); - const wrappedBalance = await cDai.balanceOf(setToken.address); - const expectedUnderlyingBalance = previousUnderlyingBalance.sub(setTokensIssued); - - expect(underlyingBalance).to.eq(expectedUnderlyingBalance); - - const expectedWrappedBalance = preciseDiv(previousUnderlyingBalance, exchangeRate); - - expect(wrappedBalance).to.eq(expectedWrappedBalance); - }); - }); - - describe("#unwrap", () => { - let subjectSetToken: Address; - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectWrappedTokenUnits: BigNumber; - let subjectIntegrationName: string; - let subjectCaller: Account; - - let wrappedQuantity: BigNumber; - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectUnderlyingToken = setup.dai.address; - subjectWrappedToken = cDai.address; - subjectWrappedTokenUnits = BigNumber.from("5000000000"); // ctokens have 8 decimals - subjectIntegrationName = compoundWrapAdapterIntegrationName; - subjectCaller = owner; - - wrappedQuantity = ether(1); - - await wrapModule.wrap( - subjectSetToken, - subjectUnderlyingToken, - subjectWrappedToken, - wrappedQuantity, - subjectIntegrationName, - ); - }); - - async function subject(): Promise { - return wrapModule.connect(subjectCaller.wallet).unwrap( - subjectSetToken, - subjectUnderlyingToken, - subjectWrappedToken, - subjectWrappedTokenUnits, - subjectIntegrationName - ); - } - - it("should burn the wrapped asset to the SetToken and increase the underlying quantity", async () => { - const previousWrappedBalance = await cDai.balanceOf(setToken.address); - - await subject(); - - const underlyingBalance = await setup.dai.balanceOf(setToken.address); - const wrappedBalance = await cDai.balanceOf(setToken.address); - const delta = preciseMul(setTokensIssued, subjectWrappedTokenUnits); - const expectedUnderlyingBalance = preciseMul(delta, exchangeRate); - - expect(underlyingBalance).to.eq(expectedUnderlyingBalance); - - const expectedWrappedBalance = previousWrappedBalance.sub(delta); - - expect(wrappedBalance).to.eq(expectedWrappedBalance); - }); - }); - }); -}); diff --git a/test/integration/dgMigrationWrapModule.spec.ts b/test/integration/dgMigrationWrapModule.spec.ts deleted file mode 100644 index 6f2fecb4c..000000000 --- a/test/integration/dgMigrationWrapModule.spec.ts +++ /dev/null @@ -1,172 +0,0 @@ -import "module-alias/register"; -import { BigNumber } from "ethers"; - -import { Address } from "@utils/types"; -import { Account } from "@utils/test/types"; -import { ADDRESS_ZERO, ZERO } from "@utils/constants"; -import { DgMigrationWrapAdapter, SetToken, WrapModule } from "@utils/contracts"; -import DeployHelper from "@utils/deploys"; -import { - ether, -} from "@utils/index"; -import { DGLight, DgToken } from "@utils/contracts/dg"; -import { - addSnapshotBeforeRestoreAfterEach, - getAccounts, - getWaffleExpect, - getSystemFixture, -} from "@utils/test/index"; -import { SystemFixture } from "@utils/fixtures"; - -const expect = getWaffleExpect(); - -describe("dgMigrationWrapModule", () => { - let owner: Account; - let deployer: DeployHelper; - let setup: SystemFixture; - - let wrapModule: WrapModule; - - let dgClassic: DgToken; - let dgLight: DGLight; - let adapter: DgMigrationWrapAdapter; - - const dgMigrationWrapAdapterIntegrationName: string = "DG_MIGRATION_WRAPPER"; - - before(async () => { - [ - owner, - ] = await getAccounts(); - - // System setup - deployer = new DeployHelper(owner.wallet); - setup = getSystemFixture(owner.address); - await setup.initialize(); - - // WrapModule setup - wrapModule = await deployer.modules.deployWrapModule(setup.controller.address, setup.weth.address); - await setup.controller.addModule(wrapModule.address); - - // Deploy DG Classic Token (dgClassic) and DG V2 token (DGLight) - dgClassic = await deployer.external.deployDgToken(); - dgLight = await deployer.external.deployDGLight(dgClassic.address); - - // DgMigrationWrapV2Adapter setup - adapter = await deployer.adapters.deployDgMigrationWrapAdapter( - dgClassic.address, - dgLight.address - ); - - await setup.integrationRegistry.addIntegration(wrapModule.address, dgMigrationWrapAdapterIntegrationName, adapter.address); - }); - - addSnapshotBeforeRestoreAfterEach(); - - context("when a SetToken has been deployed and issued", async () => { - let setToken: SetToken; - let setTokensIssued: BigNumber; - - before(async () => { - setToken = await setup.createSetToken( - [dgClassic.address], - [BigNumber.from(10 ** 8)], - [setup.issuanceModule.address, wrapModule.address] - ); - - // Initialize modules - await setup.issuanceModule.initialize(setToken.address, ADDRESS_ZERO); - await wrapModule.initialize(setToken.address); - - // Issue some Sets - setTokensIssued = ether(10); - const underlyingRequired = setTokensIssued.div(10 ** 9); - await dgClassic.approve(setup.issuanceModule.address, underlyingRequired); - await setup.issuanceModule.issue(setToken.address, setTokensIssued, owner.address); - }); - - describe("#wrap", async () => { - let subjectSetToken: Address; - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectUnderlyingUnits: BigNumber; - let subjectIntegrationName: string; - let subjectCaller: Account; - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectUnderlyingToken = dgClassic.address; - subjectWrappedToken = dgLight.address; - subjectUnderlyingUnits = BigNumber.from(10 ** 8); - subjectIntegrationName = dgMigrationWrapAdapterIntegrationName; - subjectCaller = owner; - }); - - async function subject(): Promise { - return wrapModule.connect(subjectCaller.wallet).wrap( - subjectSetToken, - subjectUnderlyingToken, - subjectWrappedToken, - subjectUnderlyingUnits, - subjectIntegrationName - ); - } - - it("should convert underlying balance of dgClassic tokens to dgLight tokens * 1000", async () => { - const previousDgTokenBalance = await dgClassic.balanceOf(setToken.address); - const previousDGLightBalance = await dgLight.balanceOf(setToken.address); - expect(previousDgTokenBalance).to.eq(BigNumber.from(10 ** 9)); - expect(previousDGLightBalance).to.eq(ZERO); - - await subject(); - - const dgTokenBalance = await dgClassic.balanceOf(setToken.address); - const DGLightBalance = await dgLight.balanceOf(setToken.address); - const components = await setToken.getComponents(); - - expect(dgTokenBalance).to.eq(ZERO); - expect(DGLightBalance).to.eq(previousDgTokenBalance.mul(1000)); - expect(components.length).to.eq(1); - }); - }); - - describe("#unwrap", async () => { - let subjectSetToken: Address; - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectWrappedUnits: BigNumber; - let subjectIntegrationName: string; - let subjectCaller: Account; - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectUnderlyingToken = dgClassic.address; - subjectWrappedToken = dgLight.address; - subjectWrappedUnits = BigNumber.from(10 ** 8); - subjectIntegrationName = dgMigrationWrapAdapterIntegrationName; - subjectCaller = owner; - - await wrapModule.connect(subjectCaller.wallet).wrap( - subjectSetToken, - subjectUnderlyingToken, - subjectWrappedToken, - subjectWrappedUnits, - subjectIntegrationName - ); - }); - - async function subject(): Promise { - return wrapModule.connect(subjectCaller.wallet).unwrap( - subjectSetToken, - subjectUnderlyingToken, - subjectWrappedToken, - subjectWrappedUnits, - subjectIntegrationName - ); - } - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("DG migration cannot be reversed"); - }); - }); - }); -}); diff --git a/test/integration/perpV2LeverageSlippageIssuance.spec.ts b/test/integration/perpV2LeverageSlippageIssuance.spec.ts deleted file mode 100644 index 4a63f384b..000000000 --- a/test/integration/perpV2LeverageSlippageIssuance.spec.ts +++ /dev/null @@ -1,1325 +0,0 @@ -import "module-alias/register"; -import { ContractTransaction } from "ethers"; -import { Address } from "@utils/types"; -import { Account } from "@utils/test/types"; -import { - SlippageIssuanceModule, - PerpV2, - PerpV2LeverageModule, - SetToken, - StandardTokenMock, -} from "@utils/contracts"; -import { PerpV2BaseToken } from "@utils/contracts/perpV2"; -import { - toUSDCDecimals, - calculateUSDCTransferIn, - calculateUSDCTransferOut, - leverUp -} from "@utils/common"; -import DeployHelper from "@utils/deploys"; -import { - ether, - usdc as usdcUnits, - preciseDiv, - preciseMul -} from "@utils/index"; -import { - cacheBeforeEach, - getAccounts, - getWaffleExpect, - getSystemFixture, - getPerpV2Fixture, -} from "@utils/test/index"; -import { PerpV2Fixture, SystemFixture } from "@utils/fixtures"; -import { BigNumber } from "ethers"; -import { ADDRESS_ZERO, ZERO, MAX_UINT_256, ZERO_BYTES } from "@utils/constants"; - -const expect = getWaffleExpect(); - -describe("PerpV2LeverageSlippageIssuance", () => { - let owner: Account; - let maker: Account; - let otherTrader: Account; - let feeRecipient: Account; - let deployer: DeployHelper; - - let perpLib: PerpV2; - let perpLeverageModule: PerpV2LeverageModule; - let slippageIssuanceModule: SlippageIssuanceModule; - let setup: SystemFixture; - let perpSetup: PerpV2Fixture; - - let vETH: PerpV2BaseToken; - let vBTC: PerpV2BaseToken; - let usdc: StandardTokenMock; - - cacheBeforeEach(async () => { - [ - owner, - maker, - otherTrader, - feeRecipient - ] = await getAccounts(); - - deployer = new DeployHelper(owner.wallet); - setup = getSystemFixture(owner.address); - await setup.initialize(); - - perpSetup = getPerpV2Fixture(owner.address); - await perpSetup.initialize(maker, otherTrader); - - // set funding rate to zero; allows us to avoid calculating small amounts of funding - // accrued in our test cases - await perpSetup.clearingHouseConfig.setMaxFundingRate(ZERO); - - vETH = perpSetup.vETH; - vBTC = perpSetup.vBTC; - usdc = perpSetup.usdc; - - // Create liquidity - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(10)); - await perpSetup.initializePoolWithLiquidityWide( - vETH, - ether(10_000), - ether(100_000) - ); - - await perpSetup.setBaseTokenOraclePrice(vBTC, usdcUnits(20)); - await perpSetup.initializePoolWithLiquidityWide( - vBTC, - ether(10_000), - ether(200_000) - ); - - perpLib = await deployer.libraries.deployPerpV2(); - perpLeverageModule = await deployer.modules.deployPerpV2LeverageModule( - setup.controller.address, - perpSetup.vault.address, - perpSetup.quoter.address, - perpSetup.marketRegistry.address, - BigNumber.from(3), - "contracts/protocol/integration/lib/PerpV2.sol:PerpV2", - perpLib.address - ); - await setup.controller.addModule(perpLeverageModule.address); - - slippageIssuanceModule = await deployer.modules.deploySlippageIssuanceModule( - setup.controller.address - ); - await setup.controller.addModule(slippageIssuanceModule.address); - - await setup.integrationRegistry.addIntegration( - perpLeverageModule.address, - "DefaultIssuanceModule", - slippageIssuanceModule.address - ); - }); - - // Helper to calculate how leveraged the Perp account gets as it mints tokens on margin - async function calculateFlashLeverage(setToken: Address, setQuantity: BigNumber): Promise { - const spotPrice = await perpSetup.getSpotPrice(vETH.address); - const { collateralBalance } = await perpLeverageModule.getAccountInfo(setToken); - const positionNotionalInfo = (await perpLeverageModule.getPositionNotionalInfo(setToken))[0]; - const positionUnitInfo = (await perpLeverageModule.getPositionUnitInfo(setToken))[0]; - - const currentAssetValue = preciseMul(positionNotionalInfo.baseBalance, spotPrice); - const currentDebtValue = positionNotionalInfo.quoteBalance; - - const flashAssetQuantityNotional = preciseMul(positionUnitInfo.baseUnit, setQuantity); - const flashAssetValue = preciseMul(flashAssetQuantityNotional, spotPrice); - const flashDebtValue = - (await perpSetup.getSwapQuote(vETH.address, flashAssetQuantityNotional, true)).deltaQuote; - - const totalAssetValueBeforeRepayment = currentAssetValue.add(flashAssetValue); - const totalDebtValueBeforeRepayment = currentDebtValue.sub(flashDebtValue); - - return preciseDiv( - totalAssetValueBeforeRepayment, - - totalAssetValueBeforeRepayment - .add(totalDebtValueBeforeRepayment) - .add(collateralBalance) - ); - } - - async function calculateTotalSlippage(setToken: SetToken, setQuantity: BigNumber): Promise { - let totalExpectedSlippage = BigNumber.from(0); - const allPositionInfo = await perpLeverageModule.getPositionNotionalInfo(setToken.address); - - for (const positionInfo of allPositionInfo) { - const basePositionUnit = preciseDiv(positionInfo.baseBalance, await setToken.totalSupply()); - const baseTradeQuantityNotional = preciseMul(basePositionUnit, setQuantity); - const isLong = (basePositionUnit.gte(ZERO)); - - const { deltaBase, deltaQuote } = await perpSetup.getSwapQuote( - positionInfo.baseToken, - baseTradeQuantityNotional.abs(), - isLong - ); - - const idealQuote = preciseMul(deltaBase, await perpSetup.getSpotPrice(positionInfo.baseToken)); - - const expectedSlippage = (isLong) - ? idealQuote.sub(deltaQuote).mul(-1) - : idealQuote.sub(deltaQuote); - - totalExpectedSlippage = totalExpectedSlippage.add(expectedSlippage); - } - - return totalExpectedSlippage; - } - - async function calculateRedemptionData( - setToken: Address, - redeemQuantity: BigNumber, - usdcTransferOutQuantity: BigNumber - ) { - // Calculate fee adjusted usdcTransferOut - const redeemQuantityWithFees = (await slippageIssuanceModule.calculateTotalFees( - setToken, - redeemQuantity, - false - ))[0]; - - const feeAdjustedTransferOutUSDC = preciseMul(redeemQuantityWithFees, usdcTransferOutQuantity); - - // Calculate realizedPnl. The amount is debited from collateral returned to redeemer *and* - // debited from the Perp account collateral balance because withdraw performs a settlement. - let realizedPnlUSDC = BigNumber.from(0); - const positionUnitInfo = await await perpLeverageModule.getPositionUnitInfo(setToken); - - for (const info of positionUnitInfo) { - const baseTradeQuantityNotional = preciseMul(info.baseUnit, redeemQuantity); - - const { deltaQuote } = await perpSetup.getSwapQuote( - info.baseToken, - baseTradeQuantityNotional, - false - ); - - const { - baseBalance, - quoteBalance - } = (await perpLeverageModule.getPositionNotionalInfo(setToken))[0]; - - const closeRatio = preciseDiv(baseTradeQuantityNotional, baseBalance); - const reducedOpenNotional = preciseMul(quoteBalance, closeRatio); - - realizedPnlUSDC = realizedPnlUSDC.add(toUSDCDecimals(reducedOpenNotional.add(deltaQuote))); - } - - return { - feeAdjustedTransferOutUSDC, - realizedPnlUSDC, - redeemQuantityWithFees - }; - } - - describe("#issuance", async () => { - let setToken: SetToken; - let issueFee: BigNumber; - let usdcDefaultPositionUnit: BigNumber; - - let subjectSetToken: Address; - let subjectQuantity: BigNumber; - let subjectCheckedComponents: Address[]; - let subjectMaxTokenAmountsIn: BigNumber[]; - let subjectTo: Address; - let subjectCaller: Account; - let issueQuantity: BigNumber; - - const initializeContracts = async function() { - usdcDefaultPositionUnit = usdcUnits(10); - setToken = await setup.createSetToken( - [usdc.address], - [usdcDefaultPositionUnit], - [perpLeverageModule.address, slippageIssuanceModule.address] - ); - issueFee = ether(0.005); - await slippageIssuanceModule.initialize( - setToken.address, - ether(0.02), - issueFee, - ether(0.005), - feeRecipient.address, - ADDRESS_ZERO - ); - // Add SetToken to allow list - await perpLeverageModule.updateAllowedSetToken(setToken.address, true); - await perpLeverageModule.initialize(setToken.address); - - // Approve tokens to issuance module and call issue - await usdc.approve(slippageIssuanceModule.address, usdcUnits(1000)); - }; - - async function subject(): Promise { - return slippageIssuanceModule.connect(subjectCaller.wallet).issueWithSlippage( - subjectSetToken, - subjectQuantity, - subjectCheckedComponents, - subjectMaxTokenAmountsIn, - subjectTo, - ); - } - - context("when there is a default usdc position with 0 supply", async () => { - cacheBeforeEach(initializeContracts); - beforeEach(() => { - subjectSetToken = setToken.address; - subjectQuantity = ether(1); - subjectCheckedComponents = []; - subjectMaxTokenAmountsIn = []; - subjectTo = owner.address; - subjectCaller = owner; - }); - - it("should not update the collateral position on the SetToken", async () => { - const initialPositions = await setToken.getPositions(); - - await subject(); - - const currentPositions = await setToken.getPositions(); - const newFirstPosition = (await setToken.getPositions())[0]; - - expect(initialPositions.length).to.eq(1); - expect(currentPositions.length).to.eq(1); - expect(newFirstPosition.component).to.eq(usdc.address); - expect(newFirstPosition.positionState).to.eq(0); // Default - expect(newFirstPosition.unit).to.eq(usdcDefaultPositionUnit); - expect(newFirstPosition.module).to.eq(ADDRESS_ZERO); - }); - - it("should not have an external usdc position", async () => { - const initialPositions = await setToken.getPositions(); - - await subject(); - - const currentPositions = await setToken.getPositions(); - - expect(initialPositions.length).to.eq(1); - expect(currentPositions.length).to.eq(1); - }); - - it("should have the correct token balances", async () => { - const preMinterUSDCBalance = await usdc.balanceOf(subjectCaller.address); - const preSetUSDCBalance = await usdc.balanceOf(subjectSetToken); - - await subject(); - - const mintQuantity = preciseMul(subjectQuantity, ether(1).add(issueFee)); - const usdcFlows = preciseMul(mintQuantity, usdcDefaultPositionUnit); - - const postMinterUSDCBalance = await usdc.balanceOf(subjectCaller.address); - const postSetUSDCBalance = await usdc.balanceOf(subjectSetToken); - - expect(postMinterUSDCBalance).to.eq(preMinterUSDCBalance.sub(usdcFlows)); - expect(postSetUSDCBalance).to.eq(preSetUSDCBalance.add(usdcFlows)); - }); - }); - - context("when there is only an external USDC position and totalSupply is 1", async () => { - let baseToken: Address; - let depositQuantityUnit: BigNumber; - let usdcTransferInQuantity: BigNumber; - - cacheBeforeEach(initializeContracts); - - beforeEach(async () => { - // Issue 1 SetToken - issueQuantity = ether(1); - await slippageIssuanceModule.issue(setToken.address, issueQuantity, owner.address); - - depositQuantityUnit = usdcDefaultPositionUnit; - await perpLeverageModule.deposit(setToken.address, depositQuantityUnit); - - // Lever up - baseToken = vETH.address; - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - baseToken, - 2, - ether(.02), - true - ); - - subjectSetToken = setToken.address; - subjectCheckedComponents = []; - subjectMaxTokenAmountsIn = []; - subjectTo = owner.address; - subjectCaller = owner; - }); - - describe("starting test assumptions", async () => { - it("should be correct", async() => { - const defaultPositionUnit = await setToken.getDefaultPositionRealUnit(usdc.address); - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(defaultPositionUnit).eq(ZERO); - expect(externalPositionUnit).eq(depositQuantityUnit); - }); - }); - - describe("when minting a single set", () => { - beforeEach(async () => { - subjectQuantity = ether(1); - - usdcTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectQuantity, - perpLeverageModule, - perpSetup - ); - }); - - it("should not update the USDC defaultPositionUnit", async () => { - const initialDefaultPositionUnit = await setToken.getDefaultPositionRealUnit(usdc.address); - await subject(); - const finalDefaultPositionUnit = await setToken.getDefaultPositionRealUnit(usdc.address);; - - expect(finalDefaultPositionUnit).to.eq(initialDefaultPositionUnit); - }); - - it("should have set the expected USDC externalPositionUnit", async () => { - const expectedExternalPositionUnit = preciseDiv(usdcTransferInQuantity, subjectQuantity); - - await subject(); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - // externalPositionUnit = 10_008_105; - expect(externalPositionUnit).to.be.closeTo(expectedExternalPositionUnit, 1); - }); - - it("have the expected virtual token balance", async () => { - const totalSupply = await setToken.totalSupply(); - - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - await subject(); - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - - const basePositionUnit = preciseDiv(initialBaseBalance, totalSupply); - const baseTokenBoughtNotional = preciseMul(basePositionUnit, subjectQuantity); - const expectedBaseBalance = initialBaseBalance.add(baseTokenBoughtNotional); - - expect(finalBaseBalance).eq(expectedBaseBalance); - }); - - it("should deposit the expected amount into the Perp vault", async () => { - const initialCollateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - await subject(); - const finalCollateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const issueQuantityWithFees = (await slippageIssuanceModule.calculateTotalFees( - subjectSetToken, - subjectQuantity, - true - ))[0]; - - const feeAdjustedTransferIn = preciseMul(issueQuantityWithFees, usdcTransferInQuantity); - - // usdcTransferIn = 10_008_105 - // feeAdjustedTransferIn = 10_058_145 - const expectedCollateralBalance = toUSDCDecimals(initialCollateralBalance).add(feeAdjustedTransferIn); - expect(toUSDCDecimals(finalCollateralBalance)).to.be.closeTo(expectedCollateralBalance, 2); - }); - - it("should get required component issuance units correctly", async () => { - const issueQuantityWithFees = (await slippageIssuanceModule.calculateTotalFees( - subjectSetToken, - subjectQuantity, - true - ))[0]; - - const externalPositionUnit = preciseDiv(usdcTransferInQuantity, subjectQuantity); - const feeAdjustedTransferIn = preciseMul(issueQuantityWithFees, externalPositionUnit); - - const [components, equityFlows, debtFlows] = await slippageIssuanceModule.callStatic.getRequiredComponentIssuanceUnitsOffChain( - subjectSetToken, - subjectQuantity - ); - - const expectedComponents = await setToken.getComponents(); - const expectedEquityFlows = [feeAdjustedTransferIn]; - const expectedDebtFlows = [ZERO]; - - expect(expectedComponents[0]).to.eq(components[0]); - expect(expectedEquityFlows[0]).to.be.closeTo(equityFlows[0], 50); - expect(expectedDebtFlows[0]).to.eq(debtFlows[0]); - }); - }); - - describe("when minting multiple sets", () => { - beforeEach(async () => { - subjectQuantity = ether(2); - - usdcTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectQuantity, - perpLeverageModule, - perpSetup - ); - }); - - it("should have set the expected USDC externalPositionUnit", async () => { - const expectedExternalPositionUnit = preciseDiv(usdcTransferInQuantity, subjectQuantity); - - await subject(); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - // externalPositionUnit = 10_008_105; - expect(externalPositionUnit).to.be.closeTo(expectedExternalPositionUnit, 1); - }); - - it("have the expected virtual token balance", async () => { - const totalSupply = await setToken.totalSupply(); - - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - await subject(); - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - - const basePositionUnit = preciseDiv(initialBaseBalance, totalSupply); - const baseTokenBoughtNotional = preciseMul(basePositionUnit, subjectQuantity); - const expectedBaseBalance = initialBaseBalance.add(baseTokenBoughtNotional); - - expect(finalBaseBalance).eq(expectedBaseBalance); - }); - - it("should deposit the expected amount into the Perp vault", async () => { - const initialCollateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - await subject(); - const finalCollateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const issueQuantityWithFees = (await slippageIssuanceModule.calculateTotalFees( - subjectSetToken, - subjectQuantity, - true - ))[0]; - - const externalPositionUnit = preciseDiv(usdcTransferInQuantity, subjectQuantity); - const feeAdjustedTransferIn = preciseMul(issueQuantityWithFees, externalPositionUnit); - - // usdcTransferIn = 20_024_302 - // feeAdjustedTransferIn = 20_124_423 - const expectedCollateralBalance = toUSDCDecimals(initialCollateralBalance).add(feeAdjustedTransferIn); - expect(toUSDCDecimals(finalCollateralBalance)).to.be.closeTo(expectedCollateralBalance, 2); - }); - - it("should deposit the expected amount into the Perp vault", async () => { - const issueQuantityWithFees = (await slippageIssuanceModule.calculateTotalFees( - subjectSetToken, - subjectQuantity, - true - ))[0]; - - const externalPositionUnit = preciseDiv(usdcTransferInQuantity, subjectQuantity); - const feeAdjustedTransferIn = preciseMul(issueQuantityWithFees, externalPositionUnit); - - const initialCollateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - await subject(); - const finalCollateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - // usdcTransferIn = 20_024_302 - // feeAdjustedTransferIn = 20_124_423 - const expectedCollateralBalance = toUSDCDecimals(initialCollateralBalance).add(feeAdjustedTransferIn); - expect(toUSDCDecimals(finalCollateralBalance)).to.be.closeTo(expectedCollateralBalance, 2); - }); - - // This is slightly off ... over a tenth of a penny. - it.skip("should not incur a premium", async () => { - const issueQuantityWithFees = (await slippageIssuanceModule.calculateTotalFees( - subjectSetToken, - subjectQuantity, - true - ))[0]; - - // Model says premium should be calculated as (usdcTransferIn / amountMinted) - const externalPositionUnit = preciseDiv(usdcTransferInQuantity, subjectQuantity); - const feeAdjustedTransferIn = preciseMul(issueQuantityWithFees, externalPositionUnit); - const feeAdjustedExternalPositionUnit = preciseDiv(feeAdjustedTransferIn, issueQuantityWithFees); - - // Slippage will be paid by the issuer, but get reflected as debt in the quote balance. - const totalSlippageAndFees = await calculateTotalSlippage(setToken, subjectQuantity); - const totalSlippagePositionUnit = preciseDiv(totalSlippageAndFees, subjectQuantity); - - const feeAndSlippageAdjustedExternalPositionUnit = feeAdjustedExternalPositionUnit - .sub(toUSDCDecimals(totalSlippagePositionUnit)); - - await subject(); - - // Calculate value of set - const accountInfo = await perpLeverageModule.getAccountInfo(subjectSetToken); - const spotPrice = await perpSetup.getSpotPrice(baseToken); - const baseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - const notionalBaseValue = preciseMul(baseBalance, spotPrice); - - const totalSetValue = notionalBaseValue - .add(accountInfo.netQuoteBalance) - .add(accountInfo.collateralBalance) - .add(accountInfo.owedRealizedPnl); - - const valuePerSet = preciseDiv(totalSetValue, await setToken.totalSupply()); - const valuePerSetUSDC = toUSDCDecimals(valuePerSet); - - // feeAdjustedExternalPositionUnit = 10012150 - // feeAndSlippageAdjustedExternalPositionUnit = 9801960 - // valuePerSet = 9818624 - expect(valuePerSetUSDC).eq(feeAndSlippageAdjustedExternalPositionUnit); - }); - }); - - describe("when flash-issuing at high margin (success)", async () => { - // Starting point is 2X leverage, with 10 USDC collateral, 20 USDC vETH, totalSupply = 1 - // Minting 3 sets raises interim leverage ratio to > 80 USDC Asset / 10 USDC collateral - // We know from spec scenario testing that the effective limit is ~ 9.1X - beforeEach(async () => { - subjectQuantity = ether(3); - }); - - // Calculated leverage = 8_702_210_816_139_153_672 - it("~8.7X succeeds", async() => { - const flashLeverage = await calculateFlashLeverage(subjectSetToken, subjectQuantity); - await subject(); - - expect(flashLeverage).to.be.gt(ether(8)); - expect(flashLeverage).to.be.lt(ether(9)); - }); - }); - - describe("when flash-issuing at high margin (failure)", async () => { - beforeEach(async () => { - subjectQuantity = ether(3.5); - }); - - // Calculated leverage = 9_911_554_370_685_102_958 - it("~9.9X fails", async () => { - const flashLeverage = await calculateFlashLeverage(subjectSetToken, subjectQuantity); - - await expect(subject()).to.be.revertedWith("CH_NEFCI"); - - expect(flashLeverage).to.be.gt(ether(9)); - expect(flashLeverage).to.be.lt(ether(10)); - }); - }); - - describe("when issuing after a liquidation", async () => { - beforeEach(async () => { - subjectQuantity = ether(1); - - // Calculated leverage = ~8.5X = 8_654_438_822_995_683_587 - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - baseToken, - 6, - ether(.02), - true - ); - - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(8.0)); - - await perpSetup - .clearingHouse - .connect(otherTrader.wallet) - .liquidate(subjectSetToken, baseToken); - }); - - it("should issue and transfer in the expected amount", async () => { - const initialTotalSupply = await setToken.totalSupply(); - const initialCollateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - await subject(); - - // We need to calculate this after the subject() fires because it will revert if the positionList - // isn't updated correctly... - const usdcTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectQuantity, - perpLeverageModule, - perpSetup - ); - - const finalTotalSupply = await setToken.totalSupply(); - const finalPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - const finalCollateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const issueQuantityWithFees = (await slippageIssuanceModule.calculateTotalFees( - subjectSetToken, - subjectQuantity, - true - ))[0]; - - const externalPositionUnit = preciseDiv(usdcTransferInQuantity, subjectQuantity); - const feeAdjustedTransferIn = preciseMul(issueQuantityWithFees, externalPositionUnit); - - const expectedTotalSupply = initialTotalSupply.add(issueQuantityWithFees); - const expectedCollateralBalance = toUSDCDecimals(initialCollateralBalance).add(feeAdjustedTransferIn); - - expect(finalTotalSupply).eq(expectedTotalSupply); - expect(finalPositionInfo.length).eq(0); - expect(toUSDCDecimals(finalCollateralBalance)).to.be.closeTo(expectedCollateralBalance, 2); - }); - }); - - describe("when liquidation results in negative account value", () => { - beforeEach(async () => { - subjectQuantity = ether(1); - - // Calculated leverage = ~8.5X = 8_654_438_822_995_683_587 - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - baseToken, - 6, - ether(.02), - true - ); - - // Move oracle price down to 5 USDC to enable liquidation - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(5)); - - // Move price down by maker selling 20_000 USDC of vETH - // Post trade spot price drops from ~10 USDC to 6_380_562_015_950_425_028 - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(20_000), - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - await perpSetup - .clearingHouse - .connect(otherTrader.wallet) - .liquidate(subjectSetToken, baseToken); - }); - - // In this test case, the account is bankrupt: - // collateralBalance = 10050000000000000000 - // owedRealizedPnl = -31795534271984084912 - it("should issue without transferring any usdc (because account worth 0)", async () => { - const issueQuantityWithFees = (await slippageIssuanceModule.calculateTotalFees( - subjectSetToken, - subjectQuantity, - true - ))[0]; - - const initialIssuerUSDCBalance = await usdc.balanceOf(subjectCaller.address); - const initialTotalSupply = await setToken.totalSupply(); - - await subject(); - - const finalIssuerUSDCBalance = await usdc.balanceOf(subjectCaller.address); - const finalTotalSupply = await setToken.totalSupply(); - - const expectedTotalSupply = initialTotalSupply.add(issueQuantityWithFees); - - expect(finalTotalSupply).eq(expectedTotalSupply); - expect(finalIssuerUSDCBalance).eq(initialIssuerUSDCBalance); - }); - }); - }); - }); - - describe("#redemption", async () => { - let setToken: SetToken; - let baseToken: Address; - let redeemFee: BigNumber; - let depositQuantityUnit: BigNumber; - let usdcDefaultPositionUnit: BigNumber; - let usdcTransferOutQuantity: BigNumber; - - let subjectSetToken: Address; - let subjectQuantity: BigNumber; - let subjectCheckedComponents: Address[]; - let subjectMaxTokenAmountsIn: BigNumber[]; - let subjectTo: Address; - let subjectCaller: Account; - let issueQuantity: BigNumber; - - const initializeContracts = async function() { - usdcDefaultPositionUnit = usdcUnits(10); - setToken = await setup.createSetToken( - [usdc.address], - [usdcDefaultPositionUnit], - [perpLeverageModule.address, slippageIssuanceModule.address] - ); - redeemFee = ether(0.005); - await slippageIssuanceModule.initialize( - setToken.address, - ether(0.02), - ether(0.005), - redeemFee, - feeRecipient.address, - ADDRESS_ZERO - ); - // Add SetToken to allow list - await perpLeverageModule.updateAllowedSetToken(setToken.address, true); - await perpLeverageModule.initialize(setToken.address); - - // Approve tokens to issuance module and call issue - await usdc.approve(slippageIssuanceModule.address, usdcUnits(1000)); - }; - - async function subject(): Promise { - return slippageIssuanceModule.connect(subjectCaller.wallet).redeemWithSlippage( - subjectSetToken, - subjectQuantity, - subjectCheckedComponents, - subjectMaxTokenAmountsIn, - subjectTo - ); - } - - context("when there is only an external USDC position and redeem will take supply to 0", async () => { - cacheBeforeEach(initializeContracts); - - beforeEach(async () => { - // Issue 1 SetToken - issueQuantity = ether(1); - await slippageIssuanceModule.issue(setToken.address, issueQuantity, owner.address); - - depositQuantityUnit = usdcUnits(10); - await perpLeverageModule.deposit(setToken.address, depositQuantityUnit); - - // Lever up 2X - baseToken = vETH.address; - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - baseToken, - 2, - ether(.02), - true - ); - - subjectSetToken = setToken.address; - subjectQuantity = issueQuantity; - subjectCheckedComponents = []; - subjectMaxTokenAmountsIn = []; - subjectTo = owner.address; - subjectCaller = owner; - - usdcTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectQuantity, - perpLeverageModule, - perpSetup - ); - }); - - it("should not update the USDC defaultPositionUnit", async () => { - const initialDefaultPositionUnit = await setToken.getDefaultPositionRealUnit(usdc.address); - await subject(); - const finalDefaultPositionUnit = await setToken.getDefaultPositionRealUnit(usdc.address); - - expect(initialDefaultPositionUnit).eq(finalDefaultPositionUnit); - }); - - it("should have updated the USDC externalPositionUnit", async () => { - const initialExternalPositionUnit = await setToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - await subject(); - const finalExternalPositionUnit = await setToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - - const expectedExternalPositionUnit = usdcTransferOutQuantity; - - expect(initialExternalPositionUnit).not.eq(finalExternalPositionUnit); - expect(finalExternalPositionUnit).eq(expectedExternalPositionUnit); - }); - - it("should have the expected virtual token balance", async () => { - const totalSupply = await setToken.totalSupply(); - - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - await subject(); - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - - const basePositionUnit = preciseDiv(initialBaseBalance, totalSupply); - const baseTokenBoughtNotional = preciseMul(basePositionUnit, subjectQuantity); - const expectedBaseBalance = initialBaseBalance.sub(baseTokenBoughtNotional); - - expect(finalBaseBalance).eq(expectedBaseBalance); - }); - - it("should not have updated the setToken USDC token balance", async () => { - const initialUSDCBalance = await usdc.balanceOf(subjectSetToken); - await subject(); - const finalUSDCBalance = await usdc.balanceOf(subjectSetToken); - - expect(initialUSDCBalance).eq(finalUSDCBalance); - }); - - describe("withdrawal", () => { - let feeAdjustedTransferOutUSDC: BigNumber; - let realizedPnlUSDC: BigNumber; - - beforeEach(async() => { - ({ - feeAdjustedTransferOutUSDC, - realizedPnlUSDC - } = await calculateRedemptionData( - subjectSetToken, - subjectQuantity, - usdcTransferOutQuantity - )); - }); - - it("should withdraw the expected amount from the Perp vault", async () => { - const initialCollateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - await subject(); - const finalCollateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const initialCollateralBalanceUSDC = toUSDCDecimals(initialCollateralBalance); - const finalCollateralBalanceUSDC = toUSDCDecimals(finalCollateralBalance); - - const expectedCollateralBalanceUSDC = initialCollateralBalanceUSDC - .sub(feeAdjustedTransferOutUSDC) - .add(realizedPnlUSDC); - - expect(finalCollateralBalanceUSDC).to.be.closeTo(expectedCollateralBalanceUSDC, 1); - }); - - it("should not update the setToken USDC token balance", async () => { - const initialUSDCBalance = await usdc.balanceOf(subjectSetToken); - await subject(); - const finalUSDCBalance = await usdc.balanceOf(subjectSetToken); - - expect(initialUSDCBalance).eq(0); - expect(finalUSDCBalance).eq(initialUSDCBalance); - }); - - it("should have transferred expected USDC to set token holder", async () => { - const initialOwnerUSDCBalance = await usdc.balanceOf(subjectCaller.address); - await subject(); - const finalOwnerUSDCBalance = await usdc.balanceOf(subjectCaller.address); - - const expectedUSDCBalance = initialOwnerUSDCBalance.add(feeAdjustedTransferOutUSDC); - expect(finalOwnerUSDCBalance).eq(expectedUSDCBalance); - }); - }); - }); - - context("when there is only an external USDC position and redeem will take supply to 1", async () => { - let depositQuantityUnit: BigNumber; - let usdcTransferOutQuantity: BigNumber; - - cacheBeforeEach(initializeContracts); - - beforeEach(async () => { - // Issue 2 SetTokens - issueQuantity = ether(2); - await slippageIssuanceModule.issue(setToken.address, issueQuantity, owner.address); - - // Deposit entire default position - depositQuantityUnit = usdcDefaultPositionUnit; - await perpLeverageModule.deposit(setToken.address, depositQuantityUnit); - - // Lever up 2X - baseToken = vETH.address; - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - baseToken, - 2, - ether(.02), - true - ); - - subjectSetToken = setToken.address; - subjectQuantity = ether(1); - subjectCheckedComponents = []; - subjectMaxTokenAmountsIn = []; - subjectTo = owner.address; - subjectCaller = owner; - - usdcTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectQuantity, - perpLeverageModule, - perpSetup - ); - }); - - it("should not update the USDC defaultPositionUnit", async () => { - const initialDefaultPositionUnit = await setToken.getDefaultPositionRealUnit(usdc.address); - await subject(); - const finalDefaultPositionUnit = await setToken.getDefaultPositionRealUnit(usdc.address); - - expect(initialDefaultPositionUnit).eq(finalDefaultPositionUnit); - }); - - it("should update the USDC externalPositionUnit", async () => { - const initialExternalPositionUnit = await setToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - await subject(); - const finalExternalPositionUnit = await setToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - - // initialExternalPositionUnit = 10_000_000 - // finalExternalPositionUnit = 9_597_857 - - const expectedExternalPositionUnit = preciseDiv(usdcTransferOutQuantity, subjectQuantity); - expect(initialExternalPositionUnit).eq(usdcDefaultPositionUnit); - expect(finalExternalPositionUnit).to.be.closeTo(expectedExternalPositionUnit, 1); - }); - - it("should have the expected virtual token balance", async () => { - const totalSupply = await setToken.totalSupply(); - - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - await subject(); - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - - const basePositionUnit = preciseDiv(initialBaseBalance, totalSupply); - const baseTokenSoldNotional = preciseMul(basePositionUnit, subjectQuantity); - const expectedBaseBalance = initialBaseBalance.sub(baseTokenSoldNotional); - - expect(finalBaseBalance).eq(expectedBaseBalance); - }); - - it("should get required component redemption units correctly", async () => { - const issueQuantityWithFees = (await slippageIssuanceModule.calculateTotalFees( - subjectSetToken, - subjectQuantity, - false - ))[0]; - - const externalPositionUnit = preciseDiv(usdcTransferOutQuantity, subjectQuantity); - const feeAdjustedTransferOut = preciseMul(issueQuantityWithFees, externalPositionUnit); - - const [components, equityFlows, debtFlows] = await slippageIssuanceModule - .callStatic - .getRequiredComponentRedemptionUnitsOffChain( - subjectSetToken, - subjectQuantity - ); - - const expectedComponents = await setToken.getComponents(); - const expectedEquityFlows = [feeAdjustedTransferOut]; - const expectedDebtFlows = [ZERO]; - - expect(expectedComponents[0]).to.eq(components[0]); - expect(expectedEquityFlows[0]).to.be.closeTo(equityFlows[0], 50); - expect(expectedDebtFlows[0]).to.eq(debtFlows[0]); - }); - - // This is slightly off ... over a tenth of a penny. - it.skip("should not incur a premium", async () => { - const redeemQuantityWithFees = (await slippageIssuanceModule.calculateTotalFees( - subjectSetToken, - subjectQuantity, - false - ))[0]; - - // Model says premium should be calculated as (usdcTransferIn / amountMinted) - const externalPositionUnit = preciseDiv(usdcTransferOutQuantity, subjectQuantity); - const feeAdjustedTransferOut = preciseMul(redeemQuantityWithFees, externalPositionUnit); - const feeAdjustedExternalPositionUnit = preciseDiv(feeAdjustedTransferOut, redeemQuantityWithFees); - - // Slippage will be paid by the redeemer - const totalSlippageAndFees = await calculateTotalSlippage(setToken, subjectQuantity); - const totalSlippagePositionUnit = preciseDiv(totalSlippageAndFees, subjectQuantity); - - const feeAndSlippageAdjustedExternalPositionUnit = feeAdjustedExternalPositionUnit - .add(toUSDCDecimals(totalSlippagePositionUnit)); - - await subject(); - - // Calculate value of set - const accountInfo = await perpLeverageModule.getAccountInfo(subjectSetToken); - const spotPrice = await perpSetup.getSpotPrice(baseToken); - const baseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - const notionalBaseValue = preciseMul(baseBalance, spotPrice); - - const totalSetValue = notionalBaseValue - .add(accountInfo.netQuoteBalance) - .add(accountInfo.collateralBalance) - .add(accountInfo.owedRealizedPnl); - - const valuePerSet = preciseDiv(totalSetValue, await setToken.totalSupply()); - const valuePerSetUSDC = toUSDCDecimals(valuePerSet); - - // feeAdjustedTransferOut = 9_553_810 - // valuePerSetUSDC = 9_796_973 - // feeAndSlippageAdjustedExternalPositionUnit = 9_808_047 - - expect(valuePerSetUSDC).eq(feeAndSlippageAdjustedExternalPositionUnit); - }); - - describe("withdrawal", () => { - let feeAdjustedTransferOutUSDC: BigNumber; - let realizedPnlUSDC: BigNumber; - - beforeEach(async() => { - ({ - feeAdjustedTransferOutUSDC, - realizedPnlUSDC - } = await calculateRedemptionData( - subjectSetToken, - subjectQuantity, - usdcTransferOutQuantity) - ); - }); - - it("should withdraw the expected amount from the Perp vault", async () => { - const initialCollateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - await subject(); - const finalCollateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const initialCollateralBalanceUSDC = toUSDCDecimals(initialCollateralBalance); - const finalCollateralBalanceUSDC = toUSDCDecimals(finalCollateralBalance); - - // realizedPnl = -398179 - // feeAdjustedTransferOut = 9553810 - const expectedCollateralBalanceUSDC = initialCollateralBalanceUSDC - .sub(feeAdjustedTransferOutUSDC) - .add(realizedPnlUSDC); - - expect(finalCollateralBalanceUSDC).to.be.closeTo(expectedCollateralBalanceUSDC, 10); - }); - - it("should not update the setToken USDC token balance", async () => { - const initialUSDCBalance = await usdc.balanceOf(subjectSetToken); - await subject(); - const finalUSDCBalance = await usdc.balanceOf(subjectSetToken); - - expect(initialUSDCBalance).eq(0); - expect(finalUSDCBalance).eq(initialUSDCBalance); - }); - - it("should have transferred expected USDC to set token holder", async () => { - const initialOwnerUSDCBalance = await usdc.balanceOf(subjectCaller.address); - await subject(); - const finalOwnerUSDCBalance = await usdc.balanceOf(subjectCaller.address); - - const expectedUSDCBalance = initialOwnerUSDCBalance.add(feeAdjustedTransferOutUSDC); - expect(finalOwnerUSDCBalance).to.be.closeTo(expectedUSDCBalance, 1); - }); - - it("should remove the module when dust is in the account and be able to add module back", async () => { - // Redeem to `1` - await subject(); - - // Check precondition - const initialModules = await setToken.getModules(); - expect(initialModules.includes(perpLeverageModule.address)).eq(true); - - // Trade to `0` - const { - baseUnit: initialBaseUnit - } = (await perpLeverageModule.getPositionUnitInfo(subjectSetToken))[0]; - - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - baseToken, - initialBaseUnit.mul(-1), - ZERO - ); - - const positionInfo = await perpLeverageModule.getPositionUnitInfo(subjectSetToken); - - // Withdraw remaining free collateral - const freeCollateral = await perpSetup.vault.getFreeCollateral(subjectSetToken); - const freeCollateralPositionUnit = preciseDiv(freeCollateral, await setToken.totalSupply()); - - // freeCollateral = 9737806 - // withdrawing this amount as a positionUnit results in a freeCollateral balance of `1` - // that can't be withdrawn due to positionUnit math rounding errors. - await perpLeverageModule - .connect(owner.wallet) - .withdraw(subjectSetToken, freeCollateralPositionUnit); - - const { - collateralBalance: finalCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken); - - - /// Remove module - await setToken.removeModule(perpLeverageModule.address); - const finalModules = await setToken.getModules(); - - expect(finalModules.includes(perpLeverageModule.address)).eq(false); - expect(positionInfo.length).eq(0); - expect(toUSDCDecimals(finalCollateralBalance)).eq(1); // <-- DUST - - // Restore module - await setToken.connect(owner.wallet).addModule(perpLeverageModule.address); - await perpLeverageModule.updateAllowedSetToken(setToken.address, true); - await perpLeverageModule.initialize(setToken.address); - - const restoredModules = await setToken.getModules(); - expect(restoredModules.includes(perpLeverageModule.address)).eq(true); - - // Verify that we can deposit again - await perpLeverageModule.deposit(setToken.address, usdcUnits(5)); - }); - }); - - describe("when redeeming after a liquidation", async () => { - beforeEach(async () => { - subjectQuantity = ether(1); - - // Calculated leverage = ~8.5X = 8_654_438_822_995_683_587 - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - baseToken, - 6, - ether(.02), - true - ); - - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(8.0)); - - await perpSetup - .clearingHouse - .connect(otherTrader.wallet) - .liquidate(subjectSetToken, baseToken); - }); - - it("should redeem and transfer out the expected amount", async () => { - const initialTotalSupply = await setToken.totalSupply(); - const initialCollateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - // Total amount of owedRealizedPnl will be debited from collateral balance - const { owedRealizedPnl } = await perpLeverageModule.getAccountInfo(subjectSetToken); - const owedRealizedPnlUSDC = toUSDCDecimals(owedRealizedPnl); - - await subject(); - - const finalTotalSupply = await setToken.totalSupply(); - const finalPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - const finalCollateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const usdcTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectQuantity, - perpLeverageModule, - perpSetup - ); - - const { - feeAdjustedTransferOutUSDC, - redeemQuantityWithFees - } = await calculateRedemptionData( - subjectSetToken, - subjectQuantity, - usdcTransferOutQuantity - ); - - const expectedTotalSupply = initialTotalSupply.sub(redeemQuantityWithFees); - const expectedCollateralBalance = toUSDCDecimals(initialCollateralBalance) - .sub(feeAdjustedTransferOutUSDC) - .add(owedRealizedPnlUSDC); - - expect(finalTotalSupply).eq(expectedTotalSupply); - expect(finalPositionInfo.length).eq(0); - expect(toUSDCDecimals(finalCollateralBalance)).to.be.closeTo(expectedCollateralBalance, 2); - }); - }); - - describe("when liquidation results in negative account value", () => { - beforeEach(async () => { - // Calculated leverage = ~8.5X = 8_654_438_822_995_683_587 - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - baseToken, - 6, - ether(.02), - true - ); - - // Move oracle price down to 5 USDC to enable liquidation - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(5.0)); - - // Move price down by maker selling 20k USDC of vETH - // Post trade spot price rises from ~10 USDC to 6_370_910_537_702_299_856 - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(20000), - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - await perpSetup - .clearingHouse - .connect(otherTrader.wallet) - .liquidate(subjectSetToken, baseToken); - }); - - // In this test case, the account is bankrupt: - // collateralBalance = 10050000000000000000 - // owedRealizedPnl = -31795534271984084912 - it("should redeem without transferring any usdc (because account worth 0)", async () => { - const redeemQuantityWithFees = (await slippageIssuanceModule.calculateTotalFees( - subjectSetToken, - subjectQuantity, - false - ))[0]; - - const initialRedeemerUSDCBalance = await usdc.balanceOf(subjectCaller.address); - const initialTotalSupply = await setToken.totalSupply(); - - await subject(); - - const finalRedeemerUSDCBalance = await usdc.balanceOf(subjectCaller.address); - const finalTotalSupply = await setToken.totalSupply(); - - const expectedTotalSupply = initialTotalSupply.sub(redeemQuantityWithFees); - - expect(finalTotalSupply).eq(expectedTotalSupply); - expect(finalRedeemerUSDCBalance).eq(initialRedeemerUSDCBalance); - }); - - it("should be possible to remove the module", async () => { - await subject(); - - const collateralBalance = await perpSetup.vault.getBalance(subjectSetToken); - const freeCollateral = await perpSetup.vault.getFreeCollateral(subjectSetToken); - const accountValue = await perpSetup.clearingHouse.getAccountValue(subjectSetToken); - - // collateralBalance: 20_100_000 (10^6) - // accountValue: -43_466_857_276_051_287_954 (10^18) - expect(collateralBalance).gt(1); - expect(freeCollateral).eq(0); - expect(accountValue).lt(-1); - - /// Remove module - await setToken.removeModule(perpLeverageModule.address); - const finalModules = await setToken.getModules(); - expect(finalModules.includes(perpLeverageModule.address)).eq(false); - }); - }); - }); - }); -}); diff --git a/test/integration/yearnWrapModule.spec.ts b/test/integration/yearnWrapModule.spec.ts deleted file mode 100644 index 128db9465..000000000 --- a/test/integration/yearnWrapModule.spec.ts +++ /dev/null @@ -1,207 +0,0 @@ -import "module-alias/register"; -import { BigNumber } from "ethers"; - -import { Address } from "@utils/types"; -import { Account } from "@utils/test/types"; -import { ADDRESS_ZERO } from "@utils/constants"; -import { YearnWrapAdapter, SetToken, WrapModule } from "@utils/contracts"; -import DeployHelper from "@utils/deploys"; -import { - ether, - preciseMul, -} from "@utils/index"; -import { - getAccounts, - getWaffleExpect, - getSystemFixture, - getYearnFixture, - addSnapshotBeforeRestoreAfterEach, -} from "@utils/test/index"; -import { YearnFixture, SystemFixture } from "@utils/fixtures"; -import { Vault } from "@utils/contracts/yearn"; - - -const expect = getWaffleExpect(); - -describe("yearnWrapModule", () => { - let owner: Account; - let deployer: DeployHelper; - let setup: SystemFixture; - - let yearnSetup: YearnFixture; - let daiVault: Vault; - - let wrapModule: WrapModule; - let yearnWrapAdapter: YearnWrapAdapter; - - const yearnWrapAdapterIntegrationName: string = "YEARN_WRAPPER"; - - before(async () => { - [ - owner, - ] = await getAccounts(); - - // System setup - deployer = new DeployHelper(owner.wallet); - setup = getSystemFixture(owner.address); - await setup.initialize(); - - // Yearn setup - yearnSetup = getYearnFixture(owner.address); - await yearnSetup.initialize(); - - daiVault = await yearnSetup.createAndEnableVaultWithStrategyMock( - setup.dai.address, owner.address, owner.address, owner.address, "daiMockStrategy", "yvDAI", ether(100) - ); - - // WrapModule setup - wrapModule = await deployer.modules.deployWrapModule(setup.controller.address, setup.weth.address); - await setup.controller.addModule(wrapModule.address); - - // YearnWrapAdapter setup - yearnWrapAdapter = await deployer.adapters.deployYearnWrapAdapter(); - await setup.integrationRegistry.addIntegration(wrapModule.address, yearnWrapAdapterIntegrationName, yearnWrapAdapter.address); - }); - - addSnapshotBeforeRestoreAfterEach(); - - context("when a SetToken has been deployed and issued", async () => { - let setToken: SetToken; - let setTokensIssued: BigNumber; - - before(async () => { - setToken = await setup.createSetToken( - [setup.dai.address], - [ether(1)], - [setup.issuanceModule.address, wrapModule.address] - ); - - // Initialize modules - await setup.issuanceModule.initialize(setToken.address, ADDRESS_ZERO); - await wrapModule.initialize(setToken.address); - - // Issue some Sets - setTokensIssued = ether(10); - const underlyingRequired = setTokensIssued; - await setup.dai.approve(setup.issuanceModule.address, underlyingRequired); - await setup.issuanceModule.issue(setToken.address, setTokensIssued, owner.address); - }); - - describe("#wrap", async () => { - let subjectSetToken: Address; - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectUnderlyingUnits: BigNumber; - let subjectIntegrationName: string; - let subjectCaller: Account; - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectUnderlyingToken = setup.dai.address; - subjectWrappedToken = daiVault.address; - subjectUnderlyingUnits = ether(1); - subjectIntegrationName = yearnWrapAdapterIntegrationName; - subjectCaller = owner; - }); - - async function subject(): Promise { - return wrapModule.connect(subjectCaller.wallet).wrap( - subjectSetToken, - subjectUnderlyingToken, - subjectWrappedToken, - subjectUnderlyingUnits, - subjectIntegrationName, - ); - } - - it("should reduce the underlying quantity and mint the wrapped asset to the SetToken", async () => { - const previousUnderlyingBalance = await setup.dai.balanceOf(setToken.address); - const previousWrappedBalance = await daiVault.balanceOf(setToken.address); - - await subject(); - - const underlyingBalance = await setup.dai.balanceOf(setToken.address); - const wrappedBalance = await daiVault.balanceOf(setToken.address); - - const expectedUnderlyingBalance = previousUnderlyingBalance.sub(setTokensIssued); - expect(underlyingBalance).to.eq(expectedUnderlyingBalance); - - const expectedWrappedBalance = previousWrappedBalance.add(setTokensIssued); - expect(wrappedBalance).to.eq(expectedWrappedBalance); - }); - - }); - - describe("#unwrap", () => { - let subjectSetToken: Address; - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectWrappedTokenUnits: BigNumber; - let subjectIntegrationName: string; - let subjectCaller: Account; - - let wrappedQuantity: BigNumber; - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectUnderlyingToken = setup.dai.address; - subjectWrappedToken = daiVault.address; - subjectWrappedTokenUnits = ether(0.5); - subjectIntegrationName = yearnWrapAdapterIntegrationName; - subjectCaller = owner; - - wrappedQuantity = ether(1); - - await wrapModule.wrap( - subjectSetToken, - subjectUnderlyingToken, - subjectWrappedToken, - wrappedQuantity, - subjectIntegrationName, - ); - }); - - async function subject(): Promise { - return wrapModule.connect(subjectCaller.wallet).unwrap( - subjectSetToken, - subjectUnderlyingToken, - subjectWrappedToken, - subjectWrappedTokenUnits, - subjectIntegrationName, - { - gasLimit: 5000000, - } - ); - } - - it("should burn the wrapped asset to the SetToken and increase the underlying quantity", async () => { - const previousUnderlyingBalance = await setup.dai.balanceOf(setToken.address); - const previousWrappedBalance = await daiVault.balanceOf(setToken.address); - - await subject(); - - const underlyingBalance = await setup.dai.balanceOf(setToken.address); - const wrappedBalance = await daiVault.balanceOf(setToken.address); - - const delta = preciseMul(setTokensIssued, wrappedQuantity.sub(subjectWrappedTokenUnits)); - - const expectedUnderlyingBalance = previousUnderlyingBalance.add(delta); - expect(underlyingBalance).to.eq(expectedUnderlyingBalance); - - const expectedWrappedBalance = previousWrappedBalance.sub(delta); - expect(wrappedBalance).to.eq(expectedWrappedBalance); - }); - - describe("when it is an invalid vault - underlying token", async () => { - beforeEach(async () => { - subjectUnderlyingToken = setup.usdc.address; - }); - - it("should revert as it the vault holds a different underlying token", async () => { - await expect(subject()).to.be.revertedWith("Must be a valid token pair"); - }); - }); - - }); - }); -}); diff --git a/test/product/assetLimitHook.spec.ts b/test/product/assetLimitHook.spec.ts index 3f68b5013..92742d130 100644 --- a/test/product/assetLimitHook.spec.ts +++ b/test/product/assetLimitHook.spec.ts @@ -2,10 +2,15 @@ import "module-alias/register"; import { BigNumber } from "ethers"; -import { Address, NAVIssuanceSettings } from "@utils/types"; +import { Address, CustomOracleNAVIssuanceSettings } from "@utils/types"; import { Account } from "@utils/test/types"; import { ZERO, ADDRESS_ZERO } from "@utils/constants"; -import { AssetLimitHook, NavIssuanceModule, SetToken, UniswapYieldHook } from "@utils/contracts"; +import { + AssetLimitHook, + CustomOracleNavIssuanceModule, + SetToken, + CustomSetValuerMock +} from "@utils/contracts"; import DeployHelper from "@utils/deploys"; import { bitcoin, @@ -30,8 +35,9 @@ describe("AssetLimitHook", () => { let deployer: DeployHelper; let setup: SystemFixture; - let navIssuanceModule: NavIssuanceModule; + let navIssuanceModule: CustomOracleNavIssuanceModule; let setToken: SetToken; + let setValuer: CustomSetValuerMock; let hook: AssetLimitHook; @@ -50,7 +56,10 @@ describe("AssetLimitHook", () => { setup = getSystemFixture(owner.address); await setup.initialize(); - navIssuanceModule = await deployer.modules.deployNavIssuanceModule(setup.controller.address, setup.weth.address); + navIssuanceModule = await deployer.modules.deployCustomOracleNavIssuanceModule( + setup.controller.address, + setup.weth.address + ); await setup.controller.addModule(navIssuanceModule.address); setToken = await setup.createSetToken( @@ -64,9 +73,12 @@ describe("AssetLimitHook", () => { [setRedeemLimit, usdcIssueLimit, ethIssueLimit], ); + setValuer = await deployer.mocks.deployCustomSetValuerMock(); + const navIssuanceSettings = { managerIssuanceHook: hook.address, managerRedemptionHook: hook.address, + setValuer: setValuer.address, reserveAssets: [setup.usdc.address, setup.weth.address], feeRecipient: feeRecipient.address, managerFees: [ether(0.001), ether(0.002)], @@ -74,7 +86,7 @@ describe("AssetLimitHook", () => { premiumPercentage: ether(0.01), maxPremiumPercentage: ether(0.1), minSetTokenSupply: ether(100), - } as NAVIssuanceSettings; + } as CustomOracleNAVIssuanceSettings; await navIssuanceModule.initialize( setToken.address, @@ -103,8 +115,8 @@ describe("AssetLimitHook", () => { subjectLimits = [ether(400), usdc(100000)]; }); - async function subject(): Promise { - return await deployer.product.deployUniswapYieldHook(subjectAssets, subjectLimits); + async function subject(): Promise { + return await deployer.product.deployAssetLimitHook(subjectAssets, subjectLimits); } it("should set the correct limits", async () => { diff --git a/test/product/uniswapYieldHook.spec.ts b/test/product/uniswapYieldHook.spec.ts deleted file mode 100644 index 285076e24..000000000 --- a/test/product/uniswapYieldHook.spec.ts +++ /dev/null @@ -1,441 +0,0 @@ -import "module-alias/register"; - -import { BigNumber } from "ethers"; - -import { Address, NAVIssuanceSettings } from "@utils/types"; -import { Account } from "@utils/test/types"; -import { ZERO, ADDRESS_ZERO } from "@utils/constants"; -import { NAVIssuanceCaller, NavIssuanceModule, SetToken, UniswapYieldHook } from "@utils/contracts"; -import DeployHelper from "@utils/deploys"; -import { - bitcoin, - ether, - usdc, -} from "@utils/index"; -import { - addSnapshotBeforeRestoreAfterEach, - getAccounts, - getWaffleExpect, - getSystemFixture, - getRandomAccount, -} from "@utils/test/index"; - -import { SystemFixture } from "@utils/fixtures"; - -const expect = getWaffleExpect(); - -describe("UniswapYieldHook", () => { - let owner: Account; - let feeRecipient: Account; - let recipient: Account; - let deployer: DeployHelper; - - let setup: SystemFixture; - let navIssuanceModule: NavIssuanceModule; - let setToken: SetToken; - - let hook: UniswapYieldHook; - let navIssuanceCaller: NAVIssuanceCaller; - - const setRedeemLimit: BigNumber = ether(435); - const usdcIssueLimit: BigNumber = usdc(100000); - const ethIssueLimit: BigNumber = ether(435); - - before(async () => { - [ - owner, - feeRecipient, - recipient, - ] = await getAccounts(); - - deployer = new DeployHelper(owner.wallet); - setup = getSystemFixture(owner.address); - await setup.initialize(); - - navIssuanceModule = await deployer.modules.deployNavIssuanceModule(setup.controller.address, setup.weth.address); - await setup.controller.addModule(navIssuanceModule.address); - - setToken = await setup.createSetToken( - [setup.weth.address], - [ether(1)], - [navIssuanceModule.address, setup.issuanceModule.address] - ); - - hook = await deployer.product.deployUniswapYieldHook( - [setToken.address, setup.usdc.address, setup.weth.address], - [setRedeemLimit, usdcIssueLimit, ethIssueLimit], - ); - - navIssuanceCaller = await deployer.mocks.deployNAVIssuanceCaller(navIssuanceModule.address); - - const navIssuanceSettings = { - managerIssuanceHook: hook.address, - managerRedemptionHook: hook.address, - reserveAssets: [setup.usdc.address, setup.weth.address], - feeRecipient: feeRecipient.address, - managerFees: [ether(0.001), ether(0.002)], - maxManagerFee: ether(0.02), - premiumPercentage: ether(0.01), - maxPremiumPercentage: ether(0.1), - minSetTokenSupply: ether(100), - } as NAVIssuanceSettings; - - await navIssuanceModule.initialize( - setToken.address, - navIssuanceSettings - ); - - // Approve tokens to the controller - await setup.weth.approve(setup.controller.address, ether(100)); - await setup.usdc.approve(setup.controller.address, usdc(1000000)); - await setup.wbtc.approve(setup.controller.address, bitcoin(1000000)); - await setup.dai.approve(setup.controller.address, ether(1000000)); - - // Seed with 100 supply - await setup.issuanceModule.initialize(setToken.address, ADDRESS_ZERO); - await setup.issuanceModule.issue(setToken.address, ether(100), owner.address); - }); - - addSnapshotBeforeRestoreAfterEach(); - - describe("#constructor", async () => { - let subjectAssets: Address[]; - let subjectLimits: BigNumber[]; - - beforeEach(async () => { - subjectAssets = [setup.weth.address, setup.usdc.address]; - subjectLimits = [ether(400), usdc(100000)]; - }); - - async function subject(): Promise { - return await deployer.product.deployUniswapYieldHook(subjectAssets, subjectLimits); - } - - it("should set the correct limits", async () => { - const hook = await subject(); - - const wethLimit = await hook.assetLimits(subjectAssets[0]); - const usdcLimit = await hook.assetLimits(subjectAssets[1]); - expect(wethLimit).to.eq(subjectLimits[0]); - expect(usdcLimit).to.eq(subjectLimits[1]); - }); - - it("should set the correct assets", async () => { - const hook = await subject(); - - const assets = await hook.getAssets(); - expect(JSON.stringify(assets)).to.eq(JSON.stringify(subjectAssets)); - }); - - describe("when asset is duplicated", async () => { - beforeEach(async () => { - subjectAssets = [setup.weth.address, setup.weth.address]; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Asset already added"); - }); - }); - - describe("when array lengths don't match", async () => { - beforeEach(async () => { - subjectAssets = [setup.weth.address]; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Arrays must be equal"); - }); - }); - - describe("when arrays are empty", async () => { - beforeEach(async () => { - subjectAssets = []; - subjectLimits = []; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Array must not be empty"); - }); - }); - }); - - describe("#issue", async () => { - let subjectSetToken: Address; - let subjectReserveAsset: Address; - let subjectReserveQuantity: BigNumber; - let subjectMinSetTokenReceived: BigNumber; - let subjectTo: Account; - let subjectCallFromContract: boolean; - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectReserveAsset = setup.usdc.address; - subjectReserveQuantity = usdc(150000); - subjectMinSetTokenReceived = ZERO; - subjectTo = recipient; - subjectCallFromContract = false; - - await setup.usdc.approve(navIssuanceModule.address, subjectReserveQuantity); - }); - - async function subject(): Promise { - if (subjectCallFromContract) { - await setup.usdc.connect(owner.wallet).transfer(navIssuanceCaller.address, subjectReserveQuantity); - return navIssuanceCaller.issue( - subjectSetToken, - subjectReserveAsset, - subjectReserveQuantity, - subjectMinSetTokenReceived, - subjectTo.address - ); - } else { - return navIssuanceModule.issue( - subjectSetToken, - subjectReserveAsset, - subjectReserveQuantity, - subjectMinSetTokenReceived, - subjectTo.address - ); - } - } - - it("should not revert", async () => { - await expect(subject()).to.not.be.reverted; - }); - - describe("when call is from contract but less than redeem limit", async () => { - beforeEach(async () => { - subjectCallFromContract = true; - subjectReserveQuantity = usdc(90000); - }); - - it("should not revert", async () => { - await expect(subject()).to.not.be.reverted; - }); - }); - - describe("when call is from contract but greater than redeem limit", async () => { - beforeEach(async () => { - subjectCallFromContract = true; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Issue size too large for call from contract."); - }); - }); - }); - - describe("#redeem", async () => { - let subjectSetToken: Address; - let subjectReserveAsset: Address; - let subjectSetTokenQuantity: BigNumber; - let subjectMinReserveQuantityReceived: BigNumber; - let subjectTo: Account; - let subjectCallFromContract: boolean; - - beforeEach(async () => { - await setup.usdc.approve(navIssuanceModule.address, usdc(150000)); - await navIssuanceModule.issue( - setToken.address, - setup.usdc.address, - usdc(150000), - ZERO, - owner.address - ); - - subjectSetToken = setToken.address; - subjectReserveAsset = setup.usdc.address; - subjectSetTokenQuantity = ether(500); - subjectMinReserveQuantityReceived = ZERO; - subjectTo = recipient; - subjectCallFromContract = false; - }); - - async function subject(): Promise { - if (subjectCallFromContract) { - await setToken.connect(owner.wallet).transfer(navIssuanceCaller.address, subjectSetTokenQuantity); - return navIssuanceCaller.redeem( - subjectSetToken, - subjectReserveAsset, - subjectSetTokenQuantity, - subjectMinReserveQuantityReceived, - subjectTo.address - ); - } else { - return navIssuanceModule.redeem( - subjectSetToken, - subjectReserveAsset, - subjectSetTokenQuantity, - subjectMinReserveQuantityReceived, - subjectTo.address - ); - } - } - - it("should not revert", async () => { - await expect(subject()).to.not.be.reverted; - }); - - describe("when call is from contract but less than redeem limit", async () => { - beforeEach(async () => { - subjectCallFromContract = true; - subjectSetTokenQuantity = ether(400); - }); - - it("should not revert", async () => { - await expect(subject()).to.not.be.reverted; - }); - }); - - describe("when call is from contract but greater than redeem limit", async () => { - beforeEach(async () => { - subjectCallFromContract = true; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Redeem size too large for call from contract."); - }); - }); - }); - - describe("#addAssetLimit", async () => { - let subjectAsset: Address; - let subjectLimit: BigNumber; - let subjectCaller: Account; - - beforeEach(async () => { - subjectAsset = setup.wbtc.address; - subjectLimit = bitcoin(10); - subjectCaller = owner; - }); - - async function subject(): Promise { - return await hook.connect(subjectCaller.wallet).addAssetLimit(subjectAsset, subjectLimit); - } - - it("should set the correct limits", async () => { - await subject(); - - const wbtcLimit = await hook.assetLimits(subjectAsset); - expect(wbtcLimit).to.eq(subjectLimit); - }); - - it("should add wbtc to assets array", async () => { - await subject(); - - const assets = await hook.getAssets(); - expect(assets).to.contain(subjectAsset); - }); - - describe("when asset is duplicated", async () => { - beforeEach(async () => { - subjectAsset = setup.weth.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Asset already added"); - }); - }); - - describe("when caller is not owner", async () => { - beforeEach(async () => { - subjectCaller = await getRandomAccount(); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Ownable: caller is not the owner"); - }); - }); - }); - - describe("#editAssetLimit", async () => { - let subjectAsset: Address; - let subjectLimit: BigNumber; - let subjectCaller: Account; - - beforeEach(async () => { - subjectAsset = setup.weth.address; - subjectLimit = ether(100); - subjectCaller = owner; - }); - - async function subject(): Promise { - return await hook.connect(subjectCaller.wallet).editAssetLimit(subjectAsset, subjectLimit); - } - - it("should set the correct limits", async () => { - await subject(); - - const wethLimit = await hook.assetLimits(subjectAsset); - expect(wethLimit).to.eq(subjectLimit); - }); - - describe("when asset is not already added", async () => { - beforeEach(async () => { - subjectAsset = setup.wbtc.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Asset not added"); - }); - }); - - describe("when caller is not owner", async () => { - beforeEach(async () => { - subjectCaller = await getRandomAccount(); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Ownable: caller is not the owner"); - }); - }); - }); - - describe("#removeAssetLimit", async () => { - let subjectAsset: Address; - let subjectCaller: Account; - - beforeEach(async () => { - subjectAsset = setup.weth.address; - subjectCaller = owner; - }); - - async function subject(): Promise { - return await hook.connect(subjectCaller.wallet).removeAssetLimit(subjectAsset); - } - - it("should set the correct limits", async () => { - await subject(); - - const wethLimit = await hook.assetLimits(subjectAsset); - expect(wethLimit).to.eq(ZERO); - }); - - it("should remove weth from assets array", async () => { - await subject(); - - const assets = await hook.getAssets(); - expect(assets).to.not.contain(subjectAsset); - }); - - describe("when asset is not already added", async () => { - beforeEach(async () => { - subjectAsset = setup.wbtc.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Asset not added"); - }); - }); - - describe("when caller is not owner", async () => { - beforeEach(async () => { - subjectCaller = await getRandomAccount(); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Ownable: caller is not the owner"); - }); - }); - }); -}); diff --git a/test/protocol-viewers/perpV2LeverageModuleViewer.spec.ts b/test/protocol-viewers/perpV2LeverageModuleViewer.spec.ts index 9ce272003..3d69171aa 100644 --- a/test/protocol-viewers/perpV2LeverageModuleViewer.spec.ts +++ b/test/protocol-viewers/perpV2LeverageModuleViewer.spec.ts @@ -3,8 +3,10 @@ import "module-alias/register"; import { Address } from "@utils/types"; import { Account } from "@utils/test/types"; import { - PerpV2, - PerpV2LeverageModule, + PositionV2, + PerpV2LibraryV2, + PerpV2Positions, + PerpV2LeverageModuleV2, DebtIssuanceMock, PerpV2LeverageModuleViewer, StandardTokenMock, @@ -48,8 +50,10 @@ describe("PerpV2LeverageModuleViewer", () => { let mockModule: Account; let deployer: DeployHelper; - let perpLib: PerpV2; - let perpLeverageModule: PerpV2LeverageModule; + let positionLib: PositionV2; + let perpLib: PerpV2LibraryV2; + let perpPositionsLib: PerpV2Positions; + let perpLeverageModule: PerpV2LeverageModuleV2; let perpViewer: PerpV2LeverageModuleViewer; let debtIssuanceMock: DebtIssuanceMock; let setup: SystemFixture; @@ -100,15 +104,23 @@ describe("PerpV2LeverageModuleViewer", () => { debtIssuanceMock = await deployer.mocks.deployDebtIssuanceMock(); await setup.controller.addModule(debtIssuanceMock.address); - perpLib = await deployer.libraries.deployPerpV2(); - perpLeverageModule = await deployer.modules.deployPerpV2LeverageModule( + // Deploy libraries + positionLib = await deployer.libraries.deployPositionV2(); + perpLib = await deployer.libraries.deployPerpV2LibraryV2(); + perpPositionsLib = await deployer.libraries.deployPerpV2Positions(); + + perpLeverageModule = await deployer.modules.deployPerpV2LeverageModuleV2( setup.controller.address, perpSetup.vault.address, perpSetup.quoter.address, perpSetup.marketRegistry.address, BigNumber.from(3), - "contracts/protocol/integration/lib/PerpV2.sol:PerpV2", - perpLib.address + "contracts/protocol/lib/PositionV2.sol:PositionV2", + positionLib.address, + "contracts/protocol/integration/lib/PerpV2LibraryV2.sol:PerpV2LibraryV2", + perpLib.address, + "contracts/protocol/integration/lib/PerpV2Positions.sol:PerpV2Positions", + perpPositionsLib.address, ); await setup.controller.addModule(perpLeverageModule.address); diff --git a/test/protocol/integration/governance/aaveGovernanceAdapter.spec.ts b/test/protocol/integration/governance/aaveGovernanceAdapter.spec.ts deleted file mode 100644 index 52966dff4..000000000 --- a/test/protocol/integration/governance/aaveGovernanceAdapter.spec.ts +++ /dev/null @@ -1,201 +0,0 @@ -import "module-alias/register"; -import { utils, BigNumber } from "ethers"; -import { Address, Bytes } from "@utils/types"; -import { Account } from "@utils/test/types"; -import { EMPTY_BYTES, ONE, TWO, ZERO } from "@utils/constants"; -import { AaveGovernanceAdapter } from "@utils/contracts"; -import DeployHelper from "@utils/deploys"; -import { - addSnapshotBeforeRestoreAfterEach, - getAccounts, - getWaffleExpect, - getAaveFixture, - getRandomAddress -} from "@utils/test/index"; -import { AaveFixture } from "@utils/fixtures"; - - -const expect = getWaffleExpect(); - -describe("AaveGovernanceAdapter", () => { - let owner: Account; - let deployer: DeployHelper; - let aaveGovernanceAdapter: AaveGovernanceAdapter; - let mockSetToken: Account; - let aaveSetup: AaveFixture; - - before(async () => { - [ - owner, - mockSetToken, - ] = await getAccounts(); - - deployer = new DeployHelper(owner.wallet); - - aaveSetup = getAaveFixture(owner.address); - await aaveSetup.initialize(); - - aaveGovernanceAdapter = await deployer.adapters.deployAaveGovernanceAdapter( - aaveSetup.aaveProtoGovernance.address, - aaveSetup.aaveToken.address, - ); - }); - - addSnapshotBeforeRestoreAfterEach(); - - describe("#constructor", async () => { - let subjectAaveToken: Address; - let subjectAaveProtoGovernance: Address; - - beforeEach(async () => { - subjectAaveToken = aaveSetup.aaveToken.address; - subjectAaveProtoGovernance = aaveSetup.aaveProtoGovernance.address; - }); - - async function subject(): Promise { - return deployer.adapters.deployAaveGovernanceAdapter( - subjectAaveProtoGovernance, - subjectAaveToken, - ); - } - - it("should have the correct AAVE token address", async () => { - const deployedAaveGovernanceAdapter = await subject(); - - const actualCompToken = await deployedAaveGovernanceAdapter.aaveToken(); - expect(actualCompToken).to.eq(subjectAaveToken); - }); - - it("should have the correct Aave proto governance contract address", async () => { - const deployedAaveGovernanceAdapter = await subject(); - - const actualGovernorAlphaAddress = await deployedAaveGovernanceAdapter.aaveProtoGovernance(); - expect(actualGovernorAlphaAddress).to.eq(subjectAaveProtoGovernance); - }); - }); - - describe("#getProposeCalldata", async () => { - let subjectProposalData: Address; - - beforeEach(async () => { - subjectProposalData = EMPTY_BYTES; - }); - - async function subject(): Promise { - return aaveGovernanceAdapter.getProposeCalldata(subjectProposalData); - } - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Creation of new proposal only available to AAVE genesis team"); - }); - }); - - describe("#getDelegateCalldata", async () => { - let subjectDelegatee: Address; - - beforeEach(async () => { - subjectDelegatee = await getRandomAddress(); - }); - - async function subject(): Promise { - return aaveGovernanceAdapter.getDelegateCalldata(subjectDelegatee); - } - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("No delegation available in AAVE governance"); - }); - }); - - describe("#getRegisterCalldata", async () => { - let subjectSetToken: Address; - - beforeEach(async () => { - subjectSetToken = mockSetToken.address; - }); - - async function subject(): Promise { - return aaveGovernanceAdapter.getRegisterCalldata(subjectSetToken); - } - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("No register available in AAVE governance"); - }); - }); - - describe("#getRevokeCalldata", async () => { - async function subject(): Promise { - return aaveGovernanceAdapter.getRevokeCalldata(); - } - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("No revoke available in AAVE governance"); - }); - }); - - describe("#getVoteCalldata", async () => { - let subjectProposalId: BigNumber; - let subjectSupport: boolean; - let subjectData: Bytes; - - beforeEach(async () => { - subjectProposalId = ZERO; - subjectSupport = true; - subjectData = EMPTY_BYTES; - }); - - async function subject(): Promise { - return aaveGovernanceAdapter.getVoteCalldata(subjectProposalId, subjectSupport, subjectData); - } - - it("should return correct data for voting with AAVE token", async () => { - const [targetAddress, ethValue, callData] = await subject(); - const expectedCallData = aaveSetup.aaveProtoGovernance.interface.encodeFunctionData("submitVoteByVoter", - [subjectProposalId, ONE, aaveSetup.aaveToken.address] - ); - - expect(targetAddress).to.eq(aaveSetup.aaveProtoGovernance.address); - expect(ethValue).to.eq(ZERO); - expect(callData).to.eq(expectedCallData); - }); - - describe("when voting with another token", () => { - beforeEach(async () => { - subjectData = utils.defaultAbiCoder.encode( - ["address"], - [aaveSetup.lendToken.address] - ); - }); - - it("should return correct data for voting", async () => { - const [targetAddress, ethValue, callData] = await subject(); - const expectedCallData = aaveSetup.aaveProtoGovernance.interface.encodeFunctionData("submitVoteByVoter", - [subjectProposalId, ONE, aaveSetup.lendToken.address] - ); - - expect(targetAddress).to.eq(aaveSetup.aaveProtoGovernance.address); - expect(ethValue).to.eq(ZERO); - expect(callData).to.eq(expectedCallData); - }); - }); - - describe("when voting against a proposal", () => { - let voteValue: BigNumber; - - beforeEach(async () => { - voteValue = TWO; - subjectSupport = false; - }); - - it("should return correct data for voting", async () => { - const [targetAddress, ethValue, callData] = await subject(); - const expectedCallData = aaveSetup.aaveProtoGovernance.interface.encodeFunctionData("submitVoteByVoter", - [subjectProposalId, voteValue, aaveSetup.aaveToken.address] - ); - - expect(targetAddress).to.eq(aaveSetup.aaveProtoGovernance.address); - expect(ethValue).to.eq(ZERO); - expect(callData).to.eq(expectedCallData); - }); - }); - }); -}); diff --git a/test/protocol/integration/governance/aaveGovernanceV2Adapter.spec.ts b/test/protocol/integration/governance/aaveGovernanceV2Adapter.spec.ts index 8fe435f8b..82b29efd4 100644 --- a/test/protocol/integration/governance/aaveGovernanceV2Adapter.spec.ts +++ b/test/protocol/integration/governance/aaveGovernanceV2Adapter.spec.ts @@ -58,7 +58,7 @@ describe("AaveGovernanceAdapter", () => { }); async function subject(): Promise { - return deployer.adapters.deployAaveGovernanceAdapter( + return deployer.adapters.deployAaveGovernanceV2Adapter( subjectAaveGovernance, subjectAaveToken, ); @@ -74,7 +74,7 @@ describe("AaveGovernanceAdapter", () => { it("should have the correct Aave governance contract address", async () => { const deployedAaveGovernanceAdapter = await subject(); - const actualGovernanceAddress = await deployedAaveGovernanceAdapter.aaveProtoGovernance(); + const actualGovernanceAddress = await deployedAaveGovernanceAdapter.aaveGovernanceV2(); expect(actualGovernanceAddress).to.eq(subjectAaveGovernance); }); }); diff --git a/test/protocol/integration/lib/perpV2Positions.spec.ts b/test/protocol/integration/lib/perpV2Positions.spec.ts index f2d0098ab..c8f2773c8 100644 --- a/test/protocol/integration/lib/perpV2Positions.spec.ts +++ b/test/protocol/integration/lib/perpV2Positions.spec.ts @@ -3,9 +3,10 @@ import "module-alias/register"; import { Address } from "@utils/types"; import { Account } from "@utils/test/types"; import { - PerpV2, + PositionV2, + PerpV2LibraryV2, PerpV2Positions, - PerpV2LeverageModule, + PerpV2LeverageModuleV2, DebtIssuanceMock, PerpV2PositionsMock, StandardTokenMock, @@ -45,9 +46,10 @@ describe("PerpV2Positions", () => { let deployer: DeployHelper; let maxPerpPositionsPerSet: BigNumber; - let perpLib: PerpV2; - let perpLeverageModule: PerpV2LeverageModule; + let positionLib: PositionV2; + let perpLib: PerpV2LibraryV2; let perpPositionsLib: PerpV2Positions; + let perpLeverageModule: PerpV2LeverageModuleV2; let perpPositionsMock: PerpV2PositionsMock; let debtIssuanceMock: DebtIssuanceMock; let setup: SystemFixture; @@ -99,15 +101,23 @@ describe("PerpV2Positions", () => { await setup.controller.addModule(debtIssuanceMock.address); maxPerpPositionsPerSet = BigNumber.from(2); - perpLib = await deployer.libraries.deployPerpV2(); - perpLeverageModule = await deployer.modules.deployPerpV2LeverageModule( + // Deploy libraries + positionLib = await deployer.libraries.deployPositionV2(); + perpLib = await deployer.libraries.deployPerpV2LibraryV2(); + perpPositionsLib = await deployer.libraries.deployPerpV2Positions(); + + perpLeverageModule = await deployer.modules.deployPerpV2LeverageModuleV2( setup.controller.address, perpSetup.vault.address, perpSetup.quoter.address, perpSetup.marketRegistry.address, maxPerpPositionsPerSet, - "contracts/protocol/integration/lib/PerpV2.sol:PerpV2", - perpLib.address + "contracts/protocol/lib/PositionV2.sol:PositionV2", + positionLib.address, + "contracts/protocol/integration/lib/PerpV2LibraryV2.sol:PerpV2LibraryV2", + perpLib.address, + "contracts/protocol/integration/lib/PerpV2Positions.sol:PerpV2Positions", + perpPositionsLib.address, ); await setup.controller.addModule(perpLeverageModule.address); diff --git a/test/protocol/integration/wrap/aaveMigrationWrapAdapter.spec.ts b/test/protocol/integration/wrap/aaveMigrationWrapAdapter.spec.ts deleted file mode 100644 index e5ce33d82..000000000 --- a/test/protocol/integration/wrap/aaveMigrationWrapAdapter.spec.ts +++ /dev/null @@ -1,168 +0,0 @@ -import "module-alias/register"; -import { BigNumber } from "ethers"; - -import { Address } from "@utils/types"; -import { Account } from "@utils/test/types"; -import { ZERO } from "@utils/constants"; -import { AaveMigrationWrapAdapter } from "@utils/contracts"; -import DeployHelper from "@utils/deploys"; -import { - ether, -} from "@utils/index"; -import { - addSnapshotBeforeRestoreAfterEach, - getAccounts, - getWaffleExpect, - getAaveFixture -} from "@utils/test/index"; - -import { AaveFixture } from "@utils/fixtures"; - - -const expect = getWaffleExpect(); - -describe("AaveMigrationWrapAdapter", () => { - let owner: Account; - let deployer: DeployHelper; - let aaveMigrationWrapAdapter: AaveMigrationWrapAdapter; - let mockOtherUnderlyingToken: Account; - let mockOtherWrappedToken: Account; - let aaveSetup: AaveFixture; - - before(async () => { - [ - owner, - mockOtherUnderlyingToken, - mockOtherWrappedToken, - ] = await getAccounts(); - - deployer = new DeployHelper(owner.wallet); - - aaveSetup = getAaveFixture(owner.address); - await aaveSetup.initialize(); - - // Note: In production, the spender is the - aaveMigrationWrapAdapter = await deployer.adapters.deployAaveMigrationWrapAdapter( - aaveSetup.lendToAaveMigrator.address, - aaveSetup.lendToken.address, - aaveSetup.aaveToken.address - ); - }); - - addSnapshotBeforeRestoreAfterEach(); - - describe("#constructor", async () => { - let subjectAaveMigrationProxy: Address; - let subjectLendToken: Address; - let subjectAaveToken: Address; - - beforeEach(async () => { - subjectAaveMigrationProxy = aaveSetup.lendToAaveMigrator.address; - subjectLendToken = aaveSetup.lendToken.address; - subjectAaveToken = aaveSetup.aaveToken.address; - }); - - async function subject(): Promise { - return deployer.adapters.deployAaveMigrationWrapAdapter( - subjectAaveMigrationProxy, - subjectLendToken, - subjectAaveToken - ); - } - - it("should have the correct migration proxy address", async () => { - const deployedAaveMigrationWrapAdapter = await subject(); - - const actualAaveMigrationProxy = await deployedAaveMigrationWrapAdapter.lendToAaveMigrationProxy(); - expect(actualAaveMigrationProxy).to.eq(subjectAaveMigrationProxy); - }); - - it("should have the correct LEND token address", async () => { - const deployedAaveMigrationWrapAdapter = await subject(); - - const actualLendTokenAddress = await deployedAaveMigrationWrapAdapter.lendToken(); - expect(actualLendTokenAddress).to.eq(subjectLendToken); - }); - }); - - describe("#getSpenderAddress", async () => { - async function subject(): Promise { - return aaveMigrationWrapAdapter.getSpenderAddress( - aaveSetup.lendToken.address, - aaveSetup.aaveToken.address, - ); - } - - it("should return the correct spender address", async () => { - const spender = await subject(); - - expect(spender).to.eq(aaveSetup.lendToAaveMigrator.address); - }); - }); - - describe("#getWrapCallData", async () => { - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectUnderlyingUnits: BigNumber; - - beforeEach(async () => { - subjectUnderlyingToken = aaveSetup.lendToken.address; - subjectWrappedToken = aaveSetup.aaveToken.address; - subjectUnderlyingUnits = ether(2); - }); - - async function subject(): Promise { - return aaveMigrationWrapAdapter.getWrapCallData(subjectUnderlyingToken, subjectWrappedToken, subjectUnderlyingUnits); - } - - it("should return correct data for valid pair", async () => { - const [targetAddress, ethValue, callData] = await subject(); - - const expectedCallData = aaveSetup.lendToAaveMigrator.interface.encodeFunctionData("migrateFromLEND", [subjectUnderlyingUnits]); - - expect(targetAddress).to.eq(aaveSetup.lendToAaveMigrator.address); - expect(ethValue).to.eq(ZERO); - expect(callData).to.eq(expectedCallData); - }); - - describe("when underlying asset is not LEND token", () => { - beforeEach(async () => { - subjectUnderlyingToken = mockOtherUnderlyingToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be LEND token"); - }); - }); - - describe("when wrapped asset is not AAVE token", () => { - beforeEach(async () => { - subjectWrappedToken = mockOtherWrappedToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be AAVE token"); - }); - }); - }); - - describe("#getUnwrapCallData", async () => { - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectWrappedTokenUnits: BigNumber; - - beforeEach(async () => { - subjectUnderlyingToken = mockOtherUnderlyingToken.address; - subjectWrappedToken = mockOtherWrappedToken.address; - subjectWrappedTokenUnits = ether(2); - }); - - async function subject(): Promise { - return aaveMigrationWrapAdapter.getUnwrapCallData(subjectUnderlyingToken, subjectWrappedToken, subjectWrappedTokenUnits); - } - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("AAVE migration cannot be reversed"); - }); - }); -}); diff --git a/test/protocol/integration/wrap/aaveWrapAdapter.spec.ts b/test/protocol/integration/wrap/aaveWrapAdapter.spec.ts deleted file mode 100644 index 41abb850a..000000000 --- a/test/protocol/integration/wrap/aaveWrapAdapter.spec.ts +++ /dev/null @@ -1,239 +0,0 @@ -import "module-alias/register"; -import { BigNumber } from "ethers"; - -import { Address } from "@utils/types"; -import { Account } from "@utils/test/types"; -import { ETH_ADDRESS, ZERO } from "@utils/constants"; -import { AaveWrapAdapter, AaveLendingPoolMock, AaveLendingPoolCoreMock } from "@utils/contracts"; -import DeployHelper from "@utils/deploys"; -import { - ether, - addressToData, - bigNumberToData -} from "@utils/index"; -import { - addSnapshotBeforeRestoreAfterEach, - getAccounts, - getWaffleExpect, -} from "@utils/test/index"; - -const expect = getWaffleExpect(); - -describe("AaveWrapAdapter", () => { - let owner: Account; - let deployer: DeployHelper; - let aaveLendingPool: AaveLendingPoolMock; - let aaveLendingPoolCore: AaveLendingPoolCoreMock; - let aaveWrapAdapter: AaveWrapAdapter; - let underlyingToken: Account; - let wrappedToken: Account; - let ethWrappedToken: Account; - let otherUnderlyingToken: Account; - - before(async () => { - [ - owner, - underlyingToken, - wrappedToken, - ethWrappedToken, - otherUnderlyingToken, - ] = await getAccounts(); - - deployer = new DeployHelper(owner.wallet); - - aaveLendingPoolCore = await deployer.mocks.deployAaveLendingPoolCoreMock(); - aaveLendingPool = await deployer.mocks.deployAaveLendingPoolMock(aaveLendingPoolCore.address); - await aaveLendingPoolCore.setReserveATokenAddress(underlyingToken.address, wrappedToken.address); - - aaveWrapAdapter = await deployer.adapters.deployAaveWrapAdapter(aaveLendingPool.address); - }); - - addSnapshotBeforeRestoreAfterEach(); - - describe("#constructor", async () => { - let subjectAaveLendingPool: Address; - - beforeEach(async () => { - subjectAaveLendingPool = aaveLendingPool.address; - }); - - async function subject(): Promise { - return deployer.adapters.deployAaveWrapAdapter(subjectAaveLendingPool); - } - - it("should have the correct lendingPool and lendingPoolCore addresses", async () => { - const deployedAaveWrapAdapter = await subject(); - - const actualAaveLendingPool = await deployedAaveWrapAdapter.aaveLendingPool(); - const actualAaveLendingPoolCore = await deployedAaveWrapAdapter.aaveLendingPoolCore(); - expect(actualAaveLendingPool).to.eq(aaveLendingPool.address); - expect(actualAaveLendingPoolCore).to.eq(aaveLendingPoolCore.address); - }); - - describe("when not a valid aaveLendingPool address", () => { - beforeEach(async () => { - subjectAaveLendingPool = aaveLendingPoolCore.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.reverted; - }); - }); - }); - - describe("#getSpenderAddress", async () => { - async function subject(): Promise { - return aaveWrapAdapter.getSpenderAddress(underlyingToken.address, wrappedToken.address); - } - - it("should return the correct spender address", async () => { - const spender = await subject(); - - expect(spender).to.eq(aaveLendingPoolCore.address); - }); - }); - - describe("#getWrapCallData", async () => { - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectUnderlyingUnits: BigNumber; - const depositSignature = "0xd2d0e066"; // deposit(address,uint256,uint16) - const generateCallData = (token: Address, units: BigNumber) => - depositSignature + - addressToData(token.toLowerCase()) + - bigNumberToData(units) + - bigNumberToData(ZERO); // referral code - - beforeEach(async () => { - subjectUnderlyingToken = underlyingToken.address; - subjectWrappedToken = wrappedToken.address; - subjectUnderlyingUnits = ether(2); - }); - - async function subject(): Promise { - return aaveWrapAdapter.getWrapCallData(subjectUnderlyingToken, subjectWrappedToken, subjectUnderlyingUnits); - } - - it("should return correct data for valid pair", async () => { - const [targetAddress, ethValue, callData] = await subject(); - - const expectedCallData = generateCallData(subjectUnderlyingToken, subjectUnderlyingUnits); - - expect(targetAddress).to.eq(aaveLendingPool.address); - expect(ethValue).to.eq(ZERO); - expect(callData).to.eq(expectedCallData); - }); - - describe("when underlying asset is ETH", () => { - beforeEach(async () => { - subjectUnderlyingToken = ETH_ADDRESS; - subjectWrappedToken = ethWrappedToken.address; - subjectUnderlyingUnits = ether(2); - - await aaveLendingPoolCore.setReserveATokenAddress(subjectUnderlyingToken, subjectWrappedToken); - }); - - it("should return correct data with eth value to send", async () => { - const [targetAddress, ethValue, callData] = await subject(); - - const expectedCallData = generateCallData(subjectUnderlyingToken, subjectUnderlyingUnits); - - expect(targetAddress).to.eq(aaveLendingPool.address); - expect(ethValue).to.eq(ether(2)); - expect(callData).to.eq(expectedCallData); - }); - }); - - describe("when invalid underlying token", () => { - beforeEach(async () => { - subjectUnderlyingToken = otherUnderlyingToken.address; - subjectWrappedToken = wrappedToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be a valid token pair"); - }); - }); - - describe("when invalid wrapped token", () => { - beforeEach(async () => { - subjectUnderlyingToken = underlyingToken.address; - subjectWrappedToken = ethWrappedToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be a valid token pair"); - }); - }); - }); - - describe("#getUnwrapCallData", async () => { - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectWrappedTokenUnits: BigNumber; - const redeemSignature = "0xdb006a75"; // redeem(uint256) - const generateCallData = (units: BigNumber) => redeemSignature + bigNumberToData(units); - - beforeEach(async () => { - subjectUnderlyingToken = underlyingToken.address; - subjectWrappedToken = wrappedToken.address; - subjectWrappedTokenUnits = ether(2); - }); - - async function subject(): Promise { - return aaveWrapAdapter.getUnwrapCallData(subjectUnderlyingToken, subjectWrappedToken, subjectWrappedTokenUnits); - } - - it("should return correct data for valid pair", async () => { - const [targetAddress, ethValue, callData] = await subject(); - - const expectedCallData = generateCallData(subjectWrappedTokenUnits); - - expect(targetAddress).to.eq(subjectWrappedToken); - expect(ethValue).to.eq(ZERO); - expect(callData).to.eq(expectedCallData); - }); - - describe("when underlying asset is ETH", () => { - beforeEach(async () => { - subjectUnderlyingToken = ETH_ADDRESS; - subjectWrappedToken = ethWrappedToken.address; - subjectWrappedTokenUnits = ether(2); - - await aaveLendingPoolCore.setReserveATokenAddress(subjectUnderlyingToken, subjectWrappedToken); - }); - - it("should return correct data with 0 eth value to send", async () => { - const [targetAddress, ethValue, callData] = await subject(); - - const expectedCallData = generateCallData(subjectWrappedTokenUnits); - - expect(targetAddress).to.eq(subjectWrappedToken); - expect(ethValue).to.eq(ZERO); - expect(callData).to.eq(expectedCallData); - }); - }); - - describe("when invalid underlying token", () => { - beforeEach(async () => { - subjectUnderlyingToken = otherUnderlyingToken.address; - subjectWrappedToken = wrappedToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be a valid token pair"); - }); - }); - - describe("when invalid wrapped token", () => { - beforeEach(async () => { - subjectUnderlyingToken = underlyingToken.address; - subjectWrappedToken = ethWrappedToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be a valid token pair"); - }); - }); - }); -}); diff --git a/test/protocol/integration/wrap/agiMigrationWrapAdapter.spec.ts b/test/protocol/integration/wrap/agiMigrationWrapAdapter.spec.ts deleted file mode 100644 index c33425a56..000000000 --- a/test/protocol/integration/wrap/agiMigrationWrapAdapter.spec.ts +++ /dev/null @@ -1,167 +0,0 @@ -import "module-alias/register"; -import { BigNumber } from "ethers"; - -import { Address } from "@utils/types"; -import { Account } from "@utils/test/types"; -import { ZERO } from "@utils/constants"; -import { AGIMigrationWrapAdapter } from "@utils/contracts"; -import { SingularityNetToken } from "@utils/contracts/"; -import DeployHelper from "@utils/deploys"; -import { - ether, -} from "@utils/index"; -import { - addSnapshotBeforeRestoreAfterEach, - getAccounts, - getWaffleExpect -} from "@utils/test/index"; - - -const expect = getWaffleExpect(); - -describe("AGIMigrationWrapAdapter", () => { - let owner: Account; - let deployer: DeployHelper; - let agiToken: SingularityNetToken; - let agiMigrationWrapAdapter: AGIMigrationWrapAdapter; - - let agiTokenV2: Account; - let mockOtherUnderlyingToken: Account; - let mockOtherWrappedToken: Account; - - before(async () => { - [ - owner, - agiTokenV2, - mockOtherUnderlyingToken, - mockOtherWrappedToken, - ] = await getAccounts(); - - deployer = new DeployHelper(owner.wallet); - - agiToken = await deployer.external.deploySingularityNetToken(); - - agiMigrationWrapAdapter = await deployer.adapters.deployAGIMigrationWrapAdapter( - agiToken.address, - agiTokenV2.address - ); - }); - - addSnapshotBeforeRestoreAfterEach(); - - describe("#constructor", async () => { - let subjectAgiToken: Address; - let subjectAgiTokenV2: Address; - - beforeEach(async () => { - subjectAgiToken = agiToken.address; - subjectAgiTokenV2 = agiTokenV2.address; - }); - - async function subject(): Promise { - return deployer.adapters.deployAGIMigrationWrapAdapter( - subjectAgiToken, - subjectAgiTokenV2 - ); - } - - it("should have the correct AGI token address", async () => { - const agiMigrationWrapAdapter = await subject(); - - const agiToken = await agiMigrationWrapAdapter.agiLegacyToken(); - const expectedAgiToken = subjectAgiToken; - - expect(agiToken).to.eq(expectedAgiToken); - }); - - it("should have the correct AGI token V2 (AGIX) address", async () => { - const agiMigrationWrapAdapter = await subject(); - - const agixToken = await agiMigrationWrapAdapter.agixToken(); - const expectedAgixToken = subjectAgiTokenV2; - - expect(agixToken).to.eq(expectedAgixToken); - }); - }); - - describe("#getSpenderAddress", async () => { - async function subject(): Promise { - return agiMigrationWrapAdapter.getSpenderAddress( - agiToken.address, - agiTokenV2.address - ); - } - - it("should return the correct spender address", async () => { - const spender = await subject(); - - expect(spender).to.eq(agiToken.address); - }); - }); - - describe("#getWrapCallData", async () => { - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectUnderlyingUnits: BigNumber; - - beforeEach(async () => { - subjectUnderlyingToken = agiToken.address; - subjectWrappedToken = agiTokenV2.address; - subjectUnderlyingUnits = ether(2); - }); - - async function subject(): Promise { - return agiMigrationWrapAdapter.getWrapCallData(subjectUnderlyingToken, subjectWrappedToken, subjectUnderlyingUnits); - } - - it("should return correct data for valid pair", async () => { - const [targetAddress, ethValue, callData] = await subject(); - - const expectedCallData = agiToken.interface.encodeFunctionData("burn", [subjectUnderlyingUnits]); - - expect(targetAddress).to.eq(agiToken.address); - expect(ethValue).to.eq(ZERO); - expect(callData).to.eq(expectedCallData); - }); - - describe("when underlying asset is not AGI token", () => { - beforeEach(async () => { - subjectUnderlyingToken = mockOtherUnderlyingToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be AGI token"); - }); - }); - - describe("when wrapped asset is not AGI token V2 (AGIX)", () => { - beforeEach(async () => { - subjectWrappedToken = mockOtherWrappedToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be AGIX token"); - }); - }); - }); - - describe("#getUnwrapCallData", async () => { - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectWrappedTokenUnits: BigNumber; - - beforeEach(async () => { - subjectUnderlyingToken = mockOtherUnderlyingToken.address; - subjectWrappedToken = mockOtherWrappedToken.address; - subjectWrappedTokenUnits = ether(2); - }); - - async function subject(): Promise { - return agiMigrationWrapAdapter.getUnwrapCallData(subjectUnderlyingToken, subjectWrappedToken, subjectWrappedTokenUnits); - } - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("AGI burn cannot be reversed"); - }); - }); -}); diff --git a/test/protocol/integration/wrap/axieInfinityMigrationWrapAdapter.spec.ts b/test/protocol/integration/wrap/axieInfinityMigrationWrapAdapter.spec.ts deleted file mode 100644 index f1a8875e3..000000000 --- a/test/protocol/integration/wrap/axieInfinityMigrationWrapAdapter.spec.ts +++ /dev/null @@ -1,229 +0,0 @@ -import "module-alias/register"; -import { BigNumber } from "ethers"; - -import { Address } from "@utils/types"; -import { Account } from "@utils/test/types"; -import { ZERO } from "@utils/constants"; -import { ContractTransaction } from "ethers"; -import { TokenSwap } from "@utils/contracts/axieInfinity"; -import { AxieInfinityMigrationWrapAdapter, StandardTokenMock } from "@utils/contracts"; -import DeployHelper from "@utils/deploys"; -import { - ether, -} from "@utils/index"; -import { - addSnapshotBeforeRestoreAfterEach, - getAccounts, - getRandomAccount, - getWaffleExpect -} from "@utils/test/index"; - -const expect = getWaffleExpect(); - -describe("AxieInfinityMigrationWrapAdapter", () => { - let owner: Account; - let deployer: DeployHelper; - let tokenSwap: TokenSwap; - let axieMigrationWrapAdapter: AxieInfinityMigrationWrapAdapter; - - let mockOtherUnderlyingToken: Account; - let mockOtherWrappedToken: Account; - let newAxsToken: StandardTokenMock; - let oldAxsToken: StandardTokenMock; - - before(async () => { - [ - owner, - mockOtherUnderlyingToken, - mockOtherWrappedToken, - ] = await getAccounts(); - - deployer = new DeployHelper(owner.wallet); - - oldAxsToken = await deployer.mocks.deployTokenMock(owner.address); - newAxsToken = await deployer.mocks.deployTokenMock(owner.address); - - tokenSwap = await deployer.external.deployTokenSwap(oldAxsToken.address, newAxsToken.address); - - // transfer new AXS tokens to TokenSwap contract - await newAxsToken.connect(owner.wallet).transfer(tokenSwap.address, ether(100000)); - - axieMigrationWrapAdapter = await deployer.adapters.deployAxieInfinityMigrationWrapAdapter( - tokenSwap.address, - oldAxsToken.address, - newAxsToken.address - ); - }); - - addSnapshotBeforeRestoreAfterEach(); - - describe("#constructor", async () => { - let subjectTokenSwap: Address; - let subjectOldAxsToken: Address; - let subjectNewAxsToken: Address; - - beforeEach(async () => { - subjectTokenSwap = tokenSwap.address; - subjectOldAxsToken = oldAxsToken.address; - subjectNewAxsToken = newAxsToken.address; - }); - - async function subject(): Promise { - return deployer.adapters.deployAxieInfinityMigrationWrapAdapter( - subjectTokenSwap, - subjectOldAxsToken, - subjectNewAxsToken - ); - } - - it("should have the correct tokenSwap address", async () => { - const deployedAxieMigrationWrapAdapter = await subject(); - - const tokenSwap = await deployedAxieMigrationWrapAdapter.tokenSwap(); - const expectedTokenSwap = subjectTokenSwap; - - expect(tokenSwap).to.eq(expectedTokenSwap); - }); - - it("should have the correct old AXS token address", async () => { - const deployedAxieMigrationWrapAdapter = await subject(); - - const oldAxsToken = await deployedAxieMigrationWrapAdapter.oldToken(); - const expectedOldAxsToken = subjectOldAxsToken; - - expect(oldAxsToken).to.eq(expectedOldAxsToken); - }); - - it("should have the correct new AXS token address", async () => { - const deployedAxieMigrationWrapAdapter = await subject(); - - const newAxsToken = await deployedAxieMigrationWrapAdapter.newToken(); - const expectedNewAxsToken = subjectNewAxsToken; - - expect(newAxsToken).to.eq(expectedNewAxsToken); - }); - }); - - describe("#swapTokenUsingAdapter", async () => { - let subjectCaller: Account; - let subjectAmount: BigNumber; - - beforeEach(async () => { - const randomAccount = await getRandomAccount(); - await oldAxsToken.connect(owner.wallet).transfer(randomAccount.address, ether(1000)); - - // Note: subjectCaller's oldAxsToken balance is higher than the subjectAmount. - // This represents the scenario when balance of oldAxsToken held in Set is greter than - // `setTokenTotalSupply.preciseMul(oldAxsPositionUnit)`, due to presence of some extra wei - // in the SetToken, accumulated due to rounding errors - subjectCaller = randomAccount; - subjectAmount = ether(100); - }); - - async function subject(): Promise { - return axieMigrationWrapAdapter.connect(subjectCaller.wallet).swapTokenUsingAdapter( - subjectAmount - ); - } - - it("Should swap old AXS tokens for new AXS tokens", async () => { - const beforeOldAxsBalance = await oldAxsToken.balanceOf(subjectCaller.address); - const beforeNewAxsBalance = await newAxsToken.balanceOf(subjectCaller.address); - - await oldAxsToken.connect(subjectCaller.wallet).approve(axieMigrationWrapAdapter.address, subjectAmount); - await subject(); - - const afterOldAxsBalance = await oldAxsToken.balanceOf(subjectCaller.address); - const afterNewAxsBalance = await newAxsToken.balanceOf(subjectCaller.address); - - const expectedAfterOldAxsBalance = beforeOldAxsBalance.sub(subjectAmount); - const expectedAfterNewAxsBalance = beforeNewAxsBalance.add(subjectAmount); - - expect(afterOldAxsBalance).to.eq(expectedAfterOldAxsBalance); - expect(afterNewAxsBalance).to.eq(expectedAfterNewAxsBalance); - }); - }); - - describe("#getSpenderAddress", async () => { - async function subject(): Promise { - return axieMigrationWrapAdapter.getSpenderAddress( - oldAxsToken.address, - newAxsToken.address - ); - } - - it("should return the correct spender address", async () => { - const spender = await subject(); - const expectedSpender = axieMigrationWrapAdapter.address; - - expect(spender).to.eq(expectedSpender); - }); - }); - - describe("#getWrapCallData", async () => { - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectNotionalUnderlying: BigNumber; - - beforeEach(async () => { - subjectUnderlyingToken = oldAxsToken.address; - subjectWrappedToken = newAxsToken.address; - subjectNotionalUnderlying = ether(2); - }); - - async function subject(): Promise { - return axieMigrationWrapAdapter.getWrapCallData(subjectUnderlyingToken, subjectWrappedToken, subjectNotionalUnderlying); - } - - it("should return correct data for valid pair", async () => { - const [targetAddress, ethValue, callData] = await subject(); - - const expectedCallData = axieMigrationWrapAdapter.interface.encodeFunctionData("swapTokenUsingAdapter", [subjectNotionalUnderlying]); - const expectedTargetAddress = axieMigrationWrapAdapter.address; - - expect(targetAddress).to.eq(expectedTargetAddress); - expect(ethValue).to.eq(ZERO); - expect(callData).to.eq(expectedCallData); - }); - - describe("when underlying asset is not old AXS token", () => { - beforeEach(async () => { - subjectUnderlyingToken = mockOtherUnderlyingToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be old AXS token"); - }); - }); - - describe("when wrapped asset is not new AXS token", () => { - beforeEach(async () => { - subjectWrappedToken = mockOtherWrappedToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be new AXS token"); - }); - }); - }); - - describe("#getUnwrapCallData", async () => { - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectNotionalUnderlying: BigNumber; - - beforeEach(async () => { - subjectUnderlyingToken = mockOtherUnderlyingToken.address; - subjectWrappedToken = mockOtherWrappedToken.address; - subjectNotionalUnderlying = ether(2); - }); - - async function subject(): Promise { - return axieMigrationWrapAdapter.getUnwrapCallData(subjectUnderlyingToken, subjectWrappedToken, subjectNotionalUnderlying); - } - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("AXS migration cannot be reversed"); - }); - }); -}); diff --git a/test/protocol/integration/wrap/compoundWrapAdapter.spec.ts b/test/protocol/integration/wrap/compoundWrapAdapter.spec.ts deleted file mode 100644 index 070f72492..000000000 --- a/test/protocol/integration/wrap/compoundWrapAdapter.spec.ts +++ /dev/null @@ -1,165 +0,0 @@ -import "module-alias/register"; -import { BigNumber } from "ethers"; - -import { Address } from "@utils/types"; -import { Account } from "@utils/test/types"; -import { CEther, CERc20 } from "@utils/contracts/compound"; -import { ETH_ADDRESS, ZERO } from "@utils/constants"; -import { CompoundFixture, SystemFixture } from "@utils/fixtures"; -import { CompoundWrapAdapter } from "@utils/contracts"; -import DeployHelper from "@utils/deploys"; -import { ether } from "@utils/index"; -import { - addSnapshotBeforeRestoreAfterEach, - getAccounts, - getSystemFixture, - getCompoundFixture, - getWaffleExpect, -} from "@utils/test/index"; - -const expect = getWaffleExpect(); - -describe("CompoundWrapAdapter", () => { - let owner: Account; - let deployer: DeployHelper; - let setup: SystemFixture; - let compoundSetup: CompoundFixture; - let compoundWrapAdapter: CompoundWrapAdapter; - let cEther: CEther; - let cDai: CERc20; - - before(async () => { - [ - owner, - ] = await getAccounts(); - - deployer = new DeployHelper(owner.wallet); - setup = getSystemFixture(owner.address); - await setup.initialize(); - - compoundSetup = getCompoundFixture(owner.address); - await compoundSetup.initialize(); - - cEther = await compoundSetup.createAndEnableCEther( - ether(200000000), - compoundSetup.comptroller.address, - compoundSetup.interestRateModel.address, - "Compound ether", - "cETH", - 8, - ether(0.75), // 75% collateral factor - ether(1000) - ); - - cDai = await compoundSetup.createAndEnableCToken( - setup.dai.address, - ether(200000000), - compoundSetup.comptroller.address, - compoundSetup.interestRateModel.address, - "Compound Dai", - "cDAI", - 8, - ether(0.75), // 75% collateral factor - ether(1) - ); - - const compoundLibrary = await deployer.libraries.deployCompound(); - compoundWrapAdapter = await deployer.adapters.deployCompoundWrapAdapter( - "contracts/protocol/integration/lib/Compound.sol:Compound", - compoundLibrary.address - ); - }); - - addSnapshotBeforeRestoreAfterEach(); - - describe("#getSpenderAddress", async () => { - async function subject(): Promise { - return compoundWrapAdapter.getSpenderAddress(setup.dai.address, cDai.address); - } - - it("should return the correct spender address", async () => { - const spender = await subject(); - expect(spender).to.eq(cDai.address); - }); - }); - - describe("#getWrapCallData", async () => { - let subjectCToken: Address; - let subjectUnderlyingToken: Address; - let subjectQuantity: BigNumber; - - beforeEach(async () => { - subjectQuantity = ether(1); - subjectUnderlyingToken = setup.dai.address; - subjectCToken = cDai.address; - }); - - async function subject(): Promise { - return compoundWrapAdapter.getWrapCallData(subjectUnderlyingToken, subjectCToken, subjectQuantity); - } - - it("should return correct data)", async () => { - const [targetAddress, ethValue, callData] = await subject(); - - const expectedCalldata = cDai.interface.encodeFunctionData("mint", [subjectQuantity]); - - expect(targetAddress).to.eq(subjectCToken); - expect(ethValue).to.eq(ZERO); - expect(callData).to.eq(expectedCalldata); - }); - - - describe("when underlying asset is ETH", () => { - let subjectCToken: Address; - let subjectQuantity: BigNumber; - - beforeEach(async () => { - subjectCToken = cEther.address; - subjectUnderlyingToken = ETH_ADDRESS; - subjectQuantity = ether(1); - }); - - async function subject(): Promise { - return compoundWrapAdapter.getWrapCallData(subjectUnderlyingToken, subjectCToken, subjectQuantity); - } - - it("should return correct data", async () => { - const [targetAddress, ethValue, callData] = await subject(); - - const expectedCallData = cEther.interface.encodeFunctionData("mint"); - - expect(targetAddress).to.eq(subjectCToken); - expect(ethValue).to.eq(subjectQuantity); - expect(callData).to.eq(expectedCallData); - }); - }); - - }); - - describe("#getUnwrapCallData", async () => { - let subjectCToken: Address; - let subjectUnderlyingToken: Address; - let subjectQuantity: BigNumber; - - beforeEach(async () => { - subjectCToken = cDai.address; - subjectUnderlyingToken = setup.dai.address; - subjectQuantity = ether(1); - }); - - async function subject(): Promise { - return compoundWrapAdapter.getUnwrapCallData(subjectUnderlyingToken, subjectCToken, subjectQuantity); - } - - it("should return correct data", async () => { - const [targetAddress, ethValue, callData] = await subject(); - - const expectedCallData = cDai.interface.encodeFunctionData("redeem", [subjectQuantity]); - - expect(targetAddress).to.eq(subjectCToken); - expect(ethValue).to.eq(ZERO); - expect(callData).to.eq(expectedCallData); - }); - }); - -}); diff --git a/test/protocol/integration/wrap/dgMigrationWrapAdapter.spec.ts b/test/protocol/integration/wrap/dgMigrationWrapAdapter.spec.ts deleted file mode 100644 index 870818315..000000000 --- a/test/protocol/integration/wrap/dgMigrationWrapAdapter.spec.ts +++ /dev/null @@ -1,152 +0,0 @@ -import "module-alias/register"; -import { BigNumber } from "ethers"; -import { Address } from "@utils/types"; -import { Account } from "@utils/test/types"; -import { DgMigrationWrapAdapter } from "@utils/contracts"; -import { DGLight, DgToken } from "@utils/contracts/dg"; -import { ZERO } from "@utils/constants"; -import DeployHelper from "@utils/deploys"; -import { - ether, -} from "@utils/index"; -import { - addSnapshotBeforeRestoreAfterEach, - getAccounts, - getWaffleExpect, -} from "@utils/test/index"; - -const expect = getWaffleExpect(); - -describe("DgMigrationWrapAdapter", () => { - let owner: Account; - let deployer: DeployHelper; - - let dgToken: DgToken; - let dgLight: DGLight; - let adapter: DgMigrationWrapAdapter; - - let mockOtherUnderlyingToken: Account; - let mockOtherWrappedToken: Account; - - before(async () => { - [ - owner, - mockOtherUnderlyingToken, - mockOtherWrappedToken - ] = await getAccounts(); - - deployer = new DeployHelper(owner.wallet); - dgToken = await deployer.mocks.deployTokenMock(owner.address); - dgLight = await deployer.external.deployDGLight(dgToken.address); - - adapter = await deployer.adapters.deployDgMigrationWrapAdapter( - dgToken.address, - dgLight.address - ); - }); - - addSnapshotBeforeRestoreAfterEach(); - - describe("#constructor", () => { - let subjectUnderlyingAddress: string; - let subjectWrappedAddress: string; - - beforeEach(async () => { - subjectUnderlyingAddress = dgToken.address; - subjectWrappedAddress = dgLight.address; - }); - - async function subject(): Promise { - return deployer.adapters.deployDgMigrationWrapAdapter( - subjectUnderlyingAddress, - subjectWrappedAddress - ); - } - - it("should have the correct legacy token address", async () => { - const deployedAdapter = await subject(); - - expect(await deployedAdapter.dgTokenV1()).to.eq(subjectUnderlyingAddress); - }); - - it("should have the correct new token address", async () => { - const deployedAdapter = await subject(); - expect(await deployedAdapter.dgTokenV2()).to.eq(subjectWrappedAddress); - }); - }); - - describe("#getWrapCallData", () => { - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectNotionalUnderlying: BigNumber; - - beforeEach(async () => { - subjectUnderlyingToken = dgToken.address; - subjectWrappedToken = dgLight.address; - subjectNotionalUnderlying = ether(2); - }); - - async function subject(): Promise<[string, BigNumber, string]> { - return adapter.getWrapCallData(subjectUnderlyingToken, subjectWrappedToken, subjectNotionalUnderlying); - } - - it("should return correct calldata", async () => { - const [targetAddress, ethValue, callData] = await subject(); - - const expectedCallData = dgLight.interface.encodeFunctionData("goLight", [subjectNotionalUnderlying]); - expect(targetAddress).to.eq(subjectWrappedToken); - expect(ethValue).to.eq(ZERO); - expect(callData).to.eq(expectedCallData); - }); - - describe("should revert when underlying is not old dg token", async () => { - beforeEach(async () => { - subjectUnderlyingToken = mockOtherUnderlyingToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be DG V1 token"); - }); - }); - - describe("should revert when wrapped asset is not new dg token", async () => { - beforeEach(async () => { - subjectWrappedToken = mockOtherWrappedToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be DG V2 token"); - }); - }); - }); - - describe("#getUnwrapCallData", () => { - let subjectUnderlyingToken: string; - let subjectWrappedToken: string; - let subjectAmount: BigNumber; - - beforeEach(async () => { - subjectUnderlyingToken = dgToken.address; - subjectWrappedToken = dgLight.address; - subjectAmount = ether(2); - }); - - async function subject(): Promise<[string, BigNumber, string]> { - return adapter.getUnwrapCallData(subjectUnderlyingToken, subjectWrappedToken, subjectAmount); - } - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("DG migration cannot be reversed"); - }); - }); - - describe("#getSpenderAddress", () => { - async function subject(): Promise { - return adapter.getSpenderAddress(dgToken.address, dgLight.address); - } - it("should return the correct spender address", async () => { - const spender = await subject(); - expect(spender).to.eq(dgLight.address); - }); - }); -}); diff --git a/test/protocol/integration/wrap/kyberMigrationWrapAdapter.spec.ts b/test/protocol/integration/wrap/kyberMigrationWrapAdapter.spec.ts deleted file mode 100644 index 8d5a127ef..000000000 --- a/test/protocol/integration/wrap/kyberMigrationWrapAdapter.spec.ts +++ /dev/null @@ -1,170 +0,0 @@ -import "module-alias/register"; -import { BigNumber } from "ethers"; - -import { Address } from "@utils/types"; -import { Account } from "@utils/test/types"; -import { ZERO } from "@utils/constants"; -import { KyberMigrationWrapAdapter } from "@utils/contracts"; -import { KyberNetworkTokenV2 } from "@utils/contracts/kyberV3"; -import DeployHelper from "@utils/deploys"; -import { - ether, -} from "@utils/index"; -import { - addSnapshotBeforeRestoreAfterEach, - getAccounts, - getWaffleExpect -} from "@utils/test/index"; - - -const expect = getWaffleExpect(); - -describe("KyberMigrationWrapAdapter", () => { - let owner: Account; - let deployer: DeployHelper; - let kyberNetworkTokenV2: KyberNetworkTokenV2; - let kyberMigrationWrapAdapter: KyberMigrationWrapAdapter; - - let minter: Account; - let kncLegacyToken: Account; - let mockOtherUnderlyingToken: Account; - let mockOtherWrappedToken: Account; - - before(async () => { - [ - owner, - minter, - kncLegacyToken, - mockOtherUnderlyingToken, - mockOtherWrappedToken, - ] = await getAccounts(); - - deployer = new DeployHelper(owner.wallet); - - kyberNetworkTokenV2 = await deployer.external.deployKyberNetworkTokenV2(); - await kyberNetworkTokenV2.initialize(kncLegacyToken.address, minter.address); - - kyberMigrationWrapAdapter = await deployer.adapters.deployKyberMigrationWrapAdapter( - kncLegacyToken.address, - kyberNetworkTokenV2.address - ); - }); - - addSnapshotBeforeRestoreAfterEach(); - - describe("#constructor", async () => { - let subjectKncLegacyToken: Address; - let subjectKncToken: Address; - - beforeEach(async () => { - subjectKncLegacyToken = kncLegacyToken.address; - subjectKncToken = kyberNetworkTokenV2.address; - }); - - async function subject(): Promise { - return deployer.adapters.deployKyberMigrationWrapAdapter( - subjectKncLegacyToken, - subjectKncToken - ); - } - - it("should have the correct KNC Legacy token address", async () => { - const deployKyberMigrationWrapAdapter = await subject(); - - const kncLegacyToken = await deployKyberMigrationWrapAdapter.kncLegacyToken(); - const expectedKncLegacyToken = subjectKncLegacyToken; - - expect(kncLegacyToken).to.eq(expectedKncLegacyToken); - }); - - it("should have the correct KNC token address", async () => { - const deployKyberMigrationWrapAdapter = await subject(); - - const kncToken = await deployKyberMigrationWrapAdapter.kncToken(); - const expectedKncToken = subjectKncToken; - - expect(kncToken).to.eq(expectedKncToken); - }); - }); - - describe("#getSpenderAddress", async () => { - async function subject(): Promise { - return kyberMigrationWrapAdapter.getSpenderAddress( - kncLegacyToken.address, - kyberNetworkTokenV2.address - ); - } - - it("should return the correct spender address", async () => { - const spender = await subject(); - - expect(spender).to.eq(kyberNetworkTokenV2.address); - }); - }); - - describe("#getWrapCallData", async () => { - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectUnderlyingUnits: BigNumber; - - beforeEach(async () => { - subjectUnderlyingToken = kncLegacyToken.address; - subjectWrappedToken = kyberNetworkTokenV2.address; - subjectUnderlyingUnits = ether(2); - }); - - async function subject(): Promise { - return kyberMigrationWrapAdapter.getWrapCallData(subjectUnderlyingToken, subjectWrappedToken, subjectUnderlyingUnits); - } - - it("should return correct data for valid pair", async () => { - const [targetAddress, ethValue, callData] = await subject(); - - const expectedCallData = kyberNetworkTokenV2.interface.encodeFunctionData("mintWithOldKnc", [subjectUnderlyingUnits]); - - expect(targetAddress).to.eq(kyberNetworkTokenV2.address); - expect(ethValue).to.eq(ZERO); - expect(callData).to.eq(expectedCallData); - }); - - describe("when underlying asset is not KNC Legacy token", () => { - beforeEach(async () => { - subjectUnderlyingToken = mockOtherUnderlyingToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be KNC Legacy token"); - }); - }); - - describe("when wrapped asset is not KNC token", () => { - beforeEach(async () => { - subjectWrappedToken = mockOtherWrappedToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be KNC token"); - }); - }); - }); - - describe("#getUnwrapCallData", async () => { - let subjectUnderlyingToken: Address; - let subjectWrappedToken: Address; - let subjectWrappedTokenUnits: BigNumber; - - beforeEach(async () => { - subjectUnderlyingToken = mockOtherUnderlyingToken.address; - subjectWrappedToken = mockOtherWrappedToken.address; - subjectWrappedTokenUnits = ether(2); - }); - - async function subject(): Promise { - return kyberMigrationWrapAdapter.getUnwrapCallData(subjectUnderlyingToken, subjectWrappedToken, subjectWrappedTokenUnits); - } - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("KNC migration cannot be reversed"); - }); - }); -}); diff --git a/test/protocol/modules/navIssuanceModule.spec.ts b/test/protocol/modules/navIssuanceModule.spec.ts deleted file mode 100644 index 629d30cb4..000000000 --- a/test/protocol/modules/navIssuanceModule.spec.ts +++ /dev/null @@ -1,3395 +0,0 @@ -import "module-alias/register"; - -import { BigNumber, BigNumberish } from "ethers"; - -import { Address, NAVIssuanceSettings } from "@utils/types"; -import { Account } from "@utils/test/types"; -import { ONE, TWO, THREE, ZERO, ADDRESS_ZERO } from "@utils/constants"; -import { ManagerIssuanceHookMock, NAVIssuanceHookMock, NavIssuanceModule, SetToken } from "@utils/contracts"; -import DeployHelper from "@utils/deploys"; -import { - bitcoin, - ether, - getExpectedIssuePositionMultiplier, - getExpectedIssuePositionUnit, - getExpectedPostFeeQuantity, - getExpectedSetTokenIssueQuantity, - getExpectedReserveRedeemQuantity, - getExpectedRedeemPositionMultiplier, - getExpectedRedeemPositionUnit, - preciseMul, - usdc, -} from "@utils/index"; -import { - getAccounts, - getRandomAddress, - cacheBeforeEach, - getRandomAccount, - getProvider, - getWaffleExpect, - getSystemFixture, -} from "@utils/test/index"; -import { SystemFixture } from "@utils/fixtures"; -import { ERC20__factory } from "../../../typechain/factories/ERC20__factory"; - -const expect = getWaffleExpect(); - -describe("NavIssuanceModule", () => { - let owner: Account; - let feeRecipient: Account; - let recipient: Account; - let deployer: DeployHelper; - - let setup: SystemFixture; - let navIssuanceModule: NavIssuanceModule; - - cacheBeforeEach(async () => { - [ - owner, - feeRecipient, - recipient, - ] = await getAccounts(); - - deployer = new DeployHelper(owner.wallet); - setup = getSystemFixture(owner.address); - await setup.initialize(); - - navIssuanceModule = await deployer.modules.deployNavIssuanceModule(setup.controller.address, setup.weth.address); - await setup.controller.addModule(navIssuanceModule.address); - }); - - describe("#constructor", async () => { - let subjectController: Address; - let subjectWETH: Address; - - beforeEach(async () => { - subjectController = setup.controller.address; - subjectWETH = setup.weth.address; - }); - - async function subject(): Promise { - return deployer.modules.deployNavIssuanceModule(subjectController, subjectWETH); - } - - it("should set the correct controller", async () => { - const navIssuanceModule = await subject(); - - const controller = await navIssuanceModule.controller(); - expect(controller).to.eq(subjectController); - }); - - it("should set the correct weth contract", async () => { - const navIssuanceModule = await subject(); - - const weth = await navIssuanceModule.weth(); - expect(weth).to.eq(subjectWETH); - }); - }); - - describe("#initialize", async () => { - let setToken: SetToken; - let managerIssuanceHook: Address; - let managerRedemptionHook: Address; - let reserveAssets: Address[]; - let managerFeeRecipient: Address; - let managerFees: [BigNumberish, BigNumberish]; - let maxManagerFee: BigNumber; - let premiumPercentage: BigNumber; - let maxPremiumPercentage: BigNumber; - let minSetTokenSupply: BigNumber; - - let subjectNAVIssuanceSettings: NAVIssuanceSettings; - let subjectSetToken: Address; - let subjectCaller: Account; - - cacheBeforeEach(async () => { - setToken = await setup.createSetToken( - [setup.weth.address], - [ether(1)], - [navIssuanceModule.address] - ); - - managerIssuanceHook = await getRandomAddress(); - managerRedemptionHook = await getRandomAddress(); - reserveAssets = [setup.usdc.address, setup.weth.address]; - managerFeeRecipient = feeRecipient.address; - // Set manager issue fee to 0.1% and redeem to 0.2% - managerFees = [ether(0.001), ether(0.002)]; - // Set max managerFee to 2% - maxManagerFee = ether(0.02); - // Set premium to 1% - premiumPercentage = ether(0.01); - // Set max premium to 10% - maxPremiumPercentage = ether(0.1); - // Set min SetToken supply to 100 units - minSetTokenSupply = ether(100); - }); - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectNAVIssuanceSettings = { - managerIssuanceHook, - managerRedemptionHook, - reserveAssets, - feeRecipient: managerFeeRecipient, - managerFees, - maxManagerFee, - premiumPercentage, - maxPremiumPercentage, - minSetTokenSupply, - } as NAVIssuanceSettings; - subjectCaller = owner; - }); - - async function subject(): Promise { - return navIssuanceModule.connect(subjectCaller.wallet).initialize( - subjectSetToken, - subjectNAVIssuanceSettings - ); - } - - it("should set the correct NAV issuance settings", async () => { - await subject(); - - const navIssuanceSettings: any = await navIssuanceModule.navIssuanceSettings(subjectSetToken); - const retrievedReserveAssets = await navIssuanceModule.getReserveAssets(subjectSetToken); - const managerIssueFee = await navIssuanceModule.getManagerFee(subjectSetToken, ZERO); - const managerRedeemFee = await navIssuanceModule.getManagerFee(subjectSetToken, ONE); - - expect(JSON.stringify(retrievedReserveAssets)).to.eq(JSON.stringify(reserveAssets)); - expect(navIssuanceSettings.managerIssuanceHook).to.eq(managerIssuanceHook); - expect(navIssuanceSettings.managerRedemptionHook).to.eq(managerRedemptionHook); - expect(navIssuanceSettings.feeRecipient).to.eq(managerFeeRecipient); - expect(managerIssueFee).to.eq(managerFees[0]); - expect(managerRedeemFee).to.eq(managerFees[1]); - expect(navIssuanceSettings.maxManagerFee).to.eq(maxManagerFee); - expect(navIssuanceSettings.premiumPercentage).to.eq(premiumPercentage); - expect(navIssuanceSettings.maxPremiumPercentage).to.eq(maxPremiumPercentage); - expect(navIssuanceSettings.minSetTokenSupply).to.eq(minSetTokenSupply); - }); - - it("should enable the Module on the SetToken", async () => { - await subject(); - - const isModuleEnabled = await setToken.isInitializedModule(navIssuanceModule.address); - expect(isModuleEnabled).to.eq(true); - }); - - it("should properly set reserve assets mapping", async () => { - await subject(); - - const isUsdcReserveAsset = await navIssuanceModule.isReserveAsset(subjectSetToken, setup.usdc.address); - const isWethReserveAsset = await navIssuanceModule.isReserveAsset(subjectSetToken, setup.weth.address); - expect(isUsdcReserveAsset).to.eq(true); - expect(isWethReserveAsset).to.eq(true); - }); - - describe("when the caller is not the SetToken manager", async () => { - beforeEach(async () => { - subjectCaller = await getRandomAccount(); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be the SetToken manager"); - }); - }); - - describe("when SetToken is not in pending state", async () => { - beforeEach(async () => { - const newModule = await getRandomAddress(); - await setup.controller.addModule(newModule); - - const navIssuanceModuleNotPendingSetToken = await setup.createSetToken( - [setup.weth.address], - [ether(1)], - [newModule] - ); - - subjectSetToken = navIssuanceModuleNotPendingSetToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be pending initialization"); - }); - }); - - describe("when the SetToken is not enabled on the controller", async () => { - beforeEach(async () => { - const nonEnabledSetToken = await setup.createNonControllerEnabledSetToken( - [setup.weth.address], - [ether(1)], - [navIssuanceModule.address] - ); - - subjectSetToken = nonEnabledSetToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be controller-enabled SetToken"); - }); - }); - - describe("when no reserve assets are specified", async () => { - beforeEach(async () => { - subjectNAVIssuanceSettings.reserveAssets = []; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Reserve assets must be greater than 0"); - }); - }); - - describe("when reserve asset is duplicated", async () => { - beforeEach(async () => { - subjectNAVIssuanceSettings.reserveAssets = [setup.weth.address, setup.weth.address]; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Reserve assets must be unique"); - }); - }); - - describe("when manager issue fee is greater than max", async () => { - beforeEach(async () => { - // Set to 100% - subjectNAVIssuanceSettings.managerFees = [ether(1), ether(0.002)]; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Manager issue fee must be less than max"); - }); - }); - - describe("when manager redeem fee is greater than max", async () => { - beforeEach(async () => { - // Set to 100% - subjectNAVIssuanceSettings.managerFees = [ether(0.001), ether(1)]; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Manager redeem fee must be less than max"); - }); - }); - - describe("when max manager fee is greater than 100%", async () => { - beforeEach(async () => { - // Set to 200% - subjectNAVIssuanceSettings.maxManagerFee = ether(2); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Max manager fee must be less than 100%"); - }); - }); - - describe("when premium is greater than max", async () => { - beforeEach(async () => { - // Set to 100% - subjectNAVIssuanceSettings.premiumPercentage = ether(1); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Premium must be less than max"); - }); - }); - - describe("when premium is greater than 100%", async () => { - beforeEach(async () => { - // Set to 100% - subjectNAVIssuanceSettings.maxPremiumPercentage = ether(2); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Max premium percentage must be less than 100%"); - }); - }); - - describe("when feeRecipient is zero address", async () => { - beforeEach(async () => { - subjectNAVIssuanceSettings.feeRecipient = ADDRESS_ZERO; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Fee Recipient must be non-zero address."); - }); - }); - - describe("when min SetToken supply is 0", async () => { - beforeEach(async () => { - subjectNAVIssuanceSettings.minSetTokenSupply = ZERO; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Min SetToken supply must be greater than 0"); - }); - }); - }); - - describe("#removeModule", async () => { - let setToken: SetToken; - - let subjectSetToken: Address; - let subjectModule: Address; - - cacheBeforeEach(async () => { - setToken = await setup.createSetToken( - [setup.weth.address], - [ether(1)], - [navIssuanceModule.address] - ); - // Set premium to 1% - const managerIssuanceHook = await getRandomAddress(); - const managerRedemptionHook = await getRandomAddress(); - const reserveAssets = [setup.usdc.address, setup.weth.address]; - const managerFeeRecipient = feeRecipient.address; - // Set manager issue fee to 0.1% and redeem to 0.2% - const managerFees = [ether(0.001), ether(0.002)] as [BigNumberish, BigNumberish]; - // Set max managerFee to 2% - const maxManagerFee = ether(0.02); - // Set premium to 1% - const premiumPercentage = ether(0.01); - // Set max premium to 10% - const maxPremiumPercentage = ether(0.1); - // Set min SetToken supply required - const minSetTokenSupply = ether(1); - - await navIssuanceModule.connect(owner.wallet).initialize( - setToken.address, - { - managerIssuanceHook, - managerRedemptionHook, - reserveAssets, - feeRecipient: managerFeeRecipient, - managerFees, - maxManagerFee, - premiumPercentage, - maxPremiumPercentage, - minSetTokenSupply, - } - ); - }); - - beforeEach(() => { - subjectSetToken = setToken.address; - subjectModule = navIssuanceModule.address; - }); - - async function subject(): Promise { - return setToken.removeModule(subjectModule); - } - - it("should delete reserve assets state", async () => { - await subject(); - - const isUsdcReserveAsset = await navIssuanceModule.isReserveAsset(setToken.address, setup.usdc.address); - const isWethReserveAsset = await navIssuanceModule.isReserveAsset(setToken.address, setup.weth.address); - expect(isUsdcReserveAsset).to.be.false; - expect(isWethReserveAsset).to.be.false; - }); - - it("should delete the NAV issuance settings", async () => { - await subject(); - - const navIssuanceSettings: any = await navIssuanceModule.navIssuanceSettings(subjectSetToken); - const retrievedReserveAssets = await navIssuanceModule.getReserveAssets(subjectSetToken); - const managerIssueFee = await navIssuanceModule.getManagerFee(subjectSetToken, ZERO); - const managerRedeemFee = await navIssuanceModule.getManagerFee(subjectSetToken, ONE); - - expect(retrievedReserveAssets).to.be.empty; - expect(navIssuanceSettings.managerIssuanceHook).to.eq(ADDRESS_ZERO); - expect(navIssuanceSettings.managerRedemptionHook).to.eq(ADDRESS_ZERO); - expect(navIssuanceSettings.feeRecipient).to.eq(ADDRESS_ZERO); - expect(managerIssueFee).to.eq(ZERO); - expect(managerRedeemFee).to.eq(ZERO); - expect(navIssuanceSettings.maxManagerFee).to.eq(ZERO); - expect(navIssuanceSettings.premiumPercentage).to.eq(ZERO); - expect(navIssuanceSettings.maxPremiumPercentage).to.eq(ZERO); - expect(navIssuanceSettings.minSetTokenSupply).to.eq(ZERO); - }); - }); - - describe("#getReserveAssets", async () => { - let reserveAssets: Address[]; - let subjectSetToken: Address; - let setToken: SetToken; - - cacheBeforeEach(async () => { - setToken = await setup.createSetToken( - [setup.weth.address], - [ether(1)], - [navIssuanceModule.address] - ); - const managerIssuanceHook = await getRandomAddress(); - const managerRedemptionHook = await getRandomAddress(); - reserveAssets = [setup.usdc.address, setup.weth.address]; - const managerFeeRecipient = feeRecipient.address; - // Set manager issue fee to 0.1% and redeem to 0.2% - const managerFees = [ether(0.001), ether(0.002)]; - // Set max managerFee to 2% - const maxManagerFee = ether(0.02); - // Set premium to 1% - const premiumPercentage = ether(0.01); - // Set max premium to 10% - const maxPremiumPercentage = ether(0.1); - // Set min SetToken supply to 100 units - const minSetTokenSupply = ether(100); - - const navIssuanceSettings = { - managerIssuanceHook, - managerRedemptionHook, - reserveAssets, - feeRecipient: managerFeeRecipient, - managerFees, - maxManagerFee, - premiumPercentage, - maxPremiumPercentage, - minSetTokenSupply, - } as NAVIssuanceSettings; - - await navIssuanceModule.initialize( - setToken.address, - navIssuanceSettings - ); - }); - - beforeEach(() => { - subjectSetToken = setToken.address; - }); - - async function subject(): Promise { - return navIssuanceModule.getReserveAssets(subjectSetToken); - } - - it("should return the valid reserve assets", async () => { - const returnedReserveAssets = await subject(); - - expect(JSON.stringify(returnedReserveAssets)).to.eq(JSON.stringify(reserveAssets)); - }); - }); - - describe("#getIssuePremium", async () => { - let premiumPercentage: BigNumber; - let subjectSetToken: Address; - let subjectReserveAsset: Address; - let subjectReserveQuantity: BigNumber; - let setToken: SetToken; - - cacheBeforeEach(async () => { - setToken = await setup.createSetToken( - [setup.weth.address], - [ether(1)], - [navIssuanceModule.address] - ); - const managerIssuanceHook = await getRandomAddress(); - const managerRedemptionHook = await getRandomAddress(); - const reserveAssets = [setup.usdc.address, setup.weth.address]; - const managerFeeRecipient = feeRecipient.address; - // Set manager issue fee to 0.1% and redeem to 0.2% - const managerFees = [ether(0.001), ether(0.002)]; - // Set max managerFee to 2% - const maxManagerFee = ether(0.02); - // Set premium to 1% - premiumPercentage = ether(0.01); - // Set max premium to 10% - const maxPremiumPercentage = ether(0.1); - // Set min SetToken supply to 100 units - const minSetTokenSupply = ether(100); - - const navIssuanceSettings = { - managerIssuanceHook, - managerRedemptionHook, - reserveAssets, - feeRecipient: managerFeeRecipient, - managerFees, - maxManagerFee, - premiumPercentage, - maxPremiumPercentage, - minSetTokenSupply, - } as NAVIssuanceSettings; - - await navIssuanceModule.initialize( - setToken.address, - navIssuanceSettings - ); - }); - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectReserveAsset = await getRandomAddress(); // Unused in NavIssuanceModule V1 - subjectReserveQuantity = ether(1); // Unused in NAVIssuanceModule V1 - }); - - async function subject(): Promise { - return navIssuanceModule.getIssuePremium(subjectSetToken, subjectReserveAsset, subjectReserveQuantity); - } - - it("should return the correct premium", async () => { - const returnedPremiumPercentage = await subject(); - - expect(returnedPremiumPercentage).to.eq(premiumPercentage); - }); - }); - - describe("#getRedeemPremium", async () => { - let premiumPercentage: BigNumber; - let subjectSetToken: Address; - let subjectReserveAsset: Address; - let subjectSetTokenQuantity: BigNumber; - let setToken: SetToken; - - cacheBeforeEach(async () => { - setToken = await setup.createSetToken( - [setup.weth.address], - [ether(1)], - [navIssuanceModule.address] - ); - const managerIssuanceHook = await getRandomAddress(); - const managerRedemptionHook = await getRandomAddress(); - const reserveAssets = [setup.usdc.address, setup.weth.address]; - const managerFeeRecipient = feeRecipient.address; - // Set manager issue fee to 0.1% and redeem to 0.2% - const managerFees = [ether(0.001), ether(0.002)]; - // Set max managerFee to 2% - const maxManagerFee = ether(0.02); - // Set premium to 1% - premiumPercentage = ether(0.01); - // Set max premium to 10% - const maxPremiumPercentage = ether(0.1); - // Set min SetToken supply to 100 units - const minSetTokenSupply = ether(100); - - const navIssuanceSettings = { - managerIssuanceHook, - managerRedemptionHook, - reserveAssets, - feeRecipient: managerFeeRecipient, - managerFees, - maxManagerFee, - premiumPercentage, - maxPremiumPercentage, - minSetTokenSupply, - } as NAVIssuanceSettings; - - await navIssuanceModule.initialize( - setToken.address, - navIssuanceSettings - ); - }); - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectReserveAsset = await getRandomAddress(); // Unused in NavIssuanceModule V1 - subjectSetTokenQuantity = ether(1); // Unused in NAVIssuanceModule V1 - }); - - async function subject(): Promise { - return navIssuanceModule.getRedeemPremium(subjectSetToken, subjectReserveAsset, subjectSetTokenQuantity); - } - - it("should return the correct premium", async () => { - const returnedPremiumPercentage = await subject(); - - expect(returnedPremiumPercentage).to.eq(premiumPercentage); - }); - }); - - describe("#getManagerFee", async () => { - let managerFees: BigNumber[]; - let subjectSetToken: Address; - let subjectFeeIndex: BigNumber; - let setToken: SetToken; - - cacheBeforeEach(async () => { - setToken = await setup.createSetToken( - [setup.weth.address], - [ether(1)], - [navIssuanceModule.address] - ); - const managerIssuanceHook = await getRandomAddress(); - const managerRedemptionHook = await getRandomAddress(); - const reserveAssets = [setup.usdc.address, setup.weth.address]; - const managerFeeRecipient = feeRecipient.address; - // Set manager issue fee to 0.1% and redeem to 0.2% - managerFees = [ether(0.001), ether(0.002)]; - // Set max managerFee to 2% - const maxManagerFee = ether(0.02); - // Set premium to 1% - const premiumPercentage = ether(0.01); - // Set max premium to 10% - const maxPremiumPercentage = ether(0.1); - // Set min SetToken supply to 100 units - const minSetTokenSupply = ether(100); - - const navIssuanceSettings = { - managerIssuanceHook, - managerRedemptionHook, - reserveAssets, - feeRecipient: managerFeeRecipient, - managerFees, - maxManagerFee, - premiumPercentage, - maxPremiumPercentage, - minSetTokenSupply, - } as NAVIssuanceSettings; - - await navIssuanceModule.initialize( - setToken.address, - navIssuanceSettings - ); - }); - - beforeEach(() => { - subjectSetToken = setToken.address; - subjectFeeIndex = ZERO; - }); - - async function subject(): Promise { - return navIssuanceModule.getManagerFee(subjectSetToken, subjectFeeIndex); - } - - it("should return the manager fee", async () => { - const returnedManagerFee = await subject(); - - expect(returnedManagerFee).to.eq(managerFees[0]); - }); - }); - - describe("#getExpectedSetTokenIssueQuantity", async () => { - let subjectSetToken: Address; - let subjectReserveAsset: Address; - let subjectReserveQuantity: BigNumber; - - let setToken: SetToken; - let managerFees: BigNumber[]; - let protocolDirectFee: BigNumber; - let premiumPercentage: BigNumber; - - cacheBeforeEach(async () => { - setToken = await setup.createSetToken( - [setup.weth.address], - [ether(1)], - [navIssuanceModule.address] - ); - const managerIssuanceHook = await getRandomAddress(); - const managerRedemptionHook = await getRandomAddress(); - const reserveAssets = [setup.usdc.address, setup.weth.address]; - const managerFeeRecipient = feeRecipient.address; - // Set manager issue fee to 0.1% and redeem to 0.2% - managerFees = [ether(0.001), ether(0.002)]; - // Set max managerFee to 2% - const maxManagerFee = ether(0.02); - // Set premium to 1% - premiumPercentage = ether(0.01); - // Set max premium to 10% - const maxPremiumPercentage = ether(0.1); - // Set min SetToken supply to 100 units - const minSetTokenSupply = ether(100); - - const navIssuanceSettings = { - managerIssuanceHook, - managerRedemptionHook, - reserveAssets, - feeRecipient: managerFeeRecipient, - managerFees, - maxManagerFee, - premiumPercentage, - maxPremiumPercentage, - minSetTokenSupply, - } as NAVIssuanceSettings; - - await navIssuanceModule.initialize( - setToken.address, - navIssuanceSettings - ); - - protocolDirectFee = ether(.02); - await setup.controller.addFee(navIssuanceModule.address, TWO, protocolDirectFee); - - const protocolManagerFee = ether(.3); - await setup.controller.addFee(navIssuanceModule.address, ZERO, protocolManagerFee); - }); - - beforeEach(() => { - subjectSetToken = setToken.address; - subjectReserveAsset = setup.usdc.address; - subjectReserveQuantity = ether(1); - }); - - async function subject(): Promise { - return navIssuanceModule.getExpectedSetTokenIssueQuantity(subjectSetToken, subjectReserveAsset, subjectReserveQuantity); - } - - it("should return the correct expected Set issue quantity", async () => { - const expectedSetTokenIssueQuantity = await getExpectedSetTokenIssueQuantity( - setToken, - setup.setValuer, - subjectReserveAsset, - usdc(1), - subjectReserveQuantity, - managerFees[0], - protocolDirectFee, - premiumPercentage - ); - const returnedSetTokenIssueQuantity = await subject(); - expect(expectedSetTokenIssueQuantity).to.eq(returnedSetTokenIssueQuantity); - }); - }); - - describe("#getExpectedReserveRedeemQuantity", async () => { - let subjectSetToken: Address; - let subjectReserveAsset: Address; - let subjectSetTokenQuantity: BigNumber; - - let setToken: SetToken; - let managerFees: BigNumber[]; - let protocolDirectFee: BigNumber; - let premiumPercentage: BigNumber; - - cacheBeforeEach(async () => { - setToken = await setup.createSetToken( - [setup.weth.address, setup.usdc.address, setup.wbtc.address, setup.dai.address], - [ether(1), usdc(270), bitcoin(1).div(10), ether(600)], - [setup.issuanceModule.address, navIssuanceModule.address] - ); - const managerIssuanceHook = await getRandomAddress(); - const managerRedemptionHook = await getRandomAddress(); - const reserveAssets = [setup.usdc.address, setup.weth.address]; - const managerFeeRecipient = feeRecipient.address; - // Set manager issue fee to 0.1% and redeem to 0.2% - managerFees = [ether(0.001), ether(0.002)]; - // Set max managerFee to 2% - const maxManagerFee = ether(0.02); - // Set premium to 1% - premiumPercentage = ether(0.01); - // Set max premium to 10% - const maxPremiumPercentage = ether(0.1); - // Set min SetToken supply to 1 unit - const minSetTokenSupply = ether(1); - - const navIssuanceSettings = { - managerIssuanceHook, - managerRedemptionHook, - reserveAssets, - feeRecipient: managerFeeRecipient, - managerFees, - maxManagerFee, - premiumPercentage, - maxPremiumPercentage, - minSetTokenSupply, - } as NAVIssuanceSettings; - - await navIssuanceModule.initialize(setToken.address, navIssuanceSettings); - // Approve tokens to the controller - await setup.weth.approve(setup.controller.address, ether(100)); - await setup.usdc.approve(setup.controller.address, usdc(1000000)); - await setup.wbtc.approve(setup.controller.address, bitcoin(1000000)); - await setup.dai.approve(setup.controller.address, ether(1000000)); - - // Seed with 10 supply - await setup.issuanceModule.connect(owner.wallet).initialize(setToken.address, ADDRESS_ZERO); - await setup.issuanceModule.connect(owner.wallet).issue(setToken.address, ether(10), owner.address); - - protocolDirectFee = ether(.02); - await setup.controller.addFee(navIssuanceModule.address, THREE, protocolDirectFee); - - const protocolManagerFee = ether(.3); - await setup.controller.addFee(navIssuanceModule.address, ONE, protocolManagerFee); - }); - - beforeEach(() => { - subjectSetToken = setToken.address; - subjectReserveAsset = setup.usdc.address; - subjectSetTokenQuantity = ether(1); - }); - - async function subject(): Promise { - return navIssuanceModule.getExpectedReserveRedeemQuantity(subjectSetToken, subjectReserveAsset, subjectSetTokenQuantity); - } - - it("should return the correct expected reserve asset redeem quantity", async () => { - const setTokenValuation = await setup.setValuer.calculateSetTokenValuation( - subjectSetToken, - subjectReserveAsset - ); - const expectedRedeemQuantity = getExpectedReserveRedeemQuantity( - subjectSetTokenQuantity, - setTokenValuation, - usdc(1), // USDC base units - managerFees[1], - protocolDirectFee, // Protocol fee percentage - premiumPercentage - ); - const returnedRedeemQuantity = await subject(); - expect(expectedRedeemQuantity).to.eq(returnedRedeemQuantity); - }); - }); - - describe("#isIssueValid", async () => { - let subjectSetToken: Address; - let subjectReserveAsset: Address; - let subjectReserveQuantity: BigNumber; - - let setToken: SetToken; - - cacheBeforeEach(async () => { - setToken = await setup.createSetToken( - [setup.weth.address, setup.usdc.address, setup.wbtc.address, setup.dai.address], - [ether(1), usdc(270), bitcoin(1).div(10), ether(600)], - [setup.issuanceModule.address, navIssuanceModule.address] - ); - const managerIssuanceHook = await getRandomAddress(); - const managerRedemptionHook = await getRandomAddress(); - const reserveAssets = [setup.usdc.address, setup.weth.address]; - const managerFeeRecipient = feeRecipient.address; - // Set manager issue fee to 0.1% and redeem to 0.2% - const managerFees = [ether(0.001), ether(0.002)]; - // Set max managerFee to 2% - const maxManagerFee = ether(0.02); - // Set premium to 1% - const premiumPercentage = ether(0.01); - // Set max premium to 10% - const maxPremiumPercentage = ether(0.1); - // Set min SetToken supply to 100 units - const minSetTokenSupply = ether(1); - - const navIssuanceSettings = { - managerIssuanceHook, - managerRedemptionHook, - reserveAssets, - feeRecipient: managerFeeRecipient, - managerFees, - maxManagerFee, - premiumPercentage, - maxPremiumPercentage, - minSetTokenSupply, - } as NAVIssuanceSettings; - - await navIssuanceModule.initialize(setToken.address, navIssuanceSettings); - // Approve tokens to the controller - await setup.weth.approve(setup.controller.address, ether(100)); - await setup.usdc.approve(setup.controller.address, usdc(1000000)); - await setup.wbtc.approve(setup.controller.address, bitcoin(1000000)); - await setup.dai.approve(setup.controller.address, ether(1000000)); - - // Seed with 10 supply - await setup.issuanceModule.connect(owner.wallet).initialize(setToken.address, ADDRESS_ZERO); - await setup.issuanceModule.connect(owner.wallet).issue(setToken.address, ether(10), owner.address); - - const protocolDirectFee = ether(.02); - await setup.controller.addFee(navIssuanceModule.address, TWO, protocolDirectFee); - - const protocolManagerFee = ether(.3); - await setup.controller.addFee(navIssuanceModule.address, ZERO, protocolManagerFee); - }); - - beforeEach(() => { - subjectSetToken = setToken.address; - subjectReserveAsset = setup.usdc.address; - subjectReserveQuantity = usdc(100); - }); - - async function subject(): Promise { - return navIssuanceModule.isIssueValid(subjectSetToken, subjectReserveAsset, subjectReserveQuantity); - } - - it("should return true", async () => { - const returnedValue = await subject(); - expect(returnedValue).to.eq(true); - }); - - describe("when total supply is less than min required for NAV issuance", async () => { - beforeEach(async () => { - // Redeem below required - await setup.issuanceModule.connect(owner.wallet).redeem(setToken.address, ether(9.5), owner.address); - }); - - it("returns false", async () => { - const returnedValue = await subject(); - expect(returnedValue).to.eq(false); - }); - }); - - describe("when the issue quantity is 0", async () => { - beforeEach(async () => { - subjectReserveQuantity = ZERO; - }); - - it("returns false", async () => { - const returnedValue = await subject(); - expect(returnedValue).to.eq(false); - }); - }); - - describe("when the reserve asset is not valid", async () => { - beforeEach(async () => { - subjectReserveAsset = setup.wbtc.address; - }); - - it("returns false", async () => { - const returnedValue = await subject(); - expect(returnedValue).to.eq(false); - }); - }); - }); - - describe("#isRedeemValid", async () => { - let subjectSetToken: Address; - let subjectReserveAsset: Address; - let subjectSetTokenQuantity: BigNumber; - - let setToken: SetToken; - - cacheBeforeEach(async () => { - setToken = await setup.createSetToken( - [setup.weth.address, setup.usdc.address, setup.wbtc.address, setup.dai.address], - [ether(1), usdc(270), bitcoin(1).div(10), ether(600)], - [setup.issuanceModule.address, navIssuanceModule.address] - ); - const managerIssuanceHook = await getRandomAddress(); - const managerRedemptionHook = await getRandomAddress(); - const reserveAssets = [setup.usdc.address, setup.weth.address]; - const managerFeeRecipient = feeRecipient.address; - // Set manager issue fee to 0.1% and redeem to 0.2% - const managerFees = [ether(0.001), ether(0.002)]; - // Set max managerFee to 2% - const maxManagerFee = ether(0.02); - // Set premium to 1% - const premiumPercentage = ether(0.01); - // Set max premium to 10% - const maxPremiumPercentage = ether(0.1); - // Set min SetToken supply to 1 unit - const minSetTokenSupply = ether(1); - - const navIssuanceSettings = { - managerIssuanceHook, - managerRedemptionHook, - reserveAssets, - feeRecipient: managerFeeRecipient, - managerFees, - maxManagerFee, - premiumPercentage, - maxPremiumPercentage, - minSetTokenSupply, - } as NAVIssuanceSettings; - - await navIssuanceModule.initialize(setToken.address, navIssuanceSettings); - // Approve tokens to the controller - await setup.weth.approve(setup.controller.address, ether(100)); - await setup.usdc.approve(setup.controller.address, usdc(1000000)); - await setup.wbtc.approve(setup.controller.address, bitcoin(1000000)); - await setup.dai.approve(setup.controller.address, ether(1000000)); - - // Seed with 10 supply - await setup.issuanceModule.connect(owner.wallet).initialize(setToken.address, ADDRESS_ZERO); - await setup.issuanceModule.connect(owner.wallet).issue(setToken.address, ether(10), owner.address); - - const protocolDirectFee = ether(.02); - await setup.controller.addFee(navIssuanceModule.address, THREE, protocolDirectFee); - - const protocolManagerFee = ether(.3); - await setup.controller.addFee(navIssuanceModule.address, ONE, protocolManagerFee); - }); - - beforeEach(() => { - subjectSetToken = setToken.address; - subjectReserveAsset = setup.usdc.address; - subjectSetTokenQuantity = ether(1); - }); - - async function subject(): Promise { - return navIssuanceModule.isRedeemValid(subjectSetToken, subjectReserveAsset, subjectSetTokenQuantity); - } - - it("should return true", async () => { - const returnedValue = await subject(); - expect(returnedValue).to.eq(true); - }); - - describe("when total supply is less than min required for NAV issuance", async () => { - beforeEach(async () => { - // Redeem below required - await setup.issuanceModule.connect(owner.wallet).redeem(setToken.address, ether(9), owner.address); - subjectSetTokenQuantity = ether(0.01); - }); - - it("returns false", async () => { - const returnedValue = await subject(); - expect(returnedValue).to.eq(false); - }); - }); - - describe("when there isn't sufficient reserve asset for withdraw", async () => { - beforeEach(async () => { - // Add self as module and update the position state - await setup.controller.addModule(owner.address); - setToken = setToken.connect(owner.wallet); - await setToken.addModule(owner.address); - await setToken.initializeModule(); - - // Remove USDC position - await setToken.editDefaultPositionUnit(setup.usdc.address, ZERO); - - subjectSetTokenQuantity = ether(1); - }); - - it("returns false", async () => { - const returnedValue = await subject(); - expect(returnedValue).to.eq(false); - }); - }); - - describe("when the redeem quantity is 0", async () => { - beforeEach(async () => { - subjectSetTokenQuantity = ZERO; - }); - - it("returns false", async () => { - const returnedValue = await subject(); - expect(returnedValue).to.eq(false); - }); - }); - - describe("when the reserve asset is not valid", async () => { - beforeEach(async () => { - await setup.wbtc.approve(setup.controller.address, bitcoin(1000000)); - subjectReserveAsset = setup.wbtc.address; - }); - - it("returns false", async () => { - const returnedValue = await subject(); - expect(returnedValue).to.eq(false); - }); - }); - }); - - describe("#issue", async () => { - let setToken: SetToken; - - let subjectSetToken: Address; - let subjectReserveAsset: Address; - let subjectReserveQuantity: BigNumber; - let subjectMinSetTokenReceived: BigNumber; - let subjectTo: Account; - let subjectCaller: Account; - - let navIssuanceSettings: NAVIssuanceSettings; - let managerIssuanceHook: Address; - let managerFees: BigNumber[]; - let premiumPercentage: BigNumber; - let units: BigNumber[]; - let issueQuantity: BigNumber; - - context("when there are 4 components and reserve asset is USDC", async () => { - const initializeContracts = async () => { - // Valued at 2000 USDC - units = [ether(1), usdc(270), bitcoin(1).div(10), ether(600)]; - setToken = await setup.createSetToken( - [setup.weth.address, setup.usdc.address, setup.wbtc.address, setup.dai.address], - units, // Set is valued at 2000 USDC - [setup.issuanceModule.address, navIssuanceModule.address] - ); - - const managerRedemptionHook = await getRandomAddress(); - const reserveAssets = [setup.usdc.address, setup.weth.address]; - const managerFeeRecipient = feeRecipient.address; - // Set max managerFee to 20% - const maxManagerFee = ether(0.2); - // Set max premium to 10% - const maxPremiumPercentage = ether(0.1); - // Set min SetToken supply required - const minSetTokenSupply = ether(1); - - navIssuanceSettings = { - managerIssuanceHook, - managerRedemptionHook, - reserveAssets, - feeRecipient: managerFeeRecipient, - managerFees, - maxManagerFee, - premiumPercentage, - maxPremiumPercentage, - minSetTokenSupply, - } as NAVIssuanceSettings; - - await navIssuanceModule.initialize(setToken.address, navIssuanceSettings); - // Approve tokens to the controller - await setup.weth.approve(setup.controller.address, ether(100)); - await setup.usdc.approve(setup.controller.address, usdc(1000000)); - await setup.wbtc.approve(setup.controller.address, bitcoin(1000000)); - await setup.dai.approve(setup.controller.address, ether(1000000)); - - // Seed with 2 supply - await setup.issuanceModule.connect(owner.wallet).initialize(setToken.address, ADDRESS_ZERO); - await setup.issuanceModule.connect(owner.wallet).issue(setToken.address, ether(2), owner.address); - - // Issue with 1k USDC - issueQuantity = usdc(1000); - - await setup.usdc.approve(navIssuanceModule.address, issueQuantity); - }; - - const initializeSubjectVariables = () => { - subjectSetToken = setToken.address; - subjectReserveAsset = setup.usdc.address; - subjectReserveQuantity = issueQuantity; - subjectMinSetTokenReceived = ether(0); - subjectTo = recipient; - subjectCaller = owner; - }; - - context("when there are no fees and no issuance hooks", async () => { - before(async () => { - managerIssuanceHook = ADDRESS_ZERO; - // Set fees to 0 - managerFees = [ether(0), ether(0)]; - // Set premium percentage to 50 bps - premiumPercentage = ether(0.005); - }); - - cacheBeforeEach(initializeContracts); - beforeEach(initializeSubjectVariables); - - async function subject(): Promise { - return navIssuanceModule.connect(subjectCaller.wallet).issue( - subjectSetToken, - subjectReserveAsset, - subjectReserveQuantity, - subjectMinSetTokenReceived, - subjectTo.address - ); - } - - it("should issue the Set to the recipient", async () => { - const expectedSetTokenIssueQuantity = await getExpectedSetTokenIssueQuantity( - setToken, - setup.setValuer, - subjectReserveAsset, - usdc(1), // USDC base units 10^6 - subjectReserveQuantity, - managerFees[0], - ZERO, // Protocol direct fee - premiumPercentage - ); - - await subject(); - - const issuedBalance = await setToken.balanceOf(recipient.address); - expect(issuedBalance).to.eq(expectedSetTokenIssueQuantity); - }); - - it("should have deposited the reserve asset into the SetToken", async () => { - const preIssueUSDCBalance = await setup.usdc.balanceOf(setToken.address); - - await subject(); - - const postIssueUSDCBalance = await setup.usdc.balanceOf(setToken.address); - const expectedUSDCBalance = preIssueUSDCBalance.add(issueQuantity); - expect(postIssueUSDCBalance).to.eq(expectedUSDCBalance); - }); - - it("should have updated the reserve asset position correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const defaultPositionUnit = await setToken.getDefaultPositionRealUnit(subjectReserveAsset); - - // (Previous supply * previous units + current units) / current supply - const newPositionMultiplier = await setToken.positionMultiplier(); - const expectedPositionUnit = getExpectedIssuePositionUnit( - units[1], - issueQuantity, - previousSetTokenSupply, - currentSetTokenSupply, - newPositionMultiplier, - managerFees[0], - ZERO // Protocol fee percentage - ); - - expect(defaultPositionUnit).to.eq(expectedPositionUnit); - }); - - it("should have updated the position multiplier correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - const preIssuePositionMultiplier = await setToken.positionMultiplier(); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const postIssuePositionMultiplier = await setToken.positionMultiplier(); - - const expectedPositionMultiplier = getExpectedIssuePositionMultiplier( - preIssuePositionMultiplier, - previousSetTokenSupply, - currentSetTokenSupply - ); - expect(postIssuePositionMultiplier).to.eq(expectedPositionMultiplier); - }); - - it("should emit the SetTokenNAVIssued event", async () => { - const expectedSetTokenIssued = await navIssuanceModule.getExpectedSetTokenIssueQuantity( - subjectSetToken, - subjectReserveAsset, - subjectReserveQuantity - ); - await expect(subject()).to.emit(navIssuanceModule, "SetTokenNAVIssued").withArgs( - subjectSetToken, - subjectCaller.address, - subjectTo.address, - subjectReserveAsset, - ADDRESS_ZERO, - expectedSetTokenIssued, - ZERO, - ZERO - ); - }); - - it("should reconcile balances", async () => { - await reconcileBalances(setToken, subject, owner); - }); - - describe("when the issue quantity is extremely small", async () => { - beforeEach(async () => { - subjectReserveQuantity = ONE; - }); - - it("should issue the Set to the recipient", async () => { - const expectedSetTokenIssueQuantity = await getExpectedSetTokenIssueQuantity( - setToken, - setup.setValuer, - subjectReserveAsset, - usdc(1), // USDC base units 10^6 - subjectReserveQuantity, - managerFees[0], - ZERO, // Protocol direct fee - premiumPercentage - ); - - await subject(); - - const issuedBalance = await setToken.balanceOf(recipient.address); - - expect(issuedBalance).to.eq(expectedSetTokenIssueQuantity); - }); - - it("should have deposited the reserve asset into the SetToken", async () => { - const preIssueUSDCBalance = await setup.usdc.balanceOf(setToken.address); - - await subject(); - - const postIssueUSDCBalance = await setup.usdc.balanceOf(setToken.address); - const expectedUSDCBalance = preIssueUSDCBalance.add(subjectReserveQuantity); - - expect(postIssueUSDCBalance).to.eq(expectedUSDCBalance); - }); - - it("should have updated the reserve asset position correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const usdcPositionUnit = await setToken.getDefaultPositionRealUnit(subjectReserveAsset); - - // (Previous supply * previous units + current units) / current supply - const newPositionMultiplier = await setToken.positionMultiplier(); - const expectedPositionUnit = getExpectedIssuePositionUnit( - units[1], - subjectReserveQuantity, - previousSetTokenSupply, - currentSetTokenSupply, - newPositionMultiplier, - managerFees[0], - ZERO // Protocol fee percentage - ); - - expect(usdcPositionUnit).to.eq(expectedPositionUnit); - }); - - it("should have updated the position multiplier correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - const preIssuePositionMultiplier = await setToken.positionMultiplier(); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const postIssuePositionMultiplier = await setToken.positionMultiplier(); - - const expectedPositionMultiplier = getExpectedIssuePositionMultiplier( - preIssuePositionMultiplier, - previousSetTokenSupply, - currentSetTokenSupply - ); - - expect(postIssuePositionMultiplier).to.eq(expectedPositionMultiplier); - }); - - it("should reconcile balances", async () => { - await reconcileBalances(setToken, subject, owner); - }); - }); - - describe("when a SetToken position is not in default state", async () => { - beforeEach(async () => { - // Add self as module and update the position state - await setup.controller.addModule(owner.address); - setToken = setToken.connect(owner.wallet); - await setToken.addModule(owner.address); - await setToken.initializeModule(); - - await setToken.addExternalPositionModule(setup.usdc.address, ADDRESS_ZERO); - - // Move default USDC to external position - await setToken.editDefaultPositionUnit(setup.usdc.address, ZERO); - await setToken.editExternalPositionUnit(setup.usdc.address, ADDRESS_ZERO, units[1]); - }); - - it("should have updated the reserve asset position correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const defaultUnit = await setToken.getDefaultPositionRealUnit(subjectReserveAsset); - - // (Previous supply * previous units + current units) / current supply - const newPositionMultiplier = await setToken.positionMultiplier(); - const expectedPositionUnit = getExpectedIssuePositionUnit( - ZERO, // Previous units are 0 - subjectReserveQuantity, - previousSetTokenSupply, - currentSetTokenSupply, - newPositionMultiplier, - managerFees[0], - ZERO // Protocol fee percentage - ); - - expect(defaultUnit).to.eq(expectedPositionUnit); - }); - - it("should have updated the position multiplier correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - const preIssuePositionMultiplier = await setToken.positionMultiplier(); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const postIssuePositionMultiplier = await setToken.positionMultiplier(); - - const expectedPositionMultiplier = getExpectedIssuePositionMultiplier( - preIssuePositionMultiplier, - previousSetTokenSupply, - currentSetTokenSupply - ); - expect(postIssuePositionMultiplier).to.eq(expectedPositionMultiplier); - }); - - it("should reconcile balances", async () => { - await reconcileBalances(setToken, subject, owner); - }); - }); - - describe("when total supply is less than min required for NAV issuance", async () => { - beforeEach(async () => { - // Redeem below required - await setup.issuanceModule.connect(owner.wallet).redeem(setToken.address, ether(1.5), owner.address); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Supply must be greater than minimum to enable issuance"); - }); - }); - - describe("when the issue quantity is 0", async () => { - beforeEach(async () => { - subjectReserveQuantity = ZERO; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Quantity must be > 0"); - }); - }); - - describe("when the reserve asset is not valid", async () => { - beforeEach(async () => { - await setup.wbtc.approve(setup.controller.address, bitcoin(1000000)); - subjectReserveAsset = setup.wbtc.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be valid reserve asset"); - }); - }); - - describe("when SetToken received is less than min required", async () => { - beforeEach(async () => { - subjectMinSetTokenReceived = ether(100); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be greater than min SetToken"); - }); - }); - - describe("when the SetToken is not enabled on the controller", async () => { - beforeEach(async () => { - const nonEnabledSetToken = await setup.createNonControllerEnabledSetToken( - [setup.weth.address], - [ether(1)], - [navIssuanceModule.address] - ); - - subjectSetToken = nonEnabledSetToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be a valid and initialized SetToken"); - }); - }); - }); - - context("when there are fees enabled and no issuance hooks", async () => { - let protocolDirectFee: BigNumber; - let protocolManagerFee: BigNumber; - - before(async () => { - managerIssuanceHook = ADDRESS_ZERO; - managerFees = [ether(0.1), ether(0.1)]; - premiumPercentage = ether(0.005); - }); - - cacheBeforeEach(initializeContracts); - - beforeEach(async () => { - initializeSubjectVariables(); - protocolDirectFee = ether(.02); - await setup.controller.addFee(navIssuanceModule.address, TWO, protocolDirectFee); - - protocolManagerFee = ether(.3); - await setup.controller.addFee(navIssuanceModule.address, ZERO, protocolManagerFee); - }); - - async function subject(): Promise { - return navIssuanceModule.connect(subjectCaller.wallet).issue( - subjectSetToken, - subjectReserveAsset, - subjectReserveQuantity, - subjectMinSetTokenReceived, - subjectTo.address - ); - } - - it("should issue the Set to the recipient", async () => { - const expectedSetTokenIssueQuantity = await getExpectedSetTokenIssueQuantity( - setToken, - setup.setValuer, - subjectReserveAsset, - usdc(1), // USDC base units 10^6 - subjectReserveQuantity, - managerFees[0], - protocolDirectFee, // Protocol direct fee - premiumPercentage - ); - await subject(); - - const issuedBalance = await setToken.balanceOf(recipient.address); - expect(issuedBalance).to.eq(expectedSetTokenIssueQuantity); - }); - - it("should have deposited the reserve asset into the SetToken", async () => { - const preIssueUSDCBalance = await setup.usdc.balanceOf(setToken.address); - - await subject(); - - const postIssueUSDCBalance = await setup.usdc.balanceOf(setToken.address); - - const postFeeQuantity = getExpectedPostFeeQuantity( - issueQuantity, - managerFees[0], - protocolDirectFee - ); - const expectedUSDCBalance = preIssueUSDCBalance.add(postFeeQuantity); - expect(postIssueUSDCBalance).to.eq(expectedUSDCBalance); - }); - - it("should have updated the reserve asset position correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const usdcPositionUnit = await setToken.getDefaultPositionRealUnit(subjectReserveAsset); - - // (Previous supply * previous units + current units) / current supply - const newPositionMultiplier = await setToken.positionMultiplier(); - const expectedPositionUnit = getExpectedIssuePositionUnit( - units[1], - issueQuantity, - previousSetTokenSupply, - currentSetTokenSupply, - newPositionMultiplier, - managerFees[0], - protocolDirectFee - ); - - expect(usdcPositionUnit).to.eq(expectedPositionUnit); - }); - - it("should have updated the position multiplier correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - const preIssuePositionMultiplier = await setToken.positionMultiplier(); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const postIssuePositionMultiplier = await setToken.positionMultiplier(); - - const expectedPositionMultiplier = getExpectedIssuePositionMultiplier( - preIssuePositionMultiplier, - previousSetTokenSupply, - currentSetTokenSupply - ); - expect(postIssuePositionMultiplier).to.eq(expectedPositionMultiplier); - }); - - it("should have properly distributed the fees", async () => { - const preIssuedManagerBalance = await setup.usdc.balanceOf(feeRecipient.address); - - const protocolFeeRecipientAddress = await setup.controller.feeRecipient(); - const preIssuedProtocolFeeRecipientBalance = await setup.usdc.balanceOf(protocolFeeRecipientAddress); - - await subject(); - - const postIssuedProtocolFeeRecipientBalance = await setup.usdc.balanceOf(protocolFeeRecipientAddress); - const protocolFeePercentage = preciseMul(managerFees[0], protocolManagerFee).add(protocolDirectFee); - const protocolFeeAmount = preciseMul(subjectReserveQuantity, protocolFeePercentage); - const expectedPostIssuanceBalance = preIssuedProtocolFeeRecipientBalance.add(protocolFeeAmount); - expect(postIssuedProtocolFeeRecipientBalance).to.eq(expectedPostIssuanceBalance); - - const postIssuedManagerBalance = await setup.usdc.balanceOf(feeRecipient.address); - const realizedManagerFeePercent = managerFees[0].sub(preciseMul(managerFees[0], protocolManagerFee)); - const managerFeeAmount = preciseMul(realizedManagerFeePercent, subjectReserveQuantity); - const expectedPostIssuanceManagerBalance = preIssuedManagerBalance.add(managerFeeAmount); - expect(postIssuedManagerBalance).to.eq(expectedPostIssuanceManagerBalance); - }); - - it("should reconcile balances", async () => { - await reconcileBalances(setToken, subject, owner); - }); - }); - - context("when there are fees, premiums and an issuance hooks", async () => { - let issuanceHookContract: NAVIssuanceHookMock; - - beforeEach(async () => { - managerIssuanceHook = ADDRESS_ZERO; - managerFees = [ether(0), ether(0)]; - premiumPercentage = ether(0.005); - - issuanceHookContract = await deployer.mocks.deployNavIssuanceHookMock(); - managerIssuanceHook = issuanceHookContract.address; - await initializeContracts(); - initializeSubjectVariables(); - }); - - async function subject(): Promise { - return navIssuanceModule.issue( - subjectSetToken, - subjectReserveAsset, - subjectReserveQuantity, - subjectMinSetTokenReceived, - subjectTo.address - ); - } - - it("should properly call the pre-issue hooks", async () => { - await subject(); - const retrievedSetToken = await issuanceHookContract.retrievedSetToken(); - const retrievedReserveAsset = await issuanceHookContract.retrievedReserveAsset(); - const retrievedReserveAssetQuantity = await issuanceHookContract.retrievedReserveAssetQuantity(); - const retrievedSender = await issuanceHookContract.retrievedSender(); - const retrievedTo = await issuanceHookContract.retrievedTo(); - - expect(retrievedSetToken).to.eq(subjectSetToken); - expect(retrievedReserveAsset).to.eq(subjectReserveAsset); - expect(retrievedReserveAssetQuantity).to.eq(subjectReserveQuantity); - expect(retrievedSender).to.eq(owner.address); - expect(retrievedTo).to.eq(subjectTo.address); - }); - }); - }); - }); - - describe("#issueWithEther", async () => { - let setToken: SetToken; - - let subjectSetToken: Address; - let subjectMinSetTokenReceived: BigNumber; - let subjectTo: Account; - let subjectCaller: Account; - let subjectValue: BigNumber; - - let navIssuanceSettings: NAVIssuanceSettings; - let managerIssuanceHook: Address; - let managerFees: BigNumber[]; - let premiumPercentage: BigNumber; - let units: BigNumber[]; - let issueQuantity: BigNumber; - - context("when there are 4 components and reserve asset is ETH", async () => { - const initializeContracts = async () => { - // Valued at 2000 USDC - units = [ether(1), usdc(270), bitcoin(1).div(10), ether(600)]; - setToken = await setup.createSetToken( - [setup.weth.address, setup.usdc.address, setup.wbtc.address, setup.dai.address], - units, // Set is valued at 2000 USDC - [setup.issuanceModule.address, navIssuanceModule.address] - ); - const managerRedemptionHook = await getRandomAddress(); - const reserveAssets = [setup.usdc.address, setup.weth.address]; - const managerFeeRecipient = feeRecipient.address; - // Set max managerFee to 20% - const maxManagerFee = ether(0.2); - // Set max premium to 10% - const maxPremiumPercentage = ether(0.1); - // Set min SetToken supply required - const minSetTokenSupply = ether(1); - - navIssuanceSettings = { - managerIssuanceHook, - managerRedemptionHook, - reserveAssets, - feeRecipient: managerFeeRecipient, - managerFees, - maxManagerFee, - premiumPercentage, - maxPremiumPercentage, - minSetTokenSupply, - } as NAVIssuanceSettings; - - await navIssuanceModule.initialize(setToken.address, navIssuanceSettings); - // Approve tokens to the controller - await setup.weth.approve(setup.controller.address, ether(100)); - await setup.usdc.approve(setup.controller.address, usdc(1000000)); - await setup.wbtc.approve(setup.controller.address, bitcoin(1000000)); - await setup.dai.approve(setup.controller.address, ether(1000000)); - - // Seed with 2 supply - await setup.issuanceModule.connect(owner.wallet).initialize(setToken.address, ADDRESS_ZERO); - await setup.issuanceModule.connect(owner.wallet).issue(setToken.address, ether(2), owner.address); - - // Issue with 1 ETH - issueQuantity = ether(0.1); - }; - - const initializeSubjectVariables = () => { - subjectSetToken = setToken.address; - subjectMinSetTokenReceived = ether(0); - subjectTo = recipient; - subjectValue = issueQuantity; - subjectCaller = owner; - }; - - context("when there are no fees and no issuance hooks", async () => { - before(async () => { - managerIssuanceHook = ADDRESS_ZERO; - // Set fees to 0 - managerFees = [ether(0), ether(0)]; - premiumPercentage = ether(0.005); - }); - - cacheBeforeEach(initializeContracts); - beforeEach(initializeSubjectVariables); - - async function subject(): Promise { - return navIssuanceModule.connect(subjectCaller.wallet).issueWithEther( - subjectSetToken, - subjectMinSetTokenReceived, - subjectTo.address, - { - value: subjectValue, - } - ); - } - - it("should issue the Set to the recipient", async () => { - const expectedSetTokenIssueQuantity = await getExpectedSetTokenIssueQuantity( - setToken, - setup.setValuer, - setup.weth.address, - ether(1), // ETH base units 10^18 - subjectValue, - managerFees[0], - ZERO, // Protocol direct fee - premiumPercentage - ); - await subject(); - - const issuedBalance = await setToken.balanceOf(recipient.address); - expect(issuedBalance).to.eq(expectedSetTokenIssueQuantity); - }); - - it("should have deposited WETH into the SetToken", async () => { - const preIssueWETHBalance = await setup.weth.balanceOf(setToken.address); - - await subject(); - - const postIssueWETHBalance = await setup.weth.balanceOf(setToken.address); - const expectedWETHBalance = preIssueWETHBalance.add(issueQuantity); - expect(postIssueWETHBalance).to.eq(expectedWETHBalance); - }); - - it("should have updated the reserve asset position correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const defaultPositionUnit = await setToken.getDefaultPositionRealUnit(setup.weth.address); - - const newPositionMultiplier = await setToken.positionMultiplier(); - const expectedPositionUnit = getExpectedIssuePositionUnit( - units[0], - issueQuantity, - previousSetTokenSupply, - currentSetTokenSupply, - newPositionMultiplier, - managerFees[0], - ZERO // Protocol fee percentage - ); - - expect(defaultPositionUnit).to.eq(expectedPositionUnit); - }); - - it("should have updated the position multiplier correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - const preIssuePositionMultiplier = await setToken.positionMultiplier(); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const postIssuePositionMultiplier = await setToken.positionMultiplier(); - - const expectedPositionMultiplier = getExpectedIssuePositionMultiplier( - preIssuePositionMultiplier, - previousSetTokenSupply, - currentSetTokenSupply - ); - expect(postIssuePositionMultiplier).to.eq(expectedPositionMultiplier); - }); - - it("should emit the SetTokenNAVIssued event", async () => { - const expectedSetTokenIssued = await navIssuanceModule.getExpectedSetTokenIssueQuantity( - subjectSetToken, - setup.weth.address, - subjectValue - ); - await expect(subject()).to.emit(navIssuanceModule, "SetTokenNAVIssued").withArgs( - subjectSetToken, - subjectCaller.address, - subjectTo.address, - setup.weth.address, - ADDRESS_ZERO, - expectedSetTokenIssued, - ZERO, - ZERO - ); - }); - - it("should reconcile balances", async () => { - await reconcileBalances(setToken, subject, owner); - }); - - describe("when a SetToken position is not in default state", async () => { - beforeEach(async () => { - // Add self as module and update the position state - await setup.controller.addModule(owner.address); - setToken = setToken.connect(owner.wallet); - await setToken.addModule(owner.address); - await setToken.initializeModule(); - - await setToken.addExternalPositionModule(setup.weth.address, ADDRESS_ZERO); - - // Move default WETH to external position - await setToken.editDefaultPositionUnit(setup.weth.address, ZERO); - await setToken.editExternalPositionUnit(setup.weth.address, ADDRESS_ZERO, units[0]); - }); - - it("should have updated the reserve asset position correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const defaultUnit = await setToken.getDefaultPositionRealUnit(setup.weth.address); - - // (Previous supply * previous units + current units) / current supply - const newPositionMultiplier = await setToken.positionMultiplier(); - const expectedPositionUnit = getExpectedIssuePositionUnit( - ZERO, // Previous units are 0 - subjectValue, - previousSetTokenSupply, - currentSetTokenSupply, - newPositionMultiplier, - managerFees[0], - ZERO // Protocol fee percentage - ); - - expect(defaultUnit).to.eq(expectedPositionUnit); - }); - - it("should have updated the position multiplier correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - const preIssuePositionMultiplier = await setToken.positionMultiplier(); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const postIssuePositionMultiplier = await setToken.positionMultiplier(); - - const expectedPositionMultiplier = getExpectedIssuePositionMultiplier( - preIssuePositionMultiplier, - previousSetTokenSupply, - currentSetTokenSupply - ); - expect(postIssuePositionMultiplier).to.eq(expectedPositionMultiplier); - }); - - it("should reconcile balances", async () => { - await reconcileBalances(setToken, subject, owner); - }); - }); - - describe("when total supply is less than min required for NAV issuance", async () => { - beforeEach(async () => { - // Redeem below required - await setup.issuanceModule.connect(owner.wallet).redeem(setToken.address, ether(1.5), owner.address); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Supply must be greater than minimum to enable issuance"); - }); - }); - - describe("when the value is 0", async () => { - beforeEach(async () => { - subjectValue = ZERO; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Quantity must be > 0"); - }); - }); - - describe("when SetToken received is less than minimum", async () => { - beforeEach(async () => { - subjectMinSetTokenReceived = ether(100); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be greater than min SetToken"); - }); - }); - - describe("when the SetToken is not enabled on the controller", async () => { - beforeEach(async () => { - const nonEnabledSetToken = await setup.createNonControllerEnabledSetToken( - [setup.weth.address], - [ether(1)], - [navIssuanceModule.address] - ); - - subjectSetToken = nonEnabledSetToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be a valid and initialized SetToken"); - }); - }); - }); - - context("when there are fees enabled and no issuance hooks", async () => { - let protocolDirectFee: BigNumber; - let protocolManagerFee: BigNumber; - - before(async () => { - managerIssuanceHook = ADDRESS_ZERO; - managerFees = [ether(0.1), ether(0.1)]; - premiumPercentage = ether(0.1); - }); - - cacheBeforeEach(initializeContracts); - beforeEach(initializeSubjectVariables); - - beforeEach(async () => { - protocolDirectFee = ether(.02); - await setup.controller.addFee(navIssuanceModule.address, TWO, protocolDirectFee); - - protocolManagerFee = ether(.3); - await setup.controller.addFee(navIssuanceModule.address, ZERO, protocolManagerFee); - }); - - async function subject(): Promise { - return navIssuanceModule.connect(subjectCaller.wallet).issueWithEther( - subjectSetToken, - subjectMinSetTokenReceived, - subjectTo.address, - { - value: subjectValue, - } - ); - } - - it("should issue the Set to the recipient", async () => { - const expectedSetTokenIssueQuantity = await getExpectedSetTokenIssueQuantity( - setToken, - setup.setValuer, - setup.weth.address, - ether(1), // ETH base units 10^18 - subjectValue, - managerFees[0], - protocolDirectFee, // Protocol direct fee - premiumPercentage - ); - - await subject(); - - const issuedBalance = await setToken.balanceOf(recipient.address); - expect(issuedBalance).to.eq(expectedSetTokenIssueQuantity); - }); - - it("should have deposited the reserve asset into the SetToken", async () => { - const preIssueWETHBalance = await setup.weth.balanceOf(setToken.address); - - await subject(); - - const postIssueWETHBalance = await setup.weth.balanceOf(setToken.address); - - const postFeeQuantity = getExpectedPostFeeQuantity( - issueQuantity, - managerFees[0], - protocolDirectFee - ); - const expectedWETHBalance = preIssueWETHBalance.add(postFeeQuantity); - expect(postIssueWETHBalance).to.eq(expectedWETHBalance); - }); - - it("should have updated the reserve asset position correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const wethPositionUnit = await setToken.getDefaultPositionRealUnit(setup.weth.address); - - // (Previous supply * previous units + current units) / current supply - const newPositionMultiplier = await setToken.positionMultiplier(); - const expectedPositionUnit = getExpectedIssuePositionUnit( - units[0], - issueQuantity, - previousSetTokenSupply, - currentSetTokenSupply, - newPositionMultiplier, - managerFees[0], - protocolDirectFee - ); - - expect(wethPositionUnit).to.eq(expectedPositionUnit); - }); - - it("should have updated the position multiplier correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - const preIssuePositionMultiplier = await setToken.positionMultiplier(); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const postIssuePositionMultiplier = await setToken.positionMultiplier(); - - const expectedPositionMultiplier = getExpectedIssuePositionMultiplier( - preIssuePositionMultiplier, - previousSetTokenSupply, - currentSetTokenSupply - ); - expect(postIssuePositionMultiplier).to.eq(expectedPositionMultiplier); - }); - - it("should have properly distributed the fees in WETH", async () => { - const preIssuedManagerBalance = await setup.weth.balanceOf(feeRecipient.address); - - const protocolFeeRecipientAddress = await setup.controller.feeRecipient(); - const preIssuedProtocolFeeRecipientBalance = await setup.weth.balanceOf(protocolFeeRecipientAddress); - - await subject(); - - const postIssuedProtocolFeeRecipientBalance = await setup.weth.balanceOf(protocolFeeRecipientAddress); - const protocolFeePercentage = preciseMul(managerFees[0], protocolManagerFee).add(protocolDirectFee); - const protocolFeeAmount = preciseMul(subjectValue, protocolFeePercentage); - const expectedPostIssuanceBalance = preIssuedProtocolFeeRecipientBalance.add(protocolFeeAmount); - expect(postIssuedProtocolFeeRecipientBalance).to.eq(expectedPostIssuanceBalance); - - const postIssuedManagerBalance = await setup.weth.balanceOf(feeRecipient.address); - const realizedManagerFeePercent = managerFees[0].sub(preciseMul(managerFees[0], protocolManagerFee)); - const managerFeeAmount = preciseMul(realizedManagerFeePercent, subjectValue); - const expectedPostIssuanceManagerBalance = preIssuedManagerBalance.add(managerFeeAmount); - expect(postIssuedManagerBalance).to.eq(expectedPostIssuanceManagerBalance); - }); - - it("should reconcile balances", async () => { - await reconcileBalances(setToken, subject, owner); - }); - }); - }); - }); - - describe("#redeem", async () => { - let setToken: SetToken; - - let subjectSetToken: Address; - let subjectReserveAsset: Address; - let subjectSetTokenQuantity: BigNumber; - let subjectMinReserveQuantityReceived: BigNumber; - let subjectTo: Account; - let subjectCaller: Account; - - let navIssuanceSettings: NAVIssuanceSettings; - let managerRedemptionHook: Address; - let managerFees: BigNumber[]; - let premiumPercentage: BigNumber; - let units: BigNumber[]; - let redeemQuantity: BigNumber; - - context("when there are 4 components and reserve asset is USDC", async () => { - const initializeContracts = async () => { - // Valued at 2000 USDC - units = [ether(1), usdc(570), bitcoin(1).div(10), ether(300)]; - setToken = await setup.createSetToken( - [setup.weth.address, setup.usdc.address, setup.wbtc.address, setup.dai.address], - units, // Set is valued at 2000 USDC - [setup.issuanceModule.address, navIssuanceModule.address] - ); - const managerIssuanceHook = await getRandomAddress(); - const reserveAssets = [setup.usdc.address, setup.weth.address]; - const managerFeeRecipient = feeRecipient.address; - // Set max managerFee to 20% - const maxManagerFee = ether(0.2); - // Set max premium to 10% - const maxPremiumPercentage = ether(0.1); - // Set min SetToken supply required - const minSetTokenSupply = ether(1); - - navIssuanceSettings = { - managerIssuanceHook, - managerRedemptionHook, - reserveAssets, - feeRecipient: managerFeeRecipient, - managerFees, - maxManagerFee, - premiumPercentage, - maxPremiumPercentage, - minSetTokenSupply, - } as NAVIssuanceSettings; - - await navIssuanceModule.initialize(setToken.address, navIssuanceSettings); - // Approve tokens to the controller - await setup.weth.approve(setup.controller.address, ether(100)); - await setup.usdc.approve(setup.controller.address, usdc(1000000)); - await setup.wbtc.approve(setup.controller.address, bitcoin(1000000)); - await setup.dai.approve(setup.controller.address, ether(1000000)); - - // Seed with 10 supply - await setup.issuanceModule.connect(owner.wallet).initialize(setToken.address, ADDRESS_ZERO); - await setup.issuanceModule.connect(owner.wallet).issue(setToken.address, ether(10), owner.address); - - // Redeem 1 SetToken - redeemQuantity = ether(2.8); - }; - - const initializeSubjectVariables = () => { - subjectSetToken = setToken.address; - subjectReserveAsset = setup.usdc.address; - subjectSetTokenQuantity = redeemQuantity; - subjectMinReserveQuantityReceived = ether(0); - subjectTo = recipient; - subjectCaller = owner; - }; - - context("when there are no fees and no redemption hooks", async () => { - before(async () => { - managerRedemptionHook = ADDRESS_ZERO; - // Set fees to 0 - managerFees = [ether(0), ether(0)]; - // Set premium percentage to 50 bps - premiumPercentage = ether(0.005); - }); - - cacheBeforeEach(initializeContracts); - beforeEach(initializeSubjectVariables); - - async function subject(): Promise { - return navIssuanceModule.connect(subjectCaller.wallet).redeem( - subjectSetToken, - subjectReserveAsset, - subjectSetTokenQuantity, - subjectMinReserveQuantityReceived, - subjectTo.address - ); - } - - it("should reduce the SetToken supply", async () => { - const previousSupply = await setToken.totalSupply(); - const preRedeemBalance = await setToken.balanceOf(owner.address); - - await subject(); - - const currentSupply = await setToken.totalSupply(); - const postRedeemBalance = await setToken.balanceOf(owner.address); - - expect(preRedeemBalance.sub(postRedeemBalance)).to.eq(previousSupply.sub(currentSupply)); - }); - - it("should have redeemed the reserve asset to the recipient", async () => { - const setTokenValuation = await setup.setValuer.calculateSetTokenValuation( - subjectSetToken, - subjectReserveAsset - ); - - await subject(); - - const postIssueUSDCBalance = await setup.usdc.balanceOf(recipient.address); - const expectedUSDCBalance = getExpectedReserveRedeemQuantity( - subjectSetTokenQuantity, - setTokenValuation, - usdc(1), // USDC base units - managerFees[1], - ZERO, // Protocol fee percentage - premiumPercentage - ); - expect(postIssueUSDCBalance).to.eq(expectedUSDCBalance); - }); - - it("should have updated the reserve asset position correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - const setTokenValuation = await setup.setValuer.calculateSetTokenValuation( - subjectSetToken, - subjectReserveAsset - ); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const defaultPositionUnit = await setToken.getDefaultPositionRealUnit(subjectReserveAsset); - - // (Previous supply * previous units + current units) / current supply - const newPositionMultiplier = await setToken.positionMultiplier(); - const expectedPositionUnit = getExpectedRedeemPositionUnit( - units[1], - redeemQuantity, - setTokenValuation, - usdc(1), // USDC base units - previousSetTokenSupply, - currentSetTokenSupply, - newPositionMultiplier, - managerFees[1], - ZERO, // Protocol fee percentage - premiumPercentage, - ); - - expect(defaultPositionUnit).to.eq(expectedPositionUnit); - }); - - it("should have updated the position multiplier correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - const preIssuePositionMultiplier = await setToken.positionMultiplier(); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const postIssuePositionMultiplier = await setToken.positionMultiplier(); - - const expectedPositionMultiplier = getExpectedRedeemPositionMultiplier( - preIssuePositionMultiplier, - previousSetTokenSupply, - currentSetTokenSupply - ); - expect(postIssuePositionMultiplier).to.eq(expectedPositionMultiplier); - }); - - it("should emit the SetTokenNAVRedeemed event", async () => { - await expect(subject()).to.emit(navIssuanceModule, "SetTokenNAVRedeemed").withArgs( - subjectSetToken, - subjectCaller.address, - subjectTo.address, - subjectReserveAsset, - ADDRESS_ZERO, - subjectSetTokenQuantity, - ZERO, - ZERO - ); - }); - - it("should reconcile balances", async () => { - await reconcileBalances(setToken, subject, owner); - }); - - describe("when the redeem quantity is extremely small", async () => { - beforeEach(async () => { - subjectSetTokenQuantity = ONE; - }); - - it("should reduce the SetToken supply", async () => { - const previousSupply = await setToken.totalSupply(); - const preRedeemBalance = await setToken.balanceOf(owner.address); - - await subject(); - - const currentSupply = await setToken.totalSupply(); - const postRedeemBalance = await setToken.balanceOf(owner.address); - - expect(preRedeemBalance.sub(postRedeemBalance)).to.eq(previousSupply.sub(currentSupply)); - }); - - it("should have redeemed the reserve asset to the recipient", async () => { - const setTokenValuation = await setup.setValuer.calculateSetTokenValuation( - subjectSetToken, - subjectReserveAsset - ); - - await subject(); - - const postIssueUSDCBalance = await setup.usdc.balanceOf(recipient.address); - const expectedUSDCBalance = getExpectedReserveRedeemQuantity( - subjectSetTokenQuantity, - setTokenValuation, - usdc(1), // USDC base units - managerFees[1], - ZERO, // Protocol fee percentage - premiumPercentage - ); - expect(postIssueUSDCBalance).to.eq(expectedUSDCBalance); - }); - - it("should have updated the reserve asset position correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - const setTokenValuation = await setup.setValuer.calculateSetTokenValuation( - subjectSetToken, - subjectReserveAsset - ); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const defaultPositionUnit = await setToken.getDefaultPositionRealUnit(subjectReserveAsset); - - // (Previous supply * previous units + current units) / current supply - const newPositionMultiplier = await setToken.positionMultiplier(); - const expectedPositionUnit = getExpectedRedeemPositionUnit( - units[1], - subjectSetTokenQuantity, - setTokenValuation, - usdc(1), // USDC base units - previousSetTokenSupply, - currentSetTokenSupply, - newPositionMultiplier, - managerFees[1], - ZERO, // Protocol fee percentage - premiumPercentage, - ); - expect(defaultPositionUnit).to.eq(expectedPositionUnit); - }); - - it("should have updated the position multiplier correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - const preIssuePositionMultiplier = await setToken.positionMultiplier(); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const postIssuePositionMultiplier = await setToken.positionMultiplier(); - - const expectedPositionMultiplier = getExpectedRedeemPositionMultiplier( - preIssuePositionMultiplier, - previousSetTokenSupply, - currentSetTokenSupply - ); - expect(postIssuePositionMultiplier).to.eq(expectedPositionMultiplier); - }); - - it("should reconcile balances", async () => { - await reconcileBalances(setToken, subject, owner); - }); - }); - - describe("when a SetToken position is not in default state", async () => { - beforeEach(async () => { - // Add self as module and update the position state - await setup.controller.addModule(owner.address); - setToken = setToken.connect(owner.wallet); - await setToken.addModule(owner.address); - await setToken.initializeModule(); - - await setToken.addExternalPositionModule(setup.usdc.address, ADDRESS_ZERO); - - // Convert half of default position to external position - await setToken.editDefaultPositionUnit(setup.usdc.address, units[1].div(2)); - await setToken.editExternalPositionUnit(setup.usdc.address, ADDRESS_ZERO, units[1].div(2)); - - subjectSetTokenQuantity = ether(0.1); - }); - - it("should have updated the reserve asset position correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - const setTokenValuation = await setup.setValuer.calculateSetTokenValuation( - subjectSetToken, - subjectReserveAsset - ); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const defaultPositionUnit = await setToken.getDefaultPositionRealUnit(subjectReserveAsset); - - // (Previous supply * previous units + current units) / current supply - const newPositionMultiplier = await setToken.positionMultiplier(); - const expectedPositionUnit = getExpectedRedeemPositionUnit( - units[1].div(2), - subjectSetTokenQuantity, - setTokenValuation, - usdc(1), // USDC base units - previousSetTokenSupply, - currentSetTokenSupply, - newPositionMultiplier, - managerFees[1], - ZERO, // Protocol fee percentage - premiumPercentage, - ); - - expect(defaultPositionUnit).to.eq(expectedPositionUnit); - }); - - it("should have updated the position multiplier correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - const preIssuePositionMultiplier = await setToken.positionMultiplier(); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const postIssuePositionMultiplier = await setToken.positionMultiplier(); - - const expectedPositionMultiplier = getExpectedRedeemPositionMultiplier( - preIssuePositionMultiplier, - previousSetTokenSupply, - currentSetTokenSupply - ); - expect(postIssuePositionMultiplier).to.eq(expectedPositionMultiplier); - }); - - it("should reconcile balances", async () => { - await reconcileBalances(setToken, subject, owner); - }); - }); - - describe("when total supply is less than min required for NAV issuance", async () => { - beforeEach(async () => { - // Redeem below required - await setup.issuanceModule.connect(owner.wallet).redeem(setToken.address, ether(9), owner.address); - subjectSetTokenQuantity = ether(0.01); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Supply must be greater than minimum to enable redemption"); - }); - }); - - describe("when there isn't sufficient reserve asset for withdraw", async () => { - beforeEach(async () => { - // Add self as module and update the position state - await setup.controller.addModule(owner.address); - setToken = setToken.connect(owner.wallet); - await setToken.addModule(owner.address); - await setToken.initializeModule(); - - // Remove USDC position - await setToken.editDefaultPositionUnit(setup.usdc.address, ZERO); - - subjectSetTokenQuantity = ether(1); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be greater than total available collateral"); - }); - }); - - describe("when the redeem quantity is 0", async () => { - beforeEach(async () => { - subjectSetTokenQuantity = ZERO; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Quantity must be > 0"); - }); - }); - - describe("when the reserve asset is not valid", async () => { - beforeEach(async () => { - await setup.wbtc.approve(setup.controller.address, bitcoin(1000000)); - subjectReserveAsset = setup.wbtc.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be valid reserve asset"); - }); - }); - - describe("when reserve asset received is less than min required", async () => { - beforeEach(async () => { - subjectMinReserveQuantityReceived = ether(100); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be greater than min receive reserve quantity"); - }); - }); - - describe("when the SetToken is not enabled on the controller", async () => { - beforeEach(async () => { - const nonEnabledSetToken = await setup.createNonControllerEnabledSetToken( - [setup.weth.address], - [ether(1)], - [navIssuanceModule.address] - ); - - subjectSetToken = nonEnabledSetToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be a valid and initialized SetToken"); - }); - }); - }); - - context("when there are fees enabled and no redemption hooks", async () => { - let protocolDirectFee: BigNumber; - let protocolManagerFee: BigNumber; - - before(async () => { - managerRedemptionHook = ADDRESS_ZERO; - managerFees = [ether(0.1), ether(0.1)]; - premiumPercentage = ether(0.005); - }); - - cacheBeforeEach(initializeContracts); - - beforeEach(async () => { - initializeSubjectVariables(); - protocolDirectFee = ether(.02); - await setup.controller.addFee(navIssuanceModule.address, THREE, protocolDirectFee); - - protocolManagerFee = ether(.3); - await setup.controller.addFee(navIssuanceModule.address, ONE, protocolManagerFee); - }); - - async function subject(): Promise { - return navIssuanceModule.connect(subjectCaller.wallet).redeem( - subjectSetToken, - subjectReserveAsset, - subjectSetTokenQuantity, - subjectMinReserveQuantityReceived, - subjectTo.address - ); - } - - it("should reduce the SetToken supply", async () => { - const previousSupply = await setToken.totalSupply(); - const preRedeemBalance = await setToken.balanceOf(owner.address); - await subject(); - const currentSupply = await setToken.totalSupply(); - const postRedeemBalance = await setToken.balanceOf(owner.address); - - expect(preRedeemBalance.sub(postRedeemBalance)).to.eq(previousSupply.sub(currentSupply)); - }); - - it("should have redeemed the reserve asset to the recipient", async () => { - const setTokenValuation = await setup.setValuer.calculateSetTokenValuation( - subjectSetToken, - subjectReserveAsset - ); - await subject(); - const postIssueUSDCBalance = await setup.usdc.balanceOf(recipient.address); - const expectedUSDCBalance = getExpectedReserveRedeemQuantity( - subjectSetTokenQuantity, - setTokenValuation, - usdc(1), // USDC base units - managerFees[1], - protocolDirectFee, // Protocol fee percentage - premiumPercentage - ); - expect(postIssueUSDCBalance).to.eq(expectedUSDCBalance); - }); - - it("should have updated the reserve asset position correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - const setTokenValuation = await setup.setValuer.calculateSetTokenValuation( - subjectSetToken, - subjectReserveAsset - ); - await subject(); - const currentSetTokenSupply = await setToken.totalSupply(); - const defaultPositionUnit = await setToken.getDefaultPositionRealUnit(subjectReserveAsset); - - // (Previous supply * previous units + current units) / current supply - const newPositionMultiplier = await setToken.positionMultiplier(); - const expectedPositionUnit = getExpectedRedeemPositionUnit( - units[1], - redeemQuantity, - setTokenValuation, - usdc(1), // USDC base units - previousSetTokenSupply, - currentSetTokenSupply, - newPositionMultiplier, - managerFees[1], - protocolDirectFee, // Protocol fee percentage - premiumPercentage, - ); - - expect(defaultPositionUnit).to.eq(expectedPositionUnit); - }); - - it("should have updated the position multiplier correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - const preIssuePositionMultiplier = await setToken.positionMultiplier(); - await subject(); - const currentSetTokenSupply = await setToken.totalSupply(); - const postIssuePositionMultiplier = await setToken.positionMultiplier(); - - const expectedPositionMultiplier = getExpectedRedeemPositionMultiplier( - preIssuePositionMultiplier, - previousSetTokenSupply, - currentSetTokenSupply - ); - expect(postIssuePositionMultiplier).to.eq(expectedPositionMultiplier); - }); - - it("should have properly distributed the fees", async () => { - // Get starting balance of reserve asset held by the SetToken - const preRedeemReserveAssetBalance = await setup.usdc.balanceOf(setToken.address); - - // Get starting balance of manager - const preRedeemManagerBalance = await setup.usdc.balanceOf(feeRecipient.address); - - // Get starting balance of the protocol fee recipient - const protocolFeeRecipientAddress = await setup.controller.feeRecipient(); - const preRedeemProtocolFeeRecipientBalance = await setup.usdc.balanceOf(protocolFeeRecipientAddress); - - await subject(); - - // Calculate the redeemed reserve asset amount - const postRedeemReserveAssetBalance = await setup.usdc.balanceOf(setToken.address); - const redeemedReserveAssetAmont = preRedeemReserveAssetBalance.sub(postRedeemReserveAssetBalance); - - // Calculate expected protocol fee from redeemed reserve asset amount - const postIssuedProtocolFeeRecipientBalance = await setup.usdc.balanceOf(protocolFeeRecipientAddress); - const protocolFeePercentage = preciseMul(managerFees[0], protocolManagerFee).add(protocolDirectFee); - const protocolFeeAmount = preciseMul(redeemedReserveAssetAmont, protocolFeePercentage); - const expectedPostRedeemBalance = preRedeemProtocolFeeRecipientBalance.add(protocolFeeAmount); - expect(postIssuedProtocolFeeRecipientBalance).to.eq(expectedPostRedeemBalance); - - // Calculate expected manager fee from redeemed reserve asset amount - const postIssuedManagerBalance = await setup.usdc.balanceOf(feeRecipient.address); - const realizedManagerFeePercent = managerFees[0].sub(preciseMul(managerFees[0], protocolManagerFee)); - const managerFeeAmount = preciseMul(realizedManagerFeePercent, redeemedReserveAssetAmont); - const expectedPostRedeemManagerBalance = preRedeemManagerBalance.add(managerFeeAmount); - expect(postIssuedManagerBalance).to.eq(expectedPostRedeemManagerBalance); - }); - - it("should reconcile balances", async () => { - await reconcileBalances(setToken, subject, owner); - }); - }); - - context("when there are fees, premiums and an redemption hook", async () => { - let issuanceHookContract: ManagerIssuanceHookMock; - - beforeEach(async () => { - managerFees = [ether(0), ether(0)]; - premiumPercentage = ether(0.005); - - issuanceHookContract = await deployer.mocks.deployManagerIssuanceHookMock(); - managerRedemptionHook = issuanceHookContract.address; - await initializeContracts(); - initializeSubjectVariables(); - }); - - async function subject(): Promise { - return navIssuanceModule.connect(subjectCaller.wallet).redeem( - subjectSetToken, - subjectReserveAsset, - subjectSetTokenQuantity, - subjectMinReserveQuantityReceived, - subjectTo.address - ); - } - - it("should properly call the pre-issue hooks", async () => { - await subject(); - - const retrievedSetToken = await issuanceHookContract.retrievedSetToken(); - const retrievedIssueQuantity = await issuanceHookContract.retrievedIssueQuantity(); - const retrievedSender = await issuanceHookContract.retrievedSender(); - const retrievedTo = await issuanceHookContract.retrievedTo(); - - expect(retrievedSetToken).to.eq(subjectSetToken); - expect(retrievedIssueQuantity).to.eq(subjectSetTokenQuantity); - expect(retrievedSender).to.eq(owner.address); - expect(retrievedTo).to.eq(subjectTo.address); - }); - }); - }); - }); - - describe("#redeemIntoEther", async () => { - let setToken: SetToken; - - let subjectSetToken: Address; - let subjectSetTokenQuantity: BigNumber; - let subjectMinReserveQuantityReceived: BigNumber; - let subjectTo: Account; - let subjectCaller: Account; - - let navIssuanceSettings: NAVIssuanceSettings; - let managerRedemptionHook: Address; - let managerFees: BigNumber[]; - let premiumPercentage: BigNumber; - let units: BigNumber[]; - let redeemQuantity: BigNumber; - - context("when there are 4 components and reserve asset is USDC", async () => { - const initializeContracts = async () => { - // Valued at 2000 USDC - units = [ether(1), usdc(270), bitcoin(1).div(10), ether(600)]; - setToken = await setup.createSetToken( - [setup.weth.address, setup.usdc.address, setup.wbtc.address, setup.dai.address], - units, // Set is valued at 2000 USDC - [setup.issuanceModule.address, navIssuanceModule.address] - ); - const managerIssuanceHook = await getRandomAddress(); - const reserveAssets = [setup.usdc.address, setup.weth.address]; - const managerFeeRecipient = feeRecipient.address; - // Set max managerFee to 20% - const maxManagerFee = ether(0.2); - // Set max premium to 10% - const maxPremiumPercentage = ether(0.1); - // Set min SetToken supply required - const minSetTokenSupply = ether(1); - - navIssuanceSettings = { - managerIssuanceHook, - managerRedemptionHook, - reserveAssets, - feeRecipient: managerFeeRecipient, - managerFees, - maxManagerFee, - premiumPercentage, - maxPremiumPercentage, - minSetTokenSupply, - } as NAVIssuanceSettings; - - await navIssuanceModule.initialize(setToken.address, navIssuanceSettings); - // Approve tokens to the controller - await setup.weth.approve(setup.controller.address, ether(100)); - await setup.usdc.approve(setup.controller.address, usdc(1000000)); - await setup.wbtc.approve(setup.controller.address, bitcoin(1000000)); - await setup.dai.approve(setup.controller.address, ether(1000000)); - - // Seed with 10 supply - await setup.issuanceModule.connect(owner.wallet).initialize(setToken.address, ADDRESS_ZERO); - await setup.issuanceModule.connect(owner.wallet).issue(setToken.address, ether(10), owner.address); - - // Redeem 1 SetToken - redeemQuantity = ether(1); - }; - - const initializeSubjectVariables = () => { - subjectSetToken = setToken.address; - subjectSetTokenQuantity = redeemQuantity; - subjectMinReserveQuantityReceived = ether(0); - subjectTo = recipient; - subjectCaller = owner; - }; - - context("when there are no fees and no redemption hooks", async () => { - before(async () => { - managerRedemptionHook = ADDRESS_ZERO; - // Set fees to 0 - managerFees = [ether(0), ether(0)]; - // Set premium percentage to 50 bps - premiumPercentage = ether(0.005); - }); - - cacheBeforeEach(initializeContracts); - beforeEach(initializeSubjectVariables); - - async function subject(): Promise { - return navIssuanceModule.connect(subjectCaller.wallet).redeemIntoEther( - subjectSetToken, - subjectSetTokenQuantity, - subjectMinReserveQuantityReceived, - subjectTo.address, - ); - } - - it("should reduce the SetToken supply", async () => { - const previousSupply = await setToken.totalSupply(); - const preRedeemBalance = await setToken.balanceOf(owner.address); - - await subject(); - - const currentSupply = await setToken.totalSupply(); - const postRedeemBalance = await setToken.balanceOf(owner.address); - - expect(preRedeemBalance.sub(postRedeemBalance)).to.eq(previousSupply.sub(currentSupply)); - }); - - it("should have redeemed the reserve asset to the recipient", async () => { - const provider = getProvider(); - const setTokenValuation = await setup.setValuer.calculateSetTokenValuation( - subjectSetToken, - setup.weth.address - ); - const preIssueETHBalance = await provider.getBalance(recipient.address); - - await subject(); - - const postIssueETHBalance = await provider.getBalance(recipient.address); - const expectedETHBalance = getExpectedReserveRedeemQuantity( - subjectSetTokenQuantity, - setTokenValuation, - ether(1), // ETH base units - managerFees[1], - ZERO, // Protocol fee percentage - premiumPercentage - ); - expect(postIssueETHBalance.sub(preIssueETHBalance)).to.eq(expectedETHBalance); - }); - - it("should have updated the reserve asset position correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - const setTokenValuation = await setup.setValuer.calculateSetTokenValuation( - subjectSetToken, - setup.weth.address - ); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const defaultPositionUnit = await setToken.getDefaultPositionRealUnit(setup.weth.address); - - const newPositionMultiplier = await setToken.positionMultiplier(); - const expectedPositionUnit = getExpectedRedeemPositionUnit( - units[0], - redeemQuantity, - setTokenValuation, - ether(1), // ETH base units - previousSetTokenSupply, - currentSetTokenSupply, - newPositionMultiplier, - managerFees[1], - ZERO, // Protocol fee percentage - premiumPercentage, - ); - - expect(defaultPositionUnit).to.eq(expectedPositionUnit); - }); - - it("should have updated the position multiplier correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - const preIssuePositionMultiplier = await setToken.positionMultiplier(); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const postIssuePositionMultiplier = await setToken.positionMultiplier(); - - const expectedPositionMultiplier = getExpectedRedeemPositionMultiplier( - preIssuePositionMultiplier, - previousSetTokenSupply, - currentSetTokenSupply - ); - expect(postIssuePositionMultiplier).to.eq(expectedPositionMultiplier); - }); - - it("should emit the SetTokenNAVRedeemed event", async () => { - await expect(subject()).to.emit(navIssuanceModule, "SetTokenNAVRedeemed").withArgs( - subjectSetToken, - subjectCaller.address, - subjectTo.address, - setup.weth.address, - ADDRESS_ZERO, - subjectSetTokenQuantity, - ZERO, - ZERO - ); - }); - - it("should reconcile balances", async () => { - await reconcileBalances(setToken, subject, owner); - }); - - describe("when total supply is less than min required for NAV issuance", async () => { - beforeEach(async () => { - // Redeem below required - await setup.issuanceModule.connect(owner.wallet).redeem(setToken.address, ether(9), owner.address); - subjectSetTokenQuantity = ether(0.01); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Supply must be greater than minimum to enable redemption"); - }); - }); - - describe("when there isn't sufficient reserve asset for withdraw", async () => { - beforeEach(async () => { - // Add self as module and update the position state - await setup.controller.addModule(owner.address); - setToken = setToken.connect(owner.wallet); - await setToken.addModule(owner.address); - await setToken.initializeModule(); - - // Remove WETH position - await setToken.editDefaultPositionUnit(setup.weth.address, ZERO); - - subjectSetTokenQuantity = ether(1); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be greater than total available collateral"); - }); - }); - - describe("when the redeem quantity is 0", async () => { - beforeEach(async () => { - subjectSetTokenQuantity = ZERO; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Quantity must be > 0"); - }); - }); - - describe("when reserve asset received is less than min required", async () => { - beforeEach(async () => { - subjectMinReserveQuantityReceived = ether(100); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be greater than min receive reserve quantity"); - }); - }); - - describe("when the SetToken is not enabled on the controller", async () => { - beforeEach(async () => { - const nonEnabledSetToken = await setup.createNonControllerEnabledSetToken( - [setup.weth.address], - [ether(1)], - [navIssuanceModule.address] - ); - - subjectSetToken = nonEnabledSetToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be a valid and initialized SetToken"); - }); - }); - }); - - context("when there are fees enabled and no redemption hooks", async () => { - let protocolDirectFee: BigNumber; - let protocolManagerFee: BigNumber; - - before(async () => { - managerRedemptionHook = ADDRESS_ZERO; - managerFees = [ether(0.1), ether(0.1)]; - premiumPercentage = ether(0.005); - }); - - cacheBeforeEach(initializeContracts); - - beforeEach(async () => { - initializeSubjectVariables(); - protocolDirectFee = ether(.02); - await setup.controller.addFee(navIssuanceModule.address, THREE, protocolDirectFee); - - protocolManagerFee = ether(.3); - await setup.controller.addFee(navIssuanceModule.address, ONE, protocolManagerFee); - }); - - async function subject(): Promise { - return navIssuanceModule.connect(subjectCaller.wallet).redeemIntoEther( - subjectSetToken, - subjectSetTokenQuantity, - subjectMinReserveQuantityReceived, - subjectTo.address, - ); - } - - it("should reduce the SetToken supply", async () => { - const previousSupply = await setToken.totalSupply(); - const preRedeemBalance = await setToken.balanceOf(owner.address); - - await subject(); - - const currentSupply = await setToken.totalSupply(); - const postRedeemBalance = await setToken.balanceOf(owner.address); - - expect(preRedeemBalance.sub(postRedeemBalance)).to.eq(previousSupply.sub(currentSupply)); - }); - - it("should have redeemed the reserve asset to the recipient", async () => { - const provider = getProvider(); - const setTokenValuation = await setup.setValuer.calculateSetTokenValuation( - subjectSetToken, - setup.weth.address - ); - const preIssueETHBalance = await provider.getBalance(recipient.address); - - await subject(); - - const postIssueETHBalance = await provider.getBalance(recipient.address); - const expectedETHBalance = getExpectedReserveRedeemQuantity( - subjectSetTokenQuantity, - setTokenValuation, - ether(1), // ETH base units - managerFees[1], - protocolDirectFee, // Protocol direct fee percentage - premiumPercentage - ); - expect(postIssueETHBalance.sub(preIssueETHBalance)).to.eq(expectedETHBalance); - }); - - it("should have updated the reserve asset position correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - const setTokenValuation = await setup.setValuer.calculateSetTokenValuation( - subjectSetToken, - setup.weth.address - ); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const defaultPositionUnit = await setToken.getDefaultPositionRealUnit(setup.weth.address); - - const newPositionMultiplier = await setToken.positionMultiplier(); - const expectedPositionUnit = getExpectedRedeemPositionUnit( - units[0], - redeemQuantity, - setTokenValuation, - ether(1), // ETH base units - previousSetTokenSupply, - currentSetTokenSupply, - newPositionMultiplier, - managerFees[1], - protocolDirectFee, // Protocol direct fee percentage - premiumPercentage, - ); - - expect(defaultPositionUnit).to.eq(expectedPositionUnit); - }); - - it("should have updated the position multiplier correctly", async () => { - const previousSetTokenSupply = await setToken.totalSupply(); - const preIssuePositionMultiplier = await setToken.positionMultiplier(); - - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const postIssuePositionMultiplier = await setToken.positionMultiplier(); - - const expectedPositionMultiplier = getExpectedRedeemPositionMultiplier( - preIssuePositionMultiplier, - previousSetTokenSupply, - currentSetTokenSupply - ); - expect(postIssuePositionMultiplier).to.eq(expectedPositionMultiplier); - }); - - it("should have properly distributed the fees in WETH", async () => { - // Get starting balance of reserve asset held by the SetToken - const preRedeemReserveAssetBalance = await setup.weth.balanceOf(setToken.address); - - // Get starting balance of manager - const preRedeemManagerBalance = await setup.weth.balanceOf(feeRecipient.address); - - // Get starting balance of the protocol fee recipient - const protocolFeeRecipientAddress = await setup.controller.feeRecipient(); - const preRedeemProtocolFeeRecipientBalance = await setup.weth.balanceOf(protocolFeeRecipientAddress); - - await subject(); - - // Calculate the redeemed reserve asset amount - const postRedeemReserveAssetBalance = await setup.weth.balanceOf(setToken.address); - const redeemedReserveAssetAmont = preRedeemReserveAssetBalance.sub(postRedeemReserveAssetBalance); - - // Calculate expected protocol fee from redeemed reserve asset amount - const postRedeemProtocolFeeRecipientBalance = await setup.weth.balanceOf(protocolFeeRecipientAddress); - const protocolFeePercentage = preciseMul(managerFees[0], protocolManagerFee).add(protocolDirectFee); - const protocolFeeAmount = preciseMul(redeemedReserveAssetAmont, protocolFeePercentage); - const expectedPostIssuanceBalance = preRedeemProtocolFeeRecipientBalance.add(protocolFeeAmount); - expect(postRedeemProtocolFeeRecipientBalance).to.eq(expectedPostIssuanceBalance); - - // Calculate expected manager fee from redeemed reserve asset amount - const postRedeemManagerBalance = await setup.weth.balanceOf(feeRecipient.address); - const realizedManagerFeePercent = managerFees[0].sub(preciseMul(managerFees[0], protocolManagerFee)); - const managerFeeAmount = preciseMul(realizedManagerFeePercent, redeemedReserveAssetAmont); - const expectedPostIssuanceManagerBalance = preRedeemManagerBalance.add(managerFeeAmount); - expect(postRedeemManagerBalance).to.eq(expectedPostIssuanceManagerBalance); - }); - - it("should reconcile balances", async () => { - await reconcileBalances(setToken, subject, owner); - }); - }); - }); - }); - - context("Manager admin functions", async () => { - let subjectSetToken: Address; - let subjectCaller: Account; - - let setToken: SetToken; - - cacheBeforeEach(async () => { - // Deploy a standard SetToken - setToken = await setup.createSetToken( - [setup.weth.address], - [ether(1)], - [navIssuanceModule.address] - ); - - const managerIssuanceHook = await getRandomAddress(); - const managerRedemptionHook = await getRandomAddress(); - const reserveAssets = [setup.weth.address, setup.usdc.address]; - const managerFeeRecipient = feeRecipient.address; - // Set manager issue fee to 0.1% and redeem to 0.2% - const managerFees = [ether(0.001), ether(0.002)]; - // Set max managerFee to 2% - const maxManagerFee = ether(0.02); - // Set premium to 1% - const premiumPercentage = ether(0.01); - // Set max premium to 10% - const maxPremiumPercentage = ether(0.1); - // Set min SetToken supply to 100 units - const minSetTokenSupply = ether(100); - - const navIssuanceSettings = { - managerIssuanceHook, - managerRedemptionHook, - reserveAssets, - feeRecipient: managerFeeRecipient, - managerFees, - maxManagerFee, - premiumPercentage, - maxPremiumPercentage, - minSetTokenSupply, - } as NAVIssuanceSettings; - - await navIssuanceModule.initialize( - setToken.address, - navIssuanceSettings - ); - - const protocolDirectFee = ether(.02); - await setup.controller.addFee(navIssuanceModule.address, TWO, protocolDirectFee); - - const protocolManagerFee = ether(.3); - await setup.controller.addFee(navIssuanceModule.address, ZERO, protocolManagerFee); - }); - - describe("#addReserveAsset", async () => { - let subjectReserveAsset: Address; - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectReserveAsset = setup.dai.address; - subjectCaller = owner; - }); - - async function subject(): Promise { - return navIssuanceModule.connect(subjectCaller.wallet).addReserveAsset(subjectSetToken, subjectReserveAsset); - } - - it("should add the reserve asset", async () => { - await subject(); - const isReserveAssetAdded = await navIssuanceModule.isReserveAsset(subjectSetToken, subjectReserveAsset); - const reserveAssets = await navIssuanceModule.getReserveAssets(subjectSetToken); - expect(isReserveAssetAdded).to.eq(true); - expect(reserveAssets.length).to.eq(3); - }); - - it("should emit correct ReserveAssetAdded event", async () => { - await expect(subject()).to.emit(navIssuanceModule, "ReserveAssetAdded").withArgs( - subjectSetToken, - subjectReserveAsset - ); - }); - - shouldRevertIfTheCallerIsNotTheManager(subject); - shouldRevertIfSetTokenIsInvalid(subject); - shouldRevertIfModuleDisabled(subject); - - describe("when the reserve asset exists", async () => { - beforeEach(async () => { - subjectReserveAsset = setup.weth.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Reserve asset already exists"); - }); - }); - }); - - describe("#removeReserveAsset", async () => { - let subjectReserveAsset: Address; - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectReserveAsset = setup.usdc.address; - subjectCaller = owner; - }); - - async function subject(): Promise { - return navIssuanceModule.connect(subjectCaller.wallet).removeReserveAsset(subjectSetToken, subjectReserveAsset); - } - - it("should remove the reserve asset", async () => { - await subject(); - const isReserveAsset = await navIssuanceModule.isReserveAsset(subjectSetToken, subjectReserveAsset); - const reserveAssets = await navIssuanceModule.getReserveAssets(subjectSetToken); - - expect(isReserveAsset).to.eq(false); - expect(JSON.stringify(reserveAssets)).to.eq(JSON.stringify([setup.weth.address])); - }); - - it("should emit correct ReserveAssetRemoved event", async () => { - await expect(subject()).to.emit(navIssuanceModule, "ReserveAssetRemoved").withArgs( - subjectSetToken, - subjectReserveAsset - ); - }); - - shouldRevertIfTheCallerIsNotTheManager(subject); - shouldRevertIfSetTokenIsInvalid(subject); - shouldRevertIfModuleDisabled(subject); - - describe("when the reserve asset does not exist", async () => { - beforeEach(async () => { - subjectReserveAsset = setup.wbtc.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Reserve asset does not exist"); - }); - }); - }); - - describe("#editPremium", async () => { - let subjectPremium: BigNumber; - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectPremium = ether(0.02); - subjectCaller = owner; - }); - - async function subject(): Promise { - return navIssuanceModule.connect(subjectCaller.wallet).editPremium(subjectSetToken, subjectPremium); - } - - it("should edit the premium", async () => { - await subject(); - const retrievedPremium = await navIssuanceModule.getIssuePremium(subjectSetToken, ADDRESS_ZERO, ZERO); - expect(retrievedPremium).to.eq(subjectPremium); - }); - - it("should emit correct PremiumEdited event", async () => { - await expect(subject()).to.emit(navIssuanceModule, "PremiumEdited").withArgs( - subjectSetToken, - subjectPremium - ); - }); - - shouldRevertIfTheCallerIsNotTheManager(subject); - shouldRevertIfSetTokenIsInvalid(subject); - shouldRevertIfModuleDisabled(subject); - - describe("when the premium is greater than maximum allowed", async () => { - beforeEach(async () => { - subjectPremium = ether(1); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Premium must be less than maximum allowed"); - }); - }); - }); - - describe("#editManagerFee", async () => { - let subjectManagerFee: BigNumber; - let subjectFeeIndex: BigNumber; - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectManagerFee = ether(0.01); - subjectFeeIndex = ZERO; - subjectCaller = owner; - }); - - async function subject(): Promise { - return navIssuanceModule.connect(subjectCaller.wallet).editManagerFee(subjectSetToken, subjectManagerFee, subjectFeeIndex); - } - - it("should edit the manager issue fee", async () => { - await subject(); - const managerIssueFee = await navIssuanceModule.getManagerFee(subjectSetToken, subjectFeeIndex); - - expect(managerIssueFee).to.eq(subjectManagerFee); - }); - - it("should emit correct ManagerFeeEdited event", async () => { - await expect(subject()).to.emit(navIssuanceModule, "ManagerFeeEdited").withArgs( - subjectSetToken, - subjectManagerFee, - subjectFeeIndex - ); - }); - - describe("when editing the redeem fee", async () => { - beforeEach(async () => { - subjectManagerFee = ether(0.002); - subjectFeeIndex = ONE; - }); - - it("should edit the manager redeem fee", async () => { - await subject(); - const managerRedeemFee = await navIssuanceModule.getManagerFee(subjectSetToken, subjectFeeIndex); - - expect(managerRedeemFee).to.eq(subjectManagerFee); - }); - }); - - shouldRevertIfTheCallerIsNotTheManager(subject); - shouldRevertIfSetTokenIsInvalid(subject); - shouldRevertIfModuleDisabled(subject); - - describe("when the manager fee is greater than maximum allowed", async () => { - beforeEach(async () => { - subjectManagerFee = ether(1); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Manager fee must be less than maximum allowed"); - }); - }); - }); - - describe("#editFeeRecipient", async () => { - let subjectFeeRecipient: Address; - - beforeEach(async () => { - subjectSetToken = setToken.address; - subjectFeeRecipient = feeRecipient.address; - subjectCaller = owner; - }); - - async function subject(): Promise { - return navIssuanceModule.connect(subjectCaller.wallet).editFeeRecipient(subjectSetToken, subjectFeeRecipient); - } - - it("should edit the manager fee recipient", async () => { - await subject(); - const navIssuanceSettings = await navIssuanceModule.navIssuanceSettings(subjectSetToken); - expect(navIssuanceSettings.feeRecipient).to.eq(subjectFeeRecipient); - }); - - it("should emit correct FeeRecipientEdited event", async () => { - await expect(subject()).to.emit(navIssuanceModule, "FeeRecipientEdited").withArgs( - subjectSetToken, - subjectFeeRecipient - ); - }); - - shouldRevertIfTheCallerIsNotTheManager(subject); - shouldRevertIfSetTokenIsInvalid(subject); - shouldRevertIfModuleDisabled(subject); - - describe("when the manager fee is greater than maximum allowed", async () => { - beforeEach(async () => { - subjectFeeRecipient = ADDRESS_ZERO; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Fee recipient must not be 0 address"); - }); - }); - }); - - function shouldRevertIfTheCallerIsNotTheManager(subject: any) { - describe("when the caller is not the manager", async () => { - beforeEach(async () => { - subjectCaller = await getRandomAccount(); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be the SetToken manager"); - }); - }); - } - - function shouldRevertIfSetTokenIsInvalid(subject: any) { - describe("when the SetToken is not enabled on the controller", async () => { - beforeEach(async () => { - const nonEnabledSetToken = await setup.createNonControllerEnabledSetToken( - [setup.weth.address], - [ether(1)], - [navIssuanceModule.address] - ); - - subjectSetToken = nonEnabledSetToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be a valid and initialized SetToken"); - }); - }); - } - - function shouldRevertIfModuleDisabled(subject: any) { - describe("when the module is disabled", async () => { - beforeEach(async () => { - await setToken.removeModule(navIssuanceModule.address); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be a valid and initialized SetToken"); - }); - }); - } - }); -}); - -async function reconcileBalances(setToken: SetToken, subject: any, signer: Account): Promise { - await subject(); - - const currentSetTokenSupply = await setToken.totalSupply(); - const components = await setToken.getComponents(); - for (let i = 0; i < components.length; i++) { - const component = ERC20__factory.connect(components[i], signer.wallet); - const defaultPositionUnit = await setToken.getDefaultPositionRealUnit(component.address); - - const expectedBalance = preciseMul(defaultPositionUnit, currentSetTokenSupply); - const actualBalance = await component.balanceOf(setToken.address); - - expect(actualBalance).to.be.gte(expectedBalance); - } -} diff --git a/test/protocol/modules/perpV2LeverageModule.spec.ts b/test/protocol/modules/perpV2LeverageModule.spec.ts deleted file mode 100644 index 966c80c5b..000000000 --- a/test/protocol/modules/perpV2LeverageModule.spec.ts +++ /dev/null @@ -1,6045 +0,0 @@ -import "module-alias/register"; - -import { Address } from "@utils/types"; -import { Account } from "@utils/test/types"; -import { - PerpV2, - PerpV2LeverageModule, - DebtIssuanceMock, - StandardTokenMock, - SetToken -} from "@utils/contracts"; - -import { PerpV2BaseToken } from "@utils/contracts/perpV2"; - -import DeployHelper from "@utils/deploys"; -import { - ether, - bitcoin, - usdc as usdcUnits, - preciseDiv, - preciseMul -} from "@utils/index"; - -import { - calculateExternalPositionUnit, - calculateUSDCTransferIn, - calculateUSDCTransferOut, - calculateUSDCTransferInPreciseUnits, - calculateUSDCTransferOutPreciseUnits, - getUSDCDeltaDueToFundingGrowth, - leverUp, - toUSDCDecimals, -} from "@utils/common"; - -import { - cacheBeforeEach, - getAccounts, - getWaffleExpect, - getSystemFixture, - getPerpV2Fixture, - getRandomAccount, - getRandomAddress, - increaseTimeAsync -} from "@utils/test/index"; - -import { PerpV2Fixture, SystemFixture } from "@utils/fixtures"; -import { ADDRESS_ZERO, ZERO, ZERO_BYTES, MAX_UINT_256, ONE_DAY_IN_SECONDS, ONE, TWO, THREE } from "@utils/constants"; -import { BigNumber } from "ethers"; - -const expect = getWaffleExpect(); - -describe("PerpV2LeverageModule", () => { - let owner: Account; - let maker: Account; - let otherTrader: Account; - let mockModule: Account; - let deployer: DeployHelper; - - let perpLib: PerpV2; - let perpLeverageModule: PerpV2LeverageModule; - let debtIssuanceMock: DebtIssuanceMock; - let setup: SystemFixture; - let perpSetup: PerpV2Fixture; - let maxPerpPositionsPerSet: BigNumber; - - let vETH: PerpV2BaseToken; - let vBTC: PerpV2BaseToken; - let usdc: StandardTokenMock; - - cacheBeforeEach(async () => { - [ - owner, - maker, - otherTrader, - mockModule, - ] = await getAccounts(); - - deployer = new DeployHelper(owner.wallet); - setup = getSystemFixture(owner.address); - await setup.initialize(); - - perpSetup = getPerpV2Fixture(owner.address); - await perpSetup.initialize(maker, otherTrader); - - // set funding rate to zero; allows us to avoid calculating small amounts of funding - // accrued in our test cases - await perpSetup.clearingHouseConfig.setMaxFundingRate(ZERO); - - vETH = perpSetup.vETH; - vBTC = perpSetup.vBTC; - usdc = perpSetup.usdc; - - // Create liquidity - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(10)); - await perpSetup.initializePoolWithLiquidityWide( - vETH, - ether(10_000), - ether(100_000) - ); - - await perpSetup.setBaseTokenOraclePrice(vBTC, usdcUnits(20)); - await perpSetup.initializePoolWithLiquidityWide( - vBTC, - ether(10_000), - ether(200_000) - ); - - debtIssuanceMock = await deployer.mocks.deployDebtIssuanceMock(); - await setup.controller.addModule(debtIssuanceMock.address); - - maxPerpPositionsPerSet = TWO; - perpLib = await deployer.libraries.deployPerpV2(); - perpLeverageModule = await deployer.modules.deployPerpV2LeverageModule( - setup.controller.address, - perpSetup.vault.address, - perpSetup.quoter.address, - perpSetup.marketRegistry.address, - maxPerpPositionsPerSet, - "contracts/protocol/integration/lib/PerpV2.sol:PerpV2", - perpLib.address - ); - await setup.controller.addModule(perpLeverageModule.address); - - await setup.integrationRegistry.addIntegration( - perpLeverageModule.address, - "DefaultIssuanceModule", - debtIssuanceMock.address - ); - }); - - /** - * HELPERS - */ - - // Creates SetToken, issues sets (default: 1), initializes PerpV2LeverageModule and deposits to Perp - async function issueSetsAndDepositToPerp( - depositQuantityUnit: BigNumber, - isInitialized: boolean = true, - issueQuantity: BigNumber = ether(1), - skipMockModuleInitialization = false - ): Promise { - const setToken = await setup.createSetToken( - [setup.wbtc.address, usdc.address, setup.weth.address], - [bitcoin(10), usdcUnits(100), ether(10)], - [perpLeverageModule.address, debtIssuanceMock.address, setup.issuanceModule.address] - ); - - if (isInitialized) { - await debtIssuanceMock.initialize(setToken.address); - await perpLeverageModule.updateAllowedSetToken(setToken.address, true); - - await perpLeverageModule.connect(owner.wallet).initialize(setToken.address); - - // Initialize mock module - if (!skipMockModuleInitialization) { - await setup.controller.addModule(mockModule.address); - await setToken.addModule(mockModule.address); - await setToken.connect(mockModule.wallet).initializeModule(); - } - - await usdc.approve(setup.issuanceModule.address, preciseMul(usdcUnits(100), issueQuantity)); - await setup.issuanceModule.initialize(setToken.address, ADDRESS_ZERO); - await setup.issuanceModule.issue(setToken.address, issueQuantity, owner.address); - - await perpLeverageModule.deposit(setToken.address, depositQuantityUnit); - } - - return setToken; - } - - async function syncOracleToSpot(baseToken: PerpV2BaseToken): Promise { - const baseTokenSpotPrice = await perpSetup.getSpotPrice(baseToken.address); - await perpSetup.setBaseTokenOraclePrice(baseToken, baseTokenSpotPrice.div(10 ** 12)); - } - - describe("#constructor", async () => { - let subjectController: Address; - let subjectVault: Address; - let subjectQuoter: Address; - let subjectMarketRegistry: Address; - let subjectMaxPerpPositionsPerSet: BigNumber; - - beforeEach(async () => { - subjectController = setup.controller.address; - subjectVault = perpSetup.vault.address; - subjectQuoter = perpSetup.quoter.address; - subjectMarketRegistry = perpSetup.marketRegistry.address; - subjectMaxPerpPositionsPerSet = ONE; - }); - - async function subject(): Promise { - return deployer.modules.deployPerpV2LeverageModule( - subjectController, - subjectVault, - subjectQuoter, - subjectMarketRegistry, - subjectMaxPerpPositionsPerSet, - "contracts/protocol/integration/lib/PerpV2.sol:PerpV2", - perpLib.address - ); - } - - it("should set the correct controller", async () => { - const perpLeverageModule = await subject(); - - const controller = await perpLeverageModule.controller(); - expect(controller).to.eq(subjectController); - }); - - it("should set the correct PerpV2 contracts and collateralToken", async () => { - const perpLeverageModule = await subject(); - - const perpAccountBalance = await perpLeverageModule.perpAccountBalance(); - const perpClearingHouse = await perpLeverageModule.perpClearingHouse(); - const perpExchange = await perpLeverageModule.perpExchange(); - const perpVault = await perpLeverageModule.perpVault(); - const perpQuoter = await perpLeverageModule.perpQuoter(); - const perpMarketRegistry = await perpLeverageModule.perpMarketRegistry(); - const collateralToken = await perpLeverageModule.collateralToken(); - - expect(perpAccountBalance).to.eq(perpSetup.accountBalance.address); - expect(perpClearingHouse).to.eq(perpSetup.clearingHouse.address); - expect(perpExchange).to.eq(perpSetup.exchange.address); - expect(perpVault).to.eq(perpSetup.vault.address); - expect(perpQuoter).to.eq(perpSetup.quoter.address); - expect(perpMarketRegistry).to.eq(perpSetup.marketRegistry.address); - expect(collateralToken).to.eq(perpSetup.usdc.address); - }); - - it("should set the correct max perp positions per Set", async () => { - const perpLeverageModule = await subject(); - - const maxPerpPositionsPerSet = await perpLeverageModule.maxPerpPositionsPerSet(); - - expect(maxPerpPositionsPerSet).to.eq(ONE); - }); - }); - - describe("#initialize", async () => { - let setToken: SetToken; - let isAllowListed: boolean; - let subjectSetToken: Address; - let subjectCaller: Account; - - const initializeContracts = async () => { - setToken = await setup.createSetToken( - [usdc.address], - [ether(100)], - [perpLeverageModule.address, debtIssuanceMock.address] - ); - await debtIssuanceMock.initialize(setToken.address); - - if (isAllowListed) { - // Add SetToken to allow list - await perpLeverageModule.updateAllowedSetToken(setToken.address, true); - } - }; - - const initializeSubjectVariables = () => { - subjectSetToken = setToken.address; - subjectCaller = owner; - }; - - async function subject(): Promise { - return perpLeverageModule.connect(subjectCaller.wallet).initialize( - subjectSetToken, - ); - } - - describe("when isAllowListed is true", () => { - before(async () => { - isAllowListed = true; - }); - - cacheBeforeEach(initializeContracts); - beforeEach(initializeSubjectVariables); - - it("should enable the Module on the SetToken", async () => { - await subject(); - const isModuleEnabled = await setToken.isInitializedModule(perpLeverageModule.address); - expect(isModuleEnabled).to.eq(true); - }); - - it("should register on the debt issuance module", async () => { - await subject(); - const isRegistered = await debtIssuanceMock.isRegistered(setToken.address); - expect(isRegistered).to.be.true; - }); - - describe("when debt issuance module is not added to integration registry", async () => { - beforeEach(async () => { - await setup.integrationRegistry.removeIntegration(perpLeverageModule.address, "DefaultIssuanceModule"); - }); - - afterEach(async () => { - // Add debt issuance address to integration - await setup.integrationRegistry.addIntegration( - perpLeverageModule.address, - "DefaultIssuanceModule", - debtIssuanceMock.address - ); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be valid adapter"); - }); - }); - - describe("when debt issuance module is not initialized on SetToken", async () => { - beforeEach(async () => { - await setToken.removeModule(debtIssuanceMock.address); - }); - - afterEach(async () => { - await setToken.addModule(debtIssuanceMock.address); - await debtIssuanceMock.initialize(setToken.address); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Issuance not initialized"); - }); - }); - - describe("when the caller is not the SetToken manager", async () => { - beforeEach(async () => { - subjectCaller = await getRandomAccount(); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be the SetToken manager"); - }); - }); - - describe("when SetToken is not in pending state", async () => { - beforeEach(async () => { - const newModule = await getRandomAddress(); - await setup.controller.addModule(newModule); - - const perpLeverageModuleNotPendingSetToken = await setup.createSetToken( - [usdc.address], - [usdcUnits(100)], - [newModule] - ); - - subjectSetToken = perpLeverageModuleNotPendingSetToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be pending initialization"); - }); - }); - - describe("when the SetToken is not enabled on the controller", async () => { - beforeEach(async () => { - const nonEnabledSetToken = await setup.createNonControllerEnabledSetToken( - [setup.weth.address], - [usdcUnits(100)], - [perpLeverageModule.address] - ); - - subjectSetToken = nonEnabledSetToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be controller-enabled SetToken"); - }); - }); - }); - - describe("when isAllowListed is false", async () => { - before(async () => { - isAllowListed = false; - }); - - cacheBeforeEach(initializeContracts); - beforeEach(initializeSubjectVariables); - - describe("when SetToken is not allowlisted", async () => { - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Not allowed SetToken"); - }); - }); - - describe("when any Set can initialize this module", async () => { - beforeEach(async () => { - await perpLeverageModule.updateAnySetAllowed(true); - }); - - it("should enable the Module on the SetToken", async () => { - await subject(); - const isModuleEnabled = await setToken.isInitializedModule(perpLeverageModule.address); - expect(isModuleEnabled).to.eq(true); - }); - }); - }); - }); - - describe("#trade", () => { - let setToken: SetToken; - let isInitialized: boolean = true; - let depositQuantity: BigNumber; - - let subjectSetToken: Address; - let subjectCaller: Account; - let subjectBaseToken: Address; - let subjectBaseTradeQuantityUnits: BigNumber; - let subjectQuoteBoundQuantityUnits: BigNumber; - - const initializeContracts = async () => { - depositQuantity = usdcUnits(10); - setToken = await issueSetsAndDepositToPerp(depositQuantity, isInitialized); - }; - - const initializeSubjectVariables = async () => { - subjectSetToken = setToken.address; - subjectCaller = owner; - subjectBaseToken = vETH.address; - }; - - cacheBeforeEach(initializeContracts); - beforeEach(initializeSubjectVariables); - - async function subject(): Promise { - return await perpLeverageModule.connect(subjectCaller.wallet).trade( - subjectSetToken, - subjectBaseToken, - subjectBaseTradeQuantityUnits, - subjectQuoteBoundQuantityUnits - ); - } - - describe("when module is initialized", async () => { - describe("when going long", () => { - describe("when no positions are open (total supply is 1)", async () => { - beforeEach(async () => { - // Long ~10 USDC of vETH - subjectBaseTradeQuantityUnits = ether(1); - subjectQuoteBoundQuantityUnits = ether(10.15); - }); - - it("should open the expected position", async () => { - const totalSupply = await setToken.totalSupply(); - - const expectedBaseBalance = preciseMul(subjectBaseTradeQuantityUnits, totalSupply); - const expectedQuoteBalance = - (await perpSetup.getSwapQuote(subjectBaseToken, subjectBaseTradeQuantityUnits, true)).deltaQuote; - - const initialPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - - await subject(); - - const finalPositionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - - expect(initialPositionInfo.length).to.eq(0); - expect(finalPositionInfo.baseBalance).gt(0); - expect(finalPositionInfo.quoteBalance).lt(0); - expect(finalPositionInfo.baseBalance).eq(expectedBaseBalance); - expect(finalPositionInfo.quoteBalance).eq(expectedQuoteBalance.mul(-1)); - expect(finalPositionInfo.quoteBalance.mul(-1)).lt(subjectQuoteBoundQuantityUnits); - }); - - it("should emit the correct PerpTraded event", async () => { - const { - deltaBase: expectedDeltaBase, - deltaQuote: expectedDeltaQuote - } = await perpSetup.getSwapQuote(subjectBaseToken, subjectBaseTradeQuantityUnits, true); - - const expectedProtocolFee = ether(0); - const expectedIsBuy = true; - - await expect(subject()).to.emit(perpLeverageModule, "PerpTraded").withArgs( - subjectSetToken, - subjectBaseToken, - expectedDeltaBase, - expectedDeltaQuote, - expectedProtocolFee, - expectedIsBuy - ); - }); - - it("should not update the USDC defaultPositionUnit", async () => { - const initialDefaultPositionUnit = await setToken.getDefaultPositionRealUnit(usdc.address); - await subject(); - const finalDefaultPositionUnit = await setToken.getDefaultPositionRealUnit(usdc.address); - - expect(initialDefaultPositionUnit).eq(finalDefaultPositionUnit); - }); - - it("should not update the USDC externalPositionUnit", async () => { - const initialExternalPositionUnit = await setToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - await subject(); - const finalExternalPositionUnit = await setToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - - expect(initialExternalPositionUnit).eq(finalExternalPositionUnit); - }); - }); - - describe("when trading on margin", async () => { - beforeEach(async () => { - // Long ~20 USDC of vETH with 10 USDC collateral - subjectBaseTradeQuantityUnits = ether(2); - subjectQuoteBoundQuantityUnits = ether(20.3); - }); - - it("should open expected position", async () => { - const totalSupply = await setToken.totalSupply(); - const collateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - const quoteBalanceMin = preciseMul(subjectQuoteBoundQuantityUnits, totalSupply); - - const expectedQuoteBalance = - (await perpSetup.getSwapQuote(subjectBaseToken, subjectBaseTradeQuantityUnits, true)).deltaQuote; - - await subject(); - - const positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - const expectedBaseBalance = preciseMul(subjectBaseTradeQuantityUnits, totalSupply); - - // Check that a levered trade happened - expect(toUSDCDecimals(collateralBalance)).to.eq(depositQuantity); - expect(toUSDCDecimals(quoteBalanceMin)).to.be.gt(depositQuantity); - - // Check balances - expect(positionInfo.baseBalance).to.eq(expectedBaseBalance); - expect(positionInfo.quoteBalance.mul(-1)).eq(expectedQuoteBalance); - expect(positionInfo.quoteBalance.mul(-1)).to.be.lt(quoteBalanceMin); - }); - }); - - describe("when total supply is 2", async () => { - let issueQuantity: BigNumber; - let otherSetToken: SetToken; - - beforeEach(async () => { - depositQuantity = usdcUnits(10); - issueQuantity = ether(2); - - otherSetToken = await issueSetsAndDepositToPerp( - depositQuantity, - isInitialized, - issueQuantity, - true - ); - - subjectSetToken = otherSetToken.address; - subjectBaseTradeQuantityUnits = ether(1); - subjectQuoteBoundQuantityUnits = ether(10.15); - }); - - it("should open position for the expected amount", async () => { - const totalSupply = await otherSetToken.totalSupply(); - const expectedBaseBalance = preciseMul(subjectBaseTradeQuantityUnits, totalSupply); - - await subject(); - - const positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - - expect(totalSupply).eq(issueQuantity); - expect(positionInfo.baseBalance).to.eq(expectedBaseBalance); - }); - }); - - describe("when slippage is greater than allowed", async () => { - beforeEach(async () => { - // Long ~10 USDC of vETH: slippage incurred as larger negative quote delta - subjectBaseTradeQuantityUnits = ether(1); - subjectQuoteBoundQuantityUnits = ether(10); - }); - - it("should revert", async () => { - // ClearingHouse: too much quote received when long - await expect(subject()).to.be.revertedWith("CH_TMRL"); - }); - }); - - describe("when an existing position is long", async () => { - beforeEach(async () => { - subjectBaseTradeQuantityUnits = ether(1); - subjectQuoteBoundQuantityUnits = ether(10.15); - - await perpLeverageModule.connect(subjectCaller.wallet).trade( - subjectSetToken, - subjectBaseToken, - subjectBaseTradeQuantityUnits, - subjectQuoteBoundQuantityUnits - ); - }); - - it("long trade should increase the position size", async () => { - const totalSupply = await setToken.totalSupply(); - const initialPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - const expectedDeltaBase = preciseMul(subjectBaseTradeQuantityUnits, totalSupply); - const expectedBaseBalance = initialPositionInfo[0].baseBalance.add(expectedDeltaBase); - - await subject(); - - const finalPositionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - - expect(initialPositionInfo.length).to.eq(1); - expect(finalPositionInfo.baseBalance).eq(expectedBaseBalance); - }); - }); - - describe("when an existing position is short", async () => { - beforeEach(async () => { - // Short ~10 USDC vETH - await perpLeverageModule.connect(subjectCaller.wallet).trade( - subjectSetToken, - subjectBaseToken, - ether(-1), - ether(9.85) - ); - - subjectBaseTradeQuantityUnits = ether(.5); - subjectQuoteBoundQuantityUnits = ether(5.15); - }); - - it("long trade should reduce the position", async () => { - const totalSupply = await setToken.totalSupply(); - const baseTradeQuantityNotional = preciseMul(subjectBaseTradeQuantityUnits, totalSupply); - - const initialPositionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - - await subject(); - - const finalPositionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - const closeRatio = preciseDiv(baseTradeQuantityNotional, initialPositionInfo.baseBalance); - const reducedOpenNotional = preciseMul(initialPositionInfo.quoteBalance, closeRatio); - - const expectedBaseBalance = initialPositionInfo.baseBalance.add(baseTradeQuantityNotional); - const expectedQuoteBalance = initialPositionInfo.quoteBalance.add(reducedOpenNotional); - - expect(finalPositionInfo.baseBalance).gt(initialPositionInfo.baseBalance); - expect(finalPositionInfo.quoteBalance).lt(initialPositionInfo.quoteBalance); - - expect(finalPositionInfo.baseBalance).eq(expectedBaseBalance); - expect(finalPositionInfo.quoteBalance).eq(expectedQuoteBalance); - }); - - describe("when the position is zeroed out", async () => { - beforeEach(async () => { - subjectBaseTradeQuantityUnits = ether(1); - subjectQuoteBoundQuantityUnits = ether(10.15); - }); - - it("should remove the position from the positions array", async () => { - const initialPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - await subject(); - const finalPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - - expect(initialPositionInfo.length).eq(1); - expect(finalPositionInfo.length).eq(0); - }); - - it("should ensure no dust amount is left on PerpV2", async () => { - await subject(); - - const baseBalance = await perpSetup.accountBalance.getBase(setToken.address, vETH.address); - expect(baseBalance).to.be.eq(ZERO); - }); - }); - - describe("when reversing the position", async () => { - beforeEach(async () => { - subjectBaseTradeQuantityUnits = ether(2); - subjectQuoteBoundQuantityUnits = ether(20.45); - }); - - it("long trade should reverse the short position to a long position", async () => { - const totalSupply = await setToken.totalSupply(); - const baseTradeQuantityNotional = preciseMul(subjectBaseTradeQuantityUnits, totalSupply); - - const { deltaQuote } = await perpSetup.getSwapQuote( - subjectBaseToken, - baseTradeQuantityNotional.abs(), - true // long - ); - const quote = deltaQuote.mul(-1); - - const initialPositionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - - await subject(); - - const finalPositionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - const closeRatio = preciseDiv(baseTradeQuantityNotional.abs(), initialPositionInfo.baseBalance.abs()); - const closedPositionNotional = preciseDiv(quote, closeRatio); - - const expectedBaseBalance = initialPositionInfo.baseBalance.add(baseTradeQuantityNotional); - const expectedQuoteBalance = quote.sub(closedPositionNotional); - - expect(finalPositionInfo.baseBalance).gt(ZERO); - expect(finalPositionInfo.quoteBalance).lt(ZERO); - - expect(finalPositionInfo.baseBalance).eq(expectedBaseBalance); - expect(finalPositionInfo.quoteBalance).eq(expectedQuoteBalance); - }); - }); - }); - - describe("when a protocol fee is charged", async () => { - let feePercentage: BigNumber; - - cacheBeforeEach(async () => { - feePercentage = ether(0.05); - setup.controller = setup.controller.connect(owner.wallet); - - await setup.controller.addFee( - perpLeverageModule.address, - ZERO, // Fee type on trade function denoted as 0 - feePercentage - ); - - // Long ~10 USDC of vETH - subjectBaseTradeQuantityUnits = ether(1); - subjectQuoteBoundQuantityUnits = ether(10.15); - }); - - it("should withdraw the expected collateral amount from the Perp vault", async () => { - const { - collateralBalance: initialCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken); - - await subject(); - - const { - collateralBalance: finalCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken); - - // Levering up from 0, the absolute value of position quote balance is size of our trade - const { quoteBalance } = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - const feeAmountInQuoteDecimals = preciseMul(quoteBalance.abs(), feePercentage); - - const expectedCollateralBalance = toUSDCDecimals(initialCollateralBalance).sub(toUSDCDecimals(feeAmountInQuoteDecimals)); - expect(toUSDCDecimals(finalCollateralBalance)).to.eq(expectedCollateralBalance); - }); - - it("should transfer the correct protocol fee to the protocol", async () => { - const feeRecipient = await setup.controller.feeRecipient(); - const initialFeeRecipientBalance = await usdc.balanceOf(feeRecipient); - - await subject(); - - const { quoteBalance } = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - const feeAmountInQuoteDecimals = preciseMul(quoteBalance.mul(-1), feePercentage); - const feeAmountInUSDCDecimals = toUSDCDecimals(feeAmountInQuoteDecimals); - const expectedFeeRecipientBalance = initialFeeRecipientBalance.add(feeAmountInUSDCDecimals); - - const finalFeeRecipientBalance = await usdc.balanceOf(feeRecipient); - expect(finalFeeRecipientBalance).to.eq(expectedFeeRecipientBalance); - }); - - it("should not change the value of the SetToken USDC defaultPositionUnit", async () => { - const initialUSDCDefaultPositionUnit = await setToken.getDefaultPositionRealUnit(usdc.address); - await subject(); - const finalUSDCDefaultPositionUnit = await setToken.getDefaultPositionRealUnit(usdc.address); - - expect(initialUSDCDefaultPositionUnit).to.eq(finalUSDCDefaultPositionUnit); - }); - - it("should not update the USDC externalPositionUnit", async () => { - const initialExternalPositionUnit = await setToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - await subject(); - const finalExternalPositionUnit = await setToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - - expect(initialExternalPositionUnit).eq(finalExternalPositionUnit); - }); - - it("should emit the correct PerpTraded event", async () => { - const { - deltaBase: expectedDeltaBase, - deltaQuote: expectedDeltaQuote - } = await perpSetup.getSwapQuote(subjectBaseToken, subjectBaseTradeQuantityUnits, true); - - const expectedProtocolFee = toUSDCDecimals(preciseMul(expectedDeltaQuote, feePercentage)); - const expectedIsBuy = true; - - await expect(subject()).to.emit(perpLeverageModule, "PerpTraded").withArgs( - subjectSetToken, - subjectBaseToken, - expectedDeltaBase, - expectedDeltaQuote, - expectedProtocolFee, - expectedIsBuy - ); - }); - }); - - describe("when amount of token to trade is 0", async () => { - beforeEach(async () => { - subjectBaseTradeQuantityUnits = ZERO; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Amount is 0"); - }); - }); - - describe("when baseToken does not exist in Perp system", async () => { - beforeEach(async () => { - subjectBaseTradeQuantityUnits = ether(1); - subjectQuoteBoundQuantityUnits = ether(10.15); - subjectBaseToken = await getRandomAddress(); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Base token does not exist"); - }); - }); - }); - - describe("when going short", () => { - beforeEach(async () => { - // Short ~10 USDC of vETH - subjectBaseTradeQuantityUnits = ether(-1); - subjectQuoteBoundQuantityUnits = ether(9.85); - }); - - it("should open the expected position", async () => { - const totalSupply = await setToken.totalSupply(); - const expectedBaseBalance = preciseMul(subjectBaseTradeQuantityUnits, totalSupply); - - const expectedQuoteBalance = (await perpSetup.getSwapQuote( - subjectBaseToken, - subjectBaseTradeQuantityUnits.mul(-1), - false - )).deltaQuote; - - const initialPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - await subject(); - const finalPositionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - - expect(initialPositionInfo.length).to.eq(0); - expect(finalPositionInfo.baseBalance).lt(0); - expect(finalPositionInfo.quoteBalance).gt(0); - expect(finalPositionInfo.baseBalance).eq(expectedBaseBalance); - expect(finalPositionInfo.quoteBalance).eq(expectedQuoteBalance); - expect(finalPositionInfo.quoteBalance).gt(subjectQuoteBoundQuantityUnits); - }); - - it("should emit the correct PerpTraded event", async () => { - const { - deltaBase: expectedDeltaBase, - deltaQuote: expectedDeltaQuote - } = await perpSetup.getSwapQuote(subjectBaseToken, subjectBaseTradeQuantityUnits.mul(-1), false); - - const expectedProtocolFee = ether(0); - const expectedIsBuy = false; - - await expect(subject()).to.emit(perpLeverageModule, "PerpTraded").withArgs( - subjectSetToken, - subjectBaseToken, - expectedDeltaBase, - expectedDeltaQuote, - expectedProtocolFee, - expectedIsBuy - ); - }); - - describe("when an existing position is long", async () => { - beforeEach(async () => { - await perpLeverageModule.connect(subjectCaller.wallet).trade( - subjectSetToken, - subjectBaseToken, - ether(1), - ether(10.15) - ); - - // Partial close - subjectBaseTradeQuantityUnits = ether(-.5); - subjectQuoteBoundQuantityUnits = ether(4.85); - }); - - it("short trade should reduce the position", async () => { - const totalSupply = await setToken.totalSupply(); - const baseTradeQuantityNotional = preciseMul(subjectBaseTradeQuantityUnits, totalSupply); - - const initialPositionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - - await subject(); - - const finalPositionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - const closeRatio = preciseDiv(baseTradeQuantityNotional, initialPositionInfo.baseBalance); - const reducedOpenNotional = preciseMul(initialPositionInfo.quoteBalance, closeRatio); - - const expectedBaseBalance = initialPositionInfo.baseBalance.sub(baseTradeQuantityNotional.abs()); - const expectedQuoteBalance = initialPositionInfo.quoteBalance.add(reducedOpenNotional); - - expect(finalPositionInfo.baseBalance).lt(initialPositionInfo.baseBalance); - expect(finalPositionInfo.quoteBalance).gt(initialPositionInfo.quoteBalance); - - expect(finalPositionInfo.baseBalance).eq(expectedBaseBalance); - expect(finalPositionInfo.quoteBalance).eq(expectedQuoteBalance); - }); - - describe("when the position is zeroed out", async () => { - beforeEach(async () => { - subjectBaseTradeQuantityUnits = ether(-1); - subjectQuoteBoundQuantityUnits = ether(9.85); - }); - - it("should remove the position from the positions array", async () => { - const initialPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - await subject(); - const finalPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - - expect(initialPositionInfo.length).eq(1); - expect(finalPositionInfo.length).eq(0); - }); - - it("should ensure no dust amount is left on PerpV2", async () => { - await subject(); - - const baseBalance = await perpSetup.accountBalance.getBase(setToken.address, vETH.address); - expect(baseBalance).to.be.eq(ZERO); - }); - }); - - describe("when the position reversed", async () => { - beforeEach(async () => { - subjectBaseTradeQuantityUnits = ether(-2); - subjectQuoteBoundQuantityUnits = ether(19.45); - }); - - it("short trade should reverse the long position to a short position", async () => { - const totalSupply = await setToken.totalSupply(); - const baseTradeQuantityNotional = preciseMul(subjectBaseTradeQuantityUnits, totalSupply); - - const { deltaQuote } = await perpSetup.getSwapQuote( - subjectBaseToken, - baseTradeQuantityNotional.abs(), - false // short - ); - - const initialPositionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - - await subject(); - - const finalPositionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - const closeRatio = preciseDiv(baseTradeQuantityNotional.abs(), initialPositionInfo.baseBalance.abs()); - const closedPositionNotional = preciseDiv(deltaQuote, closeRatio); - - const expectedBaseBalance = initialPositionInfo.baseBalance.sub(baseTradeQuantityNotional.abs()); - const expectedQuoteBalance = deltaQuote.sub(closedPositionNotional); - - expect(finalPositionInfo.baseBalance).lt(ZERO); - expect(finalPositionInfo.quoteBalance).gt(ZERO); - - expect(finalPositionInfo.baseBalance).eq(expectedBaseBalance); - expect(finalPositionInfo.quoteBalance).eq(expectedQuoteBalance); - }); - }); - }); - - describe("when an existing position is short", async () => { - beforeEach(async () => { - await perpLeverageModule.connect(subjectCaller.wallet).trade( - subjectSetToken, - subjectBaseToken, - ether(-1), - ether(9.85) - ); - }); - - it("short trade should increase the position size", async () => { - const totalSupply = await setToken.totalSupply(); - const initialPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - const expectedDeltaBase = preciseMul(subjectBaseTradeQuantityUnits, totalSupply); - const expectedBaseBalance = initialPositionInfo[0].baseBalance.add(expectedDeltaBase); - - await subject(); - - const finalPositionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - - expect(initialPositionInfo.length).to.eq(1); - expect(initialPositionInfo[0].baseBalance).gt(finalPositionInfo.baseBalance); - expect(finalPositionInfo.baseBalance).eq(expectedBaseBalance); - }); - }); - - describe("when a protocol fee is charged", async () => { - let feePercentage: BigNumber; - - cacheBeforeEach(async () => { - feePercentage = ether(0.05); - setup.controller = setup.controller.connect(owner.wallet); - - await setup.controller.addFee( - perpLeverageModule.address, - ZERO, // Fee type on trade function denoted as 0 - feePercentage - ); - - // Short ~10 USDC of vETH - subjectBaseTradeQuantityUnits = ether(-1); - subjectQuoteBoundQuantityUnits = ether(9.85); - }); - - it("should withdraw the expected collateral amount from the Perp vault", async () => { - const { - collateralBalance: initialCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken); - - await subject(); - - const { - collateralBalance: finalCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken); - - // Levering up from 0, the position quote balance is size of our trade - const { quoteBalance } = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - const feeAmountInQuoteDecimals = preciseMul(quoteBalance, feePercentage); - - const expectedCollateralBalance = toUSDCDecimals(initialCollateralBalance).sub(toUSDCDecimals(feeAmountInQuoteDecimals)); - expect(toUSDCDecimals(finalCollateralBalance)).to.eq(expectedCollateralBalance); - }); - }); - - describe("when slippage is greater than allowed", async () => { - beforeEach(async () => { - // Short ~10 USDC of vETH, slippage incurred as smaller positive quote delta - subjectBaseTradeQuantityUnits = ether(-1); - subjectQuoteBoundQuantityUnits = ether(10); - }); - - it("should revert", async () => { - // ClearingHouse: too little quote received when short - await expect(subject()).to.be.revertedWith("CH_TLRS"); - }); - }); - }); - }); - - describe("when exceeds the max number of postions", async () => { - beforeEach(async () => { - // Open a WBTC position to max out the number of positions that can be opened per Set - await perpLeverageModule.connect(owner.wallet).updateMaxPerpPositionsPerSet(ONE); - - await perpLeverageModule.trade( - subjectSetToken, - vBTC.address, - ether(0.1), - ether(2.1) // 2.1 > 2 (20 * 0.1) - ); - - // Long ~10 USDC of vETH - subjectBaseTradeQuantityUnits = ether(1); - subjectQuoteBoundQuantityUnits = ether(10.15); - }); - - after(async () => { - await perpLeverageModule.connect(owner.wallet).updateMaxPerpPositionsPerSet(TWO); - }); - - it("should revert with exceeds max perpetual positions per set", async () => { - await expect(subject()).to.be.revertedWith("Exceeds max perpetual positions per set"); - }); - }); - - describe("when the caller is not the SetToken manager", async () => { - beforeEach(async () => { - subjectCaller = await getRandomAccount(); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be the SetToken manager"); - }); - }); - - describe("when SetToken is not valid", async () => { - beforeEach(async () => { - const nonEnabledSetToken = await setup.createNonControllerEnabledSetToken( - [perpSetup.usdc.address], - [usdcUnits(100)], - [perpLeverageModule.address], - owner.address - ); - - subjectSetToken = nonEnabledSetToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be a valid and initialized SetToken"); - }); - }); - - describe("when module is not initialized", async () => { - beforeEach(async () => { - isInitialized = false; - await initializeContracts(); - await initializeSubjectVariables(); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be a valid and initialized SetToken"); - }); - }); - }); - - describe("#deposit", () => { - let subjectSetToken: SetToken; - let subjectDepositAmount: number; - let subjectDepositQuantity: BigNumber; - let subjectCaller: Account; - let isInitialized: boolean; - - const initializeContracts = async () => { - subjectSetToken = await setup.createSetToken( - [usdc.address], - [usdcUnits(100)], - [perpLeverageModule.address, debtIssuanceMock.address, setup.issuanceModule.address] - ); - - await debtIssuanceMock.initialize(subjectSetToken.address); - await perpLeverageModule.updateAllowedSetToken(subjectSetToken.address, true); - - if (isInitialized) { - await perpLeverageModule.initialize(subjectSetToken.address); - - const issueQuantity = ether(2); - await usdc.approve(setup.issuanceModule.address, usdcUnits(1000)); - await setup.issuanceModule.initialize(subjectSetToken.address, ADDRESS_ZERO); - await setup.issuanceModule.issue(subjectSetToken.address, issueQuantity, owner.address); - } - }; - - const initializeSubjectVariables = () => { - subjectCaller = owner; - subjectDepositAmount = 1; - subjectDepositQuantity = usdcUnits(subjectDepositAmount); - }; - - async function subject(): Promise { - return await perpLeverageModule - .connect(subjectCaller.wallet) - .deposit(subjectSetToken.address, subjectDepositQuantity); - } - - describe("when module is initialized", () => { - beforeEach(async () => { - isInitialized = true; - }); - - cacheBeforeEach(initializeContracts); - beforeEach(initializeSubjectVariables); - - it("should create a deposit", async () => { - const { - collateralBalance: initialCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken.address); - - await subject(); - - const { - collateralBalance: finalCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken.address); - - const totalSupply = await subjectSetToken.totalSupply(); - const expectedCollateralBalance = toUSDCDecimals(initialCollateralBalance) - .add(preciseMul(subjectDepositQuantity, totalSupply)); - expect(toUSDCDecimals(finalCollateralBalance)).to.eq(expectedCollateralBalance); - }); - - it("should add Perp as an external position module", async () => { - const initialExternalModules = await subjectSetToken.getExternalPositionModules(usdc.address); - - await subject(); - - const finalExternalPositionModules = await subjectSetToken.getExternalPositionModules(usdc.address); - - const expectedExternalPositionModule = perpLeverageModule.address; - - expect(initialExternalModules.length).eq(0); - expect(finalExternalPositionModules.length).eq(1); - expect(finalExternalPositionModules[0]).eq(expectedExternalPositionModule); - - }); - - it("should update the USDC defaultPositionUnit", async () => { - const initialDefaultPosition = await subjectSetToken.getDefaultPositionRealUnit(usdc.address); - await subject(); - const finalDefaultPosition = await subjectSetToken.getDefaultPositionRealUnit(usdc.address);; - - const expectedDefaultPosition = initialDefaultPosition.sub(usdcUnits(subjectDepositAmount)); - expect(finalDefaultPosition).to.eq(expectedDefaultPosition); - }); - - it("should update the USDC externalPositionUnit", async () => { - const initialExternalPositionUnit = await subjectSetToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - await subject(); - const finalExternalPositionUnit = await subjectSetToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - - const expectedDefaultPosition = initialExternalPositionUnit.add(subjectDepositQuantity); - expect(finalExternalPositionUnit).to.eq(expectedDefaultPosition); - }); - - it("should emit the correct CollateralDeposited event", async () => { - const totalSupply = await subjectSetToken.totalSupply(); - - await expect(subject()).to.emit(perpLeverageModule, "CollateralDeposited").withArgs( - subjectSetToken.address, - perpSetup.usdc.address, - preciseMul(subjectDepositQuantity, totalSupply) - ); - }); - - describe("when depositing and a position exists", () => { - let baseToken: Address; - - describe("when the position is long", async () => { - beforeEach(async () => { - await subject(); // should avoid calling subject here - baseToken = vETH.address; - await leverUp( - subjectSetToken, - perpLeverageModule, - perpSetup, - owner, - baseToken, - 2, - ether(.02), - true - ); - }); - - it("should create a deposit", async () => { - const { - collateralBalance: initialCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken.address); - - await subject(); - - const { - collateralBalance: finalCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken.address); - - const totalSupply = await subjectSetToken.totalSupply(); - const expectedCollateralBalance = toUSDCDecimals(initialCollateralBalance) - .add(preciseMul(subjectDepositQuantity, totalSupply)); - expect(toUSDCDecimals(finalCollateralBalance)).to.eq(expectedCollateralBalance); - }); - - - it("should set the expected position unit", async () => { - await subject(); - const externalPositionUnit = await subjectSetToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - const expectedExternalPositionUnit = await calculateExternalPositionUnit( - subjectSetToken, - perpLeverageModule, - perpSetup - ); - - // Deposit notional amount = specified position unit * totalSupply = 1 * 2 = $2 - // We've put on a position that hasn't had any real pnl, so we expect set ~= $2 net fees & slippage - // externalPositionUnit = 1_979_877 - expect(externalPositionUnit).eq(expectedExternalPositionUnit); - }); - - it("should decrease the leverage ratio", async () => { - const positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken.address))[0]; - const totalSupply = await subjectSetToken.totalSupply(); - - const { - collateralBalance: initialCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken.address); - - const initialLeverageRatio = await perpSetup.getCurrentLeverage( - subjectSetToken.address, - positionInfo, - initialCollateralBalance - ); - - await subject(); - - const { - collateralBalance: finalCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken.address); - - const finalLeverageRatio = await perpSetup.getCurrentLeverage( - subjectSetToken.address, - positionInfo, - finalCollateralBalance - ); - - const expectedCollateralBalance = toUSDCDecimals(initialCollateralBalance) - .add(preciseMul(subjectDepositQuantity, totalSupply)); - - // initialLeverageRatio = 2_040_484_848_517_694_106 - // finalLeverageRatio = 1_009_978_994_844_697_153 - expect(toUSDCDecimals(finalCollateralBalance)).to.eq(expectedCollateralBalance); - expect(finalLeverageRatio).lt(initialLeverageRatio); - }); - }); - - describe("when the position is short", async () => { - beforeEach(async () => { - await subject(); - baseToken = vETH.address; - await leverUp( - subjectSetToken, - perpLeverageModule, - perpSetup, - owner, - baseToken, - 2, - ether(.02), - false - ); - }); - - it("should create a deposit", async () => { - const { - collateralBalance: initialCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken.address); - - await subject(); - - const { - collateralBalance: finalCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken.address); - - const totalSupply = await subjectSetToken.totalSupply(); - const expectedCollateralBalance = toUSDCDecimals(initialCollateralBalance) - .add(preciseMul(subjectDepositQuantity, totalSupply)); - expect(toUSDCDecimals(finalCollateralBalance)).to.eq(expectedCollateralBalance); - }); - - it("should set the expected position unit", async () => { - await subject(); - const externalPositionUnit = await subjectSetToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - const expectedExternalPositionUnit = await calculateExternalPositionUnit( - subjectSetToken, - perpLeverageModule, - perpSetup - ); - - // Deposit amount = $1 * 2 (two deposits) - // We've put on a position that hasn't had any real pnl, so we expect set ~= $2 net fees & slippage - // externalPositionUnit = 1_980_080 - expect(externalPositionUnit).eq(expectedExternalPositionUnit); - }); - - it("should decrease the leverage ratio", async () => { - const positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken.address))[0]; - const totalSupply = await subjectSetToken.totalSupply(); - - const { - collateralBalance: initialCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken.address); - - const initialLeverageRatio = await perpSetup.getCurrentLeverage( - subjectSetToken.address, - positionInfo, - initialCollateralBalance - ); - - await subject(); - - const { - collateralBalance: finalCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken.address); - - const finalLeverageRatio = await perpSetup.getCurrentLeverage( - subjectSetToken.address, - positionInfo, - finalCollateralBalance - ); - - const expectedCollateralBalance = toUSDCDecimals(initialCollateralBalance) - .add(preciseMul(subjectDepositQuantity, totalSupply)); - - // initialLeverageRatio = 2_041_235_426_575_610_129 - // finalLeverageRation = 1_010_244_489_779_359_264 - expect(toUSDCDecimals(finalCollateralBalance)).to.eq(expectedCollateralBalance); - expect(finalLeverageRatio).lt(initialLeverageRatio); - }); - }); - - describe("when the position is mixed long and short", async () => { - beforeEach(async () => { - await subject(); - baseToken = vETH.address; - await leverUp( - subjectSetToken, - perpLeverageModule, - perpSetup, - owner, - vETH.address, - 2, - ether(.02), - true // long - ); - - await leverUp( - subjectSetToken, - perpLeverageModule, - perpSetup, - owner, - vBTC.address, - 2, - ether(.02), - false // short - ); - }); - - it("should create a deposit", async () => { - const { - collateralBalance: initialCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken.address); - - await subject(); - - const { - collateralBalance: finalCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken.address); - - const totalSupply = await subjectSetToken.totalSupply(); - const expectedCollateralBalance = toUSDCDecimals(initialCollateralBalance) - .add(preciseMul(subjectDepositQuantity, totalSupply)); - expect(toUSDCDecimals(finalCollateralBalance)).to.eq(expectedCollateralBalance); - }); - - it("should set the expected position unit", async () => { - await subject(); - const externalPositionUnit = await subjectSetToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - const expectedExternalPositionUnit = await calculateExternalPositionUnit( - subjectSetToken, - perpLeverageModule, - perpSetup - ); - - // Deposit amount = $1 * 2 (two deposits) - // We've put on a position that hasn't had any real pnl, so we expect set ~= $2 net fees & slippage - // EPU is slightly lower here than previous cases since we've traded twice - // - // externalPositionUnit = 1_959_917 - expect(externalPositionUnit).eq(expectedExternalPositionUnit); - }); - }); - }); - - describe("when deposit amount is 0", async () => { - beforeEach(() => { - subjectDepositQuantity = usdcUnits(0); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Deposit amount is 0"); - }); - }); - - describe("when not called by manager", async () => { - beforeEach(async () => { - subjectCaller = await getRandomAccount(); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be the SetToken manager"); - }); - }); - }); - - describe("when module is not initialized", async () => { - beforeEach(async () => { - isInitialized = false; - await initializeContracts(); - initializeSubjectVariables(); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be a valid and initialized SetToken"); - }); - }); - }); - - describe("#withdraw", () => { - let depositQuantity: BigNumber; - let subjectSetToken: SetToken; - let subjectWithdrawQuantity: BigNumber; - let subjectCaller: Account; - let isInitialized: boolean; - - const initializeContracts = async () => { - subjectSetToken = await setup.createSetToken( - [usdc.address], - [usdcUnits(100)], - [perpLeverageModule.address, debtIssuanceMock.address, setup.issuanceModule.address] - ); - - await debtIssuanceMock.initialize(subjectSetToken.address); - await perpLeverageModule.updateAllowedSetToken(subjectSetToken.address, true); - - if (isInitialized) { - await perpLeverageModule.initialize(subjectSetToken.address); - - const issueQuantity = ether(2); - await usdc.approve(setup.issuanceModule.address, usdcUnits(1000)); - await setup.issuanceModule.initialize(subjectSetToken.address, ADDRESS_ZERO); - await setup.issuanceModule.issue(subjectSetToken.address, issueQuantity, owner.address); - - // Deposit 10 USDC - depositQuantity = usdcUnits(10); - await perpLeverageModule - .connect(owner.wallet) - .deposit(subjectSetToken.address, depositQuantity); - } - }; - - const initializeSubjectVariables = () => { - subjectCaller = owner; - subjectWithdrawQuantity = usdcUnits(5); - }; - - async function subject(): Promise { - return await perpLeverageModule - .connect(subjectCaller.wallet) - .withdraw(subjectSetToken.address, subjectWithdrawQuantity); - } - - describe("when module is initialized", () => { - beforeEach(async () => { - isInitialized = true; - }); - - cacheBeforeEach(initializeContracts); - beforeEach(() => initializeSubjectVariables()); - - it("should withdraw an amount", async () => { - const initialCollateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken.address)).collateralBalance; - - await subject(); - - const finalCollateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken.address)).collateralBalance; - - const totalSupply = await subjectSetToken.totalSupply(); - const expectedCollateralBalance = toUSDCDecimals(initialCollateralBalance) - .sub(preciseMul(subjectWithdrawQuantity, totalSupply)); - expect(toUSDCDecimals(finalCollateralBalance)).to.eq(expectedCollateralBalance); - }); - - it("should update the USDC defaultPositionUnit", async () => { - const initialDefaultPosition = await subjectSetToken.getDefaultPositionRealUnit(usdc.address); - await subject(); - const finalDefaultPosition = await subjectSetToken.getDefaultPositionRealUnit(usdc.address);; - - const expectedDefaultPosition = initialDefaultPosition.add(subjectWithdrawQuantity); - expect(finalDefaultPosition).to.eq(expectedDefaultPosition); - }); - - it("should update the USDC externalPositionUnit", async () => { - const initialExternalPositionUnit = await subjectSetToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - await subject(); - const finalExternalPositionUnit = await subjectSetToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - - const expectedExternalPositionUnit = initialExternalPositionUnit.sub(subjectWithdrawQuantity); - expect(finalExternalPositionUnit).to.eq(expectedExternalPositionUnit); - }); - - it("should emit the correct CollateralWithdrawn event", async () => { - const totalSupply = await subjectSetToken.totalSupply(); - - await expect(subject()).to.emit(perpLeverageModule, "CollateralWithdrawn").withArgs( - subjectSetToken.address, - perpSetup.usdc.address, - preciseMul(subjectWithdrawQuantity, totalSupply) - ); - }); - - describe("when withdraw amount is 0", async () => { - beforeEach(() => { - subjectWithdrawQuantity = usdcUnits(0); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Withdraw amount is 0"); - }); - }); - - describe("when the entire amount is withdrawn", async () => { - beforeEach(() => { - subjectWithdrawQuantity = depositQuantity; - }); - - it("should remove Perp as an external position module", async () => { - const initialExternalModules = await subjectSetToken.getExternalPositionModules(usdc.address); - await subject(); - const finalExternalPositionModules = await subjectSetToken.getExternalPositionModules(usdc.address); - - expect(initialExternalModules.length).eq(1); - expect(finalExternalPositionModules.length).eq(0); - }); - }); - - describe("when withdrawing and a position exists", () => { - let baseToken: Address; - - beforeEach(async () => { - baseToken = vETH.address; - await leverUp( - subjectSetToken, - perpLeverageModule, - perpSetup, - owner, - baseToken, - 2, - ether(.02), - true - ); - - subjectWithdrawQuantity = usdcUnits(2.5); - }); - - it("should decrease the collateral balance", async () => { - const initialCollateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken.address)).collateralBalance; - - await subject(); - - const finalCollateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken.address)).collateralBalance; - - const totalSupply = await subjectSetToken.totalSupply(); - const expectedCollateralBalance = toUSDCDecimals(initialCollateralBalance) - .sub(preciseMul(subjectWithdrawQuantity, totalSupply)); - - expect(toUSDCDecimals(finalCollateralBalance)).to.eq(expectedCollateralBalance); - }); - - it("should increase the leverage ratio", async () => { - const positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken.address))[0]; - const totalSupply = await subjectSetToken.totalSupply(); - - const { - collateralBalance: initialCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken.address); - - const initialLeverageRatio = await perpSetup.getCurrentLeverage( - subjectSetToken.address, - positionInfo, - initialCollateralBalance - ); - - await subject(); - - const { - collateralBalance: finalCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken.address); - - const finalLeverageRatio = await perpSetup.getCurrentLeverage( - subjectSetToken.address, - positionInfo, - finalCollateralBalance - ); - - const expectedCollateralBalance = toUSDCDecimals(initialCollateralBalance) - .sub(preciseMul(subjectWithdrawQuantity, totalSupply)); - - // initialLeverageRatio = 2_041_219_945_269_276_819 - // finalLeverageRatio = 2_739_702_831_474_076_071 - expect(toUSDCDecimals(finalCollateralBalance)).to.eq(expectedCollateralBalance); - expect(finalLeverageRatio).gt(initialLeverageRatio); - }); - }); - - describe("when not called by manager", async () => { - beforeEach(async () => { - subjectCaller = await getRandomAccount(); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be the SetToken manager"); - }); - }); - }); - - describe("when module is not initialized", async () => { - beforeEach(async () => { - isInitialized = false; - await initializeContracts(); - initializeSubjectVariables(); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be a valid and initialized SetToken"); - }); - }); - }); - - describe("#moduleIssueHook", () => { - let setToken: SetToken; - let collateralQuantity: BigNumber; - let subjectSetToken: Address; - let subjectCaller: Account; - let subjectSetQuantity: BigNumber; - - // Start with initial total supply (2) - const initializeContracts = async () => { - collateralQuantity = usdcUnits(10); - setToken = await issueSetsAndDepositToPerp(collateralQuantity, true, ether(2)); - }; - - const initializeSubjectVariables = () => { - subjectSetToken = setToken.address; - subjectCaller = mockModule; - subjectSetQuantity = ether(1); - }; - - cacheBeforeEach(initializeContracts); - beforeEach(initializeSubjectVariables); - - async function subject(): Promise { - return await perpLeverageModule - .connect(subjectCaller.wallet) - .moduleIssueHook(subjectSetToken, subjectSetQuantity); - } - - describe("when long, single position", () => { - let baseToken: Address; - - // Set up as 2X Long, allow 2% slippage - cacheBeforeEach(async () => { - baseToken = vETH.address; - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - baseToken, - 2, - ether(.02), - true - ); - }); - - describe("when issuing a single set", async () => { - let usdcTransferInQuantity: BigNumber; - - beforeEach(async () => { - usdcTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - }); - - it("buys expected amount of vBase", async () => { - const totalSupply = await setToken.totalSupply(); - - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - - await subject(); - - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - - const basePositionUnit = preciseDiv(initialBaseBalance, totalSupply); - const baseTokenBoughtNotional = preciseMul(basePositionUnit, subjectSetQuantity); - const expectedBaseBalance = initialBaseBalance.add(baseTokenBoughtNotional); - - expect(finalBaseBalance).eq(expectedBaseBalance); - }); - - // There are 2 ways to handle funding accrued between when we fetch the usdc amount to be - // transferred in and when we determine usdc amount to be transferred in on chain. - // 1. Force funding to zero by syncing the oracle price to spot price - // 2. Calculate accrued funding and add it to our usdc amount to be transferred in - describe("sync oracle in before each", async () => { - beforeEach(async () => { - await syncOracleToSpot(vETH); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const expectedExternalPositionUnit = preciseDiv(usdcTransferInQuantity, subjectSetQuantity); - - await subject(); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.eq(expectedExternalPositionUnit); - }); - }); - - describe("do not sync oracle in before each", async () => { - beforeEach(async () => { - usdcTransferInQuantity = await calculateUSDCTransferInPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup, - false - ); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const baseBalance = await perpSetup.accountBalance.getBase(setToken.address, baseToken); - - await subject(); - - const usdcAmountDelta = await getUSDCDeltaDueToFundingGrowth( - setToken, - subjectSetQuantity, - baseToken, - baseBalance, - perpSetup - ); - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferInQuantity.add(usdcAmountDelta), subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.eq(expectedExternalPositionUnit); - }); - }); - }); - - describe("when there is positive owedRealizedPnl", async () => { - beforeEach(async () => { - // Move price up by maker buying 20k USDC of vETH - // Post trade spot price rises from ~10 USDC to 14_356_833_358_751_766_356 - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(20000), - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - // Sell a little, booking profit to owedRealizedPnl - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - vETH.address, - ether(-.4), - ether(4) - ); - - await syncOracleToSpot(vETH); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const owedRealizedPnl = (await perpLeverageModule.getAccountInfo(subjectSetToken)).owedRealizedPnl; - - const usdcTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - const expectedExternalPositionUnit = preciseDiv( - usdcTransferInQuantity, - subjectSetQuantity - ); - - await subject(); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(owedRealizedPnl).gt(0); - expect(externalPositionUnit).to.eq(expectedExternalPositionUnit); - }); - }); - - describe("when there is negative owedRealizedPnl", async () => { - beforeEach(async () => { - // Move price down by maker selling 20k USDC of vETH - // Post trade spot price rises from ~10 USDC to 6_370_910_537_702_299_856 - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(20000), - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - // Sell a little, booking loss to owedRealizedPnl - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - vETH.address, - ether(-.4), - ether(1) - ); - - await syncOracleToSpot(vETH); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const owedRealizedPnl = (await perpLeverageModule.getAccountInfo(subjectSetToken)).owedRealizedPnl; - - const usdcTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - const expectedExternalPositionUnit = preciseDiv(usdcTransferInQuantity, subjectSetQuantity); - - await subject(); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(owedRealizedPnl).lt(ether(1).mul(-1)); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when the Set owes funding", async () => { - beforeEach(async() => { - // set funding rate to non-zero value - await perpSetup.clearingHouseConfig.setMaxFundingRate(BigNumber.from(0.1e6)); // 10% in decimal 6 - }); - - it("should socialize the funding payment among existing set holders", async () => { - // Move oracle price down and wait one day - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(9.5)); - await increaseTimeAsync(ONE_DAY_IN_SECONDS); - - const baseBalance = await perpSetup.accountBalance.getBase(setToken.address, baseToken); - const pendingFunding = (await perpLeverageModule.getAccountInfo(subjectSetToken)).pendingFundingPayments; - const usdcTransferInQuantity = await calculateUSDCTransferInPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup, - false // don't include funding - ); - - await subject(); - - const usdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, baseToken, baseBalance, perpSetup); - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferInQuantity.add(usdcAmountDelta), subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(pendingFunding).lt(0); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when the Set is owed funding", async () => { - beforeEach(async() => { - // set funding rate to non-zero value - await perpSetup.clearingHouseConfig.setMaxFundingRate(BigNumber.from(0.1e6)); // 10% in decimal 6 - }); - - it("should socialize the funding payment among existing set holders", async () => { - // Move oracle price up and wait one day - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(15)); - await increaseTimeAsync(ONE_DAY_IN_SECONDS); - - const baseBalance = await perpSetup.accountBalance.getBase(setToken.address, baseToken); - const pendingFunding = (await perpLeverageModule.getAccountInfo(subjectSetToken)).pendingFundingPayments; - const usdcTransferInQuantity = await calculateUSDCTransferInPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup, - false // don't include funding - ); - - await subject(); - - const usdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, baseToken, baseBalance, perpSetup); - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferInQuantity.add(usdcAmountDelta), subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(pendingFunding).gt(ZERO); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when the market price moves up and leverage drops", async () => { - it("test assumptions and preconditions should be correct", async () => { - let positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - let collateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const initialLeverage = await perpSetup.getCurrentLeverage(subjectSetToken, positionInfo, collateralBalance); - const initialSpotPrice = await perpSetup.getSpotPrice(vETH.address); - const initialUSDCTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(10000), // move price up by buying 10k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - collateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const finalLeverage = await perpSetup.getCurrentLeverage(subjectSetToken, positionInfo, collateralBalance); - const finalSpotPrice = await perpSetup.getSpotPrice(vETH.address); - const finalUSDCTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - expect(initialSpotPrice).lt(finalSpotPrice); - expect(initialUSDCTransferInQuantity).lt(finalUSDCTransferInQuantity); - expect(initialLeverage).gt(ZERO); - expect(finalLeverage).gt(ZERO); - expect(initialLeverage).gt(finalLeverage); - }); - - it("buys expected amount of vBase", async () => { - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(10000), // move price up by buying 10k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - await subject(); - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - - const basePositionUnit = preciseDiv(initialBaseBalance, await setToken.totalSupply()); - const baseTokenBoughtNotional = preciseMul(basePositionUnit, subjectSetQuantity); - const expectedBaseBalance = initialBaseBalance.add(baseTokenBoughtNotional); - - expect(finalBaseBalance).eq(expectedBaseBalance); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(10000), // move price up by buying 10k worth of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - const usdcTransferInQuantity = await calculateUSDCTransferInPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await subject(); - - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferInQuantity, subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when issuing multiple sets", async () => { - beforeEach(async () => { - subjectSetQuantity = ether(2); - }); - - it("buys expected amount of vETH, vBTC", async () => { - const totalSupply = await setToken.totalSupply(); - const initialPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - const initialBalance = initialPositionInfo[0].baseBalance; - - await subject(); - - const finalPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - const finalBalance = finalPositionInfo[0].baseBalance; - - const basePositionUnit = preciseDiv(initialBalance, totalSupply); - const baseBoughtNotional = preciseMul(basePositionUnit, subjectSetQuantity); - - const expectedBalance = initialBalance.add(baseBoughtNotional); - - expect(finalBalance).eq(expectedBalance); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const usdcTransferInQuantity = await calculateUSDCTransferInPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await subject(); - - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferInQuantity, subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - }); - - describe("when long, multiple positions", async () => { - // Set up as 2X Long, allow 2% slippage - cacheBeforeEach(async () => { - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - vETH.address, - 2, - ether(.02), - true - ); - - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - vBTC.address, - 1, - ether(.02), - true - ); - }); - - describe("when issuing a single set", async () => { - it("buys expected amount of vETH, vBTC", async () => { - const totalSupply = await setToken.totalSupply(); - const initialPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - - const initialVETHBalance = initialPositionInfo[0].baseBalance; - const initialVBTCBalance = initialPositionInfo[1].baseBalance; - - await subject(); - - const finalPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - const finalVETHBalance = finalPositionInfo[0].baseBalance; - const finalVBTCBalance = finalPositionInfo[1].baseBalance; - - const vETHPositionUnit = preciseDiv(initialVETHBalance, totalSupply); - const vBTCPositionUnit = preciseDiv(initialVBTCBalance, totalSupply); - - const vETHBoughtNotional = preciseMul(vETHPositionUnit, subjectSetQuantity); - const vBTCBoughtNotional = preciseMul(vBTCPositionUnit, subjectSetQuantity); - - const expectedVETHBalance = initialVETHBalance.add(vETHBoughtNotional); - const expectedVBTCBalance = initialVBTCBalance.add(vBTCBoughtNotional); - - expect(finalVETHBalance).eq(expectedVETHBalance); - expect(finalVBTCBalance).eq(expectedVBTCBalance); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const usdcTransferInQuantity = await calculateUSDCTransferInPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await subject(); - - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferInQuantity, subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when issuing multiple sets", async () => { - beforeEach(async () => { - subjectSetQuantity = ether(2); - }); - - it("buys expected amount of vETH, vBTC", async () => { - const totalSupply = await setToken.totalSupply(); - const initialPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - - const initialVETHBalance = initialPositionInfo[0].baseBalance; - const initialVBTCBalance = initialPositionInfo[1].baseBalance; - - await subject(); - - const finalPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - const finalVETHBalance = finalPositionInfo[0].baseBalance; - const finalVBTCBalance = finalPositionInfo[1].baseBalance; - - const vETHPositionUnit = preciseDiv(initialVETHBalance, totalSupply); - const vBTCPositionUnit = preciseDiv(initialVBTCBalance, totalSupply); - - const vETHBoughtNotional = preciseMul(vETHPositionUnit, subjectSetQuantity); - const vBTCBoughtNotional = preciseMul(vBTCPositionUnit, subjectSetQuantity); - - const expectedVETHBalance = initialVETHBalance.add(vETHBoughtNotional); - const expectedVBTCBalance = initialVBTCBalance.add(vBTCBoughtNotional); - - expect(finalVETHBalance).eq(expectedVETHBalance); - expect(finalVBTCBalance).eq(expectedVBTCBalance); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const usdcTransferInQuantity = await calculateUSDCTransferInPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await subject(); - - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferInQuantity, subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when the Set owes funding", async () => { - beforeEach(async() => { - // set funding rate to non-zero value - await perpSetup.clearingHouseConfig.setMaxFundingRate(BigNumber.from(0.1e6)); // 10% in decimal 6 - }); - - it("should socialize the funding payment among existing set holders", async () => { - // Move oracle price down and wait one day - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(9.8)); - await perpSetup.setBaseTokenOraclePrice(vBTC, usdcUnits(19.9)); - await increaseTimeAsync(ONE_DAY_IN_SECONDS); - - const vEthBalance = await perpSetup.accountBalance.getBase(setToken.address, vETH.address); - const vBtcBalance = await perpSetup.accountBalance.getBase(setToken.address, vBTC.address); - const pendingFunding = (await perpLeverageModule.getAccountInfo(subjectSetToken)).pendingFundingPayments; - const usdcTransferInQuantity = await calculateUSDCTransferInPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup, - false // don't include funding - ); - - await subject(); - - const vEthUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vETH.address, vEthBalance, perpSetup); - const vBtcUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vBTC.address, vBtcBalance, perpSetup); - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferInQuantity.add(vEthUsdcAmountDelta).add(vBtcUsdcAmountDelta), subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(pendingFunding).lt(0); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when the Set is owed funding", async () => { - beforeEach(async() => { - // set funding rate to non-zero value - await perpSetup.clearingHouseConfig.setMaxFundingRate(BigNumber.from(0.1e6)); // 10% in decimal 6 - }); - - it("should socialize the funding payment among existing set holders", async () => { - // Move oracle price up and wait one day - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(10.5)); - await perpSetup.setBaseTokenOraclePrice(vBTC, usdcUnits(20.1)); - - await increaseTimeAsync(ONE_DAY_IN_SECONDS); - - const vEthBalance = await perpSetup.accountBalance.getBase(setToken.address, vETH.address); - const vBtcBalance = await perpSetup.accountBalance.getBase(setToken.address, vBTC.address); - const pendingFunding = (await perpLeverageModule.getAccountInfo(subjectSetToken)).pendingFundingPayments; - const usdcTransferInQuantity = await calculateUSDCTransferInPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup, - false // don't include funding - ); - - await subject(); - - const vEthUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vETH.address, vEthBalance, perpSetup); - const vBtcUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vBTC.address, vBtcBalance, perpSetup); - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferInQuantity.add(vEthUsdcAmountDelta).add(vBtcUsdcAmountDelta), subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(pendingFunding).gt(ZERO); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when there is positive owedRealizedPnl", async () => { - beforeEach(async () => { - // Move price up by maker buying 20k USDC of vETH - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(20000), - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vBTC.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(20000), - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - // Delever a little, booking profit to owedRealizedPnl - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - vETH.address, - ether(-.4), - ether(4) - ); - - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - vBTC.address, - ether(-.2), - ether(2) - ); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const owedRealizedPnl = (await perpLeverageModule.getAccountInfo(subjectSetToken)).owedRealizedPnl; - - const usdcTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - const expectedExternalPositionUnit = preciseDiv(usdcTransferInQuantity, subjectSetQuantity); - - await subject(); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(owedRealizedPnl).gt(0); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - }); - - describe("when short", async () => { - let baseToken: Address; - - // Set up as 2X Short, allow 2% slippage - cacheBeforeEach(async () => { - baseToken = vETH.address; - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - baseToken, - 2, - ether(.02), - false - ); - }); - - async function subject(): Promise { - await perpLeverageModule - .connect(subjectCaller.wallet) - .moduleIssueHook(subjectSetToken, subjectSetQuantity); - } - - describe("when issuing a single set", async () => { - it("shorts expected amount of vBase", async () => { - const totalSupply = await setToken.totalSupply(); - - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - await subject(); - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - - const basePositionUnit = preciseDiv(initialBaseBalance, totalSupply); - const baseTokenSoldNotional = preciseMul(basePositionUnit, subjectSetQuantity); - const expectedBaseBalance = initialBaseBalance.add(baseTokenSoldNotional); - - expect(finalBaseBalance).eq(expectedBaseBalance); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const usdcTransferInQuantity = await calculateUSDCTransferInPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await subject(); - - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferInQuantity, subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when there is positive owedRealizedPnl", async () => { - beforeEach(async () => { - // Move price down by maker selling 10k USDC of vETH - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(1000), - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - // Buy a little, booking profit to owedRealizedPnl - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - vETH.address, - ether(.1), - ether(2) - ); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const owedRealizedPnl = (await perpLeverageModule.getAccountInfo(subjectSetToken)).owedRealizedPnl; - - const usdcTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - const expectedExternalPositionUnit = preciseDiv( - usdcTransferInQuantity, - subjectSetQuantity - ); - - await subject(); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(owedRealizedPnl).gt(0); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when there is negative owedRealizedPnl", async () => { - beforeEach(async () => { - // Move price up by maker buying 20k USDC of vETH - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(1000), - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - // Buy a little, booking loss to owedRealizedPnl - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - vETH.address, - ether(.1), - ether(2) - ); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const owedRealizedPnl = (await perpLeverageModule.getAccountInfo(subjectSetToken)).owedRealizedPnl; - - - const usdcTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - const expectedExternalPositionUnit = preciseDiv( - usdcTransferInQuantity, - subjectSetQuantity - ); - - await subject(); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(owedRealizedPnl).lt(0); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when the Set owes funding", async () => { - beforeEach(async() => { - // set funding rate to non-zero value - await perpSetup.clearingHouseConfig.setMaxFundingRate(BigNumber.from(0.1e6)); // 10% in decimal 6 - }); - - it("should socialize the funding payment among existing set holders", async () => { - // Move oracle price up and wait one day - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(10.5)); - await increaseTimeAsync(ONE_DAY_IN_SECONDS); - - const baseBalance = await perpSetup.accountBalance.getBase(setToken.address, baseToken); - const pendingFunding = (await perpLeverageModule.getAccountInfo(subjectSetToken)).pendingFundingPayments; - - const usdcTransferInQuantity = await calculateUSDCTransferInPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup, - false // don't include funding - ); - - await subject(); - - const usdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, baseToken, baseBalance, perpSetup); - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferInQuantity.add(usdcAmountDelta), subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(pendingFunding).lt(0); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when the Set is owed funding", async () => { - beforeEach(async() => { - // set funding rate to non-zero value - await perpSetup.clearingHouseConfig.setMaxFundingRate(BigNumber.from(0.1e6)); // 10% in decimal 6 - }); - - it("should socialize the funding payment among existing set holders", async () => { - // Move oracle price down and wait one day - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(5)); - await increaseTimeAsync(ONE_DAY_IN_SECONDS); - - const baseBalance = await perpSetup.accountBalance.getBase(setToken.address, baseToken); - const pendingFunding = (await perpLeverageModule.getAccountInfo(subjectSetToken)).pendingFundingPayments; - const usdcTransferInQuantity = await calculateUSDCTransferInPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup, - false // don't include funding - ); - - await subject(); - - const usdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, baseToken, baseBalance, perpSetup); - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferInQuantity.add(usdcAmountDelta), subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(pendingFunding).gt(ZERO); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when the market price moves down and leverage drops", async () => { - it("test assumptions and preconditions should be correct", async () => { - let positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - let collateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const initialLeverage = await perpSetup.getCurrentLeverage(subjectSetToken, positionInfo, collateralBalance); - const initialSpotPrice = await perpSetup.getSpotPrice(vETH.address); - const initialUSDCTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(10000), // move price down by selling 10k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - collateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const finalLeverage = await perpSetup.getCurrentLeverage(subjectSetToken, positionInfo, collateralBalance); - const finalSpotPrice = await perpSetup.getSpotPrice(vETH.address); - const finalUSDCTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - expect(initialSpotPrice).gt(finalSpotPrice); - expect(initialUSDCTransferInQuantity).lt(finalUSDCTransferInQuantity); - expect(initialLeverage).gt(ZERO); - expect(finalLeverage).gt(ZERO); - expect(initialLeverage).gt(finalLeverage); - }); - - it("sells expected amount of vBase", async () => { - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(10000), // move price down by selling 10k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - await subject(); - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - - const basePositionUnit = preciseDiv(initialBaseBalance, await setToken.totalSupply()); - const baseTokenBoughtNotional = preciseMul(basePositionUnit, subjectSetQuantity); - const expectedBaseBalance = initialBaseBalance.add(baseTokenBoughtNotional); - - expect(finalBaseBalance).eq(expectedBaseBalance); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(10000), // move price down by selling 10k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - const usdcTransferInQuantity = await calculateUSDCTransferInPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await subject(); - - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferInQuantity, subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - }); - - describe("when long one asset and short another", async () => { - // Long 2 ETH @ 10 USDC, Short 1 BTC @ 20 USDC - cacheBeforeEach(async () => { - await leverUp(setToken, perpLeverageModule, perpSetup, owner, vETH.address, 2, ether(.02), true); - await leverUp(setToken, perpLeverageModule, perpSetup, owner, vBTC.address, 2, ether(.02), false); - }); - - describe("when issuing a single set", async () => { - beforeEach(async () => { - const vETHSpotPrice = await perpSetup.getSpotPrice(vETH.address); - await perpSetup.setBaseTokenOraclePrice(vETH, vETHSpotPrice.div(10 ** 12)); - }); - - it("buys expected amount of vETH, vBTC", async () => { - const totalSupply = await setToken.totalSupply(); - const initialPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - - const initialVETHBalance = initialPositionInfo[0].baseBalance; - const initialVBTCBalance = initialPositionInfo[1].baseBalance; - - await subject(); - - const finalPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - const finalVETHBalance = finalPositionInfo[0].baseBalance; - const finalVBTCBalance = finalPositionInfo[1].baseBalance; - - const vETHPositionUnit = preciseDiv(initialVETHBalance, totalSupply); - const vBTCPositionUnit = preciseDiv(initialVBTCBalance, totalSupply); - - const vETHBoughtNotional = preciseMul(vETHPositionUnit, subjectSetQuantity); - const vBTCBoughtNotional = preciseMul(vBTCPositionUnit, subjectSetQuantity); - - const expectedVETHBalance = initialVETHBalance.add(vETHBoughtNotional); - const expectedVBTCBalance = initialVBTCBalance.add(vBTCBoughtNotional); - - expect(finalVETHBalance).eq(expectedVETHBalance); - expect(finalVBTCBalance).eq(expectedVBTCBalance); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const usdcTransferInQuantity = await calculateUSDCTransferInPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await subject(); - - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferInQuantity, subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - - // Long profit case - describe("when the long asset market price moves up and leverage drops", async () => { - it("test assumptions and preconditions should be correct", async () => { - let positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - let collateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const initialLeverage = await perpSetup.getCurrentLeverage(subjectSetToken, positionInfo, collateralBalance); - const initialSpotPrice = await perpSetup.getSpotPrice(vETH.address); - const initialUSDCTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - // Price increases from ~10 USDC to 12_086_807_119_488_051_322 (~20%) - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(10000), // move price up by buying 10k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - collateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const finalLeverage = await perpSetup.getCurrentLeverage(subjectSetToken, positionInfo, collateralBalance); - const finalSpotPrice = await perpSetup.getSpotPrice(vETH.address); - const finalUSDCTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - - // Leverage should drop as asset value rises - // initialLeverage = 2041219945269276819 - // finalLeverage = 1731198978421953524 - - // Set should be worth 2X more as price increases in short asset - // Price rose ~20%, so set worth ~40% more - // initialUSDCTransferInQuantity = 10018070 - // finalUSDCTransferInQuantity = 14218995 - expect(initialSpotPrice).lt(finalSpotPrice); - expect(initialUSDCTransferInQuantity).lt(finalUSDCTransferInQuantity); - expect(initialLeverage).gt(ZERO); - expect(finalLeverage).gt(ZERO); - expect(initialLeverage).gt(finalLeverage); - }); - - it("sells expected amount of vBase", async () => { - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // long - isExactInput: false, // `amount` is USDC - amount: ether(10000), // move price up by buying 10k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - await subject(); - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - - const basePositionUnit = preciseDiv(initialBaseBalance, await setToken.totalSupply()); - const baseTokenBoughtNotional = preciseMul(basePositionUnit, subjectSetQuantity); - const expectedBaseBalance = initialBaseBalance.add(baseTokenBoughtNotional); - - expect(finalBaseBalance).eq(expectedBaseBalance); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // long - isExactInput: false, // `amount` is USDC - amount: ether(1000), // move price up by buying 1k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - const usdcTransferInQuantity = await calculateUSDCTransferInPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await subject(); - - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferInQuantity, subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - // Short profit case - describe("when the short asset market price moves down and leverage drops", async () => { - it("test assumptions and preconditions should be correct", async () => { - let positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[1]; - let collateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const initialLeverage = await perpSetup.getCurrentLeverage(subjectSetToken, positionInfo, collateralBalance); - const initialSpotPrice = await perpSetup.getSpotPrice(vBTC.address); - const initialUSDCTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - // Price decreases from ~20 USDC to 16_156_467_088_301_771_700 (~20%) - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vBTC.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(20000), // move price down by selling 20k USDC of vBTC - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - - positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[1]; - collateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const finalLeverage = await perpSetup.getCurrentLeverage(subjectSetToken, positionInfo, collateralBalance); - const finalSpotPrice = await perpSetup.getSpotPrice(vBTC.address); - const finalUSDCTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - // Leverage should drop as asset value rises - // initialLeverage = 2039159946037302515 - // finalLeverage = 1184528742574169001 - - // Set should be worth 2X more as price decreases in short asset - // Price dropped ~20%, so set worth ~40% more - // initialUSDCTransferInQuantity = 10_018_070 - // finalUSDCTransferInQuantity = 13_814_709 - expect(initialSpotPrice).gt(finalSpotPrice); - expect(initialUSDCTransferInQuantity).lt(finalUSDCTransferInQuantity); - expect(initialLeverage).gt(ZERO); - expect(finalLeverage).gt(ZERO); - expect(initialLeverage).gt(finalLeverage); - }); - - it("sells expected amount of vBase", async () => { - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vBTC.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(20000), // move price down by selling 20k USDC of vBTC - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - await subject(); - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - - const basePositionUnit = preciseDiv(initialBaseBalance, await setToken.totalSupply()); - const baseTokenBoughtNotional = preciseMul(basePositionUnit, subjectSetQuantity); - const expectedBaseBalance = initialBaseBalance.add(baseTokenBoughtNotional); - - expect(finalBaseBalance).eq(expectedBaseBalance); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vBTC.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(2000), // move price down by selling 2k USDC of vBTC - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - const usdcTransferInQuantity = await calculateUSDCTransferInPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await subject(); - - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferInQuantity, subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - }); - - describe("when there is positive owedRealizedPnl", async () => { - beforeEach(async () => { - // Move price up by maker selling buying USDC of vETH - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(2000), - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - // Sell a little, booking profit to owedRealizedPnl - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - vETH.address, - ether(.1).mul(-1), - ZERO - ); - - const vETHSpotPrice = await perpSetup.getSpotPrice(vETH.address); - await perpSetup.setBaseTokenOraclePrice(vETH, vETHSpotPrice.div(10 ** 12)); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const owedRealizedPnl = (await perpLeverageModule.getAccountInfo(subjectSetToken)).owedRealizedPnl; - - const usdcTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - const expectedExternalPositionUnit = preciseDiv( - usdcTransferInQuantity, - subjectSetQuantity - ); - - await subject(); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - expect(owedRealizedPnl).gt(0); - }); - }); - - describe("when there is negative owedRealizedPnl", async () => { - beforeEach(async () => { - // Move price down by maker selling 1k USDC of vETH - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(1000), - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - // Sell a little, booking profit to owedRealizedPnl - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - vETH.address, - ether(.1).mul(-1), - ZERO - ); - - const vETHSpotPrice = await perpSetup.getSpotPrice(vETH.address); - await perpSetup.setBaseTokenOraclePrice(vETH, vETHSpotPrice.div(10 ** 12)); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const owedRealizedPnl = (await perpLeverageModule.getAccountInfo(subjectSetToken)).owedRealizedPnl; - - const usdcTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - const expectedExternalPositionUnit = preciseDiv( - usdcTransferInQuantity, - subjectSetQuantity - ); - - await subject(); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - expect(owedRealizedPnl).lt(0); - }); - }); - - describe("when the Set owes funding", async () => { - beforeEach(async() => { - // set funding rate to non-zero value - await perpSetup.clearingHouseConfig.setMaxFundingRate(BigNumber.from(0.1e6)); // 10% in decimal 6 - }); - - it("should socialize the funding payment among existing set holders", async () => { - // Move oracle price up and wait one day - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(9.5)); - await increaseTimeAsync(ONE_DAY_IN_SECONDS); - - const vEthBalance = await perpSetup.accountBalance.getBase(setToken.address, vETH.address); - const vBtcBalance = await perpSetup.accountBalance.getBase(setToken.address, vBTC.address); - const pendingFunding = (await perpLeverageModule.getAccountInfo(subjectSetToken)).pendingFundingPayments; - const usdcTransferInQuantity = await calculateUSDCTransferInPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup, - false // don't include funding - ); - - await subject(); - - const vEthUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vETH.address, vEthBalance, perpSetup); - const vBtcUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vBTC.address, vBtcBalance, perpSetup); - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferInQuantity.add(vEthUsdcAmountDelta).add(vBtcUsdcAmountDelta), subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(pendingFunding).lt(0); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when the Set is owed funding", async () => { - beforeEach(async() => { - // set funding rate to non-zero value - await perpSetup.clearingHouseConfig.setMaxFundingRate(BigNumber.from(0.1e6)); // 10% in decimal 6 - }); - - it("should socialize the funding payment among existing set holders", async () => { - // Move oracle price down and wait one day - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(11)); - await increaseTimeAsync(ONE_DAY_IN_SECONDS); - - const vEthBalance = await perpSetup.accountBalance.getBase(setToken.address, vETH.address); - const vBtcBalance = await perpSetup.accountBalance.getBase(setToken.address, vBTC.address); - const pendingFunding = (await perpLeverageModule.getAccountInfo(subjectSetToken)).pendingFundingPayments; - const usdcTransferInQuantity = await calculateUSDCTransferInPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup, - false // don't include funding - ); - - await subject(); - - const vEthUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vETH.address, vEthBalance, perpSetup); - const vBtcUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vBTC.address, vBtcBalance, perpSetup); - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferInQuantity.add(vEthUsdcAmountDelta).add(vBtcUsdcAmountDelta), subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(pendingFunding).gt(ZERO); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when market prices move up and leverage drops", async () => { - it("test assumptions and preconditions should be correct", async () => { - let positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - let collateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const initialLeverage = await perpSetup.getCurrentLeverage(subjectSetToken, positionInfo, collateralBalance); - const initialSpotPrice = await perpSetup.getSpotPrice(vETH.address); - const initialUSDCTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(2000), // move price up by buying 10k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vBTC.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(4000), // move price up by buying 10k USDC of vBTC - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - collateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const finalLeverage = await perpSetup.getCurrentLeverage(subjectSetToken, positionInfo, collateralBalance); - const finalSpotPrice = await perpSetup.getSpotPrice(vETH.address); - const finalUSDCTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - expect(initialSpotPrice).lt(finalSpotPrice); - expect(initialUSDCTransferInQuantity).lt(finalUSDCTransferInQuantity); - expect(initialLeverage).gt(ZERO); - expect(finalLeverage).gt(ZERO); - expect(initialLeverage).gt(finalLeverage); - }); - - it("sells expected amount of vBase", async () => { - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(10000), // move price down by selling 10k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - await subject(); - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - - const basePositionUnit = preciseDiv(initialBaseBalance, await setToken.totalSupply()); - const baseTokenBoughtNotional = preciseMul(basePositionUnit, subjectSetQuantity); - const expectedBaseBalance = initialBaseBalance.add(baseTokenBoughtNotional); - - expect(finalBaseBalance).eq(expectedBaseBalance); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(10000), // move price down by selling 10k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - const usdcTransferInQuantity = await calculateUSDCTransferIn( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - const expectedExternalPositionUnit = preciseDiv(usdcTransferInQuantity, subjectSetQuantity); - - await subject(); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - }); - - describe("when collateral is deposited but no position is open", async () => { - async function subject(): Promise { - await perpLeverageModule - .connect(subjectCaller.wallet) - .moduleIssueHook(subjectSetToken, subjectSetQuantity); - } - - it("deposits the correct amount of collateral", async () => { - const currentPositionUnit = await setToken.getExternalPositionRealUnit(perpSetup.usdc.address, perpLeverageModule.address); - - await subject(); - - const newPositionUnit = await setToken.getExternalPositionRealUnit(perpSetup.usdc.address, perpLeverageModule.address); - - expect(currentPositionUnit).eq(newPositionUnit); - }); - }); - - describe("when total supply is 0", async () => { - let otherSetToken: SetToken; - - beforeEach(async () => { - otherSetToken = await setup.createSetToken( - [usdc.address], - [usdcUnits(10)], - [perpLeverageModule.address, debtIssuanceMock.address] - ); - await debtIssuanceMock.initialize(otherSetToken.address); - await perpLeverageModule.updateAllowedSetToken(otherSetToken.address, true); - await perpLeverageModule.connect(owner.wallet).initialize(otherSetToken.address); - - // Initialize mock module - await otherSetToken.addModule(mockModule.address); - await otherSetToken.connect(mockModule.wallet).initializeModule(); - - subjectSetToken = otherSetToken.address; - }); - - it("should not update the USDC externalPositionUnit", async () => { - const initialExternalPositionUnit = await otherSetToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - await subject(); - const finalExternalPositionUnit = await otherSetToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - - const expectedExternalPositionUnit = ZERO; - expect(initialExternalPositionUnit).to.eq(finalExternalPositionUnit); - expect(finalExternalPositionUnit).to.eq(expectedExternalPositionUnit); - }); - }); - - describe("when there is no external USDC position", () => { - let otherSetToken: SetToken; - - beforeEach(async () => { - otherSetToken = await setup.createSetToken( - [usdc.address], - [usdcUnits(10)], - [perpLeverageModule.address, debtIssuanceMock.address, setup.issuanceModule.address] - ); - - await debtIssuanceMock.initialize(otherSetToken.address); - await perpLeverageModule.updateAllowedSetToken(otherSetToken.address, true); - - await perpLeverageModule.connect(owner.wallet).initialize(otherSetToken.address); - - await otherSetToken.addModule(mockModule.address); - await otherSetToken.connect(mockModule.wallet).initializeModule(); - - // Issue to create some supply - await usdc.approve(setup.issuanceModule.address, usdcUnits(1000)); - await setup.issuanceModule.initialize(otherSetToken.address, ADDRESS_ZERO); - await setup.issuanceModule.issue(otherSetToken.address, ether(1), owner.address); - - subjectSetToken = otherSetToken.address; - }); - - it("should not update the externalPositionUnit", async () => { - const initialExternalPositionUnit = await otherSetToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - await subject(); - - const finalExternalPositionUnit = await otherSetToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(initialExternalPositionUnit).eq(ZERO); - expect(initialExternalPositionUnit).eq(finalExternalPositionUnit); - }); - }); - - describe("when caller is not module", async () => { - beforeEach(async () => { - subjectCaller = owner; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Only the module can call"); - }); - }); - - describe("if disabled module is caller", async () => { - beforeEach(async () => { - await setup.controller.removeModule(mockModule.address); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Module must be enabled on controller"); - }); - }); - }); - - describe("#moduleRedeemHook", () => { - let setToken: SetToken; - let collateralQuantity: BigNumber; - let subjectSetToken: Address; - let subjectSetQuantity: BigNumber; - let subjectCaller: Account; - - // Start with initial total supply (2) - const initializeContracts = async () => { - collateralQuantity = usdcUnits(10); - setToken = await issueSetsAndDepositToPerp(collateralQuantity, true, ether(2)); - }; - - const initializeSubjectVariables = () => { - subjectSetToken = setToken.address; - subjectCaller = mockModule; - subjectSetQuantity = ether(1); - }; - - cacheBeforeEach(initializeContracts); - beforeEach(initializeSubjectVariables); - - async function subject(): Promise { - return await perpLeverageModule - .connect(subjectCaller.wallet) - .moduleRedeemHook(subjectSetToken, subjectSetQuantity); - } - - describe("when long", async () => { - let baseToken: Address; - - // Set up as 2X Long, allow 2% slippage - cacheBeforeEach(async () => { - baseToken = vETH.address; - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - baseToken, - 2, - ether(.02), - true - ); - }); - - describe("when redeeming a single set", async () => { - it("sells expected amount of vBase", async () => { - const totalSupply = await setToken.totalSupply(); - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - const basePositionUnit = preciseDiv(initialBaseBalance, totalSupply); - - await subject(); - - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - const baseTokenSoldNotional = initialBaseBalance.sub(finalBaseBalance); - - const expectedBaseTokenSoldNotional = preciseMul(basePositionUnit, subjectSetQuantity); - - expect(baseTokenSoldNotional).eq(expectedBaseTokenSoldNotional); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const usdcTransferOutQuantity = await calculateUSDCTransferOutPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await subject(); - - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferOutQuantity, subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.eq(expectedExternalPositionUnit); - }); - }); - - describe("when there is positive owedRealizedPnl", async () => { - beforeEach(async () => { - // Move price up by maker buying 1k USDC of vETH - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(20000), - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - // Sell a little, booking profit to owedRealizedPnl - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - vETH.address, - ether(-.4), - ether(4) - ); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const owedRealizedPnl = (await perpLeverageModule.getAccountInfo(subjectSetToken)).owedRealizedPnl; - - const usdcTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - const expectedExternalPositionUnit = preciseDiv( - usdcTransferOutQuantity, - subjectSetQuantity - ); - - await subject(); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(owedRealizedPnl).gt(0); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when there is negative owedRealizedPnl", async () => { - beforeEach(async () => { - // Move price down by maker selling 1k USDC of vETH - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(10000), - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - // Sell a little, booking loss to owedRealizedPnl - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - vETH.address, - ether(-.2), - ether(1) - ); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const owedRealizedPnl = (await perpLeverageModule.getAccountInfo(subjectSetToken)).owedRealizedPnl; - - const usdcTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - const expectedExternalPositionUnit = preciseDiv( - usdcTransferOutQuantity, - subjectSetQuantity - ); - - await subject(); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(owedRealizedPnl).lt(0); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when the Set owes funding", async () => { - beforeEach(async() => { - // set funding rate to non-zero value - await perpSetup.clearingHouseConfig.setMaxFundingRate(BigNumber.from(0.1e6)); // 10% in decimal 6 - }); - - it("should socialize the funding payment among existing set holders", async () => { - // Move oracle price down and wait one day - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(9.5)); - await increaseTimeAsync(ONE_DAY_IN_SECONDS); - - const vEthBalance = await perpSetup.accountBalance.getBase(setToken.address, vETH.address); - const pendingFunding = (await perpLeverageModule.getAccountInfo(subjectSetToken)).pendingFundingPayments; - const usdcTransferOutQuantity = await calculateUSDCTransferOutPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup, - false // don't include funding - ); - - await subject(); - - const vEthUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vETH.address, vEthBalance, perpSetup); - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferOutQuantity.add(vEthUsdcAmountDelta), subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(pendingFunding).lt(0); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when the Set is owed funding", async () => { - beforeEach(async() => { - // set funding rate to non-zero value - await perpSetup.clearingHouseConfig.setMaxFundingRate(BigNumber.from(0.1e6)); // 10% in decimal 6 - }); - - it("should socialize the funding payment among existing set holders", async () => { - // Move oracle price up and wait one day - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(15)); - await increaseTimeAsync(ONE_DAY_IN_SECONDS); - - const vEthBalance = await perpSetup.accountBalance.getBase(setToken.address, vETH.address); - const pendingFunding = (await perpLeverageModule.getAccountInfo(subjectSetToken)).pendingFundingPayments; - const usdcTransferOutQuantity = await calculateUSDCTransferOutPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup, - false // don't include funding - ); - - await subject(); - - const vEthUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vETH.address, vEthBalance, perpSetup); - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferOutQuantity.add(vEthUsdcAmountDelta), subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(pendingFunding).gt(ether(1)); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when the market price moves up and leverage drops", async () => { - it("test assumptions and preconditions should be correct", async () => { - let positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - let collateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const initialLeverage = await perpSetup.getCurrentLeverage(subjectSetToken, positionInfo, collateralBalance); - const initialSpotPrice = await perpSetup.getSpotPrice(vETH.address); - const initialUSDCTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(10000), // move price up by buying 10k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - collateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const finalLeverage = await perpSetup.getCurrentLeverage(subjectSetToken, positionInfo, collateralBalance); - const finalSpotPrice = await perpSetup.getSpotPrice(vETH.address); - const finalUSDCTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - expect(initialSpotPrice).lt(finalSpotPrice); - expect(initialUSDCTransferOutQuantity).lt(finalUSDCTransferOutQuantity); - expect(initialLeverage).gt(ZERO); - expect(finalLeverage).gt(ZERO); - expect(initialLeverage).gt(finalLeverage); - }); - - it("buys expected amount of vBase", async () => { - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(10000), // move price up by buying 10k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - await subject(); - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - - const basePositionUnit = preciseDiv(initialBaseBalance, await setToken.totalSupply()); - const baseTokenBoughtNotional = preciseMul(basePositionUnit, subjectSetQuantity); - const expectedBaseBalance = initialBaseBalance.sub(baseTokenBoughtNotional); - - expect(finalBaseBalance).eq(expectedBaseBalance); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(10000), // move price up by buying 10k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - const usdcTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - const expectedExternalPositionUnit = preciseDiv(usdcTransferOutQuantity, subjectSetQuantity); - - await subject(); - - const actualExternalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(actualExternalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when redeeming multiple sets", async () => { - beforeEach(async () => { - subjectSetQuantity = ether(2); - }); - - it("sells expected amount of vBase", async () => { - const totalSupply = await setToken.totalSupply(); - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - const basePositionUnit = preciseDiv(initialBaseBalance, totalSupply); - - await subject(); - - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - const baseTokenSoldNotional = initialBaseBalance.sub(finalBaseBalance); - - const expectedBaseTokenSoldNotional = preciseMul(basePositionUnit, subjectSetQuantity); - - expect(baseTokenSoldNotional).eq(expectedBaseTokenSoldNotional); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const usdcTransferOutQuantity = await calculateUSDCTransferOutPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await subject(); - - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferOutQuantity, subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.eq(expectedExternalPositionUnit); - }); - }); - }); - - describe("when long, multiple positions", async () => { - // Set up as 2X Long, allow 2% slippage - cacheBeforeEach(async () => { - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - vETH.address, - 2, - ether(.02), - true - ); - - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - vBTC.address, - 1, - ether(.02), - true - ); - }); - - describe("when redeeming a single set", async () => { - it("sells expected amount of vETH, vBTC", async () => { - const totalSupply = await setToken.totalSupply(); - const initialPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - - const initialVETHBalance = initialPositionInfo[0].baseBalance; - const initialVBTCBalance = initialPositionInfo[1].baseBalance; - - await subject(); - - const finalPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - const finalVETHBalance = finalPositionInfo[0].baseBalance; - const finalVBTCBalance = finalPositionInfo[1].baseBalance; - - const vETHPositionUnit = preciseDiv(initialVETHBalance, totalSupply); - const vBTCPositionUnit = preciseDiv(initialVBTCBalance, totalSupply); - - const vETHSoldNotional = preciseMul(vETHPositionUnit, subjectSetQuantity); - const vBTCSoldNotional = preciseMul(vBTCPositionUnit, subjectSetQuantity); - - const expectedVETHBalance = initialVETHBalance.sub(vETHSoldNotional); - const expectedVBTCBalance = initialVBTCBalance.sub(vBTCSoldNotional); - - expect(finalVETHBalance).eq(expectedVETHBalance); - expect(finalVBTCBalance).eq(expectedVBTCBalance); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const usdcTransferOutQuantity = await calculateUSDCTransferOutPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await subject(); - - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferOutQuantity, subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when redeeming multiple sets", async () => { - it("buys expected amount of vETH, vBTC", async () => { - const totalSupply = await setToken.totalSupply(); - const initialPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - - const initialVETHBalance = initialPositionInfo[0].baseBalance; - const initialVBTCBalance = initialPositionInfo[1].baseBalance; - - await subject(); - - const finalPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - const finalVETHBalance = finalPositionInfo[0].baseBalance; - const finalVBTCBalance = finalPositionInfo[1].baseBalance; - - const vETHPositionUnit = preciseDiv(initialVETHBalance, totalSupply); - const vBTCPositionUnit = preciseDiv(initialVBTCBalance, totalSupply); - - const vETHBoughtNotional = preciseMul(vETHPositionUnit, subjectSetQuantity); - const vBTCBoughtNotional = preciseMul(vBTCPositionUnit, subjectSetQuantity); - - const expectedVETHBalance = initialVETHBalance.sub(vETHBoughtNotional); - const expectedVBTCBalance = initialVBTCBalance.sub(vBTCBoughtNotional); - - expect(finalVETHBalance).eq(expectedVETHBalance); - expect(finalVBTCBalance).eq(expectedVBTCBalance); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const usdcTransferOutQuantity = await calculateUSDCTransferOutPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await subject(); - - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferOutQuantity, subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when the Set owes funding", async () => { - beforeEach(async() => { - // set funding rate to non-zero value - await perpSetup.clearingHouseConfig.setMaxFundingRate(BigNumber.from(0.1e6)); // 10% in decimal 6 - }); - - it("should socialize the funding payment among existing set holders", async () => { - // Move oracle price down and wait one day - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(9.8)); - await perpSetup.setBaseTokenOraclePrice(vBTC, usdcUnits(19.9)); - - await increaseTimeAsync(ONE_DAY_IN_SECONDS); - const vEthBalance = await perpSetup.accountBalance.getBase(setToken.address, vETH.address); - const vBtcBalance = await perpSetup.accountBalance.getBase(setToken.address, vBTC.address); - const pendingFunding = (await perpLeverageModule.getAccountInfo(subjectSetToken)).pendingFundingPayments; - const usdcTransferOutQuantity = await calculateUSDCTransferOutPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup, - false // don't include funding - ); - - await subject(); - - const vEthUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vETH.address, vEthBalance, perpSetup); - const vBtcUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vBTC.address, vBtcBalance, perpSetup); - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferOutQuantity.add(vEthUsdcAmountDelta).add(vBtcUsdcAmountDelta), subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(pendingFunding).lt(0); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when the Set is owed funding", async () => { - beforeEach(async() => { - // set funding rate to non-zero value - await perpSetup.clearingHouseConfig.setMaxFundingRate(BigNumber.from(0.1e6)); // 10% in decimal 6 - }); - - it("should socialize the funding payment among existing set holders", async () => { - // Move oracle price up and wait one day - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(10.3)); - await perpSetup.setBaseTokenOraclePrice(vBTC, usdcUnits(20.2)); - - await increaseTimeAsync(ONE_DAY_IN_SECONDS); - - const vEthBalance = await perpSetup.accountBalance.getBase(setToken.address, vETH.address); - const vBtcBalance = await perpSetup.accountBalance.getBase(setToken.address, vBTC.address); - const pendingFunding = (await perpLeverageModule.getAccountInfo(subjectSetToken)).pendingFundingPayments; - const usdcTransferOutQuantity = await calculateUSDCTransferOutPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup, - false // don't include funding - ); - - await subject(); - - const vEthUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vETH.address, vEthBalance, perpSetup); - const vBtcUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vBTC.address, vBtcBalance, perpSetup); - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferOutQuantity.add(vEthUsdcAmountDelta).add(vBtcUsdcAmountDelta), subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(pendingFunding).gt(ether(1)); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when there is positive owedRealizedPnl", async () => { - beforeEach(async () => { - // Move price up by maker buying 2k USDC of vETH - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(2000), - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vBTC.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(2000), - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - // Sell a little, booking profit to owedRealizedPnl - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - vETH.address, - ether(-.4), - ether(4) - ); - - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - vBTC.address, - ether(-.4), - ether(4) - ); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const owedRealizedPnl = (await perpLeverageModule.getAccountInfo(subjectSetToken)).owedRealizedPnl; - - const usdcTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - const expectedExternalPositionUnit = preciseDiv( - usdcTransferOutQuantity, - subjectSetQuantity - ); - - await subject(); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(owedRealizedPnl).gt(0); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - }); - - describe("when short", async () => { - let baseToken: Address; - - // Set up as 2X Short, allow 2% slippage - cacheBeforeEach(async () => { - baseToken = vETH.address; - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - baseToken, - 2, - ether(.02), - false - ); - }); - - describe("when redeeming a single set", async () => { - it("buys expected amount of vBase", async () => { - const totalSupply = await setToken.totalSupply(); - - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - await subject(); - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - - const basePositionUnit = preciseDiv(initialBaseBalance, totalSupply); - const baseTokenBoughtNotional = preciseMul(basePositionUnit, subjectSetQuantity); - const expectedBaseBalance = initialBaseBalance.sub(baseTokenBoughtNotional); - - expect(finalBaseBalance).eq(expectedBaseBalance); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const usdcTransferOutQuantity = await calculateUSDCTransferOutPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await subject(); - - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferOutQuantity, subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when there is positive owedRealizedPnl", async () => { - beforeEach(async () => { - // Move price down by maker buying 1k USDC of vETH - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(10000), - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - // Buy a little, booking profit to owedRealizedPnl - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - vETH.address, - ether(.1), - ether(2) - ); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - // owedRealizedPnl = 1_643_798_014_140_064_947 - const owedRealizedPnl = (await perpLeverageModule.getAccountInfo(subjectSetToken)).owedRealizedPnl; - - const usdcTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - const expectedExternalPositionUnit = preciseDiv( - usdcTransferOutQuantity, - subjectSetQuantity - ); - - await subject(); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(owedRealizedPnl).gt(0); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when there is negative owedRealizedPnl", async () => { - beforeEach(async () => { - // Move price up by maker buy 1k USDC of vETH - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(10000), - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - // Buy a little, booking loss to owedRealizedPnl - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - vETH.address, - ether(.1), - ether(2) - ); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const owedRealizedPnl = (await perpLeverageModule.getAccountInfo(subjectSetToken)).owedRealizedPnl; - - const usdcTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - const expectedExternalPositionUnit = preciseDiv( - usdcTransferOutQuantity, - subjectSetQuantity - ); - - await subject(); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(owedRealizedPnl).lt(0); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when the Set owes funding", async () => { - beforeEach(async() => { - // set funding rate to non-zero value - await perpSetup.clearingHouseConfig.setMaxFundingRate(BigNumber.from(0.1e6)); // 10% in decimal 6 - }); - - it("should socialize the funding payment among existing set holders", async () => { - // Move oracle price up and wait one day - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(10.5)); - await increaseTimeAsync(ONE_DAY_IN_SECONDS); - - const vEthBalance = await perpSetup.accountBalance.getBase(setToken.address, vETH.address); - const pendingFunding = (await perpLeverageModule.getAccountInfo(subjectSetToken)).pendingFundingPayments; - const usdcTransferOutQuantity = await calculateUSDCTransferOutPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup, - false // don't include funding - ); - - await subject(); - - const vEthUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vETH.address, vEthBalance, perpSetup); - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferOutQuantity.add(vEthUsdcAmountDelta), subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(pendingFunding).lt(0); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when the Set is owed funding", async () => { - beforeEach(async() => { - // set funding rate to non-zero value - await perpSetup.clearingHouseConfig.setMaxFundingRate(BigNumber.from(0.1e6)); // 10% in decimal 6 - }); - - it("should socialize the funding payment among existing set holders", async () => { - // Move oracle price down and wait one day - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(5)); - await increaseTimeAsync(ONE_DAY_IN_SECONDS); - - const vEthBalance = await perpSetup.accountBalance.getBase(setToken.address, vETH.address); - const pendingFunding = (await perpLeverageModule.getAccountInfo(subjectSetToken)).pendingFundingPayments; - const usdcTransferOutQuantity = await calculateUSDCTransferOutPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup, - false // don't include funding - ); - - await subject(); - - const vEthUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vETH.address, vEthBalance, perpSetup); - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferOutQuantity.add(vEthUsdcAmountDelta), subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - // We expect pending funding to be greater than -1 USDC and discount applied - expect(pendingFunding).gt(0); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when the market price moves down and leverage drops", async () => { - it("test assumptions and preconditions should be correct", async () => { - let positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - let collateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const initialLeverage = await perpSetup.getCurrentLeverage(subjectSetToken, positionInfo, collateralBalance); - const initialSpotPrice = await perpSetup.getSpotPrice(vETH.address); - const initialUSDCTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(10000), // move price down by selling 10k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - collateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const finalLeverage = await perpSetup.getCurrentLeverage(subjectSetToken, positionInfo, collateralBalance); - const finalSpotPrice = await perpSetup.getSpotPrice(vETH.address); - const finalUSDCTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - expect(initialSpotPrice).gt(finalSpotPrice); - expect(initialUSDCTransferOutQuantity).lt(finalUSDCTransferOutQuantity); - expect(initialLeverage).gt(ZERO); - expect(finalLeverage).gt(ZERO); - expect(initialLeverage).gt(finalLeverage); - }); - - it("buys expected amount of vBase", async () => { - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(10000), // move price down by selling 10k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - await subject(); - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - - const basePositionUnit = preciseDiv(initialBaseBalance, await setToken.totalSupply()); - const baseTokenBoughtNotional = preciseMul(basePositionUnit, subjectSetQuantity); - const expectedBaseBalance = initialBaseBalance.sub(baseTokenBoughtNotional); - - expect(finalBaseBalance).eq(expectedBaseBalance); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(10000), // move price down by selling 10k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - const usdcTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - const expectedExternalPositionUnit = preciseDiv(usdcTransferOutQuantity, subjectSetQuantity); - - await subject(); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when redeeming multiple sets", async () => { - it("should set the expected USDC externalPositionUnit", async () => { - const usdcTransferOutQuantity = await calculateUSDCTransferOutPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await subject(); - - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferOutQuantity, subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - }); - - describe("when long one asset and short another", async () => { - // Long 2 ETH @ 10 USDC, Short 1 BTC @ 20 USDC - cacheBeforeEach(async () => { - await leverUp(setToken, perpLeverageModule, perpSetup, owner, vETH.address, 2, ether(.02), true); - await leverUp(setToken, perpLeverageModule, perpSetup, owner, vBTC.address, 2, ether(.02), false); - }); - - describe("when redeeming a single set", async () => { - beforeEach(async () => { - const vETHSpotPrice = await perpSetup.getSpotPrice(vETH.address); - await perpSetup.setBaseTokenOraclePrice(vETH, vETHSpotPrice.div(10 ** 12)); - }); - - it("sells expected amount of vETH, buys expected amount of vBTC", async () => { - const totalSupply = await setToken.totalSupply(); - const initialPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - - const initialVETHBalance = initialPositionInfo[0].baseBalance; - const initialVBTCBalance = initialPositionInfo[1].baseBalance; - - await subject(); - - const finalPositionInfo = await perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - const finalVETHBalance = finalPositionInfo[0].baseBalance; - const finalVBTCBalance = finalPositionInfo[1].baseBalance; - - const vETHPositionUnit = preciseDiv(initialVETHBalance, totalSupply); - const vBTCPositionUnit = preciseDiv(initialVBTCBalance, totalSupply); - - const vETHBoughtNotional = preciseMul(vETHPositionUnit, subjectSetQuantity); - const vBTCBoughtNotional = preciseMul(vBTCPositionUnit, subjectSetQuantity); - - const expectedVETHBalance = initialVETHBalance.sub(vETHBoughtNotional); - const expectedVBTCBalance = initialVBTCBalance.sub(vBTCBoughtNotional); - - expect(finalVETHBalance).eq(expectedVETHBalance); - expect(finalVBTCBalance).eq(expectedVBTCBalance); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const usdcTransferOutQuantity = await calculateUSDCTransferOutPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await subject(); - - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferOutQuantity, subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - - // Long profit case - describe("when the long asset market price moves up and leverage drops", async () => { - it("test assumptions and preconditions should be correct", async () => { - let positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - let collateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const initialLeverage = await perpSetup.getCurrentLeverage(subjectSetToken, positionInfo, collateralBalance); - const initialSpotPrice = await perpSetup.getSpotPrice(vETH.address); - const initialUSDCTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - // Price increases from ~10 USDC to 12_086_807_119_488_051_322 (~20%) - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(10000), // move price up by buying 10k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0]; - collateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const finalLeverage = await perpSetup.getCurrentLeverage(subjectSetToken, positionInfo, collateralBalance); - const finalSpotPrice = await perpSetup.getSpotPrice(vETH.address); - const finalUSDCTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - - // Leverage should drop as asset value rises - // initialLeverage = 2041219945269276819 - // finalLeverage = 1731198978421953524 - - // Set should be worth 2X more as price increases in short asset - // Price rose ~20%, so set worth ~40% more - // initialUSDCTransferInQuantity = 9201861 - // finalUSDCTransferInQuantity = 13316592 - expect(initialSpotPrice).lt(finalSpotPrice); - expect(initialUSDCTransferOutQuantity).lt(finalUSDCTransferOutQuantity); - expect(initialLeverage).gt(ZERO); - expect(finalLeverage).gt(ZERO); - expect(initialLeverage).gt(finalLeverage); - }); - - it("sells expected amount of vBase", async () => { - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // long - isExactInput: false, // `amount` is USDC - amount: ether(10000), // move price up by buying 10k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - await subject(); - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - - const basePositionUnit = preciseDiv(initialBaseBalance, await setToken.totalSupply()); - const baseTokenSoldNotional = preciseMul(basePositionUnit, subjectSetQuantity); - const expectedBaseBalance = initialBaseBalance.sub(baseTokenSoldNotional); - - expect(finalBaseBalance).eq(expectedBaseBalance); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // long - isExactInput: false, // `amount` is USDC - amount: ether(10000), // move price up by buying 10k USDC of vETH - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - const usdcTransferOutQuantity = await calculateUSDCTransferOutPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await subject(); - - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferOutQuantity, subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - // Short profit case - describe("when the short asset market price moves down and leverage drops", async () => { - it("test assumptions and preconditions should be correct", async () => { - let positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[1]; - let collateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const initialLeverage = await perpSetup.getCurrentLeverage(subjectSetToken, positionInfo, collateralBalance); - const initialSpotPrice = await perpSetup.getSpotPrice(vBTC.address); - const initialUSDCTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - // Price decreases from ~20 USDC to 16_156_467_088_301_771_700 (~20%) - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vBTC.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(20000), // move price down by selling 20k USDC of vBTC - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - - positionInfo = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[1]; - collateralBalance = (await perpLeverageModule.getAccountInfo(subjectSetToken)).collateralBalance; - - const finalLeverage = await perpSetup.getCurrentLeverage(subjectSetToken, positionInfo, collateralBalance); - const finalSpotPrice = await perpSetup.getSpotPrice(vBTC.address); - const finalUSDCTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - // Leverage should drop as asset value rises - // initialLeverage = 2039159946037302515 - // finalLeverage = 1184528742574169001 - - // Set should be worth 2X more as price decreases in short asset - // Price dropped ~20%, so set worth ~40% more - // initialUSDCTransferOutQuantity = 9201861 - // finalUSDCTransferOutQuantity = 13076691 - expect(initialSpotPrice).gt(finalSpotPrice); - expect(initialUSDCTransferOutQuantity).lt(finalUSDCTransferOutQuantity); - expect(initialLeverage).gt(ZERO); - expect(finalLeverage).gt(ZERO); - expect(initialLeverage).gt(finalLeverage); - }); - - it("buys expected amount of vBase", async () => { - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vBTC.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(20000), // move price down by selling 20k USDC of vBTC - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - await subject(); - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - - const basePositionUnit = preciseDiv(initialBaseBalance, await setToken.totalSupply()); - const baseTokenBoughtNotional = preciseMul(basePositionUnit, subjectSetQuantity); - const expectedBaseBalance = initialBaseBalance.sub(baseTokenBoughtNotional); - - expect(finalBaseBalance).eq(expectedBaseBalance); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vBTC.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(2000), // move price down by selling 2k USDC of vBTC - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - const usdcTransferOutQuantity = await calculateUSDCTransferOutPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - await subject(); - - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferOutQuantity, subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - }); - - describe("when there is positive owedRealizedPnl", async () => { - beforeEach(async () => { - // Move price down by maker selling 2k USDC of vETH - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: false, // long - isExactInput: true, // `amount` is USDC - amount: ether(2000), - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - // Sell a little, booking profit to owedRealizedPnl - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - vETH.address, - ether(.1).mul(-1), - ZERO - ); - - const vETHSpotPrice = await perpSetup.getSpotPrice(vETH.address); - await perpSetup.setBaseTokenOraclePrice(vETH, vETHSpotPrice.div(10 ** 12)); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const owedRealizedPnl = (await perpLeverageModule.getAccountInfo(subjectSetToken)).owedRealizedPnl; - - const usdcTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - const expectedExternalPositionUnit = preciseDiv( - usdcTransferOutQuantity, - subjectSetQuantity - ); - - await subject(); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(owedRealizedPnl).gt(0); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when there is negative owedRealizedPnl", async () => { - beforeEach(async () => { - // Move price down by maker selling 1k USDC of vETH - await perpSetup.clearingHouse.connect(maker.wallet).openPosition({ - baseToken: vETH.address, - isBaseToQuote: true, // short - isExactInput: false, // `amount` is USDC - amount: ether(1000), - oppositeAmountBound: ZERO, - deadline: MAX_UINT_256, - sqrtPriceLimitX96: ZERO, - referralCode: ZERO_BYTES - }); - - // Sell a little, booking profit to owedRealizedPnl - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - vETH.address, - ether(.1).mul(-1), - ZERO - ); - - const vETHSpotPrice = await perpSetup.getSpotPrice(vETH.address); - await perpSetup.setBaseTokenOraclePrice(vETH, vETHSpotPrice.div(10 ** 12)); - }); - - it("should set the expected USDC externalPositionUnit", async () => { - const owedRealizedPnl = (await perpLeverageModule.getAccountInfo(subjectSetToken)).owedRealizedPnl; - - const usdcTransferOutQuantity = await calculateUSDCTransferOut( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - const expectedExternalPositionUnit = preciseDiv( - usdcTransferOutQuantity, - subjectSetQuantity - ); - - await subject(); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(owedRealizedPnl).lt(0); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when the Set owes funding", async () => { - beforeEach(async() => { - // set funding rate to non-zero value - await perpSetup.clearingHouseConfig.setMaxFundingRate(BigNumber.from(0.1e6)); // 10% in decimal 6 - }); - - it("should socialize the funding payment among existing set holders", async () => { - // Move oracle price up and wait one day - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(9.7)); - await increaseTimeAsync(ONE_DAY_IN_SECONDS); - - const vEthBalance = await perpSetup.accountBalance.getBase(setToken.address, vETH.address); - const vBtcBalance = await perpSetup.accountBalance.getBase(setToken.address, vBTC.address); - const pendingFunding = (await perpLeverageModule.getAccountInfo(subjectSetToken)).pendingFundingPayments; - const usdcTransferOutQuantity = await calculateUSDCTransferOutPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup, - false // don't include funding - ); - - await subject(); - - const vEthUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vETH.address, vEthBalance, perpSetup); - const vBtcUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vBTC.address, vBtcBalance, perpSetup); - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferOutQuantity.add(vEthUsdcAmountDelta).add(vBtcUsdcAmountDelta), subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(pendingFunding).lt(0); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - - describe("when the Set is owed funding", async () => { - beforeEach(async() => { - // set funding rate to non-zero value - await perpSetup.clearingHouseConfig.setMaxFundingRate(BigNumber.from(0.1e6)); // 10% in decimal 6 - }); - - it("should socialize the funding payment among existing set holders", async () => { - // Move oracle price down and wait one day - await perpSetup.setBaseTokenOraclePrice(vETH, usdcUnits(11)); - await increaseTimeAsync(ONE_DAY_IN_SECONDS); - - const vEthBalance = await perpSetup.accountBalance.getBase(setToken.address, vETH.address); - const vBtcBalance = await perpSetup.accountBalance.getBase(setToken.address, vBTC.address); - const pendingFunding = (await perpLeverageModule.getAccountInfo(subjectSetToken)).pendingFundingPayments; - const usdcTransferOutQuantity = await calculateUSDCTransferOutPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup, - false // don't include funding - ); - - await subject(); - - const vEthUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vETH.address, vEthBalance, perpSetup); - const vBtcUsdcAmountDelta = await getUSDCDeltaDueToFundingGrowth(setToken, subjectSetQuantity, vBTC.address, vBtcBalance, perpSetup); - const expectedExternalPositionUnit = toUSDCDecimals( - preciseDiv(usdcTransferOutQuantity.add(vEthUsdcAmountDelta).add(vBtcUsdcAmountDelta), subjectSetQuantity) - ); - - const externalPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(pendingFunding).gt(ZERO); - expect(externalPositionUnit).to.be.eq(expectedExternalPositionUnit); - }); - }); - }); - - describe("when total supply is 0", async () => { - let otherSetToken: SetToken; - - beforeEach(async () => { - otherSetToken = await setup.createSetToken( - [usdc.address], - [usdcUnits(10)], - [perpLeverageModule.address, debtIssuanceMock.address] - ); - await debtIssuanceMock.initialize(otherSetToken.address); - await perpLeverageModule.updateAllowedSetToken(otherSetToken.address, true); - await perpLeverageModule.connect(owner.wallet).initialize(otherSetToken.address); - - // Initialize mock module - await otherSetToken.addModule(mockModule.address); - await otherSetToken.connect(mockModule.wallet).initializeModule(); - - subjectSetToken = otherSetToken.address; - }); - - it("should not update the USDC externalPositionUnit", async () => { - const initialExternalPositionUnit = await otherSetToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - await subject(); - const finalExternalPositionUnit = await otherSetToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - - const expectedExternalPositionUnit = ZERO; - expect(initialExternalPositionUnit).to.eq(finalExternalPositionUnit); - expect(finalExternalPositionUnit).to.eq(expectedExternalPositionUnit); - }); - }); - - describe("when there is no external USDC position", () => { - let otherSetToken: SetToken; - - beforeEach(async () => { - otherSetToken = await setup.createSetToken( - [usdc.address], - [usdcUnits(10)], - [perpLeverageModule.address, debtIssuanceMock.address, setup.issuanceModule.address] - ); - - await debtIssuanceMock.initialize(otherSetToken.address); - await perpLeverageModule.updateAllowedSetToken(otherSetToken.address, true); - - await perpLeverageModule.connect(owner.wallet).initialize(otherSetToken.address); - - await otherSetToken.addModule(mockModule.address); - await otherSetToken.connect(mockModule.wallet).initializeModule(); - - // Issue to create some supply - await usdc.approve(setup.issuanceModule.address, usdcUnits(1000)); - await setup.issuanceModule.initialize(otherSetToken.address, ADDRESS_ZERO); - await setup.issuanceModule.issue(otherSetToken.address, ether(2), owner.address); - - subjectSetToken = otherSetToken.address; - }); - - it("should not update the externalPositionUnit", async () => { - const initialExternalPositionUnit = await otherSetToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - await subject(); - - const finalExternalPositionUnit = await otherSetToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - expect(initialExternalPositionUnit).eq(ZERO); - expect(initialExternalPositionUnit).eq(finalExternalPositionUnit); - }); - }); - - describe("when caller is not module", async () => { - beforeEach(async () => subjectCaller = owner); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Only the module can call"); - }); - }); - - describe("if disabled module is caller", async () => { - beforeEach(async () => { - await setup.controller.removeModule(mockModule.address); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Module must be enabled on controller"); - }); - }); - }); - - describe("#componentIssueHook", () => { - let setToken: SetToken; - let collateralQuantity: BigNumber; - let subjectSetToken: Address; - let subjectSetQuantity: BigNumber; - let subjectIsEquity: boolean; - let subjectCaller: Account; - - const initializeContracts = async () => { - collateralQuantity = usdcUnits(10); - setToken = await issueSetsAndDepositToPerp(collateralQuantity); - }; - - const initializeSubjectVariables = () => { - subjectSetToken = setToken.address; - subjectCaller = mockModule; - subjectSetQuantity = ether(1); - subjectIsEquity = true; - }; - - cacheBeforeEach(initializeContracts); - beforeEach(initializeSubjectVariables); - - async function subject(): Promise { - return await perpLeverageModule.connect(subjectCaller.wallet).componentIssueHook( - subjectSetToken, - subjectSetQuantity, - usdc.address, - subjectIsEquity - ); - } - - describe("when long", () => { - // Set up as 2X Long, allow 2% slippage - cacheBeforeEach(async () => { - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - vETH.address, - 2, - ether(.02), - true - ); - - await perpLeverageModule - .connect(subjectCaller.wallet) - .moduleIssueHook(subjectSetToken, subjectSetQuantity); - }); - - it("transfer the expected amount from SetToken to Perp vault", async () => { - const initialSetTokenUSDCBalance = await usdc.balanceOf(subjectSetToken); - - const externalUSDCPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - const usdcToTransferOut = preciseMul(externalUSDCPositionUnit, subjectSetQuantity); - - await subject(); - - const finalSetTokenUSDCBalance = await usdc.balanceOf(subjectSetToken); - const expectedSetTokenUSDCBalance = initialSetTokenUSDCBalance.sub(usdcToTransferOut); - - expect(finalSetTokenUSDCBalance).eq(expectedSetTokenUSDCBalance); - }); - - it("should not update the USDC defaultPositionUnit", async () => { - const initialDefaultPosition = await setToken.getDefaultPositionRealUnit(usdc.address); - - await subject(); - - const finalDefaultPosition = await setToken.getDefaultPositionRealUnit(usdc.address); - - expect(finalDefaultPosition).to.eq(initialDefaultPosition); - }); - - it("should not update the USDC externalPositionUnit", async () => { - const initialExternalPositionUnit = await setToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - await subject(); - const finalExternalPositionUnit = await setToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - - expect(initialExternalPositionUnit).eq(finalExternalPositionUnit); - }); - }); - - describe("when short", () => { - // Set up as 2X Short, allow 2% slippage - cacheBeforeEach(async () => { - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - vETH.address, - 2, - ether(.02), - false - ); - - await perpLeverageModule - .connect(subjectCaller.wallet) - .moduleIssueHook(subjectSetToken, subjectSetQuantity); - }); - - it("transfer the expected amount from SetToken to Perp vault", async () => { - const initialSetTokenUSDCBalance = await usdc.balanceOf(subjectSetToken); - - const externalUSDCPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - const usdcToTransferOut = preciseMul(externalUSDCPositionUnit, subjectSetQuantity); - - await subject(); - - const finalSetTokenUSDCBalance = await usdc.balanceOf(subjectSetToken); - const expectedSetTokenUSDCBalance = initialSetTokenUSDCBalance.sub(usdcToTransferOut); - - expect(finalSetTokenUSDCBalance).eq(expectedSetTokenUSDCBalance); - }); - - it("should not update the USDC defaultPositionUnit", async () => { - const initialDefaultPosition = await setToken.getDefaultPositionRealUnit(usdc.address); - - await subject(); - - const finalDefaultPosition = await setToken.getDefaultPositionRealUnit(usdc.address); - - expect(finalDefaultPosition).to.eq(initialDefaultPosition); - }); - - it("should not update the USDC externalPositionUnit", async () => { - const initialExternalPositionUnit = await setToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - await subject(); - const finalExternalPositionUnit = await setToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - - expect(initialExternalPositionUnit).eq(finalExternalPositionUnit); - }); - }); - - describe("when isEquity is false", async () => { - beforeEach(async () => { - subjectIsEquity = false; - }); - - it("should deposit nothing", async () => { - const { - collateralBalance: initialCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken); - - await subject(); - - const { - collateralBalance: finalCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken); - - expect(initialCollateralBalance).to.eq(finalCollateralBalance); - }); - }); - - describe("when caller is not module", async () => { - beforeEach(async () => { - subjectCaller = owner; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Only the module can call"); - }); - }); - - describe("if disabled module is caller", async () => { - beforeEach(async () => { - await setup.controller.removeModule(mockModule.address); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Module must be enabled on controller"); - }); - }); - }); - - describe("#componentRedeemHook", () => { - let setToken: SetToken; - let collateralQuantity: BigNumber; - let subjectSetToken: Address; - let subjectSetQuantity: BigNumber; - let subjectIsEquity: boolean; - let subjectCaller: Account; - - const initializeContracts = async () => { - collateralQuantity = usdcUnits(10); - setToken = await issueSetsAndDepositToPerp(collateralQuantity); - }; - - const initializeSubjectVariables = () => { - subjectSetToken = setToken.address; - subjectCaller = mockModule; - subjectSetQuantity = ether(.5); // Sell half - subjectIsEquity = true; - }; - - cacheBeforeEach(initializeContracts); - beforeEach(initializeSubjectVariables); - - async function subject(): Promise { - return await perpLeverageModule.connect(subjectCaller.wallet).componentRedeemHook( - subjectSetToken, - subjectSetQuantity, - usdc.address, - subjectIsEquity - ); - } - - describe("when long", () => { - // Set up as 2X Long, allow 2% slippage - cacheBeforeEach(async () => { - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - vETH.address, - 2, - ether(.02), - true - ); - - await perpLeverageModule - .connect(subjectCaller.wallet) - .moduleRedeemHook(subjectSetToken, subjectSetQuantity); - }); - - it("transfer the expected amount from Perp vault to SetToken", async () => { - const initialSetTokenUSDCBalance = await usdc.balanceOf(subjectSetToken); - - const externalUSDCPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - const usdcToTransferOut = preciseMul(externalUSDCPositionUnit, subjectSetQuantity); - - await subject(); - - const finalSetTokenUSDCBalance = await usdc.balanceOf(subjectSetToken); - const expectedSetTokenUSDCBalance = initialSetTokenUSDCBalance.add(usdcToTransferOut); - - expect(finalSetTokenUSDCBalance).eq(expectedSetTokenUSDCBalance); - }); - - it("should not update the USDC defaultPositionUnit", async () => { - const initialDefaultPositionUnit = await setToken.getDefaultPositionRealUnit(usdc.address); - await subject(); - const finalDefaultPositionUnit = await setToken.getDefaultPositionRealUnit(usdc.address); - - expect(initialDefaultPositionUnit).eq(finalDefaultPositionUnit); - }); - - it("should not update the USDC externalPositionUnit", async () => { - const initialExternalPositionUnit = await setToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - await subject(); - const finalExternalPositionUnit = await setToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - - expect(initialExternalPositionUnit).eq(finalExternalPositionUnit); - }); - }); - - describe("when short", () => { - // Set up as 2X Short, allow 2% slippage - cacheBeforeEach(async () => { - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - vETH.address, - 2, - ether(.02), - false - ); - - await perpLeverageModule - .connect(subjectCaller.wallet) - .moduleRedeemHook(subjectSetToken, subjectSetQuantity); - }); - - it("transfer the expected amount from Perp vault to SetToken", async () => { - const initialSetTokenUSDCBalance = await usdc.balanceOf(subjectSetToken); - - const externalUSDCPositionUnit = await setToken.getExternalPositionRealUnit( - usdc.address, - perpLeverageModule.address - ); - - const usdcToTransferOut = preciseMul(externalUSDCPositionUnit, subjectSetQuantity); - - await subject(); - - const finalSetTokenUSDCBalance = await usdc.balanceOf(subjectSetToken); - const expectedSetTokenUSDCBalance = initialSetTokenUSDCBalance.add(usdcToTransferOut); - - expect(finalSetTokenUSDCBalance).eq(expectedSetTokenUSDCBalance); - }); - - it("should not update the USDC defaultPositionUnit", async () => { - const initialDefaultPositionUnit = await setToken.getDefaultPositionRealUnit(usdc.address); - await subject(); - const finalDefaultPositionUnit = await setToken.getDefaultPositionRealUnit(usdc.address); - - expect(initialDefaultPositionUnit).eq(finalDefaultPositionUnit); - }); - - it("should not update the USDC externalPositionUnit", async () => { - const initialExternalPositionUnit = await setToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - await subject(); - const finalExternalPositionUnit = await setToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - - expect(initialExternalPositionUnit).eq(finalExternalPositionUnit); - }); - }); - - describe("when isEquity is false", async () => { - beforeEach(async () => { - subjectIsEquity = false; - }); - - it("should withdraw nothing", async () => { - const { - collateralBalance: initialCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken); - - await subject(); - - const { - collateralBalance: finalCollateralBalance - } = await perpLeverageModule.getAccountInfo(subjectSetToken); - - expect(initialCollateralBalance).to.eq(finalCollateralBalance); - }); - }); - - describe("when caller is not module", async () => { - beforeEach(async () => { - subjectCaller = owner; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Only the module can call"); - }); - }); - - describe("if disabled module is caller", async () => { - beforeEach(async () => { - await setup.controller.removeModule(mockModule.address); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Module must be enabled on controller"); - }); - }); - }); - - describe("#registerToModule", async () => { - let setToken: SetToken; - let otherIssuanceModule: DebtIssuanceMock; - let isInitialized: boolean; - let subjectSetToken: Address; - let subjectDebtIssuanceModule: Address; - - const initializeContracts = async function () { - otherIssuanceModule = await deployer.mocks.deployDebtIssuanceMock(); - await setup.controller.addModule(otherIssuanceModule.address); - - setToken = await setup.createSetToken( - [usdc.address], - [ether(100)], - [perpLeverageModule.address, setup.issuanceModule.address, debtIssuanceMock.address] - ); - await debtIssuanceMock.initialize(setToken.address); - // Add SetToken to allow list - await perpLeverageModule.updateAllowedSetToken(setToken.address, true); - // Initialize module if set to true - if (isInitialized) { - await perpLeverageModule.initialize(setToken.address); - } - await setup.issuanceModule.initialize(setToken.address, ADDRESS_ZERO); - // Add other issuance mock after initializing PerpV2LeverageModule, so register is never called - await setToken.addModule(otherIssuanceModule.address); - await otherIssuanceModule.initialize(setToken.address); - }; - - const initializeSubjectVariables = () => { - subjectSetToken = setToken.address; - subjectDebtIssuanceModule = otherIssuanceModule.address; - }; - - async function subject(): Promise { - return perpLeverageModule.registerToModule(subjectSetToken, subjectDebtIssuanceModule); - } - - describe("when module is initialized", () => { - beforeEach(() => { - isInitialized = true; - }); - - cacheBeforeEach(initializeContracts); - beforeEach(initializeSubjectVariables); - - it("should register on the other issuance module", async () => { - const previousIsRegistered = await otherIssuanceModule.isRegistered(setToken.address); - await subject(); - const currentIsRegistered = await otherIssuanceModule.isRegistered(setToken.address); - expect(previousIsRegistered).to.be.false; - expect(currentIsRegistered).to.be.true; - }); - - describe("when SetToken is not valid", async () => { - beforeEach(async () => { - const nonEnabledSetToken = await setup.createNonControllerEnabledSetToken( - [usdc.address], - [ether(1)], - [perpLeverageModule.address], - owner.address - ); - - subjectSetToken = nonEnabledSetToken.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be a valid and initialized SetToken"); - }); - }); - - describe("when debt issuance module is not initialized on SetToken", async () => { - beforeEach(async () => { - await setToken.removeModule(otherIssuanceModule.address); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Issuance not initialized"); - }); - }); - }); - - describe("when module is not initialized", async () => { - beforeEach(async () => { - isInitialized = false; - await initializeContracts(); - initializeSubjectVariables(); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Must be a valid and initialized SetToken"); - }); - }); - }); - - describe("#removeModule", async () => { - let setToken: SetToken; - let subjectModule: Address; - - cacheBeforeEach(async () => { - setToken = await setup.createSetToken( - [usdc.address], - [ether(100)], - [perpLeverageModule.address, debtIssuanceMock.address, setup.issuanceModule.address] - ); - await debtIssuanceMock.initialize(setToken.address); - // Add SetToken to allow list - await perpLeverageModule.updateAllowedSetToken(setToken.address, true); - await perpLeverageModule.initialize(setToken.address); - await setup.issuanceModule.initialize(setToken.address, ADDRESS_ZERO); - - // Approve tokens to issuance module and call issue - await usdc.approve(setup.issuanceModule.address, ether(100)); - await setup.issuanceModule.issue(setToken.address, ether(1), owner.address); - }); - - beforeEach(() => { - subjectModule = perpLeverageModule.address; - }); - - async function subject(): Promise { - return setToken.removeModule(subjectModule); - } - - it("should remove the Module on the SetToken", async () => { - await subject(); - const isModuleEnabled = await setToken.isInitializedModule(perpLeverageModule.address); - expect(isModuleEnabled).to.be.false; - }); - - it("should unregister on the debt issuance module", async () => { - await subject(); - const isRegistered = await debtIssuanceMock.isRegistered(setToken.address); - expect(isRegistered).to.be.false; - }); - - describe("when the account balance is positive", async () => { - beforeEach(async () => { - await perpLeverageModule.deposit(setToken.address, usdcUnits(10)); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Account balance exists"); - }); - }); - }); - - describe("#getIssuanceAdjustments", () => { - let setToken: SetToken; - let collateralQuantity: BigNumber; - let subjectSetToken: Address; - let subjectCaller: Account; - let subjectSetQuantity: BigNumber; - - const initializeContracts = async () => { - collateralQuantity = usdcUnits(10); - setToken = await issueSetsAndDepositToPerp(collateralQuantity); - }; - - const initializeSubjectVariables = () => { - subjectSetToken = setToken.address; - subjectCaller = mockModule; - subjectSetQuantity = ether(1); - }; - - cacheBeforeEach(initializeContracts); - beforeEach(initializeSubjectVariables); - - async function subject(): Promise { - return await perpLeverageModule - .connect(subjectCaller.wallet) - .callStatic - .getIssuanceAdjustments(subjectSetToken, subjectSetQuantity); - } - - describe("when long, single position", () => { - let baseToken: Address; - - // Set up as 2X Long, allow 2% slippage - cacheBeforeEach(async () => { - baseToken = vETH.address; - - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - baseToken, - 2, - ether(.02), - true - ); - }); - - describe("when issuing a single set", async () => { - it("does *not* change the vBase balance", async () => { - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - await subject(); - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - - expect(initialBaseBalance).eq(finalBaseBalance); - }); - - it("should return adjustment arrays of the correct length with value in correct position", async () => { - const components = await setToken.getComponents(); - const expectedAdjustmentsLength = components.length; - - const adjustments = await subject(); - - const equityAdjustmentsLength = adjustments[0].length; - const debtAdjustmentsLength = adjustments[1].length; - const wbtcAdjustment = adjustments[0][0]; - const usdcAdjustment = adjustments[0][1]; - - expect(equityAdjustmentsLength).eq(expectedAdjustmentsLength); - expect(debtAdjustmentsLength).eq(debtAdjustmentsLength); - expect(wbtcAdjustment).eq(ZERO); - expect(usdcAdjustment).gt(ZERO); - }); - - it("should return the expected USDC adjustment unit", async () => { - const oldExternalPositionUnit = await setToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - const usdcTransferInQuantity = await calculateUSDCTransferInPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - const actualAdjustmentUnit = (await subject())[0][1]; // call subject - - const newExternalPositionUnit = toUSDCDecimals(preciseDiv(usdcTransferInQuantity, subjectSetQuantity)); - const expectedAdjustmentUnit = newExternalPositionUnit.sub(oldExternalPositionUnit); - - expect(actualAdjustmentUnit).to.be.eq(expectedAdjustmentUnit); - }); - - describe("when the set token doesn't contain the collateral token", async () => { - let otherSetToken: SetToken; - - beforeEach(async () => { - otherSetToken = await setup.createSetToken( - [setup.wbtc.address], - [bitcoin(10)], - [perpLeverageModule.address, debtIssuanceMock.address, setup.issuanceModule.address] - ); - await debtIssuanceMock.initialize(otherSetToken.address); - await perpLeverageModule.updateAllowedSetToken(otherSetToken.address, true); - await perpLeverageModule.connect(owner.wallet).initialize(otherSetToken.address); - - subjectSetToken = otherSetToken.address; - }); - - it("should return empty arrays", async () => { - const components = await otherSetToken.getComponents(); - const adjustments = await subject(); - - const expectedAdjustmentsLength = 2; - const expectedAdjustmentValue = ZERO; - const expectedAdjustmentsArrayLength = components.length; - - expect(adjustments.length).eq(expectedAdjustmentsLength); - expect(adjustments[0].length).eq(expectedAdjustmentsArrayLength); - expect(adjustments[1].length).eq(expectedAdjustmentsArrayLength); - - for (const adjustment of adjustments[0]) { - expect(adjustment).eq(expectedAdjustmentValue); - } - - for (const adjustment of adjustments[1]) { - expect(adjustment).eq(expectedAdjustmentValue); - } - }); - }); - }); - }); - }); - - describe("#getRedemptionAdjustments", () => { - let setToken: SetToken; - let collateralQuantity: BigNumber; - let subjectSetToken: Address; - let subjectSetQuantity: BigNumber; - let subjectCaller: Account; - - const initializeContracts = async () => { - collateralQuantity = usdcUnits(10); - setToken = await issueSetsAndDepositToPerp(collateralQuantity); - }; - - const initializeSubjectVariables = () => { - subjectSetToken = setToken.address; - subjectCaller = mockModule; - subjectSetQuantity = ether(1); - }; - - cacheBeforeEach(initializeContracts); - beforeEach(initializeSubjectVariables); - - async function subject(): Promise { - return await perpLeverageModule - .connect(subjectCaller.wallet) - .callStatic - .getRedemptionAdjustments(subjectSetToken, subjectSetQuantity); - } - - describe("when long", async () => { - let baseToken: Address; - - // Set up as 2X Long, allow 2% slippage - cacheBeforeEach(async () => { - baseToken = vETH.address; - - await leverUp( - setToken, - perpLeverageModule, - perpSetup, - owner, - baseToken, - 2, - ether(.02), - true - ); - }); - - describe("when redeeming a single set", async () => { - it("should *not* alter the vBase balance", async () => { - const initialBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - await subject(); - const finalBaseBalance = (await perpLeverageModule.getPositionNotionalInfo(subjectSetToken))[0].baseBalance; - - expect(initialBaseBalance).eq(finalBaseBalance); - }); - - it("should return adjustment arrays of the correct length with value in correct position", async () => { - const components = await setToken.getComponents(); - const expectedAdjustmentsLength = components.length; - - const adjustments = await subject(); - - const equityAdjustmentsLength = adjustments[0].length; - const debtAdjustmentsLength = adjustments[1].length; - const wbtcAdjustment = adjustments[0][0]; - const usdcAdjustment = adjustments[0][1]; - - expect(equityAdjustmentsLength).eq(expectedAdjustmentsLength); - expect(debtAdjustmentsLength).eq(debtAdjustmentsLength); - expect(wbtcAdjustment).eq(ZERO); - expect(usdcAdjustment).lt(ZERO); - }); - - it("should return the expected USDC adjustment unit", async () => { - const oldExternalPositionUnit = await setToken.getExternalPositionRealUnit(usdc.address, perpLeverageModule.address); - const usdcTransferOutQuantity = await calculateUSDCTransferOutPreciseUnits( - setToken, - subjectSetQuantity, - perpLeverageModule, - perpSetup - ); - - const actualAdjustmentUnit = (await subject())[0][1]; // call subject - - const newExternalPositionUnit = toUSDCDecimals(preciseDiv(usdcTransferOutQuantity, subjectSetQuantity)); - const expectedAdjustmentUnit = newExternalPositionUnit.sub(oldExternalPositionUnit); - - expect(actualAdjustmentUnit).to.be.eq(expectedAdjustmentUnit); - }); - - describe("when the set token doesn't contain the collateral token", async () => { - let otherSetToken: SetToken; - - beforeEach(async () => { - otherSetToken = await setup.createSetToken( - [setup.wbtc.address], - [bitcoin(10)], - [perpLeverageModule.address, debtIssuanceMock.address, setup.issuanceModule.address] - ); - await debtIssuanceMock.initialize(otherSetToken.address); - await perpLeverageModule.updateAllowedSetToken(otherSetToken.address, true); - await perpLeverageModule.connect(owner.wallet).initialize(otherSetToken.address); - - subjectSetToken = otherSetToken.address; - }); - - it("should return empty arrays", async () => { - const components = await otherSetToken.getComponents(); - const adjustments = await subject(); - - const expectedAdjustmentsLength = 2; - const expectedAdjustmentValue = ZERO; - const expectedAdjustmentsArrayLength = components.length; - - expect(adjustments.length).eq(expectedAdjustmentsLength); - expect(adjustments[0].length).eq(expectedAdjustmentsArrayLength); - expect(adjustments[1].length).eq(expectedAdjustmentsArrayLength); - - for (const adjustment of adjustments[0]) { - expect(adjustment).eq(expectedAdjustmentValue); - } - - for (const adjustment of adjustments[1]) { - expect(adjustment).eq(expectedAdjustmentValue); - } - }); - }); - }); - }); - }); - - describe("#getPositionNotionalInfo", () => { - let setToken: SetToken; - let subjectSetToken: Address; - - let issueQuantity: BigNumber; - let expectedVETHToken: Address; - let expectedVBTCToken: Address; - let vethTradeQuantityUnits: BigNumber; - let vbtcTradeQuantityUnits: BigNumber; - let expectedDepositQuantity: BigNumber; - let expectedVETHDeltaQuote: BigNumber; - let expectedVBTCDeltaQuote: BigNumber; - - beforeEach(async () => { - expectedDepositQuantity = usdcUnits(100); - issueQuantity = ether(2); - - setToken = await issueSetsAndDepositToPerp(expectedDepositQuantity, true, issueQuantity); - - subjectSetToken = setToken.address; - expectedVETHToken = vETH.address; - expectedVBTCToken = vBTC.address; - vethTradeQuantityUnits = ether(1); - vbtcTradeQuantityUnits = ether(2); - - ({ deltaQuote: expectedVETHDeltaQuote } = await perpSetup.getSwapQuote( - expectedVETHToken, - preciseMul(vethTradeQuantityUnits, issueQuantity), - true - )); - - ({ deltaQuote: expectedVBTCDeltaQuote } = await perpSetup.getSwapQuote( - expectedVBTCToken, - preciseMul(vbtcTradeQuantityUnits, issueQuantity), - true - )); - - const vETHQuoteBoundQuantityUnits = ether(10.15); - const vBTCQuoteBoundQuantityUnits = ether(101); - - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - expectedVETHToken, - vethTradeQuantityUnits, - vETHQuoteBoundQuantityUnits - ); - - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - expectedVBTCToken, - vbtcTradeQuantityUnits, - vBTCQuoteBoundQuantityUnits - ); - }); - - async function subject(): Promise { - return perpLeverageModule.getPositionNotionalInfo(subjectSetToken); - } - - it("should return info for multiple positions", async () => { - const positionInfo = await subject(); - - const expectedVETHNotionalPosition = preciseMul(vethTradeQuantityUnits, issueQuantity); - const expectedVBTCNotionalPosition = preciseMul(vbtcTradeQuantityUnits, issueQuantity); - - expect(positionInfo.length).eq(2); - expect(positionInfo[0].baseToken).eq(expectedVETHToken); - expect(positionInfo[1].baseToken).eq(expectedVBTCToken); - expect(positionInfo[0].baseBalance).eq(expectedVETHNotionalPosition); - expect(positionInfo[1].baseBalance).eq(expectedVBTCNotionalPosition); - expect(positionInfo[0].quoteBalance).eq(expectedVETHDeltaQuote.mul(-1)); - expect(positionInfo[1].quoteBalance).eq(expectedVBTCDeltaQuote.mul(-1)); - }); - }); - - describe("#getPositionUnitInfo", () => { - let setToken: SetToken; - let issueQuantity: BigNumber; - let subjectSetToken: Address; - - let expectedVETHToken: Address; - let expectedVBTCToken: Address; - let vethTradeQuantityUnits: BigNumber; - let vbtcTradeQuantityUnits: BigNumber; - let expectedDepositQuantity: BigNumber; - let expectedVETHQuoteUnits: BigNumber; - let expectedVBTCQuoteUnits: BigNumber; - - beforeEach(async () => { - issueQuantity = ether(2); - expectedDepositQuantity = usdcUnits(100); - - // Issue 2 sets - setToken = await issueSetsAndDepositToPerp(expectedDepositQuantity, true, issueQuantity); - - subjectSetToken = setToken.address; - expectedVETHToken = vETH.address; - expectedVBTCToken = vBTC.address; - vethTradeQuantityUnits = preciseDiv(ether(1), issueQuantity); - vbtcTradeQuantityUnits = preciseDiv(ether(1), issueQuantity); - - const vETHQuoteBoundQuantityUnits = preciseDiv(ether(10.15), issueQuantity); - const vBTCQuoteBoundQuantityUnits = preciseDiv(ether(50.575), issueQuantity); - - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - expectedVETHToken, - vethTradeQuantityUnits, - vETHQuoteBoundQuantityUnits - ); - - await perpLeverageModule.connect(owner.wallet).trade( - subjectSetToken, - expectedVBTCToken, - vbtcTradeQuantityUnits, - vBTCQuoteBoundQuantityUnits - ); - }); - - async function subject(): Promise { - return perpLeverageModule.getPositionUnitInfo(subjectSetToken); - } - - it("should return info for multiple positions", async () => { - const vETHQuoteBalance = await perpSetup.accountBalance.getQuote(subjectSetToken, expectedVETHToken); - const vBTCQuoteBalance = await perpSetup.accountBalance.getQuote(subjectSetToken, expectedVBTCToken); - - expectedVETHQuoteUnits = preciseDiv(vETHQuoteBalance, issueQuantity); - expectedVBTCQuoteUnits = preciseDiv(vBTCQuoteBalance, issueQuantity); - - const positionInfo = await subject(); - - expect(positionInfo.length).eq(2); - expect(positionInfo[0].baseToken).eq(expectedVETHToken); - expect(positionInfo[1].baseToken).eq(expectedVBTCToken); - expect(positionInfo[0].baseUnit).eq(vethTradeQuantityUnits); - expect(positionInfo[1].baseUnit).eq(vbtcTradeQuantityUnits); - expect(positionInfo[0].quoteUnit).eq(expectedVETHQuoteUnits); - expect(positionInfo[1].quoteUnit).eq(expectedVBTCQuoteUnits); - }); - }); - - describe("#getAccountInfo", () => { - let setToken: SetToken; - let subjectSetToken: Address; - let expectedDepositQuantity: BigNumber; - - beforeEach(async () => { - expectedDepositQuantity = usdcUnits(10); - setToken = await issueSetsAndDepositToPerp(expectedDepositQuantity); - subjectSetToken = setToken.address; - - await leverUp(setToken, perpLeverageModule, perpSetup, owner, vETH.address, 2, ether(0.02), true); - await increaseTimeAsync(ONE_DAY_IN_SECONDS); - }); - - async function subject(): Promise { - return perpLeverageModule.getAccountInfo(subjectSetToken); - } - - it("should return account info", async () => { - const pendingFunding = await perpSetup.exchange.getAllPendingFundingPayment(setToken.address); - - const accountInfo = await subject(); - - const expectedFunding = pendingFunding.mul(-1); - - expect(toUSDCDecimals(accountInfo.collateralBalance)).eq(expectedDepositQuantity); - expect(accountInfo.owedRealizedPnl).eq(0); - expect(accountInfo.pendingFundingPayments).eq(expectedFunding); - }); - }); - - describe("#updateMaxPerpPositionsPerSet", async () => { - let subjectCaller: Account; - let subjectMaxPerpPositionsPerSet: BigNumber; - - beforeEach(async () => { - subjectCaller = owner; - subjectMaxPerpPositionsPerSet = THREE; - }); - - async function subject(): Promise { - await perpLeverageModule.connect(subjectCaller.wallet).updateMaxPerpPositionsPerSet(subjectMaxPerpPositionsPerSet); - } - - it("should update max perp positions per set", async () => { - await subject(); - - const maxPerpPositionsPerSet = await perpLeverageModule.maxPerpPositionsPerSet(); - - expect(maxPerpPositionsPerSet).to.eq(THREE); - }); - - describe("when owner is not caller", async () => { - beforeEach(async () => { - subjectCaller = await getRandomAccount(); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Ownable: caller is not the owner"); - }); - }); - }); -}); diff --git a/utils/common/perpV2Utils.ts b/utils/common/perpV2Utils.ts index 109509335..942671969 100644 --- a/utils/common/perpV2Utils.ts +++ b/utils/common/perpV2Utils.ts @@ -9,7 +9,7 @@ import { } from "../index"; import { TWO, ZERO, ONE_DAY_IN_SECONDS } from "../constants"; -import { PerpV2BasisTradingModule, PerpV2LeverageModule, SetToken } from "../contracts"; +import { PerpV2BasisTradingModule, PerpV2LeverageModuleV2, SetToken } from "../contracts"; import { PerpV2Fixture } from "../fixtures"; @@ -21,7 +21,7 @@ export function toUSDCDecimals(quantity: BigNumber): BigNumber { // Allocates all deposited collateral to a levered position. Returns new baseToken position unit export async function leverUp( setToken: SetToken, - module: PerpV2LeverageModule, + module: PerpV2LeverageModuleV2, fixture: PerpV2Fixture, owner: Account, baseToken: Address, @@ -65,7 +65,7 @@ export async function leverUp( export async function calculateUSDCTransferIn( setToken: SetToken, setQuantity: BigNumber, - module: PerpV2LeverageModule, + module: PerpV2LeverageModuleV2, fixture: PerpV2Fixture, ) { return toUSDCDecimals(await calculateUSDCTransferInPreciseUnits(setToken, setQuantity, module, fixture)); @@ -75,7 +75,7 @@ export async function calculateUSDCTransferIn( export async function calculateUSDCTransferInPreciseUnits( setToken: SetToken, setQuantity: BigNumber, - module: PerpV2LeverageModule, + module: PerpV2LeverageModuleV2, fixture: PerpV2Fixture, includeFunding: boolean = true ) { @@ -124,7 +124,7 @@ export async function calculateUSDCTransferInPreciseUnits( export async function calculateUSDCTransferOut( setToken: SetToken, setQuantity: BigNumber, - module: PerpV2LeverageModule, + module: PerpV2LeverageModuleV2, fixture: PerpV2Fixture, ) { return toUSDCDecimals(await calculateUSDCTransferOutPreciseUnits(setToken, setQuantity, module, fixture)); @@ -134,7 +134,7 @@ export async function calculateUSDCTransferOut( export async function calculateUSDCTransferOutPreciseUnits( setToken: SetToken, setQuantity: BigNumber, - module: PerpV2LeverageModule | PerpV2BasisTradingModule, + module: PerpV2LeverageModuleV2 | PerpV2BasisTradingModule, fixture: PerpV2Fixture, includeFunding: boolean = true ) { @@ -179,7 +179,7 @@ export async function calculateUSDCTransferOutPreciseUnits( export async function calculateExternalPositionUnit( setToken: SetToken, - module: PerpV2LeverageModule, + module: PerpV2LeverageModuleV2, fixture: PerpV2Fixture, ): Promise { let totalPositionValue = BigNumber.from(0); @@ -272,7 +272,7 @@ export async function getNetFundingGrowth( export async function calculateLeverageRatios( setToken: Address, - perpModule: PerpV2LeverageModule, + perpModule: PerpV2LeverageModuleV2, fixture: PerpV2Fixture, ): Promise<[Address[], BigNumber[]]> { const accountInfo = await perpModule.getAccountInfo(setToken); @@ -300,7 +300,7 @@ export async function calculateLeverageRatios( export async function calculateMaxIssueQuantity( setToken: SetToken, slippage: BigNumber, - perpModule: PerpV2LeverageModule, + perpModule: PerpV2LeverageModuleV2, fixture: PerpV2Fixture, ): Promise { const totalSupply = await setToken.totalSupply(); diff --git a/utils/contracts/aave.ts b/utils/contracts/aave.ts deleted file mode 100644 index af41fd95d..000000000 --- a/utils/contracts/aave.ts +++ /dev/null @@ -1,16 +0,0 @@ -// External Aave Contracts -export { AavePropositionPower } from "../../typechain/AavePropositionPower"; -export { AaveProtoGovernance } from "../../typechain/AaveProtoGovernance"; -export { AaveTokenV2Mintable } from "../../typechain/AaveTokenV2Mintable"; -export { AssetVotingWeightProvider } from "../../typechain/AssetVotingWeightProvider"; -export { AToken } from "../../typechain/AToken"; -export { DefaultReserveInterestRateStrategy } from "../../typechain/DefaultReserveInterestRateStrategy"; -export { GovernanceParamsProvider } from "../../typechain/GovernanceParamsProvider"; -export { LendingPool } from "../../typechain/LendingPool"; -export { LendingPoolCore } from "../../typechain/LendingPoolCore"; -export { LendingPoolAddressesProvider } from "../../typechain/LendingPoolAddressesProvider"; -export { CoreLibrary } from "../../typechain/CoreLibrary"; -export { LendingPoolConfigurator } from "../../typechain/LendingPoolConfigurator"; -export { LendingRateOracle } from "../../typechain/LendingRateOracle"; -export { LendingPoolDataProvider } from "../../typechain/LendingPoolDataProvider"; -export { LendToAaveMigrator } from "../../typechain/LendToAaveMigrator"; \ No newline at end of file diff --git a/utils/contracts/axieInfinity.ts b/utils/contracts/axieInfinity.ts deleted file mode 100644 index e415217bb..000000000 --- a/utils/contracts/axieInfinity.ts +++ /dev/null @@ -1,2 +0,0 @@ -// External Axie Infinity Contracts -export { TokenSwap } from "../../typechain/TokenSwap"; \ No newline at end of file diff --git a/utils/contracts/dg.ts b/utils/contracts/dg.ts deleted file mode 100644 index fe9685dd9..000000000 --- a/utils/contracts/dg.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { DGLight } from "../../typechain/DGLight"; -export { DgToken } from "../../typechain/DgToken"; diff --git a/utils/contracts/index.ts b/utils/contracts/index.ts index 1483ac801..7bb428b03 100644 --- a/utils/contracts/index.ts +++ b/utils/contracts/index.ts @@ -1,10 +1,7 @@ -export { AaveGovernanceAdapter } from "../../typechain/AaveGovernanceAdapter"; export { AaveGovernanceV2Adapter } from "../../typechain/AaveGovernanceV2Adapter"; export { AaveLendingPoolCoreMock } from "../../typechain/AaveLendingPoolCoreMock"; export { AaveLendingPoolMock } from "../../typechain/AaveLendingPoolMock"; export { AaveLeverageModule } from "../../typechain/AaveLeverageModule"; -export { AaveMigrationWrapAdapter } from "../../typechain/AaveMigrationWrapAdapter"; -export { AaveWrapAdapter } from "../../typechain/AaveWrapAdapter"; export { AaveV2 } from "../../typechain/AaveV2"; export { AaveV2Mock } from "../../typechain/AaveV2Mock"; export { AaveV2WrapV2Adapter } from "../../typechain/AaveV2WrapV2Adapter"; @@ -12,9 +9,7 @@ export { AddressArrayUtilsMock } from "../../typechain/AddressArrayUtilsMock"; export { AirdropModule } from "../../typechain/AirdropModule"; export { AmmAdapterMock } from "../../typechain/AmmAdapterMock"; export { AmmModule } from "../../typechain/AmmModule"; -export { AGIMigrationWrapAdapter } from "../../typechain/AGIMigrationWrapAdapter"; export { AssetLimitHook } from "../../typechain/AssetLimitHook"; -export { AxieInfinityMigrationWrapAdapter } from "../../typechain/AxieInfinityMigrationWrapAdapter"; export { BalancerV1IndexExchangeAdapter } from "../../typechain/BalancerV1IndexExchangeAdapter"; export { BasicIssuanceModule } from "../../typechain/BasicIssuanceModule"; export { ChainlinkAggregatorMock } from "../../typechain/ChainlinkAggregatorMock"; @@ -25,7 +20,6 @@ export { CompoundBravoGovernanceAdapter } from "../../typechain/CompoundBravoGov export { CompoundLikeGovernanceAdapter } from "../../typechain/CompoundLikeGovernanceAdapter"; export { CompoundLeverageModule } from "../../typechain/CompoundLeverageModule"; export { CompoundMock } from "../../typechain/CompoundMock"; -export { CompoundWrapAdapter } from "../../typechain/CompoundWrapAdapter"; export { CompoundWrapV2Adapter } from "../../typechain/CompoundWrapV2Adapter"; export { CompClaimAdapter } from "../../typechain/CompClaimAdapter"; export { ComptrollerMock } from "../../typechain/ComptrollerMock"; @@ -39,7 +33,6 @@ export { DebtIssuanceModule } from "../../typechain/DebtIssuanceModule"; export { DebtIssuanceModuleV2 } from "../../typechain/DebtIssuanceModuleV2"; export { DebtModuleMock } from "../../typechain/DebtModuleMock"; export { DelegateRegistry } from "../../typechain/DelegateRegistry"; -export { DgMigrationWrapAdapter } from "../../typechain/DgMigrationWrapAdapter"; export { ExplicitERC20Mock } from "../../typechain/ExplicitERC20Mock"; export { ForceFunderMock } from "../../typechain/ForceFunderMock"; export { GaugeControllerMock } from "../../typechain/GaugeControllerMock"; @@ -53,16 +46,13 @@ export { ISetValuer } from "../../typechain/ISetValuer"; export { IssuanceModule } from "../../typechain/IssuanceModule"; export { KyberExchangeAdapter } from "../../typechain/KyberExchangeAdapter"; export { KyberV3IndexExchangeAdapter } from "../../typechain/KyberV3IndexExchangeAdapter"; -export { KyberMigrationWrapAdapter } from "../../typechain/KyberMigrationWrapAdapter"; export { KyberNetworkProxyMock } from "../../typechain/KyberNetworkProxyMock"; -export { LendToAaveMigrator } from "../../typechain/LendToAaveMigrator"; export { ManagerIssuanceHookMock } from "../../typechain/ManagerIssuanceHookMock"; export { ModuleBaseMock } from "../../typechain/ModuleBaseMock"; export { ModuleBaseV2Mock } from "../../typechain/ModuleBaseV2Mock"; export { ModuleIssuanceHookMock } from "../../typechain/ModuleIssuanceHookMock"; export { NAVIssuanceCaller } from "../../typechain/NAVIssuanceCaller"; export { NAVIssuanceHookMock } from "../../typechain/NAVIssuanceHookMock"; -export { NavIssuanceModule } from "../../typechain/NavIssuanceModule"; export { OneInchExchangeAdapter } from "../../typechain/OneInchExchangeAdapter"; export { OneInchExchangeMock } from "../../typechain/OneInchExchangeMock"; export { OracleAdapterMock } from "../../typechain/OracleAdapterMock"; @@ -78,7 +68,6 @@ export { PerpV2Mock } from "../../typechain/PerpV2Mock"; export { PerpV2LibraryV2Mock } from "../../typechain/PerpV2LibraryV2Mock"; export { PerpV2Positions } from "../../typechain/PerpV2Positions"; export { PerpV2PositionsMock } from "../../typechain/PerpV2PositionsMock"; -export { PerpV2LeverageModule } from "../../typechain/PerpV2LeverageModule"; export { PerpV2LeverageModuleV2 } from "../../typechain/PerpV2LeverageModuleV2"; export { PerpV2BasisTradingModule } from "../../typechain/PerpV2BasisTradingModule"; export { PerpV2LeverageModuleViewer } from "../../typechain/PerpV2LeverageModuleViewer"; @@ -92,7 +81,6 @@ export { SetTokenAccessibleMock } from "../../typechain/SetTokenAccessibleMock"; export { SetTokenCreator } from "../../typechain/SetTokenCreator"; export { SetValuer } from "../../typechain/SetValuer"; export { SingleIndexModule } from "../../typechain/SingleIndexModule"; -export { SingularityNetToken } from "../../typechain/SingularityNetToken"; export { SlippageIssuanceModule } from "../../typechain/SlippageIssuanceModule"; export { SnapshotGovernanceAdapter } from "../../typechain/SnapshotGovernanceAdapter"; export { StakingAdapterMock } from "../../typechain/StakingAdapterMock"; @@ -105,7 +93,6 @@ export { StreamingFeeModule } from "../../typechain/StreamingFeeModule"; export { SynthetixExchangeAdapter } from "../../typechain/SynthetixExchangeAdapter"; export { SynthetixExchangerMock } from "../../typechain/SynthetixExchangerMock"; export { SynthMock } from "../../typechain/SynthMock"; -export { TokenSwap } from "../../typechain/TokenSwap"; export { TradeModule } from "../../typechain/TradeModule"; export { TradeAdapterMock } from "../../typechain/TradeAdapterMock"; export { Uint256ArrayUtilsMock } from "../../typechain/Uint256ArrayUtilsMock"; @@ -121,7 +108,6 @@ export { UniswapV2Factory } from "../../typechain/UniswapV2Factory"; export { AMMSplitter } from "../../typechain/AMMSplitter"; export { UniswapV2Pair } from "../../typechain/UniswapV2Pair"; export { UniswapV2Router02 } from "../../typechain/UniswapV2Router02"; -export { UniswapYieldHook } from "../../typechain/UniswapYieldHook"; export { UniswapV3ExchangeAdapter } from "../../typechain/UniswapV3ExchangeAdapter"; export { UniswapV3MathMock } from "../../typechain/UniswapV3MathMock"; export { UnitConversionUtilsMock } from "../../typechain/UnitConversionUtilsMock"; @@ -130,7 +116,6 @@ export { WrapAdapterMock } from "../../typechain/WrapAdapterMock"; export { WrapV2AdapterMock } from "../../typechain/WrapV2AdapterMock"; export { WrapModule } from "../../typechain/WrapModule"; export { WrapModuleV2 } from "../../typechain/WrapModuleV2"; -export { YearnWrapAdapter } from "../../typechain/YearnWrapAdapter"; export { YearnWrapV2Adapter } from "../../typechain/YearnWrapV2Adapter"; export { YearnStrategyMock } from "../../typechain/YearnStrategyMock"; export { ZeroExApiAdapter } from "../../typechain/ZeroExApiAdapter"; diff --git a/utils/contracts/singularityNet.ts b/utils/contracts/singularityNet.ts deleted file mode 100644 index fb8d75470..000000000 --- a/utils/contracts/singularityNet.ts +++ /dev/null @@ -1,2 +0,0 @@ -// External Axie Infinity Contracts -export { SingularityNetToken } from "../../typechain/SingularityNetToken"; \ No newline at end of file diff --git a/utils/deploys/deployAdapters.ts b/utils/deploys/deployAdapters.ts index 194c666c9..885ce1aaf 100644 --- a/utils/deploys/deployAdapters.ts +++ b/utils/deploys/deployAdapters.ts @@ -1,24 +1,15 @@ import { Signer } from "ethers"; import { - AaveGovernanceAdapter, AaveGovernanceV2Adapter, AaveV2WrapV2Adapter, - AGIMigrationWrapAdapter, - AxieInfinityMigrationWrapAdapter, BalancerV1IndexExchangeAdapter, CompoundLikeGovernanceAdapter, CurveStakingAdapter, - DgMigrationWrapAdapter, KyberExchangeAdapter, KyberV3IndexExchangeAdapter, - KyberMigrationWrapAdapter, OneInchExchangeAdapter, - AaveMigrationWrapAdapter, - AaveWrapAdapter, - CompoundWrapAdapter, CompoundWrapV2Adapter, - YearnWrapAdapter, YearnWrapV2Adapter, UniswapPairPriceAdapter, UniswapV2AmmAdapter, @@ -36,24 +27,16 @@ import { } from "../contracts"; import { Address, Bytes } from "./../types"; -import { AaveGovernanceAdapter__factory } from "../../typechain/factories/AaveGovernanceAdapter__factory"; import { AaveGovernanceV2Adapter__factory } from "../../typechain/factories/AaveGovernanceV2Adapter__factory"; import { AaveV2WrapV2Adapter__factory } from "../../typechain/factories/AaveV2WrapV2Adapter__factory"; -import { AxieInfinityMigrationWrapAdapter__factory } from "../../typechain/factories/AxieInfinityMigrationWrapAdapter__factory"; import { BalancerV1IndexExchangeAdapter__factory } from "../../typechain/factories/BalancerV1IndexExchangeAdapter__factory"; import { CompoundLikeGovernanceAdapter__factory } from "../../typechain/factories/CompoundLikeGovernanceAdapter__factory"; import { CurveStakingAdapter__factory } from "../../typechain/factories/CurveStakingAdapter__factory"; -import { DgMigrationWrapAdapter__factory } from "../../typechain/factories/DgMigrationWrapAdapter__factory"; import { KyberExchangeAdapter__factory } from "../../typechain/factories/KyberExchangeAdapter__factory"; import { KyberV3IndexExchangeAdapter__factory } from "../../typechain/factories/KyberV3IndexExchangeAdapter__factory"; -import { KyberMigrationWrapAdapter__factory } from "../../typechain/factories/KyberMigrationWrapAdapter__factory"; import { OneInchExchangeAdapter__factory } from "../../typechain/factories/OneInchExchangeAdapter__factory"; import { ZeroExApiAdapter__factory } from "../../typechain/factories/ZeroExApiAdapter__factory"; -import { AaveMigrationWrapAdapter__factory } from "../../typechain/factories/AaveMigrationWrapAdapter__factory"; -import { AaveWrapAdapter__factory } from "../../typechain/factories/AaveWrapAdapter__factory"; -import { CompoundWrapAdapter__factory } from "../../typechain/factories/CompoundWrapAdapter__factory"; import { CompoundWrapV2Adapter__factory } from "../../typechain/factories/CompoundWrapV2Adapter__factory"; -import { YearnWrapAdapter__factory } from "../../typechain/factories/YearnWrapAdapter__factory"; import { YearnWrapV2Adapter__factory } from "../../typechain/factories/YearnWrapV2Adapter__factory"; import { UniswapPairPriceAdapter__factory } from "../../typechain/factories/UniswapPairPriceAdapter__factory"; import { UniswapV2ExchangeAdapter__factory } from "../../typechain/factories/UniswapV2ExchangeAdapter__factory"; @@ -66,7 +49,8 @@ import { UniswapV3ExchangeAdapter__factory } from "../../typechain/factories/Uni import { SnapshotGovernanceAdapter__factory } from "../../typechain/factories/SnapshotGovernanceAdapter__factory"; import { SynthetixExchangeAdapter__factory } from "../../typechain/factories/SynthetixExchangeAdapter__factory"; import { CompoundBravoGovernanceAdapter__factory } from "../../typechain/factories/CompoundBravoGovernanceAdapter__factory"; -import { CompClaimAdapter__factory, AGIMigrationWrapAdapter__factory } from "../../typechain"; +import { CompClaimAdapter__factory } from "../../typechain"; + export default class DeployAdapters { private _deployerSigner: Signer; @@ -111,66 +95,14 @@ export default class DeployAdapters { return await new UniswapV2IndexExchangeAdapter__factory(this._deployerSigner).deploy(uniswapV2Router); } - public async deployAaveGovernanceAdapter(aaveProtoGovernance: Address, aaveToken: Address): Promise { - return await new AaveGovernanceAdapter__factory(this._deployerSigner).deploy(aaveProtoGovernance, aaveToken); - } - public async deployAaveGovernanceV2Adapter(aaveGovernanceV2: Address, aaveToken: Address): Promise { return await new AaveGovernanceV2Adapter__factory(this._deployerSigner).deploy(aaveGovernanceV2, aaveToken); } - public async deployAaveMigrationWrapAdapter( - aaveMigrationProxy: Address, - lendToken: Address, - aaveToken: Address - ): Promise { - return await new AaveMigrationWrapAdapter__factory(this._deployerSigner).deploy(aaveMigrationProxy, lendToken, aaveToken); - } - - public async deployKyberMigrationWrapAdapter( - kncLegacyToken: Address, - kncToken: Address - ): Promise { - return await new KyberMigrationWrapAdapter__factory(this._deployerSigner).deploy(kncLegacyToken, kncToken); - } - - public async deployAaveWrapAdapter(aaveLendingPool: Address): Promise { - return await new AaveWrapAdapter__factory(this._deployerSigner).deploy(aaveLendingPool); - } - - public async deployAxieInfinityMigrationWrapAdapter( - tokenSwap: Address, - oldToken: Address, - newToken: Address - ): Promise { - return await new AxieInfinityMigrationWrapAdapter__factory(this._deployerSigner).deploy(tokenSwap, oldToken, newToken); - } - - public async deployAGIMigrationWrapAdapter( - agiLegacyToken: Address, - agixToken: Address - ): Promise { - return await new AGIMigrationWrapAdapter__factory(this._deployerSigner).deploy(agiLegacyToken, agixToken); - } - - public async deployCompoundWrapAdapter(libraryName: string, libraryAddress: Address): Promise { - return await new CompoundWrapAdapter__factory( - // @ts-ignore - { - [libraryName]: libraryAddress, - }, - this._deployerSigner - ).deploy(); - } - public async deployCompClaimAdapter(comptrollerAddress: Address): Promise { return await new CompClaimAdapter__factory(this._deployerSigner).deploy(comptrollerAddress); } - public async deployYearnWrapAdapter(): Promise { - return await new YearnWrapAdapter__factory(this._deployerSigner).deploy(); - } - public async deployBalancerV1IndexExchangeAdapter(balancerProxy: Address): Promise { return await new BalancerV1IndexExchangeAdapter__factory(this._deployerSigner).deploy(balancerProxy); } @@ -187,10 +119,6 @@ export default class DeployAdapters { return await new CurveStakingAdapter__factory(this._deployerSigner).deploy(gaugeController); } - public async deployDgMigrationWrapAdapter(legacyAddress: Address, newAddress: Address): Promise { - return await new DgMigrationWrapAdapter__factory(this._deployerSigner).deploy(legacyAddress, newAddress); - } - public async deployUniswapPairPriceAdapter( controller: Address, uniswapFactory: Address, diff --git a/utils/deploys/deployExternal.ts b/utils/deploys/deployExternal.ts index 5cdd8ea89..7b33d7f02 100644 --- a/utils/deploys/deployExternal.ts +++ b/utils/deploys/deployExternal.ts @@ -35,38 +35,6 @@ import { PriceOracleProxy__factory } from "../../typechain/factories/PriceOracle import { Unitroller__factory } from "../../typechain/factories/Unitroller__factory"; import { WETH9__factory } from "../../typechain/factories/WETH9__factory"; import { WhitePaperInterestRateModel__factory } from "../../typechain/factories/WhitePaperInterestRateModel__factory"; -import { LendingPoolAddressesProvider__factory } from "../../typechain/factories/LendingPoolAddressesProvider__factory"; - -import { - AavePropositionPower, - AaveProtoGovernance, - AaveTokenV2Mintable, - AssetVotingWeightProvider, - CoreLibrary, - DefaultReserveInterestRateStrategy, - GovernanceParamsProvider, - LendingPool, - LendingPoolAddressesProvider, - LendingPoolConfigurator, - LendingPoolCore, - LendingRateOracle, - LendToAaveMigrator -} from "../contracts/aave"; - -import { AaveTokenV2Mintable__factory } from "../../typechain/factories/AaveTokenV2Mintable__factory"; -import { AavePropositionPower__factory } from "../../typechain/factories/AavePropositionPower__factory"; -import { AaveProtoGovernance__factory } from "../../typechain/factories/AaveProtoGovernance__factory"; -import { AssetVotingWeightProvider__factory } from "../../typechain/factories/AssetVotingWeightProvider__factory"; -import { LendingPoolCore__factory, LendingPoolCoreLibraryAddresses } from "../../typechain/factories/LendingPoolCore__factory"; -import { CoreLibrary__factory } from "../../typechain/factories/CoreLibrary__factory"; -import { GovernanceParamsProvider__factory } from "../../typechain/factories/GovernanceParamsProvider__factory"; -import { LendingPool__factory } from "../../typechain/factories/LendingPool__factory"; -import { DefaultReserveInterestRateStrategy__factory } from "../../typechain/factories/DefaultReserveInterestRateStrategy__factory"; -import { LendingPoolConfigurator__factory } from "../../typechain/factories/LendingPoolConfigurator__factory"; -import { LendingRateOracle__factory } from "../../typechain/factories/LendingRateOracle__factory"; -import { LendingPoolDataProvider__factory } from "../../typechain/factories/LendingPoolDataProvider__factory"; -import { LendingPoolDataProvider } from "../../typechain/LendingPoolDataProvider"; -import { LendToAaveMigrator__factory } from "../../typechain/factories/LendToAaveMigrator__factory"; import { CurveDeposit, @@ -136,17 +104,6 @@ import { DMMRouter02__factory } from "../../typechain/factories/DMMRouter02__fac import { DMMPool__factory } from "../../typechain/factories/DMMPool__factory"; import { KyberNetworkTokenV2__factory } from "../../typechain/factories/KyberNetworkTokenV2__factory"; - -import { - TokenSwap -} from "../contracts/index"; -import { TokenSwap__factory } from "../../typechain/factories/TokenSwap__factory"; - -import { - SingularityNetToken -} from "../contracts/index"; -import { SingularityNetToken__factory } from "../../typechain/factories/SingularityNetToken__factory"; - import { SwapRouter, UniswapV3Factory, @@ -177,6 +134,7 @@ import { AaveV2LendingRateOracle, AaveV2Oracle, AaveV2PriceOracle, + AaveTokenV2Mintable, Executor, GovernanceStrategy, GenericLogic, @@ -200,9 +158,11 @@ import { AaveV2LendingRateOracle__factory } from "../../typechain/factories/Aave import { AaveV2Oracle__factory } from "../../typechain/factories/AaveV2Oracle__factory"; import { AaveV2PriceOracle__factory } from "../../typechain/factories/AaveV2PriceOracle__factory"; import { AaveGovernanceV2__factory } from "../../typechain/factories/AaveGovernanceV2__factory"; +import { AaveTokenV2Mintable__factory } from "../../typechain/factories/AaveTokenV2Mintable__factory"; import { Executor__factory } from "../../typechain/factories/Executor__factory"; import { GovernanceStrategy__factory } from "../../typechain/factories/GovernanceStrategy__factory"; + import { PerpV2MarketRegistry, PerpV2OrderBook, @@ -233,10 +193,6 @@ import { PerpV2InsuranceFund__factory } from "../../typechain/factories/PerpV2In import { PerpV2AccountBalance__factory } from "../../typechain/factories/PerpV2AccountBalance__factory"; import { PerpV2Exchange__factory } from "../../typechain/factories/PerpV2Exchange__factory"; -import { DGLight, DgToken } from "../contracts/dg"; -import { DgToken__factory } from "../../typechain/factories/DgToken__factory"; -import { DGLight__factory } from "../../typechain/factories/DGLight__factory"; - export default class DeployExternalContracts { private _deployerSigner: Signer; @@ -363,116 +319,6 @@ export default class DeployExternalContracts { return await new WETH9__factory(this._deployerSigner).deploy(); } - // AAVE - public async deployAaveProtoGovernance(govParamsProvider: Address): Promise { - return await new AaveProtoGovernance__factory(this._deployerSigner).deploy(govParamsProvider); - } - - public async deployGovernanceParamsProvider( - propositionPowerThreshold: BigNumber, - propositionPower: Address, - assetVotingWeightProvider: Address - ): Promise { - return await new GovernanceParamsProvider__factory(this._deployerSigner).deploy( - propositionPowerThreshold, - propositionPower, - assetVotingWeightProvider - ); - } - - public async deployAavePropositionPower( - name: string, - symbol: string, - decimals: BigNumberish, - council: Address[], - cap: BigNumber, - ): Promise { - return await new AavePropositionPower__factory(this._deployerSigner).deploy( - name, - symbol, - decimals, - council, - cap - ); - } - - public async deployAssetVotingWeightProvider( - assets: Address[], - weights: BigNumber[], - ): Promise { - return await new AssetVotingWeightProvider__factory(this._deployerSigner).deploy( - assets, - weights - ); - } - - public async deployLendingPoolAddressesProvider(): Promise { - return await new LendingPoolAddressesProvider__factory(this._deployerSigner).deploy(); - } - - public async deployCoreLibrary(): Promise { - return await new CoreLibrary__factory(this._deployerSigner).deploy(); - } - - public async deployLendingPoolCore(coreLibraryAddress: Address): Promise { - const lendingPoolCoreLibraryAddresses: LendingPoolCoreLibraryAddresses = { - __CoreLibrary___________________________: coreLibraryAddress, - }; - return await new LendingPoolCore__factory(lendingPoolCoreLibraryAddresses, this._deployerSigner).deploy(); - } - - public async deployLendingPool(): Promise { - return await new LendingPool__factory(this._deployerSigner).deploy(); - } - - public async deployLendingPoolConfigurator(): Promise { - return await new LendingPoolConfigurator__factory(this._deployerSigner).deploy(); - } - - public async deployDefaultReserveInterestRateStrategy( - _reserve: Address, - _AddressProvider: Address, - _baseVariableBorrowRate: BigNumberish = ether(1), - _variableRateSlope1: BigNumberish = ether(1), - _variableRateSlope2: BigNumberish = ether(1), - _stableRateSlope1: BigNumberish = ether(1), - _stableRateSlope2: BigNumberish = ether(1), - ): Promise { - return await new DefaultReserveInterestRateStrategy__factory(this._deployerSigner).deploy( - _reserve, - _AddressProvider, - _baseVariableBorrowRate, - _variableRateSlope1, - _variableRateSlope2, - _stableRateSlope1, - _stableRateSlope2, - ); - } - - public async deployLendingRateOracle(): Promise { - return await new LendingRateOracle__factory(this._deployerSigner).deploy(); - } - - public async deployLendingPoolDataProvider(): Promise { - return await new LendingPoolDataProvider__factory(this._deployerSigner).deploy(); - } - - public async deployLendToAaveMigrator( - _aaveToken: Address, - _lendToken: Address, - _aaveLendRatio: BigNumber, - ): Promise { - return await new LendToAaveMigrator__factory(this._deployerSigner).deploy( - _aaveToken, - _lendToken, - _aaveLendRatio - ); - } - - public async getLendToAaveMigrator(lendToAaveMigratorAddress: Address): Promise { - return await new LendToAaveMigrator__factory(this._deployerSigner).attach(lendToAaveMigratorAddress); - } - // AAVE V2 public async deployAaveV2LendingPoolAddressesProvider(marketId: string): Promise { return await new AaveV2LendingPoolAddressesProvider__factory(this._deployerSigner).deploy(marketId); @@ -777,16 +623,6 @@ export default class DeployExternalContracts { return await new DMMPool__factory(this._deployerSigner).deploy(); } - // AXIE-INFINITY - public async deployTokenSwap(oldToken: Address, newToken: Address): Promise { - return await new TokenSwap__factory(this._deployerSigner).deploy(oldToken, newToken); - } - - // Singularity Net - public async deploySingularityNetToken(): Promise { - return await new SingularityNetToken__factory(this._deployerSigner).deploy(); - } - // Uniswap V3 public async deployUniswapV3Factory(): Promise { return await new UniswapV3Factory__factory(this._deployerSigner).deploy(); @@ -812,15 +648,6 @@ export default class DeployExternalContracts { return await new UniswapV3Pool__factory(this._deployerSigner).attach(pool); } - // Decentral Games - public async deployDGLight(dgToken: Address): Promise { - return await new DGLight__factory(this._deployerSigner).deploy(dgToken); - } - - public async deployDgToken(): Promise { - return await new DgToken__factory(this._deployerSigner).deploy(); - } - // PerpV2 public async deployPerpV2OrderBook(): Promise { diff --git a/utils/deploys/deployModules.ts b/utils/deploys/deployModules.ts index 0309c5370..6e10b64cc 100644 --- a/utils/deploys/deployModules.ts +++ b/utils/deploys/deployModules.ts @@ -9,11 +9,10 @@ import { CompoundLeverageModule, CustomOracleNavIssuanceModule, DebtIssuanceModule, + DebtIssuanceModuleV2, GeneralIndexModule, GovernanceModule, IssuanceModule, - NavIssuanceModule, - PerpV2LeverageModule, PerpV2LeverageModuleV2, PerpV2BasisTradingModule, SingleIndexModule, @@ -39,8 +38,6 @@ import { SlippageIssuanceModule__factory } from "../../typechain/factories/Slipp import { GeneralIndexModule__factory } from "../../typechain/factories/GeneralIndexModule__factory"; import { GovernanceModule__factory } from "../../typechain/factories/GovernanceModule__factory"; import { IssuanceModule__factory } from "../../typechain/factories/IssuanceModule__factory"; -import { NavIssuanceModule__factory } from "../../typechain/factories/NavIssuanceModule__factory"; -import { PerpV2LeverageModule__factory } from "../../typechain/factories/PerpV2LeverageModule__factory"; import { PerpV2LeverageModuleV2__factory } from "../../typechain/factories/PerpV2LeverageModuleV2__factory"; import { PerpV2BasisTradingModule__factory } from "../../typechain/factories/PerpV2BasisTradingModule__factory"; import { SingleIndexModule__factory } from "../../typechain/factories/SingleIndexModule__factory"; @@ -69,7 +66,7 @@ export default class DeployModules { return await new DebtIssuanceModule__factory(this._deployerSigner).deploy(controller); } - public async deployDebtIssuanceModuleV2(controller: Address): Promise { + public async deployDebtIssuanceModuleV2(controller: Address): Promise { return await new DebtIssuanceModuleV2__factory(this._deployerSigner).deploy(controller); } @@ -97,10 +94,6 @@ export default class DeployModules { return await new AirdropModule__factory(this._deployerSigner).deploy(controller); } - public async deployNavIssuanceModule(controller: Address, weth: Address): Promise { - return await new NavIssuanceModule__factory(this._deployerSigner).deploy(controller, weth); - } - public async deployTradeModule(controller: Address): Promise { return await new TradeModule__factory(this._deployerSigner).deploy(controller); } @@ -121,10 +114,6 @@ export default class DeployModules { return await new CustomOracleNavIssuanceModule__factory(this._deployerSigner).deploy(controller, weth); } - public async getNavIssuanceModule(navIssuanceModule: Address): Promise { - return await new NavIssuanceModule__factory(this._deployerSigner).attach(navIssuanceModule); - } - public async deploySingleIndexModule( controller: Address, weth: Address, @@ -201,30 +190,6 @@ export default class DeployModules { return await new WrapModuleV2__factory(this._deployerSigner).deploy(controller, weth); } - public async deployPerpV2LeverageModule( - controller: Address, - perpVault: Address, - perpQuoter: Address, - perpMarketRegistry: Address, - maxPerpPositionsPerSet: BigNumber, - perpV2LibraryName: string, - perpV2LibraryAddress: Address - ): Promise { - return await new PerpV2LeverageModule__factory( - // @ts-ignore - { - [perpV2LibraryName]: perpV2LibraryAddress, - }, - this._deployerSigner - ).deploy( - controller, - perpVault, - perpQuoter, - perpMarketRegistry, - maxPerpPositionsPerSet - ); - } - public async deployPerpV2LeverageModuleV2( controller: Address, perpVault: Address, diff --git a/utils/deploys/deployProduct.ts b/utils/deploys/deployProduct.ts index 147777ce8..8112d7da7 100644 --- a/utils/deploys/deployProduct.ts +++ b/utils/deploys/deployProduct.ts @@ -2,12 +2,10 @@ import { Signer } from "ethers"; import { BigNumber } from "ethers"; import { - UniswapYieldHook, AssetLimitHook, AMMSplitter } from "../contracts"; -import { UniswapYieldHook__factory } from "../../typechain/factories/UniswapYieldHook__factory"; import { AssetLimitHook__factory } from "../../typechain/factories/AssetLimitHook__factory"; import { AMMSplitter__factory } from "../../typechain/factories/AMMSplitter__factory"; import { Address } from "../types"; @@ -19,13 +17,6 @@ export default class DeployProduct { this._deployerSigner = deployerSigner; } - public async deployUniswapYieldHook( - _assets: Address[], - _limits: BigNumber[] - ): Promise { - return await new UniswapYieldHook__factory(this._deployerSigner).deploy(_assets, _limits); - } - public async deployAssetLimitHook( _assets: Address[], _limits: BigNumber[] diff --git a/utils/fixtures/aaveFixture.ts b/utils/fixtures/aaveFixture.ts deleted file mode 100644 index 7837f3b0a..000000000 --- a/utils/fixtures/aaveFixture.ts +++ /dev/null @@ -1,151 +0,0 @@ -import DeployHelper from "../deploys"; -import { Signer } from "ethers"; -import { providers, BigNumber, BigNumberish } from "ethers"; -import { Address } from "../types"; - -import { - AavePropositionPower, - AaveProtoGovernance, - AssetVotingWeightProvider, - AToken, - CoreLibrary, - DefaultReserveInterestRateStrategy, - GovernanceParamsProvider, - LendingPool, - LendingPoolAddressesProvider, - LendingPoolConfigurator, - LendingPoolCore, - LendingRateOracle, - LendingPoolDataProvider, - LendToAaveMigrator, -} from "../contracts/aave"; - -import { StandardTokenMock } from "../contracts"; - -import { ether } from "../common"; - -import { AToken__factory } from "../../typechain/factories/AToken__factory"; -import { AaveTokenV2Mintable } from "../../typechain/AaveTokenV2Mintable"; - -export class AaveFixture { - private _deployer: DeployHelper; - private _ownerSigner: Signer; - - public lendingPool: LendingPool; - public lendingPoolCore: LendingPoolCore; - public lendingPoolAddressesProvider: LendingPoolAddressesProvider; - public coreLibrary: CoreLibrary; - public lendingPoolConfigurator: LendingPoolConfigurator; - public reserveInterestRateStrategy: DefaultReserveInterestRateStrategy; - public lendingRateOracle: LendingRateOracle; - public lendingPoolDataProvider: LendingPoolDataProvider; - public lendToAaveMigrator: LendToAaveMigrator; - public lendToken: StandardTokenMock; - public aaveToken: AaveTokenV2Mintable; - public aaveExchangeRatio: BigNumber; - public ethTokenAddress: Address = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; - public aaveProtoGovernance: AaveProtoGovernance; - public aavePropositionPower: AavePropositionPower; - public assetVotingWeightPower: AssetVotingWeightProvider; - public governanceParamsProvider: GovernanceParamsProvider; - - constructor(provider: providers.Web3Provider | providers.JsonRpcProvider, ownerAddress: Address) { - this._ownerSigner = provider.getSigner(ownerAddress); - this._deployer = new DeployHelper(this._ownerSigner); - } - - public async initialize(): Promise { - this.lendingPoolAddressesProvider = await this._deployer.external.deployLendingPoolAddressesProvider(); - this.lendingPool = await this._deployer.external.deployLendingPool(); - this.coreLibrary = await this._deployer.external.deployCoreLibrary(); - this.lendingPoolCore = await this._deployer.external.deployLendingPoolCore(this.coreLibrary.address); - this.lendingPoolConfigurator = await this._deployer.external.deployLendingPoolConfigurator(); - this.lendingRateOracle = await this._deployer.external.deployLendingRateOracle(); - this.lendingPoolDataProvider = await this._deployer.external.deployLendingPoolDataProvider(); - - await this.lendingPoolAddressesProvider.setLendingPoolManager(await this._ownerSigner.getAddress()); - await this.lendingPoolAddressesProvider.setLendingRateOracle(this.lendingRateOracle.address); - - await this.lendingPoolAddressesProvider.setLendingPoolCoreImpl(this.lendingPoolCore.address); - const proxyCore = await this.lendingPoolAddressesProvider.getLendingPoolCore(); - this.lendingPoolCore = this.lendingPoolCore.attach(proxyCore); - - await this.lendingPoolAddressesProvider.setLendingPoolDataProviderImpl(this.lendingPoolDataProvider.address); - const proxyDataProvider = await this.lendingPoolAddressesProvider.getLendingPoolDataProvider(); - this.lendingPoolDataProvider = this.lendingPoolDataProvider.attach(proxyDataProvider); - - await this.lendingPoolAddressesProvider.setLendingPoolImpl(this.lendingPool.address); - const proxyPool = await this.lendingPoolAddressesProvider.getLendingPool(); - this.lendingPool = this.lendingPool.attach(proxyPool); - - await this.lendingPoolAddressesProvider.setLendingPoolConfiguratorImpl(this.lendingPoolConfigurator.address); - const proxyConfigurator = await this.lendingPoolAddressesProvider.getLendingPoolConfigurator(); - this.lendingPoolConfigurator = this.lendingPoolConfigurator.attach(proxyConfigurator); - - await this.lendingPoolConfigurator.refreshLendingPoolCoreConfiguration(); - - this.reserveInterestRateStrategy = await this._deployer.external.deployDefaultReserveInterestRateStrategy( - this.lendingPoolCore.address, - this.lendingPoolAddressesProvider.address - ); - - // Deploy migration - this.lendToken = await this._deployer.mocks.deployTokenMock(await this._ownerSigner.getAddress(), ether(1000000), 18); - this.aaveToken = await this._deployer.external.deployAaveTokenV2Mintable(); - await this.aaveToken.mint(await this._ownerSigner.getAddress(), ether(100000)); - this.aaveExchangeRatio = BigNumber.from(100); // 100:1 LEND to AAVE ratio - this.lendToAaveMigrator = await this._deployer.external.deployLendToAaveMigrator( - this.aaveToken.address, - this.lendToken.address, - this.aaveExchangeRatio - ); - - // Deploy Governance - this.assetVotingWeightPower = await this._deployer.external.deployAssetVotingWeightProvider( - [this.aaveToken.address, this.lendToken.address], - [BigNumber.from(1), BigNumber.from(1)] - ); - this.aavePropositionPower = await this._deployer.external.deployAavePropositionPower( - "Aave Proposition Power", - "APP", - 18, - [await this._ownerSigner.getAddress()], - BigNumber.from(1) - ); - this.governanceParamsProvider = await this._deployer.external.deployGovernanceParamsProvider( - BigNumber.from(1), - this.aavePropositionPower.address, - this.assetVotingWeightPower.address - ); - this.aaveProtoGovernance = await this._deployer.external.deployAaveProtoGovernance(this.governanceParamsProvider.address); - - // Transfer tokens to contract for migration - await this.lendToken.transfer(this.lendToAaveMigrator.address, ether(10000)); - await this.aaveToken.transfer(this.lendToAaveMigrator.address, ether(100)); - - await this.lendToAaveMigrator.initialize(); - } - - public async deployAToken(_underlyingAsset: Address, _decimals: BigNumberish = 18): Promise { - await this.lendingPoolConfigurator.initReserve(_underlyingAsset, _decimals, this.reserveInterestRateStrategy.address); - const aTokenAddress = await this.lendingPoolCore.getReserveATokenAddress(_underlyingAsset); - return new AToken__factory(this._ownerSigner).attach(aTokenAddress); - } - - public async deployETHAToken( - _underlyingAsset: Address = this.ethTokenAddress, - _name: string = "Aave Interest bearing ETH", - _symbol: string = "aETH", - _decimals: BigNumberish = 18, - ): Promise { - await this.lendingPoolConfigurator.initReserveWithData( - _underlyingAsset, - _name, - _symbol, - _decimals, - this.reserveInterestRateStrategy.address - ); - const aTokenAddress = await this.lendingPoolCore.getReserveATokenAddress(_underlyingAsset); - return new AToken__factory(this._ownerSigner).attach(aTokenAddress); - } -} diff --git a/utils/fixtures/index.ts b/utils/fixtures/index.ts index b716841c1..e390db2c4 100644 --- a/utils/fixtures/index.ts +++ b/utils/fixtures/index.ts @@ -1,4 +1,3 @@ -export { AaveFixture } from "./aaveFixture"; export { AaveV2Fixture } from "./aaveV2Fixture"; export { BalancerFixture } from "./balancerFixture"; export { CompoundFixture } from "./compoundFixture"; diff --git a/utils/fixtures/systemFixture.ts b/utils/fixtures/systemFixture.ts index ab21faeef..1d5cbb448 100644 --- a/utils/fixtures/systemFixture.ts +++ b/utils/fixtures/systemFixture.ts @@ -14,7 +14,7 @@ import { StandardTokenMock, StreamingFeeModule, WETH9, - NavIssuanceModule + CustomOracleNavIssuanceModule } from "../contracts"; import DeployHelper from "../deploys"; import { @@ -46,7 +46,7 @@ export class SystemFixture { public issuanceModule: BasicIssuanceModule; public streamingFeeModule: StreamingFeeModule; - public navIssuanceModule: NavIssuanceModule; + public navIssuanceModule: CustomOracleNavIssuanceModule; public weth: WETH9; public usdc: StandardTokenMock; @@ -99,7 +99,7 @@ export class SystemFixture { this.integrationRegistry = await this._deployer.core.deployIntegrationRegistry(this.controller.address); this.setValuer = await this._deployer.core.deploySetValuer(this.controller.address); this.streamingFeeModule = await this._deployer.modules.deployStreamingFeeModule(this.controller.address); - this.navIssuanceModule = await this._deployer.modules.deployNavIssuanceModule(this.controller.address, this.weth.address); + this.navIssuanceModule = await this._deployer.modules.deployCustomOracleNavIssuanceModule(this.controller.address, this.weth.address); await this.controller.initialize( [this.factory.address], // Factories diff --git a/utils/test/index.ts b/utils/test/index.ts index 7a8deb62a..3cb59708d 100644 --- a/utils/test/index.ts +++ b/utils/test/index.ts @@ -3,7 +3,6 @@ import { ethers } from "hardhat"; import { Address } from "../types"; import { - AaveFixture, AaveV2Fixture, BalancerFixture, CompoundFixture, @@ -22,7 +21,6 @@ const provider = ethers.provider; export const getSystemFixture = (ownerAddress: Address) => new SystemFixture(provider, ownerAddress); export const getProtocolUtils = () => new ProtocolUtils(provider); export const getBlockchainUtils = () => new Blockchain(provider); -export const getAaveFixture = (ownerAddress: Address) => new AaveFixture(provider, ownerAddress); export const getAaveV2Fixture = (ownerAdderss: Address) => new AaveV2Fixture(provider, ownerAdderss); export const getBalancerFixture = (ownerAddress: Address) => new BalancerFixture(provider, ownerAddress); export const getCurveFixture = (ownerAddress: Address) => new CurveFixture(provider, ownerAddress); diff --git a/utils/types.ts b/utils/types.ts index 657d58e12..4108bedba 100644 --- a/utils/types.ts +++ b/utils/types.ts @@ -32,9 +32,10 @@ export interface AirdropSettings { anyoneAbsorb: boolean; } -export interface NAVIssuanceSettings { +export interface CustomOracleNAVIssuanceSettings { managerIssuanceHook: Address; managerRedemptionHook: Address; + setValuer: Address; reserveAssets: Address[]; feeRecipient: Address; managerFees: [BigNumber, BigNumber]; @@ -43,7 +44,3 @@ export interface NAVIssuanceSettings { maxPremiumPercentage: BigNumber; minSetTokenSupply: BigNumber; } - -export interface CustomOracleNAVIssuanceSettings extends NAVIssuanceSettings { - setValuer: Address; -}