- Added mocha __setup script with snapshotting

This commit is contained in:
eboado 2020-06-08 14:03:40 +02:00
parent 0a34cfe88d
commit 82de55fdbf
154 changed files with 12502 additions and 314 deletions

View File

@ -6,7 +6,7 @@ root = true
[*]
indent_style = space
indent_size = 4
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true

View File

@ -1,9 +1,9 @@
import { usePlugin, BuidlerConfig } from "@nomiclabs/buidler/config";
import {usePlugin, BuidlerConfig} from "@nomiclabs/buidler/config";
import path from "path";
import fs from "fs";
// @ts-ignore
import { accounts } from "./test-wallets.js";
import { eEthereumNetwork } from "./helpers/types";
import {accounts} from "./test-wallets.js";
import {eEthereumNetwork} from "./helpers/types";
usePlugin("@nomiclabs/buidler-ethers");
usePlugin("buidler-typechain");
@ -22,7 +22,7 @@ const HARDFORK = "istanbul";
const INFURA_KEY = "";
const ETHERSCAN_KEY = "";
const MNEMONIC_PATH = "m/44'/60'/0'/0";
const MNEMONICS: { [network: string]: string } = {
const MNEMONICS: {[network: string]: string} = {
[eEthereumNetwork.kovan]: "",
[eEthereumNetwork.ropsten]: "",
[eEthereumNetwork.main]: "",
@ -50,7 +50,7 @@ const getCommonNetworkConfig = (
const config: BuidlerConfig = {
solc: {
version: "0.6.8",
optimizer: { enabled: true, runs: 200 },
optimizer: {enabled: true, runs: 200},
evmVersion: "istanbul",
},
typechain: {
@ -63,7 +63,7 @@ const config: BuidlerConfig = {
},
defaultNetwork: "buidlerevm",
mocha: {
enableTimeouts: false,
timeout: 0,
},
networks: {
kovan: getCommonNetworkConfig(eEthereumNetwork.kovan, 42),
@ -78,7 +78,7 @@ const config: BuidlerConfig = {
throwOnTransactionFailures: true,
throwOnCallFailures: true,
accounts: accounts.map(
({ secretKey, balance }: { secretKey: string; balance: string }) => ({
({secretKey, balance}: {secretKey: string; balance: string}) => ({
privateKey: secretKey,
balance,
})

View File

@ -13,7 +13,7 @@ abstract contract Proxy {
* @dev Fallback function.
* Implemented entirely in `_fallback`.
*/
receive() external payable {
fallback() external payable {
_fallback();
}

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
contract MockAggregatorBase {
contract MockAggregator {
int256 private _latestAnswer;
event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 timestamp);

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorBAT is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorBUSD is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorDAI is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorKNC is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorLEND is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorLINK is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorMANA is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorMKR is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorREP is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorSNX is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorSUSD is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorTUSD is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorUNI_DAI_ETH is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorUNI_LEND_ETH is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorUNI_LINK_ETH is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorUNI_MKR_ETH is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorUNI_SETH_ETH is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorUNI_USDC_ETH is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorUSD is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorUSDC is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorUSDT is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorWBTC is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,8 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import "./MockAggregatorBase.sol";
contract MockAggregatorZRX is MockAggregatorBase {
constructor (int256 _initialAnswer) public MockAggregatorBase(_initialAnswer) {}
}

View File

@ -1,7 +1,121 @@
{
"Example": {
"MintableERC20": {
"buidlerevm": {
"address": "0x7c2C195CD6D34B8F845992d380aADB2730bB9C6F",
"address": "0xB00cC45B4a7d3e1FEE684cFc4417998A1c183e6d",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"LendingPoolAddressesProvider": {
"buidlerevm": {
"address": "0xAb35dEf6f863FC1e91dE4c20A3596b388eB1CFb4",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"LendingPoolAddressesProviderRegistry": {
"buidlerevm": {
"address": "0x22474D350EC2dA53D717E30b96e9a2B7628Ede5b",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"FeeProvider": {
"buidlerevm": {
"address": "0x852e3718A320aD93Ad8692E8D663d247e4c1b400"
}
},
"LendingPoolParametersProvider": {
"buidlerevm": {
"address": "0x2C4603396dE2F08642354A3A102760827FfFe113"
}
},
"LendingPoolCore": {
"buidlerevm": {
"address": "0xA10958a24032283FbE2D23cedf264d6eC9411CBA"
}
},
"LendingPoolConfigurator": {
"buidlerevm": {
"address": "0xC30DAE48c620d1C1f8Ca081547f905C7eE7c6b76"
}
},
"LendingPoolDataProvider": {
"buidlerevm": {
"address": "0x612719Ace03A8281188d61612A9f40D1da3ca420"
}
},
"LendingPool": {
"buidlerevm": {
"address": "0x820ED3d0675676203514f5fd76E5Ac40c9F0c4Bd"
}
},
"PriceOracle": {
"buidlerevm": {
"address": "0xe1B3b8F6b298b52bCd15357ED29e65e66a4045fF",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"MockAggregator": {
"buidlerevm": {
"address": "0xD83D2773a7873ae2b5f8Fb92097e20a8C64F691E",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"ChainlinkProxyPriceProvider": {
"buidlerevm": {
"address": "0x474d9b0D5F1Bb1602711F9346743a7a7478d6f52",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"LendingRateOracle": {
"buidlerevm": {
"address": "0xFc01AF83D78742DfD42631a352e33f8098e7274B",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"DefaultReserveInterestRateStrategy": {
"buidlerevm": {
"address": "0x603A373A1571783bD82b708C20a5A4b019BAB78F",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"LendingPoolLiquidationManager": {
"buidlerevm": {
"address": "0xFe230c227D3724015d0dE3dBEc831825f1ed1f59",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"MockOneSplit": {
"buidlerevm": {
"address": "0xd44937448A9f229bfae84e7d256810Ba4C4a93cC",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"OneSplitAdapter": {
"buidlerevm": {
"address": "0x70c5a4348710Fa80eE8f2bD2eD5243d1bAB90752",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"TokenDistributor": {
"buidlerevm": {
"address": "0x96049b850bE3415b4d7DcFECA2e6eE02ee580488",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"InitializableAdminUpgradeabilityProxy": {
"buidlerevm": {
"address": "0xbCf57D16d9d63aDDea3c2056A1de2A33ebD353F0",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"MockFlashLoanReceiver": {
"buidlerevm": {
"address": "0xe5a5a5b78F165C875EE2264a8743570176eA39d9",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"WalletBalanceProvider": {
"buidlerevm": {
"address": "0x828C9C41Fae6113C1DEA9056Dcd9C85A19002d52",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
}

View File

@ -1,9 +1,641 @@
import { eEthereumNetwork, tEthereumAddress } from "./types";
import {
iAssetBase,
iAavePoolAssets,
IMarketRates,
iAssetAggregatorBase,
AavePools,
iMultiPoolsAssets,
IReserveParams,
tEthereumAddress,
iBasicDistributionParams,
} from "./types";
import BigNumber from "bignumber.js";
import {getParamPerPool} from "./contracts-helpers";
export const ZERO_ADDRESS: tEthereumAddress =
"0x0000000000000000000000000000000000000000";
export const ONE_ADDRESS = "0x0000000000000000000000000000000000000001";
// ----------------
// MATH
// ----------------
export const WAD = Math.pow(10, 18).toString();
export const HALF_WAD = new BigNumber(WAD).multipliedBy(0.5).toString();
export const RAY = new BigNumber(10).exponentiatedBy(27).toFixed();
export const HALF_RAY = new BigNumber(RAY).multipliedBy(0.5).toFixed();
export const WAD_RAY_RATIO = Math.pow(10, 9).toString();
export const oneEther = new BigNumber(Math.pow(10, 18));
export const oneRay = new BigNumber(Math.pow(10, 27));
export const MAX_UINT_AMOUNT =
"115792089237316195423570985008687907853269984665640564039457584007913129639935";
// ----------------
// PROTOCOL GLOBAL PARAMS
// ----------------
export const OPTIMAL_UTILIZATION_RATE = new BigNumber(0.8).times(RAY);
export const EXCESS_UTILIZATION_RATE = new BigNumber(0.2).times(RAY);
export const ONE_YEAR = "31536000";
export const APPROVAL_AMOUNT_LENDING_POOL_CORE = "1000000000000000000000000000";
export const TOKEN_DISTRIBUTOR_PERCENTAGE_BASE = "10000";
export const MOCK_USD_PRICE_IN_WEI = "5848466240000000";
export const USD_ADDRESS = "0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96";
export const MOCK_ETH_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
export const WAD = Math.pow(10, 18).toString();
export const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
export const ONE_ADDRESS = "0x0000000000000000000000000000000000000001";
// ----------------
// COMMON PROTOCOL PARAMS ACROSS POOLS AND NETWORKS
// ----------------
export const ALL_AAVE_RESERVES_SYMBOLS = [
[
"ETH",
"DAI",
"LEND",
"TUSD",
"BAT",
"USDC",
"USDT",
"SUSD",
"ZRX",
"MKR",
"WBTC",
"LINK",
"KNC",
"MANA",
"REP",
"SNX",
"BUSD",
"UNI_DAI_ETH",
"UNI_USDC_ETH",
"UNI_SETH_ETH",
"UNI_LINK_ETH",
"UNI_MKR_ETH",
"UNI_LEND_ETH",
],
];
export const MOCK_CHAINLINK_AGGREGATORS_PRICES: iAssetAggregatorBase<string> = {
DAI: oneEther.multipliedBy("0.00369068412860").toFixed(),
TUSD: oneEther.multipliedBy("0.00364714136416").toFixed(),
USDC: oneEther.multipliedBy("0.00367714136416").toFixed(),
LEND: oneEther.multipliedBy("0.00003620948469").toFixed(),
BAT: oneEther.multipliedBy("0.00137893825230").toFixed(),
USDT: oneEther.multipliedBy("0.00369068412860").toFixed(),
SUSD: oneEther.multipliedBy("0.00364714136416").toFixed(),
MKR: oneEther.multipliedBy("2.508581").toFixed(),
REP: oneEther.multipliedBy("0.048235").toFixed(),
ZRX: oneEther.multipliedBy("0.001151").toFixed(),
WBTC: oneEther.multipliedBy("47.332685").toFixed(),
LINK: oneEther.multipliedBy("0.009955").toFixed(),
KNC: oneEther.multipliedBy("0.001072").toFixed(),
MANA: oneEther.multipliedBy("0.000158").toFixed(),
SNX: oneEther.multipliedBy("0.00442616").toFixed(),
BUSD: oneEther.multipliedBy("0.00736484").toFixed(),
USD: MOCK_USD_PRICE_IN_WEI,
UNI_DAI_ETH: oneEther.multipliedBy("2.1").toFixed(),
UNI_USDC_ETH: oneEther.multipliedBy("2.1").toFixed(),
UNI_SETH_ETH: oneEther.multipliedBy("2.1").toFixed(),
UNI_LEND_ETH: oneEther.multipliedBy("2.1").toFixed(),
UNI_LINK_ETH: oneEther.multipliedBy("2.1").toFixed(),
UNI_MKR_ETH: oneEther.multipliedBy("2.1").toFixed(),
};
export const ALL_ASSETS_INITIAL_PRICES: iAssetBase<string> = {
...MOCK_CHAINLINK_AGGREGATORS_PRICES,
ETH: oneEther.toFixed(),
};
export const LENDING_RATE_ORACLE_RATES_COMMON: iAavePoolAssets<IMarketRates> = {
ETH: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
DAI: {
borrowRate: oneRay.multipliedBy(0.039).toFixed(),
},
TUSD: {
borrowRate: oneRay.multipliedBy(0.035).toFixed(),
},
USDC: {
borrowRate: oneRay.multipliedBy(0.039).toFixed(),
},
SUSD: {
borrowRate: oneRay.multipliedBy(0.035).toFixed(),
},
USDT: {
borrowRate: oneRay.multipliedBy(0.035).toFixed(),
},
BAT: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
LEND: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
LINK: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
KNC: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
REP: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
MKR: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
MANA: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
WBTC: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
ZRX: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
SNX: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
BUSD: {
borrowRate: oneRay.multipliedBy(0.05).toFixed(),
},
};
export const getReservesConfigByPool = (
pool: AavePools
): iMultiPoolsAssets<IReserveParams> =>
getParamPerPool<iMultiPoolsAssets<IReserveParams>>(
{
[AavePools.proto]: {
DAI: {
baseVariableBorrowRate: new BigNumber(0.01)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.05)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "75",
liquidationThreshold: "80",
liquidationBonus: "105",
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: "18",
},
TUSD: {
baseVariableBorrowRate: new BigNumber(0.01)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.04)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.14).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "75",
liquidationThreshold: "80",
liquidationBonus: "105",
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: "18",
},
USDC: {
baseVariableBorrowRate: new BigNumber(0.01)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.04)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "75",
liquidationThreshold: "80",
liquidationBonus: "105",
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: "6",
},
USDT: {
baseVariableBorrowRate: new BigNumber(0.01)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.04)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.14).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "-1",
liquidationThreshold: "80",
liquidationBonus: "105",
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: "6",
},
SUSD: {
baseVariableBorrowRate: new BigNumber(0.01)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.04)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.14).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "-1",
liquidationThreshold: "80",
liquidationBonus: "105",
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: "18",
},
LEND: {
baseVariableBorrowRate: new BigNumber(0)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.08)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "60",
liquidationThreshold: "65",
liquidationBonus: "115",
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: "18",
},
BAT: {
baseVariableBorrowRate: new BigNumber(0)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.08)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "60",
liquidationThreshold: "65",
liquidationBonus: "110",
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: "18",
},
ETH: {
baseVariableBorrowRate: new BigNumber(0)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.08)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "75",
liquidationThreshold: "80",
liquidationBonus: "105",
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: "18",
},
LINK: {
baseVariableBorrowRate: new BigNumber(0)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.08)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "65",
liquidationThreshold: "70",
liquidationBonus: "110",
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: "18",
},
WBTC: {
baseVariableBorrowRate: new BigNumber(0)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.08)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "60",
liquidationThreshold: "65",
liquidationBonus: "115",
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: "8",
},
KNC: {
baseVariableBorrowRate: new BigNumber(0)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.08)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "60",
liquidationThreshold: "65",
liquidationBonus: "110",
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: "18",
},
REP: {
baseVariableBorrowRate: new BigNumber(0)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.08)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "60",
liquidationThreshold: "65",
liquidationBonus: "110",
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: "18",
},
MKR: {
baseVariableBorrowRate: new BigNumber(0)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.08)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "60",
liquidationThreshold: "65",
liquidationBonus: "110",
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: "18",
},
MANA: {
baseVariableBorrowRate: new BigNumber(0)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.08)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "60",
liquidationThreshold: "65",
liquidationBonus: "110",
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: "18",
},
ZRX: {
baseVariableBorrowRate: new BigNumber(0)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.08)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "60",
liquidationThreshold: "65",
liquidationBonus: "110",
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: "18",
},
SNX: {
baseVariableBorrowRate: new BigNumber(0.03)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.12)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "-1",
liquidationThreshold: "65",
liquidationBonus: "110",
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: "18",
},
BUSD: {
baseVariableBorrowRate: new BigNumber(0.01)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.04)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.14).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "-1",
liquidationThreshold: "80",
liquidationBonus: "110",
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: "18",
},
},
[AavePools.secondary]: {
ETH: {
baseVariableBorrowRate: new BigNumber(0)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.08)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "-1",
liquidationThreshold: "80",
liquidationBonus: "105",
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: "18",
},
DAI: {
baseVariableBorrowRate: new BigNumber(0.01)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.07)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.06).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "-1",
liquidationThreshold: "80",
liquidationBonus: "105",
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: "18",
},
USDC: {
baseVariableBorrowRate: new BigNumber(0.01)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.07)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.06).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "-1",
liquidationThreshold: "80",
liquidationBonus: "105",
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: "6",
},
USDT: {
baseVariableBorrowRate: new BigNumber(0.01)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.07)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.06).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "-1",
liquidationThreshold: "80",
liquidationBonus: "105",
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: "6",
},
UNI_DAI_ETH: {
baseVariableBorrowRate: new BigNumber(0.01)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.04)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "68",
liquidationThreshold: "73",
liquidationBonus: "110",
borrowingEnabled: false,
stableBorrowRateEnabled: false,
reserveDecimals: "18",
},
UNI_USDC_ETH: {
baseVariableBorrowRate: new BigNumber(0.01)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.04)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "68",
liquidationThreshold: "73",
liquidationBonus: "110",
borrowingEnabled: false,
stableBorrowRateEnabled: false,
reserveDecimals: "18",
},
UNI_SETH_ETH: {
baseVariableBorrowRate: new BigNumber(0.01)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.04)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "48",
liquidationThreshold: "66",
liquidationBonus: "110",
borrowingEnabled: false,
stableBorrowRateEnabled: false,
reserveDecimals: "18",
},
UNI_LEND_ETH: {
baseVariableBorrowRate: new BigNumber(0.01)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.04)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "51",
liquidationThreshold: "66",
liquidationBonus: "110",
borrowingEnabled: false,
stableBorrowRateEnabled: false,
reserveDecimals: "18",
},
UNI_LINK_ETH: {
baseVariableBorrowRate: new BigNumber(0.01)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.04)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "63",
liquidationThreshold: "68",
liquidationBonus: "110",
borrowingEnabled: false,
stableBorrowRateEnabled: false,
reserveDecimals: "18",
},
UNI_MKR_ETH: {
baseVariableBorrowRate: new BigNumber(0.01)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope1: new BigNumber(0.04)
.multipliedBy(oneRay)
.toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: "48",
liquidationThreshold: "66",
liquidationBonus: "110",
borrowingEnabled: false,
stableBorrowRateEnabled: false,
reserveDecimals: "18",
},
},
},
pool
);
export const getFeeDistributionParamsCommon = (
receiver: tEthereumAddress
): iBasicDistributionParams => {
const receivers = [receiver, ZERO_ADDRESS];
const percentages = ["2000", "8000"];
return {
receivers,
percentages,
};
};

View File

@ -1,9 +1,38 @@
import {Contract, Signer, utils} from "ethers";
import {getDb, BRE} from "./misc-utils";
import {tEthereumAddress, eContractid} from "./types";
import {
tEthereumAddress,
eContractid,
tStringTokenSmallUnits,
eEthereumNetwork,
AavePools,
iParamsPerNetwork,
iParamsPerPool,
} from "./types";
import {Example} from "../types/Example";
import {LendingPoolAddressesProvider} from "../types/LendingPoolAddressesProvider";
import {MintableErc20} from "../types/MintableErc20";
import {LendingPoolAddressesProviderRegistry} from "../types/LendingPoolAddressesProviderRegistry";
import {FeeProvider} from "../types/FeeProvider";
import {LendingPoolParametersProvider} from "../types/LendingPoolParametersProvider";
import {LendingPoolCore} from "../types/LendingPoolCore";
import {LendingPoolConfigurator} from "../types/LendingPoolConfigurator";
import {readArtifact} from "@nomiclabs/buidler/plugins";
import {Artifact} from "@nomiclabs/buidler/types";
import {LendingPoolDataProvider} from "../types/LendingPoolDataProvider";
import {LendingPool} from "../types/LendingPool";
import {PriceOracle} from "../types/PriceOracle";
import {MockAggregator} from "../types/MockAggregator";
import {LendingRateOracle} from "../types/LendingRateOracle";
import {DefaultReserveInterestRateStrategy} from "../types/DefaultReserveInterestRateStrategy";
import {LendingPoolLiquidationManager} from "../types/LendingPoolLiquidationManager";
import {MockOneSplit} from "../types/MockOneSplit";
import {OneSplitAdapter} from "../types/OneSplitAdapter";
import {TokenDistributor} from "../types/TokenDistributor";
import {InitializableAdminUpgradeabilityProxy} from "../types/InitializableAdminUpgradeabilityProxy";
import {MockFlashLoanReceiver} from "../types/MockFlashLoanReceiver";
import {WalletBalanceProvider} from "../types/WalletBalanceProvider";
export const registerContractInJsonDb = async (
contractId: string,
@ -33,6 +62,16 @@ export const registerContractInJsonDb = async (
.write();
};
export const insertContractAddressInDb = async (
id: eContractid,
address: tEthereumAddress
) =>
await getDb()
.set(`${id}.${BRE.network.name}`, {
address,
})
.write();
export const getEthersSigners = async (): Promise<Signer[]> =>
await Promise.all(await BRE.ethers.signers());
@ -53,18 +92,20 @@ export const decodeAbiNumber = (data: string): number =>
const deployContract = async <ContractType extends Contract>(
contractName: string,
args: any[]
): Promise<ContractType> =>
(await (await BRE.ethers.getContract(contractName)).deploy(
): Promise<ContractType> => {
const contract = (await (await BRE.ethers.getContract(contractName)).deploy(
...args
)) as ContractType;
await registerContractInJsonDb(<eContractid>contractName, contract);
return contract;
};
const getContract = async <ContractType extends Contract>(
contractName: string,
address: string
): Promise<ContractType> =>
(await (await BRE.ethers.getContract(contractName)).attach(
address
)) as ContractType;
(await BRE.ethers.getContractAt(contractName, address)) as ContractType;
export const deployExampleContract = async () =>
await deployContract<Example>(eContractid.Example, []);
@ -75,11 +116,336 @@ export const deployLendingPoolAddressesProvider = async () =>
[]
);
export const getExampleContract = async (address?: tEthereumAddress) => {
return await getContract<Example>(
eContractid.Example,
export const deployLendingPoolAddressesProviderRegistry = async () =>
await deployContract<LendingPoolAddressesProviderRegistry>(
eContractid.LendingPoolAddressesProviderRegistry,
[]
);
export const deployFeeProvider = async () =>
await deployContract<FeeProvider>(eContractid.FeeProvider, []);
export const deployLendingPoolParametersProvider = async () =>
await deployContract<LendingPoolParametersProvider>(
eContractid.LendingPoolParametersProvider,
[]
);
export const deployLendingPoolCore = async () => {
const CoreLibraryFactory = await BRE.ethers.getContractFactory(
eContractid.CoreLibrary
);
const coreLibrary = await CoreLibraryFactory.deploy();
await coreLibrary.deployed();
const lendingPoolCoreArtifact = await readArtifact(
BRE.config.paths.artifacts,
eContractid.LendingPoolCore
);
const linkedBytecode = linkBytecode(lendingPoolCoreArtifact, {
[eContractid.CoreLibrary]: coreLibrary.address,
});
const LendingPoolCoreFactory = await BRE.ethers.getContractFactory(
lendingPoolCoreArtifact.abi,
linkedBytecode
);
const lendingPoolCore = await LendingPoolCoreFactory.deploy({
gasLimit: 9500000,
});
return (await lendingPoolCore.deployed()) as LendingPoolCore;
};
export const deployLendingPoolConfigurator = async () =>
await deployContract<LendingPoolConfigurator>(
eContractid.LendingPoolConfigurator,
[]
);
export const deployLendingPoolDataProvider = async () =>
await deployContract<LendingPoolDataProvider>(
eContractid.LendingPoolDataProvider,
[]
);
export const deployLendingPool = async () =>
await deployContract<LendingPool>(eContractid.LendingPool, []);
export const deployPriceOracle = async () =>
await deployContract<PriceOracle>(eContractid.PriceOracle, []);
export const deployMockAggregator = async (price: tStringTokenSmallUnits) =>
await deployContract<MockAggregator>(eContractid.MockAggregator, [price]);
export const deployChainlinkProxyPriceProvider = async ([
assetsAddresses,
sourcesAddresses,
fallbackOracleAddress,
]: [tEthereumAddress[], tEthereumAddress[], tEthereumAddress]) =>
await deployContract<MockAggregator>(
eContractid.ChainlinkProxyPriceProvider,
[assetsAddresses, sourcesAddresses, fallbackOracleAddress]
);
export const deployLendingRateOracle = async () =>
await deployContract<LendingRateOracle>(eContractid.LendingRateOracle, []);
export const deployLendingPoolLiquidationManager = async () =>
await deployContract<LendingPoolLiquidationManager>(
eContractid.LendingPoolLiquidationManager,
[]
);
export const deployTokenDistributor = async () =>
await deployContract<TokenDistributor>(eContractid.TokenDistributor, []);
export const deployInitializableAdminUpgradeabilityProxy = async () =>
await deployContract<InitializableAdminUpgradeabilityProxy>(
eContractid.InitializableAdminUpgradeabilityProxy,
[]
);
export const deployMockFlashLoanReceiver = async (
addressesProvider: tEthereumAddress
) =>
await deployContract<MockFlashLoanReceiver>(
eContractid.MockFlashLoanReceiver,
[addressesProvider]
);
export const deployWalletBalancerProvider = async (
addressesProvider: tEthereumAddress
) =>
await deployContract<WalletBalanceProvider>(
eContractid.WalletBalanceProvider,
[addressesProvider]
);
export const deployMockOneSplit = async (tokenToBurn: tEthereumAddress) =>
await deployContract<MockOneSplit>(eContractid.MockOneSplit, [tokenToBurn]);
export const deployOneSplitAdapter = async () =>
await deployContract<OneSplitAdapter>(eContractid.OneSplitAdapter, []);
export const deployMintableErc20 = async ([name, symbol, decimals]: [
string,
string,
number
]) =>
await deployContract<MintableErc20>(eContractid.MintableERC20, [
name,
symbol,
decimals,
]);
export const deployDefaultReserveInterestRateStrategy = async ([
reserve,
addressesProvider,
baseVariableBorrowRate,
variableSlope1,
variableSlope2,
stableSlope1,
stableSlope2,
]: [
tEthereumAddress,
tEthereumAddress,
string,
string,
string,
string,
string
]) =>
await deployContract<DefaultReserveInterestRateStrategy>(
eContractid.DefaultReserveInterestRateStrategy,
[
reserve,
addressesProvider,
baseVariableBorrowRate,
variableSlope1,
variableSlope2,
stableSlope1,
stableSlope2,
]
);
export const getLendingPoolAddressesProvider = async (
address?: tEthereumAddress
) => {
return await getContract<LendingPoolAddressesProvider>(
eContractid.LendingPoolAddressesProvider,
address ||
(await getDb().get(`${eContractid.Example}.${BRE.network.name}`).value())
.address
(
await getDb()
.get(
`${eContractid.LendingPoolAddressesProvider}.${BRE.network.name}`
)
.value()
).address
);
};
export const getLendingPoolConfiguratorProxy = async (
address?: tEthereumAddress
) => {
return await getContract<LendingPoolConfigurator>(
eContractid.LendingPoolConfigurator,
address ||
(
await getDb()
.get(`${eContractid.LendingPoolConfigurator}.${BRE.network.name}`)
.value()
).address
);
};
export const getLendingPoolProxy = async (address?: tEthereumAddress) => {
return await getContract<LendingPool>(
eContractid.LendingPool,
address ||
(
await getDb()
.get(`${eContractid.LendingPool}.${BRE.network.name}`)
.value()
).address
);
};
export const getLendingPoolCoreProxy = async (address?: tEthereumAddress) => {
const CoreLibraryFactory = await BRE.ethers.getContractFactory(
eContractid.CoreLibrary
);
const coreLibrary = await CoreLibraryFactory.deploy();
await coreLibrary.deployed();
const lendingPoolCoreArtifact = await readArtifact(
BRE.config.paths.artifacts,
eContractid.LendingPoolCore
);
const linkedBytecode = linkBytecode(lendingPoolCoreArtifact, {
[eContractid.CoreLibrary]: coreLibrary.address,
});
const LendingPoolCoreFactory = await BRE.ethers.getContractFactory(
lendingPoolCoreArtifact.abi,
linkedBytecode
);
return <LendingPoolCore>(
await LendingPoolCoreFactory.attach(
address ||
(
await getDb()
.get(`${eContractid.LendingPoolCore}.${BRE.network.name}`)
.value()
).address
)
);
};
export const getFeeProvider = async (address?: tEthereumAddress) => {
return await getContract<FeeProvider>(
eContractid.FeeProvider,
address ||
(
await getDb()
.get(`${eContractid.FeeProvider}.${BRE.network.name}`)
.value()
).address
);
};
export const getLendingPoolParametersProvider = async (
address?: tEthereumAddress
) => {
return await getContract<LendingPoolParametersProvider>(
eContractid.LendingPoolParametersProvider,
address ||
(
await getDb()
.get(
`${eContractid.LendingPoolParametersProvider}.${BRE.network.name}`
)
.value()
).address
);
};
export const getLendingPoolDataProvider = async (
address?: tEthereumAddress
) => {
return await getContract<LendingPoolDataProvider>(
eContractid.LendingPoolDataProvider,
address ||
(
await getDb()
.get(`${eContractid.LendingPoolDataProvider}.${BRE.network.name}`)
.value()
).address
);
};
export const getPriceOracle = async (address?: tEthereumAddress) => {
return await getContract<PriceOracle>(
eContractid.PriceOracle,
address ||
(
await getDb()
.get(`${eContractid.PriceOracle}.${BRE.network.name}`)
.value()
).address
);
};
const linkBytecode = (artifact: Artifact, libraries: any) => {
let bytecode = artifact.bytecode;
for (const [fileName, fileReferences] of Object.entries(
artifact.linkReferences
)) {
for (const [libName, fixups] of Object.entries(fileReferences)) {
const addr = libraries[libName];
if (addr === undefined) {
continue;
}
for (const fixup of fixups) {
bytecode =
bytecode.substr(0, 2 + fixup.start * 2) +
addr.substr(2) +
bytecode.substr(2 + (fixup.start + fixup.length) * 2);
}
}
}
return bytecode;
};
export const getParamPerNetwork = <T>(
{kovan, ropsten, main}: iParamsPerNetwork<T>,
network: eEthereumNetwork
) => {
switch (network) {
case eEthereumNetwork.kovan:
return kovan;
case eEthereumNetwork.ropsten:
return ropsten;
case eEthereumNetwork.main:
return main;
default:
return main;
}
};
export const getParamPerPool = <T>(
{proto, secondary}: iParamsPerPool<T>,
pool: AavePools
) => {
switch (pool) {
case AavePools.proto:
return proto;
case AavePools.secondary:
return secondary;
default:
return proto;
}
};

View File

@ -26,3 +26,8 @@ export const sleep = (milliseconds: number) => {
};
export const createRandomAddress = () => Wallet.createRandom().address;
export const evmSnapshot = () => BRE.ethereum.send("evm_snapshot", []);
export const evmRevert = async (id: string) =>
BRE.ethereum.send("evm_revert", [id]);

View File

@ -4,12 +4,39 @@ export enum eEthereumNetwork {
buidlerevm = "buidlerevm",
kovan = "kovan",
ropsten = "ropsten",
main = "main"
main = "main",
}
export enum AavePools {
proto = "proto",
secondary = "secondary",
}
export enum eContractid {
Example = "Example",
LendingPoolAddressesProvider = "LendingPoolAddressesProvider"
LendingPoolAddressesProvider = "LendingPoolAddressesProvider",
MintableERC20 = "MintableERC20",
LendingPoolAddressesProviderRegistry = "LendingPoolAddressesProviderRegistry",
FeeProvider = "FeeProvider",
LendingPoolParametersProvider = "LendingPoolParametersProvider",
LendingPoolCore = "LendingPoolCore",
LendingPoolConfigurator = "LendingPoolConfigurator",
CoreLibrary = "CoreLibrary",
LendingPoolDataProvider = "LendingPoolDataProvider",
LendingPool = "LendingPool",
PriceOracle = "PriceOracle",
Proxy = "Proxy",
MockAggregator = "MockAggregator",
LendingRateOracle = "LendingRateOracle",
ChainlinkProxyPriceProvider = "ChainlinkProxyPriceProvider",
DefaultReserveInterestRateStrategy = "DefaultReserveInterestRateStrategy",
LendingPoolLiquidationManager = "LendingPoolLiquidationManager",
MockOneSplit = "MockOneSplit",
OneSplitAdapter = "OneSplitAdapter",
TokenDistributor = "TokenDistributor",
InitializableAdminUpgradeabilityProxy = "InitializableAdminUpgradeabilityProxy",
MockFlashLoanReceiver = "MockFlashLoanReceiver",
WalletBalanceProvider = "WalletBalanceProvider",
}
export type tEthereumAddress = string;
@ -17,3 +44,156 @@ export type tStringTokenBigUnits = string; // 1 ETH, or 10e6 USDC or 10e18 DAI
export type tBigNumberTokenBigUnits = BigNumber;
export type tStringTokenSmallUnits = string; // 1 wei, or 1 basic unit of USDC, or 1 basic unit of DAI
export type tBigNumberTokenSmallUnits = BigNumber;
export interface iAssetBase<T> {
ETH: T;
DAI: T;
TUSD: T;
USDC: T;
USDT: T;
SUSD: T;
LEND: T;
BAT: T;
REP: T;
MKR: T;
LINK: T;
KNC: T;
WBTC: T;
MANA: T;
ZRX: T;
SNX: T;
BUSD: T;
USD: T;
UNI_DAI_ETH: T;
UNI_USDC_ETH: T;
UNI_SETH_ETH: T;
UNI_LEND_ETH: T;
UNI_MKR_ETH: T;
UNI_LINK_ETH: T;
}
export type iAssetsWithoutETH<T> = Omit<iAssetBase<T>, "ETH">;
export type iAssetsWithoutUSD<T> = Omit<iAssetBase<T>, "USD">;
export type iAavePoolAssets<T> = Pick<
iAssetsWithoutUSD<T>,
| "ETH"
| "DAI"
| "TUSD"
| "USDC"
| "USDT"
| "SUSD"
| "LEND"
| "BAT"
| "REP"
| "MKR"
| "LINK"
| "KNC"
| "WBTC"
| "MANA"
| "ZRX"
| "SNX"
| "BUSD"
>;
export type iUniAssets<T> = Pick<
iAssetBase<T>,
| "UNI_DAI_ETH"
| "UNI_USDC_ETH"
| "UNI_SETH_ETH"
| "UNI_LEND_ETH"
| "UNI_MKR_ETH"
| "UNI_LINK_ETH"
>;
export type iAaveSecondPoolAssets<T> = Pick<
iAssetBase<T>,
| "ETH"
| "DAI"
| "USDC"
| "USDT"
| "UNI_DAI_ETH"
| "UNI_USDC_ETH"
| "UNI_SETH_ETH"
| "UNI_LEND_ETH"
| "UNI_MKR_ETH"
| "UNI_LINK_ETH"
>;
export type iMultiPoolsAssets<T> =
| iAavePoolAssets<T>
| iAaveSecondPoolAssets<T>;
export type iAavePoolTokens<T> = Omit<iAavePoolAssets<T>, "ETH">;
export type iAssetAggregatorBase<T> = iAssetsWithoutETH<T>;
export enum TokenContractId {
DAI = "DAI",
LEND = "LEND",
TUSD = "TUSD",
BAT = "BAT",
ETH = "ETH",
USDC = "USDC",
USDT = "USDT",
SUSD = "SUSD",
ZRX = "ZRX",
MKR = "MKR",
WBTC = "WBTC",
LINK = "LINK",
KNC = "KNC",
MANA = "MANA",
REP = "REP",
SNX = "SNX",
BUSD = "BUSD",
USD = "USD",
UNI_DAI_ETH = "UNI_DAI_ETH",
UNI_USDC_ETH = "UNI_USDC_ETH",
UNI_SETH_ETH = "UNI_SETH_ETH",
UNI_LINK_ETH = "UNI_LINK_ETH",
UNI_MKR_ETH = "UNI_MKR_ETH",
UNI_LEND_ETH = "UNI_LEND_ETH",
}
export interface IReserveParams
extends IReserveBorrowParams,
IReserveCollateralParams {}
export interface IReserveBorrowParams {
baseVariableBorrowRate: string;
variableRateSlope1: string;
variableRateSlope2: string;
stableRateSlope1: string;
stableRateSlope2: string;
borrowingEnabled: boolean;
stableBorrowRateEnabled: boolean;
reserveDecimals: string;
}
export interface IReserveCollateralParams {
baseLTVAsCollateral: string;
liquidationThreshold: string;
liquidationBonus: string;
}
export interface IMarketRates {
borrowRate: string;
}
export interface iParamsPerNetwork<T> {
[eEthereumNetwork.kovan]: T;
[eEthereumNetwork.ropsten]: T;
[eEthereumNetwork.main]: T;
}
export interface iParamsPerPool<T> {
[AavePools.proto]: T;
[AavePools.secondary]: T;
}
export interface iBasicDistributionParams {
receivers: string[];
percentages: string[];
}

629
test/__setup.spec.ts Normal file
View File

@ -0,0 +1,629 @@
import rawBRE from "@nomiclabs/buidler";
import {deployMockContract, MockContract} from "ethereum-waffle";
import {
deployLendingPoolAddressesProvider,
deployMintableErc20,
deployLendingPoolAddressesProviderRegistry,
deployFeeProvider,
deployLendingPoolParametersProvider,
deployLendingPoolCore,
deployLendingPoolConfigurator,
deployLendingPoolDataProvider,
deployLendingPool,
deployPriceOracle,
getLendingPoolConfiguratorProxy,
getLendingPoolCoreProxy,
deployMockAggregator,
deployChainlinkProxyPriceProvider,
deployLendingRateOracle,
deployDefaultReserveInterestRateStrategy,
deployLendingPoolLiquidationManager,
deployMockOneSplit,
deployOneSplitAdapter,
deployTokenDistributor,
deployInitializableAdminUpgradeabilityProxy,
deployMockFlashLoanReceiver,
registerContractInJsonDb,
deployWalletBalancerProvider,
getFeeProvider,
getLendingPoolParametersProvider,
getLendingPoolDataProvider,
getLendingPoolProxy,
insertContractAddressInDb,
} from "../helpers/contracts-helpers";
import {LendingPoolAddressesProvider} from "../types/LendingPoolAddressesProvider";
import {evmSnapshot} from "../helpers/misc-utils";
import {Wallet, ContractTransaction, ethers} from "ethers";
import IERC20MintableBurnableArtifact from "../artifacts/IERC20MintableBurnable.json";
import {
TokenContractId,
eContractid,
iAssetBase,
tEthereumAddress,
iAssetAggregatorBase,
IMarketRates,
iMultiPoolsAssets,
AavePools,
IReserveParams,
} from "../helpers/types";
import {MintableErc20} from "../types/MintableErc20";
import {
MOCK_USD_PRICE_IN_WEI,
ALL_ASSETS_INITIAL_PRICES,
MOCK_ETH_ADDRESS,
USD_ADDRESS,
MOCK_CHAINLINK_AGGREGATORS_PRICES,
LENDING_RATE_ORACLE_RATES_COMMON,
getReservesConfigByPool,
getFeeDistributionParamsCommon,
ZERO_ADDRESS,
} from "../helpers/constants";
import {PriceOracle} from "../types/PriceOracle";
// @ts-ignore
import {accounts} from "../test-wallets.js";
import {MockAggregator} from "../types/MockAggregator";
import {LendingRateOracle} from "../types/LendingRateOracle";
import {LendingPoolCore} from "../types/LendingPoolCore";
import {LendingPoolConfigurator} from "../types/LendingPoolConfigurator";
const deployAllMockTokens = async (
deployer: Wallet,
useDoppelganger: boolean
) => {
const tokens: {[symbol: string]: MockContract | MintableErc20} = {};
for (const tokenSymbol of Object.keys(TokenContractId)) {
if (tokenSymbol !== "ETH") {
tokens[tokenSymbol] = useDoppelganger
? await deployMockContract(deployer, IERC20MintableBurnableArtifact.abi)
: await deployMintableErc20([tokenSymbol, tokenSymbol, 18]);
}
}
return tokens;
};
const setInitialAssetPricesInOracle = async (
prices: iAssetBase<tEthereumAddress>,
assetsAddresses: iAssetBase<tEthereumAddress>,
priceOracleInstance: PriceOracle
) => {
for (const [assetSymbol, price] of Object.entries(prices) as [
string,
string
][]) {
const assetAddressIndex = Object.keys(assetsAddresses).findIndex(
(value) => value === assetSymbol
);
const [, assetAddress] = (Object.entries(assetsAddresses) as [
string,
string
][])[assetAddressIndex];
await waitForTx(
await priceOracleInstance.setAssetPrice(assetAddress, price)
);
}
};
const deployAllMockAggregators = async (
initialPrices: iAssetAggregatorBase<string>
) => {
const aggregators: {[tokenSymbol: string]: MockAggregator} = {};
for (const tokenContractName of Object.keys(initialPrices)) {
if (tokenContractName !== "ETH") {
const priceIndex = Object.keys(initialPrices).findIndex(
(value) => value === tokenContractName
);
const [, price] = (Object.entries(initialPrices) as [string, string][])[
priceIndex
];
aggregators[tokenContractName] = await deployMockAggregator(price);
}
}
return aggregators;
};
const getPairsTokenAggregator = (
allAssetsAddresses: {
[tokenSymbol: string]: tEthereumAddress;
},
aggregatorsAddresses: {[tokenSymbol: string]: tEthereumAddress}
): [string[], string[]] => {
const {ETH, ...assetsAddressesWithoutEth} = allAssetsAddresses;
const pairs = Object.entries(assetsAddressesWithoutEth).map(
([tokenSymbol, tokenAddress]) => {
if (tokenSymbol !== "ETH") {
const aggregatorAddressIndex = Object.keys(
aggregatorsAddresses
).findIndex((value) => value === tokenSymbol);
const [, aggregatorAddress] = (Object.entries(aggregatorsAddresses) as [
string,
tEthereumAddress
][])[aggregatorAddressIndex];
return [tokenAddress, aggregatorAddress];
}
}
);
const mappedPairs = pairs.map(([asset]) => asset);
const mappedAggregators = pairs.map(([, source]) => source);
return [mappedPairs, mappedAggregators];
};
const setInitialMarketRatesInRatesOracle = async (
marketRates: iMultiPoolsAssets<IMarketRates>,
assetsAddresses: {[x: string]: tEthereumAddress},
lendingRateOracleInstance: LendingRateOracle
) => {
for (const [assetSymbol, {borrowRate}] of Object.entries(marketRates) as [
string,
IMarketRates
][]) {
const assetAddressIndex = Object.keys(assetsAddresses).findIndex(
(value) => value === assetSymbol
);
const [, assetAddress] = (Object.entries(assetsAddresses) as [
string,
string
][])[assetAddressIndex];
await lendingRateOracleInstance.setMarketBorrowRate(
assetAddress,
borrowRate
);
}
};
const initReserves = async (
reservesParams: iMultiPoolsAssets<IReserveParams>,
tokenAddresses: {[symbol: string]: tEthereumAddress},
lendingPoolAddressesProvider: LendingPoolAddressesProvider,
lendingPoolCore: LendingPoolCore,
lendingPoolConfigurator: LendingPoolConfigurator,
aavePool: AavePools
) => {
if (aavePool !== AavePools.proto && aavePool !== AavePools.secondary) {
console.log(`Invalid Aave pool ${aavePool}`);
process.exit(1);
}
for (let [assetSymbol, {reserveDecimals}] of Object.entries(
reservesParams
) as [string, IReserveParams][]) {
const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
(value) => value === assetSymbol
);
const [, tokenAddress] = (Object.entries(tokenAddresses) as [
string,
string
][])[assetAddressIndex];
const reserveInitialized = await lendingPoolCore.getReserveIsActive(
tokenAddress
);
if (reserveInitialized) {
console.log(
`Reserve ${assetSymbol} is already active, skipping configuration`
);
continue;
}
try {
const reserveParamIndex = Object.keys(reservesParams).findIndex(
(value) => value === assetSymbol
);
const [
,
{
baseVariableBorrowRate,
variableRateSlope1,
variableRateSlope2,
stableRateSlope1,
stableRateSlope2,
},
] = (Object.entries(reservesParams) as [string, IReserveParams][])[
reserveParamIndex
];
const rateStrategyContract = await deployDefaultReserveInterestRateStrategy(
[
tokenAddress,
lendingPoolAddressesProvider.address,
baseVariableBorrowRate,
variableRateSlope1,
variableRateSlope2,
stableRateSlope1,
stableRateSlope2,
]
);
if (process.env.POOL === AavePools.secondary) {
if (assetSymbol.search("UNI") === -1) {
assetSymbol = `Uni${assetSymbol}`;
} else {
assetSymbol = assetSymbol.replace(/_/g, "").replace("UNI", "Uni");
}
}
await lendingPoolConfigurator.initReserveWithData(
tokenAddress,
`Aave Interest bearing ${assetSymbol}`,
`a${assetSymbol}`,
reserveDecimals,
rateStrategyContract.address
);
} catch (e) {
console.log(
`Reserve initialization for ${assetSymbol} failed with error ${e}. Skipped.`
);
}
}
};
const enableReservesToBorrow = async (
reservesParams: iMultiPoolsAssets<IReserveParams>,
tokenAddresses: {[symbol: string]: tEthereumAddress},
lendingPoolCore: LendingPoolCore,
lendingPoolConfigurator: LendingPoolConfigurator
) => {
for (const [
assetSymbol,
{borrowingEnabled, stableBorrowRateEnabled},
] of Object.entries(reservesParams) as [string, IReserveParams][]) {
if (!borrowingEnabled) continue;
try {
const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
(value) => value === assetSymbol
);
const [, tokenAddress] = (Object.entries(tokenAddresses) as [
string,
string
][])[assetAddressIndex];
const borrowingAlreadyEnabled = await lendingPoolCore.isReserveBorrowingEnabled(
tokenAddress
);
if (borrowingAlreadyEnabled) {
console.log(
`Reserve ${assetSymbol} is already enabled for borrowing, skipping`
);
continue;
}
await lendingPoolConfigurator.enableBorrowingOnReserve(
tokenAddress,
stableBorrowRateEnabled
);
} catch (e) {
console.log(
`Enabling reserve for borrowings for ${assetSymbol} failed with error ${e}. Skipped.`
);
}
}
};
const enableReservesAsCollateral = async (
reservesParams: iMultiPoolsAssets<IReserveParams>,
tokenAddresses: {[symbol: string]: tEthereumAddress},
lendingPoolCore: LendingPoolCore,
lendingPoolConfigurator: LendingPoolConfigurator
) => {
for (const [
assetSymbol,
{baseLTVAsCollateral, liquidationBonus, liquidationThreshold},
] of Object.entries(reservesParams) as [string, IReserveParams][]) {
if (baseLTVAsCollateral === "-1") continue;
const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
(value) => value === assetSymbol
);
const [, tokenAddress] = (Object.entries(tokenAddresses) as [
string,
string
][])[assetAddressIndex];
const alreadyEnabled = await lendingPoolCore.isReserveUsageAsCollateralEnabled(
tokenAddress
);
if (alreadyEnabled) {
console.log(
`Reserve ${assetSymbol} is already enabled as collateral, skipping`
);
continue;
}
try {
await lendingPoolConfigurator.enableReserveAsCollateral(
tokenAddress,
baseLTVAsCollateral,
liquidationThreshold,
liquidationBonus
);
} catch (e) {
console.log(
`Enabling reserve as collateral for ${assetSymbol} failed with error ${e}. Skipped.`
);
}
}
};
const waitForTx = async (tx: ContractTransaction) => await tx.wait();
const buildTestEnv = async (deployer: Wallet, secondaryWallet: Wallet) => {
console.time("setup");
const lendingPoolManager = deployer.address;
const mockTokens = await deployAllMockTokens(deployer, false);
const addressesProvider = await deployLendingPoolAddressesProvider();
await waitForTx(
await addressesProvider.setLendingPoolManager(lendingPoolManager)
);
const addressesProviderRegistry = await deployLendingPoolAddressesProviderRegistry();
await waitForTx(
await addressesProviderRegistry.registerAddressesProvider(
addressesProvider.address,
0
)
);
const feeProviderImpl = await deployFeeProvider();
await waitForTx(
await addressesProvider.setFeeProviderImpl(feeProviderImpl.address)
);
const feeProviderProxy = await getFeeProvider(
await addressesProvider.getFeeProvider()
);
await insertContractAddressInDb(
eContractid.FeeProvider,
feeProviderProxy.address
);
const parametersProviderImpl = await deployLendingPoolParametersProvider();
await waitForTx(
await addressesProvider.setLendingPoolParametersProviderImpl(
parametersProviderImpl.address
)
);
const parametersProviderProxy = await getLendingPoolParametersProvider(
await addressesProvider.getLendingPoolParametersProvider()
);
await insertContractAddressInDb(
eContractid.LendingPoolParametersProvider,
parametersProviderProxy.address
);
const lendingPoolCoreImpl = await deployLendingPoolCore();
await waitForTx(
await addressesProvider.setLendingPoolCoreImpl(lendingPoolCoreImpl.address)
);
const lendingPoolCoreProxy = await getLendingPoolCoreProxy(
await addressesProvider.getLendingPoolCore()
);
await insertContractAddressInDb(
eContractid.LendingPoolCore,
lendingPoolCoreProxy.address
);
const lendingPoolConfiguratorImpl = await deployLendingPoolConfigurator();
await waitForTx(
await addressesProvider.setLendingPoolConfiguratorImpl(
lendingPoolConfiguratorImpl.address
)
);
const lendingPoolConfiguratorProxy = await getLendingPoolConfiguratorProxy(
await addressesProvider.getLendingPoolConfigurator()
);
await insertContractAddressInDb(
eContractid.LendingPoolConfigurator,
lendingPoolConfiguratorProxy.address
);
const dataProviderImpl = await deployLendingPoolDataProvider();
await waitForTx(
await addressesProvider.setLendingPoolDataProviderImpl(
dataProviderImpl.address
)
);
const dataProviderProxy = await getLendingPoolDataProvider(
await addressesProvider.getLendingPoolDataProvider()
);
await insertContractAddressInDb(
eContractid.LendingPoolDataProvider,
dataProviderProxy.address
);
const lendingPoolImpl = await deployLendingPool();
await waitForTx(
await addressesProvider.setLendingPoolImpl(lendingPoolImpl.address)
);
const lendingPoolProxy = await getLendingPoolProxy(
await addressesProvider.getLendingPool()
);
await insertContractAddressInDb(
eContractid.LendingPool,
lendingPoolProxy.address
);
await waitForTx(
await lendingPoolConfiguratorProxy.refreshLendingPoolCoreConfiguration()
);
const fallbackOracle = await deployPriceOracle();
await waitForTx(await fallbackOracle.setEthUsdPrice(MOCK_USD_PRICE_IN_WEI));
await setInitialAssetPricesInOracle(
ALL_ASSETS_INITIAL_PRICES,
{
ETH: MOCK_ETH_ADDRESS,
DAI: mockTokens.DAI.address,
TUSD: mockTokens.TUSD.address,
USDC: mockTokens.USDC.address,
USDT: mockTokens.USDT.address,
SUSD: mockTokens.SUSD.address,
LEND: mockTokens.LEND.address,
BAT: mockTokens.BAT.address,
REP: mockTokens.REP.address,
MKR: mockTokens.MKR.address,
LINK: mockTokens.LINK.address,
KNC: mockTokens.KNC.address,
WBTC: mockTokens.WBTC.address,
MANA: mockTokens.MANA.address,
ZRX: mockTokens.ZRX.address,
SNX: mockTokens.SNX.address,
BUSD: mockTokens.BUSD.address,
USD: USD_ADDRESS,
UNI_DAI_ETH: mockTokens.UNI_DAI_ETH.address,
UNI_USDC_ETH: mockTokens.UNI_USDC_ETH.address,
UNI_SETH_ETH: mockTokens.UNI_SETH_ETH.address,
UNI_LEND_ETH: mockTokens.UNI_LEND_ETH.address,
UNI_MKR_ETH: mockTokens.UNI_MKR_ETH.address,
UNI_LINK_ETH: mockTokens.UNI_LINK_ETH.address,
},
fallbackOracle
);
const mockAggregators = await deployAllMockAggregators(
MOCK_CHAINLINK_AGGREGATORS_PRICES
);
const allTokenAddresses = Object.entries(mockTokens).reduce(
(
accum: {[tokenSymbol: string]: tEthereumAddress},
[tokenSymbol, tokenContract]
) => ({
...accum,
[tokenSymbol]: tokenContract.address,
}),
{}
);
const allAggregatorsAddresses = Object.entries(mockAggregators).reduce(
(
accum: {[tokenSymbol: string]: tEthereumAddress},
[tokenSymbol, aggregator]
) => ({
...accum,
[tokenSymbol]: aggregator.address,
}),
{}
);
const [tokens, aggregators] = getPairsTokenAggregator(
allTokenAddresses,
allAggregatorsAddresses
);
const chainlinkProxyPriceProvider = await deployChainlinkProxyPriceProvider([
tokens,
aggregators,
fallbackOracle.address,
]);
await waitForTx(
await addressesProvider.setPriceOracle(chainlinkProxyPriceProvider.address)
);
const lendingRateOracle = await deployLendingRateOracle();
await waitForTx(
await addressesProvider.setLendingRateOracle(lendingRateOracle.address)
);
const {USD, ...tokensAddressesWithoutUsd} = allTokenAddresses;
const allReservesAddresses = {
ETH: MOCK_ETH_ADDRESS,
...tokensAddressesWithoutUsd,
};
await setInitialMarketRatesInRatesOracle(
LENDING_RATE_ORACLE_RATES_COMMON,
allReservesAddresses,
lendingRateOracle
);
const {
UNI_DAI_ETH,
UNI_USDC_ETH,
UNI_SETH_ETH,
UNI_LINK_ETH,
UNI_MKR_ETH,
UNI_LEND_ETH,
...protoPoolReservesAddresses
} = <{[symbol: string]: tEthereumAddress}>allReservesAddresses;
const reservesParams = getReservesConfigByPool(AavePools.proto);
await initReserves(
reservesParams,
protoPoolReservesAddresses,
addressesProvider,
lendingPoolCoreProxy,
lendingPoolConfiguratorProxy,
AavePools.proto
);
await enableReservesToBorrow(
reservesParams,
protoPoolReservesAddresses,
lendingPoolCoreProxy,
lendingPoolConfiguratorProxy
);
await enableReservesAsCollateral(
reservesParams,
protoPoolReservesAddresses,
lendingPoolCoreProxy,
lendingPoolConfiguratorProxy
);
const liquidationManager = await deployLendingPoolLiquidationManager();
await waitForTx(
await addressesProvider.setLendingPoolLiquidationManager(
liquidationManager.address
)
);
const {receivers, percentages} = getFeeDistributionParamsCommon(
deployer.address
);
await deployMockOneSplit(tokensAddressesWithoutUsd.LEND);
const oneSplitAdapter = await deployOneSplitAdapter();
const tokenDistributorImpl = await deployTokenDistributor();
const tokenDistributorProxy = await deployInitializableAdminUpgradeabilityProxy();
const implementationParams = tokenDistributorImpl.interface.functions.initialize.encode(
[
ZERO_ADDRESS,
tokensAddressesWithoutUsd.LEND,
oneSplitAdapter.address,
receivers,
percentages,
Object.values(tokensAddressesWithoutUsd),
]
);
await waitForTx(
await tokenDistributorProxy.initialize(
tokenDistributorImpl.address,
secondaryWallet.address,
implementationParams
)
);
await waitForTx(
await addressesProvider.setTokenDistributor(tokenDistributorProxy.address)
);
await deployMockFlashLoanReceiver(addressesProvider.address);
await deployWalletBalancerProvider(addressesProvider.address);
await evmSnapshot();
console.timeEnd("setup");
};
before(async () => {
await rawBRE.run("set-bre");
const deployer = new ethers.Wallet(accounts[0].secretKey);
const secondaryWallet = new ethers.Wallet(accounts[1].secretKey);
await buildTestEnv(deployer, secondaryWallet);
console.log("\n***************");
console.log("Setup and snapshot finished");
console.log("***************\n");
});

View File

@ -0,0 +1,61 @@
import rawBRE from "@nomiclabs/buidler";
import {expect} from "chai";
import {MockProvider} from "ethereum-waffle";
import {BuidlerRuntimeEnvironment} from "@nomiclabs/buidler/types";
import {LendingPoolAddressesProvider} from "../types/LendingPoolAddressesProvider";
import {getLendingPoolAddressesProvider} from "../helpers/contracts-helpers";
import {evmRevert} from "../helpers/misc-utils";
describe("AToken: Modifiers", () => {
const wallets = new MockProvider().getWallets();
let BRE: BuidlerRuntimeEnvironment;
let _addressesProvider: LendingPoolAddressesProvider;
before(async () => {
await evmRevert("0x1");
_addressesProvider = await getLendingPoolAddressesProvider();
console.log(await _addressesProvider.getLendingPoolCore());
});
it("Test the accessibility of the LendingPoolAddressesProvider", async () => {});
});
// contract("AToken: Modifiers", async ([deployer, ...users]) => {
// let _testEnvProvider: ITestEnvWithoutInstances;
// let _aDAI: ATokenInstance;
// before("Initializing test variables", async () => {
// console.time("setup-test");
// _testEnvProvider = await testEnvProviderWithoutInstances(artifacts, [
// deployer,
// ...users,
// ]);
// const {getATokenInstances} = _testEnvProvider;
// _aDAI = (await getATokenInstances()).aDAI;
// console.timeEnd("setup-test");
// });
// it("Tries to invoke mintOnDeposit", async () => {
// await expectRevert(
// _aDAI.mintOnDeposit(deployer, "1"),
// "The caller of this function must be a lending pool"
// );
// });
// it("Tries to invoke burnOnLiquidation", async () => {
// await expectRevert(
// _aDAI.burnOnLiquidation(deployer, "1"),
// "The caller of this function must be a lending pool"
// );
// });
// it("Tries to invoke transferOnLiquidation", async () => {
// await expectRevert(
// _aDAI.transferOnLiquidation(deployer, users[1], "1"),
// "The caller of this function must be a lending pool"
// );
// });
// });

View File

@ -0,0 +1,190 @@
// import { ITestEnvWithoutInstances, RateMode} from '../utils/types';
// import {
// ATokenInstance,
// LendingPoolInstance,
// MintableERC20Instance,
// LendingPoolCoreInstance,
// } from '../utils/typechain-types/truffle-contracts';
// import {testEnvProviderWithoutInstances} from '../utils/truffle/dlp-tests-env';
// import {convertToCurrencyDecimals} from '../utils/misc-utils';
// import {APPROVAL_AMOUNT_LENDING_POOL_CORE, ETHEREUM_ADDRESS, oneEther, NIL_ADDRESS, MAX_UINT_AMOUNT} from '../utils/constants';
// const expectRevert = require('@openzeppelin/test-helpers').expectRevert;
// contract('AToken: Transfer', async ([deployer, ...users]) => {
// let _testEnvProvider: ITestEnvWithoutInstances;
// let _aDAI: ATokenInstance;
// let _DAI: MintableERC20Instance;
// let _lendingPoolInstance: LendingPoolInstance;
// let _lendingPoolCoreInstance: LendingPoolCoreInstance;
// before('Initializing test variables', async () => {
// console.time('setup-test');
// _testEnvProvider = await testEnvProviderWithoutInstances(
// artifacts,
// [deployer, ...users]
// );
// const {
// getLendingPoolInstance,
// getLendingPoolCoreInstance,
// getAllAssetsInstances,
// getATokenInstances
// } = _testEnvProvider;
// const instances = await Promise.all([
// getATokenInstances(), getAllAssetsInstances(), getLendingPoolInstance(), getLendingPoolCoreInstance()
// ])
// _aDAI = instances[0].aDAI
// _DAI = instances[1].DAI
// _lendingPoolInstance = instances[2];
// _lendingPoolCoreInstance = instances[3]
// console.timeEnd('setup-test');
// });
// it('User 0 deposits 1000 DAI, transfers to user 1', async () => {
// await _DAI.mint(await convertToCurrencyDecimals(_DAI.address, '1000'), {
// from: users[0],
// });
// await _DAI.approve(_lendingPoolCoreInstance.address, APPROVAL_AMOUNT_LENDING_POOL_CORE, {
// from: users[0],
// });
// //user 1 deposits 1000 DAI
// const amountDAItoDeposit = await convertToCurrencyDecimals(_DAI.address, '1000');
// await _lendingPoolInstance.deposit(_DAI.address, amountDAItoDeposit, '0', {
// from: users[0],
// });
// await _aDAI.transfer(users[1], amountDAItoDeposit, {from: users[0]})
// const fromBalance = await _aDAI.balanceOf(users[0])
// const toBalance = await _aDAI.balanceOf(users[1])
// expect(fromBalance.toString()).to.be.equal("0", "Invalid from balance after transfer")
// expect(toBalance.toString()).to.be.equal(amountDAItoDeposit.toString(), "Invalid to balance after transfer")
// });
// it('User 1 redirects interest to user 2, transfers 500 DAI back to user 0', async () => {
// await _aDAI.redirectInterestStream(users[2], {from: users[1]});
// const aDAIRedirected = await convertToCurrencyDecimals(_DAI.address, '1000');
// const aDAItoTransfer = await convertToCurrencyDecimals(_DAI.address, '500');
// const user2RedirectedBalanceBefore = await _aDAI.getRedirectedBalance(users[2])
// expect(user2RedirectedBalanceBefore.toString()).to.be.equal(aDAIRedirected, "Invalid redirected balance for user 2 before transfer")
// await _aDAI.transfer(users[0], aDAItoTransfer, {from: users[1]})
// const user2RedirectedBalanceAfter = await _aDAI.getRedirectedBalance(users[2])
// const user1RedirectionAddress = await _aDAI.getInterestRedirectionAddress(users[1])
// expect(user2RedirectedBalanceAfter.toString()).to.be.equal(aDAItoTransfer, "Invalid redirected balance for user 2 after transfer")
// expect(user1RedirectionAddress.toString()).to.be.equal(users[2], "Invalid redirection address for user 1")
// });
// it('User 0 transfers back to user 1', async () => {
// const aDAItoTransfer = await convertToCurrencyDecimals(_DAI.address, '500');
// await _aDAI.transfer(users[1], aDAItoTransfer, {from: users[0]})
// const user2RedirectedBalanceAfter = await _aDAI.getRedirectedBalance(users[2])
// const user1BalanceAfter = await _aDAI.balanceOf(users[1])
// expect(user2RedirectedBalanceAfter.toString()).to.be.equal(user1BalanceAfter.toString(), "Invalid redirected balance for user 2 after transfer")
// });
// it('User 0 deposits 1 ETH and user tries to borrow, but the aTokens received as a transfer are not available as collateral (revert expected)', async () => {
// await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, oneEther, '0', {
// from: users[0],
// value: oneEther.toFixed(0)
// });
// await expectRevert(_lendingPoolInstance.borrow(ETHEREUM_ADDRESS, await convertToCurrencyDecimals(ETHEREUM_ADDRESS,"0.1"), RateMode.Stable, "0", {from: users[1]}), "The collateral balance is 0")
// });
// it('User 1 sets the DAI as collateral and borrows, tries to transfer everything back to user 0 (revert expected)', async () => {
// await _lendingPoolInstance.setUserUseReserveAsCollateral(_DAI.address, true, {from: users[1]})
// const aDAItoTransfer = await convertToCurrencyDecimals(_DAI.address, '1000');
// await _lendingPoolInstance.borrow(ETHEREUM_ADDRESS, await convertToCurrencyDecimals(ETHEREUM_ADDRESS,"0.1"), RateMode.Stable, "0", {from: users[1]})
// await expectRevert(_aDAI.transfer(users[0], aDAItoTransfer, {from: users[1]}), "Transfer cannot be allowed.")
// });
// it('User 0 tries to transfer 0 balance (revert expected)', async () => {
// await expectRevert(_aDAI.transfer(users[1], "0", {from: users[0]}), "Transferred amount needs to be greater than zero")
// });
// it('User 1 repays the borrow, transfers aDAI back to user 0', async () => {
// await _lendingPoolInstance.repay(ETHEREUM_ADDRESS, MAX_UINT_AMOUNT, users[1], {from: users[1], value: oneEther.toFixed(0)})
// const aDAItoTransfer = await convertToCurrencyDecimals(_DAI.address, '1000');
// await _aDAI.transfer(users[0], aDAItoTransfer, {from: users[1]})
// const user2RedirectedBalanceAfter = await _aDAI.getRedirectedBalance(users[2])
// const user1RedirectionAddress = await _aDAI.getInterestRedirectionAddress(users[1])
// expect(user2RedirectedBalanceAfter.toString()).to.be.equal("0", "Invalid redirected balance for user 2 after transfer")
// expect(user1RedirectionAddress.toString()).to.be.equal(NIL_ADDRESS, "Invalid redirected address for user 1")
// });
// it('User 0 redirects interest to user 2, transfers 500 aDAI to user 1. User 1 redirects to user 3. User 0 transfers another 100 aDAI', async () => {
// let aDAItoTransfer = await convertToCurrencyDecimals(_DAI.address, '500');
// await _aDAI.redirectInterestStream(users[2], {from: users[0]})
// await _aDAI.transfer(users[1], aDAItoTransfer, {from: users[0]})
// await _aDAI.redirectInterestStream(users[3], {from: users[1]})
// aDAItoTransfer = await convertToCurrencyDecimals(_DAI.address, '100');
// await _aDAI.transfer(users[1], aDAItoTransfer, {from: users[0]})
// const user2RedirectedBalanceAfter = await _aDAI.getRedirectedBalance(users[2])
// const user3RedirectedBalanceAfter = await _aDAI.getRedirectedBalance(users[3])
// const expectedUser2Redirected = await convertToCurrencyDecimals(_DAI.address, "400")
// const expectedUser3Redirected = await convertToCurrencyDecimals(_DAI.address, "600")
// expect(user2RedirectedBalanceAfter.toString()).to.be.equal(expectedUser2Redirected, "Invalid redirected balance for user 2 after transfer")
// expect(user3RedirectedBalanceAfter.toString()).to.be.equal(expectedUser3Redirected, "Invalid redirected balance for user 3 after transfer")
// });
// });

314
test/configurator.spec.ts Normal file
View File

@ -0,0 +1,314 @@
// import {ITestEnvWithoutInstances} from '../utils/types';
// import {
// LendingPoolCoreInstance,
// LendingPoolConfiguratorInstance,
// LendingPoolInstance,
// } from '../utils/typechain-types/truffle-contracts';
// import {testEnvProviderWithoutInstances} from '../utils/truffle/dlp-tests-env';
// import {RAY, ETHEREUM_ADDRESS, APPROVAL_AMOUNT_LENDING_POOL_CORE} from '../utils/constants';
// import {convertToCurrencyDecimals} from '../utils/misc-utils';
// const expectRevert = require('@openzeppelin/test-helpers').expectRevert;
// const {expect} = require('chai');
// contract('LendingPoolConfigurator', async ([deployer, ...users]) => {
// let _testEnvProvider: ITestEnvWithoutInstances;
// let _lendingPoolConfiguratorInstance: LendingPoolConfiguratorInstance;
// let _lendingPoolCoreInstance: LendingPoolCoreInstance;
// let _lendingPoolInstance: LendingPoolInstance;
// before('Initializing LendingPoolConfigurator test variables', async () => {
// console.time('setup-test');
// _testEnvProvider = await testEnvProviderWithoutInstances(artifacts, [deployer, ...users]);
// const {
// getLendingPoolInstance,
// getLendingPoolCoreInstance,
// getLendingPoolConfiguratorInstance,
// } = _testEnvProvider;
// const instances = await Promise.all([
// getLendingPoolConfiguratorInstance(),
// getLendingPoolCoreInstance(),
// getLendingPoolInstance(),
// ]);
// _lendingPoolConfiguratorInstance = instances[0];
// _lendingPoolCoreInstance = instances[1];
// _lendingPoolInstance = instances[2];
// console.timeEnd('setup-test');
// });
// it('Deactivates the ETH reserve', async () => {
// await _lendingPoolConfiguratorInstance.deactivateReserve(ETHEREUM_ADDRESS);
// const isActive = await _lendingPoolCoreInstance.getReserveIsActive(ETHEREUM_ADDRESS);
// expect(isActive).to.be.equal(false);
// });
// it('Rectivates the ETH reserve', async () => {
// await _lendingPoolConfiguratorInstance.activateReserve(ETHEREUM_ADDRESS);
// const isActive = await _lendingPoolCoreInstance.getReserveIsActive(ETHEREUM_ADDRESS);
// expect(isActive).to.be.equal(true);
// });
// it('Check the onlyLendingPoolManager on deactivateReserve ', async () => {
// await expectRevert(
// _lendingPoolConfiguratorInstance.deactivateReserve(ETHEREUM_ADDRESS, {from: users[2]}),
// 'The caller must be a lending pool manager'
// );
// });
// it('Check the onlyLendingPoolManager on activateReserve ', async () => {
// await expectRevert(
// _lendingPoolConfiguratorInstance.activateReserve(ETHEREUM_ADDRESS, {from: users[2]}),
// 'The caller must be a lending pool manager'
// );
// });
// it('Freezes the ETH reserve', async () => {
// await _lendingPoolConfiguratorInstance.freezeReserve(ETHEREUM_ADDRESS);
// const isFreezed = await _lendingPoolCoreInstance.getReserveIsFreezed(ETHEREUM_ADDRESS);
// expect(isFreezed).to.be.equal(true);
// });
// it('Unfreezes the ETH reserve', async () => {
// await _lendingPoolConfiguratorInstance.unfreezeReserve(ETHEREUM_ADDRESS);
// const isFreezed = await _lendingPoolCoreInstance.getReserveIsFreezed(ETHEREUM_ADDRESS);
// expect(isFreezed).to.be.equal(false);
// });
// it('Check the onlyLendingPoolManager on freezeReserve ', async () => {
// await expectRevert(
// _lendingPoolConfiguratorInstance.freezeReserve(ETHEREUM_ADDRESS, {from: users[2]}),
// 'The caller must be a lending pool manager'
// );
// });
// it('Check the onlyLendingPoolManager on unfreezeReserve ', async () => {
// await expectRevert(
// _lendingPoolConfiguratorInstance.unfreezeReserve(ETHEREUM_ADDRESS, {from: users[2]}),
// 'The caller must be a lending pool manager'
// );
// });
// it('Deactivates the ETH reserve for borrowing', async () => {
// await _lendingPoolConfiguratorInstance.disableBorrowingOnReserve(ETHEREUM_ADDRESS);
// const isEnabled = await _lendingPoolCoreInstance.isReserveBorrowingEnabled(ETHEREUM_ADDRESS);
// expect(isEnabled).to.be.equal(false);
// });
// it('Activates the ETH reserve for borrowing', async () => {
// await _lendingPoolConfiguratorInstance.enableBorrowingOnReserve(ETHEREUM_ADDRESS, true);
// const isEnabled = await _lendingPoolCoreInstance.isReserveBorrowingEnabled(ETHEREUM_ADDRESS);
// const interestIndex = await _lendingPoolCoreInstance.getReserveLiquidityCumulativeIndex(
// ETHEREUM_ADDRESS
// );
// expect(isEnabled).to.be.equal(true);
// expect(interestIndex.toString()).to.be.equal(RAY);
// });
// it('Check the onlyLendingPoolManager on disableBorrowingOnReserve ', async () => {
// await expectRevert(
// _lendingPoolConfiguratorInstance.disableBorrowingOnReserve(ETHEREUM_ADDRESS, {
// from: users[2],
// }),
// 'The caller must be a lending pool manager'
// );
// });
// it('Check the onlyLendingPoolManager on enableBorrowingOnReserve ', async () => {
// await expectRevert(
// _lendingPoolConfiguratorInstance.enableBorrowingOnReserve(ETHEREUM_ADDRESS, true, {
// from: users[2],
// }),
// 'The caller must be a lending pool manager'
// );
// });
// it('Deactivates the ETH reserve as collateral', async () => {
// await _lendingPoolConfiguratorInstance.disableReserveAsCollateral(ETHEREUM_ADDRESS);
// const isEnabled = await _lendingPoolCoreInstance.isReserveUsageAsCollateralEnabled(
// ETHEREUM_ADDRESS
// );
// expect(isEnabled).to.be.equal(false);
// });
// it('Activates the ETH reserve as collateral', async () => {
// await _lendingPoolConfiguratorInstance.enableReserveAsCollateral(
// ETHEREUM_ADDRESS,
// '75',
// '80',
// '105'
// );
// const isEnabled = await _lendingPoolCoreInstance.isReserveUsageAsCollateralEnabled(
// ETHEREUM_ADDRESS
// );
// expect(isEnabled).to.be.equal(true);
// });
// it('Check the onlyLendingPoolManager on disableReserveAsCollateral ', async () => {
// await expectRevert(
// _lendingPoolConfiguratorInstance.disableReserveAsCollateral(ETHEREUM_ADDRESS, {
// from: users[2],
// }),
// 'The caller must be a lending pool manager'
// );
// });
// it('Check the onlyLendingPoolManager on enableReserveAsCollateral ', async () => {
// await expectRevert(
// _lendingPoolConfiguratorInstance.enableReserveAsCollateral(
// ETHEREUM_ADDRESS,
// '75',
// '80',
// '105',
// {from: users[2]}
// ),
// 'The caller must be a lending pool manager'
// );
// });
// it('Disable stable borrow rate on the ETH reserve', async () => {
// await _lendingPoolConfiguratorInstance.disableReserveStableBorrowRate(ETHEREUM_ADDRESS);
// const isEnabled = await _lendingPoolCoreInstance.getReserveIsStableBorrowRateEnabled(
// ETHEREUM_ADDRESS
// );
// expect(isEnabled).to.be.equal(false);
// });
// it('Enables stable borrow rate on the ETH reserve', async () => {
// await _lendingPoolConfiguratorInstance.enableReserveStableBorrowRate(ETHEREUM_ADDRESS);
// const isEnabled = await _lendingPoolCoreInstance.getReserveIsStableBorrowRateEnabled(
// ETHEREUM_ADDRESS
// );
// expect(isEnabled).to.be.equal(true);
// });
// it('Check the onlyLendingPoolManager on disableReserveStableBorrowRate', async () => {
// await expectRevert(
// _lendingPoolConfiguratorInstance.disableReserveStableBorrowRate(ETHEREUM_ADDRESS, {
// from: users[2],
// }),
// 'The caller must be a lending pool manager'
// );
// });
// it('Check the onlyLendingPoolManager on enableReserveStableBorrowRate', async () => {
// await expectRevert(
// _lendingPoolConfiguratorInstance.enableReserveStableBorrowRate(ETHEREUM_ADDRESS, {
// from: users[2],
// }),
// 'The caller must be a lending pool manager'
// );
// });
// it('Changes LTV of the reserve', async () => {
// await _lendingPoolConfiguratorInstance.setReserveBaseLTVasCollateral(ETHEREUM_ADDRESS, '60');
// const {ltv}: any = await _lendingPoolInstance.getReserveConfigurationData(ETHEREUM_ADDRESS);
// expect(ltv).to.be.bignumber.equal('60', 'Invalid LTV');
// });
// it('Check the onlyLendingPoolManager on setReserveBaseLTVasCollateral', async () => {
// await expectRevert(
// _lendingPoolConfiguratorInstance.setReserveBaseLTVasCollateral(ETHEREUM_ADDRESS, '75', {
// from: users[2],
// }),
// 'The caller must be a lending pool manager'
// );
// });
// it('Changes liquidation threshold of the reserve', async () => {
// await _lendingPoolConfiguratorInstance.setReserveLiquidationThreshold(ETHEREUM_ADDRESS, '75');
// const {liquidationThreshold}: any = await _lendingPoolInstance.getReserveConfigurationData(
// ETHEREUM_ADDRESS
// );
// expect(liquidationThreshold).to.be.bignumber.equal('75', 'Invalid Liquidation threshold');
// });
// it('Check the onlyLendingPoolManager on setReserveLiquidationThreshold', async () => {
// await expectRevert(
// _lendingPoolConfiguratorInstance.setReserveLiquidationThreshold(ETHEREUM_ADDRESS, '80', {
// from: users[2],
// }),
// 'The caller must be a lending pool manager'
// );
// });
// it('Changes liquidation bonus of the reserve', async () => {
// await _lendingPoolConfiguratorInstance.setReserveLiquidationBonus(ETHEREUM_ADDRESS, '110');
// const liquidationBonus = await _lendingPoolCoreInstance.getReserveLiquidationBonus(
// ETHEREUM_ADDRESS
// );
// expect(liquidationBonus).to.be.bignumber.equal('110', 'Invalid Liquidation discount');
// });
// it('Check the onlyLendingPoolManager on setReserveLiquidationBonus', async () => {
// await expectRevert(
// _lendingPoolConfiguratorInstance.setReserveLiquidationBonus(ETHEREUM_ADDRESS, '80', {
// from: users[2],
// }),
// 'The caller must be a lending pool manager'
// );
// });
// it('Check the onlyLendingPoolManager on setReserveDecimals', async () => {
// await expectRevert(
// _lendingPoolConfiguratorInstance.setReserveDecimals(ETHEREUM_ADDRESS, '80', {from: users[2]}),
// 'The caller must be a lending pool manager'
// );
// });
// it('Removes the last added reserve', async () => {
// const reservesBefore = await _lendingPoolInstance.getReserves();
// const lastReserve = reservesBefore[reservesBefore.length - 1];
// await _lendingPoolConfiguratorInstance.removeLastAddedReserve(lastReserve);
// const reservesAfter = await _lendingPoolInstance.getReserves();
// expect(reservesAfter.length).to.be.equal(
// reservesBefore.length - 1,
// 'Invalid number of reserves after removal'
// );
// });
// it('Check the onlyLendingPoolManager on setReserveLiquidationBonus', async () => {
// await expectRevert(
// _lendingPoolConfiguratorInstance.setReserveLiquidationBonus(ETHEREUM_ADDRESS, '80', {
// from: users[2],
// }),
// 'The caller must be a lending pool manager'
// );
// });
// it('Reverts when trying to disable the DAI reserve with liquidity on it', async () => {
// const {getAllAssetsInstances, getFirstDepositorAddressOnTests} = _testEnvProvider;
// const daiInstance = (await getAllAssetsInstances()).DAI;
// const _depositorAddress = await getFirstDepositorAddressOnTests();
// await daiInstance.mint(await convertToCurrencyDecimals(daiInstance.address, '1000'), {
// from: _depositorAddress,
// });
// //approve protocol to access depositor wallet
// await daiInstance.approve(_lendingPoolCoreInstance.address, APPROVAL_AMOUNT_LENDING_POOL_CORE, {
// from: _depositorAddress,
// });
// const amountDAItoDeposit = await convertToCurrencyDecimals(daiInstance.address, '1000');
// //user 1 deposits 1000 DAI
// await _lendingPoolInstance.deposit(daiInstance.address, amountDAItoDeposit, '0', {
// from: _depositorAddress,
// });
// await expectRevert(
// _lendingPoolConfiguratorInstance.deactivateReserve(daiInstance.address),
// 'The liquidity of the reserve needs to be 0'
// );
// });
// });

284
test/core-modifiers.spec.ts Normal file
View File

@ -0,0 +1,284 @@
// import {ITestEnvWithoutInstances, iAssetsWithoutETH, RateMode} from '../utils/types';
// import {
// LendingPoolCoreInstance,
// MintableERC20Instance,
// } from '../utils/typechain-types/truffle-contracts';
// import {testEnvProviderWithoutInstances} from '../utils/truffle/dlp-tests-env';
// import { ETHEREUM_ADDRESS} from '../utils/constants';
// const expectRevert = require('@openzeppelin/test-helpers').expectRevert;
// contract('LendingPoolCore: Modifiers', async ([deployer, ...users]) => {
// let _testEnvProvider: ITestEnvWithoutInstances;
// let _lendingPoolCoreInstance: LendingPoolCoreInstance;
// let _tokenInstances: iAssetsWithoutETH<MintableERC20Instance>;
// before('Initializing tests', async () => {
// _testEnvProvider = await testEnvProviderWithoutInstances(artifacts, [deployer, ...users]);
// const {getAllAssetsInstances, getLendingPoolCoreInstance} = _testEnvProvider;
// const instances = await Promise.all([getLendingPoolCoreInstance(), getAllAssetsInstances()]);
// _lendingPoolCoreInstance = instances[0];
// _tokenInstances = instances[1];
// });
// it('Tries invoke updateStateOnDeposit ', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// await expectRevert(
// _lendingPoolCoreInstance.updateStateOnDeposit(daiInstance.address, deployer, '0', false),
// 'The caller must be a lending pool contract'
// );
// });
// it('Tries invoke updateStateOnRedeem', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// await expectRevert(
// _lendingPoolCoreInstance.updateStateOnRedeem(daiInstance.address, deployer, '0', false),
// 'The caller must be a lending pool contract'
// );
// });
// it('Tries invoke updateStateOnBorrow', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// await expectRevert(
// _lendingPoolCoreInstance.updateStateOnBorrow(
// daiInstance.address,
// deployer,
// '0',
// '0',
// RateMode.Stable
// ),
// 'The caller must be a lending pool contract'
// );
// });
// it('Tries invoke updateStateOnRepay', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// await expectRevert(
// _lendingPoolCoreInstance.updateStateOnRepay(
// daiInstance.address,
// deployer,
// '0',
// '0',
// '0',
// false
// ),
// 'The caller must be a lending pool contract'
// );
// });
// it('Tries invoke updateStateOnSwapRate', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// await expectRevert(
// _lendingPoolCoreInstance.updateStateOnSwapRate(
// daiInstance.address,
// deployer,
// '0',
// '0',
// '0',
// RateMode.Stable
// ),
// 'The caller must be a lending pool contract'
// );
// });
// it('Tries invoke updateStateOnRebalance', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// await expectRevert(
// _lendingPoolCoreInstance.updateStateOnRebalance(daiInstance.address, deployer, '0'),
// 'The caller must be a lending pool contract'
// );
// });
// it('Tries invoke updateStateOnLiquidation', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// await expectRevert(
// _lendingPoolCoreInstance.updateStateOnLiquidation(
// ETHEREUM_ADDRESS,
// daiInstance.address,
// deployer,
// '0',
// '0',
// '0',
// '0',
// '0',
// false
// ),
// 'The caller must be a lending pool contract'
// );
// });
// it('Tries invoke setUserUseReserveAsCollateral', async () => {
// await expectRevert(
// _lendingPoolCoreInstance.setUserUseReserveAsCollateral(ETHEREUM_ADDRESS, deployer, false),
// 'The caller must be a lending pool contract'
// );
// });
// it('Tries invoke transferToUser', async () => {
// await expectRevert(
// _lendingPoolCoreInstance.transferToUser(ETHEREUM_ADDRESS, deployer, '0'),
// 'The caller must be a lending pool contract'
// );
// });
// it('Tries invoke transferToReserve', async () => {
// await expectRevert(
// _lendingPoolCoreInstance.transferToReserve(ETHEREUM_ADDRESS, deployer, '0'),
// 'The caller must be a lending pool contract'
// );
// });
// it('Tries invoke transferToFeeCollectionAddress', async () => {
// await expectRevert(
// _lendingPoolCoreInstance.transferToFeeCollectionAddress(
// ETHEREUM_ADDRESS,
// deployer,
// '0',
// deployer
// ),
// 'The caller must be a lending pool contract'
// );
// });
// it('Tries invoke liquidateFee', async () => {
// await expectRevert(
// _lendingPoolCoreInstance.liquidateFee(ETHEREUM_ADDRESS, '0', deployer),
// 'The caller must be a lending pool contract'
// );
// });
// it('Tries invoke initReserve', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// await expectRevert(
// _lendingPoolCoreInstance.initReserve(
// daiInstance.address,
// daiInstance.address,
// '18',
// deployer
// ),
// 'The caller must be a lending pool configurator contract'
// );
// });
// it('Tries invoke refreshConfiguration', async () => {
// await expectRevert(
// _lendingPoolCoreInstance.refreshConfiguration(),
// 'The caller must be a lending pool configurator contract'
// );
// });
// it('Tries invoke enableBorrowingOnReserve, disableBorrowingOnReserve', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// await expectRevert(
// _lendingPoolCoreInstance.enableBorrowingOnReserve(daiInstance.address, false),
// 'The caller must be a lending pool configurator contract'
// );
// await expectRevert(
// _lendingPoolCoreInstance.refreshConfiguration(),
// 'The caller must be a lending pool configurator contract'
// );
// });
// it('Tries invoke freezeReserve, unfreezeReserve', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// await expectRevert(
// _lendingPoolCoreInstance.freezeReserve(daiInstance.address),
// 'The caller must be a lending pool configurator contract'
// );
// await expectRevert(
// _lendingPoolCoreInstance.unfreezeReserve(daiInstance.address),
// 'The caller must be a lending pool configurator contract'
// );
// });
// it('Tries invoke enableReserveAsCollateral, disableReserveAsCollateral', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// await expectRevert(
// _lendingPoolCoreInstance.enableReserveAsCollateral(daiInstance.address, 0, 0, 0),
// 'The caller must be a lending pool configurator contract'
// );
// await expectRevert(
// _lendingPoolCoreInstance.disableReserveAsCollateral(daiInstance.address),
// 'The caller must be a lending pool configurator contract'
// );
// });
// it('Tries invoke enableReserveStableBorrowRate, disableReserveStableBorrowRate', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// await expectRevert(
// _lendingPoolCoreInstance.enableReserveStableBorrowRate(daiInstance.address),
// 'The caller must be a lending pool configurator contract'
// );
// await expectRevert(
// _lendingPoolCoreInstance.disableReserveStableBorrowRate(daiInstance.address),
// 'The caller must be a lending pool configurator contract'
// );
// });
// it('Tries invoke setReserveDecimals', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// await expectRevert(
// _lendingPoolCoreInstance.setReserveDecimals(daiInstance.address, '0'),
// 'The caller must be a lending pool configurator contract'
// );
// });
// it('Tries invoke removeLastAddedReserve', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// await expectRevert(
// _lendingPoolCoreInstance.removeLastAddedReserve(daiInstance.address),
// 'The caller must be a lending pool configurator contract'
// );
// });
// it('Tries invoke setReserveBaseLTVasCollateral', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// await expectRevert(
// _lendingPoolCoreInstance.setReserveBaseLTVasCollateral(daiInstance.address, '0'),
// 'The caller must be a lending pool configurator contract'
// );
// });
// it('Tries invoke setReserveLiquidationBonus', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// await expectRevert(
// _lendingPoolCoreInstance.setReserveLiquidationBonus(daiInstance.address, '0'),
// 'The caller must be a lending pool configurator contract'
// );
// });
// it('Tries invoke setReserveLiquidationThreshold', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// await expectRevert(
// _lendingPoolCoreInstance.setReserveLiquidationThreshold(daiInstance.address, '0'),
// 'The caller must be a lending pool configurator contract'
// );
// });
// it('Tries invoke setReserveInterestRateStrategyAddress', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// await expectRevert(
// _lendingPoolCoreInstance.setReserveInterestRateStrategyAddress(daiInstance.address, deployer),
// 'The caller must be a lending pool configurator contract'
// );
// });
// });

111
test/core.spec.ts Normal file
View File

@ -0,0 +1,111 @@
// import { ITestEnv, ContractsInstancesOrigin } from "../utils/types";
// import { LendingPoolCoreInstance, LendingPoolAddressesProviderInstance } from "../utils/typechain-types/truffle-contracts";
// import { testEnvProvider } from "../utils/truffle/dlp-tests-env";
// import { RAY, WAD, ETHEREUM_ADDRESS } from "../utils/constants";
// import BigNumber from "bignumber.js";
// /*contract("LendingPoolCore", async ([deployer, ...users]) => {
// let _testEnvProvider: ITestEnv
// let _addressesProviderInstance: LendingPoolAddressesProviderInstance
// let _lendingPoolCoreInstance: LendingPoolCoreInstance;
// let _lendAddress: string;
// before("Initializing LendingPoolCore test variables", async () => {
// _testEnvProvider = await testEnvProvider(artifacts, [deployer, ...users], ContractsInstancesOrigin.TruffleArtifacts)
// const {
// deployedInstances: {
// lendingPoolAddressesProviderInstance,
// lendingPoolCoreInstance,
// },
// getAllAssetsAddresses
// } = _testEnvProvider
// _addressesProviderInstance = lendingPoolAddressesProviderInstance
// _lendingPoolCoreInstance = lendingPoolCoreInstance
// _lendAddress = (await getAllAssetsAddresses()).LEND
// })
// it("Configure the lending pool address to the owner address to allow invocation of the methods", async () => {
// await _addressesProviderInstance.setLendingPoolConfiguratorImpl(deployer)
// await _addressesProviderInstance.setLendingPoolImpl(deployer)
// await _lendingPoolCoreInstance.refreshConfiguration()
// const providerAddress = await _addressesProviderInstance.getLendingPoolConfigurator()
// expect(providerAddress).to.be.equal(deployer)
// const poolAddress = await _addressesProviderInstance.getLendingPool()
// expect(poolAddress).to.be.equal(deployer)
// })
// it("Increases the stable total borrows of a reserve", async () => {
// await _lendingPoolCoreInstance.increaseReserveTotalBorrowsStableAndUpdateAverageRate(
// ETHEREUM_ADDRESS,
// WAD,
// new BigNumber(RAY).multipliedBy(10).toFixed(),
// ) //10% interest
// const totalBorrows = await _lendingPoolCoreInstance.getReserveTotalBorrowsStable(ETHEREUM_ADDRESS)
// expect(totalBorrows.toString()).to.be.equal(WAD)
// })
// it("Increases the variable total borrows of a reserve", async () => {
// await _lendingPoolCoreInstance.increaseReserveTotalBorrowsVariable(ETHEREUM_ADDRESS, WAD) //10% interest
// const totalBorrows = await _lendingPoolCoreInstance.getReserveTotalBorrowsVariable(ETHEREUM_ADDRESS)
// expect(totalBorrows.toString()).to.be.equal(WAD)
// })
// it("Decreases the stable total borrows of a reserve", async () => {
// await _lendingPoolCoreInstance.decreaseReserveTotalBorrowsStableAndUpdateAverageRate(
// ETHEREUM_ADDRESS,
// WAD,
// new BigNumber(RAY).multipliedBy(10).toFixed(),
// )
// const totalBorrows = await _lendingPoolCoreInstance.getReserveTotalBorrowsStable(ETHEREUM_ADDRESS)
// expect(totalBorrows.toString()).to.be.equal("0")
// })
// it("Decreases the variable total borrows of a reserve", async () => {
// await _lendingPoolCoreInstance.decreaseReserveTotalBorrowsVariable(ETHEREUM_ADDRESS, WAD)
// const totalBorrows = await _lendingPoolCoreInstance.getReserveTotalBorrowsVariable(ETHEREUM_ADDRESS)
// expect(totalBorrows.toString()).to.be.equal("0")
// })
// it("Updates the variable borrow index, checks that is equal to 1 as there are no borrows from the user", async () => {
// await _lendingPoolCoreInstance.updateUserLastVariableBorrowCumulativeIndex(_lendAddress, deployer)
// await _lendingPoolCoreInstance.updateUserLastVariableBorrowCumulativeIndex(ETHEREUM_ADDRESS, deployer)
// const indexLEND = await _lendingPoolCoreInstance.getUserVariableBorrowCumulativeIndex(
// _lendAddress,
// deployer,
// )
// const indexETH = await _lendingPoolCoreInstance.getUserVariableBorrowCumulativeIndex(ETHEREUM_ADDRESS, deployer)
// expect(indexLEND.toString()).to.be.equal(RAY, "Invalid user borrow index for LEND")
// expect(indexETH.toString()).to.be.equal(RAY, "Invalid user borrow index for ETH")
// })
// it("Disables the LEND collateral", async () => {
// await _lendingPoolCoreInstance.disableReserveAsCollateral(_lendAddress)
// const collateralEnabled = await _lendingPoolCoreInstance.isReserveUsageAsCollateralEnabled(
// _lendAddress,
// )
// expect(collateralEnabled).to.be.equal(false)
// })
// it("Deactivates the ETH reserve", async () => {
// await _lendingPoolCoreInstance.disableBorrowingOnReserve(ETHEREUM_ADDRESS)
// const isEnabled = await _lendingPoolCoreInstance.isReserveBorrowingEnabled(ETHEREUM_ADDRESS)
// expect(isEnabled).to.be.equal(false)
// })
// })
// */

278
test/flashloan.spec.ts Normal file
View File

@ -0,0 +1,278 @@
// import {
// LendingPoolInstance,
// LendingPoolCoreInstance,
// IPriceOracleInstance,
// MockFlashLoanReceiverInstance,
// TokenDistributorInstance,
// MintableERC20Instance,
// ATokenInstance,
// } from '../utils/typechain-types/truffle-contracts';
// import {iATokenBase, iAssetsWithoutETH, ITestEnvWithoutInstances} from '../utils/types';
// import BigNumber from 'bignumber.js';
// import {
// APPROVAL_AMOUNT_LENDING_POOL_CORE,
// oneEther,
// oneRay,
// ETHEREUM_ADDRESS,
// } from '../utils/constants';
// import {testEnvProviderWithoutInstances} from '../utils/truffle/dlp-tests-env';
// import {convertToCurrencyDecimals} from '../utils/misc-utils';
// const expectRevert = require('@openzeppelin/test-helpers').expectRevert;
// const {expect} = require('chai');
// contract('LendingPool FlashLoan function', async ([deployer, ...users]) => {
// let _testEnvProvider: ITestEnvWithoutInstances;
// let _lendingPoolInstance: LendingPoolInstance;
// let _lendingPoolCoreInstance: LendingPoolCoreInstance;
// let _mockFlashLoanReceiverInstance: MockFlashLoanReceiverInstance;
// let _priceOracleInstance: IPriceOracleInstance;
// let _aTokenInstances: iATokenBase<ATokenInstance>;
// let _tokenInstances: iAssetsWithoutETH<MintableERC20Instance>;
// let _tokenDistributor: TokenDistributorInstance;
// let _daiAddress: string;
// let _depositorAddress: string;
// let _web3: Web3;
// let _initialDepositorETHBalance: string;
// before('Initializing LendingPool test variables', async () => {
// console.time('setup-test');
// _testEnvProvider = await testEnvProviderWithoutInstances(artifacts, [deployer, ...users]);
// const {
// getWeb3,
// getAllAssetsInstances,
// getFirstDepositorAddressOnTests,
// getLendingPoolInstance,
// getLendingPoolCoreInstance,
// getPriceOracleInstance,
// getATokenInstances,
// getMockFlashLoanReceiverInstance,
// getTokenDistributorInstance,
// } = _testEnvProvider;
// const instances = await Promise.all([
// getLendingPoolInstance(),
// getLendingPoolCoreInstance(),
// getPriceOracleInstance(),
// getATokenInstances(),
// getMockFlashLoanReceiverInstance(),
// getAllAssetsInstances(),
// getTokenDistributorInstance(),
// ]);
// _lendingPoolInstance = instances[0];
// _lendingPoolCoreInstance = instances[1];
// _priceOracleInstance = instances[2];
// _aTokenInstances = instances[3];
// _mockFlashLoanReceiverInstance = instances[4];
// _tokenInstances = instances[5];
// _daiAddress = _tokenInstances.DAI.address;
// _depositorAddress = await getFirstDepositorAddressOnTests();
// _tokenDistributor = instances[6];
// _web3 = await getWeb3();
// _initialDepositorETHBalance = await _web3.eth.getBalance(_depositorAddress);
// console.timeEnd('setup-test');
// });
// it('Deposits ETH into the reserve', async () => {
// const amountToDeposit = await convertToCurrencyDecimals(ETHEREUM_ADDRESS, '1');
// await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, amountToDeposit, '0', {
// from: _depositorAddress,
// value: amountToDeposit,
// });
// });
// it('Takes ETH flashloan, returns the funds correctly', async () => {
// //move funds to the MockFlashLoanReceiver contract
// let send = web3.eth.sendTransaction({
// from: deployer,
// to: _mockFlashLoanReceiverInstance.address,
// value: web3.utils.toWei('0.5', 'ether'),
// });
// const txResult = await _lendingPoolInstance.flashLoan(
// _mockFlashLoanReceiverInstance.address,
// ETHEREUM_ADDRESS,
// new BigNumber(0.8).multipliedBy(oneEther),
// '0x10'
// );
// const reserveData: any = await _lendingPoolInstance.getReserveData(ETHEREUM_ADDRESS);
// const tokenDistributorBalance = await _web3.eth.getBalance(_tokenDistributor.address);
// const currentLiquidityRate = reserveData.liquidityRate;
// const currentLiquidityIndex = reserveData.liquidityIndex;
// expect(reserveData.totalLiquidity.toString()).to.be.equal('1000504000000000000');
// expect(currentLiquidityRate.toString()).to.be.equal('0');
// expect(currentLiquidityIndex.toString()).to.be.equal('1000504000000000000000000000');
// expect(tokenDistributorBalance.toString()).to.be.equal('216000000000000');
// });
// it('Takes an ETH flashloan as big as the available liquidity', async () => {
// //move funds to the MockFlashLoanReceiver contract
// let send = web3.eth.sendTransaction({
// from: deployer,
// to: _mockFlashLoanReceiverInstance.address,
// value: web3.utils.toWei('0.5', 'ether'),
// });
// const txResult = await _lendingPoolInstance.flashLoan(
// _mockFlashLoanReceiverInstance.address,
// ETHEREUM_ADDRESS,
// '1000504000000000000',
// '0x10'
// );
// const reserveData: any = await _lendingPoolInstance.getReserveData(ETHEREUM_ADDRESS);
// const tokenDistributorBalance = await _web3.eth.getBalance(_tokenDistributor.address);
// const currentLiqudityRate = reserveData.liquidityRate;
// const currentLiquidityIndex = reserveData.liquidityIndex;
// expect(reserveData.totalLiquidity.toString()).to.be.equal('1001134317520000000');
// expect(currentLiqudityRate.toString()).to.be.equal('0');
// expect(currentLiquidityIndex.toString()).to.be.equal('1001134317520000000000000000');
// expect(tokenDistributorBalance.toString()).to.be.equal('486136080000000');
// });
// it('Takes ETH flashloan, does not return the funds (revert expected)', async () => {
// //move funds to the MockFlashLoanReceiver contract
// let send = web3.eth.sendTransaction({
// from: deployer,
// to: _mockFlashLoanReceiverInstance.address,
// value: web3.utils.toWei('0.5', 'ether'),
// });
// await _mockFlashLoanReceiverInstance.setFailExecutionTransfer(true);
// await expectRevert(
// _lendingPoolInstance.flashLoan(
// _mockFlashLoanReceiverInstance.address,
// ETHEREUM_ADDRESS,
// new BigNumber(0.8).multipliedBy(oneEther),
// '0x10'
// ),
// 'The actual balance of the protocol is inconsistent'
// );
// });
// it('tries to take a very small flashloan, which would result in 0 fees (revert expected)', async () => {
// //move funds to the MockFlashLoanReceiver contract
// await expectRevert(
// _lendingPoolInstance.flashLoan(
// _mockFlashLoanReceiverInstance.address,
// ETHEREUM_ADDRESS,
// '1', //1 wei loan
// '0x10'
// ),
// 'The requested amount is too small for a flashLoan.'
// );
// });
// it('tries to take a flashloan that is bigger than the available liquidity (revert expected)', async () => {
// //move funds to the MockFlashLoanReceiver contract
// await expectRevert(
// _lendingPoolInstance.flashLoan(
// _mockFlashLoanReceiverInstance.address,
// ETHEREUM_ADDRESS,
// '1004415000000000000', //slightly higher than the available liquidity
// '0x10'
// ),
// 'There is not enough liquidity available to borrow'
// );
// });
// it('tries to take a flashloan using a non contract address as receiver (revert expected)', async () => {
// //move funds to the MockFlashLoanReceiver contract
// await expectRevert(
// _lendingPoolInstance.flashLoan(deployer, ETHEREUM_ADDRESS, '1000000000000000000', '0x10'),
// 'revert'
// );
// });
// it('Deposits DAI into the reserve', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// //mints DAI to depositor
// await daiInstance.mint(await convertToCurrencyDecimals(daiInstance.address, '1000'), {
// from: _depositorAddress,
// });
// //approve protocol to access depositor wallet
// await daiInstance.approve(_lendingPoolCoreInstance.address, APPROVAL_AMOUNT_LENDING_POOL_CORE, {
// from: _depositorAddress,
// });
// const amountToDeposit = await convertToCurrencyDecimals(_daiAddress, '1000');
// await _lendingPoolInstance.deposit(daiInstance.address, amountToDeposit, '0', {
// from: _depositorAddress,
// });
// });
// it('Takes out a 500 DAI flashloan, returns the funds correctly', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// await _mockFlashLoanReceiverInstance.setFailExecutionTransfer(false);
// await _lendingPoolInstance.flashLoan(
// _mockFlashLoanReceiverInstance.address,
// _daiAddress,
// new BigNumber(500).multipliedBy(oneEther),
// '0x10'
// );
// const reserveData: any = await _lendingPoolInstance.getReserveData(_daiAddress);
// const userData: any = await _lendingPoolInstance.getUserReserveData(_daiAddress, deployer);
// const totalLiquidity = reserveData.totalLiquidity.toString();
// const currentLiqudityRate = reserveData.liquidityRate.toString();
// const currentLiquidityIndex = reserveData.liquidityIndex.toString();
// const currentUserBalance = userData.currentATokenBalance.toString();
// const expectedLiquidity = new BigNumber('1000.315').multipliedBy(oneEther).toFixed();
// const tokenDistributorBalance = await daiInstance.balanceOf(_tokenDistributor.address);
// expect(totalLiquidity).to.be.equal(expectedLiquidity, 'Invalid total liquidity');
// expect(currentLiqudityRate).to.be.equal('0', 'Invalid liquidity rate');
// expect(currentLiquidityIndex).to.be.equal(
// new BigNumber('1.000315').multipliedBy(oneRay).toFixed(),
// 'Invalid liquidity index'
// );
// expect(currentUserBalance.toString()).to.be.equal(expectedLiquidity, 'Invalid user balance');
// expect(tokenDistributorBalance.toString()).to.be.equal(
// new BigNumber('0.135').multipliedBy(oneEther).toFixed(),
// 'Invalid token distributor balance'
// );
// });
// it('Takes out a 500 DAI flashloan, does not return the funds (revert expected)', async () => {
// //move funds to the MockFlashLoanReceiver contract
// await _mockFlashLoanReceiverInstance.setFailExecutionTransfer(true);
// await expectRevert(
// _lendingPoolInstance.flashLoan(
// _mockFlashLoanReceiverInstance.address,
// _daiAddress,
// new BigNumber(500).multipliedBy(oneEther),
// '0x10'
// ),
// 'The actual balance of the protocol is inconsistent'
// );
// });
// });

884
test/helpers/actions.ts Normal file
View File

@ -0,0 +1,884 @@
// import {convertToCurrencyDecimals} from '../../utils/misc-utils';
// import {
// LendingPoolInstance,
// LendingPoolCoreInstance,
// ATokenContract,
// ATokenInstance,
// ERC20Instance,
// ERC20DetailedInstance,
// MintableERC20Instance,
// } from '../../utils/typechain-types/truffle-contracts';
// import BigNumber from 'bignumber.js';
// import {getTruffleContractInstance} from '../../utils/truffle/truffle-core-utils';
// import {ContractId} from '../../utils/types';
// import {
// calcExpectedReserveDataAfterDeposit,
// calcExpectedReserveDataAfterRedeem,
// calcExpectedUserDataAfterDeposit,
// calcExpectedUserDataAfterRedeem,
// calcExpectedReserveDataAfterBorrow,
// calcExpectedUserDataAfterBorrow,
// calcExpectedReserveDataAfterRepay,
// calcExpectedUserDataAfterRepay,
// calcExpectedUserDataAfterSetUseAsCollateral,
// calcExpectedUserDataAfterSwapRateMode,
// calcExpectedReserveDataAfterSwapRateMode,
// calcExpectedReserveDataAfterStableRateRebalance,
// calcExpectedUserDataAfterStableRateRebalance,
// calcExpectedUsersDataAfterRedirectInterest,
// } from '../utils/calculations';
// import {getReserveAddressFromSymbol, getReserveData, getUserData} from '../utils/helpers';
// import {UserReserveData, ReserveData} from '../utils/interfaces';
// import {ONE_YEAR, MAX_UINT_AMOUNT, NIL_ADDRESS} from '../../utils/constants';
// import {TransactionObject} from 'web3/eth/types';
// const {time, expectRevert} = require('@openzeppelin/test-helpers');
// const truffleAssert = require('truffle-assertions');
// const chai = require('chai');
// const {expect} = chai;
// const almostEqualOrEqual = function(
// this: any,
// expected: ReserveData | UserReserveData,
// actual: ReserveData | UserReserveData
// ) {
// const keys = Object.keys(actual);
// keys.forEach(key => {
// if (
// key === 'lastUpdateTimestamp' ||
// key === 'marketStableRate' ||
// key === 'symbol' ||
// key === 'aTokenAddress' ||
// key === 'initialATokenExchangeRate' ||
// key === 'decimals'
// ) {
// //skipping consistency check on accessory data
// return;
// }
// this.assert(actual[key] != undefined, `Property ${key} is undefined in the actual data`);
// expect(expected[key] != undefined, `Property ${key} is undefined in the expected data`);
// if (actual[key] instanceof BigNumber) {
// const actualValue = (<BigNumber>actual[key]).decimalPlaces(0, BigNumber.ROUND_DOWN);
// const expectedValue = (<BigNumber>expected[key]).decimalPlaces(0, BigNumber.ROUND_DOWN);
// this.assert(
// actualValue.eq(expectedValue) ||
// actualValue.plus(1).eq(expectedValue) ||
// actualValue.eq(expectedValue.plus(1)) ||
// actualValue.plus(2).eq(expectedValue) ||
// actualValue.eq(expectedValue.plus(2)) ||
// actualValue.plus(3).eq(expectedValue) ||
// actualValue.eq(expectedValue.plus(3)),
// `expected #{act} to be almost equal or equal #{exp} for property ${key}`,
// `expected #{act} to be almost equal or equal #{exp} for property ${key}`,
// expectedValue.toFixed(0),
// actualValue.toFixed(0)
// );
// } else {
// this.assert(
// actual[key] !== null &&
// expected[key] !== null &&
// actual[key].toString() === expected[key].toString(),
// `expected #{act} to be equal #{exp} for property ${key}`,
// `expected #{act} to be equal #{exp} for property ${key}`,
// expected[key],
// actual[key]
// );
// }
// });
// };
// chai.use(function(chai: any, utils: any) {
// chai.Assertion.overwriteMethod('almostEqualOrEqual', function(original: any) {
// return function(this: any, expected: ReserveData | UserReserveData) {
// const actual = (expected as ReserveData)
// ? <ReserveData>this._obj
// : <UserReserveData>this._obj;
// almostEqualOrEqual.apply(this, [expected, actual]);
// };
// });
// });
// interface ActionsConfig {
// lendingPoolInstance: LendingPoolInstance;
// lendingPoolCoreInstance: LendingPoolCoreInstance;
// ethereumAddress: string;
// artifacts: Truffle.Artifacts;
// web3: Web3;
// skipIntegrityCheck: boolean;
// }
// export const configuration: ActionsConfig = <ActionsConfig>{};
// export const mint = async (reserveSymbol: string, amount: string, user: string) => {
// const {ethereumAddress, artifacts} = configuration;
// const reserve = await getReserveAddressFromSymbol(reserveSymbol, artifacts);
// if (ethereumAddress === reserve.toLowerCase()) {
// throw 'Cannot mint ethereum. Mint action is most likely not needed in this story';
// }
// const tokenInstance: MintableERC20Instance = await getTruffleContractInstance(
// artifacts,
// ContractId.MintableERC20,
// reserve
// );
// const tokensToMint = await convertToCurrencyDecimals(reserve, amount);
// const txOptions: any = {
// from: user,
// };
// await tokenInstance.mint(tokensToMint, txOptions);
// };
// export const approve = async (reserveSymbol: string, user: string) => {
// const {ethereumAddress, artifacts} = configuration;
// const reserve = await getReserveAddressFromSymbol(reserveSymbol, artifacts);
// if (ethereumAddress === reserve) {
// throw 'Cannot mint ethereum. Mint action is most likely not needed in this story';
// }
// const tokenInstance: ERC20Instance = await getTruffleContractInstance(
// artifacts,
// ContractId.ERC20,
// reserve
// );
// const txOptions: any = {
// from: user,
// };
// await tokenInstance.approve(
// configuration.lendingPoolCoreInstance.address,
// '100000000000000000000000000000',
// txOptions
// );
// };
// export const deposit = async (
// reserveSymbol: string,
// amount: string,
// user: string,
// sendValue: string,
// expectedResult: string,
// revertMessage?: string
// ) => {
// const {ethereumAddress, lendingPoolInstance, artifacts} = configuration;
// const reserve = await getReserveAddressFromSymbol(reserveSymbol, artifacts);
// const amountToDeposit = await convertToCurrencyDecimals(reserve, amount);
// const txOptions: any = {
// from: user,
// };
// const {reserveData: reserveDataBefore, userData: userDataBefore} = await getContractsData(
// reserve,
// user
// );
// if (ethereumAddress === reserve) {
// if (sendValue) {
// const valueToSend = await convertToCurrencyDecimals(reserve, sendValue);
// txOptions.value = valueToSend;
// } else {
// txOptions.value = amountToDeposit;
// }
// }
// if (expectedResult === 'success') {
// const txResult = await lendingPoolInstance.deposit(reserve, amountToDeposit, '0', txOptions);
// const {
// reserveData: reserveDataAfter,
// userData: userDataAfter,
// timestamp,
// } = await getContractsData(reserve, user);
// const {txCost, txTimestamp} = await getTxCostAndTimestamp(txResult);
// const expectedReserveData = calcExpectedReserveDataAfterDeposit(
// amountToDeposit,
// reserveDataBefore,
// txTimestamp
// );
// const expectedUserReserveData = calcExpectedUserDataAfterDeposit(
// amountToDeposit,
// reserveDataBefore,
// expectedReserveData,
// userDataBefore,
// txTimestamp,
// timestamp,
// txCost
// );
// expectEqual(reserveDataAfter, expectedReserveData);
// expectEqual(userDataAfter, expectedUserReserveData);
// truffleAssert.eventEmitted(txResult, 'Deposit', (ev: any) => {
// const {_reserve, _user, _amount} = ev;
// return (
// _reserve === reserve &&
// _user === user &&
// new BigNumber(_amount).isEqualTo(new BigNumber(amountToDeposit))
// );
// });
// } else if (expectedResult === 'revert') {
// await expectRevert(
// lendingPoolInstance.deposit(reserve, amountToDeposit, '0', txOptions),
// revertMessage
// );
// }
// };
// export const redeem = async (
// reserveSymbol: string,
// amount: string,
// user: string,
// expectedResult: string,
// revertMessage?: string
// ) => {
// const {
// aTokenInstance,
// reserve,
// txOptions,
// userData: userDataBefore,
// reserveData: reserveDataBefore,
// } = await getDataBeforeAction(reserveSymbol, user);
// let amountToRedeem = '0';
// if (amount !== '-1') {
// amountToRedeem = await convertToCurrencyDecimals(reserve, amount);
// } else {
// amountToRedeem = MAX_UINT_AMOUNT;
// }
// if (expectedResult === 'success') {
// const txResult = await aTokenInstance.redeem(amountToRedeem, txOptions);
// const {
// reserveData: reserveDataAfter,
// userData: userDataAfter,
// timestamp,
// } = await getContractsData(reserve, user);
// const {txCost, txTimestamp} = await getTxCostAndTimestamp(txResult);
// const expectedReserveData = calcExpectedReserveDataAfterRedeem(
// amountToRedeem,
// reserveDataBefore,
// userDataBefore,
// txTimestamp
// );
// const expectedUserData = calcExpectedUserDataAfterRedeem(
// amountToRedeem,
// reserveDataBefore,
// expectedReserveData,
// userDataBefore,
// txTimestamp,
// timestamp,
// txCost
// );
// const actualAmountRedeemed = userDataBefore.currentATokenBalance.minus(
// expectedUserData.currentATokenBalance
// );
// expectEqual(reserveDataAfter, expectedReserveData);
// expectEqual(userDataAfter, expectedUserData);
// truffleAssert.eventEmitted(txResult, 'Redeem', (ev: any) => {
// const {_from, _value} = ev;
// return _from === user && new BigNumber(_value).isEqualTo(actualAmountRedeemed);
// });
// } else if (expectedResult === 'revert') {
// await expectRevert(aTokenInstance.redeem(amountToRedeem, txOptions), revertMessage);
// }
// };
// export const borrow = async (
// reserveSymbol: string,
// amount: string,
// interestRateMode: string,
// user: string,
// timeTravel: string,
// expectedResult: string,
// revertMessage?: string
// ) => {
// const {lendingPoolInstance, artifacts} = configuration;
// const reserve = await getReserveAddressFromSymbol(reserveSymbol, artifacts);
// const {reserveData: reserveDataBefore, userData: userDataBefore} = await getContractsData(
// reserve,
// user
// );
// const amountToBorrow = await convertToCurrencyDecimals(reserve, amount);
// const txOptions: any = {
// from: user,
// };
// if (expectedResult === 'success') {
// const txResult = await lendingPoolInstance.borrow(
// reserve,
// amountToBorrow,
// interestRateMode,
// '0',
// txOptions
// );
// const {txCost, txTimestamp} = await getTxCostAndTimestamp(txResult);
// if (timeTravel) {
// const secondsToTravel = new BigNumber(timeTravel)
// .multipliedBy(ONE_YEAR)
// .div(365)
// .toNumber();
// await time.increase(secondsToTravel);
// }
// const {
// reserveData: reserveDataAfter,
// userData: userDataAfter,
// timestamp,
// } = await getContractsData(reserve, user);
// const expectedReserveData = calcExpectedReserveDataAfterBorrow(
// amountToBorrow,
// interestRateMode,
// reserveDataBefore,
// userDataBefore,
// txTimestamp,
// timestamp
// );
// const expectedUserData = calcExpectedUserDataAfterBorrow(
// amountToBorrow,
// interestRateMode,
// reserveDataBefore,
// expectedReserveData,
// userDataBefore,
// txTimestamp,
// timestamp,
// txCost
// );
// expectEqual(reserveDataAfter, expectedReserveData);
// expectEqual(userDataAfter, expectedUserData);
// truffleAssert.eventEmitted(txResult, 'Borrow', (ev: any) => {
// const {_reserve, _user, _amount, _borrowRateMode, _borrowRate, _originationFee} = ev;
// return (
// _reserve.toLowerCase() === reserve.toLowerCase() &&
// _user.toLowerCase() === user.toLowerCase() &&
// new BigNumber(_amount).eq(amountToBorrow) &&
// new BigNumber(_borrowRateMode).eq(expectedUserData.borrowRateMode) &&
// new BigNumber(_borrowRate).eq(expectedUserData.borrowRate) &&
// new BigNumber(_originationFee).eq(
// expectedUserData.originationFee.minus(userDataBefore.originationFee)
// )
// );
// });
// } else if (expectedResult === 'revert') {
// await expectRevert(
// lendingPoolInstance.borrow(reserve, amountToBorrow, interestRateMode, '0', txOptions),
// revertMessage
// );
// }
// };
// export const repay = async (
// reserveSymbol: string,
// amount: string,
// user: string,
// onBehalfOf: string,
// sendValue: string,
// expectedResult: string,
// revertMessage?: string
// ) => {
// const {lendingPoolInstance, artifacts, ethereumAddress} = configuration;
// const reserve = await getReserveAddressFromSymbol(reserveSymbol, artifacts);
// const {reserveData: reserveDataBefore, userData: userDataBefore} = await getContractsData(
// reserve,
// onBehalfOf
// );
// let amountToRepay = '0';
// if (amount !== '-1') {
// amountToRepay = await convertToCurrencyDecimals(reserve, amount);
// } else {
// amountToRepay = MAX_UINT_AMOUNT;
// }
// const txOptions: any = {
// from: user,
// };
// if (ethereumAddress === reserve) {
// if (sendValue) {
// if (sendValue !== '-1') {
// const valueToSend = await convertToCurrencyDecimals(reserve, sendValue);
// txOptions.value = valueToSend;
// } else {
// txOptions.value = userDataBefore.currentBorrowBalance
// .plus(await convertToCurrencyDecimals(reserve, '0.1'))
// .toFixed(0); //add 0.1 ETH to the repayment amount to cover for accrued interest during tx execution
// }
// } else {
// txOptions.value = amountToRepay;
// }
// }
// if (expectedResult === 'success') {
// const txResult = await lendingPoolInstance.repay(reserve, amountToRepay, onBehalfOf, txOptions);
// const {txCost, txTimestamp} = await getTxCostAndTimestamp(txResult);
// const {
// reserveData: reserveDataAfter,
// userData: userDataAfter,
// timestamp,
// } = await getContractsData(reserve, onBehalfOf);
// const expectedReserveData = calcExpectedReserveDataAfterRepay(
// amountToRepay,
// reserveDataBefore,
// userDataBefore,
// txTimestamp,
// timestamp
// );
// const expectedUserData = calcExpectedUserDataAfterRepay(
// amountToRepay,
// reserveDataBefore,
// expectedReserveData,
// userDataBefore,
// user,
// onBehalfOf,
// txTimestamp,
// timestamp,
// txCost
// );
// expectEqual(reserveDataAfter, expectedReserveData);
// expectEqual(userDataAfter, expectedUserData);
// truffleAssert.eventEmitted(txResult, 'Repay', (ev: any) => {
// const {_reserve, _user, _repayer} = ev;
// return (
// _reserve.toLowerCase() === reserve.toLowerCase() &&
// _user.toLowerCase() === onBehalfOf.toLowerCase() &&
// _repayer.toLowerCase() === user.toLowerCase()
// );
// });
// } else if (expectedResult === 'revert') {
// await expectRevert(
// lendingPoolInstance.repay(reserve, amountToRepay, onBehalfOf, txOptions),
// revertMessage
// );
// }
// };
// export const setUseAsCollateral = async (
// reserveSymbol: string,
// user: string,
// useAsCollateral: string,
// expectedResult: string,
// revertMessage?: string
// ) => {
// const {lendingPoolInstance, artifacts} = configuration;
// const reserve = await getReserveAddressFromSymbol(reserveSymbol, artifacts);
// const {reserveData: reserveDataBefore, userData: userDataBefore} = await getContractsData(
// reserve,
// user
// );
// const txOptions: any = {
// from: user,
// };
// const useAsCollateralBool = useAsCollateral.toLowerCase() === 'true';
// if (expectedResult === 'success') {
// const txResult = await lendingPoolInstance.setUserUseReserveAsCollateral(
// reserve,
// useAsCollateralBool,
// txOptions
// );
// const {txCost} = await getTxCostAndTimestamp(txResult);
// const {userData: userDataAfter} = await getContractsData(reserve, user);
// const expectedUserData = calcExpectedUserDataAfterSetUseAsCollateral(
// useAsCollateral.toLocaleLowerCase() === 'true',
// reserveDataBefore,
// userDataBefore,
// txCost
// );
// expectEqual(userDataAfter, expectedUserData);
// if (useAsCollateralBool) {
// truffleAssert.eventEmitted(txResult, 'ReserveUsedAsCollateralEnabled', (ev: any) => {
// const {_reserve, _user} = ev;
// return _reserve === reserve && _user === user;
// });
// } else {
// truffleAssert.eventEmitted(txResult, 'ReserveUsedAsCollateralDisabled', (ev: any) => {
// const {_reserve, _user} = ev;
// return _reserve === reserve && _user === user;
// });
// }
// } else if (expectedResult === 'revert') {
// await expectRevert(
// lendingPoolInstance.setUserUseReserveAsCollateral(reserve, useAsCollateralBool, txOptions),
// revertMessage
// );
// }
// };
// export const swapBorrowRateMode = async (
// reserveSymbol: string,
// user: string,
// expectedResult: string,
// revertMessage?: string
// ) => {
// const {lendingPoolInstance, artifacts} = configuration;
// const reserve = await getReserveAddressFromSymbol(reserveSymbol, artifacts);
// const {reserveData: reserveDataBefore, userData: userDataBefore} = await getContractsData(
// reserve,
// user
// );
// const txOptions: any = {
// from: user,
// };
// if (expectedResult === 'success') {
// const txResult = await lendingPoolInstance.swapBorrowRateMode(reserve, txOptions);
// const {txCost, txTimestamp} = await getTxCostAndTimestamp(txResult);
// const {reserveData: reserveDataAfter, userData: userDataAfter} = await getContractsData(
// reserve,
// user
// );
// const expectedReserveData = calcExpectedReserveDataAfterSwapRateMode(
// reserveDataBefore,
// userDataBefore,
// txTimestamp
// );
// const expectedUserData = calcExpectedUserDataAfterSwapRateMode(
// reserveDataBefore,
// expectedReserveData,
// userDataBefore,
// txCost,
// txTimestamp
// );
// expectEqual(reserveDataAfter, expectedReserveData);
// expectEqual(userDataAfter, expectedUserData);
// truffleAssert.eventEmitted(txResult, 'Swap', (ev: any) => {
// const {_user, _reserve, _newRateMode, _newRate} = ev;
// return (
// _user === user &&
// _reserve == reserve &&
// new BigNumber(_newRateMode).eq(expectedUserData.borrowRateMode) &&
// new BigNumber(_newRate).eq(expectedUserData.borrowRate)
// );
// });
// } else if (expectedResult === 'revert') {
// await expectRevert(lendingPoolInstance.swapBorrowRateMode(reserve, txOptions), revertMessage);
// }
// };
// export const rebalanceStableBorrowRate = async (
// reserveSymbol: string,
// user: string,
// target: string,
// expectedResult: string,
// revertMessage?: string
// ) => {
// const {lendingPoolInstance, artifacts} = configuration;
// const reserve = await getReserveAddressFromSymbol(reserveSymbol, artifacts);
// const {reserveData: reserveDataBefore, userData: userDataBefore} = await getContractsData(
// reserve,
// target
// );
// const txOptions: any = {
// from: user,
// };
// if (expectedResult === 'success') {
// const txResult = await lendingPoolInstance.rebalanceStableBorrowRate(
// reserve,
// target,
// txOptions
// );
// const {txCost, txTimestamp} = await getTxCostAndTimestamp(txResult);
// const {reserveData: reserveDataAfter, userData: userDataAfter} = await getContractsData(
// reserve,
// target
// );
// const expectedReserveData = calcExpectedReserveDataAfterStableRateRebalance(
// reserveDataBefore,
// userDataBefore,
// txTimestamp
// );
// const expectedUserData = calcExpectedUserDataAfterStableRateRebalance(
// reserveDataBefore,
// expectedReserveData,
// userDataBefore,
// txCost,
// txTimestamp
// );
// expectEqual(reserveDataAfter, expectedReserveData);
// expectEqual(userDataAfter, expectedUserData);
// truffleAssert.eventEmitted(txResult, 'RebalanceStableBorrowRate', (ev: any) => {
// const {_user, _reserve, _newStableRate} = ev;
// return (
// _user.toLowerCase() === target.toLowerCase() &&
// _reserve.toLowerCase() === reserve.toLowerCase() &&
// new BigNumber(_newStableRate).eq(expectedUserData.borrowRate)
// );
// });
// } else if (expectedResult === 'revert') {
// await expectRevert(
// lendingPoolInstance.rebalanceStableBorrowRate(reserve, target, txOptions),
// revertMessage
// );
// }
// };
// export const redirectInterestStream = async (
// reserveSymbol: string,
// user: string,
// to: string,
// expectedResult: string,
// revertMessage?: string
// ) => {
// const {
// aTokenInstance,
// reserve,
// txOptions,
// userData: fromDataBefore,
// reserveData: reserveDataBefore,
// } = await getDataBeforeAction(reserveSymbol, user);
// const {userData: toDataBefore} = await getContractsData(reserve, to);
// if (expectedResult === 'success') {
// const txResult = await aTokenInstance.redirectInterestStream(to, txOptions);
// const {txCost, txTimestamp} = await getTxCostAndTimestamp(txResult);
// const {userData: fromDataAfter} = await getContractsData(reserve, user);
// const {userData: toDataAfter} = await getContractsData(reserve, to);
// const [expectedFromData, expectedToData] = calcExpectedUsersDataAfterRedirectInterest(
// reserveDataBefore,
// fromDataBefore,
// toDataBefore,
// user,
// to,
// true,
// txCost,
// txTimestamp
// );
// expectEqual(fromDataAfter, expectedFromData);
// expectEqual(toDataAfter, expectedToData);
// truffleAssert.eventEmitted(txResult, 'InterestStreamRedirected', (ev: any) => {
// const {_from, _to} = ev;
// return _from === user
// && _to === (to === user ? NIL_ADDRESS : to);
// });
// } else if (expectedResult === 'revert') {
// await expectRevert(aTokenInstance.redirectInterestStream(to, txOptions), revertMessage);
// }
// };
// export const redirectInterestStreamOf = async (
// reserveSymbol: string,
// user: string,
// from: string,
// to: string,
// expectedResult: string,
// revertMessage?: string
// ) => {
// const {
// aTokenInstance,
// reserve,
// txOptions,
// userData: fromDataBefore,
// reserveData: reserveDataBefore,
// } = await getDataBeforeAction(reserveSymbol, from);
// const {userData: toDataBefore} = await getContractsData(reserve, user);
// if (expectedResult === 'success') {
// const txResult = await aTokenInstance.redirectInterestStreamOf(from, to, txOptions);
// const {txCost, txTimestamp} = await getTxCostAndTimestamp(txResult);
// const {userData: fromDataAfter} = await getContractsData(reserve, from);
// const {userData: toDataAfter} = await getContractsData(reserve, to);
// const [expectedFromData, exptectedToData] = calcExpectedUsersDataAfterRedirectInterest(
// reserveDataBefore,
// fromDataBefore,
// toDataBefore,
// from,
// to,
// from === user,
// txCost,
// txTimestamp
// );
// expectEqual(fromDataAfter, expectedFromData);
// expectEqual(toDataAfter, exptectedToData);
// truffleAssert.eventEmitted(txResult, 'InterestStreamRedirected', (ev: any) => {
// const {_from, _to} = ev;
// return _from.toLowerCase() === from.toLowerCase() && _to.toLowerCase() === to.toLowerCase();
// });
// } else if (expectedResult === 'revert') {
// await expectRevert(aTokenInstance.redirectInterestStreamOf(from, to, txOptions), revertMessage);
// }
// };
// export const allowInterestRedirectionTo = async (
// reserveSymbol: string,
// user: string,
// to: string,
// expectedResult: string,
// revertMessage?: string
// ) => {
// const {aTokenInstance, txOptions} = await getDataBeforeAction(reserveSymbol, user);
// if (expectedResult === 'success') {
// const txResult = await aTokenInstance.allowInterestRedirectionTo(to, txOptions);
// truffleAssert.eventEmitted(txResult, 'InterestRedirectionAllowanceChanged', (ev: any) => {
// const {_from, _to} = ev;
// return _from.toLowerCase() === user.toLowerCase() && _to.toLowerCase() === to.toLowerCase();
// });
// } else if (expectedResult === 'revert') {
// await expectRevert(aTokenInstance.allowInterestRedirectionTo(to, txOptions), revertMessage);
// }
// };
// const expectEqual = (
// actual: UserReserveData | ReserveData,
// expected: UserReserveData | ReserveData
// ) => {
// if (!configuration.skipIntegrityCheck) {
// expect(actual).to.be.almostEqualOrEqual(expected);
// }
// };
// interface ActionData {
// reserve: string;
// reserveData: ReserveData;
// userData: UserReserveData;
// aTokenInstance: ATokenInstance;
// txOptions: any;
// }
// const getDataBeforeAction = async (reserveSymbol: string, user: string): Promise<ActionData> => {
// const {artifacts} = configuration;
// const reserve = await getReserveAddressFromSymbol(reserveSymbol, artifacts);
// const {reserveData, userData} = await getContractsData(reserve, user);
// const {aTokenAddress} = reserveData;
// const aTokenInstance: ATokenInstance = await getTruffleContractInstance(
// artifacts,
// ContractId.AToken,
// aTokenAddress
// );
// const txOptions: any = {
// from: user,
// };
// return {
// reserve,
// reserveData,
// userData,
// aTokenInstance,
// txOptions,
// };
// };
// const getTxCostAndTimestamp = async (tx: any) => {
// const txTimestamp = new BigNumber((await web3.eth.getBlock(tx.receipt.blockNumber)).timestamp);
// const txInfo = await configuration.web3.eth.getTransaction(tx.receipt.transactionHash);
// const txCost = new BigNumber(tx.receipt.gasUsed).multipliedBy(txInfo.gasPrice);
// return {txCost, txTimestamp};
// };
// const getContractsData = async (reserve: string, user: string) => {
// const [reserveData, userData, timestamp] = await Promise.all([
// getReserveData(configuration.lendingPoolInstance, reserve, artifacts),
// getUserData(
// configuration.lendingPoolInstance,
// configuration.lendingPoolCoreInstance,
// reserve,
// user,
// artifacts
// ),
// time.latest(),
// ]);
// return {
// reserveData,
// userData,
// timestamp: new BigNumber(timestamp),
// };
// };

View File

@ -0,0 +1,233 @@
// import {
// deposit,
// mint,
// approve,
// redeem,
// borrow,
// repay,
// setUseAsCollateral,
// swapBorrowRateMode,
// rebalanceStableBorrowRate,
// allowInterestRedirectionTo,
// redirectInterestStream,
// redirectInterestStreamOf,
// } from '../actions';
// import {on} from 'cluster';
// import { RateMode } from '../../utils/types';
// export interface Action {
// name: string;
// args?: any;
// expected: string;
// revertMessage?: string;
// }
// export interface Story {
// description: string;
// actions: Action[];
// }
// export interface Scenario {
// title: string;
// description: string;
// stories: Story[];
// }
// export const executeStory = async (story: Story, users: string[]) => {
// for (const action of story.actions) {
// await executeAction(action, users);
// }
// };
// const executeAction = async (action: Action, users: string[]) => {
// const {reserve, user} = action.args;
// const {name, expected, revertMessage} = action;
// if (!name || name === '') {
// throw 'Action name is missing';
// }
// if (!reserve || reserve === '') {
// throw 'Invalid reserve selected for deposit';
// }
// if (!user || user === '') {
// throw `Invalid user selected to deposit into the ${reserve} reserve`;
// }
// if (!expected || expected === '') {
// throw `An expected resut for action ${name} is required`;
// }
// const userAddress = users[parseInt(user)];
// switch (name) {
// case 'mint':
// const {amount} = action.args;
// if (!amount || amount === '') {
// throw `Invalid amount of ${reserve} to mint`;
// }
// await mint(reserve, amount, userAddress);
// break;
// case 'approve':
// await approve(reserve, userAddress);
// break;
// case 'deposit':
// {
// const {amount, sendValue} = action.args;
// if (!amount || amount === '') {
// throw `Invalid amount to deposit into the ${reserve} reserve`;
// }
// await deposit(reserve, amount, userAddress, sendValue, expected, revertMessage);
// }
// break;
// case 'redeem':
// {
// const {amount} = action.args;
// if (!amount || amount === '') {
// throw `Invalid amount to redeem from the ${reserve} reserve`;
// }
// await redeem(reserve, amount, userAddress, expected, revertMessage);
// }
// break;
// case 'borrow':
// {
// const {amount, borrowRateMode, timeTravel} = action.args;
// if (!amount || amount === '') {
// throw `Invalid amount to borrow from the ${reserve} reserve`;
// }
// let rateMode: string = RateMode.None;
// if (borrowRateMode === 'none') {
// RateMode.None;
// } else if (borrowRateMode === 'stable') {
// rateMode = RateMode.Stable;
// } else if (borrowRateMode === 'variable') {
// rateMode = RateMode.Variable;
// } else {
// //random value, to test improper selection of the parameter
// rateMode = '4';
// }
// await borrow(reserve, amount, rateMode, userAddress, timeTravel, expected, revertMessage);
// }
// break;
// case 'repay':
// {
// const {amount, sendValue} = action.args;
// let {onBehalfOf} = action.args;
// if (!amount || amount === '') {
// throw `Invalid amount to repay into the ${reserve} reserve`;
// }
// if (!onBehalfOf || onBehalfOf === '') {
// console.log(
// 'WARNING: No onBehalfOf specified for a repay action. Defaulting to the repayer address'
// );
// onBehalfOf = userAddress;
// } else {
// onBehalfOf = users[parseInt(onBehalfOf)];
// }
// await repay(reserve, amount, userAddress, onBehalfOf, sendValue, expected, revertMessage);
// }
// break;
// case 'setUseAsCollateral':
// {
// const {useAsCollateral} = action.args;
// if (!useAsCollateral || useAsCollateral === '') {
// throw `A valid value for useAsCollateral needs to be set when calling setUseReserveAsCollateral on reserve ${reserve}`;
// }
// await setUseAsCollateral(reserve, userAddress, useAsCollateral, expected, revertMessage);
// }
// break;
// case 'swapBorrowRateMode':
// await swapBorrowRateMode(reserve, userAddress, expected, revertMessage);
// break;
// case 'rebalanceStableBorrowRate':
// {
// const {target} = action.args;
// if (!target || target === '') {
// throw `A target must be selected when trying to rebalance a stable rate`;
// }
// const targetAddress = users[parseInt(target)];
// await rebalanceStableBorrowRate(
// reserve,
// userAddress,
// targetAddress,
// expected,
// revertMessage
// );
// }
// break;
// case 'redirectInterestStream':
// {
// const {to} = action.args;
// if (!to || to === '') {
// throw `A target must be selected when trying to redirect the interest`;
// }
// const toAddress = users[parseInt(to)];
// await redirectInterestStream(reserve, userAddress, toAddress, expected, revertMessage);
// }
// break;
// case 'redirectInterestStreamOf':
// {
// const {from, to} = action.args;
// if (!from || from === '') {
// throw `A from address must be specified when trying to redirect the interest`;
// }
// if (!to || to === '') {
// throw `A target must be selected when trying to redirect the interest`;
// }
// const toAddress = users[parseInt(to)];
// const fromAddress = users[parseInt(from)];
// await redirectInterestStreamOf(
// reserve,
// userAddress,
// fromAddress,
// toAddress,
// expected,
// revertMessage
// );
// }
// break;
// case 'allowInterestRedirectionTo':
// {
// const {to} = action.args;
// if (!to || to === '') {
// throw `A target must be selected when trying to redirect the interest`;
// }
// const toAddress = users[parseInt(to)];
// await allowInterestRedirectionTo(reserve, userAddress, toAddress, expected, revertMessage);
// }
// break;
// default:
// throw `Invalid action requested: ${name}`;
// }
// };

View File

@ -0,0 +1,111 @@
{
"title": "LendingPool: Borrow negatives (reverts)",
"description": "Test cases for the deposit function.",
"stories": [
{
"description": "User 0 deposits 1000 DAI, user 1 deposits 1 ETH as collateral and tries to borrow 100 DAI with rate mode NONE (revert expected)",
"actions": [
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "1",
"user": "1",
"sendValue": "1"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "none",
"user": "1"
},
"expected": "revert",
"revertMessage" : "Invalid interest rate mode selected"
}
]
},
{
"description": "User 0 deposits 1000 DAI, user 1 deposits 1 ETH as collateral and tries to borrow 100 DAI with an invalid rate mode (revert expected)",
"actions": [
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "1",
"user": "1",
"sendValue": "1"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "invalid",
"user": "1"
},
"expected": "revert",
"revertMessage" : "Invalid interest rate mode selected"
}
]
}
]
}

View File

@ -0,0 +1,709 @@
{
"title": "LendingPool: Borrow/repay (stable rate)",
"description": "Test cases for the borrow function, stable mode.",
"stories": [
{
"description": "User 0 deposits 1000 DAI, user 1 deposits 1 ETH as collateral and borrows 100 DAI at stable rate",
"actions": [
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "1",
"user": "1",
"sendValue": "1"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "stable",
"user": "1",
"timeTravel": "365"
},
"expected": "success"
}
]
},
{
"description": "User 1 tries to borrow the rest of the DAI liquidity (revert expected)",
"actions": [
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "900",
"borrowRateMode": "stable",
"user": "1"
},
"expected": "revert",
"revertMessage": "There is not enough collateral to cover a new borrow"
}
]
},
{
"description": "User 1 repays the DAI borrow after one year",
"actions": [
{
"name": "mint",
"description": "Mint 15 DAI to cover the interest",
"args": {
"reserve": "DAI",
"amount": "15",
"user": "1"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "1"
},
"expected": "success"
},
{
"name": "repay",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "1",
"onBehalfOf": "1"
},
"expected": "success"
}
]
},
{
"description": "User 0 redeems the deposited DAI plus interest",
"actions": [
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "0"
},
"expected": "success"
}
]
},
{
"description": "User 1 deposits 1000 DAI, user 2 tries to borrow 1000 DAI at a stable rate without any collateral (revert expected)",
"actions": [
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "1"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "1"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "1"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "1000",
"borrowRateMode": "stable",
"user": "2"
},
"expected": "revert",
"revertMessage": "The collateral balance is 0"
}
]
},
{
"description": "User 1 deposits 1000 DAI, user 2 deposits 0.92267103215 ETH, tries to borrow 187.5 DAI which is the maximum amount he can borrow, if fees were not considered. (revert expected)",
"actions": [
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "1"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "1"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "1"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "0.92267103215",
"user": "2",
"sendValue": "0.92267103215"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "187.5",
"borrowRateMode": "stable",
"user": "2"
},
"expected": "revert",
"revertMessage": "There is not enough collateral to cover a new borrow"
},
{
"name": "redeem",
"args": {
"reserve": "ETH",
"amount": "-1",
"user": "2"
},
"expected": "success"
},
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "1"
},
"expected": "success"
}
]
},
{
"description": "User 1 deposits 1000 USDC, user 2 deposits 0.91928534104 ETH, tries to borrow 187.5 USDC which is the maximum amount he can borrow, if fees were not considered. (revert expected)",
"actions": [
{
"name": "mint",
"args": {
"reserve": "USDC",
"amount": "1000",
"user": "1"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "USDC",
"user": "1"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "USDC",
"amount": "1000",
"user": "1"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "0.91928534104",
"user": "2",
"sendValue": "0.91928534104"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "USDC",
"amount": "187.5",
"borrowRateMode": "stable",
"user": "2"
},
"expected": "revert",
"revertMessage": "There is not enough collateral to cover a new borrow"
},
{
"name": "redeem",
"args": {
"reserve": "ETH",
"amount": "-1",
"user": "2"
},
"expected": "success"
},
{
"name": "redeem",
"args": {
"reserve": "USDC",
"amount": "-1",
"user": "1"
},
"expected": "success"
}
]
},
{
"description": "User 1 deposits 1.5 ETH, user 2 deposits 100 DAI, tries to borrow 0.276801309645 ETH which is the maximum amount he can borrow, if fees were not considered. (revert expected)",
"actions": [
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "1.5",
"user": "1",
"sendValue": "1.5"
},
"expected": "success"
},
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "100",
"user": "2"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "2"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "100",
"user": "2"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "ETH",
"amount": "0.276801309645",
"borrowRateMode": "stable",
"user": "2"
},
"expected": "revert",
"revertMessage": "There is not enough collateral to cover a new borrow"
},
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "2"
},
"expected": "success"
},
{
"name": "redeem",
"args": {
"reserve": "ETH",
"amount": "-1",
"user": "1"
},
"expected": "success"
}
]
},
{
"description": "User 0 deposits 1000 DAI, user 1,2,3,4 deposit 1 ETH each and borrow 100 DAI at stable rate. Everything is repaid, user 0 redeems",
"actions": [
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "1",
"user": "1",
"sendValue": "1"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "stable",
"user": "1",
"timeTravel": "365"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "1",
"user": "2",
"sendValue": "1"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "stable",
"user": "2",
"timeTravel": "365"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "1",
"user": "3",
"sendValue": "1"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "stable",
"user": "3",
"timeTravel": "365"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "1",
"user": "4",
"sendValue": "1"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "stable",
"user": "4",
"timeTravel": "365"
},
"expected": "success"
},
{
"name": "mint",
"description": "Mint 15 DAI to cover the interest",
"args": {
"reserve": "DAI",
"amount": "15",
"user": "1"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "1"
},
"expected": "success"
},
{
"name": "repay",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "1",
"onBehalfOf": "1"
},
"expected": "success"
},
{
"name": "mint",
"description": "Mint 15 DAI to cover the interest",
"args": {
"reserve": "DAI",
"amount": "15",
"user": "2"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "2"
},
"expected": "success"
},
{
"name": "repay",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "2",
"onBehalfOf": "2"
},
"expected": "success"
},
{
"name": "mint",
"description": "Mint 30 DAI to cover the interest",
"args": {
"reserve": "DAI",
"amount": "30",
"user": "3"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "3"
},
"expected": "success"
},
{
"name": "repay",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "3",
"onBehalfOf": "3"
},
"expected": "success"
},
{
"name": "mint",
"description": "Mint 30 DAI to cover the interest",
"args": {
"reserve": "DAI",
"amount": "30",
"user": "4"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "4"
},
"expected": "success"
},
{
"name": "repay",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "4",
"onBehalfOf": "4"
},
"expected": "success"
},
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "0"
},
"expected": "success"
}
]
},
{
"description": "User 0 deposits 1000 DAI, user 1 deposits 2 ETH and borrow 100 DAI at stable rate first, then 100 DAI at variable rate, repays everything. User 0 redeems",
"actions": [
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "2",
"user": "1",
"sendValue": "2"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "stable",
"user": "1",
"timeTravel": "365"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "variable",
"user": "1",
"timeTravel": "365"
},
"expected": "success"
},
{
"name": "mint",
"description": "Mint 50 DAI to cover the interest",
"args": {
"reserve": "DAI",
"amount": "50",
"user": "1"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "1"
},
"expected": "success"
},
{
"name": "repay",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "1",
"onBehalfOf": "1"
},
"expected": "success"
},
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "0"
},
"expected": "success"
}
]
}
]
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,232 @@
{
"title" : "LendingPool: Deposit",
"description" : "Test cases for the deposit function.",
"stories": [
{
"description" : "User 0 Deposits 1000 DAI in an empty reserve",
"actions" : [
{
"name" : "mint",
"args" : {
"reserve" : "DAI",
"amount" : "1000",
"user" : "0"
},
"expected": "success"
},
{
"name" : "approve",
"args" : {
"reserve" : "DAI",
"user" : "0"
},
"expected": "success"
},
{
"name" : "deposit",
"args" : {
"reserve" : "DAI",
"amount" : "1000",
"user" : "0"
},
"expected": "success"
}
]
},
{
"description" : "User 1 deposits 1000 DAI after user 1",
"actions" : [
{
"name" : "mint",
"args" : {
"reserve" : "DAI",
"amount" : "1000",
"user" : "1"
},
"expected": "success"
},
{
"name" : "approve",
"args" : {
"reserve" : "DAI",
"user" : "1"
},
"expected": "success"
},
{
"name" : "deposit",
"args" : {
"reserve" : "DAI",
"amount" : "1000",
"user" : "1"
},
"expected": "success"
}
]
},
{
"description" : "User 0 deposits 1000 USDC in an empty reserve",
"actions" : [
{
"name" : "mint",
"args" : {
"reserve" : "USDC",
"amount" : "1000",
"user" : "0"
},
"expected": "success"
},
{
"name" : "approve",
"args" : {
"reserve" : "USDC",
"user" : "0"
},
"expected": "success"
},
{
"name" : "deposit",
"args" : {
"reserve" : "USDC",
"amount" : "1000",
"user" : "0"
},
"expected": "success"
}
]
},
{
"description" : "User 1 deposits 1000 USDC after user 0",
"actions" : [
{
"name" : "mint",
"args" : {
"reserve" : "USDC",
"amount" : "1000",
"user" : "1"
},
"expected": "success"
},
{
"name" : "approve",
"args" : {
"reserve" : "USDC",
"user" : "1"
},
"expected": "success"
},
{
"name" : "deposit",
"args" : {
"reserve" : "USDC",
"amount" : "1000",
"user" : "1"
},
"expected": "success"
}
]
},
{
"description" : "User 0 deposits 1 ETH in an empty reserve",
"actions" : [
{
"name" : "deposit",
"args" : {
"reserve" : "ETH",
"amount" : "1",
"user" : "0",
"sendValue" : "1"
},
"expected": "success"
}
]
},
{
"description" : "User 1 deposits 1 ETH after user 0",
"actions" : [
{
"name" : "deposit",
"args" : {
"reserve" : "ETH",
"amount" : "1",
"user" : "1",
"sendValue" : "1"
},
"expected": "success"
}
]
},
{
"description" : "User 1 deposits 0 ETH (revert expected)",
"actions" : [
{
"name" : "deposit",
"args" : {
"reserve" : "ETH",
"amount" : "0",
"user" : "1"
},
"expected": "revert",
"revertMessage" : "Amount must be greater than 0"
}
]
},
{
"description" : "User 1 deposits 0 DAI",
"actions" : [
{
"name" : "deposit",
"args" : {
"reserve" : "DAI",
"amount" : "0",
"user" : "1"
},
"expected": "revert",
"revertMessage" : "Amount must be greater than 0"
}
]
},
{
"description" : "User 1 tries to deposit ETH without sending any value",
"actions" : [
{
"name" : "deposit",
"args" : {
"reserve" : "ETH",
"amount" : "1",
"user" : "1",
"sendValue" : "0"
},
"expected": "revert",
"revertMessage" : "The amount and the value sent to deposit do not match"
}
]
},
{
"description" : "User 1 tries to deposit ETH by sending less value than required",
"actions" : [
{
"name" : "deposit",
"args" : {
"reserve" : "ETH",
"amount" : "1",
"user" : "1",
"sendValue" : "0.5"
},
"expected": "revert",
"revertMessage" : "The amount and the value sent to deposit do not match"
}
]
}
]
}

View File

@ -0,0 +1,102 @@
{
"title": "AToken: interest rate redirection negative test cases",
"description": "Test cases for the aToken interest rate redirection.",
"stories": [
{
"description": "User 0 deposits 1000 DAI, tries to give allowance to redirect interest to himself (revert expected)",
"actions": [
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "allowInterestRedirectionTo",
"args": {
"reserve": "DAI",
"user": "0",
"to": "0"
},
"expected": "revert",
"revertMessage": "User cannot give allowance to himself"
}
]
},
{
"description": "User 1 tries to redirect the interest of user 0 without allowance (revert expected)",
"actions": [
{
"name": "redirectInterestStreamOf",
"args": {
"reserve": "DAI",
"user": "1",
"from": "0",
"to": "2"
},
"expected": "revert",
"revertMessage": "Caller is not allowed to redirect the interest of the user"
}
]
},
{
"description": "User 0 tries to redirect the interest to user 2 twice (revert expected)",
"actions": [
{
"name": "redirectInterestStream",
"args": {
"reserve": "DAI",
"user": "0",
"to": "2"
},
"expected": "success"
},
{
"name": "redirectInterestStream",
"args": {
"reserve": "DAI",
"user": "0",
"to": "2"
},
"expected": "revert",
"revertMessage": "Interest is already redirected to the user"
}
]
},
{
"description": "User 3 with 0 balance tries to redirect the interest to user 2 (revert expected)",
"actions": [
{
"name": "redirectInterestStream",
"args": {
"reserve": "DAI",
"user": "3",
"to": "2"
},
"expected": "revert",
"revertMessage" : "Interest stream can only be redirected if there is a valid balance"
}
]
}
]
}

View File

@ -0,0 +1,386 @@
{
"title": "AToken: interest rate redirection",
"description": "Test cases for the aToken interest rate redirection.",
"stories": [
{
"description": "User 0 deposits 1000 DAI, redirects the interest to user 2",
"actions": [
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "redirectInterestStream",
"args": {
"reserve": "DAI",
"user": "0",
"to": "2"
},
"expected": "success"
}
]
},
{
"description": "User 1 deposits 1 ETH, borrows 100 DAI, repays after one year. Users 0 deposits another 1000 DAI. Redirected balance of user 2 is updated",
"actions": [
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "2",
"user": "1",
"sendValue": "2"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "stable",
"user": "1",
"timeTravel": "365"
},
"expected": "success"
},
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
}
]
},
{
"description": "User 1 borrows another 100 DAI, repay the whole amount. Users 0 and User 2 redeem",
"actions": [
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "stable",
"user": "1",
"timeTravel": "365"
},
"expected": "success"
},
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "100",
"user": "1"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "1"
},
"expected": "success"
},
{
"name": "repay",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "1",
"onBehalfOf": "1"
},
"expected": "success"
},
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "0"
},
"expected": "success"
},
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "2"
},
"expected": "success"
}
]
},
{
"description": "User 0 deposits 1000 DAI, redirects interest to user 2, user 1 borrows 100 DAI. After one year, user 0 redirects interest back to himself, user 1 borrows another 100 DAI and after another year repays the whole amount. Users 0 and User 2 redeem",
"actions": [
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "redirectInterestStream",
"args": {
"reserve": "DAI",
"user": "0",
"to": "2"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "stable",
"user": "1",
"timeTravel": "365"
},
"expected": "success"
},
{
"name": "redirectInterestStream",
"args": {
"reserve": "DAI",
"user": "0",
"to": "0"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "stable",
"user": "1",
"timeTravel": "365"
},
"expected": "success"
},
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "100",
"user": "1"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "1"
},
"expected": "success"
},
{
"name": "repay",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "1",
"onBehalfOf": "1"
},
"expected": "success"
},
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "0"
},
"expected": "success"
},
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "2"
},
"expected": "success"
}
]
},
{
"description": "User 0 deposits 1000 DAI, redirects interest to user 2, user 1 borrows 100 DAI. After one year, user 2 redirects interest to user 3. user 1 borrows another 100 DAI, user 0 deposits another 100 DAI. User 1 repays the whole amount. Users 0, 2 first 1 DAI, then everything. User 3 redeems",
"actions": [
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "redirectInterestStream",
"args": {
"reserve": "DAI",
"user": "0",
"to": "2"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "stable",
"user": "1",
"timeTravel": "365"
},
"expected": "success"
},
{
"name": "redirectInterestStream",
"args": {
"reserve": "DAI",
"user": "2",
"to": "3"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "stable",
"user": "1",
"timeTravel": "365"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "100",
"user": "0"
},
"expected": "success"
},
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "100",
"user": "1"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "1"
},
"expected": "success"
},
{
"name": "repay",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "1",
"onBehalfOf": "1"
},
"expected": "success"
},
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "1",
"user": "0"
},
"expected": "success"
},
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "1",
"user": "2"
},
"expected": "success"
},
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "0"
},
"expected": "success"
},
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "2"
},
"expected": "success"
},
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "3"
},
"expected": "success"
}
]
}
]
}

View File

@ -0,0 +1,175 @@
{
"title": "LendingPool: Rebalance stable rate",
"description": "Test cases for the rebalanceStableBorrowRate() function.",
"stories": [
{
"description": "User 0 tries to rebalance user 1 who has no borrows in progress (revert expected)",
"actions": [
{
"name": "rebalanceStableBorrowRate",
"args": {
"reserve": "DAI",
"user": "0",
"target": "1"
},
"expected": "revert",
"revertMessage": "User does not have any borrow for this reserve"
}
]
},
{
"description": "User 0 deposits 1000 DAI, user 1 deposits 1 ETH, borrows 100 DAI at a variable rate, user 0 rebalances user 1 (revert expected)",
"actions": [
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "1",
"user": "1",
"sendValue": "1"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "variable",
"user": "1",
"timeTravel": "365"
},
"expected": "success"
},
{
"name": "rebalanceStableBorrowRate",
"args": {
"reserve": "DAI",
"user": "0",
"target": "1"
},
"expected": "revert",
"revertMessage": "The user borrow is variable and cannot be rebalanced"
}
]
},
{
"description": "User 1 swaps to stable, user 0 tries to rebalance but the conditions are not met (revert expected)",
"actions": [
{
"name": "swapBorrowRateMode",
"args": {
"reserve": "DAI",
"user": "1"
},
"expected": "success"
},
{
"name": "rebalanceStableBorrowRate",
"args": {
"reserve": "DAI",
"user": "0",
"target": "1"
},
"expected": "revert",
"revertMessage": "Interest rate rebalance conditions were not met"
}
]
},
{
"description": "User 2 deposits ETH and borrows the remaining DAI, causing the stable rates to rise (liquidity rate < user 1 borrow rate). User 0 tries to rebalance user 1 (revert expected)",
"actions": [
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "5",
"user": "2",
"sendValue": "5"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "variable",
"user": "2"
},
"expected": "success"
},
{
"name": "rebalanceStableBorrowRate",
"args": {
"reserve": "DAI",
"user": "0",
"target": "1"
},
"expected": "revert",
"revertMessage": "Interest rate rebalance conditions were not met"
}
]
},
{
"description": "User 2 borrows more DAI, causing the liquidity rate to rise above user 1 stable borrow rate User 0 rebalances user 1",
"actions": [
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "3",
"user": "2",
"sendValue": "3"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "700",
"borrowRateMode": "variable",
"user": "2"
},
"expected": "success"
},
{
"name": "rebalanceStableBorrowRate",
"args": {
"reserve": "DAI",
"user": "0",
"target": "1"
},
"expected": "success"
}
]
}
]
}

View File

@ -0,0 +1,98 @@
{
"title": "LendingPool: Redeem negative test cases",
"description": "Redeem function.",
"stories": [
{
"description": "Users 0 Deposits 1000 DAI and tries to redeem 0 DAI (revert expected)",
"actions": [
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "0",
"user": "0"
},
"expected": "revert",
"revertMessage": "Amount to redeem needs to be > 0"
}
]
},
{
"description": "Users 0 tries to redeem 1100 DAI from the 1000 DAI deposited (revert expected)",
"actions": [
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "1100",
"user": "0"
},
"expected": "revert",
"revertMessage": "User cannot redeem more than the available balance"
}
]
},
{
"description": "Users 1 deposits 1 ETH, borrows 100 DAI, tries to redeem the 1 ETH deposited (revert expected)",
"actions": [
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "1",
"user": "1",
"sendValue": "1"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"user": "1",
"borrowRateMode": "stable"
},
"expected": "success"
},
{
"name": "redeem",
"args": {
"reserve": "ETH",
"amount": "-1",
"user": "1"
},
"expected": "revert",
"revertMessage" : "Transfer cannot be allowed."
}
]
}
]
}

View File

@ -0,0 +1,311 @@
{
"title": "LendingPool: Redeem",
"description": "Redeem function.",
"stories": [
{
"description": "User 0 Deposits 1000 DAI in an empty reserve",
"actions": [
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
}
]
},
{
"description": "User 0 redeems half of the deposited DAI",
"actions": [
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "500",
"user": "0"
},
"expected": "success"
}
]
},
{
"description": "User 0 redeems remaining half of the deposited DAI",
"actions": [
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "0"
},
"expected": "success"
}
]
},
{
"description": "User 0 Deposits 1000 USDC in an empty reserve",
"actions": [
{
"name": "mint",
"args": {
"reserve": "USDC",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "USDC",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "USDC",
"amount": "1000",
"user": "0"
},
"expected": "success"
}
]
},
{
"description": "User 0 redeems half of the deposited USDC",
"actions": [
{
"name": "redeem",
"args": {
"reserve": "USDC",
"amount": "500",
"user": "0"
},
"expected": "success"
}
]
},
{
"description": "User 0 redeems remaining half of the deposited USDC",
"actions": [
{
"name": "redeem",
"args": {
"reserve": "USDC",
"amount": "-1",
"user": "0"
},
"expected": "success"
}
]
},
{
"description": "User 0 Deposits 1 ETH in an empty reserve",
"actions": [
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "1",
"user": "0",
"sendValue": "1"
},
"expected": "success"
}
]
},
{
"description": "User 0 redeems half of the deposited ETH",
"actions": [
{
"name": "redeem",
"args": {
"reserve": "ETH",
"amount": "0.5",
"user": "0"
},
"expected": "success"
}
]
},
{
"description": "User 0 redeems remaining half of the deposited ETH",
"actions": [
{
"name": "redeem",
"args": {
"reserve": "ETH",
"amount": "-1",
"user": "0"
},
"expected": "success"
}
]
},
{
"description": "Users 0 and 1 Deposit 1000 DAI, both redeem",
"actions": [
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "1"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "1"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "1"
},
"expected": "success"
},
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "0"
},
"expected": "success"
},
{
"name": "redeem",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "1"
},
"expected": "success"
}
]
},
{
"description": "Users 0 deposits 1000 DAI, user 1 Deposit 1000 USDC and 1 ETH, borrows 100 DAI. User 1 tries to redeem all the USDC",
"actions": [
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "1"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "1"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "mint",
"args": {
"reserve": "USDC",
"amount": "1000",
"user": "1"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "USDC",
"user": "1"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "USDC",
"amount": "1000",
"user": "1"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "1",
"user": "1",
"sendValue": "1"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"user": "1",
"borrowRateMode": "stable"
},
"expected": "success"
},
{
"name": "redeem",
"args": {
"reserve": "USDC",
"amount": "-1",
"user": "1"
},
"expected": "success"
}
]
}
]
}

View File

@ -0,0 +1,133 @@
{
"title": "LendingPool: Usage as collateral",
"description": "Test cases for the setUserUseReserveAsCollateral() function.",
"stories": [
{
"description": "User 0 Deposits 1000 DAI, disables DAI as collateral",
"actions": [
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "setUseAsCollateral",
"args": {
"reserve": "DAI",
"user": "0",
"useAsCollateral": "false"
},
"expected": "success"
}
]
},
{
"description": "User 1 Deposits 2 ETH, disables ETH as collateral, borrows 400 DAI (revert expected)",
"actions": [
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "2",
"user": "1",
"sendValue": "2"
},
"expected": "success"
},
{
"name": "setUseAsCollateral",
"args": {
"reserve": "ETH",
"user": "1",
"useAsCollateral": "false"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "400",
"borrowRateMode": "variable",
"user": "1"
},
"expected": "revert",
"revertMessage": "The collateral balance is 0"
}
]
},
{
"description": "User 1 enables ETH as collateral, borrows 400 DAI",
"actions": [
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "2",
"user": "1",
"sendValue": "2"
},
"expected": "success"
},
{
"name": "setUseAsCollateral",
"args": {
"reserve": "ETH",
"user": "1",
"useAsCollateral": "true"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "400",
"borrowRateMode": "variable",
"user": "1"
},
"expected": "success"
}
]
},
{
"description": "User 1 disables ETH as collateral (revert expected)",
"actions": [
{
"name": "setUseAsCollateral",
"args": {
"reserve": "ETH",
"user": "1",
"useAsCollateral": "false"
},
"expected": "revert",
"revertMessage" : "User deposit is already being used as collateral"
}
]
}
]
}

View File

@ -0,0 +1,132 @@
{
"title": "LendingPool: Swap rate mode",
"description": "Test cases for the swapBorrowRateMode() function.",
"stories": [
{
"description": "User 0 tries to swap rate mode without any borrow in progress (revert expected)",
"actions": [
{
"name": "swapBorrowRateMode",
"args": {
"reserve": "DAI",
"user": "1"
},
"expected": "revert",
"revertMessage": "User does not have a borrow in progress on this reserve"
}
]
},
{
"description": "User 0 deposits 1000 DAI, user 1 deposits 2 ETH as collateral, borrows 100 DAI at variable rate and swaps to stable after one year",
"actions": [
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "ETH",
"amount": "2",
"user": "1",
"sendValue": "2"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "variable",
"user": "1",
"timeTravel": "365"
},
"expected": "success"
},
{
"name": "swapBorrowRateMode",
"args": {
"reserve": "DAI",
"user": "1"
},
"expected": "success"
}
]
},
{
"description": "User 1 borrows another 100 DAI, and swaps back to variable after one year, repays the loan",
"actions": [
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "stable",
"user": "1",
"timeTravel": "365"
},
"expected": "success"
},
{
"name": "swapBorrowRateMode",
"args": {
"reserve": "DAI",
"user": "1"
},
"expected": "success"
},
{
"name": "mint",
"description": "Mint 50 DAI to cover the interest",
"args": {
"reserve": "DAI",
"amount": "50",
"user": "1"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "1"
},
"expected": "success"
},
{
"name": "repay",
"args": {
"reserve": "DAI",
"amount": "-1",
"user": "1",
"onBehalfOf": "1"
},
"expected": "success"
}
]
}
]
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,172 @@
// import {
// ERC20DetailedInstance,
// LendingPoolInstance,
// LendingRateOracleInstance,
// ATokenInstance,
// LendingPoolCoreInstance,
// } from '../../utils/typechain-types/truffle-contracts';
// import {getTruffleContractInstance} from '../../utils/truffle/truffle-core-utils';
// import {ContractId} from '../../utils/types';
// import {ReserveData, UserReserveData} from './interfaces';
// import BigNumber from 'bignumber.js';
// import {configuration} from '../actions';
// import {NIL_ADDRESS, ETHEREUM_ADDRESS} from '../../utils/constants';
// export const getReserveData = async (
// poolInstance: LendingPoolInstance,
// reserve: string,
// artifacts: Truffle.Artifacts
// ): Promise<ReserveData> => {
// const data: any = await poolInstance.getReserveData(reserve);
// const rateOracle: LendingRateOracleInstance = await getTruffleContractInstance(
// artifacts,
// ContractId.LendingRateOracle
// );
// const rate = await rateOracle.getMarketBorrowRate(reserve);
// const isEthReserve = reserve === ETHEREUM_ADDRESS;
// let symbol = 'ETH';
// let decimals = new BigNumber(18);
// if (!isEthReserve) {
// const contractInstance: ERC20DetailedInstance = await getTruffleContractInstance(
// artifacts,
// ContractId.ERC20Detailed,
// reserve
// );
// symbol = await contractInstance.symbol();
// decimals = new BigNumber(await contractInstance.decimals());
// }
// return {
// totalLiquidity: new BigNumber(data.totalLiquidity),
// availableLiquidity: new BigNumber(data.availableLiquidity),
// totalBorrowsStable: new BigNumber(data.totalBorrowsStable),
// totalBorrowsVariable: new BigNumber(data.totalBorrowsVariable),
// liquidityRate: new BigNumber(data.liquidityRate),
// variableBorrowRate: new BigNumber(data.variableBorrowRate),
// stableBorrowRate: new BigNumber(data.stableBorrowRate),
// averageStableBorrowRate: new BigNumber(data.averageStableBorrowRate),
// utilizationRate: new BigNumber(data.utilizationRate),
// liquidityIndex: new BigNumber(data.liquidityIndex),
// variableBorrowIndex: new BigNumber(data.variableBorrowIndex),
// lastUpdateTimestamp: new BigNumber(data.lastUpdateTimestamp),
// address: reserve,
// aTokenAddress: data.aTokenAddress,
// symbol,
// decimals,
// marketStableRate: new BigNumber(rate),
// };
// };
// export const getUserData = async (
// poolInstance: LendingPoolInstance,
// coreInstance: LendingPoolCoreInstance,
// reserve: string,
// user: string,
// artifacts: Truffle.Artifacts
// ): Promise<UserReserveData> => {
// const {web3} = configuration;
// const [data, aTokenData] = await Promise.all([
// poolInstance.getUserReserveData(reserve, user),
// getATokenUserData(reserve, user, coreInstance),
// ]);
// const [
// userIndex,
// redirectedBalance,
// principalATokenBalance,
// redirectionAddressRedirectedBalance,
// interestRedirectionAddress,
// ] = aTokenData;
// let walletBalance;
// if (reserve === ETHEREUM_ADDRESS) {
// walletBalance = new BigNumber(await web3.eth.getBalance(user));
// } else {
// const reserveInstance: ERC20DetailedInstance = await getTruffleContractInstance(
// artifacts,
// ContractId.ERC20Detailed,
// reserve
// );
// walletBalance = new BigNumber(await reserveInstance.balanceOf(user));
// }
// const userData : any = data
// return {
// principalATokenBalance: new BigNumber(principalATokenBalance),
// interestRedirectionAddress,
// redirectionAddressRedirectedBalance: new BigNumber(redirectionAddressRedirectedBalance),
// redirectedBalance: new BigNumber(redirectedBalance),
// currentATokenUserIndex: new BigNumber(userIndex),
// currentATokenBalance: new BigNumber(userData.currentATokenBalance),
// currentBorrowBalance: new BigNumber(userData.currentBorrowBalance),
// principalBorrowBalance: new BigNumber(userData.principalBorrowBalance),
// borrowRateMode: userData.borrowRateMode.toString(),
// borrowRate: new BigNumber(userData.borrowRate),
// liquidityRate: new BigNumber(userData.liquidityRate),
// originationFee: new BigNumber(userData.originationFee),
// variableBorrowIndex: new BigNumber(userData.variableBorrowIndex),
// lastUpdateTimestamp: new BigNumber(userData.lastUpdateTimestamp),
// usageAsCollateralEnabled: userData.usageAsCollateralEnabled,
// walletBalance,
// };
// };
// export const getReserveAddressFromSymbol = async (symbol: string, artifacts: Truffle.Artifacts) => {
// if (symbol.toUpperCase() === 'ETH') {
// return ETHEREUM_ADDRESS;
// }
// const contractName: string = 'Mock' + symbol.toUpperCase();
// const contractInstance: ERC20DetailedInstance = await getTruffleContractInstance(artifacts, <
// ContractId
// >contractName);
// if (!contractInstance) {
// throw `Could not find instance for contract ${contractName}`;
// }
// return contractInstance.address;
// };
// const getATokenUserData = async (
// reserve: string,
// user: string,
// coreInstance: LendingPoolCoreInstance
// ) => {
// const aTokenAddress: string = await coreInstance.getReserveATokenAddress(reserve);
// const aTokenInstance: ATokenInstance = await getTruffleContractInstance(
// artifacts,
// ContractId.AToken,
// aTokenAddress
// );
// const [
// userIndex,
// interestRedirectionAddress,
// redirectedBalance,
// principalTokenBalance,
// ] = await Promise.all([
// aTokenInstance.getUserIndex(user),
// aTokenInstance.getInterestRedirectionAddress(user),
// aTokenInstance.getRedirectedBalance(user),
// aTokenInstance.principalBalanceOf(user),
// ]);
// const redirectionAddressRedirectedBalance =
// interestRedirectionAddress !== NIL_ADDRESS
// ? new BigNumber(await aTokenInstance.getRedirectedBalance(interestRedirectionAddress))
// : new BigNumber('0');
// return [
// userIndex.toString(),
// redirectedBalance.toString(),
// principalTokenBalance.toString(),
// redirectionAddressRedirectedBalance.toString(),
// interestRedirectionAddress,
// ];
// };

View File

@ -0,0 +1,42 @@
import BigNumber from "bignumber.js";
export interface UserReserveData {
principalATokenBalance: BigNumber
currentATokenBalance: BigNumber
currentATokenUserIndex: BigNumber
interestRedirectionAddress: string
redirectionAddressRedirectedBalance: BigNumber
redirectedBalance: BigNumber
principalBorrowBalance: BigNumber
borrowRateMode: string
borrowRate: BigNumber
liquidityRate: BigNumber
originationFee: BigNumber
variableBorrowIndex: BigNumber
lastUpdateTimestamp: BigNumber
usageAsCollateralEnabled: Boolean
walletBalance: BigNumber
currentBorrowBalance: BigNumber
[key: string]: BigNumber | string | Boolean
}
export interface ReserveData {
address: string
symbol: string
decimals: BigNumber
totalLiquidity: BigNumber
availableLiquidity: BigNumber
totalBorrowsStable: BigNumber
totalBorrowsVariable: BigNumber
averageStableBorrowRate: BigNumber
variableBorrowRate: BigNumber
stableBorrowRate: BigNumber
utilizationRate: BigNumber
liquidityIndex: BigNumber
variableBorrowIndex: BigNumber
aTokenAddress: string
marketStableRate: BigNumber
lastUpdateTimestamp: BigNumber
liquidityRate: BigNumber
[key: string]: BigNumber | string
}

View File

@ -0,0 +1,80 @@
// import {RAY, WAD, HALF_RAY, HALF_WAD, WAD_RAY_RATIO} from "../../utils/constants"
// import BigNumber from "bignumber.js"
// declare module "bignumber.js" {
// interface BigNumber {
// ray: () => BigNumber
// wad: () => BigNumber
// halfRay: () => BigNumber
// halfWad: () => BigNumber
// wadMul: (a: BigNumber) => BigNumber
// wadDiv: (a: BigNumber) => BigNumber
// rayMul: (a: BigNumber) => BigNumber
// rayDiv: (a: BigNumber) => BigNumber
// rayToWad: () => BigNumber
// wadToRay: () => BigNumber
// rayPow: (n: BigNumber) => BigNumber
// }
// }
// BigNumber.prototype.ray = (): BigNumber => {
// return new BigNumber(RAY).decimalPlaces(0)
// }
// BigNumber.prototype.wad = (): BigNumber => {
// return new BigNumber(WAD).decimalPlaces(0)
// }
// BigNumber.prototype.halfRay = (): BigNumber => {
// return new BigNumber(HALF_RAY).decimalPlaces(0, BigNumber.ROUND_DOWN)
// }
// BigNumber.prototype.halfWad = (): BigNumber => {
// return new BigNumber(HALF_WAD).decimalPlaces(0, BigNumber.ROUND_DOWN)
// }
// BigNumber.prototype.wadMul = function(b: BigNumber): BigNumber {
// return this.halfWad().plus(this.multipliedBy(b)).div(WAD).decimalPlaces(0,BigNumber.ROUND_DOWN)
// }
// BigNumber.prototype.wadDiv = function(a: BigNumber) : BigNumber {
// const halfA = a.div(2).decimalPlaces(0,BigNumber.ROUND_DOWN)
// return halfA.plus(this.multipliedBy(WAD)).div(a).decimalPlaces(0, BigNumber.ROUND_DOWN)
// }
// BigNumber.prototype.rayMul = function(a: BigNumber) : BigNumber {
// return this.halfRay().plus(this.multipliedBy(a)).div(RAY).decimalPlaces(0, BigNumber.ROUND_DOWN)
// }
// BigNumber.prototype.rayDiv = function(a: BigNumber) : BigNumber{
// const halfA = a.div(2).decimalPlaces(0,BigNumber.ROUND_DOWN)
// return halfA.plus(this.multipliedBy(RAY)).decimalPlaces(0,BigNumber.ROUND_DOWN).div(a).decimalPlaces(0,BigNumber.ROUND_DOWN)
// }
// BigNumber.prototype.rayToWad = function(): BigNumber{
// const halfRatio = new BigNumber(WAD_RAY_RATIO).div(2);
// return halfRatio.plus(this).div(WAD_RAY_RATIO).decimalPlaces(0, BigNumber.ROUND_DOWN)
// }
// BigNumber.prototype.wadToRay = function() : BigNumber {
// return this.multipliedBy(WAD_RAY_RATIO).decimalPlaces(0, BigNumber.ROUND_DOWN)
// }
// BigNumber.prototype.rayPow = function(n: BigNumber) : BigNumber {
// let z = !n.modulo(2).eq(0) ? this : new BigNumber(RAY);
// let x = new BigNumber(this)
// for (n = n.div(2); !n.eq(0); n = n.div(2)) {
// x = x.rayMul(x);
// if (!n.modulo(2).eq(0)) {
// z = z.rayMul(x);
// }
// }
// return z;
// }

View File

@ -0,0 +1,493 @@
// import {
// LendingPoolInstance,
// LendingPoolCoreInstance,
// IPriceOracleInstance,
// ATokenInstance,
// LendingPoolAddressesProviderInstance,
// MintableERC20Instance,
// } from '../utils/typechain-types/truffle-contracts';
// import {
// ContractId,
// IReserveParams,
// iATokenBase,
// iAavePoolAssets,
// iAssetsWithoutETH,
// ITestEnvWithoutInstances,
// RateMode,
// } from '../utils/types';
// import BigNumber from 'bignumber.js';
// import {
// APPROVAL_AMOUNT_LENDING_POOL_CORE,
// oneEther,
// ETHEREUM_ADDRESS,
// } from '../utils/constants';
// import {testEnvProviderWithoutInstances} from '../utils/truffle/dlp-tests-env';
// import {convertToCurrencyDecimals} from '../utils/misc-utils';
// import {getTruffleContractInstance} from '../utils/truffle/truffle-core-utils';
// const expectRevert = require('@openzeppelin/test-helpers').expectRevert;
// const {expect} = require('chai');
// const almostEqual: any = function(this: any, expected: any, actual: any): any {
// this.assert(
// expected.plus(new BigNumber(1)).eq(actual) ||
// expected.plus(new BigNumber(2)).eq(actual) ||
// actual.plus(new BigNumber(1)).eq(expected) ||
// actual.plus(new BigNumber(2)).eq(expected) ||
// expected.eq(actual),
// 'expected #{act} to be almost equal #{exp}',
// 'expected #{act} to be different from #{exp}',
// expected.toString(),
// actual.toString()
// );
// };
// require('chai').use(function(chai: any, utils: any) {
// chai.Assertion.overwriteMethod('almostEqual', function(original: any) {
// return function(this: any, value: any) {
// if (utils.flag(this, 'bignumber')) {
// var expected = new BigNumber(value);
// var actual = new BigNumber(this._obj);
// almostEqual.apply(this, [expected, actual]);
// } else {
// original.apply(this, arguments);
// }
// };
// });
// });
// contract('LendingPool liquidation - liquidator receiving aToken', async ([deployer, ...users]) => {
// let _testEnvProvider: ITestEnvWithoutInstances;
// let _lendingPoolInstance: LendingPoolInstance;
// let _lendingPoolCoreInstance: LendingPoolCoreInstance;
// let _lendingPoolAddressesProviderInstance: LendingPoolAddressesProviderInstance;
// let _priceOracleInstance: IPriceOracleInstance;
// let _aTokenInstances: iATokenBase<ATokenInstance>;
// let _tokenInstances: iAssetsWithoutETH<MintableERC20Instance>;
// let _daiAddress: string;
// let _reservesParams: iAavePoolAssets<IReserveParams>;
// let _depositorAddress: string;
// let _borrowerAddress: string;
// let _web3: Web3;
// let _initialDepositorETHBalance: string;
// before('Initializing LendingPool test variables', async () => {
// console.time('setup-test');
// _testEnvProvider = await testEnvProviderWithoutInstances(artifacts, [deployer, ...users]);
// const {
// getWeb3,
// getAllAssetsInstances,
// getFirstBorrowerAddressOnTests,
// getFirstDepositorAddressOnTests,
// getAavePoolReservesParams,
// getLendingPoolInstance,
// getLendingPoolCoreInstance,
// getPriceOracleInstance,
// getATokenInstances,
// getLendingPoolAddressesProviderInstance,
// } = _testEnvProvider;
// const instances = await Promise.all([
// getLendingPoolInstance(),
// getLendingPoolCoreInstance(),
// getPriceOracleInstance(),
// getATokenInstances(),
// getLendingPoolAddressesProviderInstance(),
// getAllAssetsInstances(),
// ]);
// _reservesParams = await getAavePoolReservesParams();
// _lendingPoolInstance = instances[0];
// _lendingPoolCoreInstance = instances[1];
// _priceOracleInstance = instances[2];
// _aTokenInstances = instances[3];
// _lendingPoolAddressesProviderInstance = instances[4];
// _tokenInstances = instances[5];
// _daiAddress = _tokenInstances.DAI.address;
// _depositorAddress = await getFirstDepositorAddressOnTests();
// _borrowerAddress = await getFirstBorrowerAddressOnTests();
// _web3 = await getWeb3();
// _initialDepositorETHBalance = await _web3.eth.getBalance(_depositorAddress);
// console.timeEnd('setup-test');
// });
// it('LIQUIDATION - Deposits ETH, borrows DAI/Check liquidation fails because health factor is above 1', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// const aEthInstance: ATokenInstance = await getTruffleContractInstance(
// artifacts,
// ContractId.AToken,
// await _lendingPoolCoreInstance.getReserveATokenAddress(ETHEREUM_ADDRESS)
// );
// //mints DAI to depositor
// await daiInstance.mint(await convertToCurrencyDecimals(daiInstance.address, '1000'), {
// from: _depositorAddress,
// });
// //approve protocol to access depositor wallet
// await daiInstance.approve(_lendingPoolCoreInstance.address, APPROVAL_AMOUNT_LENDING_POOL_CORE, {
// from: _depositorAddress,
// });
// //user 1 deposits 1000 DAI
// const amountDAItoDeposit = await convertToCurrencyDecimals(_daiAddress, '1000');
// await _lendingPoolInstance.deposit(_daiAddress, amountDAItoDeposit, '0', {
// from: _depositorAddress,
// });
// //user 2 deposits 1 ETH
// const amountETHtoDeposit = await convertToCurrencyDecimals(ETHEREUM_ADDRESS, '1');
// await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, amountETHtoDeposit, '0', {
// from: _borrowerAddress,
// value: amountETHtoDeposit,
// });
// //user 2 borrows
// const userGlobalData: any = await _lendingPoolInstance.getUserAccountData(_borrowerAddress);
// const daiPrice = await _priceOracleInstance.getAssetPrice(_daiAddress);
// const amountDAIToBorrow = await convertToCurrencyDecimals(
// _daiAddress,
// new BigNumber(userGlobalData.availableBorrowsETH)
// .div(daiPrice)
// .multipliedBy(0.95)
// .toFixed(0)
// );
// await _lendingPoolInstance.borrow(_daiAddress, amountDAIToBorrow, RateMode.Stable, '0', {
// from: _borrowerAddress,
// });
// const userGlobalDataAfter: any = await _lendingPoolInstance.getUserAccountData(
// _borrowerAddress
// );
// expect(userGlobalDataAfter.currentLiquidationThreshold).to.be.bignumber.equal(
// '80',
// 'Invalid liquidation threshold'
// );
// //user 2 tries to borrow
// await expectRevert(
// _lendingPoolInstance.liquidationCall(
// ETHEREUM_ADDRESS,
// _daiAddress,
// _borrowerAddress,
// amountDAIToBorrow,
// true
// ),
// 'Health factor is not below the threshold'
// );
// });
// it('LIQUIDATION - Drop the health factor below 1', async () => {
// const daiPrice = await _priceOracleInstance.getAssetPrice(_daiAddress);
// //halving the price of ETH - means doubling the DAIETH exchange rate
// await _priceOracleInstance.setAssetPrice(
// _daiAddress,
// new BigNumber(daiPrice).multipliedBy(1.15).toFixed(0)
// );
// const userGlobalData: any = await _lendingPoolInstance.getUserAccountData(_borrowerAddress);
// expect(userGlobalData.healthFactor).to.be.bignumber.lt(
// oneEther.toFixed(0),
// 'Invalid health factor'
// );
// });
// it('LIQUIDATION - Tries to liquidate a different currency than the loan principal', async () => {
// //user 2 tries to borrow
// await expectRevert(
// _lendingPoolInstance.liquidationCall(
// ETHEREUM_ADDRESS,
// ETHEREUM_ADDRESS,
// _borrowerAddress,
// oneEther,
// true
// ),
// 'User did not borrow the specified currency'
// );
// });
// it('LIQUIDATION - Tries to liquidate a different collateral than the borrower collateral', async () => {
// //user 2 tries to borrow
// await expectRevert(
// _lendingPoolInstance.liquidationCall(
// _daiAddress,
// _daiAddress,
// _borrowerAddress,
// oneEther,
// true
// ),
// 'Invalid collateral to liquidate'
// );
// });
// it('LIQUIDATION - Liquidates the borrow', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// //mints dai to the caller
// await daiInstance.mint(await convertToCurrencyDecimals(daiInstance.address, '1000'));
// //approve protocol to access depositor wallet
// await daiInstance.approve(_lendingPoolCoreInstance.address, APPROVAL_AMOUNT_LENDING_POOL_CORE);
// const userReserveDataBefore: any = await _lendingPoolInstance.getUserReserveData(
// _daiAddress,
// _borrowerAddress
// );
// const daiReserveDataBefore: any = await _lendingPoolInstance.getReserveData(_daiAddress);
// const ethReserveDataBefore: any = await _lendingPoolInstance.getReserveData(ETHEREUM_ADDRESS);
// const amountToLiquidate = new BigNumber(userReserveDataBefore.currentBorrowBalance)
// .div(2)
// .toFixed(0);
// await _lendingPoolInstance.liquidationCall(
// ETHEREUM_ADDRESS,
// _daiAddress,
// _borrowerAddress,
// amountToLiquidate,
// true
// );
// const userReserveDataAfter: any = await _lendingPoolInstance.getUserReserveData(
// _daiAddress,
// _borrowerAddress
// );
// const userGlobalDataAfter: any = await _lendingPoolInstance.getUserAccountData(
// _borrowerAddress
// );
// const daiReserveDataAfter: any = await _lendingPoolInstance.getReserveData(_daiAddress);
// const ethReserveDataAfter: any = await _lendingPoolInstance.getReserveData(ETHEREUM_ADDRESS);
// const feeAddress = await _lendingPoolAddressesProviderInstance.getTokenDistributor();
// const feeAddressBalance = await web3.eth.getBalance(feeAddress);
// const collateralPrice = await _priceOracleInstance.getAssetPrice(ETHEREUM_ADDRESS);
// const principalPrice = await _priceOracleInstance.getAssetPrice(_daiAddress);
// const collateralDecimals = await _lendingPoolCoreInstance.getReserveDecimals(ETHEREUM_ADDRESS);
// const principalDecimals = await _lendingPoolCoreInstance.getReserveDecimals(_daiAddress);
// const expectedCollateralLiquidated = new BigNumber(principalPrice)
// .times(new BigNumber(amountToLiquidate).times(105))
// .times(new BigNumber(10).pow(collateralDecimals))
// .div(new BigNumber(collateralPrice).times(new BigNumber(10).pow(principalDecimals)))
// .decimalPlaces(0, BigNumber.ROUND_DOWN);
// const expectedFeeLiquidated = new BigNumber(principalPrice)
// .times(new BigNumber(userReserveDataBefore.originationFee).times(105))
// .times(new BigNumber(10).pow(collateralDecimals))
// .div(new BigNumber(collateralPrice).times(new BigNumber(10).pow(principalDecimals)))
// .div(100)
// .decimalPlaces(0, BigNumber.ROUND_DOWN);
// expect(userGlobalDataAfter.healthFactor).to.be.bignumber.gt(
// oneEther.toFixed(0),
// 'Invalid health factor'
// );
// expect(userReserveDataAfter.originationFee).to.be.bignumber.eq(
// '0',
// 'Origination fee should be repaid'
// );
// expect(feeAddressBalance).to.be.bignumber.gt('0');
// expect(userReserveDataAfter.principalBorrowBalance).to.be.bignumber.almostEqual(
// new BigNumber(userReserveDataBefore.currentBorrowBalance).minus(amountToLiquidate).toFixed(0),
// 'Invalid user borrow balance after liquidation'
// );
// expect(daiReserveDataAfter.availableLiquidity).to.be.bignumber.almostEqual(
// new BigNumber(daiReserveDataBefore.availableLiquidity).plus(amountToLiquidate).toFixed(0),
// 'Invalid principal available liquidity'
// );
// expect(ethReserveDataAfter.availableLiquidity).to.be.bignumber.almostEqual(
// new BigNumber(ethReserveDataBefore.availableLiquidity)
// .minus(expectedFeeLiquidated)
// .toFixed(0),
// 'Invalid collateral available liquidity'
// );
// });
// it('User 3 deposits 1000 USDC, user 4 1 ETH, user 4 borrows - drops HF, liquidates the borrow', async () => {
// const {USDC: usdcInstance} = _tokenInstances;
// //mints USDC to depositor
// await usdcInstance.mint(await convertToCurrencyDecimals(usdcInstance.address, '1000'), {
// from: users[3],
// });
// //approve protocol to access depositor wallet
// await usdcInstance.approve(
// _lendingPoolCoreInstance.address,
// APPROVAL_AMOUNT_LENDING_POOL_CORE,
// {
// from: users[3],
// }
// );
// //user 3 deposits 1000 USDC
// const amountUSDCtoDeposit = await convertToCurrencyDecimals(usdcInstance.address, '1000');
// await _lendingPoolInstance.deposit(usdcInstance.address, amountUSDCtoDeposit, '0', {
// from: users[3],
// });
// //user 4 deposits 1 ETH
// const amountETHtoDeposit = await convertToCurrencyDecimals(ETHEREUM_ADDRESS, '1');
// await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, amountETHtoDeposit, '0', {
// from: users[4],
// value: amountETHtoDeposit,
// });
// //user 4 borrows
// const userGlobalData: any = await _lendingPoolInstance.getUserAccountData(users[4]);
// const usdcPrice = await _priceOracleInstance.getAssetPrice(usdcInstance.address);
// const amountUSDCToBorrow = await convertToCurrencyDecimals(
// usdcInstance.address,
// new BigNumber(userGlobalData.availableBorrowsETH)
// .div(usdcPrice)
// .multipliedBy(0.95)
// .toFixed(0)
// );
// await _lendingPoolInstance.borrow(
// usdcInstance.address,
// amountUSDCToBorrow,
// RateMode.Stable,
// '0',
// {
// from: users[4],
// }
// );
// //drops HF below 1
// await _priceOracleInstance.setAssetPrice(
// usdcInstance.address,
// new BigNumber(usdcPrice).multipliedBy(1.2).toFixed(0)
// );
// //mints dai to the liquidator
// await usdcInstance.mint(await convertToCurrencyDecimals(usdcInstance.address, '1000'));
// //approve protocol to access depositor wallet
// await usdcInstance.approve(_lendingPoolCoreInstance.address, APPROVAL_AMOUNT_LENDING_POOL_CORE);
// const userReserveDataBefore: any = await _lendingPoolInstance.getUserReserveData(
// usdcInstance.address,
// users[4]
// );
// const usdcReserveDataBefore: any = await _lendingPoolInstance.getReserveData(
// usdcInstance.address
// );
// const ethReserveDataBefore: any = await _lendingPoolInstance.getReserveData(ETHEREUM_ADDRESS);
// const amountToLiquidate = new BigNumber(userReserveDataBefore.currentBorrowBalance)
// .div(2)
// .toFixed(0);
// await _lendingPoolInstance.liquidationCall(
// ETHEREUM_ADDRESS,
// usdcInstance.address,
// users[4],
// amountToLiquidate,
// true
// );
// const userReserveDataAfter: any = await _lendingPoolInstance.getUserReserveData(
// usdcInstance.address,
// users[4]
// );
// const userGlobalDataAfter: any = await _lendingPoolInstance.getUserAccountData(users[4]);
// const usdcReserveDataAfter: any = await _lendingPoolInstance.getReserveData(
// usdcInstance.address
// );
// const ethReserveDataAfter: any = await _lendingPoolInstance.getReserveData(ETHEREUM_ADDRESS);
// const feeAddress = await _lendingPoolAddressesProviderInstance.getTokenDistributor();
// const feeAddressBalance = await web3.eth.getBalance(feeAddress);
// const collateralPrice = await _priceOracleInstance.getAssetPrice(ETHEREUM_ADDRESS);
// const principalPrice = await _priceOracleInstance.getAssetPrice(usdcInstance.address);
// const collateralDecimals = await _lendingPoolCoreInstance.getReserveDecimals(ETHEREUM_ADDRESS);
// const principalDecimals = await _lendingPoolCoreInstance.getReserveDecimals(
// usdcInstance.address
// );
// const expectedCollateralLiquidated = new BigNumber(principalPrice)
// .times(new BigNumber(amountToLiquidate).times(105))
// .times(new BigNumber(10).pow(collateralDecimals))
// .div(new BigNumber(collateralPrice).times(new BigNumber(10).pow(principalDecimals)))
// .decimalPlaces(0, BigNumber.ROUND_DOWN);
// const expectedFeeLiquidated = new BigNumber(principalPrice)
// .times(new BigNumber(userReserveDataBefore.originationFee).times(105))
// .times(new BigNumber(10).pow(collateralDecimals))
// .div(new BigNumber(collateralPrice).times(new BigNumber(10).pow(principalDecimals)))
// .div(100)
// .decimalPlaces(0, BigNumber.ROUND_DOWN);
// expect(userGlobalDataAfter.healthFactor).to.be.bignumber.gt(
// oneEther.toFixed(0),
// 'Invalid health factor'
// );
// expect(userReserveDataAfter.originationFee).to.be.bignumber.eq(
// '0',
// 'Origination fee should be repaid'
// );
// expect(feeAddressBalance).to.be.bignumber.gt('0');
// expect(userReserveDataAfter.principalBorrowBalance).to.be.bignumber.almostEqual(
// new BigNumber(userReserveDataBefore.currentBorrowBalance).minus(amountToLiquidate).toFixed(0),
// 'Invalid user borrow balance after liquidation'
// );
// expect(usdcReserveDataAfter.availableLiquidity).to.be.bignumber.almostEqual(
// new BigNumber(usdcReserveDataBefore.availableLiquidity).plus(amountToLiquidate).toFixed(0),
// 'Invalid principal available liquidity'
// );
// expect(ethReserveDataAfter.availableLiquidity).to.be.bignumber.almostEqual(
// new BigNumber(ethReserveDataBefore.availableLiquidity)
// .minus(expectedFeeLiquidated)
// .toFixed(0),
// 'Invalid collateral available liquidity'
// );
// });
// });

View File

@ -0,0 +1,610 @@
// import {
// LendingPoolInstance,
// LendingPoolCoreInstance,
// IPriceOracleInstance,
// ATokenInstance,
// LendingPoolAddressesProviderInstance,
// MintableERC20Instance,
// } from '../utils/typechain-types/truffle-contracts';
// import {
// ContractId,
// IReserveParams,
// iATokenBase,
// iAavePoolAssets,
// iAssetsWithoutETH,
// ITestEnvWithoutInstances,
// RateMode,
// } from '../utils/types';
// import BigNumber from 'bignumber.js';
// import {
// APPROVAL_AMOUNT_LENDING_POOL_CORE,
// oneEther,
// ETHEREUM_ADDRESS,
// } from '../utils/constants';
// import {testEnvProviderWithoutInstances} from '../utils/truffle/dlp-tests-env';
// import {convertToCurrencyDecimals} from '../utils/misc-utils';
// import {getTruffleContractInstance} from '../utils/truffle/truffle-core-utils';
// const chai = require('chai');
// chai.use(require('chai-bignumber')());
// const {expect} = chai
// const almostEqual: any = function(this: any, expected: any, actual: any): any {
// this.assert(
// expected.plus(new BigNumber(1)).eq(actual) ||
// expected.plus(new BigNumber(2)).eq(actual) ||
// actual.plus(new BigNumber(1)).eq(expected) ||
// actual.plus(new BigNumber(2)).eq(expected) ||
// expected.eq(actual),
// 'expected #{act} to be almost equal #{exp}',
// 'expected #{act} to be different from #{exp}',
// expected.toString(),
// actual.toString()
// );
// };
// chai.use(function(chai: any, utils: any) {
// chai.Assertion.overwriteMethod('almostEqual', function(original: any) {
// return function(this: any, value: any) {
// if (utils.flag(this, 'bignumber')) {
// var expected = new BigNumber(value);
// var actual = new BigNumber(this._obj);
// almostEqual.apply(this, [expected, actual]);
// } else {
// original.apply(this, arguments);
// }
// };
// });
// });
// contract(
// 'LendingPool liquidation - liquidator receiving underlying asset',
// async ([deployer, ...users]) => {
// let _testEnvProvider: ITestEnvWithoutInstances;
// let _lendingPoolInstance: LendingPoolInstance;
// let _lendingPoolCoreInstance: LendingPoolCoreInstance;
// let _priceOracleInstance: IPriceOracleInstance;
// let _aTokenInstances: iATokenBase<ATokenInstance>;
// let _tokenInstances: iAssetsWithoutETH<MintableERC20Instance>;
// let _lendingPoolAddressesProviderInstance: LendingPoolAddressesProviderInstance;
// let _daiAddress: string;
// let _reservesParams: iAavePoolAssets<IReserveParams>;
// let _depositorAddress: string;
// let _borrowerAddress: string;
// let _web3: Web3;
// let _initialDepositorETHBalance: string;
// before('Initializing LendingPool test variables', async () => {
// console.time('setup-test');
// _testEnvProvider = await testEnvProviderWithoutInstances(artifacts, [deployer, ...users]);
// const {
// getWeb3,
// getAllAssetsInstances,
// getFirstBorrowerAddressOnTests,
// getFirstDepositorAddressOnTests,
// getAavePoolReservesParams,
// getLendingPoolInstance,
// getLendingPoolCoreInstance,
// getPriceOracleInstance,
// getATokenInstances,
// getLendingPoolAddressesProviderInstance,
// } = _testEnvProvider;
// const instances = await Promise.all([
// getLendingPoolInstance(),
// getLendingPoolCoreInstance(),
// getPriceOracleInstance(),
// getATokenInstances(),
// getLendingPoolAddressesProviderInstance(),
// getAllAssetsInstances(),
// ]);
// _reservesParams = await getAavePoolReservesParams();
// _lendingPoolInstance = instances[0];
// _lendingPoolCoreInstance = instances[1];
// _priceOracleInstance = instances[2];
// _aTokenInstances = instances[3];
// _lendingPoolAddressesProviderInstance = instances[4];
// _tokenInstances = instances[5];
// _daiAddress = _tokenInstances.DAI.address;
// _depositorAddress = await getFirstDepositorAddressOnTests();
// _borrowerAddress = await getFirstBorrowerAddressOnTests();
// _web3 = await getWeb3();
// _initialDepositorETHBalance = await _web3.eth.getBalance(_depositorAddress);
// console.timeEnd('setup-test');
// });
// it('LIQUIDATION - Deposits ETH, borrows DAI', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// const aEthInstance: ATokenInstance = await getTruffleContractInstance(
// artifacts,
// ContractId.AToken,
// await _lendingPoolCoreInstance.getReserveATokenAddress(ETHEREUM_ADDRESS)
// );
// //mints DAI to depositor
// await daiInstance.mint(await convertToCurrencyDecimals(daiInstance.address, '1000'), {
// from: _depositorAddress,
// });
// //approve protocol to access depositor wallet
// await daiInstance.approve(
// _lendingPoolCoreInstance.address,
// APPROVAL_AMOUNT_LENDING_POOL_CORE,
// {
// from: _depositorAddress,
// }
// );
// //user 1 deposits 1000 DAI
// const amountDAItoDeposit = await convertToCurrencyDecimals(_daiAddress, '1000');
// await _lendingPoolInstance.deposit(_daiAddress, amountDAItoDeposit, '0', {
// from: _depositorAddress,
// });
// //user 2 deposits 1 ETH
// const amountETHtoDeposit = await convertToCurrencyDecimals(ETHEREUM_ADDRESS, '1');
// await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, amountETHtoDeposit, '0', {
// from: _borrowerAddress,
// value: amountETHtoDeposit,
// });
// //user 2 borrows
// const userGlobalData: any = await _lendingPoolInstance.getUserAccountData(_borrowerAddress);
// const daiPrice = await _priceOracleInstance.getAssetPrice(_daiAddress);
// const amountDAIToBorrow = await convertToCurrencyDecimals(
// _daiAddress,
// new BigNumber(userGlobalData.availableBorrowsETH)
// .div(daiPrice)
// .multipliedBy(0.95)
// .toFixed(0)
// );
// await _lendingPoolInstance.borrow(_daiAddress, amountDAIToBorrow, RateMode.Stable, '0', {
// from: _borrowerAddress,
// });
// const userGlobalDataAfter: any = await _lendingPoolInstance.getUserAccountData(
// _borrowerAddress
// );
// expect(userGlobalDataAfter.currentLiquidationThreshold.toString()).to.be.bignumber.equal(
// '80',
// 'Invalid liquidation threshold'
// );
// });
// it('LIQUIDATION - Drop the health factor below 1', async () => {
// const daiPrice = await _priceOracleInstance.getAssetPrice(_daiAddress);
// //halving the price of ETH - means doubling the DAIETH exchange rate
// const userGlobalDataBefore: any = await _lendingPoolInstance.getUserAccountData(
// _borrowerAddress
// );
// await _priceOracleInstance.setAssetPrice(
// _daiAddress,
// new BigNumber(daiPrice).multipliedBy(1.15).toFixed(0)
// );
// const userGlobalData: any = await _lendingPoolInstance.getUserAccountData(_borrowerAddress);
// expect(userGlobalData.healthFactor.toString()).to.be.bignumber.lt(
// oneEther.toFixed(0),
// 'Invalid health factor'
// );
// });
// it('LIQUIDATION - Liquidates the borrow', async () => {
// const {DAI: daiInstance} = _tokenInstances;
// //mints dai to the caller
// await daiInstance.mint(await convertToCurrencyDecimals(daiInstance.address, '1000'));
// //approve protocol to access depositor wallet
// await daiInstance.approve(
// _lendingPoolCoreInstance.address,
// APPROVAL_AMOUNT_LENDING_POOL_CORE
// );
// const daiPrice = await _priceOracleInstance.getAssetPrice(_daiAddress);
// const userReserveDataBefore: any = await _lendingPoolInstance.getUserReserveData(
// _daiAddress,
// _borrowerAddress
// );
// const daiReserveDataBefore: any = await _lendingPoolInstance.getReserveData(_daiAddress);
// const ethReserveDataBefore: any = await _lendingPoolInstance.getReserveData(ETHEREUM_ADDRESS);
// const amountToLiquidate = new BigNumber(userReserveDataBefore.currentBorrowBalance)
// .div(2)
// .toFixed(0);
// await _lendingPoolInstance.liquidationCall(
// ETHEREUM_ADDRESS,
// _daiAddress,
// _borrowerAddress,
// amountToLiquidate,
// false
// );
// const userReserveDataAfter: any = await _lendingPoolInstance.getUserReserveData(
// _daiAddress,
// _borrowerAddress
// );
// const daiReserveDataAfter: any = await _lendingPoolInstance.getReserveData(_daiAddress);
// const ethReserveDataAfter: any = await _lendingPoolInstance.getReserveData(ETHEREUM_ADDRESS);
// const collateralPrice = await _priceOracleInstance.getAssetPrice(ETHEREUM_ADDRESS);
// const principalPrice = await _priceOracleInstance.getAssetPrice(_daiAddress);
// const collateralDecimals = await _lendingPoolCoreInstance.getReserveDecimals(
// ETHEREUM_ADDRESS
// );
// const principalDecimals = await _lendingPoolCoreInstance.getReserveDecimals(_daiAddress);
// const expectedCollateralLiquidated = new BigNumber(principalPrice)
// .times(new BigNumber(amountToLiquidate).times(105))
// .times(new BigNumber(10).pow(collateralDecimals))
// .div(new BigNumber(collateralPrice).times(new BigNumber(10).pow(principalDecimals)))
// .div(100)
// .decimalPlaces(0, BigNumber.ROUND_DOWN);
// const expectedFeeLiquidated = new BigNumber(principalPrice)
// .times(new BigNumber(userReserveDataBefore.originationFee).times(105))
// .times(new BigNumber(10).pow(collateralDecimals))
// .div(new BigNumber(collateralPrice).times(new BigNumber(10).pow(principalDecimals)))
// .div(100)
// .decimalPlaces(0, BigNumber.ROUND_DOWN);
// const feeAddress = await _lendingPoolAddressesProviderInstance.getTokenDistributor();
// const feeAddressBalance = await web3.eth.getBalance(feeAddress);
// expect(userReserveDataAfter.originationFee.toString()).to.be.bignumber.eq(
// '0',
// 'Origination fee should be repaid'
// );
// expect(feeAddressBalance).to.be.bignumber.gt('0');
// expect(userReserveDataAfter.principalBorrowBalance.toString()).to.be.bignumber.almostEqual(
// new BigNumber(userReserveDataBefore.currentBorrowBalance)
// .minus(amountToLiquidate)
// .toFixed(0),
// 'Invalid user borrow balance after liquidation'
// );
// expect(daiReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
// new BigNumber(daiReserveDataBefore.availableLiquidity).plus(amountToLiquidate).toFixed(0),
// 'Invalid principal available liquidity'
// );
// expect(ethReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
// new BigNumber(ethReserveDataBefore.availableLiquidity)
// .minus(expectedFeeLiquidated)
// .minus(expectedCollateralLiquidated)
// .toFixed(0),
// 'Invalid collateral available liquidity'
// );
// });
// it('User 3 deposits 1000 USDC, user 4 1 ETH, user 4 borrows - drops HF, liquidates the borrow', async () => {
// const {USDC: usdcInstance} = _tokenInstances;
// //mints USDC to depositor
// await usdcInstance.mint(await convertToCurrencyDecimals(usdcInstance.address, '1000'), {
// from: users[3],
// });
// //approve protocol to access depositor wallet
// await usdcInstance.approve(
// _lendingPoolCoreInstance.address,
// APPROVAL_AMOUNT_LENDING_POOL_CORE,
// {
// from: users[3],
// }
// );
// //user 3 deposits 1000 USDC
// const amountUSDCtoDeposit = await convertToCurrencyDecimals(usdcInstance.address, '1000');
// await _lendingPoolInstance.deposit(usdcInstance.address, amountUSDCtoDeposit, '0', {
// from: users[3],
// });
// //user 4 deposits 1 ETH
// const amountETHtoDeposit = await convertToCurrencyDecimals(ETHEREUM_ADDRESS, '1');
// await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, amountETHtoDeposit, '0', {
// from: users[4],
// value: amountETHtoDeposit,
// });
// //user 4 borrows
// const userGlobalData: any = await _lendingPoolInstance.getUserAccountData(users[4]);
// const usdcPrice = await _priceOracleInstance.getAssetPrice(usdcInstance.address);
// const amountUSDCToBorrow = await convertToCurrencyDecimals(
// usdcInstance.address,
// new BigNumber(userGlobalData.availableBorrowsETH)
// .div(usdcPrice)
// .multipliedBy(0.95)
// .toFixed(0)
// );
// await _lendingPoolInstance.borrow(
// usdcInstance.address,
// amountUSDCToBorrow,
// RateMode.Stable,
// '0',
// {
// from: users[4],
// }
// );
// //drops HF below 1
// await _priceOracleInstance.setAssetPrice(
// usdcInstance.address,
// new BigNumber(usdcPrice).multipliedBy(1.2).toFixed(0)
// );
// //mints dai to the liquidator
// await usdcInstance.mint(await convertToCurrencyDecimals(usdcInstance.address, '1000'));
// //approve protocol to access depositor wallet
// await usdcInstance.approve(
// _lendingPoolCoreInstance.address,
// APPROVAL_AMOUNT_LENDING_POOL_CORE
// );
// const userReserveDataBefore: any = await _lendingPoolInstance.getUserReserveData(
// usdcInstance.address,
// users[4]
// );
// const usdcReserveDataBefore: any = await _lendingPoolInstance.getReserveData(
// usdcInstance.address
// );
// const ethReserveDataBefore: any = await _lendingPoolInstance.getReserveData(ETHEREUM_ADDRESS);
// const amountToLiquidate = new BigNumber(userReserveDataBefore.currentBorrowBalance)
// .div(2)
// .decimalPlaces(0, BigNumber.ROUND_DOWN)
// .toFixed(0);
// await _lendingPoolInstance.liquidationCall(
// ETHEREUM_ADDRESS,
// usdcInstance.address,
// users[4],
// amountToLiquidate,
// false
// );
// const userReserveDataAfter: any = await _lendingPoolInstance.getUserReserveData(
// usdcInstance.address,
// users[4]
// );
// const userGlobalDataAfter: any = await _lendingPoolInstance.getUserAccountData(users[4]);
// const usdcReserveDataAfter: any = await _lendingPoolInstance.getReserveData(
// usdcInstance.address
// );
// const ethReserveDataAfter: any = await _lendingPoolInstance.getReserveData(ETHEREUM_ADDRESS);
// const feeAddress = await _lendingPoolAddressesProviderInstance.getTokenDistributor();
// const feeAddressBalance = await web3.eth.getBalance(feeAddress);
// const collateralPrice = await _priceOracleInstance.getAssetPrice(ETHEREUM_ADDRESS);
// const principalPrice = await _priceOracleInstance.getAssetPrice(usdcInstance.address);
// const collateralDecimals = await _lendingPoolCoreInstance.getReserveDecimals(
// ETHEREUM_ADDRESS
// );
// const principalDecimals = await _lendingPoolCoreInstance.getReserveDecimals(
// usdcInstance.address
// );
// const expectedCollateralLiquidated = new BigNumber(principalPrice)
// .times(new BigNumber(amountToLiquidate).times(105))
// .times(new BigNumber(10).pow(collateralDecimals))
// .div(new BigNumber(collateralPrice).times(new BigNumber(10).pow(principalDecimals)))
// .div(100)
// .decimalPlaces(0, BigNumber.ROUND_DOWN);
// const expectedFeeLiquidated = new BigNumber(principalPrice)
// .times(new BigNumber(userReserveDataBefore.originationFee).times(105))
// .times(new BigNumber(10).pow(collateralDecimals))
// .div(new BigNumber(collateralPrice).times(new BigNumber(10).pow(principalDecimals)))
// .div(100)
// .decimalPlaces(0, BigNumber.ROUND_DOWN);
// expect(userGlobalDataAfter.healthFactor.toString()).to.be.bignumber.gt(
// oneEther.toFixed(0),
// 'Invalid health factor'
// );
// expect(userReserveDataAfter.originationFee.toString()).to.be.bignumber.eq(
// '0',
// 'Origination fee should be repaid'
// );
// expect(feeAddressBalance.toString()).to.be.bignumber.gt('0');
// expect(userReserveDataAfter.principalBorrowBalance.toString()).to.be.bignumber.almostEqual(
// new BigNumber(userReserveDataBefore.currentBorrowBalance.toString())
// .minus(amountToLiquidate)
// .toFixed(0),
// 'Invalid user borrow balance after liquidation'
// );
// expect(usdcReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
// new BigNumber(usdcReserveDataBefore.availableLiquidity).plus(amountToLiquidate).toFixed(0),
// 'Invalid principal available liquidity'
// );
// expect(ethReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
// new BigNumber(ethReserveDataBefore.availableLiquidity)
// .minus(expectedFeeLiquidated)
// .minus(expectedCollateralLiquidated)
// .toFixed(0),
// 'Invalid collateral available liquidity'
// );
// });
// it('User 4 deposits 1000 LEND - drops HF, liquidates the LEND, which results on a lower amount being liquidated', async () => {
// const {USDC: usdcInstance, LEND: lendInstance} = _tokenInstances;
// //mints USDC to depositor
// await lendInstance.mint(await convertToCurrencyDecimals(lendInstance.address, '1000'), {
// from: users[4],
// });
// //approve protocol to access depositor wallet
// await lendInstance.approve(
// _lendingPoolCoreInstance.address,
// APPROVAL_AMOUNT_LENDING_POOL_CORE,
// {
// from: users[4],
// }
// );
// //user 4 deposits 100 USDC
// const amountLENDtoDeposit = await convertToCurrencyDecimals(lendInstance.address, '1000');
// await _lendingPoolInstance.deposit(lendInstance.address, amountLENDtoDeposit, '0', {
// from: users[4],
// });
// const usdcPrice = await _priceOracleInstance.getAssetPrice(usdcInstance.address);
// //drops HF below 1
// await _priceOracleInstance.setAssetPrice(
// usdcInstance.address,
// new BigNumber(usdcPrice).multipliedBy(1.10).toFixed(0)
// );
// //mints usdc to the liquidator
// await usdcInstance.mint(await convertToCurrencyDecimals(usdcInstance.address, '1000'));
// //approve protocol to access depositor wallet
// await usdcInstance.approve(
// _lendingPoolCoreInstance.address,
// APPROVAL_AMOUNT_LENDING_POOL_CORE
// );
// const userReserveDataBefore: any = await _lendingPoolInstance.getUserReserveData(
// usdcInstance.address,
// users[4]
// );
// const usdcReserveDataBefore: any = await _lendingPoolInstance.getReserveData(
// usdcInstance.address
// );
// const lendReserveDataBefore: any = await _lendingPoolInstance.getReserveData(
// lendInstance.address
// );
// const amountToLiquidate = new BigNumber(userReserveDataBefore.currentBorrowBalance)
// .div(2)
// .decimalPlaces(0, BigNumber.ROUND_DOWN)
// .toFixed(0);
// const collateralPrice = await _priceOracleInstance.getAssetPrice(lendInstance.address);
// const principalPrice = await _priceOracleInstance.getAssetPrice(usdcInstance.address);
// await _lendingPoolInstance.liquidationCall(
// lendInstance.address,
// usdcInstance.address,
// users[4],
// amountToLiquidate,
// false
// );
// const userReserveDataAfter: any = await _lendingPoolInstance.getUserReserveData(
// usdcInstance.address,
// users[4]
// );
// const userGlobalDataAfter: any = await _lendingPoolInstance.getUserAccountData(users[4]);
// const usdcReserveDataAfter: any = await _lendingPoolInstance.getReserveData(
// usdcInstance.address
// );
// const lendReserveDataAfter: any = await _lendingPoolInstance.getReserveData(
// lendInstance.address
// );
// const collateralDecimals = await _lendingPoolCoreInstance.getReserveDecimals(
// lendInstance.address
// );
// const principalDecimals = await _lendingPoolCoreInstance.getReserveDecimals(
// usdcInstance.address
// );
// const expectedCollateralLiquidated = oneEther.multipliedBy('1000');
// const liquidationBonus = await _lendingPoolCoreInstance.getReserveLiquidationBonus(
// lendInstance.address
// );
// const expectedPrincipal = new BigNumber(collateralPrice)
// .times(expectedCollateralLiquidated)
// .times(new BigNumber(10).pow(principalDecimals))
// .div(new BigNumber(principalPrice).times(new BigNumber(10).pow(collateralDecimals)))
// .times(100)
// .div(liquidationBonus.toString())
// .decimalPlaces(0, BigNumber.ROUND_DOWN);
// expect(userGlobalDataAfter.healthFactor.toString()).to.be.bignumber.gt(
// oneEther.toFixed(0),
// 'Invalid health factor'
// );
// expect(userReserveDataAfter.originationFee.toString()).to.be.bignumber.eq(
// '0',
// 'Origination fee should be repaid'
// );
// expect(userReserveDataAfter.principalBorrowBalance.toString()).to.be.bignumber.almostEqual(
// new BigNumber(userReserveDataBefore.currentBorrowBalance)
// .minus(expectedPrincipal)
// .toFixed(0),
// 'Invalid user borrow balance after liquidation'
// );
// expect(usdcReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
// new BigNumber(usdcReserveDataBefore.availableLiquidity).plus(expectedPrincipal).toFixed(0),
// 'Invalid principal available liquidity'
// );
// expect(lendReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
// new BigNumber(lendReserveDataBefore.availableLiquidity)
// .minus(expectedCollateralLiquidated)
// .toFixed(0),
// 'Invalid collateral available liquidity'
// );
// });
// }
// );

241
test/pool-modifiers.spec.ts Normal file
View File

@ -0,0 +1,241 @@
// import {iATokenBase, iAssetsWithoutETH, ITestEnvWithoutInstances, RateMode} from '../utils/types';
// import {
// LendingPoolConfiguratorInstance,
// LendingPoolInstance,
// ATokenInstance,
// LendingPoolCoreInstance,
// MintableERC20Instance,
// } from '../utils/typechain-types/truffle-contracts';
// import {testEnvProviderWithoutInstances} from '../utils/truffle/dlp-tests-env';
// import {oneEther, ETHEREUM_ADDRESS} from '../utils/constants';
// import {convertToCurrencyDecimals} from '../utils/misc-utils';
// const expectRevert = require('@openzeppelin/test-helpers').expectRevert;
// contract('LendingPool: Modifiers', async ([deployer, ...users]) => {
// let _testEnvProvider: ITestEnvWithoutInstances;
// let _lendingPoolConfiguratorInstance: LendingPoolConfiguratorInstance;
// let _lendingPoolInstance: LendingPoolInstance;
// let _lendingPoolCoreInstance: LendingPoolCoreInstance;
// let _aTokenInstances: iATokenBase<ATokenInstance>;
// let _tokenInstances: iAssetsWithoutETH<MintableERC20Instance>;
// before('Initializing LendingPool test variables', async () => {
// console.time('setup-test');
// _testEnvProvider = await testEnvProviderWithoutInstances(artifacts, [deployer, ...users]);
// const {
// getAllAssetsInstances,
// getLendingPoolInstance,
// getLendingPoolCoreInstance,
// getLendingPoolConfiguratorInstance,
// getATokenInstances,
// } = _testEnvProvider;
// const instances = await Promise.all([
// getLendingPoolInstance(),
// getLendingPoolCoreInstance(),
// getLendingPoolConfiguratorInstance(),
// getATokenInstances(),
// getAllAssetsInstances(),
// ]);
// _lendingPoolInstance = instances[0];
// _lendingPoolCoreInstance = instances[1];
// _lendingPoolConfiguratorInstance = instances[2];
// _aTokenInstances = instances[3];
// _tokenInstances = instances[4];
// console.timeEnd('setup-test');
// });
// it('Tries to deposit in an inactive reserve', async () => {
// //using the deployer address as a fake reserve address
// await expectRevert(
// _lendingPoolInstance.deposit(deployer, '1', '0'),
// 'Action requires an active reserve'
// );
// });
// it('Tries to invoke redeemUnderlying on an reserve, from a non-aToken address', async () => {
// await expectRevert(
// _lendingPoolInstance.redeemUnderlying(ETHEREUM_ADDRESS, deployer, '1', '0'),
// 'The caller of this function can only be the aToken contract of this reserve'
// );
// });
// it('Tries to borrow from an inactive reserve', async () => {
// //using the deployer address as a fake reserve address
// await expectRevert(
// _lendingPoolInstance.borrow(deployer, '1', '0', RateMode.Stable),
// 'Action requires an active reserve'
// );
// });
// it('Tries to repay in an inactive reserve', async () => {
// //using the deployer address as a fake reserve address
// await expectRevert(
// _lendingPoolInstance.repay(deployer, '1', deployer),
// 'Action requires an active reserve'
// );
// });
// it('Tries to swapBorrowRateMode on an inactive reserve', async () => {
// //using the deployer address as a fake reserve address
// await expectRevert(
// _lendingPoolInstance.swapBorrowRateMode(deployer),
// 'Action requires an active reserve'
// );
// });
// it('Tries to rebalanceStableBorrowRate on an inactive reserve', async () => {
// //using the deployer address as a fake reserve address
// await expectRevert(
// _lendingPoolInstance.rebalanceStableBorrowRate(deployer, deployer),
// 'Action requires an active reserve'
// );
// });
// it('Tries to setUserUseReserveAsCollateral on an inactive reserve', async () => {
// //using the deployer address as a fake reserve address
// await expectRevert(
// _lendingPoolInstance.setUserUseReserveAsCollateral(deployer, true),
// 'Action requires an active reserve'
// );
// });
// it('Tries to invoke liquidationCall on an inactive reserve', async () => {
// //using the deployer address as a fake reserve address
// await expectRevert(
// _lendingPoolInstance.liquidationCall(ETHEREUM_ADDRESS, deployer, deployer, '1', false),
// 'Action requires an active reserve'
// );
// });
// it('Tries to invoke liquidationCall on an inactive collateral', async () => {
// //using the deployer address as a fake reserve address
// await expectRevert(
// _lendingPoolInstance.liquidationCall(deployer, ETHEREUM_ADDRESS, deployer, '1', false),
// 'Action requires an active reserve'
// );
// });
// it('Freezes the ETH reserve', async () => {
// await _lendingPoolConfiguratorInstance.freezeReserve(ETHEREUM_ADDRESS);
// });
// it('tries to deposit in a freezed reserve', async () => {
// await expectRevert(
// _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, '1', '0'),
// 'Action requires an unfreezed reserve'
// );
// });
// it('tries to borrow from a freezed reserve', async () => {
// await expectRevert(
// _lendingPoolInstance.borrow(ETHEREUM_ADDRESS, '1', '0', '0'),
// 'Action requires an unfreezed reserve'
// );
// });
// it('tries to swap interest rate mode in a freezed reserve', async () => {
// await expectRevert(
// _lendingPoolInstance.swapBorrowRateMode(ETHEREUM_ADDRESS),
// 'Action requires an unfreezed reserve'
// );
// });
// it('tries to disable as collateral a freezed reserve', async () => {
// await expectRevert(
// _lendingPoolInstance.setUserUseReserveAsCollateral(ETHEREUM_ADDRESS, false),
// 'Action requires an unfreezed reserve'
// );
// });
// it('unfreezes the reserve, user deposits 1 ETH, freezes the reserve, check that the user can redeem', async () => {
// const {aETH} = _aTokenInstances;
// //unfreezes the reserve
// await _lendingPoolConfiguratorInstance.unfreezeReserve(ETHEREUM_ADDRESS);
// //deposit 1 ETH
// await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, oneEther, '0', {
// value: oneEther.toString(),
// });
// //freezes the reserve
// await _lendingPoolConfiguratorInstance.freezeReserve(ETHEREUM_ADDRESS);
// const balance = await aETH.balanceOf(deployer);
// await aETH.redeem(balance);
// });
// it('unfreezes the reserve, user 0 deposits 100 DAI, user 1 deposits 1 ETH and borrows 50 DAI, freezes the reserve, checks that the user 1 can repay', async () => {
// const {aETH, aDAI} = _aTokenInstances;
// const {DAI} = _tokenInstances;
// //unfreezes the reserve
// await _lendingPoolConfiguratorInstance.unfreezeReserve(ETHEREUM_ADDRESS);
// const amountDAI = await convertToCurrencyDecimals(DAI.address, '100');
// //user 0 deposits 100 DAI
// await DAI.mint(amountDAI, {from: users[0]});
// await DAI.approve(_lendingPoolCoreInstance.address, amountDAI, {from: users[0]});
// await _lendingPoolInstance.deposit(DAI.address, amountDAI, '0', {from: users[0]});
// //user 1 deposits 1 ETH
// await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, oneEther, '0', {
// from: users[1],
// value: oneEther.toString(),
// });
// const amountDAIToBorrow = await convertToCurrencyDecimals(DAI.address, '10');
// //user 1 borrows 10 DAI
// await _lendingPoolInstance.borrow(DAI.address, amountDAIToBorrow, RateMode.Stable, '0', {
// from: users[1],
// });
// //freezes the reserve
// await _lendingPoolConfiguratorInstance.freezeReserve(ETHEREUM_ADDRESS);
// //user 1 repays 1 DAI
// await DAI.approve(_lendingPoolCoreInstance.address, amountDAIToBorrow, {from: users[1]});
// await _lendingPoolInstance.repay(DAI.address, oneEther, users[1], {from: users[1]});
// });
// it('Check that liquidationCall can be executed on a freezed reserve', async () => {
// const {aETH, aDAI} = _aTokenInstances;
// const {DAI} = _tokenInstances;
// //user 2 tries to liquidate
// await expectRevert(
// _lendingPoolInstance.liquidationCall(
// ETHEREUM_ADDRESS,
// DAI.address,
// users[1],
// oneEther,
// true,
// {from: users[2]}
// ),
// 'Health factor is not below the threshold'
// );
// });
// it('Check that rebalanceStableBorrowRate can be executed on a freezed reserve', async () => {
// const {aETH, aDAI} = _aTokenInstances;
// const {DAI} = _tokenInstances;
// //user 2 tries to liquidate
// await expectRevert(
// _lendingPoolInstance.rebalanceStableBorrowRate(DAI.address, users[1]),
// 'Interest rate rebalance conditions were not met'
// );
// });
// });

165
test/rate-strategy.spec.ts Normal file
View File

@ -0,0 +1,165 @@
// import {
// IReserveParams,
// iAavePoolAssets,
// iAssetsWithoutETH,
// ITestEnvWithoutInstances,
// } from "../utils/types"
// import {
// LendingPoolAddressesProviderInstance,
// DefaultReserveInterestRateStrategyInstance,
// MintableERC20Instance,
// } from "../utils/typechain-types/truffle-contracts"
// import { testEnvProviderWithoutInstances} from "../utils/truffle/dlp-tests-env"
// import {RAY} from "../utils/constants"
// import BigNumber from "bignumber.js"
// const {expect} = require("chai")
// contract("Interest rate strategy", async ([deployer, ...users]) => {
// let _testEnvProvider: ITestEnvWithoutInstances
// let _strategyInstance: DefaultReserveInterestRateStrategyInstance
// let _tokenInstances: iAssetsWithoutETH<MintableERC20Instance>
// let _addressesProviderInstance: LendingPoolAddressesProviderInstance
// let _reservesParams: iAavePoolAssets<IReserveParams>
// before("Initializing test variables", async () => {
// console.time('setup-test');
// _testEnvProvider = await testEnvProviderWithoutInstances(
// artifacts,
// [deployer, ...users],
// )
// const {
// getAllAssetsInstances,
// getLendingPoolAddressesProviderInstance,
// getAavePoolReservesParams,
// } = _testEnvProvider
// const instances = await Promise.all([
// getAllAssetsInstances(),
// getLendingPoolAddressesProviderInstance()
// ])
// _tokenInstances = instances[0]
// _addressesProviderInstance = instances[1]
// _reservesParams = await getAavePoolReservesParams()
// console.timeEnd('setup-test');
// })
// it("Deploys a new instance of a DefaultReserveInterestRateStrategy contract", async () => {
// const {DAI: daiInstance} = _tokenInstances
// const {DAI: daiConfiguration} = _reservesParams
// const contract: any = await artifacts.require("DefaultReserveInterestRateStrategy")
// const mathLibrary = await artifacts.require("WadRayMath")
// const mathLibraryInstance = await mathLibrary.new()
// await contract.link("WadRayMath", mathLibraryInstance.address)
// _strategyInstance = await contract.new(
// daiInstance.address,
// _addressesProviderInstance.address,
// daiConfiguration.baseVariableBorrowRate,
// daiConfiguration.variableRateSlope1,
// daiConfiguration.variableRateSlope2,
// daiConfiguration.stableRateSlope1,
// daiConfiguration.stableRateSlope2,
// )
// })
// it("Checks rates at 0% utilization rate", async () => {
// const {DAI: daiInstance} = _tokenInstances
// const {DAI: daiConfiguration} = _reservesParams
// const data: any = await _strategyInstance.calculateInterestRates(
// daiInstance.address,
// "1000000000000000000",
// "0",
// "0",
// "0",
// )
// expect(data.currentLiquidityRate.toString()).to.be.equal("0", "Invalid liquidity rate")
// expect(data.currentStableBorrowRate.toString()).to.be.equal(
// new BigNumber(0.039).times(RAY).toFixed(0),
// "Invalid stable rate",
// )
// expect(data.currentVariableBorrowRate.toString()).to.be.equal(
// daiConfiguration.baseVariableBorrowRate,
// "Invalid variable rate",
// )
// })
// it("Checks rates at 80% utilization rate", async () => {
// const {DAI: daiInstance} = _tokenInstances
// const {DAI: daiConfiguration} = _reservesParams
// const data: any = await _strategyInstance.calculateInterestRates(
// daiInstance.address,
// "200000000000000000",
// "0",
// "800000000000000000",
// "0",
// )
// const expectedVariableRate = new BigNumber(daiConfiguration.baseVariableBorrowRate)
// .plus(daiConfiguration.variableRateSlope1)
// expect(data.currentLiquidityRate.toString()).to.be.equal(
// expectedVariableRate.times(0.8).toFixed(0),
// "Invalid liquidity rate",
// )
// expect(data.currentVariableBorrowRate.toString()).to.be.equal(
// new BigNumber(daiConfiguration.baseVariableBorrowRate)
// .plus(daiConfiguration.variableRateSlope1)
// .toFixed(0),
// "Invalid variable rate",
// )
// expect(data.currentStableBorrowRate.toString()).to.be.equal(
// new BigNumber(0.039)
// .times(RAY)
// .plus(daiConfiguration.stableRateSlope1)
// .toFixed(0),
// "Invalid stable rate",
// )
// })
// it("Checks rates at 100% utilization rate", async () => {
// const {DAI: daiInstance} = _tokenInstances
// const {DAI: daiConfiguration} = _reservesParams
// const data: any = await _strategyInstance.calculateInterestRates(
// daiInstance.address,
// "0",
// "0",
// "1000000000000000000",
// "0",
// )
// const expectedVariableRate = new BigNumber(daiConfiguration.baseVariableBorrowRate)
// .plus(daiConfiguration.variableRateSlope1)
// .plus(daiConfiguration.variableRateSlope2)
// .toFixed(0)
// expect(data.currentLiquidityRate.toString()).to.be.equal(
// expectedVariableRate,
// "Invalid liquidity rate",
// )
// expect(data.currentVariableBorrowRate.toString()).to.be.equal(
// expectedVariableRate,
// "Invalid variable rate",
// )
// expect(data.currentStableBorrowRate.toString()).to.be.equal(
// new BigNumber(0.039)
// .times(RAY)
// .plus(daiConfiguration.stableRateSlope1)
// .plus(daiConfiguration.stableRateSlope2)
// .toFixed(0),
// "Invalid stable rate",
// )
// })
// })

56
test/scenario.spec.ts Normal file
View File

@ -0,0 +1,56 @@
// import {ITestEnvWithoutInstances} from '../utils/types';
// import {testEnvProviderWithoutInstances} from '../utils/truffle/dlp-tests-env';
// import {configuration as actionsConfiguration, deposit} from './actions';
// import {configuration as calculationsConfiguration} from './utils/calculations';
// import {executeStory} from './engine/scenario-engine';
// import fs from 'fs';
// import BigNumber from 'bignumber.js';
// import {ETHEREUM_ADDRESS} from '../utils/constants';
// BigNumber.config({DECIMAL_PLACES: 0, ROUNDING_MODE: BigNumber.ROUND_DOWN});
// const scenarioFolder = './test/scenarios/';
// fs.readdirSync(scenarioFolder).forEach(file => {
// // if (file !== "interest-redirection-negatives.json" &&
// // file !== "interest-redirection.json" ) return
// const scenario = require(`./scenarios/${file}`);
// contract(scenario.title, async ([deployer, ...users]) => {
// let _testEnvProvider: ITestEnvWithoutInstances;
// before('Initializing configuration', async () => {
// console.time('setup-test');
// _testEnvProvider = await testEnvProviderWithoutInstances(artifacts, [deployer, ...users]);
// const {
// getWeb3,
// getAavePoolReservesParams,
// getLendingPoolInstance,
// getLendingPoolCoreInstance,
// } = _testEnvProvider;
// const instances = await Promise.all([getLendingPoolInstance(), getLendingPoolCoreInstance()]);
// actionsConfiguration.lendingPoolInstance = instances[0];
// actionsConfiguration.lendingPoolCoreInstance = instances[1];
// actionsConfiguration.ethereumAddress = ETHEREUM_ADDRESS;
// actionsConfiguration.artifacts = artifacts;
// actionsConfiguration.web3 = await getWeb3();
// actionsConfiguration.skipIntegrityCheck = false; //set this to true to execute solidity-coverage
// calculationsConfiguration.reservesParams = await getAavePoolReservesParams();
// calculationsConfiguration.web3 = actionsConfiguration.web3;
// calculationsConfiguration.ethereumAddress = actionsConfiguration.ethereumAddress;
// console.time('setup-test');
// });
// for (const story of scenario.stories) {
// it(story.description, async () => {
// await executeStory(story, users);
// });
// }
// });
// });

View File

@ -0,0 +1,199 @@
// import {
// LendingPoolInstance,
// LendingPoolCoreInstance,
// MintableERC20Instance,
// ATokenInstance,
// } from "../utils/typechain-types/truffle-contracts"
// import {
// iATokenBase,
// iAssetsWithoutETH,
// ITestEnvWithoutInstances,
// RateMode,
// } from "../utils/types"
// import {
// APPROVAL_AMOUNT_LENDING_POOL_CORE,
// ETHEREUM_ADDRESS,
// } from "../utils/constants"
// import { testEnvProviderWithoutInstances} from "../utils/truffle/dlp-tests-env"
// import {convertToCurrencyDecimals} from "../utils/misc-utils"
// const expectRevert = require("@openzeppelin/test-helpers").expectRevert
// contract("LendingPool - stable rate economy tests", async ([deployer, ...users]) => {
// let _testEnvProvider: ITestEnvWithoutInstances
// let _lendingPoolInstance: LendingPoolInstance
// let _lendingPoolCoreInstance: LendingPoolCoreInstance
// let _aTokenInstances: iATokenBase<ATokenInstance>
// let _tokenInstances: iAssetsWithoutETH<MintableERC20Instance>
// let _daiAddress: string
// let _depositorAddress: string
// let _borrowerAddress: string
// let _web3: Web3
// before("Initializing LendingPool test variables", async () => {
// console.time('setup-test');
// _testEnvProvider = await testEnvProviderWithoutInstances(
// artifacts,
// [deployer, ...users]
// )
// const {
// getWeb3,
// getAllAssetsInstances,
// getFirstBorrowerAddressOnTests,
// getFirstDepositorAddressOnTests,
// getLendingPoolInstance,
// getLendingPoolCoreInstance,
// getATokenInstances
// } = _testEnvProvider
// const instances = await Promise.all([
// getLendingPoolInstance(),
// getLendingPoolCoreInstance(),
// getATokenInstances(),
// getAllAssetsInstances()
// ])
// _lendingPoolInstance = instances[0]
// _lendingPoolCoreInstance = instances[1]
// _aTokenInstances = instances[2]
// _tokenInstances = instances[3]
// _daiAddress = _tokenInstances.DAI.address
// _depositorAddress = await getFirstDepositorAddressOnTests()
// _borrowerAddress = await getFirstBorrowerAddressOnTests()
// _web3 = await getWeb3()
// console.timeEnd('setup-test');
// })
// it("BORROW - Test user cannot borrow using the same currency as collateral", async () => {
// const {aDAI: aDaiInstance} = _aTokenInstances
// const {DAI: daiInstance} = _tokenInstances
// //mints DAI to depositor
// await daiInstance.mint(await convertToCurrencyDecimals(daiInstance.address, "1000"), {
// from: _depositorAddress,
// })
// //mints DAI to borrower
// await daiInstance.mint(await convertToCurrencyDecimals(daiInstance.address, "1000"), {
// from: _borrowerAddress,
// })
// //approve protocol to access depositor wallet
// await daiInstance.approve(_lendingPoolCoreInstance.address, APPROVAL_AMOUNT_LENDING_POOL_CORE, {
// from: _depositorAddress,
// })
// //approve protocol to access borrower wallet
// await daiInstance.approve(_lendingPoolCoreInstance.address, APPROVAL_AMOUNT_LENDING_POOL_CORE, {
// from: _borrowerAddress,
// })
// const amountDAItoDeposit = await convertToCurrencyDecimals(_daiAddress, "1000")
// //user 1 deposits 1000 DAI
// const txResult = await _lendingPoolInstance.deposit(_daiAddress, amountDAItoDeposit, "0", {
// from: _depositorAddress,
// })
// //user 2 deposits 1000 DAI, tries to borrow. Needs to be reverted as you can't borrow at a stable rate with the same collateral as the currency.
// const amountDAIToDepositBorrower = await convertToCurrencyDecimals(_daiAddress, "1000")
// await _lendingPoolInstance.deposit(_daiAddress, amountDAIToDepositBorrower, "0", {
// from: _borrowerAddress,
// })
// const data: any = await _lendingPoolInstance.getReserveData(_daiAddress)
// //user 2 tries to borrow
// const amountDAIToBorrow = await convertToCurrencyDecimals(_daiAddress, "250")
// //user 2 tries to borrow
// await expectRevert(
// _lendingPoolInstance.borrow(_daiAddress, amountDAIToBorrow, RateMode.Stable, "0", {
// from: _borrowerAddress,
// }),
// "User cannot borrow the selected amount with a stable rate",
// )
// })
// it("BORROW - Test user cannot borrow more than 25% of the liquidity available", async () => {
// const {aDAI: aDaiInstance} = _aTokenInstances
// const {DAI: daiInstance} = _tokenInstances
// //redeem the DAI previously deposited
// const amountADAIToRedeem = await convertToCurrencyDecimals(aDaiInstance.address, "1000")
// await aDaiInstance.redeem(amountADAIToRedeem, {
// from: _borrowerAddress,
// })
// //user 2 deposits 5 ETH tries to borrow. needs to be reverted as you can't borrow more than 25% of the available reserve (250 DAI)
// const amountETHToDeposit = await convertToCurrencyDecimals(ETHEREUM_ADDRESS, "5")
// await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, amountETHToDeposit, "0", {
// from: _borrowerAddress,
// value: amountETHToDeposit,
// })
// const data: any = await _lendingPoolInstance.getReserveData(_daiAddress)
// const amountDAIToBorrow = await convertToCurrencyDecimals(_daiAddress, "500")
// //user 2 tries to borrow
// await expectRevert(
// _lendingPoolInstance.borrow(_daiAddress, amountDAIToBorrow, RateMode.Stable, "0", {
// from: _borrowerAddress,
// }),
// "User is trying to borrow too much liquidity at a stable rate",
// )
// })
// it("BORROW - Test user can still borrow a currency that he previously deposited as a collateral but he transferred/redeemed", async () => {
// const {aDAI: aDaiInstance} = _aTokenInstances
// const {DAI: daiInstance} = _tokenInstances
// const user = users[2]
// //user deposits 1000 DAI
// await daiInstance.mint(await convertToCurrencyDecimals(daiInstance.address, "1000"), {
// from: user,
// })
// await daiInstance.approve(_lendingPoolCoreInstance.address, APPROVAL_AMOUNT_LENDING_POOL_CORE, {
// from: user,
// })
// const amountDAIToDeposit = await convertToCurrencyDecimals(daiInstance.address, "1000")
// await _lendingPoolInstance.deposit(daiInstance.address, amountDAIToDeposit, "0", {
// from: user,
// })
// //user deposits 5 ETH as collateral
// const amountETHToDeposit = await convertToCurrencyDecimals(ETHEREUM_ADDRESS, "5")
// await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, amountETHToDeposit, "0", {
// from: user,
// value: amountETHToDeposit,
// })
// //user transfers to another address all the overlying aDAI
// const aDAIBalance = await aDaiInstance.balanceOf(user)
// await aDaiInstance.transfer(users[3], aDAIBalance, {
// from: user,
// })
// //check the underlying balance is 0
// const userData: any = await _lendingPoolInstance.getUserReserveData(daiInstance.address, user)
// expect(userData.currentATokenBalance.toString()).to.be.equal("0")
// //user tries to borrow the DAI at a stable rate using the ETH as collateral
// const amountDAIToBorrow = await convertToCurrencyDecimals(_daiAddress, "100")
// //user tries to borrow. No revert expected
// await _lendingPoolInstance.borrow(_daiAddress, amountDAIToBorrow, RateMode.Stable, "0", {
// from: user,
// })
// })
// })

View File

@ -0,0 +1,277 @@
// import {
// ITestEnv,
// ContractsInstancesOrigin,
// iBasicDistributionParams,
// iTokenBalances,
// iDistributionParams,
// } from '../utils/types';
// import {
// TokenDistributorInstance,
// MintableERC20Instance,
// } from '../utils/typechain-types/truffle-contracts';
// import {testEnvProvider} from '../utils/truffle/dlp-tests-env';
// import {
// TOKEN_DISTRIBUTOR_PERCENTAGE_BASE,
// ETHEREUM_ADDRESS,
// ONE_ADDRESS,
// NIL_ADDRESS,
// } from '../utils/constants';
// import BigNumber from 'bignumber.js';
// import {expect} from 'chai';
// const testAndExecMintAndTransferTokens = async (
// tokenInstance: MintableERC20Instance,
// amount: string,
// minter: string,
// receiver: string
// ) => {
// const initialMinterBalance = new BigNumber(await tokenInstance.balanceOf(minter));
// const initialReceiverBalance = new BigNumber(await tokenInstance.balanceOf(receiver));
// await tokenInstance.mint(amount, {
// from: minter,
// });
// expect(initialMinterBalance.plus(amount).toFixed()).to.be.equal(
// new BigNumber(await tokenInstance.balanceOf(minter)).toFixed()
// );
// await tokenInstance.transfer(receiver, amount, {from: minter});
// expect(initialReceiverBalance.plus(amount).toFixed()).to.be.equal(
// new BigNumber(await tokenInstance.balanceOf(receiver)).toFixed()
// );
// };
// const testAndExecEthTransfer = async (
// amount: string,
// sender: string,
// receiver: string,
// web3: Web3
// ) => {
// const initialReceiverEthBalance = await web3.eth.getBalance(receiver);
// await web3.eth.sendTransaction({
// from: sender,
// to: receiver,
// value: amount,
// });
// expect(new BigNumber(initialReceiverEthBalance).plus(amount).toFixed()).to.be.equal(
// await web3.eth.getBalance(receiver)
// );
// };
// const testAndExecDistributeToken = async (
// tokenInstances: MintableERC20Instance[],
// tokenToBurnInstance: MintableERC20Instance,
// tokenDistributorInstance: TokenDistributorInstance,
// distributionParams: iBasicDistributionParams[]
// ) => {
// const tokenBalancesBefore: iTokenBalances[] = [];
// for (const [index, tokenInstance] of tokenInstances.entries()) {
// const {receivers} = distributionParams[index];
// const tokenBalancesReceiversBefore: string[][] = [[], []];
// for (const receiver of receivers) {
// if (receiver.toUpperCase() !== NIL_ADDRESS.toUpperCase()) {
// tokenBalancesReceiversBefore[index].push(
// (await tokenInstance.balanceOf(receiver)).toString()
// );
// } else {
// tokenBalancesReceiversBefore[index].push(
// (await tokenToBurnInstance.balanceOf(
// await tokenDistributorInstance.recipientBurn()
// )).toString()
// );
// }
// }
// tokenBalancesBefore.push({
// tokenDistributor: (await tokenInstance.balanceOf(
// tokenDistributorInstance.address
// )).toString(),
// receivers: tokenBalancesReceiversBefore[index],
// });
// }
// const tokenDistribution = await tokenDistributorInstance.getDistribution();
// await tokenDistributorInstance.distribute(
// tokenInstances.map(tokenInstance => tokenInstance.address)
// );
// const tokenBalanceOfDistributorAfter: string[] = [];
// for (const [indexToken, tokenInstance] of tokenInstances.entries()) {
// const newLength = tokenBalanceOfDistributorAfter.push(
// (await tokenInstance.balanceOf(tokenDistributorInstance.address)).toString()
// );
// const receivers = distributionParams[indexToken].receivers;
// expect(parseInt(tokenBalanceOfDistributorAfter[newLength - 1])).to.be.within(
// 0,
// receivers.length - 1
// );
// for (const [indexReceiver, receiver] of receivers.entries()) {
// const receiverPercentage = new BigNumber(tokenDistribution[1][indexReceiver]).toFixed();
// const tokenAmountToReceiver = new BigNumber(tokenBalancesBefore[indexToken].tokenDistributor)
// .multipliedBy(receiverPercentage)
// .dividedBy(TOKEN_DISTRIBUTOR_PERCENTAGE_BASE)
// .toFixed(0, BigNumber.ROUND_DOWN);
// const tokenBalanceOfReceiverAfter = (await tokenInstance.balanceOf(receiver)).toString();
// const recipientBurnBalanceAfter = (await tokenToBurnInstance.balanceOf(
// await tokenDistributorInstance.recipientBurn()
// )).toString();
// if (receiver.toUpperCase() !== NIL_ADDRESS.toUpperCase()) {
// expect(tokenBalanceOfReceiverAfter).to.be.equal(
// new BigNumber(tokenBalancesBefore[indexToken].receivers[indexReceiver])
// .plus(tokenAmountToReceiver)
// .toFixed()
// );
// } else {
// // 1 ether received from "burning" DAI and 264 LEND wei received from the 34% of the 777 LEND amount sent to the token distributor
// expect(recipientBurnBalanceAfter).to.be.equal('1000000000000000264');
// }
// }
// }
// };
// const testAndExecDistributeEth = async (
// tokenDistributorInstance: TokenDistributorInstance,
// tokenToBurnInstance: MintableERC20Instance,
// distributionParams: iBasicDistributionParams,
// web3: Web3
// ) => {
// const {receivers} = distributionParams;
// const ethBalancesReceiversBefore = [];
// for (const receiver of receivers) {
// if (receiver.toUpperCase() !== NIL_ADDRESS.toUpperCase()) {
// ethBalancesReceiversBefore.push(await web3.eth.getBalance(receiver));
// } else {
// ethBalancesReceiversBefore.push(await web3.eth.getBalance(ONE_ADDRESS));
// }
// }
// const ethBalancesBefore: iTokenBalances = {
// tokenDistributor: await web3.eth.getBalance(tokenDistributorInstance.address),
// receivers: ethBalancesReceiversBefore,
// };
// const ethDistribution = await tokenDistributorInstance.getDistribution();
// await tokenDistributorInstance.distribute([ETHEREUM_ADDRESS]);
// const ethBalanceOfDistributorAfter = await web3.eth.getBalance(tokenDistributorInstance.address);
// expect(parseInt(ethBalanceOfDistributorAfter)).to.be.within(0, receivers.length - 1);
// for (const [index, receiver] of receivers.entries()) {
// const receiverPercentage = new BigNumber(ethDistribution[1][index]).toFixed();
// const ethAmountToReceiver = new BigNumber(ethBalancesBefore.tokenDistributor)
// .multipliedBy(receiverPercentage)
// .dividedBy(TOKEN_DISTRIBUTOR_PERCENTAGE_BASE)
// .toFixed(0, BigNumber.ROUND_DOWN);
// const ethBalanceOfReceiverAfter = await web3.eth.getBalance(receiver);
// const recipientBurnBalanceAfter = (await tokenToBurnInstance.balanceOf(
// await tokenDistributorInstance.recipientBurn()
// )).toString();
// if (receiver.toUpperCase() !== NIL_ADDRESS.toUpperCase()) {
// expect(ethBalanceOfReceiverAfter).to.be.equal(
// new BigNumber(ethBalancesBefore.receivers[index]).plus(ethAmountToReceiver).toFixed()
// );
// } else {
// // 1 ether received from "burning" DAI, 1 ether from ETH and 264 LEND wei received from the 34% of the 777 LEND amount sent to the token distributor
// expect(recipientBurnBalanceAfter).to.be.equal('2000000000000000264');
// }
// }
// };
// contract('TokenDistributor', async ([deployer, ...users]) => {
// // let _testEnvProvider: ITestEnv;
// // let _tokenDistributorInstance: TokenDistributorInstance;
// // let _tokenInstances: iAavePoolAssets<MintableERC20Instance>;
// // let _web3: Web3;
// // let _depositorAddress: string;
// // let _daiDistributionParams: iDistributionParams;
// // let _lendDistributionParams: iDistributionParams;
// // let _ethDistributionParams: iDistributionParams;
// // before('Initializing LendingPoolConfigurator test variables', async () => {
// // _testEnvProvider = await testEnvProvider(
// // artifacts,
// // [deployer, ...users],
// // ContractsInstancesOrigin.TruffleArtifacts
// // );
// // const {
// // deployedInstances: {tokenDistributorInstance},
// // getAllAssetsInstances,
// // getWeb3,
// // getFirstDepositorAddressOnTests,
// // getFeeDistributionParams,
// // } = _testEnvProvider;
// // _tokenDistributorInstance = tokenDistributorInstance;
// // _tokenInstances = await getAllAssetsInstances();
// // _web3 = await getWeb3();
// // _depositorAddress = await getFirstDepositorAddressOnTests();
// // const {receivers, percentages} = await getFeeDistributionParams();
// // _daiDistributionParams = {
// // amountToDistribute: '333',
// // receivers,
// // percentages,
// // };
// // _lendDistributionParams = {
// // amountToDistribute: '777',
// // receivers,
// // percentages,
// // };
// // _ethDistributionParams = {
// // amountToDistribute: '2534',
// // receivers,
// // percentages,
// // };
// // });
// // it('Transfers ETH to the TokenDistributor', async () => {
// // await testAndExecEthTransfer(
// // _ethDistributionParams.amountToDistribute,
// // deployer,
// // _tokenDistributorInstance.address,
// // _web3
// // );
// // });
// // it('Mints and transfers DAI to the TokenDistributor', async () => {
// // await testAndExecMintAndTransferTokens(
// // _tokenInstances.DAI,
// // _daiDistributionParams.amountToDistribute,
// // _depositorAddress,
// // _tokenDistributorInstance.address
// // );
// // });
// // it('Mints and transfers LEND to the TokenDistributor', async () => {
// // await testAndExecMintAndTransferTokens(
// // _tokenInstances.LEND,
// // _lendDistributionParams.amountToDistribute,
// // _depositorAddress,
// // _tokenDistributorInstance.address
// // );
// // });
// // it('distribute() for the receivers', async () => {
// // await testAndExecDistributeToken(
// // [_tokenInstances.DAI, _tokenInstances.LEND],
// // _tokenInstances.LEND,
// // _tokenDistributorInstance,
// // [_daiDistributionParams, _lendDistributionParams]
// // );
// // });
// // it('Distributes the ETH to the receivers', async () => {
// // await testAndExecDistributeEth(
// // _tokenDistributorInstance,
// // _tokenInstances.LEND,
// // _ethDistributionParams,
// // _web3
// // );
// // });
// });

134
test/upgradeability.spec.ts Normal file
View File

@ -0,0 +1,134 @@
// import {ContractId, ITestEnvWithoutInstances} from '../utils/types';
// import {
// LendingPoolCoreInstance,
// LendingPoolConfiguratorInstance,
// LendingPoolAddressesProviderInstance,
// LendingPoolDataProviderInstance,
// LendingPoolInstance,
// MockLendingPoolCoreInstance,
// } from '../utils/typechain-types/truffle-contracts';
// import {testEnvProviderWithoutInstances} from '../utils/truffle/dlp-tests-env';
// import {ETHEREUM_ADDRESS} from '../utils/constants';
// import {getTruffleContractInstance} from '../utils/truffle/truffle-core-utils';
// import BN = require('bn.js');
// const {expectEvent, expectRevert} = require('@openzeppelin/test-helpers');
// contract('Upgradeability', async ([deployer, ...users]) => {
// let _testEnvProvider: ITestEnvWithoutInstances;
// let _configuratorInstance: LendingPoolConfiguratorInstance;
// let _coreInstance: LendingPoolCoreInstance;
// let _poolInstance: LendingPoolInstance;
// let _addressesProviderInstance: LendingPoolAddressesProviderInstance;
// let _dataProviderInstance: LendingPoolDataProviderInstance;
// let _mockCoreInstance: MockLendingPoolCoreInstance;
// before('Initializing test variables', async () => {
// _testEnvProvider = await testEnvProviderWithoutInstances(artifacts, [deployer, ...users]);
// const {
// getLendingPoolAddressesProviderInstance,
// getLendingPoolConfiguratorInstance,
// getLendingPoolCoreInstance,
// getLendingPoolDataProviderInstance,
// getLendingPoolInstance,
// } = _testEnvProvider;
// const instances = await Promise.all([
// getLendingPoolAddressesProviderInstance(),
// getLendingPoolConfiguratorInstance(),
// getLendingPoolCoreInstance(),
// getLendingPoolDataProviderInstance(),
// getLendingPoolInstance(),
// ]);
// _addressesProviderInstance = instances[0];
// _configuratorInstance = instances[1];
// _coreInstance = instances[2];
// _dataProviderInstance = instances[3];
// _poolInstance = instances[4];
// });
// it('tries to call the initialization function on LendingPoolConfigurator', async () => {
// await expectRevert(
// _configuratorInstance.initialize(_addressesProviderInstance.address),
// 'Contract instance has already been initialized'
// );
// });
// it('tries to call the initialization function on LendingPoolCore', async () => {
// await expectRevert(
// _coreInstance.initialize(_addressesProviderInstance.address),
// 'Contract instance has already been initialized'
// );
// });
// it('tries to call the initialization function on LendingPool', async () => {
// await expectRevert(
// _poolInstance.initialize(_addressesProviderInstance.address),
// 'Contract instance has already been initialized'
// );
// });
// it('tries to call the initialization function on DataProvider', async () => {
// await expectRevert(
// _dataProviderInstance.initialize(_addressesProviderInstance.address),
// 'Contract instance has already been initialized'
// );
// });
// it('Deploys a new version of a LendingPoolCore contract', async () => {
// const contract: any = await artifacts.require('MockLendingPoolCore');
// const mathLibrary = await artifacts.require('WadRayMath');
// const mathLibraryInstance = await mathLibrary.new();
// const coreLibrary = await artifacts.require('CoreLibrary');
// await coreLibrary.link('WadRayMath', mathLibraryInstance.address);
// await contract.link('CoreLibrary', coreLibrary.address);
// await contract.link('WadRayMath', mathLibraryInstance.address);
// _mockCoreInstance = await contract.new();
// const txResult = await _addressesProviderInstance.setLendingPoolCoreImpl(
// _mockCoreInstance.address
// );
// expectEvent(txResult, 'LendingPoolCoreUpdated', {
// newAddress: _mockCoreInstance.address,
// });
// });
// it('Tries to execute initialize() on the newly deployed core', async () => {
// const coreProxyAddress = await _addressesProviderInstance.getLendingPoolCore();
// const instance: LendingPoolCoreInstance = await getTruffleContractInstance(
// artifacts,
// ContractId.LendingPoolCore,
// coreProxyAddress
// );
// await expectRevert(
// instance.initialize(_addressesProviderInstance.address),
// 'Contract instance has already been initialized'
// );
// });
// it('Tries to deposit', async () => {
// const coreProxyAddress = await _addressesProviderInstance.getLendingPoolCore();
// const txReceipt: Truffle.TransactionResponse = await _poolInstance.deposit(
// ETHEREUM_ADDRESS,
// '100',
// '0',
// {value: '100'}
// );
// expectEvent.inTransaction(txReceipt.tx, coreProxyAddress, 'ReserveUpdatedFromMock', {
// revision: new BN(2),
// });
// });
// });

View File

@ -5,7 +5,8 @@
"strict": true,
"esModuleInterop": true,
"outDir": "dist",
"resolveJsonModule": true
"resolveJsonModule": true,
"downlevelIteration": true
},
"include": ["./**/*"],
"files": [

File diff suppressed because one or more lines are too long

View File

@ -56,4 +56,4 @@ const _abi = [
];
const _bytecode =
"0x608060405234801561001057600080fd5b5061010a806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806321f8a72114602d575b600080fd5b605660048036036020811015604157600080fd5b81019080803590602001909291905050506098565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600080600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905091905056fea2646970667358221220a16c9e7d045268148ef25ca3a4b35c2d6af3954ef6b65238e4dc4a8820245b4c64736f6c63430006080033";
"0x6080604052348015600f57600080fd5b5060b48061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806321f8a72114602d575b600080fd5b604760048036036020811015604157600080fd5b50356063565b604080516001600160a01b039092168252519081900360200190f35b6000908152602081905260409020546001600160a01b03169056fea2646970667358221220f09fcedc0f4e085a79292d7250a582eb479b29b554e5b6f0da0a8b9d6519437d64736f6c63430006080033";

File diff suppressed because one or more lines are too long

View File

@ -72,6 +72,10 @@ const _abi = [
name: "Upgraded",
type: "event"
},
{
stateMutability: "payable",
type: "fallback"
},
{
inputs: [],
name: "admin",
@ -141,12 +145,8 @@ const _abi = [
outputs: [],
stateMutability: "payable",
type: "function"
},
{
stateMutability: "payable",
type: "receive"
}
];
const _bytecode =
"0x608060405234801561001057600080fd5b50610908806100206000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100625780634f1ef286146100b35780635c60da1b1461014c5780638f283970146101a3578063f851a440146101f45761005d565b3661005d5761005b61024b565b005b600080fd5b34801561006e57600080fd5b506100b16004803603602081101561008557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610265565b005b61014a600480360360408110156100c957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561010657600080fd5b82018360208201111561011857600080fd5b8035906020019184600183028401116401000000008311171561013a57600080fd5b90919293919293905050506102ba565b005b34801561015857600080fd5b50610161610390565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156101af57600080fd5b506101f2600480360360208110156101c657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506103e8565b005b34801561020057600080fd5b50610209610561565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102536105b9565b61026361025e61064f565b610680565b565b61026d6106a6565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102ae576102a9816106d7565b6102b7565b6102b661024b565b5b50565b6102c26106a6565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610382576102fe836106d7565b60008373ffffffffffffffffffffffffffffffffffffffff168383604051808383808284378083019250505092505050600060405180830381855af49150503d8060008114610369576040519150601f19603f3d011682016040523d82523d6000602084013e61036e565b606091505b505090508061037c57600080fd5b5061038b565b61038a61024b565b5b505050565b600061039a6106a6565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103dc576103d561064f565b90506103e5565b6103e461024b565b5b90565b6103f06106a6565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561055557600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156104a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001806108626036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104d26106a6565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161055081610726565b61055e565b61055d61024b565b5b50565b600061056b6106a6565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156105ad576105a66106a6565b90506105b6565b6105b561024b565b5b90565b6105c16106a6565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610645576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806108306032913960400191505060405180910390fd5b61064d610755565b565b6000807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b9050805491505090565b3660008037600080366000845af43d6000803e80600081146106a1573d6000f35b3d6000fd5b6000807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610360001b9050805491505090565b6106e081610757565b8073ffffffffffffffffffffffffffffffffffffffff167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b60405160405180910390a250565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610360001b90508181555050565b565b610760816107e4565b6107b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b815260200180610898603b913960400191505060405180910390fd5b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b90508181555050565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f915080821415801561082657506000801b8214155b9250505091905056fe43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e2066726f6d207468652070726f78792061646d696e43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a2646970667358221220bcf7a9ee60dd93ba2095ea1f2c9d93ef295f42fdea1cdd54f83dddb8429a479164736f6c63430006080033";
"0x608060405234801561001057600080fd5b50610652806100206000396000f3fe60806040526004361061004a5760003560e01c80633659cfe6146100545780634f1ef286146100875780635c60da1b146101075780638f28397014610138578063f851a4401461016b575b610052610180565b005b34801561006057600080fd5b506100526004803603602081101561007757600080fd5b50356001600160a01b031661019a565b6100526004803603604081101561009d57600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156100c857600080fd5b8201836020820111156100da57600080fd5b803590602001918460018302840111640100000000831117156100fc57600080fd5b5090925090506101d4565b34801561011357600080fd5b5061011c610281565b604080516001600160a01b039092168252519081900360200190f35b34801561014457600080fd5b506100526004803603602081101561015b57600080fd5b50356001600160a01b03166102be565b34801561017757600080fd5b5061011c610378565b6101886103a3565b610198610193610403565b610428565b565b6101a261044c565b6001600160a01b0316336001600160a01b031614156101c9576101c481610471565b6101d1565b6101d1610180565b50565b6101dc61044c565b6001600160a01b0316336001600160a01b03161415610274576101fe83610471565b6000836001600160a01b031683836040518083838082843760405192019450600093509091505080830381855af49150503d806000811461025b576040519150601f19603f3d011682016040523d82523d6000602084013e610260565b606091505b505090508061026e57600080fd5b5061027c565b61027c610180565b505050565b600061028b61044c565b6001600160a01b0316336001600160a01b031614156102b3576102ac610403565b90506102bb565b6102bb610180565b90565b6102c661044c565b6001600160a01b0316336001600160a01b031614156101c9576001600160a01b0381166103245760405162461bcd60e51b81526004018080602001828103825260368152602001806105ac6036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61034d61044c565b604080516001600160a01b03928316815291841660208301528051918290030190a16101c4816104b1565b600061038261044c565b6001600160a01b0316336001600160a01b031614156102b3576102ac61044c565b6103ab61044c565b6001600160a01b0316336001600160a01b031614156103fb5760405162461bcd60e51b815260040180806020018281038252603281526020018061057a6032913960400191505060405180910390fd5b610198610198565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610447573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b61047a816104d5565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b6104de8161053d565b6105195760405162461bcd60e51b815260040180806020018281038252603b8152602001806105e2603b913960400191505060405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061057157508115155b94935050505056fe43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e2066726f6d207468652070726f78792061646d696e43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a2646970667358221220153c3fcf73e6d2ff5abc19385f928b0ad6ca58f36558f457764b0ad8f1b590d964736f6c63430006080033";

View File

@ -53,9 +53,9 @@ const _abi = [
},
{
stateMutability: "payable",
type: "receive"
type: "fallback"
}
];
const _bytecode =
"0x608060405234801561001057600080fd5b5060b78061001f6000396000f3fe608060405236601057600e6015565b005b600080fd5b601b6029565b60276023602b565b605c565b565b565b6000807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b9050805491505090565b3660008037600080366000845af43d6000803e8060008114607c573d6000f35b3d6000fdfea26469706673582212205b9fe06218823c76111682e2b2f093d5f7713a33f64a2a9d36ab2e46371e031664736f6c63430006080033";
"0x6080604052348015600f57600080fd5b50609e8061001e6000396000f3fe6080604052600a600c565b005b6012601e565b601e601a6020565b6045565b565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e8080156063573d6000f35b3d6000fdfea2646970667358221220f39c60065bf5bc2b317031ab707b9f77fec3571f3c29e70ce25a3329a851e15664736f6c63430006080033";

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -68,4 +68,4 @@ const _abi = [
];
const _bytecode =
"0x608060405234801561001057600080fd5b50600560008190555060b4806100276000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80631aadff81146037578063f8a8fd6d146053575b600080fd5b603d606f565b6040518082815260200191505060405180910390f35b60596075565b6040518082815260200191505060405180910390f35b60005481565b6000805490509056fea264697066735822122057a64b654e079499c1bcb7323ed02df7274732301ad598f3679f40351bdb288464736f6c63430006080033";
"0x6080604052348015600f57600080fd5b5060056000556097806100236000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80631aadff81146037578063f8a8fd6d14604f575b600080fd5b603d6055565b60408051918252519081900360200190f35b603d605b565b60005481565b6000549056fea2646970667358221220db729e656432d2a44942aae506cff90eea05978605f6847ecdf717665d7a04e664736f6c63430006080033";

View File

@ -113,4 +113,4 @@ const _abi = [
];
const _bytecode =
"0x60806040526000805534801561001457600080fd5b506105a6806100246000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80639403ed3a1461005c578063b0d73d4e1461007a578063c211f9a414610098578063c4d66de8146100b6578063e563a7d0146100fa575b600080fd5b61006461015c565b6040518082815260200191505060405180910390f35b610082610162565b6040518082815260200191505060405180910390f35b6100a0610167565b6040518082815260200191505060405180910390f35b6100f8600480360360208110156100cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610171565b005b6101466004803603604081101561011057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061026f565b6040518082815260200191505060405180910390f35b60345481565b600181565b6000603454905090565b600061017b61028e565b9050600160009054906101000a900460ff168061019c575061019b610297565b5b806101a8575060005481115b6101fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180610543602e913960400191505060405180910390fd5b6000600160009054906101000a900460ff16159050801561023a5760018060006101000a81548160ff021916908315150217905550816000819055505b6608e1bc9bf04000603481905550801561026a576000600160006101000a81548160ff0219169083151502179055505b505050565b6000610286603454836102a890919063ffffffff16565b905092915050565b60006001905090565b600080303b90506000811491505090565b60006102fb670de0b6b3a76400006102ed6102cc858761030390919063ffffffff16565b6002670de0b6b3a7640000816102de57fe5b0461038990919063ffffffff16565b61041190919063ffffffff16565b905092915050565b6000808314156103165760009050610383565b600082840290508284828161032757fe5b041461037e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806105226021913960400191505060405180910390fd5b809150505b92915050565b600080828401905083811015610407576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600061045383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061045b565b905092915050565b60008083118290610507576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156104cc5780820151818401526020810190506104b1565b50505050905090810190601f1680156104f95780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161051357fe5b04905080915050939250505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564a264697066735822122089bcac65a55f6d08c407c046f359ea89e8c8a9faef3d94cacf55fb22990f71fb64736f6c63430006080033";
"0x60806040526000805534801561001457600080fd5b50610411806100246000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80639403ed3a1461005c578063b0d73d4e14610076578063c211f9a41461007e578063c4d66de814610086578063e563a7d0146100ae575b600080fd5b6100646100da565b60408051918252519081900360200190f35b6100646100e0565b6100646100e5565b6100ac6004803603602081101561009c57600080fd5b50356001600160a01b03166100eb565b005b610064600480360360408110156100c457600080fd5b506001600160a01b038135169060200135610193565b60345481565b600181565b60345490565b60006100f56101b3565b60015490915060ff168061010c575061010c6101b8565b80610118575060005481115b6101535760405162461bcd60e51b815260040180806020018281038252602e8152602001806103ae602e913960400191505060405180910390fd5b60015460ff16158015610172576001805460ff19168117905560008290555b6608e1bc9bf04000603455801561018e576001805460ff191690555b505050565b60006101aa603454836101be90919063ffffffff16565b90505b92915050565b600190565b303b1590565b60006101aa670de0b6b3a76400006101ee6101df868663ffffffff6101fa16565b6706f05b59d3b2000090610253565b9063ffffffff6102ad16565b600082610209575060006101ad565b8282028284828161021657fe5b04146101aa5760405162461bcd60e51b815260040180806020018281038252602181526020018061038d6021913960400191505060405180910390fd5b6000828201838110156101aa576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006101aa83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250600081836103765760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561033b578181015183820152602001610323565b50505050905090810190601f1680156103685780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161038257fe5b049594505050505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564a2646970667358221220b6d286d1f0b82789105155b663f2705ed827df2cb1cad4c6923082f530bb3d2264736f6c63430006080033";

74
types/Ierc20Burnable.d.ts vendored Normal file
View File

@ -0,0 +1,74 @@
/* Generated by ts-generator ver. 0.0.8 */
/* tslint:disable */
import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
import { Listener, Provider } from "ethers/providers";
import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
import {
TransactionOverrides,
TypedEventDescription,
TypedFunctionDescription
} from ".";
interface Ierc20BurnableInterface extends Interface {
functions: {
burn: TypedFunctionDescription<{
encode([amount]: [BigNumberish]): string;
}>;
burnFrom: TypedFunctionDescription<{
encode([account, amount]: [string, BigNumberish]): string;
}>;
};
events: {};
}
export class Ierc20Burnable extends Contract {
connect(signerOrProvider: Signer | Provider | string): Ierc20Burnable;
attach(addressOrName: string): Ierc20Burnable;
deployed(): Promise<Ierc20Burnable>;
on(event: EventFilter | string, listener: Listener): Ierc20Burnable;
once(event: EventFilter | string, listener: Listener): Ierc20Burnable;
addListener(
eventName: EventFilter | string,
listener: Listener
): Ierc20Burnable;
removeAllListeners(eventName: EventFilter | string): Ierc20Burnable;
removeListener(eventName: any, listener: Listener): Ierc20Burnable;
interface: Ierc20BurnableInterface;
functions: {
burn(
amount: BigNumberish,
overrides?: TransactionOverrides
): Promise<ContractTransaction>;
burnFrom(
account: string,
amount: BigNumberish,
overrides?: TransactionOverrides
): Promise<ContractTransaction>;
};
burn(
amount: BigNumberish,
overrides?: TransactionOverrides
): Promise<ContractTransaction>;
burnFrom(
account: string,
amount: BigNumberish,
overrides?: TransactionOverrides
): Promise<ContractTransaction>;
filters: {};
estimate: {
burn(amount: BigNumberish): Promise<BigNumber>;
burnFrom(account: string, amount: BigNumberish): Promise<BigNumber>;
};
}

View File

@ -0,0 +1,50 @@
/* Generated by ts-generator ver. 0.0.8 */
/* tslint:disable */
import { Contract, Signer } from "ethers";
import { Provider } from "ethers/providers";
import { Ierc20Burnable } from "./Ierc20Burnable";
export class Ierc20BurnableFactory {
static connect(
address: string,
signerOrProvider: Signer | Provider
): Ierc20Burnable {
return new Contract(address, _abi, signerOrProvider) as Ierc20Burnable;
}
}
const _abi = [
{
inputs: [
{
internalType: "uint256",
name: "amount",
type: "uint256"
}
],
name: "burn",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{
internalType: "address",
name: "account",
type: "address"
},
{
internalType: "uint256",
name: "amount",
type: "uint256"
}
],
name: "burnFrom",
outputs: [],
stateMutability: "nonpayable",
type: "function"
}
];

View File

@ -76,4 +76,4 @@ const _abi = [
];
const _bytecode =
"0x608060405234801561001057600080fd5b5060dd8061001f6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c806306fdde03146041578063313ce56714605d57806395d89b41146079575b600080fd5b60476095565b6040518082815260200191505060405180910390f35b6063609b565b6040518082815260200191505060405180910390f35b607f60a1565b6040518082815260200191505060405180910390f35b60005481565b60025481565b6001548156fea264697066735822122012181cc1edfa2cb5dc11110436ba200114c6189dd7b22301a6738f7f6169359264736f6c63430006080033";
"0x608060405234801561001057600080fd5b5060ad8061001f6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c806306fdde03146041578063313ce56714605957806395d89b4114605f575b600080fd5b60476065565b60408051918252519081900360200190f35b6047606b565b60476071565b60005481565b60025481565b6001548156fea26469706673582212203768796577a99ad3a548ada1f422b9a27c862840dd4342467451416181f264f564736f6c63430006080033";

54
types/Ierc20Mintable.d.ts vendored Normal file
View File

@ -0,0 +1,54 @@
/* Generated by ts-generator ver. 0.0.8 */
/* tslint:disable */
import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
import { Listener, Provider } from "ethers/providers";
import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
import {
TransactionOverrides,
TypedEventDescription,
TypedFunctionDescription
} from ".";
interface Ierc20MintableInterface extends Interface {
functions: {
mint: TypedFunctionDescription<{ encode([value]: [BigNumberish]): string }>;
};
events: {};
}
export class Ierc20Mintable extends Contract {
connect(signerOrProvider: Signer | Provider | string): Ierc20Mintable;
attach(addressOrName: string): Ierc20Mintable;
deployed(): Promise<Ierc20Mintable>;
on(event: EventFilter | string, listener: Listener): Ierc20Mintable;
once(event: EventFilter | string, listener: Listener): Ierc20Mintable;
addListener(
eventName: EventFilter | string,
listener: Listener
): Ierc20Mintable;
removeAllListeners(eventName: EventFilter | string): Ierc20Mintable;
removeListener(eventName: any, listener: Listener): Ierc20Mintable;
interface: Ierc20MintableInterface;
functions: {
mint(
value: BigNumberish,
overrides?: TransactionOverrides
): Promise<ContractTransaction>;
};
mint(
value: BigNumberish,
overrides?: TransactionOverrides
): Promise<ContractTransaction>;
filters: {};
estimate: {
mint(value: BigNumberish): Promise<BigNumber>;
};
}

204
types/Ierc20MintableBurnable.d.ts vendored Normal file
View File

@ -0,0 +1,204 @@
/* Generated by ts-generator ver. 0.0.8 */
/* tslint:disable */
import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
import { Listener, Provider } from "ethers/providers";
import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
import {
TransactionOverrides,
TypedEventDescription,
TypedFunctionDescription
} from ".";
interface Ierc20MintableBurnableInterface extends Interface {
functions: {
allowance: TypedFunctionDescription<{
encode([owner, spender]: [string, string]): string;
}>;
approve: TypedFunctionDescription<{
encode([spender, amount]: [string, BigNumberish]): string;
}>;
balanceOf: TypedFunctionDescription<{
encode([account]: [string]): string;
}>;
burn: TypedFunctionDescription<{
encode([amount]: [BigNumberish]): string;
}>;
burnFrom: TypedFunctionDescription<{
encode([account, amount]: [string, BigNumberish]): string;
}>;
mint: TypedFunctionDescription<{ encode([value]: [BigNumberish]): string }>;
totalSupply: TypedFunctionDescription<{ encode([]: []): string }>;
transfer: TypedFunctionDescription<{
encode([recipient, amount]: [string, BigNumberish]): string;
}>;
transferFrom: TypedFunctionDescription<{
encode([sender, recipient, amount]: [
string,
string,
BigNumberish
]): string;
}>;
};
events: {
Approval: TypedEventDescription<{
encodeTopics([owner, spender, value]: [
string | null,
string | null,
null
]): string[];
}>;
Transfer: TypedEventDescription<{
encodeTopics([from, to, value]: [
string | null,
string | null,
null
]): string[];
}>;
};
}
export class Ierc20MintableBurnable extends Contract {
connect(signerOrProvider: Signer | Provider | string): Ierc20MintableBurnable;
attach(addressOrName: string): Ierc20MintableBurnable;
deployed(): Promise<Ierc20MintableBurnable>;
on(event: EventFilter | string, listener: Listener): Ierc20MintableBurnable;
once(event: EventFilter | string, listener: Listener): Ierc20MintableBurnable;
addListener(
eventName: EventFilter | string,
listener: Listener
): Ierc20MintableBurnable;
removeAllListeners(eventName: EventFilter | string): Ierc20MintableBurnable;
removeListener(eventName: any, listener: Listener): Ierc20MintableBurnable;
interface: Ierc20MintableBurnableInterface;
functions: {
allowance(owner: string, spender: string): Promise<BigNumber>;
approve(
spender: string,
amount: BigNumberish,
overrides?: TransactionOverrides
): Promise<ContractTransaction>;
balanceOf(account: string): Promise<BigNumber>;
burn(
amount: BigNumberish,
overrides?: TransactionOverrides
): Promise<ContractTransaction>;
burnFrom(
account: string,
amount: BigNumberish,
overrides?: TransactionOverrides
): Promise<ContractTransaction>;
mint(
value: BigNumberish,
overrides?: TransactionOverrides
): Promise<ContractTransaction>;
totalSupply(): Promise<BigNumber>;
transfer(
recipient: string,
amount: BigNumberish,
overrides?: TransactionOverrides
): Promise<ContractTransaction>;
transferFrom(
sender: string,
recipient: string,
amount: BigNumberish,
overrides?: TransactionOverrides
): Promise<ContractTransaction>;
};
allowance(owner: string, spender: string): Promise<BigNumber>;
approve(
spender: string,
amount: BigNumberish,
overrides?: TransactionOverrides
): Promise<ContractTransaction>;
balanceOf(account: string): Promise<BigNumber>;
burn(
amount: BigNumberish,
overrides?: TransactionOverrides
): Promise<ContractTransaction>;
burnFrom(
account: string,
amount: BigNumberish,
overrides?: TransactionOverrides
): Promise<ContractTransaction>;
mint(
value: BigNumberish,
overrides?: TransactionOverrides
): Promise<ContractTransaction>;
totalSupply(): Promise<BigNumber>;
transfer(
recipient: string,
amount: BigNumberish,
overrides?: TransactionOverrides
): Promise<ContractTransaction>;
transferFrom(
sender: string,
recipient: string,
amount: BigNumberish,
overrides?: TransactionOverrides
): Promise<ContractTransaction>;
filters: {
Approval(
owner: string | null,
spender: string | null,
value: null
): EventFilter;
Transfer(from: string | null, to: string | null, value: null): EventFilter;
};
estimate: {
allowance(owner: string, spender: string): Promise<BigNumber>;
approve(spender: string, amount: BigNumberish): Promise<BigNumber>;
balanceOf(account: string): Promise<BigNumber>;
burn(amount: BigNumberish): Promise<BigNumber>;
burnFrom(account: string, amount: BigNumberish): Promise<BigNumber>;
mint(value: BigNumberish): Promise<BigNumber>;
totalSupply(): Promise<BigNumber>;
transfer(recipient: string, amount: BigNumberish): Promise<BigNumber>;
transferFrom(
sender: string,
recipient: string,
amount: BigNumberish
): Promise<BigNumber>;
};
}

View File

@ -0,0 +1,250 @@
/* Generated by ts-generator ver. 0.0.8 */
/* tslint:disable */
import { Contract, Signer } from "ethers";
import { Provider } from "ethers/providers";
import { Ierc20MintableBurnable } from "./Ierc20MintableBurnable";
export class Ierc20MintableBurnableFactory {
static connect(
address: string,
signerOrProvider: Signer | Provider
): Ierc20MintableBurnable {
return new Contract(
address,
_abi,
signerOrProvider
) as Ierc20MintableBurnable;
}
}
const _abi = [
{
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: [
{
internalType: "uint256",
name: "amount",
type: "uint256"
}
],
name: "burn",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{
internalType: "address",
name: "account",
type: "address"
},
{
internalType: "uint256",
name: "amount",
type: "uint256"
}
],
name: "burnFrom",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{
internalType: "uint256",
name: "value",
type: "uint256"
}
],
name: "mint",
outputs: [],
stateMutability: "nonpayable",
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"
}
];

View File

@ -0,0 +1,32 @@
/* Generated by ts-generator ver. 0.0.8 */
/* tslint:disable */
import { Contract, Signer } from "ethers";
import { Provider } from "ethers/providers";
import { Ierc20Mintable } from "./Ierc20Mintable";
export class Ierc20MintableFactory {
static connect(
address: string,
signerOrProvider: Signer | Provider
): Ierc20Mintable {
return new Contract(address, _abi, signerOrProvider) as Ierc20Mintable;
}
}
const _abi = [
{
inputs: [
{
internalType: "uint256",
name: "value",
type: "uint256"
}
],
name: "mint",
outputs: [],
stateMutability: "nonpayable",
type: "function"
}
];

File diff suppressed because one or more lines are too long

View File

@ -53,6 +53,10 @@ const _abi = [
name: "Upgraded",
type: "event"
},
{
stateMutability: "payable",
type: "fallback"
},
{
inputs: [
{
@ -70,12 +74,8 @@ const _abi = [
outputs: [],
stateMutability: "payable",
type: "function"
},
{
stateMutability: "payable",
type: "receive"
}
];
const _bytecode =
"0x608060405234801561001057600080fd5b50610450806100206000396000f3fe6080604052600436106100225760003560e01c8063d1f578941461003657610031565b366100315761002f610111565b005b600080fd5b61010f6004803603604081101561004c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561008957600080fd5b82018360208201111561009b57600080fd5b803590602001918460018302840111640100000000831117156100bd57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061012b565b005b6101196102ae565b6101296101246102b0565b6102e1565b565b600073ffffffffffffffffffffffffffffffffffffffff1661014b6102b0565b73ffffffffffffffffffffffffffffffffffffffff161461016b57600080fd5b600160405180807f656970313936372e70726f78792e696d706c656d656e746174696f6e00000000815250601c019050604051809103902060001c0360001b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b146101d557fe5b6101de82610307565b6000815111156102aa5760008273ffffffffffffffffffffffffffffffffffffffff16826040518082805190602001908083835b602083106102355780518252602082019150602081019050602083039250610212565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d8060008114610295576040519150601f19603f3d011682016040523d82523d6000602084013e61029a565b606091505b50509050806102a857600080fd5b505b5050565b565b6000807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b9050805491505090565b3660008037600080366000845af43d6000803e8060008114610302573d6000f35b3d6000fd5b61031081610394565b610365576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001806103e0603b913960400191505060405180910390fd5b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b90508181555050565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f91508082141580156103d657506000801b8214155b9250505091905056fe43616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a2646970667358221220ec5e8c1744cf082a11e2b69560ecd27aab52ab8ed1a234f721fc2b20fc028b1264736f6c63430006080033";
"0x608060405234801561001057600080fd5b50610398806100206000396000f3fe60806040526004361061001e5760003560e01c8063d1f5789414610028575b6100266100de565b005b6100266004803603604081101561003e57600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561006957600080fd5b82018360208201111561007b57600080fd5b8035906020019184600183028401116401000000008311171561009d57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506100f8945050505050565b6100e66100f6565b6100f66100f161023a565b61025f565b565b600061010261023a565b6001600160a01b03161461011557600080fd5b604080517f656970313936372e70726f78792e696d706c656d656e746174696f6e000000008152905190819003601c0190207f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6000199091011461017557fe5b61017e82610283565b805115610236576000826001600160a01b0316826040518082805190602001908083835b602083106101c15780518252601f1990920191602091820191016101a2565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d8060008114610221576040519150601f19603f3d011682016040523d82523d6000602084013e610226565b606091505b505090508061023457600080fd5b505b5050565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e80801561027e573d6000f35b3d6000fd5b61028c816102eb565b6102c75760405162461bcd60e51b815260040180806020018281038252603b815260200180610328603b913960400191505060405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061031f57508115155b94935050505056fe43616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a264697066735822122039ea210f3068bef90dab509c4cdfa0a898049566f198f6e2518a306b66f48d6464736f6c63430006080033";

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -100,4 +100,4 @@ const _abi = [
];
const _bytecode =
"0x60806040526000805534801561001457600080fd5b50610290806100246000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806346f4f8d114610051578063586feb401461006f578063c4d66de814610094578063d6b725ac146100d8575b600080fd5b6100596100f6565b6040518082815260200191505060405180910390f35b610077610109565b604051808381526020018281526020019250505060405180910390f35b6100d6600480360360208110156100aa57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610119565b005b6100e0610209565b6040518082815260200191505060405180910390f35b60006aa56fa5b99019a5c8000000905090565b6000806009610bb8915091509091565b6000610123610212565b9050600160009054906101000a900460ff1680610144575061014361021b565b5b80610150575060005481115b6101a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e81526020018061022d602e913960400191505060405180910390fd5b6000600160009054906101000a900460ff1615905080156101e25760018060006101000a81548160ff021916908315150217905550816000819055505b8015610204576000600160006101000a81548160ff0219169083151502179055505b505050565b60006019905090565b60006002905090565b600080303b9050600081149150509056fe436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564a264697066735822122050334318a13f1846df34a2f3f07056510a562429c75e298756c07808c9722f5264736f6c63430006080033";
"0x60806040526000805534801561001457600080fd5b506101e5806100246000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806346f4f8d114610051578063586feb401461006b578063c4d66de81461008c578063d6b725ac146100b4575b600080fd5b6100596100bc565b60408051918252519081900360200190f35b6100736100cb565b6040805192835260208301919091528051918290030190f35b6100b2600480360360208110156100a257600080fd5b50356001600160a01b03166100d4565b005b610059610171565b6aa56fa5b99019a5c800000090565b6009610bb89091565b60006100de610176565b60015490915060ff16806100f557506100f561017b565b80610101575060005481115b61013c5760405162461bcd60e51b815260040180806020018281038252602e815260200180610182602e913960400191505060405180910390fd5b60015460ff1615801561015b576001805460ff19168117905560008290555b801561016c576001805460ff191690555b505050565b601990565b600290565b303b159056fe436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564a264697066735822122063901128b8eb0844da98c6440cfb4a178fa19b719b954c9bf24df1d1abd1811064736f6c63430006080033";

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

62
types/MockAggregator.d.ts vendored Normal file
View File

@ -0,0 +1,62 @@
/* Generated by ts-generator ver. 0.0.8 */
/* tslint:disable */
import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
import { Listener, Provider } from "ethers/providers";
import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
import {
TransactionOverrides,
TypedEventDescription,
TypedFunctionDescription
} from ".";
interface MockAggregatorInterface extends Interface {
functions: {
latestAnswer: TypedFunctionDescription<{ encode([]: []): string }>;
};
events: {
AnswerUpdated: TypedEventDescription<{
encodeTopics([current, roundId, timestamp]: [
BigNumberish | null,
BigNumberish | null,
null
]): string[];
}>;
};
}
export class MockAggregator extends Contract {
connect(signerOrProvider: Signer | Provider | string): MockAggregator;
attach(addressOrName: string): MockAggregator;
deployed(): Promise<MockAggregator>;
on(event: EventFilter | string, listener: Listener): MockAggregator;
once(event: EventFilter | string, listener: Listener): MockAggregator;
addListener(
eventName: EventFilter | string,
listener: Listener
): MockAggregator;
removeAllListeners(eventName: EventFilter | string): MockAggregator;
removeListener(eventName: any, listener: Listener): MockAggregator;
interface: MockAggregatorInterface;
functions: {
latestAnswer(): Promise<BigNumber>;
};
latestAnswer(): Promise<BigNumber>;
filters: {
AnswerUpdated(
current: BigNumberish | null,
roundId: BigNumberish | null,
timestamp: null
): EventFilter;
};
estimate: {
latestAnswer(): Promise<BigNumber>;
};
}

View File

@ -95,4 +95,4 @@ const _abi = [
];
const _bytecode =
"0x608060405234801561001057600080fd5b5060405161011c38038061011c8339818101604052602081101561003357600080fd5b8101908080519060200190929190505050806000819055506000817f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f426040518082815260200191505060405180910390a3506088806100946000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806350d25bcd14602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000805490509056fea264697066735822122083cd3338e2c5f27a248c6cdcef44a00876f4c0a90224071a888dde6fe01f9b4964736f6c63430006080033";
"0x608060405234801561001057600080fd5b506040516101003803806101008339818101604052602081101561003357600080fd5b5051600081815560408051428152905183917f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f919081900360200190a35060818061007f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806350d25bcd14602d575b600080fd5b60336045565b60408051918252519081900360200190f35b6000549056fea2646970667358221220060be671455ecf17204969f30e34b79826d0c5978aa24f70ee045096a697a9a764736f6c63430006080033";

View File

@ -95,4 +95,4 @@ const _abi = [
];
const _bytecode =
"0x608060405234801561001057600080fd5b5060405161011e38038061011e8339818101604052602081101561003357600080fd5b810190808051906020019092919050505080806000819055506000817f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f426040518082815260200191505060405180910390a350506088806100966000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806350d25bcd14602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000805490509056fea2646970667358221220d02cf6d0c06b0214acfdf5e8b4a57a0c44208ace17e6c4480413bc174398d4e064736f6c63430006080033";
"0x608060405234801561001057600080fd5b506040516101033803806101038339818101604052602081101561003357600080fd5b5051600081815560408051428152905183929183917f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f9181900360200190a350506081806100826000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806350d25bcd14602d575b600080fd5b60336045565b60408051918252519081900360200190f35b6000549056fea264697066735822122067d1fc92dfb4035995fc56942a8fac11af7dd9f3a19251990effa2c9b6e9e8ab64736f6c63430006080033";

View File

@ -95,4 +95,4 @@ const _abi = [
];
const _bytecode =
"0x608060405234801561001057600080fd5b5060405161011e38038061011e8339818101604052602081101561003357600080fd5b810190808051906020019092919050505080806000819055506000817f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f426040518082815260200191505060405180910390a350506088806100966000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806350d25bcd14602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000805490509056fea2646970667358221220c29b105d310069f50df84f472945922156c9124f347756abceadb0750ad984ef64736f6c63430006080033";
"0x608060405234801561001057600080fd5b506040516101033803806101038339818101604052602081101561003357600080fd5b5051600081815560408051428152905183929183917f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f9181900360200190a350506081806100826000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806350d25bcd14602d575b600080fd5b60336045565b60408051918252519081900360200190f35b6000549056fea26469706673582212201f1bc6664c0ae2c54149c6ff1b532f7c023d4323052eec4d7e5668bb18caf4ad64736f6c63430006080033";

View File

@ -95,4 +95,4 @@ const _abi = [
];
const _bytecode =
"0x608060405234801561001057600080fd5b5060405161011e38038061011e8339818101604052602081101561003357600080fd5b810190808051906020019092919050505080806000819055506000817f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f426040518082815260200191505060405180910390a350506088806100966000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806350d25bcd14602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000805490509056fea26469706673582212202f3e307b78e825c1b1c5a5fb19f7c382e9b3e0cc54843d37895492794bbd407264736f6c63430006080033";
"0x608060405234801561001057600080fd5b506040516101033803806101038339818101604052602081101561003357600080fd5b5051600081815560408051428152905183929183917f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f9181900360200190a350506081806100826000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806350d25bcd14602d575b600080fd5b60336045565b60408051918252519081900360200190f35b6000549056fea2646970667358221220bc460a71c6f5f56df369342d0898d38ca6d1be268930ce0e8c567cd7620b901364736f6c63430006080033";

View File

@ -0,0 +1,96 @@
/* Generated by ts-generator ver. 0.0.8 */
/* tslint:disable */
import { Contract, ContractFactory, Signer } from "ethers";
import { Provider } from "ethers/providers";
import { UnsignedTransaction } from "ethers/utils/transaction";
import { BigNumberish } from "ethers/utils";
import { TransactionOverrides } from ".";
import { MockAggregator } from "./MockAggregator";
export class MockAggregatorFactory extends ContractFactory {
constructor(signer?: Signer) {
super(_abi, _bytecode, signer);
}
deploy(
_initialAnswer: BigNumberish,
overrides?: TransactionOverrides
): Promise<MockAggregator> {
return super.deploy(_initialAnswer, overrides) as Promise<MockAggregator>;
}
getDeployTransaction(
_initialAnswer: BigNumberish,
overrides?: TransactionOverrides
): UnsignedTransaction {
return super.getDeployTransaction(_initialAnswer, overrides);
}
attach(address: string): MockAggregator {
return super.attach(address) as MockAggregator;
}
connect(signer: Signer): MockAggregatorFactory {
return super.connect(signer) as MockAggregatorFactory;
}
static connect(
address: string,
signerOrProvider: Signer | Provider
): MockAggregator {
return new Contract(address, _abi, signerOrProvider) as MockAggregator;
}
}
const _abi = [
{
inputs: [
{
internalType: "int256",
name: "_initialAnswer",
type: "int256"
}
],
stateMutability: "nonpayable",
type: "constructor"
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "int256",
name: "current",
type: "int256"
},
{
indexed: true,
internalType: "uint256",
name: "roundId",
type: "uint256"
},
{
indexed: false,
internalType: "uint256",
name: "timestamp",
type: "uint256"
}
],
name: "AnswerUpdated",
type: "event"
},
{
inputs: [],
name: "latestAnswer",
outputs: [
{
internalType: "int256",
name: "",
type: "int256"
}
],
stateMutability: "view",
type: "function"
}
];
const _bytecode =
"0x608060405234801561001057600080fd5b506040516101003803806101008339818101604052602081101561003357600080fd5b5051600081815560408051428152905183917f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f919081900360200190a35060818061007f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806350d25bcd14602d575b600080fd5b60336045565b60408051918252519081900360200190f35b6000549056fea264697066735822122091d4f0afd82a633f8071a785eb6981a22f2cbb2175e6501f53f446275b42e05764736f6c63430006080033";

Some files were not shown because too many files have changed in this diff Show More