From dd17c55aef3d990e7f5ce2262b32090a375058d3 Mon Sep 17 00:00:00 2001 From: dmtrbch Date: Thu, 24 Oct 2024 11:49:09 +0200 Subject: [PATCH] Migrated xdc-prod branch to Hardhat (Asterizm Bridge included) --- README.md | 119 +- coralX-scenarios.js | 28 - .../01_deploy_add_collateral.js | 2 +- deploy/deploy-main/01_deploy.js | 2 +- .../01_deploy_test_fixture.js | 2 +- deploy/deploy-tokens/01_deploy_tokens.js | 2 +- package.json | 25 +- .../add-collateral/configPool.js | 4 +- .../addCollateralConfigPool.js | 9 +- .../deploy-test-fixture/addCollateralPools.js | 2 +- .../addCollateralPoolsPostDeployment.js | 2 +- .../deploy-test-fixture/addRoles.js | 2 +- .../addRolesPostDeployment.js | 2 +- .../deploy/addCollateralPools.js | 6 +- .../configuration/1_config-pool.js | 47 - .../add-collateral/deployment/1_deploy.js | 22 - .../deployment/2_deployProxies.js | 18 - .../add-collateral/deployment/3_initialize.js | 38 - .../add-collateral/deployment/4_add-roles.js | 22 - .../deployment/5_deployVault.js | 16 - .../collateral-tokens/1_deploy-tokens.js | 21 - .../configuration/1_add-collateral-pools.js | 61 - scripts/migrations/deployment/1_deploy.js | 69 - .../migrations/deployment/2_deployProxies.js | 45 - scripts/migrations/deployment/3_initialize.js | 146 -- scripts/migrations/deployment/4_add-roles.js | 62 - .../migrations/deployment/5_configure-fees.js | 22 - .../deployment/6_configure-show-stopper.js | 16 - .../migrations/deployment/7_deployVault.js | 14 - .../8_initialize_collateralTokenAdapter.js | 12 - .../deployment/9_configure-flash-lending.js | 9 - .../fathom-solidity-sdk/1_deploy.js | 35 - scripts/migrations/priceFeed/1_initialize.js | 25 - .../configuration/1_config-pool.js | 54 - .../pre-deployment/1_pre-deploy.js | 26 - .../test/configuration/1_add-roles.js | 26 - .../configuration/2_add-collateral-pools.js | 58 - .../test/post-deployment/1_deploy-mocks.js | 48 - .../post-deployment/2_add-collateral-pools.js | 58 - .../test/post-deployment/3_add-roles.js | 18 - .../test/pre-deployment/1_deploy-mocks.js | 88 - scripts/setup/add-collateral/addRoles.js | 2 +- scripts/setup/add-collateral/deploy.js | 4 +- scripts/setup/add-collateral/deployProxies.js | 2 +- scripts/setup/add-collateral/deployVault.js | 2 +- scripts/setup/add-collateral/initialize.js | 2 +- .../addCollateralPreDeployment.js | 2 +- .../setup/deploy-test-fixture/deployMocks.js | 2 +- .../deployMocksPostDeployment.js | 10 +- scripts/setup/deploy/addRoles.js | 4 +- scripts/setup/deploy/configFlashLending.js | 2 +- scripts/setup/deploy/configureFees.js | 4 +- scripts/setup/deploy/configureShowStopper.js | 2 +- scripts/setup/deploy/deployContracts.js | 4 +- scripts/setup/deploy/deployProxies.js | 4 +- scripts/setup/deploy/deployVault.js | 2 +- .../deploy/initCollateralTokenAdapter.js | 2 +- scripts/setup/deploy/initialize.js | 17 +- .../tests/integration/AdminControls.test.js | 98 - .../CollateralTokenAdapter.test.js | 580 ----- .../integration/FathomProxyActions.test.js | 214 -- .../tests/integration/FlashMintModule.test.js | 191 -- .../integration/LiquidationEngine.test.js | 762 ------- .../integration/PositionPermissions.test.js | 1977 ----------------- scripts/tests/integration/ProxyWallet.test.js | 133 -- scripts/tests/integration/ShowStopper.test.js | 482 ---- .../integration/StabilityFeeCollector.test.js | 163 -- .../integration/StableSwapModule.test.js | 585 ----- tasks/fathom-solidity-sdk.js | 51 +- tasks/price-feed.js | 6 +- test/integration/AdminControls.test.js | 2 +- .../CollateralTokenAdapter.test.js | 2 +- test/integration/FathomProxyActions.test.js | 2 +- test/integration/FlashMintModule.test.js | 2 +- test/integration/LiquidationEngine.test.js | 26 +- test/integration/PositionPermissions.test.js | 94 +- test/integration/ProxyWallet.test.js | 4 +- test/integration/ShowStopper.test.js | 2 +- .../integration/StabilityFeeCollector.test.js | 2 +- test/integration/StableSwapModule.test.js | 100 +- .../StableSwapModuleWrapper.test.js | 489 ++-- test/unit/adapter/StablecoinAdapter.test.js | 8 +- test/unit/adapter/TokenAdapter.test.js | 12 +- test/unit/config/CollateralPoolConfig.test.js | 2 +- test/unit/fathom-bridge/FathomBridge.test.js | 16 +- test/unit/flash-mint/FlashMintModule.test.js | 2 +- .../FixedSpreadLiquidationStrategy.test.js | 9 +- test/unit/managers/PositionManager.test.js | 6 +- .../CentralizedOraclePriceFeed.test.js | 2 +- .../unit/price-oracles/DexPriceOracle.test.js | 2 +- .../SlidingWindowDexOracle.test.js | 2 +- .../stablecoin-core/AdminControls.test.js | 2 +- test/unit/stablecoin-core/BookKeeper.test.js | 2 +- .../stablecoin-core/FathomStablecoin.test.js | 2 +- .../stablecoin-core/LiquidationEngine.test.js | 2 +- test/unit/stablecoin-core/PriceOracle.test.js | 2 +- test/unit/stablecoin-core/ShowStopper.test.js | 14 +- .../StabilityFeeCollector.test.js | 2 +- .../StableSwapModuleWrapper.test.js | 4 +- .../stablecoin-core/SystemDebtEngine.test.js | 2 +- 100 files changed, 479 insertions(+), 6931 deletions(-) delete mode 100644 coralX-scenarios.js delete mode 100644 scripts/migrations/add-collateral/configuration/1_config-pool.js delete mode 100644 scripts/migrations/add-collateral/deployment/1_deploy.js delete mode 100644 scripts/migrations/add-collateral/deployment/2_deployProxies.js delete mode 100644 scripts/migrations/add-collateral/deployment/3_initialize.js delete mode 100644 scripts/migrations/add-collateral/deployment/4_add-roles.js delete mode 100644 scripts/migrations/add-collateral/deployment/5_deployVault.js delete mode 100644 scripts/migrations/collateral-tokens/1_deploy-tokens.js delete mode 100644 scripts/migrations/configuration/1_add-collateral-pools.js delete mode 100644 scripts/migrations/deployment/1_deploy.js delete mode 100644 scripts/migrations/deployment/2_deployProxies.js delete mode 100644 scripts/migrations/deployment/3_initialize.js delete mode 100644 scripts/migrations/deployment/4_add-roles.js delete mode 100644 scripts/migrations/deployment/5_configure-fees.js delete mode 100644 scripts/migrations/deployment/6_configure-show-stopper.js delete mode 100644 scripts/migrations/deployment/7_deployVault.js delete mode 100644 scripts/migrations/deployment/8_initialize_collateralTokenAdapter.js delete mode 100644 scripts/migrations/deployment/9_configure-flash-lending.js delete mode 100644 scripts/migrations/fathom-solidity-sdk/1_deploy.js delete mode 100644 scripts/migrations/priceFeed/1_initialize.js delete mode 100644 scripts/migrations/test/add-collateral/configuration/1_config-pool.js delete mode 100644 scripts/migrations/test/add-collateral/pre-deployment/1_pre-deploy.js delete mode 100644 scripts/migrations/test/configuration/1_add-roles.js delete mode 100644 scripts/migrations/test/configuration/2_add-collateral-pools.js delete mode 100644 scripts/migrations/test/post-deployment/1_deploy-mocks.js delete mode 100644 scripts/migrations/test/post-deployment/2_add-collateral-pools.js delete mode 100644 scripts/migrations/test/post-deployment/3_add-roles.js delete mode 100644 scripts/migrations/test/pre-deployment/1_deploy-mocks.js delete mode 100644 scripts/tests/integration/AdminControls.test.js delete mode 100644 scripts/tests/integration/CollateralTokenAdapter.test.js delete mode 100644 scripts/tests/integration/FathomProxyActions.test.js delete mode 100644 scripts/tests/integration/FlashMintModule.test.js delete mode 100644 scripts/tests/integration/LiquidationEngine.test.js delete mode 100644 scripts/tests/integration/PositionPermissions.test.js delete mode 100644 scripts/tests/integration/ProxyWallet.test.js delete mode 100644 scripts/tests/integration/ShowStopper.test.js delete mode 100644 scripts/tests/integration/StabilityFeeCollector.test.js delete mode 100644 scripts/tests/integration/StableSwapModule.test.js rename {scripts/tests => test}/integration/StableSwapModuleWrapper.test.js (63%) diff --git a/README.md b/README.md index 25a62941..0d663ad9 100644 --- a/README.md +++ b/README.md @@ -10,15 +10,13 @@ Various mechanisms, including price oracles, Stable Swap, and a risk management ## Package version requirements for your machine: -- node v18.12.1 -- npm v8.19.2 -- CoralX v0.2.0 -- Solidity =0.8.17 (solc) -- Ganache CLI v6.12.2 (ganache-core: 2.13.2) +- node v20.17.0 +- npm v10.8.2 +- Hardhat v^2.22.12 ## Basic setup -The smart contracts are written in [Solidity](https://github.com/ethereum/solidity) and tested/deployed using [CoralX](https://github.com/Securrency-OSS/CoralX). +The smart contracts are written in [Solidity](https://github.com/ethereum/solidity) and tested/deployed using [Hardhat](https://hardhat.org/). ### Install nodejs: @@ -32,27 +30,6 @@ $ sudo apt install nodejs $ sudo apt install npm ``` -### Intall CoralX from the Securrency private registry. - -### Install CoralX package globally: - -```bash -$ npm install -g coral-x -``` - -### Install ganache-cli: - -```bash -$ npm install -g ganache-cli -``` - -### Install Solc (https://docs.soliditylang.org/en/v0.8.13/installing-solidity.html) - -```bash -$ curl -o /usr/bin/solc -fL https://github.com/ethereum/solidity/releases/download/v0.8.13/solc-static-linux \ - && chmod u+x /usr/bin/solc -``` - ## Running tests ### 0) After cloning the repo, install dependencies @@ -61,23 +38,15 @@ $ curl -o /usr/bin/solc -fL https://github.com/ethereum/solidity/releases/downlo $ npm i ``` -### 1) Run ganache with predefined accounts: - -```bash -$ ganache-cli -m MNEMONIC --gasLimit 12500000 -v -e 100000000 -``` - -### 2) Create file called "privateKey" in the root directory (to run tests, copy the privateKey of the first account of ganache): +### 1) Create SEED_PHRASE environment variable: ```bash -$ echo -n PRIVATE_KEY_WITHOUT_0x_PREFIX > privateKey +$ echo -n SEED_PHRASE=12_WORD_MNEMONIC > .env ``` -Please make sure that the privateKey file's content doesn't have any unneccesary text. The file should only contain privateKey without the 0x prefix. Otherwise, it will fail. - -### 3) Create externalAddresses.json file in root +### 2) Create externalAddresses.json file in root -The chainId 31337 addresses are required to execute the test scripts on Ganache. Checksummed addresses must be included in the externalAddresses.json file as placeholder addresses for test execution. Use the content provided below for the externalAddresses.json file to run the test scripts. +The chainId 31337 addresses are required to execute the test scripts on built-in Hardhat Network. Checksummed addresses must be included in the externalAddresses.json file as placeholder addresses for test execution. Use the content provided below for the externalAddresses.json file to run the test scripts. ```JSON { @@ -93,41 +62,33 @@ The chainId 31337 addresses are required to execute the test scripts on Ganache. ``` -### 4) Run commands to run tests in root +### 3) Run commands to run tests in root ```bash -$ coralX test +$ npm run test ``` The contracts will compile, be deployed, and then the test scripts will run. -To run a specific test script instead of running the the whole tests, run as below. For example, to run PositionPermissions.test.js +To run a specific test script instead of running the the whole tests, run as below. For example, to run AdminControls.test.js ```bash -$ coralX test --path integration/PositionPermissions.test.js +$ npx hardhat test test/integration/AdminControls.test.js ``` -You might face some tests failing with 'out of gas' error. - ## Deployment The current codebase is structured so that the same set of smart contracts will be deployed, regardless of the target blockchain. By default, the protocol's price feed after deployment is set to `SimplePriceFeed`, a mock price feed that allows the protocol's deployer (owner) to freely modify prices. This default setting is based on the consideration that other price feeds for commercial use, whether sourcing from a DEX or a Centralized one, require external addresses or even price-related bots for successful deployment. Consequently, the adjusted deployment/migration script will deploy `DexPriceOracle`, `DelayFathomOraclePriceFeed`, `CentralizedOraclePriceFeed`, and `SlidingWindowDexOracle` using proxy patterns, but will not initialize them. Documentation regarding price feed changes will be included in this markdown document following the deployment section. -### On Ganache - -#### 0) Run ganache with predefined accounts: - -```bash -$ ganache-cli -m MNEMONIC --gasLimit 12500000 -v -e 100000000 -``` +### On built-in Hardhat network, Chain id: 31337 -### 1) Create file called "privateKey" in the root directory (copy the privateKey of the first account of ganache): +### 0) Create SEED_PHRASE environment variable: ```bash -$ echo -n PRIVATE_KEY_WITHOUT_0x_PREFIX > privateKey +$ echo -n SEED_PHRASE=12_WORD_MNEMONIC > .env ``` -#### 2) Create externalAddresses.json in root directory. +#### 1) Create externalAddresses.json in root directory. The format of the content can be same as in the Running test sections. Like below @@ -145,35 +106,35 @@ The format of the content can be same as in the Running test sections. Like belo ``` -If you want to see the protocol in action by depositing test ETH and borrowing FXD, I recommend that you first deploy WXDC||WETH on Ganache. After that, update the WXDC address in the externalAddresses.json file with the address of the WXDC you deployed. Additionally, if you aim to thoroughly test the StableSwapModule post-deployment, you must deploy an ERC20 token that can subsequently be deposited into the StableSwapModule. Therefore, please deploy an ERC20 token to substitute for the USD token, and update the USD value in the aforementioned JSON file. +If you want to see the protocol in action by depositing test ETH and borrowing FXD, I recommend that you first deploy WXDC||WETH on Hardhat network. After that, update the WXDC address in the externalAddresses.json file with the address of the WXDC you deployed. Additionally, if you aim to thoroughly test the StableSwapModule post-deployment, you must deploy an ERC20 token that can subsequently be deposited into the StableSwapModule. Therefore, please deploy an ERC20 token to substitute for the USD token, and update the USD value in the aforementioned JSON file. -#### 3) Compile contracts +#### 2) Compile contracts ```bash -$ coralX compile +$ npm run compile ``` make sure that the contracts compile before deployment -#### 4) Deploy with below command +#### 3) Deploy with below command ```bash -$ coralX scenario --run deployLocal +$ npm run deploy-local ``` -#### 5) Check contract addresses in addresses.json file in root +#### 4) Check contract addresses in addresses.json file in root After deployment, addresses.json gets updated with addresses of proxies. ### On apothem (XDC Testnet) -#### 1) Create file called "privateKey" in the root directory (PRIVATE_KEY_WITHOUT_0x_PREFIX of the EOA that you would like to deploy contracts from): +#### 0) Create SEED_PHRASE environment variable: ```bash -$ echo -n PRIVATE_KEY_WITHOUT_0x_PREFIX > privateKey +$ echo -n SEED_PHRASE=12_WORD_MNEMONIC > .env ``` -#### 2) Create externalAddresses.json in root directory.: +#### 1) Create externalAddresses.json in root directory.: ChainID of apothem is 51. Therefore, the externalAddresses.json need to have the sets of addresses having 51 as key. For example, like below. @@ -196,33 +157,33 @@ The USDSTABLE will be the USD address used for the StableSwapModule. You may kee DEXFactory refers to the factory address of UniswapV2 fork. In this deployment, you can use the FathomSwap factory address provided above, or you can use your own factory address if you prefer. DEXFactory address was used for the priceOracle and priceFeed that use a DEX as the source of truth, but the default deployment setting does not use the address -#### 4) Compile contracts +#### 2) Compile contracts ```bash -$ coralX compile +$ npm run compile ``` make sure that the contracts compile before deployment -#### 5) Deploy with below command +#### 3) Deploy with below command ```bash -$ coralX scenario --run deployApothem +$ npm run deploy-apothem ``` -#### 6) Check contract addresses in addresses.json file in root +#### 4) Check contract addresses in addresses.json file in root After deployment, addresses.json gets updated with addresses of proxies. ### On XDC mainnet (chainID 50) -#### 1) Create file called "privateKey" in the root directory (PRIVATE_KEY_WITHOUT_0x_PREFIX of the EOA that you would like to deploy contracts from): +#### 0) Create SEED_PHRASE environment variable: ```bash -$ echo -n PRIVATE_KEY_WITHOUT_0x_PREFIX > privateKey +$ echo -n SEED_PHRASE=12_WORD_MNEMONIC > .env ``` -#### 2) Create externalAddresses.json in root directory.: +#### 1) Create externalAddresses.json in root directory.: ChainID of XDC mainnet is 50. Therefore, the externalAddresses.json need to have the sets of addresses having 51 as key. For example, like below. @@ -245,21 +206,21 @@ The USDSTABLE will be the USD address used for the StableSwapModule. You may kee DEXFactory refers to the factory address of UniswapV2. In this deployment, you can find and use the FathomSwap factory address or you can use your own factory address if you prefer. DEXFactory address was used for the priceOracle and priceFeed that use a DEX as the source of truth, but the default deployment setting does not use this address. -#### 4) Compile contracts +#### 2) Compile contracts ```bash -$ coralX compile +$ npm run compile ``` make sure that the contracts compile before deployment -#### 5) Deploy with below command +#### 3) Deploy with below command ```bash -$ coralX scenario --run deployMainnet +$ npm run deploy-mainnet ``` -#### 6) Check contract addresses in addresses.json file in root +#### 4) Check contract addresses in addresses.json file in root After deployment, addresses.json gets updated with addresses of proxies. @@ -321,7 +282,7 @@ Line 5~6 verifies the solvency of the new priceFeed. New priceFeed must have poo can be initialized with script below ``` -scripts/migrations/priceFeed/1_initialize.js +tasks/price-feed.js ``` #### To run the script with DEX as the price source, ensure that: @@ -334,7 +295,7 @@ The default PriceOracle for DelayFathomOraclePriceFeed is set as DexPriceOracle #### Run the init script with below command ```bash -$ coralX execute --path scripts/migrations/priceFeed/1_initialize.js +$ npx hardhat price-feed --proxyFactoryAddress "Address of FathomProxyFactory contract" ``` ### DEX price feed info diff --git a/coralX-scenarios.js b/coralX-scenarios.js deleted file mode 100644 index fab0d3c3..00000000 --- a/coralX-scenarios.js +++ /dev/null @@ -1,28 +0,0 @@ -module.exports = { - deployLocal: [ - ["execute", "--path", "scripts/migrations/deployment", "--network", "development"], - ["execute", "--path", "scripts/migrations/configuration", "--network", "development"], - ], - deployMainnet: [ - ["execute", "--path", "scripts/migrations/deployment", "--network", "mainnet"], - ["execute", "--path", "scripts/migrations/configuration", "--network", "mainnet"], - ], - deployApothem: [ - ["execute", "--path", "scripts/migrations/deployment", "--network", "apothem"], - ["execute", "--path", "scripts/migrations/configuration", "--network", "apothem"], - ], - - deployTokensLocal: [["execute", "--path", "scripts/migrations/collateral-tokens", "--network", "development"]], - deployTokensApothem: [["execute", "--path", "scripts/migrations/collateral-tokens", "--network", "apothem"]], - migrateAndConfigureForTests: [ - ["compile"], - ["execute", "--path", "scripts/migrations/test/pre-deployment"], - ["execute", "--path", "scripts/migrations/deployment"], - ["execute", "--path", "scripts/migrations/test/configuration"], - ["execute", "--path", "scripts/migrations/test/post-deployment"], - // add new collateral flow - ["execute", "--path", "scripts/migrations/test/add-collateral/pre-deployment"], - ["execute", "--path", "scripts/migrations/add-collateral/deployment"], - ["execute", "--path", "scripts/migrations/test/add-collateral/configuration"], - ], -}; diff --git a/deploy/deploy-add-collateral/01_deploy_add_collateral.js b/deploy/deploy-add-collateral/01_deploy_add_collateral.js index 2e67e908..fc75ed51 100644 --- a/deploy/deploy-add-collateral/01_deploy_add_collateral.js +++ b/deploy/deploy-add-collateral/01_deploy_add_collateral.js @@ -20,4 +20,4 @@ module.exports = async ({ getNamedAccounts, deployments, getChainId }) => { await configPool(getChainId); }; -module.exports.tags = ["DeployAddCollateral"]; \ No newline at end of file +module.exports.tags = ["DeployAddCollateral"]; diff --git a/deploy/deploy-main/01_deploy.js b/deploy/deploy-main/01_deploy.js index 73b25941..6af23e32 100644 --- a/deploy/deploy-main/01_deploy.js +++ b/deploy/deploy-main/01_deploy.js @@ -28,4 +28,4 @@ module.exports = async ({ getNamedAccounts, deployments, getChainId }) => { await addCollateralPools(deployments, getChainId); }; -module.exports.tags = ["DeployMain"]; \ No newline at end of file +module.exports.tags = ["DeployMain"]; diff --git a/deploy/deploy-test-fixture/01_deploy_test_fixture.js b/deploy/deploy-test-fixture/01_deploy_test_fixture.js index 3df04a67..13d921a4 100644 --- a/deploy/deploy-test-fixture/01_deploy_test_fixture.js +++ b/deploy/deploy-test-fixture/01_deploy_test_fixture.js @@ -65,4 +65,4 @@ module.exports = async ({ getNamedAccounts, deployments, getChainId }) => { await addCollateralConfigPool(deployments, getChainId); }; -module.exports.tags = ["DeployTestFixture"]; \ No newline at end of file +module.exports.tags = ["DeployTestFixture"]; diff --git a/deploy/deploy-tokens/01_deploy_tokens.js b/deploy/deploy-tokens/01_deploy_tokens.js index cacc43a0..14e0b88e 100644 --- a/deploy/deploy-tokens/01_deploy_tokens.js +++ b/deploy/deploy-tokens/01_deploy_tokens.js @@ -36,4 +36,4 @@ module.exports = async ({ getNamedAccounts, deployments }) => { await fthm.mint(deployer, BigNumber.from("10000000000000000000000000000")); }; -module.exports.tags = ["DeployTokens"]; \ No newline at end of file +module.exports.tags = ["DeployTokens"]; diff --git a/package.json b/package.json index d1369425..6a1c6dc8 100644 --- a/package.json +++ b/package.json @@ -5,21 +5,18 @@ "main": "", "directories": {}, "scripts": { - "format": "prettier --write .", - "test": "coralX test", - "test-with-timeout": "coralX test --params TIMEOUT=100000", - "test-skip-compile": "coralX test skip_compile true", - "test-use-snapshot": "coralX test skip_compile true use_snapshot true", - "compile": "npm run prettier && npm run lint && coralX compile", - "prettier": "prettier --write 'contracts/**/*.sol'", "lint": "solhint 'contracts/**/*.sol'", - "pre-release": "npm run prettier && npm run lint && npm run test-with-timeout", - "migrate-reset": "rm -rf build/contracts && rm -rf build/job-logs && coralX compile && coralX scenario --run migrateAndConfigureForTests", - "migrate-reset-local": "rm -rf build/contracts && rm -rf build/job-logs && coralX compile && coralX scenario --run deployLocal", - "migrate-reset-apothem": "rm -rf build/contracts && rm -rf build/job-logs && coralX compile && coralX scenario --run deployApothem", - "migrate-reset-mainnet": "rm -rf build/contracts && rm -rf build/job-logs && coralX compile && coralX scenario --run deployMainNet", - "deploy-tokens-local": "coralX scenario --run deployTokensLocal", - "deploy-tokens-apothem": "coralX scenario --run deployTokensApothem" + "lint:fix": "solhint 'contracts/**/*.sol' --fix", + "format": "prettier --write .", + "compile": "hardhat compile", + "test": "hardhat test", + "node": "hardhat node --tags DeployMain", + "pre-release": "npm run format && npm run lint && npm run test", + "deploy-local": "hardhat deploy --deploy-scripts deploy/deploy-main --network hardhat", + "deploy-apothem": "hardhat deploy --deploy-scripts deploy/deploy-main --network apothem", + "deploy-mainnet": "hardhat deploy --deploy-scripts deploy/deploy-main --network xdc", + "deploy-tokens-local": "hardhat deploy --deploy-scripts deploy/deploy-tokens --network hardhat", + "deploy-tokens-apothem": "hardhat deploy --deploy-scripts deploy/deploy-tokens --network apothem" }, "author": "", "license": "", diff --git a/scripts/configuration/add-collateral/configPool.js b/scripts/configuration/add-collateral/configPool.js index d737caea..da9a7944 100644 --- a/scripts/configuration/add-collateral/configPool.js +++ b/scripts/configuration/add-collateral/configPool.js @@ -42,9 +42,9 @@ async function configPool(getChainId) { CLOSE_FACTOR_BPS.mul(2), LIQUIDATOR_INCENTIVE_BPS, TREASURY_FEE_BPS, - fixedSpreadLiquidationStrategy.address, + fixedSpreadLiquidationStrategy.address ); await priceOracle.setPrice(poolId); } -module.exports = { configPool }; \ No newline at end of file +module.exports = { configPool }; diff --git a/scripts/configuration/deploy-test-fixture/addCollateralConfigPool.js b/scripts/configuration/deploy-test-fixture/addCollateralConfigPool.js index 109156e4..d3bed850 100644 --- a/scripts/configuration/deploy-test-fixture/addCollateralConfigPool.js +++ b/scripts/configuration/deploy-test-fixture/addCollateralConfigPool.js @@ -16,7 +16,6 @@ const DEBT_CEILING = WeiPerRad.mul(10000000).div(2); const { getProxyId, poolId } = require("../../../common/add-collateral-helper"); async function addCollateralConfigPool(deployments, getChainId) { - const ProxyFactory = await deployments.get("FathomProxyFactory"); const proxyFactory = await ethers.getContractAt("FathomProxyFactory", ProxyFactory.address); @@ -25,13 +24,13 @@ async function addCollateralConfigPool(deployments, getChainId) { const collateralPoolConfig = await getProxy(proxyFactory, "CollateralPoolConfig"); const priceOracle = await getProxy(proxyFactory, "PriceOracle"); const accessControlConfig = await getProxy(proxyFactory, "AccessControlConfig"); - + const TestOracleMock = await deployments.get("TestOracleMock"); const CentralizedOraclePriceFeed = await getProxy(proxyFactory, "CentralizedOraclePriceFeed"); await CentralizedOraclePriceFeed.initialize(TestOracleMock.address, accessControlConfig.address, poolId); const simplePriceFeed = await getProxy(proxyFactory, "SimplePriceFeed"); - + const priceFeed = simplePriceFeed; await simplePriceFeed.setPrice(WeiPerWad.toString()); await simplePriceFeed.setPoolId(poolId); @@ -50,7 +49,7 @@ async function addCollateralConfigPool(deployments, getChainId) { CLOSE_FACTOR_BPS.mul(2), LIQUIDATOR_INCENTIVE_BPS, TREASURY_FEE_BPS, - fixedSpreadLiquidationStrategy.address, + fixedSpreadLiquidationStrategy.address ); await priceOracle.setPrice(poolId); @@ -58,4 +57,4 @@ async function addCollateralConfigPool(deployments, getChainId) { module.exports = { addCollateralConfigPool, -}; \ No newline at end of file +}; diff --git a/scripts/configuration/deploy-test-fixture/addCollateralPools.js b/scripts/configuration/deploy-test-fixture/addCollateralPools.js index de1a9eaf..92e7631a 100644 --- a/scripts/configuration/deploy-test-fixture/addCollateralPools.js +++ b/scripts/configuration/deploy-test-fixture/addCollateralPools.js @@ -65,4 +65,4 @@ async function addCollateralPools(deployments) { module.exports = { addCollateralPools, -}; \ No newline at end of file +}; diff --git a/scripts/configuration/deploy-test-fixture/addCollateralPoolsPostDeployment.js b/scripts/configuration/deploy-test-fixture/addCollateralPoolsPostDeployment.js index 280e8deb..eed41fc8 100644 --- a/scripts/configuration/deploy-test-fixture/addCollateralPoolsPostDeployment.js +++ b/scripts/configuration/deploy-test-fixture/addCollateralPoolsPostDeployment.js @@ -62,4 +62,4 @@ async function addCollateralPoolsPostDeployment(deployments) { module.exports = { addCollateralPoolsPostDeployment, -}; \ No newline at end of file +}; diff --git a/scripts/configuration/deploy-test-fixture/addRoles.js b/scripts/configuration/deploy-test-fixture/addRoles.js index f248409b..dddf28cc 100644 --- a/scripts/configuration/deploy-test-fixture/addRoles.js +++ b/scripts/configuration/deploy-test-fixture/addRoles.js @@ -26,4 +26,4 @@ async function addRoles(getNamedAccounts, deployments) { module.exports = { addRoles, -}; \ No newline at end of file +}; diff --git a/scripts/configuration/deploy-test-fixture/addRolesPostDeployment.js b/scripts/configuration/deploy-test-fixture/addRolesPostDeployment.js index 628d9bfd..6af20f7a 100644 --- a/scripts/configuration/deploy-test-fixture/addRolesPostDeployment.js +++ b/scripts/configuration/deploy-test-fixture/addRolesPostDeployment.js @@ -23,4 +23,4 @@ async function addRolesPostDeployment(deployments) { module.exports = { addRolesPostDeployment, -}; \ No newline at end of file +}; diff --git a/scripts/configuration/deploy/addCollateralPools.js b/scripts/configuration/deploy/addCollateralPools.js index a04bff12..908cfe12 100644 --- a/scripts/configuration/deploy/addCollateralPools.js +++ b/scripts/configuration/deploy/addCollateralPools.js @@ -19,7 +19,7 @@ async function addCollateralPools(deployments, getChainId) { const ProxyFactory = await deployments.get("FathomProxyFactory"); const proxyFactory = await ethers.getContractAt("FathomProxyFactory", ProxyFactory.address); - + const fixedSpreadLiquidationStrategy = await getProxy(proxyFactory, "FixedSpreadLiquidationStrategy"); const bookKeeper = await getProxy(proxyFactory, "BookKeeper"); const collateralPoolConfig = await getProxy(proxyFactory, "CollateralPoolConfig"); @@ -30,7 +30,7 @@ async function addCollateralPools(deployments, getChainId) { const debtCeilingSetUpTotal = WeiPerRad.mul(10000000); const debtCeilingSetUp = WeiPerRad.mul(10000000).div(2); - + // initial collateral price as 1 USD await simplePriceFeed.setPrice(WeiPerWad.toString()); await simplePriceFeed.setPoolId(pools.XDC); @@ -67,4 +67,4 @@ async function addCollateralPools(deployments, getChainId) { module.exports = { addCollateralPools, -}; \ No newline at end of file +}; diff --git a/scripts/migrations/add-collateral/configuration/1_config-pool.js b/scripts/migrations/add-collateral/configuration/1_config-pool.js deleted file mode 100644 index 66fc5499..00000000 --- a/scripts/migrations/add-collateral/configuration/1_config-pool.js +++ /dev/null @@ -1,47 +0,0 @@ -const { getProxy, getProxyById } = require("../../../common/proxies"); - -const { BigNumber } = require("ethers"); -const WeiPerRay = BigNumber.from(`1${"0".repeat(27)}`); -const WeiPerRad = BigNumber.from(`1${"0".repeat(45)}`); - -const CLOSE_FACTOR_BPS = BigNumber.from(2500); // <- 0.25 -const LIQUIDATOR_INCENTIVE_BPS = BigNumber.from(10500); // <- 1.05 -const TREASURY_FEE_BPS = BigNumber.from(8000); // <- 0.8 -const STABILITY_FEE = BigNumber.from("1000000000627937192491029811"); -const LIQUIDATIONRATIO_75 = WeiPerRay.mul(133).div(100).toString(); // LTV 75% -const DEBT_CEILING = WeiPerRad.mul(10000000).div(2); - -const { getConfig, getProxyId, poolId } = require("../../../common/add-collateral-helper"); - -module.exports = async function (deployer) { - const config = getConfig(deployer.networkId()); - - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", config.fathomProxyFactory); - const collateralTokenAdapter = await getProxyById(proxyFactory, "CollateralTokenAdapter", getProxyId("CollateralTokenAdapter")); - const fixedSpreadLiquidationStrategy = await getProxy(proxyFactory, "FixedSpreadLiquidationStrategy"); - const collateralPoolConfig = await getProxy(proxyFactory, "CollateralPoolConfig"); - const priceOracle = await getProxy(proxyFactory, "PriceOracle"); - const simplePriceFeed = await getProxy(proxyFactory, "SimplePriceFeed"); - - const priceFeed = simplePriceFeed; - - await priceFeed.peekPrice({ gasLimit: 2000000 }); - - await collateralPoolConfig.initCollateralPool( - poolId, - DEBT_CEILING, - 0, - WeiPerRad.mul(50000), - priceFeed.address, - LIQUIDATIONRATIO_75, - STABILITY_FEE, - collateralTokenAdapter.address, - CLOSE_FACTOR_BPS.mul(2), - LIQUIDATOR_INCENTIVE_BPS, - TREASURY_FEE_BPS, - fixedSpreadLiquidationStrategy.address, - { gas: 5000000 } - ); - - await priceOracle.setPrice(poolId, { gasLimit: 2000000 }); -}; diff --git a/scripts/migrations/add-collateral/deployment/1_deploy.js b/scripts/migrations/add-collateral/deployment/1_deploy.js deleted file mode 100644 index 28bd0687..00000000 --- a/scripts/migrations/add-collateral/deployment/1_deploy.js +++ /dev/null @@ -1,22 +0,0 @@ -const DexPriceOracle = artifacts.require("DexPriceOracle.sol"); -const SlidingWindowDexOracle = artifacts.require("SlidingWindowDexOracle.sol"); -const DelayFathomOraclePriceFeed = artifacts.require("DelayFathomOraclePriceFeed.sol"); -const CollateralTokenAdapter = artifacts.require("CollateralTokenAdapter.sol"); -const CentralizedOraclePriceFeed = artifacts.require("CentralizedOraclePriceFeed.sol"); - -const { usePlugin } = require("../../../common/add-collateral-helper"); - -module.exports = async function (deployer) { - let promises = [ - deployer.deploy(DexPriceOracle, { gas: 7050000 }), - deployer.deploy(DelayFathomOraclePriceFeed, { gas: 7050000 }), - deployer.deploy(CollateralTokenAdapter, { gas: 7050000 }), - deployer.deploy(SlidingWindowDexOracle, { gas: 7050000 }), - ]; - - if (usePlugin(deployer.networkId())) { - promises.push(deployer.deploy(CentralizedOraclePriceFeed, { gas: 7050000 })); - } - - await Promise.all(promises); -}; diff --git a/scripts/migrations/add-collateral/deployment/2_deployProxies.js b/scripts/migrations/add-collateral/deployment/2_deployProxies.js deleted file mode 100644 index d32b0a03..00000000 --- a/scripts/migrations/add-collateral/deployment/2_deployProxies.js +++ /dev/null @@ -1,18 +0,0 @@ -const { getConfig, getProxyId, token } = require("../../../common/add-collateral-helper"); - -module.exports = async function (deployer) { - const config = getConfig(deployer.networkId()); - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", config.fathomProxyFactory); - const proxyAdmin = await artifacts.initializeInterfaceAt("FathomProxyAdmin", config.fathomProxyAdmin); - - const contracts = ["DelayFathomOraclePriceFeed", "DexPriceOracle", "CollateralTokenAdapter", "SlidingWindowDexOracle"]; - - contracts.push("CentralizedOraclePriceFeed"); - - const promises = contracts.map((contract) => { - const instance = artifacts.require(`${contract}.sol`); - return proxyFactory.createProxy(getProxyId(contract), instance.address, proxyAdmin.address, "0x", { gasLimit: 2000000 }); - }); - - await Promise.all(promises); -}; diff --git a/scripts/migrations/add-collateral/deployment/3_initialize.js b/scripts/migrations/add-collateral/deployment/3_initialize.js deleted file mode 100644 index ced62106..00000000 --- a/scripts/migrations/add-collateral/deployment/3_initialize.js +++ /dev/null @@ -1,38 +0,0 @@ -const fs = require("fs"); - -const { getAddresses } = require("../../../common/addresses"); -const { getProxy, getProxyById } = require("../../../common/proxies"); - -const { getConfig, getProxyId, token, poolId } = require("../../../common/add-collateral-helper"); - -module.exports = async function (deployer) { - const config = getConfig(deployer.networkId()); - const addresses = getAddresses(deployer.networkId()); - - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", config.fathomProxyFactory); - - const proxyWalletFactory = await getProxy(proxyFactory, "ProxyWalletFactory"); - const positionManager = await getProxy(proxyFactory, "PositionManager"); - const bookKeeper = await getProxy(proxyFactory, "BookKeeper"); - const accessControlConfig = await getProxy(proxyFactory, "AccessControlConfig"); - - const delayFathomOraclePriceFeed = await getProxyById(proxyFactory, "DelayFathomOraclePriceFeed", getProxyId("DelayFathomOraclePriceFeed")); - const dexPriceOracle = await getProxyById(proxyFactory, "DexPriceOracle", getProxyId("DexPriceOracle")); - const collateralTokenAdapter = await getProxyById(proxyFactory, "CollateralTokenAdapter", getProxyId("CollateralTokenAdapter")); - - const newAddresses = { - dexPriceOracle: dexPriceOracle.address, - collateralTokenAdapter: collateralTokenAdapter.address, - delayFathomOraclePriceFeed: delayFathomOraclePriceFeed.address, - }; - - const promises = [ - dexPriceOracle.initialize(addresses.DEXFactory, { gasLimit: 1000000 }), - collateralTokenAdapter.initialize(bookKeeper.address, poolId, config.tokenAddress, proxyWalletFactory.address), - delayFathomOraclePriceFeed.initialize(dexPriceOracle.address, config.tokenAddress, addresses.USD, accessControlConfig.address, poolId), - ]; - - await Promise.all(promises); - - fs.writeFileSync(`./addresses_${token}.json`, JSON.stringify(newAddresses)); -}; diff --git a/scripts/migrations/add-collateral/deployment/4_add-roles.js b/scripts/migrations/add-collateral/deployment/4_add-roles.js deleted file mode 100644 index 562908a9..00000000 --- a/scripts/migrations/add-collateral/deployment/4_add-roles.js +++ /dev/null @@ -1,22 +0,0 @@ -const { getProxy, getProxyById } = require("../../../common/proxies"); -const { getConfig, getProxyId } = require("../../../common/add-collateral-helper"); - -module.exports = async function (deployer) { - const config = getConfig(deployer.networkId()); - - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", config.fathomProxyFactory); - - const fixedSpreadLiquidationStrategy = await getProxy(proxyFactory, "FixedSpreadLiquidationStrategy"); - const showStopper = await getProxy(proxyFactory, "ShowStopper"); - const positionManager = await getProxy(proxyFactory, "PositionManager"); - const liquidationEngine = await getProxy(proxyFactory, "LiquidationEngine"); - const accessControlConfig = await getProxy(proxyFactory, "AccessControlConfig"); - const collateralTokenAdapter = await getProxyById(proxyFactory, "CollateralTokenAdapter", getProxyId("CollateralTokenAdapter")); - - await accessControlConfig.grantRole(accessControlConfig.ADAPTER_ROLE(), collateralTokenAdapter.address); - - await collateralTokenAdapter.addToWhitelist(positionManager.address, { gasLimit: 1000000 }); - await collateralTokenAdapter.addToWhitelist(fixedSpreadLiquidationStrategy.address, { gasLimit: 1000000 }); - await collateralTokenAdapter.addToWhitelist(liquidationEngine.address, { gasLimit: 1000000 }); - await collateralTokenAdapter.addToWhitelist(showStopper.address, { gasLimit: 1000000 }); -}; diff --git a/scripts/migrations/add-collateral/deployment/5_deployVault.js b/scripts/migrations/add-collateral/deployment/5_deployVault.js deleted file mode 100644 index e2e2e839..00000000 --- a/scripts/migrations/add-collateral/deployment/5_deployVault.js +++ /dev/null @@ -1,16 +0,0 @@ -const Vault = artifacts.require("Vault.sol"); -const { getProxyById } = require("../../../common/proxies"); -const { formatBytes32String } = require("ethers/lib/utils"); -const { getConfig, getProxyId, token } = require("../../../common/add-collateral-helper"); -const { getAddresses } = require("../../../common/addresses"); - -module.exports = async function (deployer) { - const config = getConfig(deployer.networkId()); - const addresses = getAddresses(deployer.networkId()); - - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", config.fathomProxyFactory); - const collateralTokenAdapter = await getProxyById(proxyFactory, "CollateralTokenAdapter", getProxyId("CollateralTokenAdapter")); - - await deployer.deploy(Vault, formatBytes32String(token), config.tokenAddress, collateralTokenAdapter.address, { gas: 7050000 }); - await collateralTokenAdapter.setVault(Vault.address); -}; diff --git a/scripts/migrations/collateral-tokens/1_deploy-tokens.js b/scripts/migrations/collateral-tokens/1_deploy-tokens.js deleted file mode 100644 index f33ee9f3..00000000 --- a/scripts/migrations/collateral-tokens/1_deploy-tokens.js +++ /dev/null @@ -1,21 +0,0 @@ -const ERC20 = artifacts.require("ERC20Mintable.sol"); -const { BigNumber } = require("ethers"); - -const addresses = require("../../common/addresses"); - -module.exports = async function (deployer) { - await deployer.deploy(ERC20, "WXDC", "WXDC", { gas: 3050000 }); - const wxdc = await artifacts.initializeInterfaceAt("ERC20Mintable", "ERC20Mintable"); - await deployer.deploy(ERC20, "USDT", "USDT", { gas: 3050000 }); - const usdc = await artifacts.initializeInterfaceAt("ERC20Mintable", "ERC20Mintable"); - await deployer.deploy(ERC20, "FTHM", "FTHM", { gas: 3050000 }); - const fthm = await artifacts.initializeInterfaceAt("ERC20Mintable", "ERC20Mintable"); - - await wxdc.mint(addresses.Deployer, BigNumber.from("10000000000000000000000000000"), { gasLimit: 1000000 }); - await usdc.mint(addresses.Deployer, BigNumber.from("10000000000000000000000000000"), { gasLimit: 1000000 }); - await fthm.mint(addresses.Deployer, BigNumber.from("10000000000000000000000000000"), { gasLimit: 1000000 }); - - console.log("WXDC: " + wxdc.address); - console.log("USDT: " + usdc.address); - console.log("FTHM: " + fthm.address); -}; diff --git a/scripts/migrations/configuration/1_add-collateral-pools.js b/scripts/migrations/configuration/1_add-collateral-pools.js deleted file mode 100644 index cee035be..00000000 --- a/scripts/migrations/configuration/1_add-collateral-pools.js +++ /dev/null @@ -1,61 +0,0 @@ -const pools = require("../../common/collateral"); -const { getAddresses } = require("../../common/addresses"); -const { getProxy } = require("../../common/proxies"); - -const { BigNumber } = require("ethers"); -const WeiPerWad = BigNumber.from(`1${"0".repeat(18)}`); -const WeiPerRay = BigNumber.from(`1${"0".repeat(27)}`); -const WeiPerRad = BigNumber.from(`1${"0".repeat(45)}`); - -const CLOSE_FACTOR_BPS = BigNumber.from(2500); // <- 0.25 -const LIQUIDATOR_INCENTIVE_BPS = BigNumber.from(10500); // <- 1.05 -const TREASURY_FEE_BPS = BigNumber.from(8000); // <- 0.8 -const STABILITY_FEE = BigNumber.from("1000000000627937192491029811"); -const LIQUIDATIONRATIO_75 = WeiPerRay.mul(133).div(100).toString(); // LTV 75% - -module.exports = async function (deployer) { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - - const fixedSpreadLiquidationStrategy = await getProxy(proxyFactory, "FixedSpreadLiquidationStrategy"); - const bookKeeper = await getProxy(proxyFactory, "BookKeeper"); - const collateralPoolConfig = await getProxy(proxyFactory, "CollateralPoolConfig"); - const priceOracle = await getProxy(proxyFactory, "PriceOracle"); - const simplePriceFeed = await getProxy(proxyFactory, "SimplePriceFeed"); - // const centralizedOraclePriceFeed = await getProxy(proxyFactory, "CentralizedOraclePriceFeed"); - const collateralTokenAdapter = await getProxy(proxyFactory, "CollateralTokenAdapter"); - - const debtCeilingSetUpTotal = WeiPerRad.mul(10000000); - const debtCeilingSetUp = WeiPerRad.mul(10000000).div(2); - - // initial collateral price as 1 USD - await simplePriceFeed.setPrice(WeiPerWad.toString()); - await simplePriceFeed.setPoolId(pools.XDC); - await simplePriceFeed.peekPrice(); - // await centralizedOraclePriceFeed.peekPrice({ gasLimit: 2000000 }); - - const promises = [initPool(pools.XDC, collateralTokenAdapter.address, simplePriceFeed.address, LIQUIDATIONRATIO_75)]; - - await Promise.all(promises); - - await bookKeeper.setTotalDebtCeiling(debtCeilingSetUpTotal, { gasLimit: 2000000 }); - - async function initPool(poolId, adapter, priceFeed, liquidationRatio) { - await collateralPoolConfig.initCollateralPool( - poolId, - debtCeilingSetUp, - 0, - WeiPerRad.mul(50000), - priceFeed, - liquidationRatio, - STABILITY_FEE, - adapter, - CLOSE_FACTOR_BPS.mul(2), - LIQUIDATOR_INCENTIVE_BPS, - TREASURY_FEE_BPS, - fixedSpreadLiquidationStrategy.address, - { gas: 5000000 } - ); - - await priceOracle.setPrice(poolId, { gasLimit: 2000000 }); - } -}; diff --git a/scripts/migrations/deployment/1_deploy.js b/scripts/migrations/deployment/1_deploy.js deleted file mode 100644 index a2d61c26..00000000 --- a/scripts/migrations/deployment/1_deploy.js +++ /dev/null @@ -1,69 +0,0 @@ -const AccessControlConfig = artifacts.require("AccessControlConfig.sol"); -const CollateralPoolConfig = artifacts.require("CollateralPoolConfig.sol"); -const BookKeeper = artifacts.require("BookKeeper.sol"); -const FathomStablecoin = artifacts.require("FathomStablecoin.sol"); -const SystemDebtEngine = artifacts.require("SystemDebtEngine.sol"); -const StableSwapModule = artifacts.require("StableSwapModule.sol"); -const DexPriceOracle = artifacts.require("DexPriceOracle.sol"); -const SlidingWindowDexOracle = artifacts.require("SlidingWindowDexOracle.sol"); -const ProxyWalletRegistry = artifacts.require("ProxyWalletRegistry.sol"); -const ProxyWalletFactory = artifacts.require("ProxyWalletFactory.sol"); -const StabilityFeeCollector = artifacts.require("StabilityFeeCollector.sol"); -const FathomStablecoinProxyActions = artifacts.require("FathomStablecoinProxyActions.sol"); -const FixedSpreadLiquidationStrategy = artifacts.require("FixedSpreadLiquidationStrategy.sol"); -const PositionManager = artifacts.require("PositionManager.sol"); -const ShowStopper = artifacts.require("ShowStopper.sol"); -const PriceOracle = artifacts.require("PriceOracle.sol"); -const StablecoinAdapter = artifacts.require("StablecoinAdapter.sol"); -const LiquidationEngine = artifacts.require("LiquidationEngine.sol"); -const FlashMintModule = artifacts.require("FlashMintModule.sol"); -const FlashMintArbitrager = artifacts.require("FlashMintArbitrager.sol"); -const BookKeeperFlashMintArbitrager = artifacts.require("BookKeeperFlashMintArbitrager.sol"); -const FathomProxyFactory = artifacts.require("FathomProxyFactory.sol"); -const FathomProxyAdmin = artifacts.require("FathomProxyAdmin.sol"); -const DelayFathomOraclePriceFeed = artifacts.require("DelayFathomOraclePriceFeed.sol"); -const CollateralTokenAdapter = artifacts.require("CollateralTokenAdapter.sol"); -const ProxyActionsStorage = artifacts.require("ProxyActionsStorage.sol"); -const AdminControls = artifacts.require("AdminControls.sol"); -const CentralizedOraclePriceFeed = artifacts.require("CentralizedOraclePriceFeed.sol"); -const StableSwapModuleWrapper = artifacts.require("StableSwapModuleWrapper.sol"); -const SimplePriceFeed = artifacts.require("SimplePriceFeed.sol"); -const FathomBridge = artifacts.require("FathomBridge.sol"); - -module.exports = async function (deployer) { - let promises = [ - deployer.deploy(AccessControlConfig, { gas: 7050000 }), - deployer.deploy(CollateralPoolConfig, { gas: 7050000 }), - deployer.deploy(BookKeeper, { gas: 7050000 }), - deployer.deploy(FathomStablecoin, { gas: 7050000 }), - deployer.deploy(SystemDebtEngine, { gas: 7050000 }), - deployer.deploy(LiquidationEngine, { gas: 7050000 }), - deployer.deploy(StablecoinAdapter, { gas: 7050000 }), - deployer.deploy(PriceOracle, { gas: 7050000 }), - deployer.deploy(ShowStopper, { gas: 7050000 }), - deployer.deploy(PositionManager, { gas: 7050000 }), - deployer.deploy(FixedSpreadLiquidationStrategy, { gas: 7050000 }), - deployer.deploy(FathomStablecoinProxyActions, { gas: 7050000 }), - deployer.deploy(StabilityFeeCollector, { gas: 7050000 }), - deployer.deploy(ProxyWalletFactory, { gas: 7050000 }), - deployer.deploy(ProxyWalletRegistry, { gas: 7050000 }), - deployer.deploy(DexPriceOracle, { gas: 7050000 }), - deployer.deploy(StableSwapModule, { gas: 7050000 }), - deployer.deploy(FlashMintModule, { gas: 7050000 }), - deployer.deploy(FlashMintArbitrager, { gas: 7050000 }), - deployer.deploy(BookKeeperFlashMintArbitrager, { gas: 7050000 }), - deployer.deploy(FathomProxyFactory, { gas: 7050000 }), - deployer.deploy(FathomProxyAdmin, { gas: 7050000 }), - deployer.deploy(DelayFathomOraclePriceFeed, { gas: 7050000 }), - deployer.deploy(CollateralTokenAdapter, { gas: 7050000 }), - deployer.deploy(ProxyActionsStorage, { gas: 7050000 }), - deployer.deploy(SlidingWindowDexOracle, { gas: 7050000 }), - deployer.deploy(AdminControls, { gas: 7050000 }), - deployer.deploy(CentralizedOraclePriceFeed, { gas: 7050000 }), - deployer.deploy(StableSwapModuleWrapper, { gas: 7050000 }), - deployer.deploy(SimplePriceFeed, { gas: 7050000 }), - deployer.deploy(FathomBridge, { gas: 7050000 }), - ]; - - await Promise.all(promises); -}; diff --git a/scripts/migrations/deployment/2_deployProxies.js b/scripts/migrations/deployment/2_deployProxies.js deleted file mode 100644 index 22ec05e3..00000000 --- a/scripts/migrations/deployment/2_deployProxies.js +++ /dev/null @@ -1,45 +0,0 @@ -const { formatBytes32String } = require("ethers/lib/utils"); - -const ProxyAdmin = artifacts.require("FathomProxyAdmin.sol"); - -module.exports = async function (deployer) { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - - const contracts = [ - "AccessControlConfig", - "CollateralPoolConfig", - "BookKeeper", - "FathomStablecoin", - "SystemDebtEngine", - "LiquidationEngine", - "StablecoinAdapter", - "PriceOracle", - "ShowStopper", - "PositionManager", - "FixedSpreadLiquidationStrategy", - "StabilityFeeCollector", - "ProxyWalletRegistry", - "ProxyWalletFactory", - "ProxyActionsStorage", - "FlashMintModule", - "StableSwapModule", - "FlashMintArbitrager", - "BookKeeperFlashMintArbitrager", - "DelayFathomOraclePriceFeed", - "DexPriceOracle", - "CollateralTokenAdapter", - "SlidingWindowDexOracle", - "AdminControls", - "CentralizedOraclePriceFeed", - "StableSwapModuleWrapper", - "SimplePriceFeed", - "FathomBridge", - ]; - - const promises = contracts.map((contract) => { - const instance = artifacts.require(contract + ".sol"); - return proxyFactory.createProxy(formatBytes32String(contract), instance.address, ProxyAdmin.address, "0x", { gasLimit: 2000000 }); - }); - - await Promise.all(promises); -}; diff --git a/scripts/migrations/deployment/3_initialize.js b/scripts/migrations/deployment/3_initialize.js deleted file mode 100644 index f00ab3ad..00000000 --- a/scripts/migrations/deployment/3_initialize.js +++ /dev/null @@ -1,146 +0,0 @@ -const fs = require("fs"); - -const pools = require("../../common/collateral"); -const { getAddresses } = require("../../common/addresses"); -const { getProxy } = require("../../common/proxies"); - -const FathomStablecoinProxyActions = artifacts.require("FathomStablecoinProxyActions.sol"); - -module.exports = async function (deployer) { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - const proxyAdmin = await artifacts.initializeInterfaceAt("FathomProxyAdmin", "FathomProxyAdmin"); - const fixedSpreadLiquidationStrategy = await getProxy(proxyFactory, "FixedSpreadLiquidationStrategy"); - const proxyWalletRegistry = await getProxy(proxyFactory, "ProxyWalletRegistry"); - const proxyWalletFactory = await getProxy(proxyFactory, "ProxyWalletFactory"); - const stabilityFeeCollector = await getProxy(proxyFactory, "StabilityFeeCollector"); - const stablecoinAdapter = await getProxy(proxyFactory, "StablecoinAdapter"); - const showStopper = await getProxy(proxyFactory, "ShowStopper"); - const priceOracle = await getProxy(proxyFactory, "PriceOracle"); - const fathomStablecoin = await getProxy(proxyFactory, "FathomStablecoin"); - const positionManager = await getProxy(proxyFactory, "PositionManager"); - const systemDebtEngine = await getProxy(proxyFactory, "SystemDebtEngine"); - const liquidationEngine = await getProxy(proxyFactory, "LiquidationEngine"); - const bookKeeper = await getProxy(proxyFactory, "BookKeeper"); - const collateralPoolConfig = await getProxy(proxyFactory, "CollateralPoolConfig"); - const accessControlConfig = await getProxy(proxyFactory, "AccessControlConfig"); - const flashMintModule = await getProxy(proxyFactory, "FlashMintModule"); - const stableSwapModule = await getProxy(proxyFactory, "StableSwapModule"); - const flashMintArbitrager = await getProxy(proxyFactory, "FlashMintArbitrager"); - const bookKeeperFlashMintArbitrager = await getProxy(proxyFactory, "BookKeeperFlashMintArbitrager"); - const delayFathomOraclePriceFeed = await getProxy(proxyFactory, "DelayFathomOraclePriceFeed"); - const dexPriceOracle = await getProxy(proxyFactory, "DexPriceOracle"); - const collateralTokenAdapter = await getProxy(proxyFactory, "CollateralTokenAdapter"); - const proxyActionsStorage = await getProxy(proxyFactory, "ProxyActionsStorage"); - const adminControls = await getProxy(proxyFactory, "AdminControls"); - const centralizedOraclePriceFeed = await getProxy(proxyFactory, "CentralizedOraclePriceFeed"); - const stableSwapModuleWrapper = await getProxy(proxyFactory, "StableSwapModuleWrapper"); - const simplePriceFeed = await getProxy(proxyFactory, "SimplePriceFeed"); - const slidingWindowDexOracle = await getProxy(proxyFactory, "SlidingWindowDexOracle"); - const fathomBridge = await getProxy(proxyFactory, "FathomBridge"); - - const fathomStablecoinProxyActions = await artifacts.initializeInterfaceAt("FathomStablecoinProxyActions", "FathomStablecoinProxyActions"); - - const addresses = getAddresses(deployer.networkId()); - const dailyLimitNumerator = 2000; //on denomination of 10000th, 2000/10000 = 20% - const singleSwapLimitNumerator = 100; ///on denomination of 10000th, 100/10000 = 1% - const numberOfSwapsLimitPerUser = 1; // number of swaps per user per limit period - const blocksPerLimit = 2; // blocks per limit period - - const promises = [ - accessControlConfig.initialize({ gasLimit: 1000000 }), - collateralPoolConfig.initialize(accessControlConfig.address, { gasLimit: 1000000 }), - bookKeeper.initialize(collateralPoolConfig.address, accessControlConfig.address, { gasLimit: 1000000 }), - fathomStablecoin.initialize("Fathom USD", "FXD", { gasLimit: 1000000 }), - systemDebtEngine.initialize(bookKeeper.address, { gasLimit: 1000000 }), - liquidationEngine.initialize(bookKeeper.address, systemDebtEngine.address, { gasLimit: 1500000 }), - stablecoinAdapter.initialize(bookKeeper.address, fathomStablecoin.address, { gasLimit: 1000000 }), - priceOracle.initialize(bookKeeper.address, { gasLimit: 1000000 }), - showStopper.initialize(bookKeeper.address, { gasLimit: 1000000 }), - positionManager.initialize(bookKeeper.address, showStopper.address, priceOracle.address, { gasLimit: 1000000 }), - fixedSpreadLiquidationStrategy.initialize( - bookKeeper.address, - priceOracle.address, - liquidationEngine.address, - systemDebtEngine.address, - stablecoinAdapter.address - ), - stabilityFeeCollector.initialize(bookKeeper.address, systemDebtEngine.address, { gaslimit: 4050000 }), - proxyActionsStorage.initialize(fathomStablecoinProxyActions.address, bookKeeper.address, { gasLimit: 1000000 }), - proxyWalletFactory.initialize(proxyActionsStorage.address, proxyWalletRegistry.address, { gasLimit: 1000000 }), - proxyWalletRegistry.initialize(proxyWalletFactory.address, bookKeeper.address, { gasLimit: 1000000 }), - flashMintModule.initialize(stablecoinAdapter.address, systemDebtEngine.address, { gasLimit: 1000000 }), - - stableSwapModule.initialize( - bookKeeper.address, - addresses.USDSTABLE, - fathomStablecoin.address, - dailyLimitNumerator, - singleSwapLimitNumerator, - numberOfSwapsLimitPerUser, - blocksPerLimit, - { gasLimit: 1000000 } - ), - flashMintArbitrager.initialize({ gasLimit: 1000000 }), - bookKeeperFlashMintArbitrager.initialize(fathomStablecoin.address, { gasLimit: 1000000 }), - // dexPriceOracle.initialize(addresses.DEXFactory, { gasLimit: 1000000 }), - collateralTokenAdapter.initialize(bookKeeper.address, pools.XDC, addresses.WXDC, proxyWalletFactory.address), - // delayFathomOraclePriceFeed.initialize( - // dexPriceOracle.address, - // addresses.WXDC, - // addresses.USD, - // accessControlConfig.address, - // pools.XDC - // ), - adminControls.initialize( - bookKeeper.address, - liquidationEngine.address, - priceOracle.address, - positionManager.address, - systemDebtEngine.address, - flashMintModule.address, - stablecoinAdapter.address - ), - // centralizedOraclePriceFeed.initialize(priceOracleAddress, accessControlConfig.address, pools.XDC), - stableSwapModuleWrapper.initialize(bookKeeper.address, stableSwapModule.address), - simplePriceFeed.initialize(accessControlConfig.address), - // slidingWindowDexOracle.initialize(addresses.DEXFactory, 1800, 15); - fathomBridge.initialize(addresses.AsterizmInitializerLib, fathomStablecoin.address, accessControlConfig.address), - ]; - - await Promise.all(promises); - - const newAddresses = { - proxyFactory: proxyFactory.address, - proxyAdmin: proxyAdmin.address, - fixedSpreadLiquidationStrategy: fixedSpreadLiquidationStrategy.address, - proxyWalletRegistry: proxyWalletRegistry.address, - stabilityFeeCollector: stabilityFeeCollector.address, - stablecoinAdapter: stablecoinAdapter.address, - showStopper: showStopper.address, - priceOracle: priceOracle.address, - fathomStablecoin: fathomStablecoin.address, - positionManager: positionManager.address, - systemDebtEngine: systemDebtEngine.address, - liquidationEngine: liquidationEngine.address, - bookKeeper: bookKeeper.address, - collateralPoolConfig: collateralPoolConfig.address, - accessControlConfig: accessControlConfig.address, - flashMintModule: flashMintModule.address, - stableSwapModule: stableSwapModule.address, - flashMintArbitrager: flashMintArbitrager.address, - bookKeeperFlashMintArbitrager: bookKeeperFlashMintArbitrager.address, - dexPriceOracle: dexPriceOracle.address, - proxyWalletFactory: proxyWalletFactory.address, - fathomStablecoinProxyActions: FathomStablecoinProxyActions.address, - collateralTokenAdapter: collateralTokenAdapter.address, - delayFathomOraclePriceFeed: delayFathomOraclePriceFeed.address, - adminControls: adminControls.address, - centralizedOraclePriceFeed: centralizedOraclePriceFeed.address, - proxyActionsStorage: proxyActionsStorage.address, - fathomProxyAdmin: proxyAdmin.address, - slidingWindowDexOracle: slidingWindowDexOracle.address, - fathomBridge: fathomBridge.address, - }; - - fs.writeFileSync("./addresses.json", JSON.stringify(newAddresses)); -}; diff --git a/scripts/migrations/deployment/4_add-roles.js b/scripts/migrations/deployment/4_add-roles.js deleted file mode 100644 index 2c9be6e7..00000000 --- a/scripts/migrations/deployment/4_add-roles.js +++ /dev/null @@ -1,62 +0,0 @@ -const { getProxy } = require("../../common/proxies"); -const pools = require("../../common/collateral"); - -module.exports = async function (deployer) { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - - const fixedSpreadLiquidationStrategy = await getProxy(proxyFactory, "FixedSpreadLiquidationStrategy"); - const stabilityFeeCollector = await getProxy(proxyFactory, "StabilityFeeCollector"); - const stablecoinAdapter = await getProxy(proxyFactory, "StablecoinAdapter"); - const showStopper = await getProxy(proxyFactory, "ShowStopper"); - const priceOracle = await getProxy(proxyFactory, "PriceOracle"); - const fathomStablecoin = await getProxy(proxyFactory, "FathomStablecoin"); - const positionManager = await getProxy(proxyFactory, "PositionManager"); - const liquidationEngine = await getProxy(proxyFactory, "LiquidationEngine"); - const bookKeeper = await getProxy(proxyFactory, "BookKeeper"); - const accessControlConfig = await getProxy(proxyFactory, "AccessControlConfig"); - const flashMintModule = await getProxy(proxyFactory, "FlashMintModule"); - const stableSwapModule = await getProxy(proxyFactory, "StableSwapModule"); - const collateralTokenAdapter = await getProxy(proxyFactory, "CollateralTokenAdapter"); - const systemDebtEngine = await getProxy(proxyFactory, "SystemDebtEngine"); - const adminControls = await getProxy(proxyFactory, "AdminControls"); - const fathomBridge = await getProxy(proxyFactory, "FathomBridge"); - - await accessControlConfig.grantRole(await accessControlConfig.BOOK_KEEPER_ROLE(), bookKeeper.address); - - await accessControlConfig.grantRole(await accessControlConfig.POSITION_MANAGER_ROLE(), positionManager.address); - await accessControlConfig.grantRole(await accessControlConfig.COLLATERAL_MANAGER_ROLE(), positionManager.address); - - await accessControlConfig.grantRole(await accessControlConfig.STABILITY_FEE_COLLECTOR_ROLE(), stabilityFeeCollector.address); - - await accessControlConfig.grantRole(await accessControlConfig.LIQUIDATION_ENGINE_ROLE(), liquidationEngine.address); - - await accessControlConfig.grantRole(await accessControlConfig.LIQUIDATION_ENGINE_ROLE(), fixedSpreadLiquidationStrategy.address); - await accessControlConfig.grantRole(await accessControlConfig.COLLATERAL_MANAGER_ROLE(), fixedSpreadLiquidationStrategy.address); - - await accessControlConfig.grantRole(await accessControlConfig.LIQUIDATION_ENGINE_ROLE(), showStopper.address); - await accessControlConfig.grantRole(await accessControlConfig.COLLATERAL_MANAGER_ROLE(), showStopper.address); - await accessControlConfig.grantRole(await accessControlConfig.SHOW_STOPPER_ROLE(), showStopper.address); - - await accessControlConfig.grantRole(await accessControlConfig.PRICE_ORACLE_ROLE(), priceOracle.address); - - await accessControlConfig.grantRole(accessControlConfig.ADAPTER_ROLE(), collateralTokenAdapter.address); - - await accessControlConfig.grantRole(await accessControlConfig.MINTABLE_ROLE(), flashMintModule.address); - - await accessControlConfig.grantRole(await accessControlConfig.POSITION_MANAGER_ROLE(), stableSwapModule.address); - await accessControlConfig.grantRole(await accessControlConfig.COLLATERAL_MANAGER_ROLE(), stableSwapModule.address); - - await accessControlConfig.grantRole(await accessControlConfig.COLLATERAL_MANAGER_ROLE(), systemDebtEngine.address); - - await fathomStablecoin.grantRole(await fathomStablecoin.MINTER_ROLE(), fathomBridge.address); - await fathomStablecoin.grantRole(await fathomStablecoin.MINTER_ROLE(), stablecoinAdapter.address); - - await accessControlConfig.grantRole(await accessControlConfig.GOV_ROLE(), adminControls.address); - - await bookKeeper.whitelist(stablecoinAdapter.address, { gasLimit: 1000000 }); - - await collateralTokenAdapter.addToWhitelist(positionManager.address, { gasLimit: 1000000 }); - await collateralTokenAdapter.addToWhitelist(fixedSpreadLiquidationStrategy.address, { gasLimit: 1000000 }); - await collateralTokenAdapter.addToWhitelist(liquidationEngine.address, { gasLimit: 1000000 }); - await collateralTokenAdapter.addToWhitelist(showStopper.address, { gasLimit: 1000000 }); -}; diff --git a/scripts/migrations/deployment/5_configure-fees.js b/scripts/migrations/deployment/5_configure-fees.js deleted file mode 100644 index 51d17d54..00000000 --- a/scripts/migrations/deployment/5_configure-fees.js +++ /dev/null @@ -1,22 +0,0 @@ -const { getProxy } = require("../../common/proxies"); - -const { BigNumber } = require("ethers"); -const WeiPerWad = BigNumber.from(`1${"0".repeat(18)}`); - -// [wad = 100%] -const SSM_FEE_IN = WeiPerWad.div(1000); -const SSM_FEE_OUT = WeiPerWad.div(1000); -const FMM_FEE = WeiPerWad.mul(4).div(1000); - -module.exports = async function (deployer) { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - - const stableSwapModule = await getProxy(proxyFactory, "StableSwapModule"); - const flashMintModule = await getProxy(proxyFactory, "FlashMintModule"); - - await stableSwapModule.setFeeIn(SSM_FEE_IN, { gasLimit: 1000000 }); - await stableSwapModule.setFeeOut(SSM_FEE_OUT, { gasLimit: 1000000 }); - - await flashMintModule.setFeeRate(FMM_FEE, { gasLimit: 1000000 }); - await flashMintModule.setMax(WeiPerWad.mul("1000000000"), { gasLimit: 1000000 }); -}; diff --git a/scripts/migrations/deployment/6_configure-show-stopper.js b/scripts/migrations/deployment/6_configure-show-stopper.js deleted file mode 100644 index c4cd0f20..00000000 --- a/scripts/migrations/deployment/6_configure-show-stopper.js +++ /dev/null @@ -1,16 +0,0 @@ -const { getProxy } = require("../../common/proxies"); - -module.exports = async function (deployer) { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - - const showStopper = await getProxy(proxyFactory, "ShowStopper"); - const bookKeeper = await getProxy(proxyFactory, "BookKeeper"); - const liquidationEngine = await getProxy(proxyFactory, "LiquidationEngine"); - const systemDebtEngine = await getProxy(proxyFactory, "SystemDebtEngine"); - const priceOracle = await getProxy(proxyFactory, "PriceOracle"); - - await showStopper.setBookKeeper(bookKeeper.address, { gasLimit: 1000000 }); - await showStopper.setLiquidationEngine(liquidationEngine.address, { gasLimit: 1000000 }); - await showStopper.setSystemDebtEngine(systemDebtEngine.address, { gasLimit: 1000000 }); - await showStopper.setPriceOracle(priceOracle.address, { gasLimit: 1000000 }); -}; diff --git a/scripts/migrations/deployment/7_deployVault.js b/scripts/migrations/deployment/7_deployVault.js deleted file mode 100644 index 3f0a1415..00000000 --- a/scripts/migrations/deployment/7_deployVault.js +++ /dev/null @@ -1,14 +0,0 @@ -const Vault = artifacts.require("Vault.sol"); -const { getAddresses } = require("../../common/addresses"); -const { getProxy } = require("../../common/proxies"); -const pools = require("../../common/collateral"); - -module.exports = async function (deployer) { - const addresses = getAddresses(deployer.networkId()); - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - const collateralTokenAdapter = await getProxy(proxyFactory, "CollateralTokenAdapter"); - - let promises = [deployer.deploy(Vault, pools.XDC, addresses.WXDC, collateralTokenAdapter.address, { gas: 7050000 })]; - - await Promise.all(promises); -}; diff --git a/scripts/migrations/deployment/8_initialize_collateralTokenAdapter.js b/scripts/migrations/deployment/8_initialize_collateralTokenAdapter.js deleted file mode 100644 index 1c80ad03..00000000 --- a/scripts/migrations/deployment/8_initialize_collateralTokenAdapter.js +++ /dev/null @@ -1,12 +0,0 @@ -const { getProxy } = require("../../common/proxies"); - -const Vault = artifacts.require("Vault.sol"); - -module.exports = async function (deployer) { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - const collateralTokenAdapter = await getProxy(proxyFactory, "CollateralTokenAdapter"); - - const promises = [collateralTokenAdapter.setVault(Vault.address)]; - - await Promise.all(promises); -}; diff --git a/scripts/migrations/deployment/9_configure-flash-lending.js b/scripts/migrations/deployment/9_configure-flash-lending.js deleted file mode 100644 index 8c25553b..00000000 --- a/scripts/migrations/deployment/9_configure-flash-lending.js +++ /dev/null @@ -1,9 +0,0 @@ -const { getProxy } = require("../../common/proxies"); - -module.exports = async function (deployer) { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - - const fixedSpreadLiquidationStrategy = await getProxy(proxyFactory, "FixedSpreadLiquidationStrategy"); - - await fixedSpreadLiquidationStrategy.setFlashLendingEnabled(true, { gasLimit: 1000000 }); -}; diff --git a/scripts/migrations/fathom-solidity-sdk/1_deploy.js b/scripts/migrations/fathom-solidity-sdk/1_deploy.js deleted file mode 100644 index a6b31e3d..00000000 --- a/scripts/migrations/fathom-solidity-sdk/1_deploy.js +++ /dev/null @@ -1,35 +0,0 @@ -const fs = require("fs"); -const pools = require("../../common/collateral"); - -const rawdata = fs.readFileSync("../../../addresses.json"); -const addresses = JSON.parse(rawdata); - -const FathomProxyWalletOwner = artifacts.require("FathomProxyWalletOwner.sol"); - -const proxyWalletRegistry = addresses.proxyWalletRegistry; -const bookKeeper = addresses.bookKeeper; -const collateralPoolConfig = addresses.collateralPoolConfig; -const fathomStablecoin = addresses.fathomStablecoin; -const positionManager = addresses.positionManager; -const stabilityFeeCollector = addresses.stabilityFeeCollector; -const collateralTokenAdapter = addresses.collateralTokenAdapter; -const stablecoinAdapter = addresses.stablecoinAdapter; - -module.exports = async function (deployer) { - let promises = [ - deployer.deploy( - FathomProxyWalletOwner, - proxyWalletRegistry, - bookKeeper, - collateralPoolConfig, - fathomStablecoin, - positionManager, - stabilityFeeCollector, - collateralTokenAdapter, - stablecoinAdapter, - pools.XDC, - { gas: 7050000 } - ), - ]; - await Promise.all(promises); -}; diff --git a/scripts/migrations/priceFeed/1_initialize.js b/scripts/migrations/priceFeed/1_initialize.js deleted file mode 100644 index 7f6e5d8e..00000000 --- a/scripts/migrations/priceFeed/1_initialize.js +++ /dev/null @@ -1,25 +0,0 @@ -const fs = require("fs"); - -const pools = require("../../common/collateral"); -const { getAddresses } = require("../../common/addresses"); -const { getProxy } = require("../../common/proxies"); - -module.exports = async function (deployer) { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - const delayFathomOraclePriceFeed = await getProxy(proxyFactory, "DelayFathomOraclePriceFeed"); - const dexPriceOracle = await getProxy(proxyFactory, "DexPriceOracle"); - // const centralizedOraclePriceFeed = await getProxy(proxyFactory, "CentralizedOraclePriceFeed"); - const slidingWindowDexOracle = await getProxy(proxyFactory, "SlidingWindowDexOracle"); - const accessControlConfig = await getProxy(proxyFactory, "AccessControlConfig"); - - const addresses = getAddresses(deployer.networkId()); - - const promises = [ - dexPriceOracle.initialize(addresses.DEXFactory, { gasLimit: 1000000 }), - slidingWindowDexOracle.initialize(addresses.DEXFactory, 1800, 15), - delayFathomOraclePriceFeed.initialize(dexPriceOracle.address, addresses.WXDC, addresses.USD, accessControlConfig.address, pools.XDC), - // centralizedOraclePriceFeed.initialize(priceOracleAddress, accessControlConfig.address, pools.XDC), - ]; - - await Promise.all(promises); -}; diff --git a/scripts/migrations/test/add-collateral/configuration/1_config-pool.js b/scripts/migrations/test/add-collateral/configuration/1_config-pool.js deleted file mode 100644 index 5428b5c4..00000000 --- a/scripts/migrations/test/add-collateral/configuration/1_config-pool.js +++ /dev/null @@ -1,54 +0,0 @@ -const { getProxy, getProxyById } = require("../../../../common/proxies"); - -const { BigNumber } = require("ethers"); -const WeiPerWad = BigNumber.from(`1${"0".repeat(18)}`); -const WeiPerRay = BigNumber.from(`1${"0".repeat(27)}`); -const WeiPerRad = BigNumber.from(`1${"0".repeat(45)}`); - -const CLOSE_FACTOR_BPS = BigNumber.from(2500); // <- 0.25 -const LIQUIDATOR_INCENTIVE_BPS = BigNumber.from(10500); // <- 1.05 -const TREASURY_FEE_BPS = BigNumber.from(8000); // <- 0.8 -const STABILITY_FEE = BigNumber.from("1000000000627937192491029811"); -const LIQUIDATIONRATIO_75 = WeiPerRay.mul(133).div(100).toString(); // LTV 75% -const DEBT_CEILING = WeiPerRad.mul(10000000).div(2); - -const { getConfig, getProxyId, poolId } = require("../../../../common/add-collateral-helper"); - -module.exports = async function (deployer) { - const config = getConfig(deployer.networkId()); - - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", config.fathomProxyFactory); - const collateralTokenAdapter = await getProxyById(proxyFactory, "CollateralTokenAdapter", getProxyId("CollateralTokenAdapter")); - const fixedSpreadLiquidationStrategy = await getProxy(proxyFactory, "FixedSpreadLiquidationStrategy"); - const collateralPoolConfig = await getProxy(proxyFactory, "CollateralPoolConfig"); - const priceOracle = await getProxy(proxyFactory, "PriceOracle"); - const accessControlConfig = await getProxy(proxyFactory, "AccessControlConfig"); - const TestOracleMock = await artifacts.require("TestOracleMock"); - const CentralizedOraclePriceFeed = await getProxy(proxyFactory, "CentralizedOraclePriceFeed"); - await CentralizedOraclePriceFeed.initialize(TestOracleMock.address, accessControlConfig.address, poolId); - const simplePriceFeed = await getProxy(proxyFactory, "SimplePriceFeed"); - - const priceFeed = simplePriceFeed; - await simplePriceFeed.setPrice(WeiPerWad.toString()); - await simplePriceFeed.setPoolId(poolId); - - await priceFeed.peekPrice({ gasLimit: 2000000 }); - - await collateralPoolConfig.initCollateralPool( - poolId, - DEBT_CEILING, - 1, - WeiPerRad.mul(50000), - priceFeed.address, - WeiPerRay, - STABILITY_FEE, - collateralTokenAdapter.address, - CLOSE_FACTOR_BPS.mul(2), - LIQUIDATOR_INCENTIVE_BPS, - TREASURY_FEE_BPS, - fixedSpreadLiquidationStrategy.address, - { gas: 5000000 } - ); - - await priceOracle.setPrice(poolId, { gasLimit: 2000000 }); -}; diff --git a/scripts/migrations/test/add-collateral/pre-deployment/1_pre-deploy.js b/scripts/migrations/test/add-collateral/pre-deployment/1_pre-deploy.js deleted file mode 100644 index dc62cfab..00000000 --- a/scripts/migrations/test/add-collateral/pre-deployment/1_pre-deploy.js +++ /dev/null @@ -1,26 +0,0 @@ -const fs = require("fs"); -const { BigNumber } = require("ethers"); - -let addresses = JSON.parse(fs.readFileSync("../../../../../addresses.json")); -let addCollateral = JSON.parse(fs.readFileSync("../../../../../add-collateral.json")); - -const ERC20 = artifacts.require("ERC20Mintable.sol"); -const StableswapMultipleSwapsMock = artifacts.require("StableswapMultipleSwapsMock"); -const TestOracleMock = artifacts.require("TestOracleMock"); - -const WeiPerRay = BigNumber.from(`1${"0".repeat(27)}`); - -module.exports = async function (deployer) { - const promises = [deployer.deploy(ERC20, "GLD", "GLD", { gas: 3050000 }), deployer.deploy(TestOracleMock, WeiPerRay, { gas: 7050000 })]; - - await Promise.all(promises); - - const chainId = deployer.networkId(ERC20.address); - addCollateral[chainId].fathomProxyFactory = addresses.proxyFactory; - addCollateral[chainId].fathomProxyAdmin = addresses.proxyAdmin; - addCollateral[chainId].testOracle = TestOracleMock.address; - addCollateral[chainId].tokenAddress = ERC20.address; - - await deployer.deploy(StableswapMultipleSwapsMock, { gas: 3050000 }); - fs.writeFileSync("./add-collateral.json", JSON.stringify(addCollateral)); -}; diff --git a/scripts/migrations/test/configuration/1_add-roles.js b/scripts/migrations/test/configuration/1_add-roles.js deleted file mode 100644 index 45883b28..00000000 --- a/scripts/migrations/test/configuration/1_add-roles.js +++ /dev/null @@ -1,26 +0,0 @@ -const { getProxy } = require("../../../common/proxies"); -const pools = require("../../../common/collateral"); - -const DeployerWallet = "0x4C5F0f90a2D4b518aFba11E22AC9b8F6B031d204"; - -module.exports = async function (deployer) { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - - const fathomStablecoin = await getProxy(proxyFactory, "FathomStablecoin"); - const accessControlConfig = await getProxy(proxyFactory, "AccessControlConfig"); - const collateralTokenAdapter = await getProxy(proxyFactory, "CollateralTokenAdapter"); - const fixedSpreadLiquidationStrategy = await getProxy(proxyFactory, "FixedSpreadLiquidationStrategy"); - const stableSwap = await getProxy(proxyFactory, "StableSwapModule"); - const stableSwapModuleWrapper = await getProxy(proxyFactory, "StableSwapModuleWrapper"); - - await fathomStablecoin.grantRole(await fathomStablecoin.MINTER_ROLE(), DeployerWallet); - - await accessControlConfig.grantRole(await accessControlConfig.PRICE_ORACLE_ROLE(), DeployerWallet); - await accessControlConfig.grantRole(await accessControlConfig.OWNER_ROLE(), DeployerWallet); - - await accessControlConfig.grantRole(await accessControlConfig.MINTABLE_ROLE(), DeployerWallet); - - await stableSwap.addToWhitelist(DeployerWallet); - await stableSwapModuleWrapper.addToWhitelist(DeployerWallet); - await stableSwap.setStableSwapWrapper(stableSwapModuleWrapper.address, { gasLimit: 1000000 }); -}; diff --git a/scripts/migrations/test/configuration/2_add-collateral-pools.js b/scripts/migrations/test/configuration/2_add-collateral-pools.js deleted file mode 100644 index c078cb8e..00000000 --- a/scripts/migrations/test/configuration/2_add-collateral-pools.js +++ /dev/null @@ -1,58 +0,0 @@ -const pools = require("../../../common/collateral"); -const { getProxy } = require("../../../common/proxies"); - -const { BigNumber } = require("ethers"); -const WeiPerWad = BigNumber.from(`1${"0".repeat(18)}`); -const WeiPerRay = BigNumber.from(`1${"0".repeat(27)}`); -const WeiPerRad = BigNumber.from(`1${"0".repeat(45)}`); - -const CLOSE_FACTOR_BPS = BigNumber.from(2500); // <- 0.25 -const LIQUIDATOR_INCENTIVE_BPS = BigNumber.from(10500); // <- 1.05 -const TREASURY_FEE_BPS = BigNumber.from(8000); // <- 0.8 -const STABILITY_FEE = BigNumber.from("1000000000627937192491029811"); - -module.exports = async function (deployer) { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - const simplePriceFeed = await artifacts.initializeInterfaceAt("SimplePriceFeed", "SimplePriceFeed"); - - const accessControlConfig = await getProxy(proxyFactory, "AccessControlConfig"); - const fixedSpreadLiquidationStrategy = await getProxy(proxyFactory, "FixedSpreadLiquidationStrategy"); - const bookKeeper = await getProxy(proxyFactory, "BookKeeper"); - const collateralPoolConfig = await getProxy(proxyFactory, "CollateralPoolConfig"); - const priceOracle = await getProxy(proxyFactory, "PriceOracle"); - const collateralTokenAdapter = await getProxy(proxyFactory, "CollateralTokenAdapter"); - - await simplePriceFeed.initialize(accessControlConfig.address, { gasLimit: 5000000 }); - - const debtCeilingSetUpTotal = WeiPerRad.mul(100000000000000); - const debtCeilingSetUp = WeiPerRad.mul(100000000000000); - await simplePriceFeed.setPoolId(pools.XDC); - await simplePriceFeed.setPrice(WeiPerWad.mul(1), { gasLimit: 2000000 }); - await simplePriceFeed.setPoolId(pools.XDC, { gasLimit: 2000000 }); - - const promises = [initPool(pools.XDC, collateralTokenAdapter.address, simplePriceFeed.address, WeiPerRay)]; - - await Promise.all(promises); - - await bookKeeper.setTotalDebtCeiling(debtCeilingSetUpTotal, { gasLimit: 2000000 }); - - async function initPool(poolId, adapter, priceFeed, liquidationRatio) { - await collateralPoolConfig.initCollateralPool( - poolId, - debtCeilingSetUp, - 0, - WeiPerRad.mul(1000000), - priceFeed, - liquidationRatio, - STABILITY_FEE, - adapter, - CLOSE_FACTOR_BPS.mul(2), - LIQUIDATOR_INCENTIVE_BPS, - TREASURY_FEE_BPS, - fixedSpreadLiquidationStrategy.address, - { gas: 5000000 } - ); - - await priceOracle.setPrice(poolId, { gasLimit: 2000000 }); - } -}; diff --git a/scripts/migrations/test/post-deployment/1_deploy-mocks.js b/scripts/migrations/test/post-deployment/1_deploy-mocks.js deleted file mode 100644 index 5105e450..00000000 --- a/scripts/migrations/test/post-deployment/1_deploy-mocks.js +++ /dev/null @@ -1,48 +0,0 @@ -const { getAddresses } = require("../../../common/addresses"); -const { getProxy } = require("../../../common/proxies"); -const pools = require("../../../common/collateral"); - -module.exports = async function (deployer) { - const addresses = getAddresses(deployer.networkId()); - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - const bookKeeper = await getProxy(proxyFactory, "BookKeeper"); - const positionManager = await getProxy(proxyFactory, "PositionManager"); - const proxyWalletFactory = await getProxy(proxyFactory, "ProxyWalletFactory"); - const proxyWalletRegistry = await getProxy(proxyFactory, "ProxyWalletRegistry"); - const accessControlConfig = await getProxy(proxyFactory, "AccessControlConfig"); - - let MockSimplePriceFeed = artifacts.require("MockSimplePriceFeed.sol"); - let MockVault = artifacts.require("MockVault.sol"); - let MockCollateralTokenAdapter = artifacts.require("MockCollateralTokenAdapter.sol"); - let ReentrancyAttacker = artifacts.require("ReentrancyAttacker"); - let ReentrancyAttacker2 = artifacts.require("ReentrancyAttacker2"); - - //deploying a mockVault and mockColTokenAdapter to add one more collateral type - const promises0 = [ - deployer.deploy(MockCollateralTokenAdapter, { gas: 3050000 }), - deployer.deploy(MockSimplePriceFeed, { gas: 3050000 }), - deployer.deploy(ReentrancyAttacker, proxyWalletRegistry.address, { gas: 3050000 }), - deployer.deploy(ReentrancyAttacker2, proxyWalletRegistry.address, { gas: 3050000 }), - ]; - - await Promise.all(promises0); - - MockCollateralTokenAdapter = await artifacts.initializeInterfaceAt("MockCollateralTokenAdapter", "MockCollateralTokenAdapter"); - MockSimplePriceFeed = await artifacts.initializeInterfaceAt("MockSimplePriceFeed", "MockSimplePriceFeed"); - - const promises1 = [ - MockCollateralTokenAdapter.initialize(bookKeeper.address, pools.WXDC, addresses.WXDC, positionManager.address, proxyWalletFactory.address), - - deployer.deploy(MockVault, pools.WXDC, addresses.WXDC, MockCollateralTokenAdapter.address, { gas: 3050000 }), - ]; - - await Promise.all(promises1); - - MockVault = await artifacts.initializeInterfaceAt("MockVault", "MockVault"); - //giving ADAPTER_ROLE to MockCollateralTokenAdapter - await accessControlConfig.grantRole(accessControlConfig.ADAPTER_ROLE(), MockCollateralTokenAdapter.address); - - const promises2 = [MockCollateralTokenAdapter.setVault(MockVault.address)]; - - await Promise.all(promises2); -}; diff --git a/scripts/migrations/test/post-deployment/2_add-collateral-pools.js b/scripts/migrations/test/post-deployment/2_add-collateral-pools.js deleted file mode 100644 index 5558960f..00000000 --- a/scripts/migrations/test/post-deployment/2_add-collateral-pools.js +++ /dev/null @@ -1,58 +0,0 @@ -const pools = require("../../../common/collateral"); -const { getProxy } = require("../../../common/proxies"); - -const { BigNumber } = require("ethers"); -const WeiPerWad = BigNumber.from(`1${"0".repeat(18)}`); -const WeiPerRay = BigNumber.from(`1${"0".repeat(27)}`); -const WeiPerRad = BigNumber.from(`1${"0".repeat(45)}`); - -const CLOSE_FACTOR_BPS = BigNumber.from(2500); // <- 0.25 -const LIQUIDATOR_INCENTIVE_BPS = BigNumber.from(10500); // <- 1.05 -const TREASURY_FEE_BPS = BigNumber.from(8000); // <- 0.8 -const STABILITY_FEE = BigNumber.from("1000000000627937192491029811"); - -module.exports = async function (deployer) { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - const MockSimplePriceFeed = await artifacts.initializeInterfaceAt("MockSimplePriceFeed", "MockSimplePriceFeed"); - - const accessControlConfig = await getProxy(proxyFactory, "AccessControlConfig"); - const fixedSpreadLiquidationStrategy = await getProxy(proxyFactory, "FixedSpreadLiquidationStrategy"); - const bookKeeper = await getProxy(proxyFactory, "BookKeeper"); - const collateralPoolConfig = await getProxy(proxyFactory, "CollateralPoolConfig"); - const priceOracle = await getProxy(proxyFactory, "PriceOracle"); - const MockCollateralTokenAdapter = await artifacts.initializeInterfaceAt("MockCollateralTokenAdapter", "MockCollateralTokenAdapter"); - - await MockSimplePriceFeed.initialize(accessControlConfig.address, { gasLimit: 5000000 }); - - const debtCeilingSetUpTotal = WeiPerRad.mul(200000000000000); - const debtCeilingSetUp = WeiPerRad.mul(100000000000000); - await MockSimplePriceFeed.setPoolId(pools.WXDC); - await MockSimplePriceFeed.setPrice(WeiPerWad.mul(1), { gasLimit: 2000000 }); - await MockSimplePriceFeed.setPoolId(pools.WXDC, { gasLimit: 2000000 }); - - const promises = [initPool(pools.WXDC, MockCollateralTokenAdapter.address, MockSimplePriceFeed.address, WeiPerRay)]; - - await Promise.all(promises); - - await bookKeeper.setTotalDebtCeiling(debtCeilingSetUpTotal, { gasLimit: 2000000 }); - - async function initPool(poolId, adapter, priceFeed, liquidationRatio) { - await collateralPoolConfig.initCollateralPool( - poolId, - debtCeilingSetUp, - 0, - WeiPerRad.mul(50000), - priceFeed, - liquidationRatio, - STABILITY_FEE, - adapter, - CLOSE_FACTOR_BPS.mul(2), - LIQUIDATOR_INCENTIVE_BPS, - TREASURY_FEE_BPS, - fixedSpreadLiquidationStrategy.address, - { gas: 5000000 } - ); - - await priceOracle.setPrice(poolId, { gasLimit: 2000000 }); - } -}; diff --git a/scripts/migrations/test/post-deployment/3_add-roles.js b/scripts/migrations/test/post-deployment/3_add-roles.js deleted file mode 100644 index 55aa856b..00000000 --- a/scripts/migrations/test/post-deployment/3_add-roles.js +++ /dev/null @@ -1,18 +0,0 @@ -const { getProxy } = require("../../../common/proxies"); - -module.exports = async function (deployer) { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - const accessControlConfig = await getProxy(proxyFactory, "AccessControlConfig"); - const positionManager = await getProxy(proxyFactory, "PositionManager"); - const fixedSpreadLiquidationStrategy = await getProxy(proxyFactory, "FixedSpreadLiquidationStrategy"); - const liquidationEngine = await getProxy(proxyFactory, "LiquidationEngine"); - const showStopper = await getProxy(proxyFactory, "ShowStopper"); - - const MockCollateralTokenAdapter = await artifacts.initializeInterfaceAt("MockCollateralTokenAdapter", "MockCollateralTokenAdapter"); - await accessControlConfig.grantRole(accessControlConfig.ADAPTER_ROLE(), MockCollateralTokenAdapter.address); - - await MockCollateralTokenAdapter.addToWhitelist(positionManager.address, { gasLimit: 1000000 }); - await MockCollateralTokenAdapter.addToWhitelist(fixedSpreadLiquidationStrategy.address, { gasLimit: 1000000 }); - await MockCollateralTokenAdapter.addToWhitelist(liquidationEngine.address, { gasLimit: 1000000 }); - await MockCollateralTokenAdapter.addToWhitelist(showStopper.address, { gasLimit: 1000000 }); -}; diff --git a/scripts/migrations/test/pre-deployment/1_deploy-mocks.js b/scripts/migrations/test/pre-deployment/1_deploy-mocks.js deleted file mode 100644 index 0f7cab29..00000000 --- a/scripts/migrations/test/pre-deployment/1_deploy-mocks.js +++ /dev/null @@ -1,88 +0,0 @@ -const fs = require("fs"); -const { BigNumber } = require("ethers"); - -const rawdata = fs.readFileSync("../../../../externalAddresses.json"); -let addresses = JSON.parse(rawdata); - -const MockedDexRouter = artifacts.require("MockedDexRouter.sol"); -const MockStablecoinAdapter = artifacts.require("MockStablecoinAdapter.sol"); -const MockCollateralPoolConfig = artifacts.require("MockCollateralPoolConfig.sol"); - -const MockFlashMintModule = artifacts.require("MockFlashMintModule.sol"); -const MockFixedSpreadLiquidationStrategy = artifacts.require("MockFixedSpreadLiquidationStrategy.sol"); - -const MockPositionManager = artifacts.require("MockPositionManager.sol"); -const MockCentralizedOraclePriceFeed = artifacts.require("MockCentralizedOraclePriceFeed.sol"); -const MockDelayFathomOraclePriceFeed = artifacts.require("MockDelayFathomOraclePriceFeed.sol"); -const MockDexPriceOracle = artifacts.require("MockDexPriceOracle.sol"); -const MockSlidingWindowDexOracle = artifacts.require("MockSlidingWindowDexOracle.sol"); -const MockAdminControls = artifacts.require("MockAdminControls.sol"); -const MockBookKeeper = artifacts.require("MockBookKeeper.sol"); - -const MockFathomStablecoin = artifacts.require("MockFathomStablecoin.sol"); - -const MockLiquidationEngine = artifacts.require("MockLiquidationEngine.sol"); - -const MockPriceOracle = artifacts.require("MockPriceOracle.sol"); - -const MockFathomBridge = artifacts.require("MockFathomBridge.sol"); - -const MockShowStopper = artifacts.require("MockShowStopper.sol"); - -const MockStabilityFeeCollector = artifacts.require("MockStabilityFeeCollector.sol"); -const MockStableSwapModule = artifacts.require("MockStableSwapModule.sol"); -const MockStableSwapModuleWrapper = artifacts.require("MockStableSwapModuleWrapper.sol"); -const MockSystemDebtEngine = artifacts.require("MockSystemDebtEngine.sol"); - -const TokenAdapter = artifacts.require("TokenAdapter.sol"); -const FathomToken = artifacts.require("FathomToken.sol"); -const ERC20 = artifacts.require("ERC20Mintable.sol"); -const WXDC = artifacts.require("WXDC.sol"); -const ERC20Stable = artifacts.require("ERC20MintableStableSwap.sol"); -const SimplePriceFeed = artifacts.require("SimplePriceFeed.sol"); -const StableswapMultipleSwapsMock = artifacts.require("StableswapMultipleSwapsMock"); -const TestOracleMock = artifacts.require("TestOracleMock"); - -module.exports = async function (deployer) { - const promises = [ - deployer.deploy(ERC20, "US+", "US+", { gas: 3050000 }), - deployer.deploy(MockedDexRouter, { gas: 3050000 }), - deployer.deploy(TokenAdapter, { gas: 3050000 }), - deployer.deploy(FathomToken, 88, 89, { gas: 3050000 }), - deployer.deploy(ERC20Stable, "StableCoin", "SFC", { gas: 3050000 }), - deployer.deploy(SimplePriceFeed, { gas: 7050000 }), - deployer.deploy(TestOracleMock, 1000, { gas: 7050000 }), - deployer.deploy(MockStablecoinAdapter, { gas: 7050000 }), - deployer.deploy(MockCollateralPoolConfig, { gas: 7050000 }), - deployer.deploy(MockFlashMintModule, { gas: 7050000 }), - deployer.deploy(MockFixedSpreadLiquidationStrategy, { gas: 7050000 }), - deployer.deploy(MockPositionManager, { gas: 7050000 }), - deployer.deploy(MockCentralizedOraclePriceFeed, { gas: 7050000 }), - deployer.deploy(MockDelayFathomOraclePriceFeed, { gas: 7050000 }), - deployer.deploy(MockDexPriceOracle, { gas: 7050000 }), - deployer.deploy(MockSlidingWindowDexOracle, { gas: 7050000 }), - deployer.deploy(MockAdminControls, { gas: 7050000 }), - deployer.deploy(MockBookKeeper, { gas: 7050000 }), - deployer.deploy(MockFathomStablecoin, { gas: 7050000 }), - deployer.deploy(MockLiquidationEngine, { gas: 7050000 }), - deployer.deploy(MockPriceOracle, { gas: 7050000 }), - deployer.deploy(MockFathomBridge, { gas: 7050000 }), - deployer.deploy(MockShowStopper, { gas: 7050000 }), - deployer.deploy(MockStabilityFeeCollector, { gas: 7050000 }), - deployer.deploy(MockStableSwapModule, { gas: 7050000 }), - deployer.deploy(MockStableSwapModuleWrapper, { gas: 7050000 }), - deployer.deploy(MockSystemDebtEngine, { gas: 7050000 }), - ]; - - await Promise.all(promises); - - const chainId = deployer.networkId(ERC20.address); - addresses[chainId].USD = ERC20.address; - addresses[chainId].USDSTABLE = ERC20Stable.address; - - await deployer.deploy(WXDC, { gas: 3050000 }), (addresses[chainId].WXDC = WXDC.address); - addresses[chainId].testOracle = TestOracleMock.address; - - await deployer.deploy(StableswapMultipleSwapsMock, { gas: 3050000 }); - fs.writeFileSync("./externalAddresses.json", JSON.stringify(addresses)); -}; diff --git a/scripts/setup/add-collateral/addRoles.js b/scripts/setup/add-collateral/addRoles.js index 6e4f86fd..66904fdb 100644 --- a/scripts/setup/add-collateral/addRoles.js +++ b/scripts/setup/add-collateral/addRoles.js @@ -29,4 +29,4 @@ async function addRoles(getChainId, forFixture = false) { await collateralTokenAdapter.addToWhitelist(liquidationEngine.address); await collateralTokenAdapter.addToWhitelist(showStopper.address); } -module.exports = { addRoles }; \ No newline at end of file +module.exports = { addRoles }; diff --git a/scripts/setup/add-collateral/deploy.js b/scripts/setup/add-collateral/deploy.js index 21f7f032..8bef5535 100644 --- a/scripts/setup/add-collateral/deploy.js +++ b/scripts/setup/add-collateral/deploy.js @@ -4,7 +4,7 @@ async function deploy(getNamedAccounts, deployments, getChainId) { const { deploy } = deployments; const { deployer } = await getNamedAccounts(); const chainId = await getChainId(); - + await deploy("DexPriceOracle", { from: deployer, args: [], @@ -34,4 +34,4 @@ async function deploy(getNamedAccounts, deployments, getChainId) { }); } } -module.exports = { deploy }; \ No newline at end of file +module.exports = { deploy }; diff --git a/scripts/setup/add-collateral/deployProxies.js b/scripts/setup/add-collateral/deployProxies.js index 31f5637c..a0534d97 100644 --- a/scripts/setup/add-collateral/deployProxies.js +++ b/scripts/setup/add-collateral/deployProxies.js @@ -28,4 +28,4 @@ async function deployProxies(deployments, getChainId, forFixture = false) { }) ); } -module.exports = { deployProxies }; \ No newline at end of file +module.exports = { deployProxies }; diff --git a/scripts/setup/add-collateral/deployVault.js b/scripts/setup/add-collateral/deployVault.js index 980cb224..ea0ee209 100644 --- a/scripts/setup/add-collateral/deployVault.js +++ b/scripts/setup/add-collateral/deployVault.js @@ -37,4 +37,4 @@ async function deployVault(getNamedAccounts, deployments, getChainId, forFixture const Vault = await deployments.get("Vault"); await collateralTokenAdapter.setVault(Vault.address); } -module.exports = { deployVault }; \ No newline at end of file +module.exports = { deployVault }; diff --git a/scripts/setup/add-collateral/initialize.js b/scripts/setup/add-collateral/initialize.js index d22073d7..4dc8ce64 100644 --- a/scripts/setup/add-collateral/initialize.js +++ b/scripts/setup/add-collateral/initialize.js @@ -49,4 +49,4 @@ async function initialize(getChainId, forFixture = false) { delayFathomOraclePriceFeed.initialize(dexPriceOracle.address, tokenAddress, usdAddress, accessControlConfig.address, poolId); fs.writeFileSync(`./addresses_${token}.json`, JSON.stringify(newAddresses)); } -module.exports = { initialize }; \ No newline at end of file +module.exports = { initialize }; diff --git a/scripts/setup/deploy-test-fixture/addCollateralPreDeployment.js b/scripts/setup/deploy-test-fixture/addCollateralPreDeployment.js index bcccfc51..3b577011 100644 --- a/scripts/setup/deploy-test-fixture/addCollateralPreDeployment.js +++ b/scripts/setup/deploy-test-fixture/addCollateralPreDeployment.js @@ -63,4 +63,4 @@ async function addCollateralPreDeployment(getNamedAccounts, deployments, getChai module.exports = { addCollateralPreDeployment, -}; \ No newline at end of file +}; diff --git a/scripts/setup/deploy-test-fixture/deployMocks.js b/scripts/setup/deploy-test-fixture/deployMocks.js index b549f96d..6bc0a3c8 100644 --- a/scripts/setup/deploy-test-fixture/deployMocks.js +++ b/scripts/setup/deploy-test-fixture/deployMocks.js @@ -180,4 +180,4 @@ async function deployMocks(getNamedAccounts, deployments, getChainId) { module.exports = { deployMocks, -}; \ No newline at end of file +}; diff --git a/scripts/setup/deploy-test-fixture/deployMocksPostDeployment.js b/scripts/setup/deploy-test-fixture/deployMocksPostDeployment.js index fe8be608..d7895b6d 100644 --- a/scripts/setup/deploy-test-fixture/deployMocksPostDeployment.js +++ b/scripts/setup/deploy-test-fixture/deployMocksPostDeployment.js @@ -39,13 +39,7 @@ async function deployMocksPostDeployment(getNamedAccounts, deployments, getChain const mockCollateralTokenAdapter = await ethers.getContractAt("MockCollateralTokenAdapter", MockCollateralTokenAdapter.address); const WXDC = await deployments.get("WXDC"); - await mockCollateralTokenAdapter.initialize( - bookKeeper.address, - pools.WXDC, - WXDC.address, - positionManager.address, - proxyWalletFactory.address - ); + await mockCollateralTokenAdapter.initialize(bookKeeper.address, pools.WXDC, WXDC.address, positionManager.address, proxyWalletFactory.address); await deploy("MockVault", { from: deployer, args: [pools.WXDC, WXDC.address, MockCollateralTokenAdapter.address], @@ -61,4 +55,4 @@ async function deployMocksPostDeployment(getNamedAccounts, deployments, getChain module.exports = { deployMocksPostDeployment, -}; \ No newline at end of file +}; diff --git a/scripts/setup/deploy/addRoles.js b/scripts/setup/deploy/addRoles.js index db5dfbcd..d1fe65a9 100644 --- a/scripts/setup/deploy/addRoles.js +++ b/scripts/setup/deploy/addRoles.js @@ -3,7 +3,7 @@ const { getProxy } = require("../../../common/proxies"); async function addRoles(deployments, getChainId) { const chainId = await getChainId(); - + const ProxyFactory = await deployments.get("FathomProxyFactory"); const proxyFactory = await ethers.getContractAt("FathomProxyFactory", ProxyFactory.address); @@ -77,4 +77,4 @@ async function addRoles(deployments, getChainId) { module.exports = { addRoles, -}; \ No newline at end of file +}; diff --git a/scripts/setup/deploy/configFlashLending.js b/scripts/setup/deploy/configFlashLending.js index db01b2c4..7460a794 100644 --- a/scripts/setup/deploy/configFlashLending.js +++ b/scripts/setup/deploy/configFlashLending.js @@ -19,4 +19,4 @@ async function configFlashLending(deployments) { module.exports = { configFlashLending, -}; \ No newline at end of file +}; diff --git a/scripts/setup/deploy/configureFees.js b/scripts/setup/deploy/configureFees.js index b0f706d6..a5fa919f 100644 --- a/scripts/setup/deploy/configureFees.js +++ b/scripts/setup/deploy/configureFees.js @@ -13,7 +13,7 @@ async function configureFees(deployments) { const ProxyFactory = await deployments.get("FathomProxyFactory"); const proxyFactory = await ethers.getContractAt("FathomProxyFactory", ProxyFactory.address); - const stableSwapModule = await getProxy(proxyFactory, "StableSwapModule") + const stableSwapModule = await getProxy(proxyFactory, "StableSwapModule"); const flashMintModule = await getProxy(proxyFactory, "FlashMintModule"); await stableSwapModule.setFeeIn(SSM_FEE_IN); @@ -25,4 +25,4 @@ async function configureFees(deployments) { module.exports = { configureFees, -}; \ No newline at end of file +}; diff --git a/scripts/setup/deploy/configureShowStopper.js b/scripts/setup/deploy/configureShowStopper.js index e509aa97..eed35d6f 100644 --- a/scripts/setup/deploy/configureShowStopper.js +++ b/scripts/setup/deploy/configureShowStopper.js @@ -19,4 +19,4 @@ async function configureShowStopper(deployments) { module.exports = { configureShowStopper, -}; \ No newline at end of file +}; diff --git a/scripts/setup/deploy/deployContracts.js b/scripts/setup/deploy/deployContracts.js index 9a7522e9..a9657397 100644 --- a/scripts/setup/deploy/deployContracts.js +++ b/scripts/setup/deploy/deployContracts.js @@ -28,7 +28,7 @@ async function deployContracts(getNamedAccounts, deployments, getChainId) { args: [], log: true, }); - await deploy("LiquidationEngine", { + await deploy("LiquidationEngine", { from: deployer, args: [], log: true, @@ -165,4 +165,4 @@ async function deployContracts(getNamedAccounts, deployments, getChainId) { module.exports = { deployContracts, -}; \ No newline at end of file +}; diff --git a/scripts/setup/deploy/deployProxies.js b/scripts/setup/deploy/deployProxies.js index f13c2765..e978f522 100644 --- a/scripts/setup/deploy/deployProxies.js +++ b/scripts/setup/deploy/deployProxies.js @@ -34,7 +34,7 @@ const contracts = [ async function deployProxies(deployments, getChainId) { const chainId = await getChainId(); - + const fathomProxyFactory = await deployments.get("FathomProxyFactory"); const fathomProxyFactoryAddress = fathomProxyFactory.address; @@ -58,4 +58,4 @@ async function deployProxies(deployments, getChainId) { module.exports = { deployProxies, -}; \ No newline at end of file +}; diff --git a/scripts/setup/deploy/deployVault.js b/scripts/setup/deploy/deployVault.js index 0f6e48c7..abe99882 100644 --- a/scripts/setup/deploy/deployVault.js +++ b/scripts/setup/deploy/deployVault.js @@ -29,4 +29,4 @@ async function deployVault(getNamedAccounts, deployments, getChainId, forFixture module.exports = { deployVault, -}; \ No newline at end of file +}; diff --git a/scripts/setup/deploy/initCollateralTokenAdapter.js b/scripts/setup/deploy/initCollateralTokenAdapter.js index bc201599..0fe2f279 100644 --- a/scripts/setup/deploy/initCollateralTokenAdapter.js +++ b/scripts/setup/deploy/initCollateralTokenAdapter.js @@ -13,4 +13,4 @@ async function initCollateralTokenAdapter(deployments) { module.exports = { initCollateralTokenAdapter, -}; \ No newline at end of file +}; diff --git a/scripts/setup/deploy/initialize.js b/scripts/setup/deploy/initialize.js index f53cfc6d..9640814d 100644 --- a/scripts/setup/deploy/initialize.js +++ b/scripts/setup/deploy/initialize.js @@ -14,7 +14,7 @@ async function initialize(deployments, getChainId, forFixture = false) { const proxyFactory = await ethers.getContractAt("FathomProxyFactory", ProxyFactory.address); const ProxyAdmin = await deployments.get("FathomProxyAdmin"); const proxyAdmin = await ethers.getContractAt("FathomProxyAdmin", ProxyAdmin.address); - + const fixedSpreadLiquidationStrategy = await getProxy(proxyFactory, "FixedSpreadLiquidationStrategy"); const proxyWalletRegistry = await getProxy(proxyFactory, "ProxyWalletRegistry"); const proxyWalletFactory = await getProxy(proxyFactory, "ProxyWalletFactory"); @@ -50,7 +50,7 @@ async function initialize(deployments, getChainId, forFixture = false) { } else { fathomBridge = null; } - + const fathomStablecoinProxyActions = await ethers.getContractAt("FathomStablecoinProxyActions", FathomStablecoinProxyActions.address); const addresses = getAddresses(chainId); @@ -81,7 +81,7 @@ async function initialize(deployments, getChainId, forFixture = false) { await proxyWalletFactory.initialize(proxyActionsStorage.address, proxyWalletRegistry.address); await proxyWalletRegistry.initialize(proxyWalletFactory.address, bookKeeper.address); await flashMintModule.initialize(stablecoinAdapter.address, systemDebtEngine.address); - + await stableSwapModule.initialize( bookKeeper.address, addresses.USDSTABLE, @@ -89,12 +89,12 @@ async function initialize(deployments, getChainId, forFixture = false) { dailyLimitNumerator, singleSwapLimitNumerator, numberOfSwapsLimitPerUser, - blocksPerLimit, + blocksPerLimit ); await flashMintArbitrager.initialize(); await bookKeeperFlashMintArbitrager.initialize(fathomStablecoin.address); // await dexPriceOracle.initialize(addresses.DEXFactory, { gasLimit: 1000000 }), - + let wxdcAddress; if (forFixture) { const WXDC = await deployments.get("WXDC"); @@ -120,10 +120,7 @@ async function initialize(deployments, getChainId, forFixture = false) { stablecoinAdapter.address ); // await centralizedOraclePriceFeed.initialize(fathomPriceOracle.address, accessControlConfig.address, pools.XDC); - await stableSwapModuleWrapper.initialize( - bookKeeper.address, - stableSwapModule.address - ); + await stableSwapModuleWrapper.initialize(bookKeeper.address, stableSwapModule.address); await simplePriceFeed.initialize(accessControlConfig.address); // await slidingWindowDexOracle.initialize(addresses.DEXFactory, 1800, 15); @@ -175,4 +172,4 @@ async function initialize(deployments, getChainId, forFixture = false) { module.exports = { initialize, -}; \ No newline at end of file +}; diff --git a/scripts/tests/integration/AdminControls.test.js b/scripts/tests/integration/AdminControls.test.js deleted file mode 100644 index 5bb2be39..00000000 --- a/scripts/tests/integration/AdminControls.test.js +++ /dev/null @@ -1,98 +0,0 @@ -const chai = require("chai"); -const { solidity } = require("ethereum-waffle"); -chai.use(solidity); - -const { loadFixture } = require("../helper/fixtures"); -const { getProxy } = require("../../common/proxies"); - -const { expect } = chai; - -const setup = async () => { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - - const adminControls = await getProxy(proxyFactory, "AdminControls"); - const liquidationEngine = await getProxy(proxyFactory, "LiquidationEngine"); - const positionManager = await getProxy(proxyFactory, "PositionManager"); - const stablecoinAdapter = await getProxy(proxyFactory, "StablecoinAdapter"); - const systemDebtEngine = await getProxy(proxyFactory, "SystemDebtEngine"); - const priceOracle = await getProxy(proxyFactory, "PriceOracle"); - const stableSwapModule = await getProxy(proxyFactory, "StableSwapModule"); - const flashMintModule = await getProxy(proxyFactory, "FlashMintModule"); - const bookKeeper = await getProxy(proxyFactory, "BookKeeper"); - - return { - adminControls, - bookKeeper, - liquidationEngine, - systemDebtEngine, - priceOracle, - stablecoinAdapter, - positionManager, - stableSwapModule, - flashMintModule, - }; -}; - -describe("AdminControls", () => { - // Contract - let adminControls; - let positionManager; - let bookKeeper; - let liquidationEngine; - let systemDebtEngine; - let priceOracle; - let stablecoinAdapter; - let stableSwapModule; - let flashMintModule; - - before(async () => { - await snapshot.revertToSnapshot(); - }); - - beforeEach(async () => { - ({ - adminControls, - bookKeeper, - liquidationEngine, - systemDebtEngine, - priceOracle, - stablecoinAdapter, - positionManager, - stableSwapModule, - flashMintModule, - } = await loadFixture(setup)); - }); - - describe("#pause", () => { - context("pause protocol", () => { - it("protocol contracts should be paused", async () => { - await adminControls.pauseProtocol(); - - expect(await bookKeeper.paused()).to.be.equal(true); - expect(await liquidationEngine.paused()).to.be.equal(true); - expect(await positionManager.paused()).to.be.equal(true); - expect(await systemDebtEngine.paused()).to.be.equal(true); - expect(await stablecoinAdapter.paused()).to.be.equal(true); - expect(await priceOracle.paused()).to.be.equal(true); - expect(await flashMintModule.paused()).to.be.equal(true); - }); - }); - }); - describe("#unpause", () => { - context("unpause protocol", () => { - it("protocol contracts should be unpaused", async () => { - await adminControls.pauseProtocol(); - - await adminControls.unpauseProtocol(); - - expect(await bookKeeper.paused()).to.be.equal(false); - expect(await liquidationEngine.paused()).to.be.equal(false); - expect(await positionManager.paused()).to.be.equal(false); - expect(await systemDebtEngine.paused()).to.be.equal(false); - expect(await stablecoinAdapter.paused()).to.be.equal(false); - expect(await priceOracle.paused()).to.be.equal(false); - expect(await flashMintModule.paused()).to.be.equal(false); - }); - }); - }); -}); diff --git a/scripts/tests/integration/CollateralTokenAdapter.test.js b/scripts/tests/integration/CollateralTokenAdapter.test.js deleted file mode 100644 index c1a765d6..00000000 --- a/scripts/tests/integration/CollateralTokenAdapter.test.js +++ /dev/null @@ -1,580 +0,0 @@ -const chai = require("chai"); -const { ethers } = require("ethers"); - -const { solidity } = require("ethereum-waffle"); -chai.use(solidity); - -const { weiToRay, WeiPerWad } = require("../helper/unit"); -const { advanceBlock } = require("../helper/time"); -const { DeployerAddress, AliceAddress, BobAddress, TreasuryAddress } = require("../helper/address"); -const { loadFixture } = require("../helper/fixtures"); -const { getProxy } = require("../../common/proxies"); - -const { expect } = chai; - -const setup = async () => { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - const collateralPoolConfig = await getProxy(proxyFactory, "CollateralPoolConfig"); - const accessControlConfig = await getProxy(proxyFactory, "AccessControlConfig"); - const collateralTokenAdapter = await getProxy(proxyFactory, "CollateralTokenAdapter"); - const bookKeeper = await getProxy(proxyFactory, "BookKeeper"); - - const wxdcAddr = await collateralTokenAdapter.collateralToken(); - const WXDC = await artifacts.initializeInterfaceAt("WXDC", "WXDC"); - - return { - collateralPoolConfig, - accessControlConfig, - WXDC, - collateralTokenAdapter, - wxdcAddr, - bookKeeper, - }; -}; - -describe("CollateralTokenAdapter", () => { - // Contracts - let collateralTokenAdapter; - let WXDC; - - before(async () => { - await snapshot.revertToSnapshot(); - }); - - beforeEach(async () => { - ({ collateralPoolConfig, accessControlConfig, WXDC, collateralTokenAdapter, wxdcAddr, bookKeeper } = await loadFixture(setup)); - }); - describe("#totalShare", async () => { - context("when all collateral tokens are deposited by deposit function", async () => { - it("should return the correct net asset valuation", async () => { - //Alice wraps XDC to WXDC - await WXDC.deposit({ from: AliceAddress, value: ethers.constants.WeiPerEther.mul(2), gasLimit: 1000000 }); - //Alice is whiteListed to directly call deposit function on CollateralTokenAdapter - await collateralTokenAdapter.addToWhitelist(AliceAddress, { gasLimit: 1000000 }); - await WXDC.approve(collateralTokenAdapter.address, ethers.utils.parseEther("1"), { from: AliceAddress, gasLimit: 1000000 }); - await collateralTokenAdapter.deposit( - AliceAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: AliceAddress, gasLimit: 2000000 } - ); - - expect(await collateralTokenAdapter.totalShare()).to.be.eq(ethers.utils.parseEther("1")); - - await collateralTokenAdapter.withdraw( - AliceAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: AliceAddress, gasLimit: 1000000 } - ); - expect(await collateralTokenAdapter.totalShare()).to.be.eq(0); - }); - }); - - context("when some one directly transfer collateral tokens to CollateralTokenAdapter", async () => { - it("should only recognized collateral tokens from deposit function", async () => { - //Alice wraps XDC to WXDC - await WXDC.deposit({ from: AliceAddress, value: ethers.constants.WeiPerEther.mul(2), gasLimit: 1000000 }); - //Alice is whiteListed to directly call deposit function on CollateralTokenAdapter - await collateralTokenAdapter.addToWhitelist(AliceAddress, { gasLimit: 1000000 }); - await WXDC.approve(collateralTokenAdapter.address, ethers.utils.parseEther("1"), { from: AliceAddress, gasLimit: 1000000 }); - await collateralTokenAdapter.deposit( - AliceAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: AliceAddress, gasLimit: 2000000 } - ); - //Bob wraps XDC to WXDC - await WXDC.deposit({ from: BobAddress, value: ethers.constants.WeiPerEther.mul(89), gasLimit: 1000000 }); - await WXDC.transfer(collateralTokenAdapter.address, ethers.utils.parseEther("88"), { from: BobAddress }); - - expect(await WXDC.balanceOf(collateralTokenAdapter.address)).to.be.eq(ethers.utils.parseEther("88")); - expect(await collateralTokenAdapter.totalShare()).to.be.eq(ethers.utils.parseEther("1")); - - await collateralTokenAdapter.withdraw( - AliceAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: AliceAddress, gasLimit: 1000000 } - ); - - expect(await WXDC.balanceOf(collateralTokenAdapter.address)).to.be.eq(ethers.utils.parseEther("88")); - expect(await collateralTokenAdapter.totalShare()).to.be.eq(0); - }); - }); - }); - - describe("#deposit", async () => { - context("when CollateralTokenAdapter is not live", async () => { - it("should revert", async () => { - // Cage collateralTokenAdapter - await collateralTokenAdapter.cage(); - await collateralTokenAdapter.addToWhitelist(DeployerAddress, { gasLimit: 1000000 }); - await expect( - collateralTokenAdapter.deposit( - DeployerAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [DeployerAddress]) - ) - ).to.be.revertedWith("CollateralTokenAdapter/not-live"); - }); - }); - - context("when all parameters are valid", async () => { - it("should work", async () => { - //Alice wraps XDC to WXDC - await WXDC.deposit({ from: AliceAddress, value: ethers.constants.WeiPerEther.mul(2), gasLimit: 1000000 }); - // Assuming Alice is the first one to deposit hence no rewards to be harvested yet - await WXDC.approve(collateralTokenAdapter.address, ethers.utils.parseEther("2"), { from: AliceAddress, gasLimit: 1000000 }); - //Alice is whiteListed to directly call deposit function on CollateralTokenAdapter - await collateralTokenAdapter.addToWhitelist(AliceAddress, { gasLimit: 1000000 }); - await collateralTokenAdapter.deposit( - AliceAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: AliceAddress, gasLimit: 1000000 } - ); - - expect(await collateralTokenAdapter.totalShare()).to.be.eq(ethers.utils.parseEther("1")); - let collateralPoolIdFromAdapter = await collateralTokenAdapter.collateralPoolId(); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("1")); - - await collateralTokenAdapter.deposit(AliceAddress, 0, ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), { - from: AliceAddress, - gasLimit: 1000000, - }); - - expect(await collateralTokenAdapter.totalShare()).to.be.eq(ethers.utils.parseEther("1")); - - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("1")); - - //Bob wraps XDC to WXDC - await WXDC.deposit({ from: BobAddress, value: ethers.constants.WeiPerEther.mul(4), gasLimit: 1000000 }); - await WXDC.approve(collateralTokenAdapter.address, ethers.utils.parseEther("4"), { from: BobAddress }); - //Alice is whiteListed to directly call deposit function on CollateralTokenAdapter - await collateralTokenAdapter.addToWhitelist(BobAddress, { gasLimit: 1000000 }); - await collateralTokenAdapter.deposit( - BobAddress, - ethers.utils.parseEther("4"), - ethers.utils.defaultAbiCoder.encode(["address"], [BobAddress]), - { from: BobAddress } - ); - - expect(await collateralTokenAdapter.totalShare()).to.be.eq(ethers.utils.parseEther("5")); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("1")); - - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, BobAddress)).to.be.eq(ethers.utils.parseEther("4")); - - await collateralTokenAdapter.deposit(BobAddress, 0, ethers.utils.defaultAbiCoder.encode(["address"], [BobAddress]), { from: BobAddress }); - - expect(await collateralTokenAdapter.totalShare()).to.be.eq(ethers.utils.parseEther("5")); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("1")); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, BobAddress)).to.be.eq(ethers.utils.parseEther("4")); - }); - }); - }); - - describe("#withdraw", async () => { - context("when withdraw more than what CollateralTokenAdapter staked", async () => { - it("should revert", async () => { - await collateralTokenAdapter.addToWhitelist(AliceAddress, { gasLimit: 1000000 }); - //Alice wraps XDC to WXDC - await WXDC.deposit({ from: AliceAddress, value: ethers.constants.WeiPerEther.mul(2), gasLimit: 1000000 }); - await WXDC.approve(collateralTokenAdapter.address, ethers.utils.parseEther("1"), { from: AliceAddress, gasLimit: 1000000 }); - await collateralTokenAdapter.deposit( - AliceAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: AliceAddress, gasLimit: 1000000 } - ); - - await expect( - collateralTokenAdapter.withdraw( - AliceAddress, - ethers.utils.parseEther("100"), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: AliceAddress, gasLimit: 1000000 } - ) - ).to.be.revertedWith("CollateralTokenAdapter/insufficient collateral amount"); - }); - }); - - context("when withdraw more than what he staked", async () => { - it("should revert", async () => { - await collateralTokenAdapter.addToWhitelist(AliceAddress, { gasLimit: 1000000 }); - await WXDC.deposit({ from: AliceAddress, value: ethers.constants.WeiPerEther.mul(2), gasLimit: 1000000 }); - await WXDC.approve(collateralTokenAdapter.address, ethers.utils.parseEther("1"), { from: AliceAddress, gasLimit: 1000000 }); - await collateralTokenAdapter.deposit( - AliceAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: AliceAddress, gasLimit: 1000000 } - ); - await collateralTokenAdapter.addToWhitelist(BobAddress, { gasLimit: 1000000 }); - await WXDC.deposit({ from: BobAddress, value: ethers.constants.WeiPerEther.mul(4), gasLimit: 1000000 }); - await WXDC.approve(collateralTokenAdapter.address, ethers.utils.parseEther("4"), { from: BobAddress }); - await collateralTokenAdapter.deposit( - BobAddress, - ethers.utils.parseEther("4"), - ethers.utils.defaultAbiCoder.encode(["address"], [BobAddress]), - { from: BobAddress } - ); - - await expect( - collateralTokenAdapter.withdraw( - AliceAddress, - ethers.utils.parseEther("2"), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: AliceAddress, gasLimit: 1000000 } - ) - ).to.be.revertedWith("CollateralTokenAdapter/insufficient collateral amount"); - }); - }); - - context("when CollateralTokenAdapter is not live", async () => { - it("should still allow user to withdraw", async () => { - await collateralTokenAdapter.addToWhitelist(AliceAddress, { gasLimit: 1000000 }); - // Assuming Alice is the first one to deposit hence no rewards to be harvested yet - await WXDC.deposit({ from: AliceAddress, value: ethers.constants.WeiPerEther.mul(2), gasLimit: 1000000 }); - await WXDC.approve(collateralTokenAdapter.address, ethers.utils.parseEther("1"), { from: AliceAddress, gasLimit: 1000000 }); - await collateralTokenAdapter.deposit( - AliceAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: AliceAddress, gasLimit: 1000000 } - ); - - expect(await collateralTokenAdapter.totalShare()).to.be.eq(ethers.utils.parseEther("1")); - let collateralPoolIdFromAdapter = await collateralTokenAdapter.collateralPoolId(); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("1")); - - // Cage CollateralTokenAdapter - await collateralTokenAdapter.cage(); - expect(await collateralTokenAdapter.live()).to.be.eq(0); - - // Now Alice withdraw her position. 4 blocks have been passed. - // CollateralTokenAdapter is caged, non of FXD has been harvested. - // Staked collateralTokens have been emergencyWithdraw from FairLaunch. - // The following conditions must be satisfy: - // - Alice should get 0 FXD as cage before FXD get harvested. - // - Alice should get 1 WXDC back. - let aliceWXDCbefore = await WXDC.balanceOf(AliceAddress); - await collateralTokenAdapter.withdraw( - AliceAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: AliceAddress, gasLimit: 1000000 } - ); - let aliceWXDCafter = await WXDC.balanceOf(AliceAddress); - - expect(aliceWXDCafter.sub(aliceWXDCbefore)).to.be.eq(ethers.utils.parseEther("1")); - expect(await collateralTokenAdapter.totalShare()).to.be.eq(0); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("0")); - }); - - it("should still allow user to withdraw with pending rewards (if any)", async () => { - await collateralTokenAdapter.addToWhitelist(AliceAddress, { gasLimit: 1000000 }); - await WXDC.deposit({ from: AliceAddress, value: ethers.constants.WeiPerEther.mul(2), gasLimit: 1000000 }); - - // Assuming Alice is the first one to deposit hence no rewards to be harvested yet - await WXDC.approve(collateralTokenAdapter.address, ethers.utils.parseEther("1"), { from: AliceAddress, gasLimit: 1000000 }); - await collateralTokenAdapter.deposit( - AliceAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: AliceAddress, gasLimit: 1000000 } - ); - - expect(await collateralTokenAdapter.totalShare()).to.be.eq(ethers.utils.parseEther("1")); - let collateralPoolIdFromAdapter = await collateralTokenAdapter.collateralPoolId(); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("1")); - - await WXDC.deposit({ from: BobAddress, value: ethers.constants.WeiPerEther.mul(4), gasLimit: 1000000 }); - await collateralTokenAdapter.addToWhitelist(BobAddress, { gasLimit: 1000000 }); - - // Bob join the party with 4 WXDC! 2 Blocks have been passed. - await WXDC.approve(collateralTokenAdapter.address, ethers.utils.parseEther("4"), { from: BobAddress }); - await collateralTokenAdapter.deposit( - BobAddress, - ethers.utils.parseEther("4"), - ethers.utils.defaultAbiCoder.encode(["address"], [BobAddress]), - { from: BobAddress } - ); - - expect(await collateralTokenAdapter.totalShare()).to.be.eq(ethers.utils.parseEther("5")); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("1")); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, BobAddress)).to.be.eq(ethers.utils.parseEther("4")); - - await advanceBlock(); - - // Cage CollateralTokenAdapter - await collateralTokenAdapter.cage(); - expect(await collateralTokenAdapter.live()).to.be.eq(0); - - // Now Alice withdraw her position. Only 200 FXD has been harvested from FairLaunch. - // CollateralTokenAdapter is caged. Staked collateralTokens have been emergencyWithdraw from FairLaunch. - // The following conditions must be satisfy: - // - Alice pending rewards must be 200 FXD - // - Bob pending rewards must be 0 FXD as all rewards after Bob deposited hasn't been harvested. - // - Alice should get 180 (200 - 10%) FXD that is harvested before cage (when Bob deposited) - // - Alice should get 1 WXDC back. - // - treasury account should get 20 FXD. - - let aliceWXDCbefore = await WXDC.balanceOf(AliceAddress); - await collateralTokenAdapter.withdraw( - AliceAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: AliceAddress, gasLimit: 1000000 } - ); - let aliceWXDCafter = await WXDC.balanceOf(AliceAddress); - - expect(aliceWXDCafter.sub(aliceWXDCbefore)).to.be.eq(ethers.utils.parseEther("1")); - expect(await collateralTokenAdapter.totalShare()).to.be.eq(ethers.utils.parseEther("4")); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("0")); - - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, BobAddress)).to.be.eq(ethers.utils.parseEther("4")); - - let bobWXDCbefore = await WXDC.balanceOf(BobAddress); - await collateralTokenAdapter.withdraw( - BobAddress, - ethers.utils.parseEther("4"), - ethers.utils.defaultAbiCoder.encode(["address"], [BobAddress]), - { from: BobAddress } - ); - let bobWXDCafter = await WXDC.balanceOf(BobAddress); - - expect(bobWXDCafter.sub(bobWXDCbefore)).to.be.eq(ethers.utils.parseEther("4")); - expect(await collateralTokenAdapter.totalShare()).to.be.eq(0); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("0")); - - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, BobAddress)).to.be.eq(ethers.utils.parseEther("0")); - }); - }); - - context("when all parameters are valid", async () => { - it("should work", async () => { - await collateralTokenAdapter.addToWhitelist(AliceAddress, { gasLimit: 1000000 }); - //Alice wraps XDC to WXDC - await WXDC.deposit({ from: AliceAddress, value: ethers.constants.WeiPerEther.mul(2), gasLimit: 1000000 }); - // Assuming Alice is the first one to deposit hence no rewards to be harvested yet - await WXDC.approve(collateralTokenAdapter.address, ethers.utils.parseEther("1"), { from: AliceAddress, gasLimit: 1000000 }); - await collateralTokenAdapter.deposit( - AliceAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: AliceAddress, gasLimit: 1000000 } - ); - - expect(await collateralTokenAdapter.totalShare()).to.be.eq(ethers.utils.parseEther("1")); - let collateralPoolIdFromAdapter = await collateralTokenAdapter.collateralPoolId(); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("1")); - - // Now Alice withdraw her position. 1 block has been passed, hence Alice should get 90 (100 - 10%) FXD, treasury account should get 10 FXD. - let aliceWXDCbefore = await WXDC.balanceOf(AliceAddress); - await collateralTokenAdapter.withdraw( - AliceAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: AliceAddress, gasLimit: 1000000 } - ); - let aliceWXDCafter = await WXDC.balanceOf(AliceAddress); - - expect(aliceWXDCafter.sub(aliceWXDCbefore)).to.be.eq(ethers.utils.parseEther("1")); - expect(await collateralTokenAdapter.totalShare()).to.be.eq(0); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("0")); - }); - }); - context("when bob withdraw collateral to alice", async () => { - context("when bob doesn't has collateral", () => { - it("should be revert", async () => { - await collateralTokenAdapter.addToWhitelist(AliceAddress, { gasLimit: 1000000 }); - await WXDC.deposit({ from: AliceAddress, value: ethers.constants.WeiPerEther.mul(2), gasLimit: 1000000 }); - // Assuming Alice is the first one to deposit hence no rewards to be harvested yet - await WXDC.approve(collateralTokenAdapter.address, ethers.utils.parseEther("1"), { from: AliceAddress, gasLimit: 1000000 }); - await collateralTokenAdapter.deposit( - AliceAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: AliceAddress, gasLimit: 1000000 } - ); - await collateralTokenAdapter.addToWhitelist(BobAddress, { gasLimit: 1000000 }); - //checking with Subik-ji - let collateralPoolIdFromAdapter = await collateralTokenAdapter.collateralPoolId(); - - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("1")); - - await expect( - collateralTokenAdapter.withdraw( - AliceAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [BobAddress]), - { from: BobAddress } - ) - ).to.be.revertedWith("CollateralTokenAdapter/insufficient collateral amount"); - }); - }); - context("when bob has collateral", async () => { - it("should be able to call withdraw", async () => { - await collateralTokenAdapter.addToWhitelist(AliceAddress, { gasLimit: 1000000 }); - await WXDC.deposit({ from: AliceAddress, value: ethers.constants.WeiPerEther.mul(2), gasLimit: 1000000 }); - await WXDC.approve(collateralTokenAdapter.address, ethers.utils.parseEther("1"), { from: AliceAddress, gasLimit: 1000000 }); - await collateralTokenAdapter.deposit( - AliceAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: AliceAddress, gasLimit: 1000000 } - ); - - expect(await collateralTokenAdapter.totalShare()).to.be.eq(ethers.utils.parseEther("1")); - let collateralPoolIdFromAdapter = await collateralTokenAdapter.collateralPoolId(); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("1")); - - await collateralTokenAdapter.addToWhitelist(BobAddress, { gasLimit: 1000000 }); - await WXDC.deposit({ from: BobAddress, value: ethers.constants.WeiPerEther.mul(2), gasLimit: 1000000 }); - await WXDC.approve(collateralTokenAdapter.address, ethers.utils.parseEther("1"), { from: BobAddress }); - await collateralTokenAdapter.deposit( - BobAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [BobAddress]), - { from: BobAddress } - ); - - let aliceWXDCbefore = await WXDC.balanceOf(AliceAddress); - let bobWXDCbefore = await WXDC.balanceOf(BobAddress); - await collateralTokenAdapter.withdraw(AliceAddress, ethers.utils.parseEther("1"), "0x", { from: BobAddress }); - let aliceWXDCafter = await WXDC.balanceOf(AliceAddress); - let bobWXDCafter = await WXDC.balanceOf(BobAddress); - - expect(aliceWXDCafter.sub(aliceWXDCbefore)).to.be.eq(ethers.utils.parseEther("1")); - expect(bobWXDCafter.sub(bobWXDCbefore)).to.be.eq(ethers.utils.parseEther("0")); - }); - }); - }); - }); - - describe("#emergencyWithdraw", async () => { - context("when CollateralTokenAdapter is not live", async () => { - it("should allow users to exit with emergencyWithdraw and normal withdraw", async () => { - await WXDC.deposit({ from: AliceAddress, value: ethers.constants.WeiPerEther.mul(2), gasLimit: 1000000 }); - await collateralTokenAdapter.addToWhitelist(AliceAddress, { gasLimit: 1000000 }); - // Assuming Alice is the first one to deposit hence no rewards to be harvested yet - await WXDC.approve(collateralTokenAdapter.address, ethers.utils.parseEther("1"), { from: AliceAddress, gasLimit: 1000000 }); - await collateralTokenAdapter.deposit( - AliceAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: AliceAddress, gasLimit: 1000000 } - ); - - expect(await collateralTokenAdapter.totalShare()).to.be.eq(ethers.utils.parseEther("1")); - let collateralPoolIdFromAdapter = await collateralTokenAdapter.collateralPoolId(); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("1")); - - await WXDC.deposit({ from: BobAddress, value: ethers.constants.WeiPerEther.mul(4), gasLimit: 1000000 }); - await collateralTokenAdapter.addToWhitelist(BobAddress, { gasLimit: 1000000 }); - // Bob join the party with 4 WXDC! 2 Blocks have been passed. - await WXDC.approve(collateralTokenAdapter.address, ethers.utils.parseEther("4"), { from: BobAddress }); - await collateralTokenAdapter.deposit( - BobAddress, - ethers.utils.parseEther("4"), - ethers.utils.defaultAbiCoder.encode(["address"], [BobAddress]), - { from: BobAddress } - ); - - expect(await collateralTokenAdapter.totalShare()).to.be.eq(ethers.utils.parseEther("5")); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("1")); - - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, BobAddress)).to.be.eq(ethers.utils.parseEther("4")); - - // Move 1 block so CollateralTokenAdapter make 100 FXD. However this portion - // won't be added as CollateralTokenAdapter cage before it get harvested. - await advanceBlock(); - - // Cage CollateralTokenAdapter - await collateralTokenAdapter.cage(); - expect(await collateralTokenAdapter.live()).to.be.eq(0); - - // Alice panic and decided to emergencyWithdraw. - // The following states are expected: - // - Alice should get 1 WXDC back. - let aliceWXDCbefore = await WXDC.balanceOf(AliceAddress); - await collateralTokenAdapter.emergencyWithdraw(AliceAddress, { from: AliceAddress, gasLimit: 1000000 }); - let aliceWXDCafter = await WXDC.balanceOf(AliceAddress); - - expect(aliceWXDCafter.sub(aliceWXDCbefore)).to.be.eq(ethers.utils.parseEther("1")); - expect(await collateralTokenAdapter.totalShare()).to.be.eq(ethers.utils.parseEther("4")); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("0")); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, BobAddress)).to.be.eq(ethers.utils.parseEther("4")); - - // Bob chose to withdraw normal. - // But in real life situation, Bob would not be whitelisted so that he can - // directly deposit and withdraw WXDC via CollateralTokenAdapter. - // The following states are expected: - // - Bob should get his 4 WXDC back - let bobWXDCbefore = await WXDC.balanceOf(BobAddress); - await collateralTokenAdapter.withdraw( - BobAddress, - ethers.utils.parseEther("4"), - ethers.utils.defaultAbiCoder.encode(["address"], [BobAddress]), - { from: BobAddress } - ); - let bobWXDCafter = await WXDC.balanceOf(BobAddress); - - expect(bobWXDCafter.sub(bobWXDCbefore)).to.be.eq(ethers.utils.parseEther("4")); - expect(await collateralTokenAdapter.totalShare()).to.be.eq(0); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("0")); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, BobAddress)).to.be.eq(ethers.utils.parseEther("0")); - }); - }); - - context("when all states are normal", async () => { - it("can call emergencyWithdraw but the state will stay the same", async () => { - await WXDC.deposit({ from: AliceAddress, value: ethers.constants.WeiPerEther.mul(1), gasLimit: 1000000 }); - await collateralTokenAdapter.addToWhitelist(AliceAddress, { gasLimit: 1000000 }); - await WXDC.approve(collateralTokenAdapter.address, ethers.utils.parseEther("1"), { from: AliceAddress, gasLimit: 1000000 }); - await collateralTokenAdapter.deposit( - AliceAddress, - ethers.utils.parseEther("1"), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: AliceAddress, gasLimit: 1000000 } - ); - - expect(await collateralTokenAdapter.totalShare()).to.be.eq(ethers.utils.parseEther("1")); - let collateralPoolIdFromAdapter = await collateralTokenAdapter.collateralPoolId(); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("1")); - - // Alice feels in-secure, so she does emergencyWithdraw - // However, the collateralTokenAdapter is not uncaged, therefore - // - Alice cannot get here 1 WXDC back - // - Alice's state stays the same. - let aliceWXDCbefore = await WXDC.balanceOf(AliceAddress); - await collateralTokenAdapter.emergencyWithdraw(AliceAddress, { from: AliceAddress, gasLimit: 1000000 }); - let aliceWXDCafter = await WXDC.balanceOf(AliceAddress); - - expect(aliceWXDCafter.sub(aliceWXDCbefore)).to.be.eq(ethers.utils.parseEther("0")); - expect(await collateralTokenAdapter.totalShare()).to.be.eq(ethers.utils.parseEther("1")); - expect(await bookKeeper.collateralToken(collateralPoolIdFromAdapter, AliceAddress)).to.be.eq(ethers.utils.parseEther("1")); - }); - }); - }); - - describe("#cage/#uncage", async () => { - context("when whitelist cage", async () => { - it("should put CollateralTokenAdapter live = 0", async () => { - await collateralTokenAdapter.cage(); - expect(await collateralTokenAdapter.live()).to.be.eq(0); - }); - }); - - context("when caller not owner role cage", async () => { - context("when assumptions still valid", async () => { - it("should revert", async () => { - await expect(collateralTokenAdapter.cage({ from: AliceAddress, gasLimit: 1000000 })).to.be.revertedWith( - "CollateralTokenAdapter/not-authorized" - ); - }); - }); - }); - }); -}); diff --git a/scripts/tests/integration/FathomProxyActions.test.js b/scripts/tests/integration/FathomProxyActions.test.js deleted file mode 100644 index 8c999b5e..00000000 --- a/scripts/tests/integration/FathomProxyActions.test.js +++ /dev/null @@ -1,214 +0,0 @@ -const chai = require("chai"); - -const { solidity } = require("ethereum-waffle"); -chai.use(solidity); -const { expect } = chai; - -const { WeiPerRay, WeiPerWad } = require("../helper/unit"); -const AssertHelpers = require("../helper/assert"); -const { createProxyWallets } = require("../helper/proxy-wallets"); -const { AliceAddress, DevAddress } = require("../helper/address"); -const PositionHelper = require("../helper/positions"); -const { loadFixture } = require("../helper/fixtures"); -const { getProxy } = require("../../common/proxies"); -const pools = require("../../common/collateral"); - -const setup = async () => { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - const simplePriceFeed = await artifacts.initializeInterfaceAt("SimplePriceFeed", "SimplePriceFeed"); - - const collateralPoolConfig = await getProxy(proxyFactory, "CollateralPoolConfig"); - const bookKeeper = await getProxy(proxyFactory, "BookKeeper"); - const stabilityFeeCollector = await getProxy(proxyFactory, "StabilityFeeCollector"); - const positionManager = await getProxy(proxyFactory, "PositionManager"); - const stablecoinAdapter = await getProxy(proxyFactory, "StablecoinAdapter"); - const fathomStablecoin = await getProxy(proxyFactory, "FathomStablecoin"); - const proxyWalletRegistry = await getProxy(proxyFactory, "ProxyWalletRegistry"); - await proxyWalletRegistry.setDecentralizedMode(true); - - ({ - proxyWallets: [aliceProxyWallet], - } = await createProxyWallets([AliceAddress])); - const reentrancyAttacker = await artifacts.initializeInterfaceAt("ReentrancyAttacker", "ReentrancyAttacker"); - const reentrancyAttacker2 = await artifacts.initializeInterfaceAt("ReentrancyAttacker2", "ReentrancyAttacker2"); - - //making proxyWallet of reentrancyAttacker contract - await proxyWalletRegistry.build(reentrancyAttacker.address); - await proxyWalletRegistry.build(reentrancyAttacker2.address); - - const reEntrantProxyWallet = await proxyWalletRegistry.proxies(reentrancyAttacker.address); - const reEntrantProxyWallet2 = await proxyWalletRegistry.proxies(reentrancyAttacker2.address); - - await reentrancyAttacker.setProxyWallet(reEntrantProxyWallet); - await reentrancyAttacker2.setProxyWallet(reEntrantProxyWallet2); - - await stabilityFeeCollector.setSystemDebtEngine(DevAddress); - - await fathomStablecoin.approve(aliceProxyWallet.address, WeiPerWad.mul(10000), { from: AliceAddress }); - - return { - bookKeeper, - stablecoinAdapter, - positionManager, - stabilityFeeCollector, - simplePriceFeed, - collateralPoolConfig, - aliceProxyWallet, - reEntrantProxyWallet, - reEntrantProxyWallet2, - reentrancyAttacker, - reentrancyAttacker2, - fathomStablecoin, - }; -}; - -describe("Position Closure without collateral withdrawal", () => { - // Proxy wallet - let aliceProxyWallet; - - // Contract - let positionManager; - let bookKeeper; - let simplePriceFeed; - - before(async () => { - await snapshot.revertToSnapshot(); - }); - - beforeEach(async () => { - ({ - bookKeeper, - stablecoinAdapter, - positionManager, - // tokenAdapter, - stabilityFeeCollector, - simplePriceFeed, - collateralPoolConfig, - aliceProxyWallet, - reEntrantProxyWallet, - reEntrantProxyWallet2, - reentrancyAttacker, - reentrancyAttacker2, - fathomStablecoin, - } = await loadFixture(setup)); - }); - - describe("#wipeAndUnlockXDC", () => { - context("open position and pay back debt without collateral withdrawal", () => { - it("should be success", async () => { - await simplePriceFeed.setPrice(WeiPerRay, { gasLimit: 1000000 }); - - // position 1 - // a. open a new position - // b. lock WXDC - // c. mint FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - - const positionId = await positionManager.ownerLastPositionId(aliceProxyWallet.address); - const positionAddress = await positionManager.positions(positionId); - - // a. repay 2 WAD of FXD - // b. alice doesn't unlock any XDC - // c. check if the position has the same amount of lockedCollateral - // d. check if the position has now debtShare of 3 WAD (5-2) - - await PositionHelper.wipeAndUnlockXDC(aliceProxyWallet, AliceAddress, positionId, 0, WeiPerWad.mul(2)); - - const [lockedCollateral, debtShare] = await bookKeeper.positions(pools.XDC, positionAddress); - - expect(lockedCollateral).to.be.equal(WeiPerWad.mul(10)); - AssertHelpers.assertAlmostEqual(debtShare, WeiPerWad.mul(3)); - }); - }); - context("try reentry with ReentrancyAttacker", () => { - it("should not make change to the position", async () => { - await simplePriceFeed.setPrice(WeiPerRay, { gasLimit: 1000000 }); - - // position 1 - // a. open a new position - // b. lock WXDC - // c. mint FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - - const positionId = await positionManager.ownerLastPositionId(aliceProxyWallet.address); - const positionAddress = await positionManager.positions(positionId); - - // call allowmanagerPosition so that reentrancyAttacker can close position - await PositionHelper.allowManagePosition(aliceProxyWallet, AliceAddress, 1, reEntrantProxyWallet, true); - //transfer some FXD to reentrancyAttacker contract - await fathomStablecoin.transfer(reentrancyAttacker.address, WeiPerWad.mul(5), { from: AliceAddress }); - //reentrancyAttack approve reEntrantProxyWallet as spender of FXD - await reentrancyAttacker.approveWallet(fathomStablecoin.address); - //reentrancyAttacker tries to call wipeAndUnlockXDC and then all proxyWallet again with fallback function - //but due to gas limit set in safeTransferETH, the fn call fails. - - PositionHelper.wipeAndUnlockXDC(reentrancyAttacker, AliceAddress, positionId, WeiPerWad.mul(1), WeiPerWad.mul(2)); - - const [lockedCollateral, debtShare] = await bookKeeper.positions(pools.XDC, positionAddress); - - expect(lockedCollateral).to.be.equal(WeiPerWad.mul(10)); - AssertHelpers.assertAlmostEqual(debtShare, WeiPerWad.mul(5)); - }); - }); - context("try reentry with ReentrancyAttacker2", () => { - it("should fail", async () => { - await simplePriceFeed.setPrice(WeiPerRay, { gasLimit: 1000000 }); - - // position 1 - // a. open a new position - // b. lock WXDC - // c. mint FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - - const positionId = await positionManager.ownerLastPositionId(aliceProxyWallet.address); - const positionAddress = await positionManager.positions(positionId); - - // call allowmanagerPosition so that reentrancyAttacker can close position - await PositionHelper.allowManagePosition(aliceProxyWallet, AliceAddress, 1, reEntrantProxyWallet2, true); - //transfer some FXD to reentrancyAttacker contract - await fathomStablecoin.transfer(reentrancyAttacker2.address, WeiPerWad.mul(5), { from: AliceAddress }); - //reentrancyAttack approve reEntrantProxyWallet as spender of FXD - await reentrancyAttacker2.approveWallet(fathomStablecoin.address); - //reentrancyAttacker tries to call wipeAndUnlockXDC and then all proxyWallet again with fallback function - //but due to gas limit set in safeTransferETH, the fn call fails. - - await expect( - PositionHelper.wipeAndUnlockXDC(reentrancyAttacker2, AliceAddress, positionId, WeiPerWad.mul(1), WeiPerWad.mul(2)) - ).to.be.revertedWith("!safeTransferETH"); - }); - }); - }); - - describe("#wipeAllAndUnlockXDC", () => { - context("open position and pay back debt without collateral withdrawal", () => { - it("should be success", async () => { - await simplePriceFeed.setPrice(WeiPerRay, { gasLimit: 1000000 }); - - // position 1 - // a. open a new position - // b. lock WXDC - // c. mint FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - const positionId = await positionManager.ownerLastPositionId(aliceProxyWallet.address); - const positionAddress = await positionManager.positions(positionId); - - // position 2 - // a. open a new position - // b. lock WXDC - // c. mint FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - - // a. repay debt fully for position1 - // b. alice doesn't unlock any XDC - // c. check if the position has the same amount of lockedCollateral - // d. check if the position has now debtShare of 0 WAD - await PositionHelper.wipeAllAndUnlockXDC(aliceProxyWallet, AliceAddress, positionId, 0); - - const [lockedCollateral, debtShare] = await bookKeeper.positions(pools.XDC, positionAddress); - - expect(lockedCollateral).to.be.equal(WeiPerWad.mul(10)); - expect(debtShare).to.be.equal(0); - }); - }); - }); -}); diff --git a/scripts/tests/integration/FlashMintModule.test.js b/scripts/tests/integration/FlashMintModule.test.js deleted file mode 100644 index bb020b02..00000000 --- a/scripts/tests/integration/FlashMintModule.test.js +++ /dev/null @@ -1,191 +0,0 @@ -const chai = require("chai"); -const { ethers } = require("ethers"); -const { parseEther } = require("ethers/lib/utils"); -const { MaxUint256 } = require("@ethersproject/constants"); - -const { solidity } = require("ethereum-waffle"); -chai.use(solidity); -const { expect } = chai; - -const { WeiPerRay, WeiPerRad } = require("../helper/unit"); -const { loadFixture } = require("../helper/fixtures"); -const { DeployerAddress } = require("../helper/address"); - -const { getProxy } = require("../../common/proxies"); - -const loadFixtureHandler = async () => { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - - const bookKeeper = await getProxy(proxyFactory, "BookKeeper"); - const stableSwapModule = await getProxy(proxyFactory, "StableSwapModule"); - const stableSwapModuleWrapper = await getProxy(proxyFactory, "StableSwapModuleWrapper"); - const stablecoinAdapter = await getProxy(proxyFactory, "StablecoinAdapter"); - - const usdtAddr = await stableSwapModule.token(); - const USDT = await artifacts.initializeInterfaceAt("ERC20MintableStableSwap", usdtAddr); - - const flashMintModule = await getProxy(proxyFactory, "FlashMintModule"); - - const fathomStablecoin = await getProxy(proxyFactory, "FathomStablecoin"); - const router = await artifacts.initializeInterfaceAt("MockedDexRouter", "MockedDexRouter"); - const flashMintArbitrager = await getProxy(proxyFactory, "FlashMintArbitrager"); - const bookKeeperFlashMintArbitrager = await getProxy(proxyFactory, "BookKeeperFlashMintArbitrager"); - - return { - bookKeeper, - USDT, - fathomStablecoin, - flashMintModule, - flashMintArbitrager, - router, - stableSwapModule, - bookKeeperFlashMintArbitrager, - stableSwapModuleWrapper, - stablecoinAdapter, - }; -}; - -describe("FlastMintModule", () => { - // Contracts - let bookKeeper; - let USDT; - let flashMintModule; - let flashMintArbitrager; - let fathomStablecoin; - let router; - let stableSwapModule; - let stableSwapModuleWrapper; - let bookKeeperFlashMintArbitrager; - let stablecoinAdapter; - - before(async () => { - await snapshot.revertToSnapshot(); - }); - - beforeEach(async () => { - ({ - bookKeeper, - USDT, - fathomStablecoin, - flashMintModule, - flashMintArbitrager, - router, - stableSwapModule, - bookKeeperFlashMintArbitrager, - stableSwapModuleWrapper, - stablecoinAdapter, - } = await loadFixture(loadFixtureHandler)); - }); - describe("#flashLoan", async () => { - context("receiver doesn't have enough tokens to return the loan + fee", async () => { - it("should revert", async () => { - await fathomStablecoin.mint(DeployerAddress, parseEther("3000"), { gasLimit: 1000000 }); - await bookKeeper.mintUnbackedStablecoin(stablecoinAdapter.address, stablecoinAdapter.address, WeiPerRad.mul(3500), { gasLimit: 1000000 }); - await fathomStablecoin.approve(stableSwapModuleWrapper.address, parseEther("3000"), { gasLimit: 1000000 }); - await USDT.mint(DeployerAddress, parseEther("3500"), { gasLimit: 1000000 }); - await USDT.approve(stableSwapModuleWrapper.address, parseEther("3000"), { gasLimit: 1000000 }); - await stableSwapModuleWrapper.depositTokens(parseEther("3000"), { gasLimit: 1000000 }); - - await flashMintModule.addToWhitelist(DeployerAddress); - await stableSwapModule.addToWhitelist(flashMintArbitrager.address); - await USDT.approve(router.address, parseEther("500"), { gasLimit: 1000000 }); - await router.deposit(USDT.address, parseEther("500"), { gasLimit: 1000000 }); - await expect( - flashMintModule.flashLoan( - flashMintArbitrager.address, - fathomStablecoin.address, - parseEther("100"), - ethers.utils.defaultAbiCoder.encode(["address", "address", "address"], [router.address, USDT.address, stableSwapModule.address]), - { gasLimit: 1000000 } - ) - ).to.be.revertedWith("!safeTransferFrom"); - }); - }); - - context("receiver has enough tokens to return the loan + fee", async () => { - it("should success", async () => { - await fathomStablecoin.mint(DeployerAddress, parseEther("3500"), { gasLimit: 1000000 }); - await bookKeeper.mintUnbackedStablecoin(stablecoinAdapter.address, stablecoinAdapter.address, WeiPerRad.mul(3500), { gasLimit: 1000000 }); - await fathomStablecoin.approve(stableSwapModuleWrapper.address, parseEther("3000"), { gasLimit: 1000000 }); - await USDT.mint(DeployerAddress, parseEther("3500"), { gasLimit: 1000000 }); - await USDT.approve(stableSwapModuleWrapper.address, parseEther("3000"), { gasLimit: 1000000 }); - await stableSwapModuleWrapper.depositTokens(parseEther("3000"), { gasLimit: 1000000 }); - - await flashMintModule.addToWhitelist(DeployerAddress); - await stableSwapModule.addToWhitelist(flashMintArbitrager.address); - await USDT.approve(router.address, parseEther("500"), { gasLimit: 1000000 }); - await router.deposit(USDT.address, parseEther("500"), { gasLimit: 1000000 }); - await router.setProfit(true); - await flashMintModule.flashLoan( - flashMintArbitrager.address, - fathomStablecoin.address, - parseEther("100"), - ethers.utils.defaultAbiCoder.encode(["address", "address", "address"], [router.address, USDT.address, stableSwapModule.address]), - { gasLimit: 1000000 } - ); - - const profitFromArbitrage = await fathomStablecoin.balanceOf(flashMintArbitrager.address); - expect(profitFromArbitrage).to.be.equal(parseEther("9.49")); - - const feeCollectedFromFlashMint = await bookKeeper.stablecoin(flashMintModule.address); - expect(feeCollectedFromFlashMint).to.be.equal(parseEther("0.4").mul(WeiPerRay)); - }); - }); - }); - - describe("#bookKeeperFlashLoan", async () => { - context("receiver doesn't have enough tokens to return the loan + fee", async () => { - it("should revert", async () => { - await fathomStablecoin.mint(DeployerAddress, parseEther("3500"), { gasLimit: 1000000 }); - await bookKeeper.mintUnbackedStablecoin(stablecoinAdapter.address, stablecoinAdapter.address, WeiPerRad.mul(3500), { gasLimit: 1000000 }); - await fathomStablecoin.approve(stableSwapModuleWrapper.address, parseEther("3000"), { gasLimit: 1000000 }); - await USDT.mint(DeployerAddress, parseEther("3500"), { gasLimit: 1000000 }); - await USDT.approve(stableSwapModuleWrapper.address, parseEther("3000"), { gasLimit: 1000000 }); - await stableSwapModuleWrapper.depositTokens(parseEther("3000"), { gasLimit: 1000000 }); - - await flashMintModule.addToWhitelist(DeployerAddress); - await stableSwapModule.addToWhitelist(bookKeeperFlashMintArbitrager.address); - await USDT.approve(router.address, parseEther("500"), { gasLimit: 1000000 }); - await router.deposit(USDT.address, parseEther("500"), { gasLimit: 1000000 }); - - await expect( - flashMintModule.bookKeeperFlashLoan( - bookKeeperFlashMintArbitrager.address, - parseEther("100"), - ethers.utils.defaultAbiCoder.encode(["address", "address", "address"], [router.address, USDT.address, stableSwapModule.address]) - ) - ).to.be.reverted; - }); - }); - - context("receiver has enough tokens to return the loan + fee", async () => { - it("should success", async () => { - await fathomStablecoin.mint(DeployerAddress, parseEther("3500"), { gasLimit: 1000000 }); - await bookKeeper.mintUnbackedStablecoin(stablecoinAdapter.address, stablecoinAdapter.address, WeiPerRad.mul(3500), { gasLimit: 1000000 }); - await fathomStablecoin.approve(stableSwapModuleWrapper.address, parseEther("3000"), { gasLimit: 1000000 }); - await USDT.mint(DeployerAddress, parseEther("3500"), { gasLimit: 1000000 }); - await USDT.approve(stableSwapModuleWrapper.address, parseEther("3000"), { gasLimit: 1000000 }); - await stableSwapModuleWrapper.depositTokens(parseEther("3000"), { gasLimit: 1000000 }); - - await flashMintModule.addToWhitelist(DeployerAddress); - await stableSwapModule.addToWhitelist(bookKeeperFlashMintArbitrager.address); - await USDT.approve(router.address, parseEther("500"), { gasLimit: 1000000 }); - await router.deposit(USDT.address, parseEther("500"), { gasLimit: 1000000 }); - await router.setProfit(true); - - // Perform flash mint - await flashMintModule.bookKeeperFlashLoan( - bookKeeperFlashMintArbitrager.address, - parseEther("100").mul(WeiPerRay), - ethers.utils.defaultAbiCoder.encode(["address", "address", "address"], [router.address, USDT.address, stableSwapModule.address]) - ); - - const profitFromArbitrage = await fathomStablecoin.balanceOf(bookKeeperFlashMintArbitrager.address); - expect(profitFromArbitrage).to.be.equal(parseEther("9.49")); - - const feeCollectedFromFlashMint = await bookKeeper.stablecoin(flashMintModule.address); - expect(feeCollectedFromFlashMint).to.be.equal(parseEther("0.4").mul(WeiPerRay)); - }); - }); - }); -}); diff --git a/scripts/tests/integration/LiquidationEngine.test.js b/scripts/tests/integration/LiquidationEngine.test.js deleted file mode 100644 index 5b2f6c61..00000000 --- a/scripts/tests/integration/LiquidationEngine.test.js +++ /dev/null @@ -1,762 +0,0 @@ -const chai = require("chai"); -const { BigNumber, ethers } = require("ethers"); -const { MaxUint256 } = require("@ethersproject/constants"); - -const { solidity } = require("ethereum-waffle"); -chai.use(solidity); -const provider = ethers.getDefaultProvider("http://127.0.0.1:8545"); - -const { WeiPerRad, WeiPerRay, WeiPerWad } = require("../helper/unit"); -const TimeHelpers = require("../helper/time"); -const AssertHelpers = require("../helper/assert"); -const { createProxyWallets } = require("../helper/proxy-wallets"); -const { DeployerAddress, AliceAddress, BobAddress } = require("../helper/address"); -const PositionHelper = require("../helper/positions"); -const { parseEther, parseUnits, defaultAbiCoder, formatBytes32String } = require("ethers/lib/utils"); -const { loadFixture } = require("../helper/fixtures"); -const { getProxy } = require("../../common/proxies"); -const { getContractAt } = require("../helper/contracts"); -const pools = require("../../common/collateral"); - -const { expect } = chai; - -const CLOSE_FACTOR_BPS = BigNumber.from(5000); -const LIQUIDATOR_INCENTIVE_BPS = BigNumber.from(10500); -const TREASURY_FEE_BPS = BigNumber.from(5000); -const COLLATERAL_POOL_ID = formatBytes32String("XDC"); -const BPS = BigNumber.from(10000); - -const setup = async () => { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - const WXDC = await artifacts.initializeInterfaceAt("WXDC", "WXDC"); - - const collateralPoolConfig = await getProxy(proxyFactory, "CollateralPoolConfig"); - const bookKeeper = await getProxy(proxyFactory, "BookKeeper"); - const positionManager = await getProxy(proxyFactory, "PositionManager"); - const stabilityFeeCollector = await getProxy(proxyFactory, "StabilityFeeCollector"); - const fixedSpreadLiquidationStrategy = await getProxy(proxyFactory, "FixedSpreadLiquidationStrategy"); - const liquidationEngineAsAdmin = await getProxy(proxyFactory, "LiquidationEngine"); - const systemDebtEngine = await getProxy(proxyFactory, "SystemDebtEngine"); - const fathomStablecoin = await getProxy(proxyFactory, "FathomStablecoin"); - const priceOracle = await getProxy(proxyFactory, "PriceOracle"); - const proxyWalletRegistry = await getProxy(proxyFactory, "ProxyWalletRegistry"); - await proxyWalletRegistry.setDecentralizedMode(true); - - const liquidationEngine = getContractAt("LiquidationEngine", liquidationEngineAsAdmin.address, BobAddress); - - const fathomToken = await artifacts.initializeInterfaceAt("FathomToken", "FathomToken"); - const simplePriceFeed = await artifacts.initializeInterfaceAt("SimplePriceFeed", "SimplePriceFeed"); - - ({ - proxyWallets: [aliceProxyWallet], - } = await createProxyWallets([AliceAddress, BobAddress])); - - await collateralPoolConfig.setStabilityFeeRate(pools.XDC, WeiPerRay, { gasLimit: 1000000 }); - await collateralPoolConfig.setLiquidationRatio(pools.XDC, WeiPerRay, { gasLimit: 1000000 }); - await collateralPoolConfig.setLiquidatorIncentiveBps(pools.XDC, LIQUIDATOR_INCENTIVE_BPS, { gasLimit: 1000000 }); - await collateralPoolConfig.setCloseFactorBps(pools.XDC, CLOSE_FACTOR_BPS, { gasLimit: 1000000 }); - await collateralPoolConfig.setTreasuryFeesBps(pools.XDC, TREASURY_FEE_BPS, { gasLimit: 1000000 }); - - await bookKeeper.whitelist(liquidationEngine.address, { from: BobAddress, gasLimit: 3000000 }); - await bookKeeper.whitelist(fixedSpreadLiquidationStrategy.address, { from: BobAddress, gasLimit: 3000000 }); - await liquidationEngineAsAdmin.addToWhitelist(BobAddress); - - return { - bookKeeper, - collateralPoolConfig, - positionManager, - simplePriceFeed, - aliceProxyWallet, - stabilityFeeCollector, - fathomToken, - liquidationEngine, - systemDebtEngine, - fathomStablecoin, - fixedSpreadLiquidationStrategy, - priceOracle, - WXDC, - }; -}; - -describe("LiquidationEngine", () => { - // Contracts - let aliceProxyWallet; - let WXDC; - let bookKeeper; - let fathomToken; - let positionManager; - let stabilityFeeCollector; - let liquidationEngine; - let fixedSpreadLiquidationStrategy; - let fathomStablecoin; - let simplePriceFeed; - let systemDebtEngine; - let collateralPoolConfig; - let priceOracle; - - before(async () => { - await snapshot.revertToSnapshot(); - }); - - beforeEach(async () => { - ({ - bookKeeper, - collateralPoolConfig, - positionManager, - WXDC, - simplePriceFeed, - aliceProxyWallet, - stabilityFeeCollector, - fathomToken, - liquidationEngine, - systemDebtEngine, - fathomStablecoin, - fixedSpreadLiquidationStrategy, - priceOracle, - } = await loadFixture(setup)); - }); - - describe("#liquidate", async () => { - context("price drop but does not make the position underwater", async () => { - it("should revert", async () => { - // 1. Set price for XDC to 2 USD - await simplePriceFeed.setPrice(WeiPerRay.mul(2), { gasLimit: 1000000 }); - await priceOracle.setPrice(COLLATERAL_POOL_ID); - - // 2. Alice open a new position with 1 XDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, COLLATERAL_POOL_ID, WeiPerWad, WeiPerWad); - const alicePositionAddress = await positionManager.positions(1); - - // 3. XDC price drop to 1 USD - await simplePriceFeed.setPrice(WeiPerRay, { gasLimit: 1000000 }); - await priceOracle.setPrice(COLLATERAL_POOL_ID); - - // 3.5 whitelist bob as liquidator - // 4. Bob try to liquidate Alice's position but failed due to the price did not drop low enough - await expect( - liquidationEngine["liquidate(bytes32,address,uint256,uint256,address,bytes)"]( - COLLATERAL_POOL_ID, - alicePositionAddress, - 1, - 1, - AliceAddress, - "0x", - { gasLimit: 3000000 } - ) - ).to.be.revertedWith("LiquidationEngine/position-is-safe"); - }); - }); - - context("safety buffer -0.1%, but liquidator does not have enough FXD to liquidate", async () => { - it("should revert", async () => { - // 1. Set priceWithSafetyMargin for XDC to 2 USD - await simplePriceFeed.setPrice(WeiPerRay.mul(2), { gasLimit: 1000000 }); - await priceOracle.setPrice(COLLATERAL_POOL_ID); - await collateralPoolConfig.setLiquidationRatio(COLLATERAL_POOL_ID, WeiPerRay, { gasLimit: 1000000 }); - - // 2. Alice open a new position with 1 XDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, COLLATERAL_POOL_ID, WeiPerWad, WeiPerWad); - const alicePositionAddress = await positionManager.positions(1); - - // 3. XDC price drop to 0.99 USD - await simplePriceFeed.setPrice(WeiPerRay.sub(1).div(1e9), { gasLimit: 1000000 }); - await priceOracle.setPrice(COLLATERAL_POOL_ID); - - // 4. Bob liquidate Alice's position up to full close factor successfully - const debtShareToRepay = parseEther("0.5"); - await bookKeeper.whitelist(liquidationEngine.address, { gasLimit: 1000000 }); - - await expect( - liquidationEngine["liquidate(bytes32,address,uint256,uint256,address,bytes)"]( - COLLATERAL_POOL_ID, - alicePositionAddress, - debtShareToRepay, - MaxUint256, - BobAddress, - defaultAbiCoder.encode(["address", "bytes"], [BobAddress, []]), - { gasLimit: 1000000 } - ) - ).to.be.reverted; - }); - }); - - context("main liquidation scenarios", async () => { - const testParams = [ - { - label: "safety buffer -0.18%, position is liquidated up to full close factor", - collateralAmount: "10", - collateralFactor: "0.7", - liquidatorIncentiveBps: "10500", - treasuryFeeBps: "5000", - closeFactorBps: "5000", - debtFloor: "100", - drawStablecoinAmount: "2000", - startingPrice: "420", - nextPrice: "285", - debtShareToRepay: "1000", - expectedDebtValueToRepay: "1000", - expectedSeizedCollateral: "3.684210526315790000", - expectedDebtShareAfterLiquidation: "1000", - expectedSystemBadDebt: "0", - }, - { - label: "safety buffer -0.18%, position is liquidated up to some portion of close factor", - collateralAmount: "10", - collateralFactor: "0.7", - liquidatorIncentiveBps: "10500", - treasuryFeeBps: "5000", - closeFactorBps: "5000", - debtFloor: "100", - drawStablecoinAmount: "2000", - startingPrice: "420", - nextPrice: "285", - debtShareToRepay: "200", - expectedDebtValueToRepay: "200", - expectedSeizedCollateral: "0.7368", - expectedDebtShareAfterLiquidation: "1800", - expectedSystemBadDebt: "0", - }, - { - label: "safety buffer -0.18%, position is liquidated exceeding close factor", - collateralAmount: "10", - collateralFactor: "0.7", - liquidatorIncentiveBps: "10500", - treasuryFeeBps: "5000", - closeFactorBps: "5000", - debtFloor: "100", - drawStablecoinAmount: "2000", - startingPrice: "420", - nextPrice: "285", - debtShareToRepay: "2000", - expectedDebtValueToRepay: "1000", - expectedSeizedCollateral: "3.684210526315790000", - expectedDebtShareAfterLiquidation: "1000", - expectedSystemBadDebt: "0", - }, - { - label: "safety buffer -30%, position is liquidated up to full close factor, bad debt", - collateralAmount: "10", - collateralFactor: "0.7", - liquidatorIncentiveBps: "10500", - treasuryFeeBps: "5000", - closeFactorBps: "5000", - debtFloor: "100", - drawStablecoinAmount: "2000", - startingPrice: "420", - nextPrice: "200", - debtShareToRepay: "1000", - expectedDebtValueToRepay: "1904.761905", - expectedSeizedCollateral: "10", - expectedDebtShareAfterLiquidation: "0", - expectedSystemBadDebt: "95.238095", - }, - { - label: "safety buffer -30%, position is liquidated up to some portion of full close factor, bad debt", - collateralAmount: "10", - collateralFactor: "0.7", - liquidatorIncentiveBps: "10500", - treasuryFeeBps: "5000", - closeFactorBps: "5000", - debtFloor: "100", - drawStablecoinAmount: "2000", - startingPrice: "420", - nextPrice: "200", - debtShareToRepay: "200", - expectedDebtValueToRepay: "1904.761905", - expectedSeizedCollateral: "10", - expectedDebtShareAfterLiquidation: "0", - expectedSystemBadDebt: "95.238095", - }, - { - label: "safety buffer -10%, position collateral is fully liquidated because debt floor", - collateralAmount: "10", - collateralFactor: "0.7", - liquidatorIncentiveBps: "10500", - treasuryFeeBps: "5000", - closeFactorBps: "5000", - debtFloor: "1500", - drawStablecoinAmount: "2000", - startingPrice: "420", - nextPrice: "250", - debtShareToRepay: "1000", - expectedDebtValueToRepay: "2000", - expectedSeizedCollateral: "8.4", - expectedDebtShareAfterLiquidation: "0", - expectedSystemBadDebt: "0", - }, - { - label: "safety buffer -5.71% with 99% collateral factor, position is liquidated up to full close factor, bad debt", - collateralAmount: "2000", - collateralFactor: "0.99", - liquidatorIncentiveBps: "10500", - treasuryFeeBps: "5000", - closeFactorBps: "5000", - debtFloor: "100", - drawStablecoinAmount: "1975", - startingPrice: "1", - nextPrice: "0.99", - debtShareToRepay: "987.5", - expectedDebtValueToRepay: "1885.714286", - expectedSeizedCollateral: "2000", - expectedDebtShareAfterLiquidation: "0", - expectedSystemBadDebt: "89.285714", - }, - { - label: "safety buffer -5.71% with 99% collateral factor, position collateral is fully liquidated because debt floor", - collateralAmount: "2000", - collateralFactor: "0.9", - liquidatorIncentiveBps: "10500", - treasuryFeeBps: "5000", - closeFactorBps: "5000", - debtFloor: "100", - drawStablecoinAmount: "1800", - startingPrice: "1", - nextPrice: "0.99", - debtShareToRepay: "900", - expectedDebtValueToRepay: "900", - expectedSeizedCollateral: "954.5455", - expectedDebtShareAfterLiquidation: "900", - expectedSystemBadDebt: "0", - }, - { - label: "safety buffer -7.83% with 99% collateral factor, position is liquidated up to full close factor, bad debt", - collateralAmount: "2000", - collateralFactor: "0.9", - liquidatorIncentiveBps: "10500", - treasuryFeeBps: "5000", - closeFactorBps: "5000", - debtFloor: "100", - drawStablecoinAmount: "1800", - startingPrice: "1", - nextPrice: "0.92", - debtShareToRepay: "900", - expectedDebtValueToRepay: "1752.380952", - expectedSeizedCollateral: "2000", - expectedDebtShareAfterLiquidation: "0", - expectedSystemBadDebt: "47.619048", - }, - { - label: "safety buffer -8.90% with 99% collateral factor, position is liquidated up to full close factor, bad debt", - collateralAmount: "2000", - collateralFactor: "0.9", - liquidatorIncentiveBps: "10500", - treasuryFeeBps: "5000", - closeFactorBps: "2500", - debtFloor: "100", - drawStablecoinAmount: "1800", - startingPrice: "1", - nextPrice: "0.91", - debtShareToRepay: "450", - expectedDebtValueToRepay: "1733.333333", - expectedSeizedCollateral: "2000", - expectedDebtShareAfterLiquidation: "0", - expectedSystemBadDebt: "66.666667", - }, - { - label: "safety buffer -0.91% with 99% collateral factor, position collateral is fully liquidated because debt floor", - collateralAmount: "555.560", - collateralFactor: "0.9", - liquidatorIncentiveBps: "10500", - treasuryFeeBps: "5000", - closeFactorBps: "2500", - debtFloor: "500", - drawStablecoinAmount: "500", - startingPrice: "1", - nextPrice: "0.99", - debtShareToRepay: "125", - expectedDebtValueToRepay: "500", - expectedSeizedCollateral: "530.3030303", - expectedDebtShareAfterLiquidation: "0", - expectedSystemBadDebt: "0", - }, - { - label: "safety buffer -0.91% with 99% collateral factor, position is liquidated up to full close factor", - collateralAmount: "555.560", - collateralFactor: "0.9", - liquidatorIncentiveBps: "10500", - treasuryFeeBps: "5000", - closeFactorBps: "2500", - debtFloor: "100", - drawStablecoinAmount: "500", - startingPrice: "1", - nextPrice: "0.99", - debtShareToRepay: "125", - expectedDebtValueToRepay: "125", - expectedSeizedCollateral: "132.5758", - expectedDebtShareAfterLiquidation: "375.00", - expectedSystemBadDebt: "0", - }, - ]; - for (let i = 0; i < testParams.length; i++) { - const testParam = testParams[i]; - it(testParam.label, async () => { - await fathomStablecoin.approve(fixedSpreadLiquidationStrategy.address, MaxUint256, { from: BobAddress, gasLimit: 1000000 }); - await fathomStablecoin.mint(BobAddress, parseUnits(testParam.debtShareToRepay, 46), { gasLimit: 1000000 }); - - await collateralPoolConfig.setLiquidatorIncentiveBps(COLLATERAL_POOL_ID, testParam.liquidatorIncentiveBps); - await collateralPoolConfig.setCloseFactorBps(COLLATERAL_POOL_ID, testParam.closeFactorBps); - await simplePriceFeed.setPrice(parseUnits(testParam.startingPrice, 18), { gasLimit: 3000000 }); - await priceOracle.setPrice(COLLATERAL_POOL_ID); - let ratio = WeiPerRay.mul(1000).div(parseUnits(testParam.collateralFactor, 3)); - await collateralPoolConfig.setLiquidationRatio(COLLATERAL_POOL_ID, ratio, { gasLimit: 3000000 }); - await collateralPoolConfig.setDebtFloor(COLLATERAL_POOL_ID, parseUnits(testParam.debtFloor, 45), { gasLimit: 1000000 }); - - // 2. Alice open a new position with 1 XDC and draw 1 FXD - const lockedCollateralAmount = parseEther(testParam.collateralAmount); - const drawStablecoinAmount = parseEther(testParam.drawStablecoinAmount); - - await PositionHelper.openXDCPositionAndDraw( - aliceProxyWallet, - AliceAddress, - COLLATERAL_POOL_ID, - lockedCollateralAmount, - drawStablecoinAmount - ); - const alicePositionAddress = await positionManager.positions(1); - const alicePosition = await bookKeeper.positions(COLLATERAL_POOL_ID, alicePositionAddress); - - // 3. XDC price drop to 0.99 USD - await simplePriceFeed.setPrice(parseUnits(testParam.nextPrice, 18), { gasLimit: 3000000 }); - await priceOracle.setPrice(COLLATERAL_POOL_ID); - - // 4. Bob liquidate Alice's position up to full close factor successfully - const debtShareToRepay = parseEther(testParam.debtShareToRepay); - const bobStablecoinBeforeLiquidation = await fathomStablecoin.balanceOf(BobAddress); //await bookKeeper.stablecoin(BobAddress) - await liquidationEngine["liquidate(bytes32,address,uint256,uint256,address,bytes)"]( - COLLATERAL_POOL_ID, - alicePositionAddress, - debtShareToRepay, - MaxUint256, - BobAddress, - "0x", - { gasLimit: 5000000 } - ); - const bobWETHAfterLiq = await WXDC.balanceOf(BobAddress); - // 5. Settle system bad debt - await systemDebtEngine.settleSystemBadDebt(await bookKeeper.stablecoin(systemDebtEngine.address), { gasLimit: 1000000 }); - - const bobStablecoinAfterLiquidation = await fathomStablecoin.balanceOf(BobAddress); //await bookKeeper.stablecoin(BobAddress) - - const alicePositionAfterLiquidation = await bookKeeper.positions(COLLATERAL_POOL_ID, alicePositionAddress); - const expectedSeizedCollateral = parseUnits(testParam.expectedSeizedCollateral, 18); - const expectedLiquidatorIncentive = expectedSeizedCollateral.sub(expectedSeizedCollateral.mul(BPS).div(testParam.liquidatorIncentiveBps)); - const expectedTreasuryFee = expectedLiquidatorIncentive.mul(testParam.treasuryFeeBps).div(BPS); - const expectedCollateralBobShouldReceive = expectedSeizedCollateral.sub(expectedTreasuryFee).div(WeiPerWad); - - AssertHelpers.assertAlmostEqual( - alicePosition.lockedCollateral.sub(alicePositionAfterLiquidation.lockedCollateral).toString(), - expectedSeizedCollateral.toString() - ); - expect(alicePositionAfterLiquidation.debtShare).to.be.eq(parseUnits(testParam.expectedDebtShareAfterLiquidation, 18)); - AssertHelpers.assertAlmostEqual( - (await bookKeeper.systemBadDebt(systemDebtEngine.address)).toString(), - parseUnits(testParam.expectedSystemBadDebt, 45).toString() - ); - AssertHelpers.assertAlmostEqual(bobWETHAfterLiq.div(WeiPerWad).toString(), expectedCollateralBobShouldReceive.toString()); - AssertHelpers.assertAlmostEqual( - bobStablecoinBeforeLiquidation.sub(bobStablecoinAfterLiquidation).toString(), - parseUnits(testParam.expectedDebtValueToRepay, 18).toString() - ); - AssertHelpers.assertAlmostEqual( - (await bookKeeper.collateralToken(COLLATERAL_POOL_ID, systemDebtEngine.address)).toString(), - expectedTreasuryFee.toString() - ); - }); - } - }); - - context("1st liquidation keep position unsafe, 2nd position fully liquidate the position", async () => { - it("should success", async () => { - const testParam = { - label: "safety buffer -0.18%, position is liquidated up to full close factor", - collateralAmount: "10", - collateralFactor: "0.7", - liquidatorIncentiveBps: "10500", - treasuryFeeBps: "5000", - closeFactorBps: "5000", - debtFloor: "100", - drawStablecoinAmount: "2000", - startingPrice: "420", - nextPrice: "250", - debtShareToRepay: "200", - expectedDebtValueToRepay: "200", - expectedSeizedCollateral: "0.84", - expectedDebtShareAfterLiquidation: "1800", - expectedSystemBadDebt: "0", - }; - it(testParam.label, async () => { - await collateralPoolConfig.setLiquidatorIncentiveBps(COLLATERAL_POOL_ID, testParam.liquidatorIncentiveBps); - await collateralPoolConfig.setCloseFactorBps(COLLATERAL_POOL_ID, testParam.closeFactorBps); - await simplePriceFeed.setPrice(parseUnits(testParam.startingPrice, 18), { gasLimit: 1000000 }); - await priceOracle.setPrice(COLLATERAL_POOL_ID); - let ratio = WeiPerRay.mul(1000).div(parseUnits(testParam.collateralFactor, 3)); - await collateralPoolConfig.setLiquidationRatio(COLLATERAL_POOL_ID, ratio, { gasLimit: 1000000 }); - await collateralPoolConfig.setDebtFloor(COLLATERAL_POOL_ID, parseUnits(testParam.debtFloor, 45), { gasLimit: 1000000 }); - - // 2. Alice open a new position with 1 XDC and draw 1 FXD - const lockedCollateralAmount = parseEther(testParam.collateralAmount); - const drawStablecoinAmount = parseEther(testParam.drawStablecoinAmount); - // await XDC.approve(aliceProxyWallet.address, lockedCollateralAmount, { from: AliceAddress }) - await PositionHelper.openXDCPositionAndDraw( - aliceProxyWallet, - AliceAddress, - COLLATERAL_POOL_ID, - lockedCollateralAmount, - drawStablecoinAmount - ); - const alicePositionAddress = await positionManager.positions(1); - // const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress) - const alicePosition = await bookKeeper.positions(COLLATERAL_POOL_ID, alicePositionAddress); - - // 3. XDC price drop to 0.99 USD - await simplePriceFeed.setPrice(parseUnits(testParam.nextPrice, 18), { gasLimit: 1000000 }); - await priceOracle.setPrice(COLLATERAL_POOL_ID); - - // 4. Bob liquidate Alice's position up to full close factor successfully - const debtShareToRepay = parseEther(testParam.debtShareToRepay); - const bobStablecoinBeforeLiquidation = await bookKeeper.stablecoin(BobAddress); - await liquidationEngine["liquidate(bytes32,address,uint256,uint256,address,bytes)"]( - COLLATERAL_POOL_ID, - alicePositionAddress, - debtShareToRepay, - MaxUint256, - BobAddress, - "0x", - { gasLimit: 1000000 } - ); - - // 5. Settle system bad debt - await systemDebtEngine.settleSystemBadDebt(await bookKeeper.stablecoin(systemDebtEngine.address), { gasLimit: 1000000 }); - - const bobStablecoinAfterLiquidation = await bookKeeper.stablecoin(BobAddress); - - const alicePositionAfterLiquidation = await bookKeeper.positions(COLLATERAL_POOL_ID, alicePositionAddress); - const expectedSeizedCollateral = parseUnits(testParam.expectedSeizedCollateral, 18); - const expectedLiquidatorIncentive = expectedSeizedCollateral.sub(expectedSeizedCollateral.mul(BPS).div(testParam.liquidatorIncentiveBps)); - const expectedTreasuryFee = expectedLiquidatorIncentive.mul(testParam.treasuryFeeBps).div(BPS); - - AssertHelpers.assertAlmostEqual( - alicePosition.lockedCollateral.sub(alicePositionAfterLiquidation.lockedCollateral).toString(), - expectedSeizedCollateral.toString() - ); - AssertHelpers.assertAlmostEqual( - alicePosition.lockedCollateral.sub(alicePositionAfterLiquidation.lockedCollateral).toString(), - expectedSeizedCollateral.toString() - ); - expect(alicePositionAfterLiquidation.debtShare).to.be.eq(parseUnits(testParam.expectedDebtShareAfterLiquidation, 18)); - AssertHelpers.assertAlmostEqual( - (await bookKeeper.systemBadDebt(systemDebtEngine.address)).toString(), - parseUnits(testParam.expectedSystemBadDebt, 45).toString() - ); - - const expectedCollateralBobShouldReceive = expectedSeizedCollateral.sub(expectedTreasuryFee).div(WeiPerWad); - AssertHelpers.assertAlmostEqual((await provider.getBalance(BobAddress)).toString(), expectedCollateralBobShouldReceive.toString()); - AssertHelpers.assertAlmostEqual( - bobStablecoinBeforeLiquidation.sub(bobStablecoinAfterLiquidation).toString(), - parseUnits(testParam.expectedDebtValueToRepay, 45).toString() - ); - AssertHelpers.assertAlmostEqual( - (await bookKeeper.collateralToken(COLLATERAL_POOL_ID, systemDebtEngine.address)).toString(), - expectedTreasuryFee.toString() - ); - expect( - await fathomToken.balanceOf(aliceProxyWallet.address), - "Alice's proxy wallet should have more than 0 FATHOM, because the liquidation process will distribute the pending FATHOM rewards to the position owner" - ).to.not.equal(0); - - // Second Liquidation - await liquidationEngine["liquidate(bytes32,address,uint256,uint256,address,bytes)"]( - COLLATERAL_POOL_ID, - alicePositionAddress, - MaxUint256, - MaxUint256, - BobAddress, - "0x", - { gasLimit: 1000000 } - ); - const alicePositionAfterLiquidation2 = await bookKeeper.positions(COLLATERAL_POOL_ID, alicePositionAddress); - expect(alicePositionAfterLiquidation2.lockedCollateral).to.be.eq(parseEther("4.62")); - expect(alicePositionAfterLiquidation2.debtShare).to.be.eq(parseEther("900")); - }); - }); - }); - - context("safety buffer -20%, position is liquidated up to full close factor with some interest and debt floor", async () => { - it("should success", async () => { - // 0 whitelist bob as liquidator - await fathomStablecoin.mint(BobAddress, parseUnits("3000", 45), { gasLimit: 1000000 }); - await fathomStablecoin.approve(fixedSpreadLiquidationStrategy.address, MaxUint256, { from: BobAddress, gasLimit: 1000000 }); - - // 1. Set priceWithSafetyMargin for XDC to 420 USD - await simplePriceFeed.setPrice(parseUnits("367", 18), { gasLimit: 1000000 }); - await priceOracle.setPrice(COLLATERAL_POOL_ID); - let ratio = WeiPerRay.mul(1000).div(parseUnits("0.8", 3)); - await collateralPoolConfig.setLiquidationRatio(COLLATERAL_POOL_ID, ratio, { gasLimit: 1000000 }); - // await collateralPoolConfig.setPriceWithSafetyMargin(COLLATERAL_POOL_ID, parseUnits("294", 27), { gasLimit: 1000000 }) - await collateralPoolConfig.setDebtFloor(COLLATERAL_POOL_ID, parseEther("100").mul(WeiPerRay), { gasLimit: 1000000 }); - - // 2. Alice open a new position with 10 XDC and draw 2000 FXD - const lockedCollateralAmount = parseEther("10"); - const drawStablecoinAmount = parseEther("2000"); - - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, COLLATERAL_POOL_ID, lockedCollateralAmount, drawStablecoinAmount); - - // Set stability fee rate to 0.5% APR - await collateralPoolConfig.setStabilityFeeRate(COLLATERAL_POOL_ID, BigNumber.from("1000000000158153903837946258"), { gasLimit: 1000000 }); - - const alicePositionAddress = await positionManager.positions(1); - // const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress) - const alicePosition = await bookKeeper.positions(COLLATERAL_POOL_ID, alicePositionAddress); - - // 3. 1 year passed, XDC price drop to 285 USD - await TimeHelpers.increase(TimeHelpers.duration.seconds(ethers.BigNumber.from("31536000"))); - await stabilityFeeCollector.collect(COLLATERAL_POOL_ID, { gasLimit: 1000000 }); - const aliceDebtValueAfterOneYear = (await bookKeeper.positions(COLLATERAL_POOL_ID, alicePositionAddress)).debtShare.mul( - (await collateralPoolConfig.collateralPools(COLLATERAL_POOL_ID)).debtAccumulatedRate - ); - AssertHelpers.assertAlmostEqual(aliceDebtValueAfterOneYear.toString(), parseEther("2010").mul(WeiPerRay).toString()); - await simplePriceFeed.setPrice(parseEther("249.37"), { gasLimit: 1000000 }); - await priceOracle.setPrice(COLLATERAL_POOL_ID); - - // 4. Bob liquidate Alice's position up to full close factor successfully - const debtShareToRepay = parseEther("1000"); - const bobStablecoinBeforeLiquidation = await fathomStablecoin.balanceOf(BobAddress); - await liquidationEngine["liquidate(bytes32,address,uint256,uint256,address,bytes)"]( - COLLATERAL_POOL_ID, - alicePositionAddress, - debtShareToRepay, - MaxUint256, - BobAddress, - "0x", - { gasLimit: 2000000 } - ); - const bobWETHAfterLiq = await WXDC.balanceOf(BobAddress); - - // // 5. Settle system bad debt - await systemDebtEngine.settleSystemBadDebt(await bookKeeper.systemBadDebt(systemDebtEngine.address), { gasLimit: 1000000 }); - AssertHelpers.assertAlmostEqual( - (await bookKeeper.stablecoin(systemDebtEngine.address)).toString(), - parseEther("10").mul(WeiPerRay).toString() - ); // There should be 10 FXD left in SystemDebtEngine collected from stability fee after `settleSystemBadDebt` - - const bobStablecoinAfterLiquidation = await fathomStablecoin.balanceOf(BobAddress); - - const alicePositionAfterLiquidation = await bookKeeper.positions(COLLATERAL_POOL_ID, alicePositionAddress); - - AssertHelpers.assertAlmostEqual(alicePositionAfterLiquidation.lockedCollateral.toString(), parseEther("5.768").toString()); - expect(alicePositionAfterLiquidation.debtShare, "debtShare should be 1000 FXD, because Bob liquidated 1000 FXD from Alice's position") - .to.be.equal(alicePosition.debtShare.sub(debtShareToRepay)) - .to.be.equal(parseEther("1000")); - expect(await bookKeeper.systemBadDebt(systemDebtEngine.address), "System bad debt should be 0 FXD").to.be.equal(0); - - AssertHelpers.assertAlmostEqual(bobWETHAfterLiq.div(WeiPerWad).toString(), parseEther("4.1309099").div(WeiPerWad).toString()); - AssertHelpers.assertAlmostEqual(bobStablecoinBeforeLiquidation.sub(bobStablecoinAfterLiquidation).toString(), parseEther("1005").toString()); // Bob should pay 1005 FXD for this liquidation - AssertHelpers.assertAlmostEqual( - (await bookKeeper.collateralToken(COLLATERAL_POOL_ID, systemDebtEngine.address)).toString(), - parseEther("0.1007539").toString() - ); - }); - }); - - context("batch liquidation", async () => { - const testParams = [ - { - label: "safety buffer -0.18%, position is liquidated up to full close factor", - collateralAmount: "10", - collateralFactor: "0.7", - liquidatorIncentiveBps: "10500", - treasuryFeeBps: "5000", - closeFactorBps: "5000", - debtFloor: "100", - drawStablecoinAmount: "2000", - startingPrice: "420", - nextPrice: "285", - debtShareToRepay: "1000", - expectedDebtValueToRepay: "2000", - expectedSeizedCollateral: "3.684210526315790000", - expectedDebtShareAfterLiquidation: "1000", - expectedSystemBadDebt: "0", - }, - ]; - const testParam = testParams[0]; - it(testParam.label, async () => { - await fathomStablecoin.mint(BobAddress, parseUnits("2000", 46), { gasLimit: 1000000 }); - await fathomStablecoin.approve(fixedSpreadLiquidationStrategy.address, MaxUint256, { from: BobAddress, gasLimit: 1000000 }); - - await collateralPoolConfig.setLiquidatorIncentiveBps(COLLATERAL_POOL_ID, testParam.liquidatorIncentiveBps); - await collateralPoolConfig.setCloseFactorBps(COLLATERAL_POOL_ID, testParam.closeFactorBps); - await simplePriceFeed.setPrice(parseUnits(testParam.startingPrice, 18), { gasLimit: 1000000 }); - await priceOracle.setPrice(COLLATERAL_POOL_ID); - let ratio = WeiPerRay.mul(1000).div(parseUnits(testParam.collateralFactor, 3)); - await collateralPoolConfig.setLiquidationRatio(COLLATERAL_POOL_ID, ratio, { gasLimit: 1000000 }); - await collateralPoolConfig.setDebtFloor(COLLATERAL_POOL_ID, parseUnits(testParam.debtFloor, 45), { gasLimit: 1000000 }); - - // 2. Alice open a new position with 1 XDC and draw 1 FXD - const lockedCollateralAmount = parseEther(testParam.collateralAmount); - const drawStablecoinAmount = parseEther(testParam.drawStablecoinAmount); - - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, COLLATERAL_POOL_ID, lockedCollateralAmount, drawStablecoinAmount); - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, COLLATERAL_POOL_ID, lockedCollateralAmount, drawStablecoinAmount); - - const alicePositionAddress1 = await positionManager.positions(1); - const alicePositionAddress2 = await positionManager.positions(2); - const alicePosition = await bookKeeper.positions(COLLATERAL_POOL_ID, alicePositionAddress1); - - // 3. XDC price drop to 0.99 USD - await simplePriceFeed.setPrice(parseUnits(testParam.nextPrice, 18), { gasLimit: 1000000 }); - await priceOracle.setPrice(COLLATERAL_POOL_ID); - - // 4. Bob liquidate Alice's position up to full close factor successfully - const debtShareToRepay = parseEther(testParam.debtShareToRepay); - const bobStablecoinBeforeLiquidation = await fathomStablecoin.balanceOf(BobAddress); - - await liquidationEngine.batchLiquidate( - [COLLATERAL_POOL_ID, COLLATERAL_POOL_ID], - [alicePositionAddress1, alicePositionAddress2], - [debtShareToRepay, debtShareToRepay], - [MaxUint256, MaxUint256], - [BobAddress, BobAddress], - ["0x", "0x"], - { gasLimit: 4000000 } - ); - const bobWETHAfterLiq = await WXDC.balanceOf(BobAddress); - - // 5. Settle system bad debt - await systemDebtEngine.settleSystemBadDebt(await bookKeeper.stablecoin(systemDebtEngine.address), { gasLimit: 1000000 }); - - const bobStablecoinAfterLiquidation = await fathomStablecoin.balanceOf(BobAddress); - - const alicePositionAfterLiquidation = await bookKeeper.positions(COLLATERAL_POOL_ID, alicePositionAddress1); - const expectedSeizedCollateral = parseUnits(testParam.expectedSeizedCollateral, 18); - const expectedLiquidatorIncentive = expectedSeizedCollateral.sub(expectedSeizedCollateral.mul(BPS).div(testParam.liquidatorIncentiveBps)); - const expectedTreasuryFee = expectedLiquidatorIncentive.mul(testParam.treasuryFeeBps).div(BPS); - const expectedCollateralBobShouldReceive = expectedSeizedCollateral.sub(expectedTreasuryFee).mul(2); - - // TODO: check - AssertHelpers.assertAlmostEqual( - alicePosition.lockedCollateral.sub(alicePositionAfterLiquidation.lockedCollateral).toString(), - expectedSeizedCollateral.toString() - ); - - expect(alicePositionAfterLiquidation.debtShare).to.be.eq(parseUnits(testParam.expectedDebtShareAfterLiquidation, 18)); - - AssertHelpers.assertAlmostEqual( - (await bookKeeper.systemBadDebt(systemDebtEngine.address)).toString(), - parseUnits(testParam.expectedSystemBadDebt, 45).toString() - ); - - AssertHelpers.assertAlmostEqual(bobWETHAfterLiq.div(WeiPerWad).toString(), expectedCollateralBobShouldReceive.div(WeiPerWad).toString()); - - AssertHelpers.assertAlmostEqual( - bobStablecoinBeforeLiquidation.sub(bobStablecoinAfterLiquidation).toString(), - parseUnits(testParam.expectedDebtValueToRepay, 18).toString() - ); - - AssertHelpers.assertAlmostEqual( - (await bookKeeper.collateralToken(COLLATERAL_POOL_ID, systemDebtEngine.address)).toString(), - expectedTreasuryFee.mul(2).toString() - ); - }); - }); - }); -}); diff --git a/scripts/tests/integration/PositionPermissions.test.js b/scripts/tests/integration/PositionPermissions.test.js deleted file mode 100644 index 93300633..00000000 --- a/scripts/tests/integration/PositionPermissions.test.js +++ /dev/null @@ -1,1977 +0,0 @@ -const chai = require("chai"); -const { ethers, BigNumber } = require("ethers"); - -const { solidity } = require("ethereum-waffle"); -chai.use(solidity); - -const { WeiPerRad, WeiPerRay, WeiPerWad } = require("../helper/unit"); -const { createProxyWallets } = require("../helper/proxy-wallets"); -const { AliceAddress, BobAddress } = require("../helper/address"); -const PositionHelper = require("../helper/positions"); -const TimeHelpers = require("../helper/time"); -const { loadFixture } = require("../helper/fixtures"); -const { getProxy } = require("../../common/proxies"); -const pools = require("../../common/collateral"); - -const { expect } = chai; - -const setup = async () => { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - const simplePriceFeed = await artifacts.initializeInterfaceAt("SimplePriceFeed", "SimplePriceFeed"); - const fathomStablecoinProxyActions = await artifacts.initializeInterfaceAt("FathomStablecoinProxyActions", "FathomStablecoinProxyActions"); - - const bookKeeper = await getProxy(proxyFactory, "BookKeeper"); - const positionManager = await getProxy(proxyFactory, "PositionManager"); - const stablecoinAdapter = await getProxy(proxyFactory, "StablecoinAdapter"); - const fathomStablecoin = await getProxy(proxyFactory, "FathomStablecoin"); - const stabilityFeeCollector = await getProxy(proxyFactory, "StabilityFeeCollector"); - const priceOracle = await getProxy(proxyFactory, "PriceOracle"); - const collateralTokenAdapter = await getProxy(proxyFactory, "CollateralTokenAdapter"); - const collateralPoolConfig = await getProxy(proxyFactory, "CollateralPoolConfig"); - const proxyWalletRegistry = await getProxy(proxyFactory, "ProxyWalletRegistry"); - await proxyWalletRegistry.setDecentralizedMode(true); - - const collateralTokenAdapter2Addr = await collateralPoolConfig.getAdapter(pools.GLD); - const collateralTokenAdapter2 = await artifacts.initializeInterfaceAt("CollateralTokenAdapter", collateralTokenAdapter2Addr); - - ({ - proxyWallets: [aliceProxyWallet, bobProxyWallet], - } = await createProxyWallets([AliceAddress, BobAddress])); - - const gldAddr = await collateralTokenAdapter2.collateralToken(); - const GLD = await artifacts.initializeInterfaceAt("ERC20Mintable", gldAddr); - - await GLD.mint(AliceAddress, WeiPerWad.mul(1000), { gasLimit: 1000000 }); - await GLD.approve(aliceProxyWallet.address, WeiPerWad.mul(1000), { from: AliceAddress, gasLimit: 1000000 }); - await GLD.mint(BobAddress, WeiPerWad.mul(1000), { gasLimit: 1000000 }); - await GLD.approve(bobProxyWallet.address, WeiPerWad.mul(1000), { from: BobAddress, gasLimit: 1000000 }); - - await simplePriceFeed.setPrice(WeiPerRay, { gasLimit: 1000000 }); - await collateralPoolConfig.setStabilityFeeRate(pools.XDC, WeiPerRay, { gasLimit: 1000000 }); - await collateralPoolConfig.setStabilityFeeRate(pools.GLD, WeiPerRay, { gasLimit: 1000000 }); - - await priceOracle.setPrice(pools.GLD, { gasLimit: 1000000 }); - await TimeHelpers.increase(TimeHelpers.duration.seconds(BigNumber.from("900"))); - await priceOracle.setPrice(pools.GLD, { gasLimit: 1000000 }); - await priceOracle.setPrice(pools.XDC); - - return { - bookKeeper, - collateralTokenAdapter, - positionManager, - aliceProxyWallet, - bobProxyWallet, - fathomStablecoin, - fathomStablecoinProxyActions, - stablecoinAdapter, - stabilityFeeCollector, - simplePriceFeed, - collateralTokenAdapter2, - }; -}; - -describe("PositionPermissions", () => { - // Contracts - let aliceProxyWallet; - let bobProxyWallet; - let collateralTokenAdapter; - let stablecoinAdapter; - let bookKeeper; - let positionManager; - let fathomStablecoin; - let stabilityFeeCollector; - let simplePriceFeed; - let collateralTokenAdapter2; - - before(async () => { - await snapshot.revertToSnapshot(); - }); - - beforeEach(async () => { - ({ - bookKeeper, - collateralTokenAdapter, - positionManager, - aliceProxyWallet, - bobProxyWallet, - fathomStablecoin, - fathomStablecoinProxyActions, - stablecoinAdapter, - stabilityFeeCollector, - simplePriceFeed, - collateralTokenAdapter2, - } = await loadFixture(setup)); - }); - - describe("#permissions", async () => { - context("position owner is able to", async () => { - context("lock collateral into their own position", async () => { - it("should success", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - - expect(alicePosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC").to.be.equal(WeiPerWad); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Alice try to adjust position, add 2 WXDC to position - const posId = await positionManager.ownerLastPositionId(aliceProxyWallet.address); - const own = await positionManager.owners(1); - await PositionHelper.lockXDC(aliceProxyWallet, AliceAddress, 1, WeiPerWad.mul(2)); - const aliceAdjustPosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 3 WXDC, because Alice locked 2 more WXDC").to.be.equal( - WeiPerWad.mul(3) - ); - expect(aliceAdjustPosition.debtShare, "debtShare should be 1 FXD, because Alice didn't draw more").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - }); - }); - - context("move collateral", async () => { - context("same collateral pool", async () => { - context( - "call openLockTokenAndDraw, unlock collateral and move the collateral from one position to another position within the same collateral pool", - async () => { - it("should success", async () => { - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC").to.be.equal(WeiPerWad); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Alice open a second new position with 2 WXDC and draw 1 FXD at same collateral pool - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(2), WeiPerWad); - - const alicePositionAddress2 = await positionManager.positions(2); - const fathomStablecoinBalance2 = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition2 = await bookKeeper.positions(pools.XDC, alicePositionAddress2); - expect(alicePosition2.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal( - WeiPerWad.mul(2) - ); - expect(alicePosition2.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress2), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance2, "Alice should receive 2 FXD from drawing FXD 2 times form 2 positions").to.be.equal( - WeiPerWad.mul(2) - ); - // 3. Alice try to unlock 1 WXDC at second position - await PositionHelper.adjustPosition( - aliceProxyWallet, - AliceAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - WeiPerWad.mul(-1), - 0 - ); - const aliceAdjustPosition = await bookKeeper.positions(pools.XDC, alicePositionAddress2); - expect( - aliceAdjustPosition.lockedCollateral, - "Position #2's lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC from it" - ).to.be.equal(WeiPerWad); - expect(aliceAdjustPosition.debtShare, "debtShare should be 1 FXD, because Alice didn't draw more").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress2), - "collateralToken inside Alice's Position#2 address should be 1 WXDC, because Alice unlocked 1 WXDC from the position" - ).to.be.equal(WeiPerWad); - // 4. Alice try to move collateral from second position to first position - await PositionHelper.moveCollateral( - aliceProxyWallet, - AliceAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - alicePositionAddress, - WeiPerWad - ); - const aliceMoveCollateral = await bookKeeper.positions(pools.XDC, alicePositionAddress); - const fathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(AliceAddress); - expect( - aliceMoveCollateral.lockedCollateral, - "Alice's Position #1 lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC" - ).to.be.equal(WeiPerWad); - expect(aliceMoveCollateral.debtShare, "Alice's Position #1 debtShare should be 1 FXD, because Alice doesn't draw more").to.be.equal( - WeiPerWad - ); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's Position #1 address should be 1 WXDC, because Alice moved 1 WXDC from Position #2 to Position #1." - ).to.be.equal(WeiPerWad); - expect(fathomStablecoinBalancefinal, "Alice should receive 2 FXD from drawing 2 FXD, because Alice draw 2 times").to.be.equal( - WeiPerWad.mul(2) - ); - }); - } - ); - context("open position, deposit collateral and move collateral from one position to another position", async () => { - it("should success", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC").to.be.equal(WeiPerWad); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Alice open a second new position at same collateral pool - await PositionHelper.openPosition(aliceProxyWallet, AliceAddress, pools.XDC); - const alicePositionAddress2 = await positionManager.positions(2); - const alicePosition2 = await bookKeeper.positions(pools.XDC, alicePositionAddress2); - expect(alicePosition2.lockedCollateral, "lockedCollateral should be 0 WXDC, because Alice doesn't locked WXDC").to.be.equal(0); - expect(alicePosition2.debtShare, "debtShare should be 0 FXD, because doesn't drew FXD").to.be.equal(0); - // 3. Alice deposit 3 WXDC to new position - await PositionHelper.xdcAdapterDeposit(aliceProxyWallet, AliceAddress, await positionManager.positions(2), WeiPerWad.mul(3)); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress2), - "collateralToken inside Alice's second position address should be 3 WXDC, because Alice deposit 3 WXDC into the second position" - ).to.be.equal(WeiPerWad.mul(3)); - // 4. Alice try to move collateral from second position to first position - await PositionHelper.moveCollateral( - aliceProxyWallet, - AliceAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - alicePositionAddress, - WeiPerWad - ); - const aliceMoveCollateral = await bookKeeper.positions(pools.XDC, alicePositionAddress); - const fathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(AliceAddress); - expect( - aliceMoveCollateral.lockedCollateral, - "Alice's Position #1 lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC" - ).to.be.equal(WeiPerWad); - expect(aliceMoveCollateral.debtShare, "Alice's Position #1 debtShare should be 1 FXD, because Alice doesn't draw more").to.be.equal( - WeiPerWad - ); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's Position #1 address should be 1 WXDC, because Alice moved 1 WXDC from Position #2 to Position #1." - ).to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress2), - "collateralToken inside Alice's Position #2 address should be 2 WXDC, because Alice moved 1 WXDC to Position #1" - ).to.be.equal(WeiPerWad.mul(2)); - expect(fathomStablecoinBalancefinal, "Alice should receive 1 FXD, because Alice draw 1 time").to.be.equal(WeiPerWad); - }); - }); - context("Alice open a position, lock collateral and move collateral to Bob's position", async () => { - it("should success", async () => { - // 1. Alice open position - await PositionHelper.openPosition(aliceProxyWallet, AliceAddress, pools.XDC); - const alicePositionAddress = await positionManager.positions(1); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 0 WXDC, because Alice doesn't locked WXDC").to.be.equal(0); - expect(alicePosition.debtShare, "debtShare should be 0 FXD, because doesn't drew FXD").to.be.equal(0); - // 2. Alice deposit 3 WXDC to new position - await PositionHelper.xdcAdapterDeposit(aliceProxyWallet, AliceAddress, await positionManager.positions(1), WeiPerWad.mul(3)); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's second position address should be 3 WXDC, because Alice deposit 3 WXDC into the second position" - ).to.be.equal(WeiPerWad.mul(3)); - // 3. Bob open a position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(bobProxyWallet, BobAddress, pools.XDC, WeiPerWad, WeiPerWad); - - const bobPositionAddress = await positionManager.positions(2); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const bobPosition = await bookKeeper.positions(pools.XDC, bobPositionAddress); - expect(bobPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Bob locked 1 WXDC").to.be.equal(WeiPerWad); - expect(bobPosition.debtShare, "debtShare should be 1 FXD, because Bob drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Bob should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 4. Alice try to move collateral to bob position - await PositionHelper.moveCollateral( - aliceProxyWallet, - AliceAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - bobPositionAddress, - WeiPerWad - ); - const aliceFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(AliceAddress); - const bobFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(BobAddress); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's Position address should be 2 WXDC, because Alice move 1 WXDC from Alice's Position to Bob's Position." - ).to.be.equal(WeiPerWad.mul(2)); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken inside Bob's Position address should be 1 WXDC, because Alice moved 1 WXDC from Alice's Position to Bob's position" - ).to.be.equal(WeiPerWad); - expect(aliceFathomStablecoinBalancefinal, "Alice should receive 0 FXD, because Alice doesn't draw").to.be.equal(0); - expect(bobFathomStablecoinBalancefinal, "Bob should receive 1 FXD, because Bob draw 1 time").to.be.equal(WeiPerWad); - }); - }); - }); - context("between 2 collateral pool", async () => { - context( - "Alice opens 2 positions on 2 collateral pools (one position for each collateral pool) and Alice move collateral from one position to another position by calling openLockTokenAndDraw() twice", - async () => { - it("should success", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC").to.be.equal(WeiPerWad); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Alice open a second new position with 2 WXDC and draw 1 FXD at new collateral pool - await PositionHelper.openPositionAndDraw(aliceProxyWallet, AliceAddress, pools.GLD, WeiPerWad.mul(2), WeiPerWad); - - const alicePositionAddress2 = await positionManager.positions(2); - const fathomStablecoinBalance2 = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition2 = await bookKeeper.positions(pools.GLD, alicePositionAddress2); - expect(alicePosition2.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal( - WeiPerWad.mul(2) - ); - expect(alicePosition2.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.GLD, alicePositionAddress2), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance2, "Alice should receive 2 FXD from drawing 1 FXD 2 times form 2 positions").to.be.equal( - WeiPerWad.mul(2) - ); - // 3. Alice try to unlock 1 WXDC at second position - await PositionHelper.adjustPosition( - aliceProxyWallet, - AliceAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - WeiPerWad.mul(-1), - 0, - collateralTokenAdapter2.address - ); - const aliceAdjustPosition = await bookKeeper.positions(pools.GLD, alicePositionAddress2); - expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC").to.be.equal( - WeiPerWad - ); - expect(aliceAdjustPosition.debtShare, "debtShare should be 1 FXD, because Alice didn't draw more").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.GLD, alicePositionAddress2), - "collateralToken inside Alice's position address should be 1 WXDC, because Alice unlocked 1 WXDC into the position" - ).to.be.equal(WeiPerWad); - // 4. Alice try to move collateral from second position to first position - await PositionHelper.moveCollateral( - aliceProxyWallet, - AliceAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - alicePositionAddress, - WeiPerWad, - collateralTokenAdapter2.address - ); - const aliceMoveCollateral = await bookKeeper.positions(pools.XDC, alicePositionAddress); - const fathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(AliceAddress); - expect( - aliceMoveCollateral.lockedCollateral, - "Alice's Position #1 lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC" - ).to.be.equal(WeiPerWad); - expect(aliceMoveCollateral.debtShare, "Alice's Position #1 debtShare should be 1 FXD, because Alice didn't draw more").to.be.equal( - WeiPerWad - ); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken from Collateral Pool #1 inside Alice's Position #1 address should be 0 WXDC, because Alice can't move collateral from Position #2 to Position #1 as they are not from the same Collateral Pool." - ).to.be.equal(0); - expect( - await bookKeeper.collateralToken(pools.GLD, alicePositionAddress2), - "collateralToken from Collateral Pool #2 inside Alice's position #2 address should be 0 WXDC, because Alice moved 1 WXDC into Collateral Pool #2 inside Alice's position #1" - ).to.be.equal(0); - expect( - await bookKeeper.collateralToken(pools.GLD, alicePositionAddress), - "collateralToken from Collateral Pool #2 inside Alice's position #1 address should be 1 WXDC, because Alice moved 1 WXDC form Alice's position #2 to Collateral Pool #2 inside Alice's position #1" - ).to.be.equal(WeiPerWad); - expect(fathomStablecoinBalancefinal, "Alice should receive 2 FXD from drawing 2 FXD, because Alice drew 2 times").to.be.equal( - WeiPerWad.mul(2) - ); - }); - } - ); - context( - "Alice opens 2 positions on 2 collateral pools (one position for each collateral pool) and Alice move collateral from one position to another position", - async () => { - it("should success", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC").to.be.equal(WeiPerWad); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Alice open a second position at another collateral pool - await PositionHelper.openPosition(aliceProxyWallet, AliceAddress, pools.GLD); - - const alicePositionAddress2 = await positionManager.positions(2); - const alicePosition2 = await bookKeeper.positions(pools.GLD, alicePositionAddress2); - expect(alicePosition2.lockedCollateral, "lockedCollateral should be 0 WXDC, because Alice doesn't locked WXDC").to.be.equal(0); - expect(alicePosition2.debtShare, "debtShare should be 0 FXD, because doesn't drew FXD").to.be.equal(0); - // 3. Alice deposit 3 WXDC to second position - await PositionHelper.tokenAdapterDeposit( - aliceProxyWallet, - AliceAddress, - await positionManager.positions(2), - WeiPerWad.mul(3), - collateralTokenAdapter2.address - ); - expect( - await bookKeeper.collateralToken(pools.GLD, alicePositionAddress2), - "collateralToken inside Alice's second position address should be 3 WXDC, because Alice deposit 3 WXDC into the second position" - ).to.be.equal(WeiPerWad.mul(3)); - // 4. Alice try to move collateral from second position to first position - await PositionHelper.moveCollateral( - aliceProxyWallet, - AliceAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - alicePositionAddress, - WeiPerWad, - collateralTokenAdapter2.address - ); - const aliceMoveCollateral = await bookKeeper.positions(pools.XDC, alicePositionAddress); - const fathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(AliceAddress); - expect( - aliceMoveCollateral.lockedCollateral, - "Alice's Position #1 lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC" - ).to.be.equal(WeiPerWad); - expect(aliceMoveCollateral.debtShare, "Alice's Position #1 debtShare should be 1 FXD, because Alice doesn't draw more").to.be.equal( - WeiPerWad - ); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken from Collateral Pool #1 inside Alice's Position #1 address should be 0 WXDC, because Alice can't move collateral from Position #2 to Position #1 as they are not from the same Collateral Pool." - ).to.be.equal(0); - expect( - await bookKeeper.collateralToken(pools.GLD, alicePositionAddress2), - "collateralToken from Collateral Pool #2 inside Alice's Position #2 address should be 2 WXDC, because Alice move 1 WXDC into Collateral Pool #2 inside Alice's position #1" - ).to.be.equal(WeiPerWad.mul(2)); - expect( - await bookKeeper.collateralToken(pools.GLD, alicePositionAddress), - "collateralToken from Collateral Pool #2 inside Alice's Position #1 address should be 1 WXDC, because Alice move 1 WXDC form Alice's position #2 to Collateral Pool #2 inside Alice's position #1" - ).to.be.equal(WeiPerWad); - expect(fathomStablecoinBalancefinal, "Alice should receive 1 FXD, because Alice draw 1 time").to.be.equal(WeiPerWad); - }); - } - ); - context( - "Alice open a position, lock collateral and move collateral to Bob's position at another collateral pool by calling openLockTokenAndDraw() once and open() once", - async () => { - it("should success", async () => { - // 1. Alice open position - await PositionHelper.openPosition(aliceProxyWallet, AliceAddress, pools.XDC); - const alicePositionAddress = await positionManager.positions(1); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect( - alicePosition.lockedCollateral, - "Alice's Position #1 lockedCollateral should be 0 WXDC, because Alice didn't lock WXDC" - ).to.be.equal(0); - expect(alicePosition.debtShare, "Alice's Position #1 debtShare should be 0 FXD, because didn't draw FXD").to.be.equal(0); - // 2. Alice deposit 3 WXDC to her position - await PositionHelper.xdcAdapterDeposit( - aliceProxyWallet, - AliceAddress, - await positionManager.positions(1), - WeiPerWad.mul(3), - collateralTokenAdapter.address - ); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken from Collateral Pool #1 inside Alice's Position #1 address should be 3 WXDC, because Alice deposit 3 WXDC into the her position" - ).to.be.equal(WeiPerWad.mul(3)); - // 3. Bob open a position with 1 WXDC and draw 1 FXD at another collateral pool - await PositionHelper.openPositionAndDraw(bobProxyWallet, BobAddress, pools.GLD, WeiPerWad, WeiPerWad); - - const bobPositionAddress = await positionManager.positions(2); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const bobPosition = await bookKeeper.positions(pools.GLD, bobPositionAddress); - expect( - bobPosition.lockedCollateral, - "lockedCollateral from Collateral Pool #2 inside Bob's Position #1 address should be 1 WXDC, because Bob locked 1 WXDC" - ).to.be.equal(WeiPerWad); - expect( - bobPosition.debtShare, - "debtShare from Collateral Pool #2 inside Bob's Position #1 address should be 1 FXD, because Bob drew 1 FXD" - ).to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.GLD, bobPositionAddress), - "collateralToken from Collateral Pool #2 inside Bob's Position #1 address should be 0 WXDC, because Bob locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Bob should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 4. Alice try to move collateral to Bob's position across collateral pool - await PositionHelper.moveCollateral( - aliceProxyWallet, - AliceAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - bobPositionAddress, - WeiPerWad, - collateralTokenAdapter.address - ); - const aliceFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(AliceAddress); - const bobFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(BobAddress); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken from Collateral Pool #1 inside Alice's Position #1 address should be 2 WXDC, because Alice move 1 WXDC to Bob's position" - ).to.be.equal(WeiPerWad.mul(2)); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken from Collateral Pool #1 inside new Bob's Position address should be 1 WXDC, because System auto create Bob's position at Collateral Pool #1, so Alice can move 1 WXDC into the new Bob's position" - ).to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.GLD, bobPositionAddress), - "collateralToken from Collateral Pool #2 inside Bob's Position #1 address should be 0 WXDC, because Alice can't move WXDC across collateral pool" - ).to.be.equal(0); - expect(aliceFathomStablecoinBalancefinal, "Alice should receive 0 FXD, because Alice didn't draw more").to.be.equal(0); - expect(bobFathomStablecoinBalancefinal, "Bob should receive 1 FXD, because Bob drew 1 time").to.be.equal(WeiPerWad); - }); - } - ); - }); - }); - - context("mint FXD", async () => { - it("should success", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(2), WeiPerWad); - - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - - // 2. Alice try to mint FXD - await PositionHelper.draw( - aliceProxyWallet, - AliceAddress, - pools.XDC, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - WeiPerWad - ); - const fathomStablecoinBalance2 = await fathomStablecoin.balanceOf(AliceAddress); - const aliceAdjustPosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice doesn't add WXDC").to.be.equal( - WeiPerWad.mul(2) - ); - expect(aliceAdjustPosition.debtShare, "debtShare should be 2 FXD, because Alice drew more").to.be.equal(WeiPerWad.mul(2)); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance2, "Alice should receive 2 FXD from drawing 2 FXD").to.be.equal(WeiPerWad.mul(2)); - }); - }); - - context("move position", async () => { - context("same collateral pool", async () => { - context( - "call openLockTokenAndDraw, unlock collateral and move the collateral from one position to another position within the same collateral pool", - async () => { - it("should success", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - - expect( - alicePosition.lockedCollateral, - "Alice's Position #1 lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC" - ).to.be.equal(WeiPerWad); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "Alice's Position #1 collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - - // 2. Alice open a second new position with 2 WXDC and draw 1 FXD at same collateral pool - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(2), WeiPerWad); - - const alicePositionAddress2 = await positionManager.positions(2); - const fathomStablecoinBalance2 = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition2 = await bookKeeper.positions(pools.XDC, alicePositionAddress2); - - expect( - alicePosition2.lockedCollateral, - "Alice's Position #2 lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC" - ).to.be.equal(WeiPerWad.mul(2)); - expect(alicePosition2.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress2), - "Alice's Position #2 collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance2, "Alice should receive 2 FXD, because Alice drew FXD 2 times form 2 positions").to.be.equal( - WeiPerWad.mul(2) - ); - - // 3. Alice try to unlock 1 WXDC at second position - await PositionHelper.adjustPosition( - aliceProxyWallet, - AliceAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - WeiPerWad.mul(-1), - 0 - ); - const aliceAdjustPosition = await bookKeeper.positions(pools.XDC, alicePositionAddress2); - expect( - aliceAdjustPosition.lockedCollateral, - "Alice's Position #2 lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC" - ).to.be.equal(WeiPerWad); - expect(aliceAdjustPosition.debtShare, "Alice's Position #2 debtShare should be 1 FXD, because Alice didn't draw more").to.be.equal( - WeiPerWad - ); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress2), - "Alice's Position #2 collateralToken should be 1 WXDC, because Alice unlocked 1 WXDC into the position" - ).to.be.equal(WeiPerWad); - - // 4. Alice try to move position from second position to first position - await PositionHelper.movePosition(aliceProxyWallet, AliceAddress, 2, 1); - const alicemovePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - const fathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(AliceAddress); - expect( - alicemovePosition.lockedCollateral, - "Alice's Position #1 lockedCollateral should be 2 WXDC, because Alice move form Position #2 to Position #1" - ).to.be.equal(WeiPerWad.mul(2)); - expect( - alicemovePosition.debtShare, - "Alice's Position #1 debtShare should be 2 FXD, because Alice move form Position #2 to Position #1" - ).to.be.equal(WeiPerWad.mul(2)); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress2), - "collateralToken inside Alice's Position #2 address should still be 1 WXDC, because Alice moving position will not move collateral" - ).to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's Position #1 address should still be 0 WXDC, because Alice moving position will not move collateral" - ).to.be.equal(0); - expect(fathomStablecoinBalancefinal, "Alice should receive 2 FXD from drawing 2 FXD, because Alice drew 2 times").to.be.equal( - WeiPerWad.mul(2) - ); - }); - } - ); - }); - context("between 2 collateral pool", async () => { - context( - "Alice opens 2 positions on 2 collateral pools (one position for each collateral pool) and Alice move collateral from one position to another position", - async () => { - it("should revert", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - - expect( - alicePosition.lockedCollateral, - "Collateral Pool #1 inside Bob's Position #1 lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC" - ).to.be.equal(WeiPerWad); - expect( - alicePosition.debtShare, - "Collateral Pool #1 inside Bob's Position #1 debtShare should be 1 FXD, because Alice drew 1 FXD" - ).to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - - // 2. Alice open a second new position with 2 WXDC and draw 1 FXD at new collateral pool - await PositionHelper.openPositionAndDraw(aliceProxyWallet, AliceAddress, pools.GLD, WeiPerWad.mul(2), WeiPerWad); - const alicePositionAddress2 = await positionManager.positions(2); - const fathomStablecoinBalance2 = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition2 = await bookKeeper.positions(pools.GLD, alicePositionAddress2); - - expect( - alicePosition2.lockedCollateral, - "Collateral Pool #2 inside Bob's Position #2 lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC" - ).to.be.equal(WeiPerWad.mul(2)); - expect( - alicePosition2.debtShare, - "Collateral Pool #2 inside Bob's Position #2 debtShare should be 1 FXD, because Alice drew 1 FXD" - ).to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.GLD, alicePositionAddress2), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance2, "Alice should receive 2 FXD from drawing 1 FXD 2 times form 2 positions").to.be.equal( - WeiPerWad.mul(2) - ); - - // 3. Alice try to unlock 1 WXDC at second position - await PositionHelper.adjustPosition( - aliceProxyWallet, - AliceAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - WeiPerWad.mul(-1), - 0, - collateralTokenAdapter2.address - ); - const aliceAdjustPosition = await bookKeeper.positions(pools.GLD, alicePositionAddress2); - expect( - aliceAdjustPosition.lockedCollateral, - "Collateral Pool #2 inside Bob's Position #2 lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC" - ).to.be.equal(WeiPerWad); - expect( - aliceAdjustPosition.debtShare, - "Collateral Pool #2 inside Bob's Position #2 debtShare should be 1 FXD, because Alice didn't draw more" - ).to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.GLD, alicePositionAddress2), - "collateralToken inside Alice's position address should be 1 WXDC, because Alice unlocked 1 WXDC into the position" - ).to.be.equal(WeiPerWad); - - // 4. Alice try to move collateral from second position to first position - const movePositionAbi = ["function movePosition(address _manager, uint256 _source, uint256 _destination)"]; - const movePositionIFace = new ethers.utils.Interface(movePositionAbi); - const movePosition = movePositionIFace.encodeFunctionData("movePosition", [positionManager.address, 2, 1]); - await expect(aliceProxyWallet.execute(movePosition, { from: AliceAddress })).to.be.revertedWith("!same collateral pool"); - }); - } - ); - }); - }); - }); - - context("position owner allow other user to manage position with proxy wallet", async () => { - context("lock collateral into their own position", async () => { - it("should success", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC").to.be.equal(WeiPerWad); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Alice allow Bob to manage position - await PositionHelper.allowManagePosition(aliceProxyWallet, AliceAddress, 1, bobProxyWallet.address, true); - expect(await positionManager.ownerWhitelist(aliceProxyWallet.address, 1, bobProxyWallet.address)).to.be.equal(true); - // 3. Bob try to adjust Alice's position, add 2 WXDC to position - await PositionHelper.lockXDC(bobProxyWallet, BobAddress, 1, WeiPerWad.mul(2)); - - const aliceAdjustPosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 3 WXDC, because Bob add locked 2 WXDC").to.be.equal( - WeiPerWad.mul(3) - ); - }); - }); - context("move collateral", async () => { - context("same collateral pool", async () => { - context("and Bob move collateral of Alice to himself", async () => { - it("should success", async () => { - // 1. Alice open a new position with 2 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(2), WeiPerWad); - - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Bob open a position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(bobProxyWallet, BobAddress, pools.XDC, WeiPerWad, WeiPerWad); - const bobPositionAddress = await positionManager.positions(2); - const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const bobPosition = await bookKeeper.positions(pools.XDC, bobPositionAddress); - expect(bobPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Bob locked 1 WXDC").to.be.equal(WeiPerWad); - expect(bobPosition.debtShare, "debtShare should be 1 FXD, because Bob drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob locked all WXDC into the position" - ).to.be.equal(0); - expect(bobFathomStablecoinBalance, "Bob should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 3. Alice try to unlock 1 WXDC at her position - await PositionHelper.adjustPosition( - aliceProxyWallet, - AliceAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - WeiPerWad.mul(-1), - 0 - ); - const aliceAdjustPosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC").to.be.equal(WeiPerWad); - expect(aliceAdjustPosition.debtShare, "debtShare should be 1 FXD, because Alice doesn't draw more").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 1 WXDC, because Alice unlocked 1 WXDC into the position" - ).to.be.equal(WeiPerWad); - // 4. Alice allow Bob to manage position - await PositionHelper.allowManagePosition(aliceProxyWallet, AliceAddress, 1, bobProxyWallet.address, true); - expect(await positionManager.ownerWhitelist(aliceProxyWallet.address, 1, bobProxyWallet.address)).to.be.equal(true); - // 5. Bob try to move collateral to Alice position - await PositionHelper.moveCollateral( - bobProxyWallet, - BobAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - bobPositionAddress, - WeiPerWad - ); - const aliceFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(AliceAddress); - const bobFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(BobAddress); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Bob move 1 WXDC of Alice's position to his position" - ).to.be.equal(0); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob move 1 WXDC of Alice's position to his position" - ).to.be.equal(WeiPerWad); - expect(aliceFathomStablecoinBalancefinal, "Alice should receive 1 FXD, because Alice drew 1 time").to.be.equal(WeiPerWad); - expect(bobFathomStablecoinBalancefinal, "Bob should receive 1 FXD, because Bob drew 1 time").to.be.equal(WeiPerWad); - }); - }); - }); - context("between collateral pool", async () => { - context("and Bob move collateral of Alice to himself", async () => { - it("should success", async () => { - // 1. Alice open a new position with 2 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(2), WeiPerWad); - - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Bob open a position at collateral pool 2 with 1 WXDC and draw 1 FXD - await PositionHelper.openPositionAndDraw(bobProxyWallet, BobAddress, pools.GLD, WeiPerWad, WeiPerWad); - const bobPositionAddress = await positionManager.positions(2); - const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const bobPosition = await bookKeeper.positions(pools.GLD, bobPositionAddress); - expect(bobPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Bob locked 1 WXDC").to.be.equal(WeiPerWad); - expect(bobPosition.debtShare, "debtShare should be 1 FXD, because Bob drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.GLD, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob locked all WXDC into the position" - ).to.be.equal(0); - expect(bobFathomStablecoinBalance, "Bob should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 3. Alice try to unlock 1 WXDC at her position - await PositionHelper.adjustPosition( - aliceProxyWallet, - AliceAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - WeiPerWad.mul(-1), - 0, - collateralTokenAdapter.address - ); - const aliceAdjustPosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC").to.be.equal(WeiPerWad); - expect(aliceAdjustPosition.debtShare, "debtShare should be 1 FXD, because Alice didn't draw more").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 1 WXDC, because Alice unlocked 1 WXDC at her position" - ).to.be.equal(WeiPerWad); - // 4. Alice allow Bob to manage position - await PositionHelper.allowManagePosition(aliceProxyWallet, AliceAddress, 1, bobProxyWallet.address, true); - expect(await positionManager.ownerWhitelist(aliceProxyWallet.address, 1, bobProxyWallet.address)).to.be.equal(true); - // 5. Bob try to move collateral to Alice position - await PositionHelper.moveCollateral( - bobProxyWallet, - BobAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - bobPositionAddress, - WeiPerWad, - collateralTokenAdapter.address - ); - - const aliceFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(AliceAddress); - const bobFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(BobAddress); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Bob move 1 WXDC of Alice's position to himself" - ).to.be.equal(0); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken inside Bob's position address should be 1 WXDC, because Bob move 1 WXDC of Alice's position to himself" - ).to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.GLD, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob move 1 WXDC of Alice's position to himself" - ).to.be.equal(0); - expect(aliceFathomStablecoinBalancefinal, "Alice should receive 1 FXD, because Alice drew 1 time").to.be.equal(WeiPerWad); - expect(bobFathomStablecoinBalancefinal, "Bob should receive 1 FXD, because Bob drew 1 time").to.be.equal(WeiPerWad); - }); - }); - }); - }); - context("mint FXD", async () => { - it("should success", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(2), WeiPerWad); - - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Alice allow Bob to manage position - await PositionHelper.allowManagePosition(aliceProxyWallet, AliceAddress, 1, bobProxyWallet.address, true); - expect(await positionManager.ownerWhitelist(aliceProxyWallet.address, 1, bobProxyWallet.address)).to.be.equal(true); - // 3. Bob try to mint FXD at Alice position - await PositionHelper.draw( - bobProxyWallet, - BobAddress, - pools.XDC, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - WeiPerWad - ); - const fathomStablecoinBalance2 = await fathomStablecoin.balanceOf(AliceAddress); - const BobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const aliceAdjustPosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice didn't add WXDC").to.be.equal( - WeiPerWad.mul(2) - ); - expect(aliceAdjustPosition.debtShare, "debtShare should be 2 FXD, because Alice drew more").to.be.equal(WeiPerWad.mul(2)); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance2, "Alice should receive 1 FXD from Alice drew 1 time").to.be.equal(WeiPerWad); - expect(BobFathomStablecoinBalance, "Bob should receive 1 FXD from mint FXD at Alice position").to.be.equal(WeiPerWad); - }); - }); - context("move position", async () => { - context("same collateral pool", async () => { - it("should success", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect( - alicePosition.lockedCollateral, - "Collateral Pool #1 inside Alice's Position #1 lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC" - ).to.be.equal(WeiPerWad); - expect( - alicePosition.debtShare, - "Collateral Pool #1 inside Alice's Position #1 debtShare should be 1 FXD, because Alice drew 1 FXD" - ).to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Bob open a position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(bobProxyWallet, BobAddress, pools.XDC, WeiPerWad, WeiPerWad); - const bobPositionAddress = await positionManager.positions(2); - const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const bobPosition = await bookKeeper.positions(pools.XDC, bobPositionAddress); - expect( - bobPosition.lockedCollateral, - "Collateral Pool #1 inside Bob's Position #1 lockedCollateral should be 1 WXDC, because Bob locked 1 WXDC" - ).to.be.equal(WeiPerWad); - expect( - bobPosition.debtShare, - "Collateral Pool #1 inside Bob's Position #1 debtShare should be 1 FXD, because Bob drew 1 FXD" - ).to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob locked all WXDC into the position" - ).to.be.equal(0); - expect(bobFathomStablecoinBalance, "Bob should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 3. Alice allow Bob to manage position - await PositionHelper.allowManagePosition(aliceProxyWallet, AliceAddress, 1, bobProxyWallet.address, true); - expect(await positionManager.ownerWhitelist(aliceProxyWallet.address, 1, bobProxyWallet.address)).to.be.equal(true); - // 4. Bob try to move collateral to alice position - await PositionHelper.movePosition(bobProxyWallet, BobAddress, 2, 1); - const aliceFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(AliceAddress); - const bobFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(BobAddress); - const alicePositionAfterMovePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect( - alicePositionAfterMovePosition.lockedCollateral, - "Collateral Pool #1 inside Alice's Position #1 lockedCollateral should be 2 WXDC, because Bob move locked 1 WXDC to Alice" - ).to.be.equal(WeiPerWad.mul(2)); - expect( - alicePositionAfterMovePosition.debtShare, - "Collateral Pool #1 inside Alice's Position #1 debtShare should be 1 FXD, because Bob move DebtShare to Alice" - ).to.be.equal(WeiPerWad.mul(2)); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice all lock collateral" - ).to.be.equal(0); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob all lock collateral" - ).to.be.equal(0); - expect(aliceFathomStablecoinBalancefinal, "Alice should receive 1 FXD, because Alice drew 1 time").to.be.equal(WeiPerWad); - expect(bobFathomStablecoinBalancefinal, "Bob should receive 1 FXD, because Bob drew 1 time").to.be.equal(WeiPerWad); - }); - }); - context("between 2 collateral pool", async () => { - it("should revert", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect( - alicePosition.lockedCollateral, - "Collateral Pool #1 inside Alice's Position #1 lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC" - ).to.be.equal(WeiPerWad); - expect( - alicePosition.debtShare, - "Collateral Pool #1 inside Bob's Position #1 debtShare should be 1 FXD, because Alice drew 1 FXD" - ).to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Bob open a position with 1 WXDC and draw 1 FXD at collateral pool id 2 - await PositionHelper.openPositionAndDraw(bobProxyWallet, BobAddress, pools.GLD, WeiPerWad, WeiPerWad); - const bobPositionAddress = await positionManager.positions(2); - const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const bobPosition = await bookKeeper.positions(pools.GLD, bobPositionAddress); - expect( - bobPosition.lockedCollateral, - "Collateral Pool #1 inside Bob's Position #1 lockedCollateral should be 1 WXDC, because Bob locked 1 WXDC" - ).to.be.equal(WeiPerWad); - expect( - bobPosition.debtShare, - "Collateral Pool #1 inside Bob's Position #1 debtShare should be 1 FXD, because Bob drew 1 FXD" - ).to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.GLD, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob locked all WXDC into the position" - ).to.be.equal(0); - expect(bobFathomStablecoinBalance, "Bob should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 3. Alice allow Bob to manage position - await PositionHelper.allowManagePosition(aliceProxyWallet, AliceAddress, 1, bobProxyWallet.address, true); - expect(await positionManager.ownerWhitelist(aliceProxyWallet.address, 1, bobProxyWallet.address)).to.be.equal(true); - // 4. Bob try to move position to Alice position - const movePositionAbi = ["function movePosition(address _manager, uint256 _source, uint256 _destination)"]; - const movePositionIFace = new ethers.utils.Interface(movePositionAbi); - const movePositionCall = movePositionIFace.encodeFunctionData("movePosition", [positionManager.address, 2, 1]); - await expect(bobProxyWallet.execute(movePositionCall, { from: BobAddress })).to.be.revertedWith("!same collateral pool"); - }); - }); - }); - }); - - context("position owner not allow other user to manage position with proxy wallet", async () => { - context("lock collateral into their own position", async () => { - it("should revert", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC").to.be.equal(WeiPerWad); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - - // 2. Bob try to adjust Alice's position, add 2 WXDC to position - const lockAbi = ["function lockXDC(address _manager, address _xdcAdapter, uint256 _positionId, bytes calldata _data)"]; - let lockIFace = new ethers.utils.Interface(lockAbi); - const lockTokenCall = lockIFace.encodeFunctionData("lockXDC", [ - positionManager.address, - collateralTokenAdapter.address, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - ]); - - await expect(bobProxyWallet.execute(lockTokenCall, { value: WeiPerWad, from: BobAddress })).to.be.revertedWith("owner not allowed"); - }); - }); - context("move collateral", async () => { - context("same collateral pool", async () => { - context("and Bob move collateral to Alice", async () => { - it("should success", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC").to.be.equal(WeiPerWad); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Bob open a position with 2 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(bobProxyWallet, BobAddress, pools.XDC, WeiPerWad.mul(2), WeiPerWad); - const bobPositionAddress = await positionManager.positions(2); - const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const bobPosition = await bookKeeper.positions(pools.XDC, bobPositionAddress); - expect(bobPosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Bob locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); - expect(bobPosition.debtShare, "debtShare should be 1 FXD, because Bob drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob locked all WXDC into the position" - ).to.be.equal(0); - expect(bobFathomStablecoinBalance, "Bob should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 3. Bob try to unlock 1 WXDC at second position - await PositionHelper.adjustPosition( - bobProxyWallet, - BobAddress, - await positionManager.ownerLastPositionId(bobProxyWallet.address), - WeiPerWad.mul(-1), - 0 - ); - const bobAdjustPosition = await bookKeeper.positions(pools.XDC, bobPositionAddress); - expect(bobAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Bob unlocked 1 WXDC").to.be.equal(WeiPerWad); - expect(bobAdjustPosition.debtShare, "debtShare should be 1 FXD, because Bob doesn't draw more").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken inside Bob's position address should be 1 WXDC, because Bob unlocked 1 WXDC into the position" - ).to.be.equal(WeiPerWad); - // 4. Bob try to move collateral to Alice position - await PositionHelper.moveCollateral( - bobProxyWallet, - BobAddress, - await positionManager.ownerLastPositionId(bobProxyWallet.address), - alicePositionAddress, - WeiPerWad - ); - const aliceFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(AliceAddress); - const bobFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(BobAddress); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 1 WXDC, because Bob move 1 WXDC to Alice's position" - ).to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob move 1 WXDC to Alice's position" - ).to.be.equal(0); - expect(aliceFathomStablecoinBalancefinal, "Alice should receive 1 FXD, because Alice drew 1 time").to.be.equal(WeiPerWad); - expect(bobFathomStablecoinBalancefinal, "Bob should receive 1 FXD, because Bob drew 1 time").to.be.equal(WeiPerWad); - }); - }); - }); - context("between collateral pool", async () => { - context("and Bob move collateral to Alice", async () => { - it("should success", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC").to.be.equal(WeiPerWad); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Bob open a position at collateral pool 2 with 2 WXDC and draw 1 FXD - await PositionHelper.openPositionAndDraw(bobProxyWallet, BobAddress, pools.GLD, WeiPerWad.mul(2), WeiPerWad); - const bobPositionAddress = await positionManager.positions(2); - const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const bobPosition = await bookKeeper.positions(pools.GLD, bobPositionAddress); - expect(bobPosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Bob locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); - expect(bobPosition.debtShare, "debtShare should be 1 FXD, because Bob drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.GLD, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob locked all WXDC into the position" - ).to.be.equal(0); - expect(bobFathomStablecoinBalance, "Bob should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 3. Bob try to unlock 1 WXDC at second position - await PositionHelper.adjustPosition( - bobProxyWallet, - BobAddress, - await positionManager.ownerLastPositionId(bobProxyWallet.address), - WeiPerWad.mul(-1), - 0, - collateralTokenAdapter2.address - ); - const bobAdjustPosition = await bookKeeper.positions(pools.GLD, bobPositionAddress); - expect(bobAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Bob unlocked 1 WXDC").to.be.equal(WeiPerWad); - expect(bobAdjustPosition.debtShare, "debtShare should be 1 FXD, because Bob didn't draw more").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.GLD, bobPositionAddress), - "collateralToken inside Bob's position address should be 1 WXDC, because Bob unlocked 1 WXDC into the position" - ).to.be.equal(WeiPerWad); - // 4. Bob try to move collateral to Alice position - await PositionHelper.moveCollateral( - bobProxyWallet, - BobAddress, - await positionManager.ownerLastPositionId(bobProxyWallet.address), - alicePositionAddress, - WeiPerWad, - collateralTokenAdapter2.address - ); - const aliceFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(AliceAddress); - const bobFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(BobAddress); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Bob move 1 WXDC to Alice's position" - ).to.be.equal(0); - expect( - await bookKeeper.collateralToken(pools.GLD, alicePositionAddress), - "collateralToken inside Alice's position address should be 1 WXDC, because Bob move 1 WXDC to Alice's position" - ).to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob move 1 WXDC to Alice's position" - ).to.be.equal(0); - expect(aliceFathomStablecoinBalancefinal, "Alice should receive 1 FXD, because Alice drew 1 time").to.be.equal(WeiPerWad); - expect(bobFathomStablecoinBalancefinal, "Bob should receive 1 FXD, because Bob drew 1 time").to.be.equal(WeiPerWad); - }); - }); - }); - }); - context("mint FXD", async () => { - it("should revert", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(2), WeiPerWad); - - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Bob try to mint FXD at Alice position - let drawTokenAbi = [ - "function draw(address _manager, address _stabilityFeeCollector, address _stablecoinAdapter, uint256 _positionId, uint256 _amount, bytes calldata _data)", - ]; - let drawTokenIFace = new ethers.utils.Interface(drawTokenAbi); - let drawTokenCall = drawTokenIFace.encodeFunctionData("draw", [ - positionManager.address, - stabilityFeeCollector.address, - stablecoinAdapter.address, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - WeiPerWad, - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - ]); - await expect(bobProxyWallet.execute(drawTokenCall, { from: BobAddress })).to.be.revertedWith("owner not allowed"); - }); - }); - context("move position", async () => { - context("same collateral pool", async () => { - it("should revert", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC").to.be.equal(WeiPerWad); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Bob open a position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(bobProxyWallet, BobAddress, pools.XDC, WeiPerWad, WeiPerWad); - const bobPositionAddress = await positionManager.positions(2); - const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const bobPosition = await bookKeeper.positions(pools.XDC, bobPositionAddress); - expect(bobPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Bob locked 1 WXDC").to.be.equal(WeiPerWad); - expect(bobPosition.debtShare, "debtShare should be 1 FXD, because Bob drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob locked all WXDC into the position" - ).to.be.equal(0); - expect(bobFathomStablecoinBalance, "Bob should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 3. Bob try to move collateral to alice position - const movePositionAbi = ["function movePosition(address _manager, uint256 _source, uint256 _destination)"]; - const movePositionIFace = new ethers.utils.Interface(movePositionAbi); - const movePositionCall = movePositionIFace.encodeFunctionData("movePosition", [positionManager.address, 2, 1]); - await expect(bobProxyWallet.execute(movePositionCall, { from: BobAddress })).to.be.revertedWith("owner not allowed"); - }); - }); - context("between 2 collateral pool", async () => { - it("should revert", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC").to.be.equal(WeiPerWad); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - - // 2. Bob open a position with 1 WXDC and draw 1 FXD at collateral pool id 2 - await PositionHelper.openPositionAndDraw(bobProxyWallet, BobAddress, pools.GLD, WeiPerWad, WeiPerWad); - const bobPositionAddress = await positionManager.positions(2); - const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const bobPosition = await bookKeeper.positions(pools.GLD, bobPositionAddress); - expect(bobPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Bob locked 1 WXDC").to.be.equal(WeiPerWad); - expect(bobPosition.debtShare, "debtShare should be 1 FXD, because Bob drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.GLD, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob locked all WXDC into the position" - ).to.be.equal(0); - expect(bobFathomStablecoinBalance, "Bob should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - - // 3. Bob try to move position to Alice position - const movePositionAbi = ["function movePosition(address _manager, uint256 _source, uint256 _destination)"]; - const movePositionIFace = new ethers.utils.Interface(movePositionAbi); - const movePositionCall = movePositionIFace.encodeFunctionData("movePosition", [positionManager.address, 2, 1]); - await expect(bobProxyWallet.execute(movePositionCall, { from: BobAddress })).to.be.revertedWith("owner not allowed"); - }); - }); - }); - }); - - context("position owner allow other user to manage position with user wallet address", async () => { - context("move collateral", async () => { - context("same collateral pool", async () => { - context("and Bob move collateral of Alice to himself", async () => { - it("should success", async () => { - // 1. Alice open a new position with 2 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(2), WeiPerWad); - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Bob open a position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(bobProxyWallet, BobAddress, pools.XDC, WeiPerWad, WeiPerWad); - const bobPositionAddress = await positionManager.positions(2); - const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const bobPosition = await bookKeeper.positions(pools.XDC, bobPositionAddress); - expect(bobPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Bob locked 1 WXDC").to.be.equal(WeiPerWad); - expect(bobPosition.debtShare, "debtShare should be 1 FXD, because Bob drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob locked all WXDC into the position" - ).to.be.equal(0); - expect(bobFathomStablecoinBalance, "Bob should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 3. Alice try to unlock 1 WXDC at her position - await PositionHelper.adjustPosition( - aliceProxyWallet, - AliceAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - WeiPerWad.mul(-1), - 0 - ); - const aliceAdjustPosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC").to.be.equal(WeiPerWad); - expect(aliceAdjustPosition.debtShare, "debtShare should be 1 FXD, because Alice didn't draw more").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 1 WXDC, because Alice unlocked 1 WXDC into the position" - ).to.be.equal(WeiPerWad); - - // 4. Alice allow Bob to manage position - await PositionHelper.allowManagePosition(aliceProxyWallet, AliceAddress, 1, bobProxyWallet.address, true); - expect(await positionManager.ownerWhitelist(aliceProxyWallet.address, 1, bobProxyWallet.address)).to.be.equal(true); - - // 5. Bob try to move collateral of Alice position to Bob position - // await positionManager["moveCollateral(uint256,address,uint256,address,bytes)"]( - await PositionHelper.moveCollateral( - bobProxyWallet, - BobAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - bobPositionAddress, - WeiPerWad - ); - - const aliceFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(AliceAddress); - const bobFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(BobAddress); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Bob move 1 WXDC to his position" - ).to.be.equal(0); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken inside Alice's position address should be 1 WXDC, because Bob move 1 WXDC to his position" - ).to.be.equal(WeiPerWad); - expect(aliceFathomStablecoinBalancefinal, "Alice should receive 1 FXD, because Alice drew 1 time").to.be.equal(WeiPerWad); - expect(bobFathomStablecoinBalancefinal, "Bob should receive 1 FXD, because Bob drew 1 time").to.be.equal(WeiPerWad); - }); - }); - }); - context("between collateral pool", async () => { - context("and Bob move collateral of Alice to himself", async () => { - it("should success", async () => { - // 1. Alice open a new position with 2 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(2), WeiPerWad); - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Bob open a position at collateral pool 2 with 2 WXDC and draw 1 FXD - await PositionHelper.openPositionAndDraw(bobProxyWallet, BobAddress, pools.GLD, WeiPerWad.mul(2), WeiPerWad); - const bobPositionAddress = await positionManager.positions(2); - const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const bobPosition = await bookKeeper.positions(pools.GLD, bobPositionAddress); - expect(bobPosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Bob locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); - expect(bobPosition.debtShare, "debtShare should be 1 FXD, because Bob drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.GLD, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob locked all WXDC into the position" - ).to.be.equal(0); - expect(bobFathomStablecoinBalance, "Bob should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 3. Alice try to unlock 1 WXDC at her position - await PositionHelper.adjustPosition( - aliceProxyWallet, - AliceAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - WeiPerWad.mul(-1), - 0, - collateralTokenAdapter.address - ); - const aliceAdjustPosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC").to.be.equal(WeiPerWad); - expect(aliceAdjustPosition.debtShare, "debtShare should be 1 FXD, because Alice didn't draw more").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 1 WXDC, because Alice unlocked 1 WXDC" - ).to.be.equal(WeiPerWad); - - // 4. Alice allow Bob to manage her position - await PositionHelper.allowManagePosition(aliceProxyWallet, AliceAddress, 1, bobProxyWallet.address, true); - expect(await positionManager.ownerWhitelist(aliceProxyWallet.address, 1, bobProxyWallet.address)).to.be.equal(true); - - // 5. Bob try to move collateral of Alice position to his position - await PositionHelper.moveCollateral( - bobProxyWallet, - BobAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - bobPositionAddress, - WeiPerWad, - collateralTokenAdapter.address, - AliceAddress - ); - const aliceFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(AliceAddress); - const bobFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(BobAddress); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Bob move 1 WXDC to his position" - ).to.be.equal(0); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken inside Bob's position address should be 1 WXDC at collater pool 1, because Bob move 1 WXDC to his position" - ).to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.GLD, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC at collater pool 2, because Bob move 1 WXDC to his position at collateral pool 1" - ).to.be.equal(0); - expect(aliceFathomStablecoinBalancefinal, "Alice should receive 1 FXD, because Alice drew 1 time").to.be.equal(WeiPerWad); - expect(bobFathomStablecoinBalancefinal, "Bob should receive 1 FXD, because Bob drew 1 time").to.be.equal(WeiPerWad); - }); - }); - }); - }); - context("mint FXD", async () => { - it("should success", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(2), WeiPerWad); - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Alice allow Bob to manage position - await PositionHelper.allowManagePosition(aliceProxyWallet, AliceAddress, 1, BobAddress, true); - expect(await positionManager.ownerWhitelist(aliceProxyWallet.address, 1, BobAddress)).to.be.equal(true); - // 3. Bob try to mint FXD at Alice position - - await positionManager.adjustPosition( - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - 0, - alicePosition.debtShare, - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: BobAddress } - ); - - // 4. move stablecoin of alice to bob - await positionManager.moveStablecoin(await positionManager.ownerLastPositionId(aliceProxyWallet.address), BobAddress, WeiPerRad, { - from: BobAddress, - }); - - // 5. allow bob to window - await bookKeeper.whitelist(stablecoinAdapter.address, { from: BobAddress }); - - // 6. mint FXD - await stablecoinAdapter.withdraw(BobAddress, WeiPerWad, ethers.utils.defaultAbiCoder.encode(["address"], [BobAddress]), { - from: BobAddress, - }); - const fathomStablecoinBalance2 = await fathomStablecoin.balanceOf(AliceAddress); - const BobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const aliceAdjustPosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice doesn't add WXDC").to.be.equal( - WeiPerWad.mul(2) - ); - expect(aliceAdjustPosition.debtShare, "debtShare should be 2 FXD, because Alice drew more").to.be.equal(WeiPerWad.mul(2)); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance2, "Alice should receive 1 FXD, because Alice drew 1 time").to.be.equal(WeiPerWad); - expect(BobFathomStablecoinBalance, "Bob should receive 1 FXD from Alice position").to.be.equal(WeiPerWad); - }); - }); - context("move position", async () => { - context("same collateral pool", async () => { - it("should success", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC").to.be.equal(WeiPerWad); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Bob open a position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(bobProxyWallet, BobAddress, pools.XDC, WeiPerWad, WeiPerWad); - const bobPositionAddress = await positionManager.positions(2); - const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const bobPosition = await bookKeeper.positions(pools.XDC, bobPositionAddress); - expect(bobPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Bob locked 1 WXDC").to.be.equal(WeiPerWad); - expect(bobPosition.debtShare, "debtShare should be 1 FXD, because Bob drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob locked all WXDC into the position" - ).to.be.equal(0); - expect(bobFathomStablecoinBalance, "Bob should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 3. Alice allow Bob to manage position - await PositionHelper.allowManagePosition(aliceProxyWallet, AliceAddress, 1, BobAddress, true); - expect(await positionManager.ownerWhitelist(aliceProxyWallet.address, 1, BobAddress)).to.be.equal(true); - - // 4. bob proxy wallet allow Bob address to manage position - await PositionHelper.allowManagePosition(bobProxyWallet, BobAddress, 2, BobAddress, true); - expect(await positionManager.ownerWhitelist(bobProxyWallet.address, 2, BobAddress)).to.be.equal(true); - - // 5. Bob try to move collateral to alice position - await positionManager.movePosition(2, 1, { from: BobAddress }); - const aliceFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(AliceAddress); - const bobFathomStablecoinBalancefinal = await fathomStablecoin.balanceOf(BobAddress); - const alicePositionAfterMovePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect( - alicePositionAfterMovePosition.lockedCollateral, - "lockedCollateral should be 2 WXDC, because Bob move locked 1 WXDC to Alice" - ).to.be.equal(WeiPerWad.mul(2)); - expect(alicePositionAfterMovePosition.debtShare, "debtShare should be 1 FXD, because Bob move DebtShare to Alice").to.be.equal( - WeiPerWad.mul(2) - ); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice all lock collateral" - ).to.be.equal(0); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob all lock collateral" - ).to.be.equal(0); - expect(aliceFathomStablecoinBalancefinal, "Alice should receive 1 FXD, because Alice drew 1 time").to.be.equal(WeiPerWad); - expect(bobFathomStablecoinBalancefinal, "Bob should receive 1 FXD, because Bob drew 1 time").to.be.equal(WeiPerWad); - }); - }); - context("between 2 collateral pool", async () => { - it("should revert", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC").to.be.equal(WeiPerWad); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Bob open a position with 1 WXDC and draw 1 FXD at collateral pool id 2 - await PositionHelper.openPositionAndDraw(bobProxyWallet, BobAddress, pools.GLD, WeiPerWad, WeiPerWad); - const bobPositionAddress = await positionManager.positions(2); - const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const bobPosition = await bookKeeper.positions(pools.GLD, bobPositionAddress); - expect(bobPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Bob locked 1 WXDC").to.be.equal(WeiPerWad); - expect(bobPosition.debtShare, "debtShare should be 1 FXD, because Bob drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.GLD, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob locked all WXDC into the position" - ).to.be.equal(0); - expect(bobFathomStablecoinBalance, "Bob should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - - // 3. Alice allow Bob to manage position - await PositionHelper.allowManagePosition(aliceProxyWallet, AliceAddress, 1, BobAddress, true); - expect(await positionManager.ownerWhitelist(aliceProxyWallet.address, 1, BobAddress)).to.be.equal(true); - - // 4. bob proxy wallet allow Bob address to manage position - await PositionHelper.allowManagePosition(bobProxyWallet, BobAddress, 2, BobAddress, true); - expect(await positionManager.ownerWhitelist(bobProxyWallet.address, 2, BobAddress)).to.be.equal(true); - - // 5. Bob try to move position to Alice position - await expect(positionManager.movePosition(2, 1, { from: BobAddress })).to.be.revertedWith("!same collateral pool"); - }); - }); - }); - }); - - context("position owner not allow other user to manage position with user wallet address", async () => { - context("move collateral", async () => { - context("same collateral pool", async () => { - context("and Bob move collateral of Alice to himself", async () => { - it("should revert", async () => { - // 1. Alice open a new position with 2 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(2), WeiPerWad); - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Bob open a position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(bobProxyWallet, BobAddress, pools.XDC, WeiPerWad, WeiPerWad); - const bobPositionAddress = await positionManager.positions(2); - const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const bobPosition = await bookKeeper.positions(pools.XDC, bobPositionAddress); - expect(bobPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Bob locked 1 WXDC").to.be.equal(WeiPerWad); - expect(bobPosition.debtShare, "debtShare should be 1 FXD, because Bob drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob locked all WXDC into the position" - ).to.be.equal(0); - expect(bobFathomStablecoinBalance, "Bob should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 3. Alice try to unlock 1 WXDC at her position - await PositionHelper.adjustPosition( - aliceProxyWallet, - AliceAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - WeiPerWad.mul(-1), - 0 - ); - const aliceAdjustPosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC").to.be.equal(WeiPerWad); - expect(aliceAdjustPosition.debtShare, "debtShare should be 1 FXD, because Alice didn't draw more").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 1 WXDC, because Alice unlocked 1 WXDC into the position" - ).to.be.equal(WeiPerWad); - - // 4. Bob try to move collateral of Alice position to Bob position - await expect( - PositionHelper.moveCollateral( - bobProxyWallet, - BobAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - bobPositionAddress, - WeiPerWad - ) - ).to.be.revertedWith("owner not allowed"); - }); - }); - }); - context("between collateral pool", async () => { - context("and Bob move collateral of Alice to himself", async () => { - it("should revert", async () => { - // 1. Alice open a new position with 2 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(2), WeiPerWad); - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Bob open a position at collateral pool 2 with 2 WXDC and draw 1 FXD - await PositionHelper.openPositionAndDraw(bobProxyWallet, BobAddress, pools.GLD, WeiPerWad.mul(2), WeiPerWad); - const bobPositionAddress = await positionManager.positions(2); - const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const bobPosition = await bookKeeper.positions(pools.GLD, bobPositionAddress); - expect(bobPosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Bob locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); - expect(bobPosition.debtShare, "debtShare should be 1 FXD, because Bob drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.GLD, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob locked all WXDC into the position" - ).to.be.equal(0); - expect(bobFathomStablecoinBalance, "Bob should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 3. Alice try to unlock 1 WXDC at her position - await PositionHelper.adjustPosition( - aliceProxyWallet, - AliceAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - WeiPerWad.mul(-1), - 0, - collateralTokenAdapter.address - ); - const aliceAdjustPosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC").to.be.equal(WeiPerWad); - expect(aliceAdjustPosition.debtShare, "debtShare should be 1 FXD, because Alice didn't draw more").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 1 WXDC, because Alice unlocked 1 WXDC" - ).to.be.equal(WeiPerWad); - - // 4. Bob try to move collateral of Alice position to his position - await expect( - PositionHelper.moveCollateral( - bobProxyWallet, - BobAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - bobPositionAddress, - WeiPerWad, - collateralTokenAdapter.address - ) - ).to.be.revertedWith("owner not allowed"); - }); - }); - }); - }); - - context("mint FXD", async () => { - it("should revert", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(2), WeiPerWad); - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - - // 2. Bob try to mint FXD at Alice position - await expect( - positionManager.adjustPosition( - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - 0, - alicePosition.debtShare, - ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), - { from: BobAddress } - ) - ).to.be.revertedWith("owner not allowed"); - }); - }); - - context("move position", async () => { - context("same collateral pool", async () => { - it("should revert", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC").to.be.equal(WeiPerWad); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Bob open a position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(bobProxyWallet, BobAddress, pools.XDC, WeiPerWad, WeiPerWad); - const bobPositionAddress = await positionManager.positions(2); - const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const bobPosition = await bookKeeper.positions(pools.XDC, bobPositionAddress); - expect(bobPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Bob locked 1 WXDC").to.be.equal(WeiPerWad); - expect(bobPosition.debtShare, "debtShare should be 1 FXD, because Bob drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob locked all WXDC into the position" - ).to.be.equal(0); - expect(bobFathomStablecoinBalance, "Bob should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - - // 3. Bob try to move collateral to alice position - await expect(positionManager.movePosition(2, 1, { from: BobAddress })).to.be.revertedWith("owner not allowed"); - }); - }); - context("between 2 collateral pool", async () => { - it("should revert", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC").to.be.equal(WeiPerWad); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - // 2. Bob open a position with 1 WXDC and draw 1 FXD at collateral pool id 2 - await PositionHelper.openPositionAndDraw(bobProxyWallet, BobAddress, pools.GLD, WeiPerWad, WeiPerWad); - const bobPositionAddress = await positionManager.positions(2); - const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); - const bobPosition = await bookKeeper.positions(pools.GLD, bobPositionAddress); - expect(bobPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Bob locked 1 WXDC").to.be.equal(WeiPerWad); - expect(bobPosition.debtShare, "debtShare should be 1 FXD, because Bob drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.GLD, bobPositionAddress), - "collateralToken inside Bob's position address should be 0 WXDC, because Bob locked all WXDC into the position" - ).to.be.equal(0); - expect(bobFathomStablecoinBalance, "Bob should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - - // 3. Bob try to move position to Alice position - await expect(positionManager.movePosition(2, 1, { from: BobAddress })).to.be.revertedWith("owner not allowed"); - }); - }); - }); - }); - - context("position owner can export and can import", async () => { - it("should success", async () => { - // 1. Alice open a new position with 1 WXDC and draw 1 FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad, WeiPerWad); - const alicePositionAddress = await positionManager.positions(1); - const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); - const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice locked 1 WXDC").to.be.equal(WeiPerWad); - expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); - expect( - await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), - "collateralToken inside Alice's position address should be 0 WXDC, because Alice locked all WXDC into the position" - ).to.be.equal(0); - expect(fathomStablecoinBalance, "Alice should receive 1 FXD from drawing 1 FXD").to.be.equal(WeiPerWad); - - // 2. alice allow manage position - await PositionHelper.allowManagePosition(aliceProxyWallet, AliceAddress, 1, AliceAddress, true); - expect(await positionManager.ownerWhitelist(aliceProxyWallet.address, 1, AliceAddress)).to.be.equal(true); - - // 3. alice allow positionManage - await bookKeeper.whitelist(positionManager.address, { from: AliceAddress }); - - // 4. alice allow migration - await positionManager.allowMigratePosition(aliceProxyWallet.address, true, { from: AliceAddress }); - expect(await positionManager.migrationWhitelist(AliceAddress, aliceProxyWallet.address)).to.be.equal(true); - - // 5. Alice export position - await PositionHelper.exportPosition(aliceProxyWallet, AliceAddress, 1, AliceAddress); - const alicePositionAfterExport = await bookKeeper.positions(pools.XDC, AliceAddress); - expect(alicePositionAfterExport.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice export").to.be.equal(WeiPerWad); - expect(alicePositionAfterExport.debtShare, "debtShare should be 1 FXD, because Alice export").to.be.equal(WeiPerWad); - const alicePositionWalletPositionAfterExport = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePositionWalletPositionAfterExport.lockedCollateral, "lockedCollateral should be 0 WXDC, because Alice export").to.be.equal(0); - expect(alicePositionWalletPositionAfterExport.debtShare, "debtShare should be 0 FXD, because Alice export").to.be.equal(0); - - //6. alice import position back - await PositionHelper.importPosition(aliceProxyWallet, AliceAddress, AliceAddress, 1); - const alicePositionAfterImport = await bookKeeper.positions(pools.XDC, AliceAddress); - expect(alicePositionAfterImport.lockedCollateral, "lockedCollateral should be 0 WXDC, because Alice Import").to.be.equal(0); - expect(alicePositionAfterImport.debtShare, "debtShare should be 0 FXD, because Alice Import").to.be.equal(0); - const alicePositionWalletPositionAfterImport = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePositionWalletPositionAfterImport.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice Import").to.be.equal( - WeiPerWad - ); - expect(alicePositionWalletPositionAfterImport.debtShare, "debtShare should be 1 FXD, because Alice Import").to.be.equal(WeiPerWad); - }); - }); - context("position ceiling", async () => { - context("open position exceeds position ceiling", async () => { - it("should revert", async () => { - await simplePriceFeed.setPrice(WeiPerRay.div(1000), { gasLimit: 1000000 }); - - await expect( - PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(2000), WeiPerWad.mul(1000001)) - ).to.be.revertedWith("BookKeeper/position-debt-ceiling-exceeded"); - }); - }); - context("adjust position exceeds position ceiling", async () => { - it("should revert", async () => { - await simplePriceFeed.setPrice(WeiPerRay.div(1000), { gasLimit: 1000000 }); - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(2000), WeiPerWad.mul(1000000)); - await expect( - PositionHelper.adjustPosition( - aliceProxyWallet, - AliceAddress, - await positionManager.ownerLastPositionId(aliceProxyWallet.address), - 0, - WeiPerWad - ) - ).to.be.revertedWith("BookKeeper/position-debt-ceiling-exceeded"); - }); - }); - }); - }); -}); diff --git a/scripts/tests/integration/ProxyWallet.test.js b/scripts/tests/integration/ProxyWallet.test.js deleted file mode 100644 index fdbe7c27..00000000 --- a/scripts/tests/integration/ProxyWallet.test.js +++ /dev/null @@ -1,133 +0,0 @@ -const chai = require("chai"); -const { solidity } = require("ethereum-waffle"); -chai.use(solidity); -const { expect } = require("chai"); - -const { AliceAddress, BobAddress, AddressZero } = require("../helper/address"); -const { loadFixture } = require("../helper/fixtures"); -const { getProxy } = require("../../common/proxies"); - -const setup = async () => { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - - const proxyWalletRegistry = await getProxy(proxyFactory, "ProxyWalletRegistry"); - await proxyWalletRegistry.setDecentralizedMode(true); - - return { proxyWalletRegistry }; -}; - -describe("ProxyWallet", () => { - // Contract - let proxyWalletRegistry; - - before(async () => { - await snapshot.revertToSnapshot(); - }); - - beforeEach(async () => { - ({ proxyWalletRegistry } = await loadFixture(setup)); - }); - describe("#new user create a new proxy wallet", async () => { - context("alice create a new proxy wallet", async () => { - it("alice should be able to create a proxy wallet", async () => { - expect(await proxyWalletRegistry.proxies(AliceAddress)).to.be.equal(AddressZero); - - await proxyWalletRegistry.build(AliceAddress, { from: AliceAddress, gasLimit: 2000000 }); - const proxyWalletAliceAddress = await proxyWalletRegistry.proxies(AliceAddress); - expect(proxyWalletAliceAddress).to.be.not.equal(AddressZero); - const proxyWalletAsAlice = await artifacts.initializeInterfaceAt("ProxyWallet", proxyWalletAliceAddress); - expect(await proxyWalletAsAlice.owner({ from: AliceAddress })).to.be.equal(AliceAddress); - }); - }); - }); - describe("#user already has a proxy wallet", async () => { - context("alice already has a proxy wallet and alice creates a new proxy wallet", async () => { - it("alice should not be able to create a proxy wallet", async () => { - expect(await proxyWalletRegistry.proxies(AliceAddress)).to.be.equal(AddressZero); - // #1 alice create a proxy wallet 1 - await proxyWalletRegistry.build(AliceAddress, { from: AliceAddress, gasLimit: 2000000 }); - const proxyWalletAliceAddress = await proxyWalletRegistry.proxies(AliceAddress); - expect(proxyWalletAliceAddress).to.be.not.equal(AddressZero); - const proxyWalletAsAlice = await artifacts.initializeInterfaceAt("ProxyWallet", proxyWalletAliceAddress); - expect(await proxyWalletAsAlice.owner({ from: AliceAddress })).to.be.equal(AliceAddress); - - // #2 alice create a proxy wallet 2 - await expect(proxyWalletRegistry.build(AliceAddress, { from: AliceAddress, gasLimit: 2000000 })).to.be.reverted; - }); - }); - }); - describe("#user want to change the owner of a proxy wallet", async () => { - context("alice want to change the owner of a proxy wallet to bob, but bob already has proxy wallet", async () => { - it("alice should not be able to change the owner of a proxy wallet", async () => { - // #1 alice create a proxy wallet - await proxyWalletRegistry.build(AliceAddress, { from: AliceAddress, gasLimit: 2000000 }); - const proxyWalletAliceAddress = await proxyWalletRegistry.proxies(AliceAddress); - expect(proxyWalletAliceAddress).to.be.not.equal(AddressZero); - const proxyWalletAsAlice = await artifacts.initializeInterfaceAt("ProxyWallet", proxyWalletAliceAddress); - expect(await proxyWalletAsAlice.owner({ from: AliceAddress })).to.be.equal(AliceAddress); - - // #2 bob create a proxy wallet - await proxyWalletRegistry.build(BobAddress, { from: BobAddress, gasLimit: 2000000 }); - const proxyWalletBobAddress = await proxyWalletRegistry.proxies(BobAddress); - expect(proxyWalletBobAddress).to.be.not.equal(AddressZero); - const proxyWalletAsBob = await artifacts.initializeInterfaceAt("ProxyWallet", proxyWalletBobAddress); - expect(await proxyWalletAsBob.owner({ from: BobAddress })).to.be.equal(BobAddress); - - // #3 alice set bob to owner proxy wallet registry - await expect(proxyWalletRegistry.setOwner(BobAddress, { from: AliceAddress })).to.be.reverted; - }); - }); - context("alice only change the owner of a proxy wallet registry", async () => { - it("alice should not be able to change the owner of a proxy wallet registry", async () => { - // #1 alice create a proxy wallet - await proxyWalletRegistry.build(AliceAddress, { from: AliceAddress, gasLimit: 2000000 }); - const proxyWalletAliceAddress = await proxyWalletRegistry.proxies(AliceAddress); - expect(proxyWalletAliceAddress).to.be.not.equal(AddressZero); - const proxyWalletAsAlice = await artifacts.initializeInterfaceAt("ProxyWallet", proxyWalletAliceAddress); - expect(await proxyWalletAsAlice.owner({ from: AliceAddress })).to.be.equal(AliceAddress); - - // #2 alice set bob to owner proxy wallet registry - await expect(proxyWalletRegistry.setOwner(BobAddress, { from: AliceAddress })).to.be.reverted; - }); - }); - context("alice change the owner of a proxy wallet and proxy wallet registry", async () => { - it("alice should be able to change the owner of a proxy wallet", async () => { - // #1 alice create a proxy wallet - await proxyWalletRegistry.build(AliceAddress, { from: AliceAddress, gasLimit: 2000000 }); - const proxyWalletAliceAddress = await proxyWalletRegistry.proxies(AliceAddress); - expect(proxyWalletAliceAddress).to.be.not.equal(AddressZero); - const proxyWalletAsAlice = await artifacts.initializeInterfaceAt("ProxyWallet", proxyWalletAliceAddress); - expect(await proxyWalletAsAlice.owner({ from: AliceAddress })).to.be.equal(AliceAddress); - - // #2 alice set bob to owner proxy wallet - await proxyWalletAsAlice.setOwner(BobAddress, { from: AliceAddress }); - expect(await proxyWalletAsAlice.owner({ from: AliceAddress })).to.be.equal(BobAddress); - - // #3 alice set bob to owner proxy wallet registry - await proxyWalletRegistry.setOwner(BobAddress, { from: AliceAddress }); - expect(await proxyWalletRegistry.proxies(BobAddress)).to.be.equal(proxyWalletAliceAddress); - expect(await proxyWalletRegistry.proxies(AliceAddress)).to.be.equal(AddressZero); - }); - }); - }); - - describe("Should fail for empty data", async () => { - context("Should not be able to execute empty data", async () => { - it("Should revert for empty data", async () => { - await proxyWalletRegistry.build(AliceAddress, { from: AliceAddress, gasLimit: 2000000 }); - const proxyWalletAliceAddress = await proxyWalletRegistry.proxies(AliceAddress); - expect(proxyWalletAliceAddress).to.be.not.equal(AddressZero); - const proxyWalletAsAlice = await artifacts.initializeInterfaceAt("ProxyWallet", proxyWalletAliceAddress); - expect(await proxyWalletAsAlice.owner({ from: AliceAddress })).to.be.equal(AliceAddress); - await expect( - proxyWalletAsAlice.execute( - [], //EMPTY DATA - { - from: AliceAddress, - } - ) - ).to.be.revertedWith("proxy-wallet-data-required"); - }); - }); - }); -}); diff --git a/scripts/tests/integration/ShowStopper.test.js b/scripts/tests/integration/ShowStopper.test.js deleted file mode 100644 index 0ddd715b..00000000 --- a/scripts/tests/integration/ShowStopper.test.js +++ /dev/null @@ -1,482 +0,0 @@ -const chai = require("chai"); -const { ethers } = require("ethers"); -const { solidity } = require("ethereum-waffle"); -chai.use(solidity); - -const { WeiPerRad, WeiPerRay, WeiPerWad } = require("../helper/unit"); -const { advanceBlock, increase } = require("../helper/time"); -const { createProxyWallets } = require("../helper/proxy-wallets"); -const { AliceAddress, BobAddress } = require("../helper/address"); -const PositionHelper = require("../helper/positions"); -const { loadFixture } = require("../helper/fixtures"); -const { getProxy } = require("../../common/proxies"); -const pools = require("../../common/collateral"); -const { getContract, createMock } = require("../helper/contracts"); - -const { expect } = chai; - -const WeekInSeconds = 604800; - -const setup = async () => { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - - const bookKeeper = await getProxy(proxyFactory, "BookKeeper"); - const liquidationEngine = await getProxy(proxyFactory, "LiquidationEngine"); - const positionManager = await getProxy(proxyFactory, "PositionManager"); - const stablecoinAdapter = await getProxy(proxyFactory, "StablecoinAdapter"); - const fathomStablecoin = await getProxy(proxyFactory, "FathomStablecoin"); - const systemDebtEngine = await getProxy(proxyFactory, "SystemDebtEngine"); - const priceOracle = await getProxy(proxyFactory, "PriceOracle"); - const showStopper = await getProxy(proxyFactory, "ShowStopper"); - const mockFathomBridge = await createMock("MockFathomBridge"); - const accessControlConfig = await getProxy(proxyFactory, "AccessControlConfig"); - const collateralPoolConfig = await getProxy(proxyFactory, "CollateralPoolConfig"); - const collateralTokenAdapter = await getProxy(proxyFactory, "CollateralTokenAdapter"); - const WXDC = await artifacts.initializeInterfaceAt("WXDC", "WXDC"); - const MockCollateralTokenAdapter = await artifacts.initializeInterfaceAt("MockCollateralTokenAdapter", "MockCollateralTokenAdapter"); - const proxyWalletRegistry = await getProxy(proxyFactory, "ProxyWalletRegistry"); - await proxyWalletRegistry.setDecentralizedMode(true); - await showStopper.setFathomBridge(mockFathomBridge.address, { gasLimit: 1000000 }); - await mockFathomBridge.mock.totalBridgedInAmount.returns(0); - await mockFathomBridge.mock.totalBridgedOutAmount.returns(0); - await mockFathomBridge.mock.cage.returns(); - - ({ - proxyWallets: [aliceProxyWallet, bobProxyWallet], - } = await createProxyWallets([AliceAddress, BobAddress])); - - await collateralPoolConfig.setStabilityFeeRate(pools.XDC, WeiPerRay, { gasLimit: 1000000 }); - await collateralPoolConfig.setStabilityFeeRate(pools.WXDC, WeiPerRay, { gasLimit: 1000000 }); - - await fathomStablecoin.approve(stablecoinAdapter.address, WeiPerWad.mul(10000), { from: AliceAddress }); - - return { - bookKeeper, - showStopper, - liquidationEngine, - systemDebtEngine, - priceOracle, - stablecoinAdapter, - accessControlConfig, - positionManager, - aliceProxyWallet, - bobProxyWallet, - collateralTokenAdapter, - WXDC, - MockCollateralTokenAdapter, - }; -}; - -describe("ShowStopper", () => { - // Proxy wallet - let aliceProxyWallet; - let bobProxyWallet; - - // Contract - let positionManager; - let showStopper; - let bookKeeper; - let liquidationEngine; - let systemDebtEngine; - let priceOracle; - let stablecoinAdapter; - let accessControlConfig; - - before(async () => { - await snapshot.revertToSnapshot(); - }); - - beforeEach(async () => { - ({ - bookKeeper, - showStopper, - liquidationEngine, - systemDebtEngine, - priceOracle, - stablecoinAdapter, - accessControlConfig, - positionManager, - aliceProxyWallet, - bobProxyWallet, - collateralTokenAdapter, - WXDC, - MockCollateralTokenAdapter, - } = await loadFixture(setup)); - }); - - describe("#cage", () => { - context("when doesn't grant showStopperRole for showStopper", () => { - it("should be revert", async () => { - await accessControlConfig.revokeRole(await accessControlConfig.SHOW_STOPPER_ROLE(), showStopper.address); - await expect(showStopper.cage(WeekInSeconds, { gasLimit: 1000000 })).to.be.revertedWith("!(ownerRole or showStopperRole)"); - }); - }); - context("when grant showStopperRole for all contract", () => { - it("should be able to cage", async () => { - await showStopper.cage(WeekInSeconds, { gasLimit: 1000000 }); - - expect(await bookKeeper.live()).to.be.equal(0); - expect(await liquidationEngine.live()).to.be.equal(0); - expect(await systemDebtEngine.live()).to.be.equal(0); - expect(await priceOracle.live()).to.be.equal(0); - }); - }); - context("when some contract was already caged", () => { - it("should be able to cage", async () => { - await systemDebtEngine.cage({ gasLimit: 1000000 }); - await showStopper.cage(WeekInSeconds, { gasLimit: 1000000 }); - - expect(await bookKeeper.live()).to.be.equal(0); - expect(await liquidationEngine.live()).to.be.equal(0); - expect(await systemDebtEngine.live()).to.be.equal(0); - expect(await priceOracle.live()).to.be.equal(0); - }); - }); - }); - describe("#cage(collateralPoolId)", () => { - context("deployer cage WXDC pool", () => { - it("should be able to cage", async () => { - // 1. - // a. open a new position - // b. lock WXDC - // c. mint FXD - - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - - await showStopper.cage(WeekInSeconds); - await showStopper.cagePool(pools.XDC); - - expect(await showStopper.cagePrice(pools.XDC)).to.be.equal(WeiPerRay); - expect(await showStopper.totalDebtShare(pools.XDC)).to.be.equal(WeiPerWad.mul(5)); - }); - }); - context("bookKeeper was already caged", () => { - it("should be able to cage", async () => { - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - - await bookKeeper.cage(); - await showStopper.cage(WeekInSeconds); - await showStopper.cagePool(pools.XDC); - - expect(await showStopper.cagePrice(pools.XDC)).to.be.equal(WeiPerRay); - expect(await showStopper.totalDebtShare(pools.XDC)).to.be.equal(WeiPerWad.mul(5)); - }); - }); - }); - describe("#accumulateBadDebt, #redeemLockedCollateral", () => { - context("when the caller is not the position owner", () => { - it("should not be able to redeemLockedCollateral", async () => { - // alice's position #1 - // a. open a new position - // b. lock WXDC - // c. mint FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - await advanceBlock(); - const positionId = await positionManager.ownerLastPositionId(aliceProxyWallet.address); - const positionAddress = await positionManager.positions(positionId); - - await showStopper.cage(WeekInSeconds); - - await showStopper.cagePool(pools.XDC); - - // accumulate bad debt posiion #1 - await showStopper.accumulateBadDebt(pools.XDC, positionAddress); - - // redeem lock collateral position #1 - await expect(PositionHelper.redeemLockedCollateral(bobProxyWallet, BobAddress, positionId)).to.be.revertedWith("owner not allowed"); - }); - }); - context("when the caller is the position owner", () => { - it("should be able to redeemLockedCollateral", async () => { - // alice's position #1 - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - await advanceBlock(); - const positionId = await positionManager.ownerLastPositionId(aliceProxyWallet.address); - const positionAddress = await positionManager.positions(positionId); - - // bob's position #2 - await PositionHelper.openXDCPositionAndDraw(bobProxyWallet, BobAddress, pools.XDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - await advanceBlock(); - const positionId2 = await positionManager.ownerLastPositionId(bobProxyWallet.address); - const positionAddress2 = await positionManager.positions(positionId2); - - await showStopper.cage(WeekInSeconds); - - await showStopper.cagePool(pools.XDC); - - // accumulate bad debt posiion #1 - await showStopper.accumulateBadDebt(pools.XDC, positionAddress); - const position1 = await bookKeeper.positions(pools.XDC, positionAddress); - expect(position1.lockedCollateral).to.be.equal(WeiPerWad.mul(5)); - expect(position1.debtShare).to.be.equal(0); - expect(await bookKeeper.collateralToken(pools.XDC, showStopper.address)).to.be.equal(WeiPerWad.mul(5)); - expect(await bookKeeper.systemBadDebt(systemDebtEngine.address)).to.be.equal(WeiPerRad.mul(5)); - - // accumulate bad debt posiion #2 - await showStopper.accumulateBadDebt(pools.XDC, positionAddress2); - const position2 = await bookKeeper.positions(pools.XDC, positionAddress2); - expect(position2.lockedCollateral).to.be.equal(WeiPerWad.mul(5)); - expect(position2.debtShare).to.be.equal(0); - expect(await bookKeeper.collateralToken(pools.XDC, showStopper.address)).to.be.equal(WeiPerWad.mul(10)); - expect(await bookKeeper.systemBadDebt(systemDebtEngine.address)).to.be.equal(WeiPerRad.mul(10)); - - // redeem lock collateral position #1 - await PositionHelper.redeemLockedCollateral(aliceProxyWallet, AliceAddress, positionId); - - expect((await bookKeeper.positions(pools.XDC, positionAddress)).lockedCollateral).to.be.equal(0); - expect(await bookKeeper.collateralToken(pools.XDC, aliceProxyWallet.address)).to.be.equal(WeiPerWad.mul(5)); - - // redeem lock collateral position #2 - await PositionHelper.redeemLockedCollateral(bobProxyWallet, BobAddress, positionId2); - - expect((await bookKeeper.positions(pools.XDC, positionAddress2)).lockedCollateral).to.be.equal(0); - expect(await bookKeeper.collateralToken(pools.XDC, bobProxyWallet.address)).to.be.equal(WeiPerWad.mul(5)); - await collateralTokenAdapter.cage(); - - // emergency withdraw position #1 - await PositionHelper.emergencyWithdraw(aliceProxyWallet, AliceAddress, collateralTokenAdapter.address); - expect(await WXDC.balanceOf(AliceAddress)).to.be.equal(WeiPerWad.mul(5)); - // emergency withdraw position #2 - await PositionHelper.emergencyWithdraw(bobProxyWallet, BobAddress, collateralTokenAdapter.address); - expect(await WXDC.balanceOf(AliceAddress)).to.be.equal(WeiPerWad.mul(5)); - }); - }); - }); - describe("#finalizeDebt, #finalizeCashPrice", () => { - context("when finalizeDebt and finalizeCashPrice", () => { - it("should be able to call", async () => { - // alice's position #1 - // a. open a new position - // b. lock XDC - // c. mint FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - await advanceBlock(); - const positionId = await positionManager.ownerLastPositionId(aliceProxyWallet.address); - const positionAddress = await positionManager.positions(positionId); - - // bob's position #2 - // a. open a new position - // b. lock XDC - // c. mint FXD - await PositionHelper.openXDCPositionAndDraw(bobProxyWallet, BobAddress, pools.XDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - await advanceBlock(); - const positionId2 = await positionManager.ownerLastPositionId(bobProxyWallet.address); - const positionAddress2 = await positionManager.positions(positionId2); - - await showStopper.cage(WeekInSeconds); - - await showStopper.cagePool(pools.XDC); - - // accumulate bad debt posiion #1 - await showStopper.accumulateBadDebt(pools.XDC, positionAddress); - const position1 = await bookKeeper.positions(pools.XDC, positionAddress); - expect(position1.lockedCollateral).to.be.equal(WeiPerWad.mul(5)); - expect(position1.debtShare).to.be.equal(0); - expect(await bookKeeper.collateralToken(pools.XDC, showStopper.address)).to.be.equal(WeiPerWad.mul(5)); - expect(await bookKeeper.systemBadDebt(systemDebtEngine.address)).to.be.equal(WeiPerRad.mul(5)); - - // accumulate bad debt posiion #2 - await showStopper.accumulateBadDebt(pools.XDC, positionAddress2); - const position2 = await bookKeeper.positions(pools.XDC, positionAddress2); - expect(position2.lockedCollateral).to.be.equal(WeiPerWad.mul(5)); - expect(position2.debtShare).to.be.equal(0); - expect(await bookKeeper.collateralToken(pools.XDC, showStopper.address)).to.be.equal(WeiPerWad.mul(10)); - expect(await bookKeeper.systemBadDebt(systemDebtEngine.address)).to.be.equal(WeiPerRad.mul(10)); - - // finalize debt - await increase(WeekInSeconds); - await showStopper.finalizeDebt(); - // total debt - expect(await showStopper.debt()).to.be.equal(WeiPerRad.mul(10)); - - // finalize cash price - await showStopper.finalizeCashPrice(pools.XDC); - // badDebtAccumulator / totalDebt = 10000000000000000000000000000000000000000000000 / 10000000000000000000 = 1000000000000000000000000000 - expect(await showStopper.finalCashPrice(pools.XDC)).to.be.equal(WeiPerRay); - }); - }); - }); - describe("#accumulateStablecoin, #redeemStablecoin", () => { - context("when redeem stablecoin", () => { - it("should be able to accumulateStablecoin, redeemStablecoin", async () => { - // alice's position #1 - // a. open a new position - // b. lock XDC - // c. mint FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - await advanceBlock(); - const positionId = await positionManager.ownerLastPositionId(aliceProxyWallet.address); - const positionAddress = await positionManager.positions(positionId); - - // bob's position #2 - // a. open a new position - // b. lock XDC - // c. mint FXD - await PositionHelper.openXDCPositionAndDraw(bobProxyWallet, BobAddress, pools.XDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - await advanceBlock(); - const positionId2 = await positionManager.ownerLastPositionId(bobProxyWallet.address); - const positionAddress2 = await positionManager.positions(positionId2); - - await showStopper.cage(WeekInSeconds); - - await showStopper.cagePool(pools.XDC); - - // accumulate bad debt posiion #1 - await showStopper.accumulateBadDebt(pools.XDC, positionAddress); - const position1 = await bookKeeper.positions(pools.XDC, positionAddress); - expect(position1.lockedCollateral).to.be.equal(WeiPerWad.mul(5)); - expect(position1.debtShare).to.be.equal(0); - expect(await bookKeeper.collateralToken(pools.XDC, showStopper.address)).to.be.equal(WeiPerWad.mul(5)); - expect(await bookKeeper.systemBadDebt(systemDebtEngine.address)).to.be.equal(WeiPerRad.mul(5)); - - // accumulate bad debt posiion #2 - await showStopper.accumulateBadDebt(pools.XDC, positionAddress2); - const position2 = await bookKeeper.positions(pools.XDC, positionAddress2); - expect(position2.lockedCollateral).to.be.equal(WeiPerWad.mul(5)); - expect(position2.debtShare).to.be.equal(0); - expect(await bookKeeper.collateralToken(pools.XDC, showStopper.address)).to.be.equal(WeiPerWad.mul(10)); - expect(await bookKeeper.systemBadDebt(systemDebtEngine.address)).to.be.equal(WeiPerRad.mul(10)); - - // finalize debt - await increase(WeekInSeconds); - await showStopper.finalizeDebt(); - expect(await showStopper.debt()).to.be.equal(WeiPerRad.mul(10)); - - // finalize cash price XDC - await showStopper.finalizeCashPrice(pools.XDC); - // badDebtAccumulator / totalDebt = 10000000000000000000000000000000000000000000000 / 10000000000000000000 = 1000000000000000000000000000 - expect(await showStopper.finalCashPrice(pools.XDC)).to.be.equal("1000000000000000000000000000"); - - // accumulate stablecoin - await stablecoinAdapter.deposit(AliceAddress, WeiPerWad.mul(5), ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), { - from: AliceAddress, - gasLimit: 1000000, - }); - - await bookKeeper.whitelist(showStopper.address, { from: AliceAddress }); - - await showStopper.accumulateStablecoin(WeiPerWad.mul(5), { from: AliceAddress }); - - // redeem stablecoin - //, - await showStopper.redeemStablecoin(pools.XDC, WeiPerWad.mul(5), { from: AliceAddress }); - expect(await bookKeeper.collateralToken(pools.XDC, AliceAddress)).to.be.equal("5000000000000000000"); - }); - }); - context("when redeem stablecoin with two col types", () => { - it("should be able to accumulateStablecoin, redeemStablecoin", async () => { - // alice's position #1 - // a. open a new position - // b. lock XDC - // c. mint FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - await advanceBlock(); - const positionId = await positionManager.ownerLastPositionId(aliceProxyWallet.address); - const positionAddress = await positionManager.positions(positionId); - - // bob's position #2 - // a. open a new position - // b. lock XDC - // c. mint FXD - await PositionHelper.openXDCPositionAndDraw(bobProxyWallet, BobAddress, pools.XDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - await advanceBlock(); - const positionId2 = await positionManager.ownerLastPositionId(bobProxyWallet.address); - const positionAddress2 = await positionManager.positions(positionId2); - - // alice's position #3 - // a. open a new position - // b. lock WXDC - // c. mint FXD - await PositionHelper.openXDCPositionAndDrawMock(aliceProxyWallet, AliceAddress, pools.WXDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - await advanceBlock(); - const positionId3 = await positionManager.ownerLastPositionId(aliceProxyWallet.address); - const positionAddress3 = await positionManager.positions(positionId3); - - // bob's position #4 - // a. open a new position - // b. lock WXDC - // c. mint FXD - await PositionHelper.openXDCPositionAndDrawMock(bobProxyWallet, BobAddress, pools.WXDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - await advanceBlock(); - const positionId4 = await positionManager.ownerLastPositionId(bobProxyWallet.address); - const positionAddress4 = await positionManager.positions(positionId4); - - await showStopper.cage(WeekInSeconds, { gasLimit: 1000000 }); - - await showStopper.cagePool(pools.XDC); - - await showStopper.cagePool(pools.WXDC); - - // accumulate bad debt posiion #1 - await showStopper.accumulateBadDebt(pools.XDC, positionAddress); - const position1 = await bookKeeper.positions(pools.XDC, positionAddress); - expect(position1.lockedCollateral).to.be.equal(WeiPerWad.mul(5)); - expect(position1.debtShare).to.be.equal(0); - expect(await bookKeeper.collateralToken(pools.XDC, showStopper.address)).to.be.equal(WeiPerWad.mul(5)); - expect(await bookKeeper.systemBadDebt(systemDebtEngine.address)).to.be.equal(WeiPerRad.mul(5)); - - // accumulate bad debt posiion #2 - await showStopper.accumulateBadDebt(pools.XDC, positionAddress2); - const position2 = await bookKeeper.positions(pools.XDC, positionAddress2); - expect(position2.lockedCollateral).to.be.equal(WeiPerWad.mul(5)); - expect(position2.debtShare).to.be.equal(0); - expect(await bookKeeper.collateralToken(pools.XDC, showStopper.address)).to.be.equal(WeiPerWad.mul(10)); - expect(await bookKeeper.systemBadDebt(systemDebtEngine.address)).to.be.equal(WeiPerRad.mul(10)); - - // accumulate bad debt posiion #3 - await showStopper.accumulateBadDebt(pools.WXDC, positionAddress3); - const position3 = await bookKeeper.positions(pools.WXDC, positionAddress3); - expect(position3.lockedCollateral).to.be.equal(WeiPerWad.mul(5)); - expect(position3.debtShare).to.be.equal(0); - expect(await bookKeeper.collateralToken(pools.WXDC, showStopper.address)).to.be.equal(WeiPerWad.mul(5)); - expect(await bookKeeper.systemBadDebt(systemDebtEngine.address)).to.be.equal(WeiPerRad.mul(15)); - - // accumulate bad debt posiion #4 - await showStopper.accumulateBadDebt(pools.WXDC, positionAddress4); - const position4 = await bookKeeper.positions(pools.WXDC, positionAddress4); - expect(position4.lockedCollateral).to.be.equal(WeiPerWad.mul(5)); - expect(position4.debtShare).to.be.equal(0); - expect(await bookKeeper.collateralToken(pools.WXDC, showStopper.address)).to.be.equal(WeiPerWad.mul(10)); - expect(await bookKeeper.systemBadDebt(systemDebtEngine.address)).to.be.equal(WeiPerRad.mul(20)); - - // finalize debt - await increase(WeekInSeconds); - await showStopper.finalizeDebt(); - expect(await showStopper.debt()).to.be.equal(WeiPerRad.mul(20)); - - // // finalize cash price XDC - await showStopper.finalizeCashPrice(pools.XDC); - - expect(await showStopper.finalCashPrice(pools.XDC)).to.be.equal("500000000000000000000000000"); - - // finalize cash price WXDC - await showStopper.finalizeCashPrice(pools.WXDC); - - expect(await showStopper.finalCashPrice(pools.WXDC)).to.be.equal("500000000000000000000000000"); - - // accumulate stablecoin - await stablecoinAdapter.deposit(AliceAddress, WeiPerWad.mul(5), ethers.utils.defaultAbiCoder.encode(["address"], [AliceAddress]), { - from: AliceAddress, - gasLimit: 1000000, - }); - - await bookKeeper.whitelist(showStopper.address, { from: AliceAddress }); - - await showStopper.accumulateStablecoin(WeiPerWad.mul(5), { from: AliceAddress }); - - await showStopper.redeemStablecoin(pools.XDC, WeiPerWad.mul(5), { from: AliceAddress }); - expect(await bookKeeper.collateralToken(pools.XDC, AliceAddress)).to.be.equal("2500000000000000000"); - - await showStopper.redeemStablecoin(pools.WXDC, WeiPerWad.mul(5), { from: AliceAddress }); - expect(await bookKeeper.collateralToken(pools.WXDC, AliceAddress)).to.be.equal("2500000000000000000"); - - await collateralTokenAdapter.cage(); - await collateralTokenAdapter.emergencyWithdraw(AliceAddress, { from: AliceAddress }); - expect(await WXDC.balanceOf(AliceAddress)).to.be.equal("2500000000000000000"); - await MockCollateralTokenAdapter.cage(); - await MockCollateralTokenAdapter.emergencyWithdraw(AliceAddress, { from: AliceAddress }); - expect(await WXDC.balanceOf(AliceAddress)).to.be.equal("5000000000000000000"); - }); - }); - }); -}); diff --git a/scripts/tests/integration/StabilityFeeCollector.test.js b/scripts/tests/integration/StabilityFeeCollector.test.js deleted file mode 100644 index d7e6911b..00000000 --- a/scripts/tests/integration/StabilityFeeCollector.test.js +++ /dev/null @@ -1,163 +0,0 @@ -const { BigNumber } = require("ethers"); -const chai = require("chai"); -const { solidity } = require("ethereum-waffle"); -chai.use(solidity); - -const { WeiPerRay, WeiPerWad } = require("../helper/unit"); -const TimeHelpers = require("../helper/time"); -const AssertHelpers = require("../helper/assert"); -const { createProxyWallets } = require("../helper/proxy-wallets"); -const { AliceAddress, DevAddress } = require("../helper/address"); -const PositionHelper = require("../helper/positions"); -const { loadFixture } = require("../helper/fixtures"); -const { getProxy } = require("../../common/proxies"); -const pools = require("../../common/collateral"); - -const setup = async () => { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - const simplePriceFeed = await artifacts.initializeInterfaceAt("SimplePriceFeed", "SimplePriceFeed"); - - const collateralPoolConfig = await getProxy(proxyFactory, "CollateralPoolConfig"); - const bookKeeper = await getProxy(proxyFactory, "BookKeeper"); - const stabilityFeeCollector = await getProxy(proxyFactory, "StabilityFeeCollector"); - const positionManager = await getProxy(proxyFactory, "PositionManager"); - const stablecoinAdapter = await getProxy(proxyFactory, "StablecoinAdapter"); - const fathomStablecoin = await getProxy(proxyFactory, "FathomStablecoin"); - - const proxyWalletRegistry = await getProxy(proxyFactory, "ProxyWalletRegistry"); - await proxyWalletRegistry.setDecentralizedMode(true); - - ({ - proxyWallets: [aliceProxyWallet], - } = await createProxyWallets([AliceAddress])); - - await stabilityFeeCollector.setSystemDebtEngine(DevAddress); - - await fathomStablecoin.approve(aliceProxyWallet.address, WeiPerWad.mul(10000), { from: AliceAddress }); - - return { - bookKeeper, - stablecoinAdapter, - positionManager, - stabilityFeeCollector, - simplePriceFeed, - collateralPoolConfig, - aliceProxyWallet, - }; -}; - -describe("Stability Fee", () => { - // Proxy wallet - let aliceProxyWallet; - - // Contract - let positionManager; - let bookKeeper; - // let tokenAdapter - let stablecoinAdapter; - let stabilityFeeCollector; - let collateralPoolConfig; - let simplePriceFeed; - - before(async () => { - await snapshot.revertToSnapshot(); - }); - - beforeEach(async () => { - ({ - bookKeeper, - stablecoinAdapter, - positionManager, - // tokenAdapter, - stabilityFeeCollector, - simplePriceFeed, - collateralPoolConfig, - aliceProxyWallet, - } = await loadFixture(setup)); - }); - - describe("#collect", () => { - context("when call collect directly and call deposit", () => { - it("should be success", async () => { - await collateralPoolConfig.setStabilityFeeRate(pools.XDC, BigNumber.from("1000000005781378656804591713"), { gasLimit: 1000000 }); - - // time increase 6 month - await TimeHelpers.increase(TimeHelpers.duration.seconds(BigNumber.from("15768000"))); - await simplePriceFeed.setPrice(WeiPerRay, { gasLimit: 1000000 }); - await stabilityFeeCollector.collect(pools.XDC, { gasLimit: 1000000 }); - const debtAccumulatedRate = await collateralPoolConfig.collateralPools(pools.XDC); - // debtAccumulatedRate = RAY(1000000005781378656804591713^15768000) = 1095445115010332226911367294 - AssertHelpers.assertAlmostEqual(debtAccumulatedRate.debtAccumulatedRate.toString(), "1095445115010332226911367294"); - AssertHelpers.assertAlmostEqual((await bookKeeper.stablecoin(DevAddress)).toString(), "0"); - - // position 1 - // a. open a new position - // b. lock WXDC - // c. mint FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - const positionId = await positionManager.ownerLastPositionId(aliceProxyWallet.address); - const positionAddress = await positionManager.positions(positionId); - - // position debtShare = 5000000000000000000000000000000000000000000000 / 1095445115010332226911367294 = 4564354645876384278 - AssertHelpers.assertAlmostEqual((await bookKeeper.positions(pools.XDC, positionAddress)).debtShare.toString(), "4564354645876384278"); - AssertHelpers.assertAlmostEqual((await collateralPoolConfig.collateralPools(pools.XDC)).totalDebtShare.toString(), "4564354645876384278"); - AssertHelpers.assertAlmostEqual( - (await collateralPoolConfig.collateralPools(pools.XDC)).debtAccumulatedRate.toString(), - "1095445115010332226911367294" - ); - - // time increase 1 year - await TimeHelpers.increase(TimeHelpers.duration.seconds(BigNumber.from("31536000"))); - await simplePriceFeed.setPrice(WeiPerRay, { gasLimit: 1000000 }); - - // position 2 - // a. open a new position - // b. lock WXDC - // c. mint FXD - await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, pools.XDC, WeiPerWad.mul(10), WeiPerWad.mul(5)); - - const positionId2 = await positionManager.ownerLastPositionId(aliceProxyWallet.address); - const positionAddress2 = await positionManager.positions(positionId2); - - // debtAccumulatedRate = RAY((1000000005781378656804591713^31536000) * 1095445115010332226911367294) = 1314534138012398672287467301 - AssertHelpers.assertAlmostEqual( - (await collateralPoolConfig.collateralPools(pools.XDC)).debtAccumulatedRate.toString(), - "1314534138012398672287467301" - ); - // debtShare * diffDebtAccumulatedRate = 4564354645876384278 * (1314534138012398672287467301 - 1095445115010332226911367294) = 999999999999999999792432233173942358090489946 - AssertHelpers.assertAlmostEqual((await bookKeeper.stablecoin(DevAddress)).toString(), "999999999999999999792432233173942358090489946"); - - // position debtShare = 5000000000000000000000000000000000000000000000 / 1314534138012398672287467301 = 3803628871563653565 - AssertHelpers.assertAlmostEqual((await bookKeeper.positions(pools.XDC, positionAddress2)).debtShare.toString(), "3803628871563653565"); - // 4564354645876384278 + 3803628871563653565 = 8367983517440037843 - AssertHelpers.assertAlmostEqual((await collateralPoolConfig.collateralPools(pools.XDC)).totalDebtShare.toString(), "8367983517440037843"); - - // time increase 1 year - await TimeHelpers.increase(TimeHelpers.duration.seconds(BigNumber.from("31536000"))); - await simplePriceFeed.setPrice(WeiPerRay, { gasLimit: 1000000 }); - - // debtAccumulatedRate ~ 20% - await stabilityFeeCollector.collect(pools.XDC, { gasLimit: 1000000 }); - - // debtAccumulatedRate = RAY((1000000005781378656804591713^31536000) * 1314534138012398672287467301) = 1577440965614878406737552619 - AssertHelpers.assertAlmostEqual( - (await collateralPoolConfig.collateralPools(pools.XDC)).debtAccumulatedRate.toString(), - "1577440965614878406737552619" - ); - // debtShare * diffDebtAccumulatedRate = 8367983517440037843 * (1577440965614878406737552619 - 1314534138012398672287467301) = 2199999999999999999533019044066331740498689074 - // 2199999999999999999533019044066331740498689074 + 999999999999999999792432233173942358090489946 = 3199999999999999999325451277240274098589179020 - AssertHelpers.assertAlmostEqual((await bookKeeper.stablecoin(DevAddress)).toString(), "3199999999999999999325451277240274098589179020"); - - // a. repay some FXD - // b. alice unlock some WXDC - await PositionHelper.wipeAndUnlockXDC(aliceProxyWallet, AliceAddress, positionId, WeiPerWad, WeiPerWad); - - AssertHelpers.assertAlmostEqual( - (await collateralPoolConfig.collateralPools(pools.XDC)).debtAccumulatedRate.toString(), - "1577440965614878406737552619" - ); - AssertHelpers.assertAlmostEqual((await bookKeeper.stablecoin(DevAddress)).toString(), "3199999999999999999325451277240274098589179020"); - }); - }); - }); -}); diff --git a/scripts/tests/integration/StableSwapModule.test.js b/scripts/tests/integration/StableSwapModule.test.js deleted file mode 100644 index 5fa1bba8..00000000 --- a/scripts/tests/integration/StableSwapModule.test.js +++ /dev/null @@ -1,585 +0,0 @@ -const chai = require("chai"); -const { BigNumber, ethers } = require("ethers"); -const { MaxUint256 } = require("@ethersproject/constants"); -const TimeHelpers = require("../helper/time"); -const ONE_BIG_NUMBER = BigNumber.from(1); - -const { solidity } = require("ethereum-waffle"); -chai.use(solidity); - -const { DeployerAddress } = require("../helper/address"); -const { loadFixture } = require("../helper/fixtures"); -const { getProxy } = require("../../common/proxies"); -const { WeiPerWad } = require("../helper/unit"); -const { expect } = chai; -const WeiPerSixDecimals = BigNumber.from(`1${"0".repeat(6)}`); - -const TO_DEPOSIT = ethers.utils.parseEther("10000000"); -const TO_MINT = ethers.utils.parseEther("20000000"); -const TO_DEPOSIT_USD = WeiPerSixDecimals.mul(10000000); -const TO_MINT_USD = WeiPerSixDecimals.mul(20000000); - -const TWENTY_PERCENT_OF_TO_DEPOSIT = ethers.utils.parseEther("4000000"); //20Million * 20% = 400k -const THIRTY_PERCENT_OF_TO_DEPOSIT = ethers.utils.parseEther("6000000"); -const ONE_PERCENT_OF_TOTAL_DEPOSIT = ethers.utils.parseEther("200000"); -const FOURTY_PERCENT_OF_TO_DEPOSIT = ethers.utils.parseEther("8000000"); - -const ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS = WeiPerSixDecimals.mul(200000); -const THIRTY_PERCENT_OF_TO_DEPOSIT_SIX_DECIMALS = WeiPerSixDecimals.mul(6000000); -const FOURTY_PERCENT_OF_TO_DEPOSIT_SIX_DECIMALS = WeiPerSixDecimals.mul(8000000); - -//why this divider: -//right now fee is 0.001 -//so for ONE_PERCENT_OF_TOTAL_DEPOSIT = 200000, fee = 200 -//so, totalValueDeposited will be decreased by 200 each time we swap to account for fees -//ie. for first swap it will reduce from 200,000,000 to 199,999,800 -//for second swap it will reduce from 199,999,800 to 199,999,600 -//so, taking One percent of total Deposit = 199,999,800 * 0.01 = 199998 after first swap -//therfore, we divide by 100000 (onehundred thousand)in each swap because we want to take 1% of total deposit -//ie, 200000 * 1e18 - 200000 * 1e18 / 100000 = =~ 199998 ether -//but dividing by 1000(thousand) so that we account for previous swaps fees -const DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT = BigNumber.from("1000"); - -const setup = async () => { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - const stableswapMultipleSwapsMock = await artifacts.initializeInterfaceAt("StableswapMultipleSwapsMock", "StableswapMultipleSwapsMock"); - - const stableSwapModule = await getProxy(proxyFactory, "StableSwapModule"); - const fathomStablecoin = await getProxy(proxyFactory, "FathomStablecoin"); - const stableSwapModuleWrapper = await getProxy(proxyFactory, "StableSwapModuleWrapper"); - - const usdtAddr = await stableSwapModule.token(); - const USDT = await artifacts.initializeInterfaceAt("ERC20Mintable", usdtAddr); - - await USDT.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000 }); - await fathomStablecoin.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000 }); - - await USDT.mint(DeployerAddress, TO_DEPOSIT, { gasLimit: 1000000 }); - await fathomStablecoin.mint(DeployerAddress, TO_DEPOSIT, { gasLimit: 1000000 }); - - await stableSwapModuleWrapper.depositTokens(TO_DEPOSIT, { gasLimit: 1000000 }); - - await USDT.approve(stableSwapModule.address, MaxUint256, { gasLimit: 1000000 }); - await fathomStablecoin.approve(stableSwapModule.address, MaxUint256, { gasLimit: 1000000 }); - await USDT.mint(DeployerAddress, TO_MINT, { gasLimit: 1000000 }); - await fathomStablecoin.mint(DeployerAddress, TO_MINT, { gasLimit: 1000000 }); - - return { - USDT, - stableSwapModule, - fathomStablecoin, - stableswapMultipleSwapsMock, - stableSwapModuleWrapper, - }; -}; - -describe("StableSwapModule", () => { - // Contracts - let USDT; - let stableSwapModule; - let fathomStablecoin; - let stableSwapModuleWrapper; - let stableswapMultipleSwapsMock; - - before(async () => { - await snapshot.revertToSnapshot(); - }); - - beforeEach(async () => { - ({ USDT, stableSwapModule, fathomStablecoin, stableswapMultipleSwapsMock, stableSwapModuleWrapper } = await loadFixture(setup)); - }); - - describe("#swapTokenToStablecoin", async () => { - context("swap USDT to FXD", async () => { - it("should success", async () => { - const beforeBalanceOfStablecoin = await fathomStablecoin.balanceOf(DeployerAddress); - const beforeBalanceOfUSDT = await USDT.balanceOf(DeployerAddress); - const FIVE_HUNDRED_THOUSAND_SIX_DECIMALS = WeiPerSixDecimals.mul(500000); - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, FIVE_HUNDRED_THOUSAND_SIX_DECIMALS, { gasLimit: 1000000 }); - const afterBalanceOfStablecoin = await fathomStablecoin.balanceOf(DeployerAddress); - const afterBalanceOfUSDT = await USDT.balanceOf(DeployerAddress); - - // 500000 -> from swap, -ve 500 -> from fee. Total balance = 500000-500 = 499500 - expect(afterBalanceOfStablecoin.sub(beforeBalanceOfStablecoin)).to.be.equal(ethers.utils.parseEther("499500")); - //-ve 500000 -> from swap. Total Balance = 500000 - expect(beforeBalanceOfUSDT.sub(afterBalanceOfUSDT)).to.be.equal(FIVE_HUNDRED_THOUSAND_SIX_DECIMALS); - }); - }); - - context("swap USDT to FXD", async () => { - it("should success", async () => { - const beforeBalanceOfStablecoin = await fathomStablecoin.balanceOf(DeployerAddress); - const beforeBalanceOfUSDT = await USDT.balanceOf(DeployerAddress); - const ONE_MILLION_SIX_DECIMALS = WeiPerSixDecimals.mul(1000000); - - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_MILLION_SIX_DECIMALS, { gasLimit: 1000000 }); - const afterBalanceOfStablecoin = await fathomStablecoin.balanceOf(DeployerAddress); - const afterBalanceOfUSDT = await USDT.balanceOf(DeployerAddress); - - // 1000000 -> from swap, -ve 500-> from fee. Total balance = 1000000 - 1000 = 999000 - expect(afterBalanceOfStablecoin.sub(beforeBalanceOfStablecoin)).to.be.equal(ethers.utils.parseEther("999000")); - // -ve 1000000 -> from swap. Total Balance = 1000000 - expect(beforeBalanceOfUSDT.sub(afterBalanceOfUSDT)).to.be.equal(ONE_MILLION_SIX_DECIMALS); - }); - }); - }); - - describe("#swapStablecoinToToken", async () => { - context("collateral not enough", async () => { - it("should SWAP", async () => { - const beforeBalanceOfStablecoin = await fathomStablecoin.balanceOf(DeployerAddress); - const beforeBalanceOfUSDT = await USDT.balanceOf(DeployerAddress); - - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ethers.utils.parseEther("1000000"), { gasLimit: 1000000 }); - const afterBalanceOfStablecoin = await fathomStablecoin.balanceOf(DeployerAddress); - const afterBalanceOfUSDT = await USDT.balanceOf(DeployerAddress); - expect(beforeBalanceOfStablecoin.sub(afterBalanceOfStablecoin)).to.be.equal(ethers.utils.parseEther("1000000")); - // 1000000 -> from swap, -ve 500-> from fee. Total balance = 1000000 - 1000 = 999000 - expect(afterBalanceOfUSDT.sub(beforeBalanceOfUSDT)).to.be.equal(WeiPerSixDecimals.mul(999000)); - }); - }); - - context("swap FXD to USDT", async () => { - it("should success", async () => { - // Mint 1000 USDT to deployer - - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, WeiPerSixDecimals.mul(1000), { gasLimit: 1000000 }); - // Swap 998 FXD to USDT - await fathomStablecoin.approve(stableSwapModule.address, MaxUint256, { gasLimit: 1000000 }); - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ethers.utils.parseEther("998"), { gasLimit: 1000000 }); - }); - }); - }); - - describe("#addToWhitelist", async () => { - context("add to whitelist and check it should swap", async () => { - it("should swapStablecoinToToken", async () => { - const whitelistAccount = accounts[2]; - await fathomStablecoin.approve(stableSwapModule.address, MaxUint256, { from: whitelistAccount, gasLimit: 1000000 }); - await fathomStablecoin.mint(whitelistAccount, TO_MINT, { gasLimit: 1000000 }); - await stableSwapModule.addToWhitelist(whitelistAccount); - const beforeBalanceOfStablecoin = await fathomStablecoin.balanceOf(whitelistAccount); - const beforeBalanceOfUSDT = await USDT.balanceOf(whitelistAccount); - - await stableSwapModule.swapStablecoinToToken(whitelistAccount, ethers.utils.parseEther("1000000"), { - from: whitelistAccount, - gasLimit: 1000000, - }); - const afterBalanceOfStablecoin = await fathomStablecoin.balanceOf(whitelistAccount); - const afterBalanceOfUSDT = await USDT.balanceOf(whitelistAccount); - expect(beforeBalanceOfStablecoin.sub(afterBalanceOfStablecoin)).to.be.equal(ethers.utils.parseEther("1000000")); - // 1000000 -> from swap, -ve 500-> from fee. Total balance = 1000000 - 1000 = 999000 - expect(afterBalanceOfUSDT.sub(beforeBalanceOfUSDT)).to.be.equal(WeiPerSixDecimals.mul(999000)); - }); - }); - - context("add to whitelist and check it should swap", async () => { - it("should swapTokenToStablecoin", async () => { - const whitelistAccount = accounts[2]; - await USDT.approve(stableSwapModule.address, MaxUint256, { from: whitelistAccount, gasLimit: 1000000 }); - await USDT.mint(whitelistAccount, TO_MINT, { gasLimit: 1000000 }); - await fathomStablecoin.mint(whitelistAccount, TO_MINT, { gasLimit: 1000000 }); - await stableSwapModule.addToWhitelist(whitelistAccount); - await stableSwapModule.swapTokenToStablecoin(whitelistAccount, WeiPerSixDecimals.mul(1000000), { from: whitelistAccount, gasLimit: 1000000 }); - }); - }); - }); - - describe("#removeFromWhitelist", async () => { - context("add to whitelist and check it should swap and again remove from whitelist and check for revert", async () => { - it("should swapStablecoinToToken and revert", async () => { - const whitelistAccount = accounts[2]; - await fathomStablecoin.approve(stableSwapModule.address, MaxUint256, { from: whitelistAccount, gasLimit: 1000000 }); - await fathomStablecoin.mint(whitelistAccount, TO_MINT, { gasLimit: 1000000 }); - await stableSwapModule.addToWhitelist(whitelistAccount); - await stableSwapModule.swapStablecoinToToken(whitelistAccount, ethers.utils.parseEther("1000000"), { - from: whitelistAccount, - gasLimit: 1000000, - }); - await stableSwapModule.removeFromWhitelist(whitelistAccount); - await expect( - stableSwapModule.swapStablecoinToToken(whitelistAccount, ethers.utils.parseEther("1000000"), { from: whitelistAccount, gasLimit: 1000000 }) - ).to.be.revertedWith("user-not-whitelisted"); - }); - }); - - context("add to whitelist and check it should swap and again remove from whitelist and check for revert", async () => { - it("should swapTokenToStablecoin and revert", async () => { - const whitelistAccount = accounts[2]; - await USDT.approve(stableSwapModule.address, MaxUint256, { from: whitelistAccount, gasLimit: 1000000 }); - await USDT.mint(whitelistAccount, TO_MINT, { gasLimit: 1000000 }); - await fathomStablecoin.mint(whitelistAccount, TO_MINT, { gasLimit: 1000000 }); - await stableSwapModule.addToWhitelist(whitelistAccount); - await stableSwapModule.swapTokenToStablecoin(whitelistAccount, WeiPerSixDecimals.mul(1000000), { from: whitelistAccount, gasLimit: 1000000 }); - await stableSwapModule.removeFromWhitelist(whitelistAccount); - await expect( - stableSwapModule.swapTokenToStablecoin(whitelistAccount, WeiPerSixDecimals.mul(1000000), { from: whitelistAccount, gasLimit: 1000000 }) - ).to.be.revertedWith("user-not-whitelisted"); - }); - }); - }); - - describe("#dailyLimitCheck", async () => { - context("check for daily limit", async () => { - it("Should swap tokens and revert when dailyswap limit is reached", async () => { - //first swap which takes all the allowance - await stableSwapModule.setDecentralizedStatesStatus(true, { gasLimit: 8000000 }); - console.log("Swapping twenty times to check for DailyLimit Cross"); - let numberOfSwaps = 0; - for (let i = 0; i < 10; i++) { - console.log("Swapping Token to Stablecoin - No...........", i + 1); - //div by 1000 so that single swap limit is not reached - await stableSwapModule.swapTokenToStablecoin( - DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)), - { gasLimit: 1000000 } - ); - //increase block time so that a block is mined before swapping - await TimeHelpers.increase(1); - numberOfSwaps++; - } - - for (let i = 0; i < 10; i++) { - console.log("Swapping Stablecion to Token - No...........", i + 1); - await stableSwapModule.swapStablecoinToToken( - DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)), - { gasLimit: 1000000 } - ); - //increase block time so that a block is mined before swapping - await TimeHelpers.increase(1); - numberOfSwaps++; - } - //revert because it exceed allowance - - await expect( - stableSwapModule.swapTokenToStablecoin( - DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)), - { gasLimit: 1000000 } - ) - ).to.be.revertedWith("_updateAndCheckDailyLimit/daily-limit-exceeded"); - await TimeHelpers.increase(1); - await expect( - stableSwapModule.swapStablecoinToToken( - DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)), - { gasLimit: 1000000 } - ) - ).to.be.revertedWith("_updateAndCheckDailyLimit/daily-limit-exceeded"); - await TimeHelpers.increase(1); - const ONE_DAY = 86400; - await TimeHelpers.increase(ONE_DAY + 20); - //again swap after increasing timestamp - //should succeed - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT), { - gasLimit: 1000000, - }); - await stableSwapModule.initializeFeesAfterUpgrade({ gasLimit: 8000000 }); - await expect(stableSwapModule.initializeFeesAfterUpgrade({ gasLimit: 8000000 })).to.be.revertedWith("StableSwapModule/already-initialized"); - }); - }); - - context("check for daily limit - depositToken", async () => { - it("Should update dailyLimit on depositing more token", async () => { - await TimeHelpers.increase(1); - await stableSwapModule.setDecentralizedStatesStatus(true, { gasLimit: 800000 }); - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS, { gasLimit: 1000000 }); - await TimeHelpers.increase(1); - await stableSwapModuleWrapper.depositTokens(TO_DEPOSIT, { gasLimit: 1000000 }); - //Why GreaterThanOrEqual? Because there is one swap already done which incurs fee so total pool has increased - await TimeHelpers.increase(1); - const remainingDailySwapAmount = await stableSwapModule.remainingDailySwapAmount(); - expect(remainingDailySwapAmount).to.be.gte( - FOURTY_PERCENT_OF_TO_DEPOSIT.sub(FOURTY_PERCENT_OF_TO_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)) - ); - }); - }); - - context("check for daily limit - setDailySwapLimitNumerator", async () => { - it("Should update dailyLimit on depositing more token", async () => { - await stableSwapModule.setDecentralizedStatesStatus(true, { gasLimit: 8000000 }); - await stableSwapModuleWrapper.depositTokens(TO_DEPOSIT, { gasLimit: 1000000 }); - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS, { gasLimit: 1000000 }); - await stableSwapModule.setDailySwapLimitNumerator(3000, { gasLimit: 8000000 }); - //Why GreaterThanOrEqual? Because there is one swap already done which incurs fee so total pool has increased - const remainingDailySwapAmount = await stableSwapModule.remainingDailySwapAmount(); - expect(remainingDailySwapAmount).to.be.gte(THIRTY_PERCENT_OF_TO_DEPOSIT); - }); - }); - }); - - describe("#singleSwapLimitCheck", async () => { - context("check for daily limit", async () => { - it("Should revert when SingleSwap Limit is reached", async () => { - //first swap which takes all the allowance - await stableSwapModule.setDecentralizedStatesStatus(true, { gasLimit: 8000000 }); - await expect( - stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT.add(1), { gasLimit: 1000000 }) - ).to.be.revertedWith("_checkSingleSwapLimit/single-swap-exceeds-limit"); - }); - }); - }); - - describe("#singleBlockLimitCheck", async () => { - context("check for block limit", async () => { - it("Should revert when number of swaps per block limit is reached", async () => { - await stableSwapModule.setDecentralizedStatesStatus(true, { gasLimit: 8000000 }); - - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT, { gasLimit: 1000000 }); - //this reverts because one user can swap only once in two blocks and we have already done one swap - await expect( - stableSwapModule.swapTokenToStablecoin( - DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)), - { gasLimit: 1000000 } - ) - ).to.be.revertedWith("_updateAndCheckNumberOfSwapsInBlocksPerLimit/swap-limit-exceeded"); - }); - }); - }); - - describe("#checkForDifferentBlockLimitsSet", async () => { - context("check for block limit", async () => { - it("Should revert when SingleSwap Limit is reached", async () => { - //first swap which takes all the allowance - await stableSwapModule.setDecentralizedStatesStatus(true, { gasLimit: 8000000 }); - const newNumberOfSwapsLimitPerUser = 2; - const newBlocksPerLimit = 3; - await stableSwapModule.setNumberOfSwapsLimitPerUser(newNumberOfSwapsLimitPerUser, { gasLimit: 1000000 }); - await stableSwapModule.setBlocksPerLimit(newBlocksPerLimit, { gasLimit: 1000000 }); - - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT, { gasLimit: 1000000 }); - - await stableSwapModule.swapStablecoinToToken( - DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)), - { gasLimit: 1000000 } - ); - - await expect( - stableSwapModule.swapTokenToStablecoin( - DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)), - { gasLimit: 1000000 } - ) - ).to.be.revertedWith("_updateAndCheckNumberOfSwapsInBlocksPerLimit/swap-limit-exceeded"); - }); - }); - context("check for block limit", async () => { - it("Should be successful and not reach limit - setting 3 swaps per 3 blocks", async () => { - //first swap which takes all the allowance - await stableSwapModule.setDecentralizedStatesStatus(true, { gasLimit: 8000000 }); - const newNumberOfSwapsLimitPerUser = 3; - const newBlocksPerLimit = 3; - await stableSwapModule.setNumberOfSwapsLimitPerUser(newNumberOfSwapsLimitPerUser, { gasLimit: 1000000 }); - await stableSwapModule.setBlocksPerLimit(newBlocksPerLimit, { gasLimit: 1000000 }); - - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT, { gasLimit: 1000000 }); - - await stableSwapModule.swapStablecoinToToken( - DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)), - { gasLimit: 1000000 } - ); - - await stableSwapModule.swapStablecoinToToken( - DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)), - { gasLimit: 1000000 } - ); - - await stableSwapModule.swapStablecoinToToken( - DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)), - { gasLimit: 1000000 } - ); - }); - }); - context("check for block limit", async () => { - it("Should revert for extra swap in the limit and then again be sucessful after enough block passes", async () => { - //first swap which takes all the allowance - await stableSwapModule.setDecentralizedStatesStatus(true, { gasLimit: 8000000 }); - const newNumberOfSwapsLimitPerUser = 3; - const newBlocksPerLimit = 10; - const blockNumbersToReachForNextSwap = 12; - await stableSwapModule.setNumberOfSwapsLimitPerUser(newNumberOfSwapsLimitPerUser, { gasLimit: 1000000 }); - await stableSwapModule.setBlocksPerLimit(newBlocksPerLimit, { gasLimit: 1000000 }); - - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT, { gasLimit: 1000000 }); - await stableSwapModule.swapStablecoinToToken( - DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)), - { gasLimit: 1000000 } - ); - await stableSwapModule.swapStablecoinToToken( - DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)), - { gasLimit: 1000000 } - ); - //This should fail because its 4th swap within 500 block window - await expect( - stableSwapModule.swapTokenToStablecoin( - DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)), - { gasLimit: 1000000 } - ) - ).to.be.revertedWith("_updateAndCheckNumberOfSwapsInBlocksPerLimit/swap-limit-exceeded"); - for (let i = 0; i < blockNumbersToReachForNextSwap; i++) { - await TimeHelpers.advanceBlock(); - } - - await stableSwapModule.swapStablecoinToToken( - DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)), - { gasLimit: 1000000 } - ); - }); - }); - }); - - describe("#stableSwapEmergencyWithdraw", async () => { - context("emergency withdraw", async () => { - it("Should emergency withdraw when paused", async () => { - await expect(stableSwapModule.emergencyWithdraw(accounts[5])).to.be.reverted; - await stableSwapModule.pause(); - await stableSwapModule.emergencyWithdraw(accounts[5]); - const balanceOfStablecoin = await fathomStablecoin.balanceOf(accounts[5]); - const balanceOfToken = await USDT.balanceOf(accounts[5]); - expect(balanceOfStablecoin).to.be.equal(ethers.utils.parseEther("10000000")); - expect(balanceOfToken).to.be.equal(WeiPerSixDecimals.mul(10000000)); - }); - }); - }); - - describe("#StableswapMultipleSwapsMock", async () => { - context("twoStablecoinToTokenSwapAtSameBlock- swap tokens in same block", async () => { - it("should revert if we swap tokens in same block", async () => { - await stableSwapModule.setDecentralizedStatesStatus(true, { gasLimit: 8000000 }); - await fathomStablecoin.approve(stableswapMultipleSwapsMock.address, MaxUint256, { gasLimit: 8000000 }); - await expect( - stableswapMultipleSwapsMock.twoStablecoinToTokenSwapAtSameBlock( - stableSwapModule.address, - fathomStablecoin.address, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(5000)), - { gasLimit: 8000000 } - ) - ).to.be.revertedWith("_updateAndCheckNumberOfSwapsInBlocksPerLimit/swap-limit-exceeded"); - }); - }); - - context("twoTokenToStablecoinSwapAtSameBlock- swap tokens in same block", async () => { - it("should revert if we swap tokens in same block", async () => { - await stableSwapModule.setDecentralizedStatesStatus(true, { gasLimit: 8000000 }); - await USDT.approve(stableswapMultipleSwapsMock.address, MaxUint256, { gasLimit: 8000000 }); - await expect( - stableswapMultipleSwapsMock.twoTokenToStablecoinSwapAtSameBlock( - stableSwapModule.address, - USDT.address, - ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.div(5000)), - { gasLimit: 8000000 } - ) - ).to.be.revertedWith("_updateAndCheckNumberOfSwapsInBlocksPerLimit/swap-limit-exceeded"); - }); - }); - context("twoStablecoinToTokenSwapAtSameBlock- swap tokens in same block", async () => { - it("Should be successful for two swaps in same block", async () => { - await stableSwapModule.setDecentralizedStatesStatus(true, { gasLimit: 8000000 }); - const newNumberOfSwapsLimitPerUser = 3; - const newBlocksPerLimit = 1; - await stableSwapModule.setNumberOfSwapsLimitPerUser(newNumberOfSwapsLimitPerUser, { gasLimit: 1000000 }); - await stableSwapModule.setBlocksPerLimit(newBlocksPerLimit, { gasLimit: 1000000 }); - - await fathomStablecoin.approve(stableswapMultipleSwapsMock.address, MaxUint256, { gasLimit: 8000000 }); - await stableswapMultipleSwapsMock.twoStablecoinToTokenSwapAtSameBlock( - stableSwapModule.address, - fathomStablecoin.address, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(4000)), - { gasLimit: 8000000 } - ); - }); - }); - - context("twoTokenToStablecoinSwapAtSameBlock- swap tokens in same block", async () => { - it("Should be successful for two swaps in same block", async () => { - await stableSwapModule.setDecentralizedStatesStatus(true, { gasLimit: 8000000 }); - const newNumberOfSwapsLimitPerUser = 3; - const newBlocksPerLimit = 1; - await stableSwapModule.setNumberOfSwapsLimitPerUser(newNumberOfSwapsLimitPerUser, { gasLimit: 1000000 }); - await stableSwapModule.setBlocksPerLimit(newBlocksPerLimit, { gasLimit: 1000000 }); - - await USDT.approve(stableswapMultipleSwapsMock.address, MaxUint256, { gasLimit: 8000000 }); - await stableswapMultipleSwapsMock.twoTokenToStablecoinSwapAtSameBlock( - stableSwapModule.address, - USDT.address, - ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.div(4000)), - { gasLimit: 8000000 } - ); - }); - }); - }); - - describe("#stableswapNotWhitelistedUserSwaps", async () => { - context("not whitelisted-swapTokenToStablecoin", () => { - it("should revert - fail if the decentralized state is not activated and sender is not whitelisted", async () => { - await expect(stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT, { from: accounts[2] })).to.be.revertedWith( - "user-not-whitelisted" - ); - }); - }); - context("not whitelisted-swapStablecoinToToken", () => { - it("should revert - fail if the decentralized state is not activated and sender is not whitelisted", async () => { - await expect(stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT, { from: accounts[2] })).to.be.revertedWith( - "user-not-whitelisted" - ); - }); - }); - }); - - describe("#getIsUsersWhitelisted", async () => { - context("is whitelisted should be true", () => { - it("should return true", async () => { - const isUserWhitelisted = await stableSwapModule.isUserWhitelisted(DeployerAddress); - expect(isUserWhitelisted).to.be.equal(true); - }); - }); - - context("is whitelisted should be true", () => { - it("should return false", async () => { - const isUserWhitelisted = await stableSwapModule.isUserWhitelisted(accounts[2]); - expect(isUserWhitelisted).to.be.equal(false); - }); - }); - }); - - describe("#totalValueDeposited", async () => { - context("update total value deposited after upgrade", async () => { - it("totalValueDeposited: should be same before and after upgrade", async () => { - const totalValueDepositedBeforeUpdate = await stableSwapModule.totalValueDeposited(); - await stableSwapModule.udpateTotalValueDeposited(); - const totalValueDepositedAfterUpdate = await stableSwapModule.totalValueDeposited(); - expect(totalValueDepositedAfterUpdate).to.be.equal(totalValueDepositedBeforeUpdate); - }); - }); - }); - - describe("#unitTests", async () => { - context("exceed single swap limit", () => { - it("should revert after setting decentralized state - single swap limit - swapStablecoinToToken", async () => { - await stableSwapModule.setDecentralizedStatesStatus(true, { gasLimit: 8000000 }); - await expect( - stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT.add(1), { gasLimit: 1000000 }) - ).to.be.revertedWith("_checkSingleSwapLimit/single-swap-exceeds-limit"); - }); - }); - - context("exceed single swap limit", () => { - it("should revert after setting decentralized state - single swap limit - swapTokenToStablecoin", async () => { - await stableSwapModule.setDecentralizedStatesStatus(true, { gasLimit: 8000000 }); - await expect( - stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.add(1), { gasLimit: 1000000 }) - ).to.be.revertedWith("_checkSingleSwapLimit/single-swap-exceeds-limit"); - }); - }); - }); -}); diff --git a/tasks/fathom-solidity-sdk.js b/tasks/fathom-solidity-sdk.js index e6410d12..a12ed2de 100644 --- a/tasks/fathom-solidity-sdk.js +++ b/tasks/fathom-solidity-sdk.js @@ -12,31 +12,30 @@ try { addresses = {}; } -task("fathom-solidity-sdk", "Fathom Solidity SDK") - .setAction(async () => { - const FathomProxyWalletOwner = await ethers.getContractFactory("FathomProxyWalletOwner"); +task("fathom-solidity-sdk", "Fathom Solidity SDK").setAction(async () => { + const FathomProxyWalletOwner = await ethers.getContractFactory("FathomProxyWalletOwner"); - const proxyWalletRegistry = addresses.proxyWalletRegistry; - const bookKeeper = addresses.bookKeeper; - const collateralPoolConfig = addresses.collateralPoolConfig; - const fathomStablecoin = addresses.fathomStablecoin; - const positionManager = addresses.positionManager; - const stabilityFeeCollector = addresses.stabilityFeeCollector; - const collateralTokenAdapter = addresses.collateralTokenAdapter; - const stablecoinAdapter = addresses.stablecoinAdapter; + const proxyWalletRegistry = addresses.proxyWalletRegistry; + const bookKeeper = addresses.bookKeeper; + const collateralPoolConfig = addresses.collateralPoolConfig; + const fathomStablecoin = addresses.fathomStablecoin; + const positionManager = addresses.positionManager; + const stabilityFeeCollector = addresses.stabilityFeeCollector; + const collateralTokenAdapter = addresses.collateralTokenAdapter; + const stablecoinAdapter = addresses.stablecoinAdapter; - proxyWalletOwner = await FathomProxyWalletOwner.deploy( - proxyWalletRegistry, - bookKeeper, - collateralPoolConfig, - fathomStablecoin, - positionManager, - stabilityFeeCollector, - collateralTokenAdapter, - stablecoinAdapter, - pools.XDC - ); - await proxyWalletOwner.deployed(); - }); - -module.exports = {}; \ No newline at end of file + proxyWalletOwner = await FathomProxyWalletOwner.deploy( + proxyWalletRegistry, + bookKeeper, + collateralPoolConfig, + fathomStablecoin, + positionManager, + stabilityFeeCollector, + collateralTokenAdapter, + stablecoinAdapter, + pools.XDC + ); + await proxyWalletOwner.deployed(); +}); + +module.exports = {}; diff --git a/tasks/price-feed.js b/tasks/price-feed.js index b04061ea..e426dc32 100644 --- a/tasks/price-feed.js +++ b/tasks/price-feed.js @@ -9,7 +9,7 @@ task("price-feed", "Price Feed") } const proxyFactory = await ethers.getContractAt("FathomProxyFactory", taskArgs.proxyFactoryAddress); - + const delayFathomOraclePriceFeed = await getProxy(proxyFactory, "DelayFathomOraclePriceFeed"); const dexPriceOracle = await getProxy(proxyFactory, "DexPriceOracle"); // const centralizedOraclePriceFeed = await getProxy(proxyFactory, "CentralizedOraclePriceFeed"); @@ -22,5 +22,5 @@ task("price-feed", "Price Feed") await slidingWindowDexOracle.initialize(addresses.DEXFactory, 1800, 15); await delayFathomOraclePriceFeed.initialize(dexPriceOracle.address, addresses.WXDC, addresses.USD, accessControlConfig.address, pools.XDC); }); - -module.exports = {}; \ No newline at end of file + +module.exports = {}; diff --git a/test/integration/AdminControls.test.js b/test/integration/AdminControls.test.js index a653c2fa..47bc3fe6 100644 --- a/test/integration/AdminControls.test.js +++ b/test/integration/AdminControls.test.js @@ -64,4 +64,4 @@ describe("AdminControls", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/integration/CollateralTokenAdapter.test.js b/test/integration/CollateralTokenAdapter.test.js index fdcfc81f..666a8d32 100644 --- a/test/integration/CollateralTokenAdapter.test.js +++ b/test/integration/CollateralTokenAdapter.test.js @@ -482,4 +482,4 @@ describe("CollateralTokenAdapter", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/integration/FathomProxyActions.test.js b/test/integration/FathomProxyActions.test.js index 4dbb65fb..eb7bc870 100644 --- a/test/integration/FathomProxyActions.test.js +++ b/test/integration/FathomProxyActions.test.js @@ -187,4 +187,4 @@ describe("Position Closure without collateral withdrawal", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/integration/FlashMintModule.test.js b/test/integration/FlashMintModule.test.js index 094b0ff7..d61ce159 100644 --- a/test/integration/FlashMintModule.test.js +++ b/test/integration/FlashMintModule.test.js @@ -155,4 +155,4 @@ describe("FlastMintModule", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/integration/LiquidationEngine.test.js b/test/integration/LiquidationEngine.test.js index 2ee40df8..48f92021 100644 --- a/test/integration/LiquidationEngine.test.js +++ b/test/integration/LiquidationEngine.test.js @@ -563,13 +563,7 @@ describe("LiquidationEngine", () => { const lockedCollateralAmount = parseEther("10"); const drawStablecoinAmount = parseEther("2000"); - await PositionHelper.openXDCPositionAndDraw( - aliceProxyWallet, - AliceAddress, - COLLATERAL_POOL_ID, - lockedCollateralAmount, - drawStablecoinAmount - ); + await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, COLLATERAL_POOL_ID, lockedCollateralAmount, drawStablecoinAmount); // Set stability fee rate to 0.5% APR await collateralPoolConfig.setStabilityFeeRate(COLLATERAL_POOL_ID, BigNumber.from("1000000000158153903837946258")); @@ -664,20 +658,8 @@ describe("LiquidationEngine", () => { const lockedCollateralAmount = parseEther(testParam.collateralAmount); const drawStablecoinAmount = parseEther(testParam.drawStablecoinAmount); - await PositionHelper.openXDCPositionAndDraw( - aliceProxyWallet, - AliceAddress, - COLLATERAL_POOL_ID, - lockedCollateralAmount, - drawStablecoinAmount - ); - await PositionHelper.openXDCPositionAndDraw( - aliceProxyWallet, - AliceAddress, - COLLATERAL_POOL_ID, - lockedCollateralAmount, - drawStablecoinAmount - ); + await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, COLLATERAL_POOL_ID, lockedCollateralAmount, drawStablecoinAmount); + await PositionHelper.openXDCPositionAndDraw(aliceProxyWallet, AliceAddress, COLLATERAL_POOL_ID, lockedCollateralAmount, drawStablecoinAmount); const alicePositionAddress1 = await positionManager.positions(1); const alicePositionAddress2 = await positionManager.positions(2); @@ -739,4 +721,4 @@ describe("LiquidationEngine", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/integration/PositionPermissions.test.js b/test/integration/PositionPermissions.test.js index 54bcd61c..ba3040c6 100644 --- a/test/integration/PositionPermissions.test.js +++ b/test/integration/PositionPermissions.test.js @@ -536,9 +536,7 @@ describe("PositionPermissions", () => { const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal( - WeiPerWad.mul(2) - ); + expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), @@ -783,9 +781,7 @@ describe("PositionPermissions", () => { const alicePositionAddress = await positionManager.positions(1); const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal( - WeiPerWad.mul(2) - ); + expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), @@ -813,9 +809,7 @@ describe("PositionPermissions", () => { 0 ); const aliceAdjustPosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC").to.be.equal( - WeiPerWad - ); + expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC").to.be.equal(WeiPerWad); expect(aliceAdjustPosition.debtShare, "debtShare should be 1 FXD, because Alice doesn't draw more").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), @@ -856,9 +850,7 @@ describe("PositionPermissions", () => { const alicePositionAddress = await positionManager.positions(1); const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal( - WeiPerWad.mul(2) - ); + expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), @@ -887,9 +879,7 @@ describe("PositionPermissions", () => { collateralTokenAdapter.address ); const aliceAdjustPosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC").to.be.equal( - WeiPerWad - ); + expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC").to.be.equal(WeiPerWad); expect(aliceAdjustPosition.debtShare, "debtShare should be 1 FXD, because Alice didn't draw more").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), @@ -936,9 +926,7 @@ describe("PositionPermissions", () => { const alicePositionAddress = await positionManager.positions(1); const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal( - WeiPerWad.mul(2) - ); + expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), @@ -1147,9 +1135,7 @@ describe("PositionPermissions", () => { const bobPositionAddress = await positionManager.positions(2); const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); const bobPosition = await bookKeeper.positions(pools.XDC, bobPositionAddress); - expect(bobPosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Bob locked 2 WXDC").to.be.equal( - WeiPerWad.mul(2) - ); + expect(bobPosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Bob locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); expect(bobPosition.debtShare, "debtShare should be 1 FXD, because Bob drew 1 FXD").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), @@ -1165,9 +1151,7 @@ describe("PositionPermissions", () => { 0 ); const bobAdjustPosition = await bookKeeper.positions(pools.XDC, bobPositionAddress); - expect(bobAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Bob unlocked 1 WXDC").to.be.equal( - WeiPerWad - ); + expect(bobAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Bob unlocked 1 WXDC").to.be.equal(WeiPerWad); expect(bobAdjustPosition.debtShare, "debtShare should be 1 FXD, because Bob doesn't draw more").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.XDC, bobPositionAddress), @@ -1217,9 +1201,7 @@ describe("PositionPermissions", () => { const bobPositionAddress = await positionManager.positions(2); const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); const bobPosition = await bookKeeper.positions(pools.GLD, bobPositionAddress); - expect(bobPosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Bob locked 2 WXDC").to.be.equal( - WeiPerWad.mul(2) - ); + expect(bobPosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Bob locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); expect(bobPosition.debtShare, "debtShare should be 1 FXD, because Bob drew 1 FXD").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.GLD, bobPositionAddress), @@ -1236,9 +1218,7 @@ describe("PositionPermissions", () => { collateralTokenAdapter2.address ); const bobAdjustPosition = await bookKeeper.positions(pools.GLD, bobPositionAddress); - expect(bobAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Bob unlocked 1 WXDC").to.be.equal( - WeiPerWad - ); + expect(bobAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Bob unlocked 1 WXDC").to.be.equal(WeiPerWad); expect(bobAdjustPosition.debtShare, "debtShare should be 1 FXD, because Bob didn't draw more").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.GLD, bobPositionAddress), @@ -1282,9 +1262,7 @@ describe("PositionPermissions", () => { const alicePositionAddress = await positionManager.positions(1); const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal( - WeiPerWad.mul(2) - ); + expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), @@ -1389,9 +1367,7 @@ describe("PositionPermissions", () => { const alicePositionAddress = await positionManager.positions(1); const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal( - WeiPerWad.mul(2) - ); + expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), @@ -1419,9 +1395,7 @@ describe("PositionPermissions", () => { 0 ); const aliceAdjustPosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC").to.be.equal( - WeiPerWad - ); + expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC").to.be.equal(WeiPerWad); expect(aliceAdjustPosition.debtShare, "debtShare should be 1 FXD, because Alice didn't draw more").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), @@ -1465,9 +1439,7 @@ describe("PositionPermissions", () => { const alicePositionAddress = await positionManager.positions(1); const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal( - WeiPerWad.mul(2) - ); + expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), @@ -1479,9 +1451,7 @@ describe("PositionPermissions", () => { const bobPositionAddress = await positionManager.positions(2); const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); const bobPosition = await bookKeeper.positions(pools.GLD, bobPositionAddress); - expect(bobPosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Bob locked 2 WXDC").to.be.equal( - WeiPerWad.mul(2) - ); + expect(bobPosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Bob locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); expect(bobPosition.debtShare, "debtShare should be 1 FXD, because Bob drew 1 FXD").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.GLD, bobPositionAddress), @@ -1498,9 +1468,7 @@ describe("PositionPermissions", () => { collateralTokenAdapter.address ); const aliceAdjustPosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC").to.be.equal( - WeiPerWad - ); + expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC").to.be.equal(WeiPerWad); expect(aliceAdjustPosition.debtShare, "debtShare should be 1 FXD, because Alice didn't draw more").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), @@ -1548,9 +1516,7 @@ describe("PositionPermissions", () => { const alicePositionAddress = await positionManager.positions(1); const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal( - WeiPerWad.mul(2) - ); + expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), @@ -1709,9 +1675,7 @@ describe("PositionPermissions", () => { const alicePositionAddress = await positionManager.positions(1); const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal( - WeiPerWad.mul(2) - ); + expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), @@ -1739,9 +1703,7 @@ describe("PositionPermissions", () => { 0 ); const aliceAdjustPosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC").to.be.equal( - WeiPerWad - ); + expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC").to.be.equal(WeiPerWad); expect(aliceAdjustPosition.debtShare, "debtShare should be 1 FXD, because Alice didn't draw more").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), @@ -1769,9 +1731,7 @@ describe("PositionPermissions", () => { const alicePositionAddress = await positionManager.positions(1); const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal( - WeiPerWad.mul(2) - ); + expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), @@ -1783,9 +1743,7 @@ describe("PositionPermissions", () => { const bobPositionAddress = await positionManager.positions(2); const bobFathomStablecoinBalance = await fathomStablecoin.balanceOf(BobAddress); const bobPosition = await bookKeeper.positions(pools.GLD, bobPositionAddress); - expect(bobPosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Bob locked 2 WXDC").to.be.equal( - WeiPerWad.mul(2) - ); + expect(bobPosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Bob locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); expect(bobPosition.debtShare, "debtShare should be 1 FXD, because Bob drew 1 FXD").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.GLD, bobPositionAddress), @@ -1802,9 +1760,7 @@ describe("PositionPermissions", () => { collateralTokenAdapter.address ); const aliceAdjustPosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC").to.be.equal( - WeiPerWad - ); + expect(aliceAdjustPosition.lockedCollateral, "lockedCollateral should be 1 WXDC, because Alice unlocked 1 WXDC").to.be.equal(WeiPerWad); expect(aliceAdjustPosition.debtShare, "debtShare should be 1 FXD, because Alice didn't draw more").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), @@ -1834,9 +1790,7 @@ describe("PositionPermissions", () => { const alicePositionAddress = await positionManager.positions(1); const fathomStablecoinBalance = await fathomStablecoin.balanceOf(AliceAddress); const alicePosition = await bookKeeper.positions(pools.XDC, alicePositionAddress); - expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal( - WeiPerWad.mul(2) - ); + expect(alicePosition.lockedCollateral, "lockedCollateral should be 2 WXDC, because Alice locked 2 WXDC").to.be.equal(WeiPerWad.mul(2)); expect(alicePosition.debtShare, "debtShare should be 1 FXD, because Alice drew 1 FXD").to.be.equal(WeiPerWad); expect( await bookKeeper.collateralToken(pools.XDC, alicePositionAddress), @@ -1998,4 +1952,4 @@ describe("PositionPermissions", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/integration/ProxyWallet.test.js b/test/integration/ProxyWallet.test.js index 768c97e8..d43c2c71 100644 --- a/test/integration/ProxyWallet.test.js +++ b/test/integration/ProxyWallet.test.js @@ -24,7 +24,7 @@ describe("ProxyWallet", () => { const proxyFactory = await ethers.getContractAt("FathomProxyFactory", ProxyFactory.address); proxyWalletRegistry = await getProxy(proxyFactory, "ProxyWalletRegistry"); - proxyWalletRegistry.setDecentralizedMode(true); + await proxyWalletRegistry.setDecentralizedMode(true); }); describe("#new user create a new proxy wallet", async () => { context("alice create a new proxy wallet", async () => { @@ -126,4 +126,4 @@ describe("ProxyWallet", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/integration/ShowStopper.test.js b/test/integration/ShowStopper.test.js index bffd611c..eeb2e772 100644 --- a/test/integration/ShowStopper.test.js +++ b/test/integration/ShowStopper.test.js @@ -464,4 +464,4 @@ describe("ShowStopper", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/integration/StabilityFeeCollector.test.js b/test/integration/StabilityFeeCollector.test.js index b95b7422..9a38b080 100644 --- a/test/integration/StabilityFeeCollector.test.js +++ b/test/integration/StabilityFeeCollector.test.js @@ -142,4 +142,4 @@ describe("Stability Fee", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/integration/StableSwapModule.test.js b/test/integration/StableSwapModule.test.js index 0a14d06f..7f713232 100644 --- a/test/integration/StableSwapModule.test.js +++ b/test/integration/StableSwapModule.test.js @@ -2,7 +2,6 @@ const { ethers } = require("hardhat"); const provider = ethers.provider; const { expect } = require("chai"); const { BigNumber } = ethers; -const TimeHelpers = require("../helper/time"); const { time } = require("@nomicfoundation/hardhat-network-helpers"); const { getProxy } = require("../../common/proxies"); @@ -46,23 +45,23 @@ describe("StableSwapModule", () => { const ProxyFactory = await deployments.get("FathomProxyFactory"); const proxyFactory = await ethers.getContractAt("FathomProxyFactory", ProxyFactory.address); - + const StableswapMultipleSwapsMock = await deployments.get("StableswapMultipleSwapsMock"); stableswapMultipleSwapsMock = await ethers.getContractAt("StableswapMultipleSwapsMock", StableswapMultipleSwapsMock.address); - + stableSwapModule = await getProxy(proxyFactory, "StableSwapModule"); fathomStablecoin = await getProxy(proxyFactory, "FathomStablecoin"); stableSwapModuleWrapper = await getProxy(proxyFactory, "StableSwapModuleWrapper"); const usdtAddr = await stableSwapModule.token(); USDT = await ethers.getContractAt("ERC20Mintable", usdtAddr); - + await USDT.approve(stableSwapModuleWrapper.address, ethers.constants.MaxUint256); await fathomStablecoin.approve(stableSwapModuleWrapper.address, ethers.constants.MaxUint256); await USDT.mint(DeployerAddress, TO_DEPOSIT); await fathomStablecoin.mint(DeployerAddress, TO_DEPOSIT); - + await stableSwapModuleWrapper.depositTokens(TO_DEPOSIT); await USDT.approve(stableSwapModule.address, ethers.constants.MaxUint256); @@ -143,7 +142,9 @@ describe("StableSwapModule", () => { const beforeBalanceOfStablecoin = await fathomStablecoin.balanceOf(whitelistAccount); const beforeBalanceOfUSDT = await USDT.balanceOf(whitelistAccount); - await stableSwapModule.connect(provider.getSigner(whitelistAccount)).swapStablecoinToToken(whitelistAccount, ethers.utils.parseEther("1000000")); + await stableSwapModule + .connect(provider.getSigner(whitelistAccount)) + .swapStablecoinToToken(whitelistAccount, ethers.utils.parseEther("1000000")); const afterBalanceOfStablecoin = await fathomStablecoin.balanceOf(whitelistAccount); const afterBalanceOfUSDT = await USDT.balanceOf(whitelistAccount); expect(beforeBalanceOfStablecoin.sub(afterBalanceOfStablecoin)).to.be.equal(ethers.utils.parseEther("1000000")); @@ -171,7 +172,9 @@ describe("StableSwapModule", () => { await fathomStablecoin.connect(provider.getSigner(whitelistAccount)).approve(stableSwapModule.address, ethers.constants.MaxUint256); await fathomStablecoin.mint(whitelistAccount, TO_MINT); await stableSwapModule.addToWhitelist(whitelistAccount); - await stableSwapModule.connect(provider.getSigner(whitelistAccount)).swapStablecoinToToken(whitelistAccount, ethers.utils.parseEther("1000000")); + await stableSwapModule + .connect(provider.getSigner(whitelistAccount)) + .swapStablecoinToToken(whitelistAccount, ethers.utils.parseEther("1000000")); await stableSwapModule.removeFromWhitelist(whitelistAccount); await expect( stableSwapModule.connect(provider.getSigner(whitelistAccount)).swapStablecoinToToken(whitelistAccount, ethers.utils.parseEther("1000000")) @@ -207,7 +210,8 @@ describe("StableSwapModule", () => { //div by 1000 so that single swap limit is not reached await stableSwapModule.swapTokenToStablecoin( DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT))); + ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)) + ); //increase block time so that a block is mined before swapping await time.increase(1); numberOfSwaps++; @@ -217,7 +221,8 @@ describe("StableSwapModule", () => { console.log("Swapping Stablecion to Token - No...........", i + 1); await stableSwapModule.swapStablecoinToToken( DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT))); + ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)) + ); //increase block time so that a block is mined before swapping await time.increase(1); numberOfSwaps++; @@ -227,13 +232,15 @@ describe("StableSwapModule", () => { await expect( stableSwapModule.swapTokenToStablecoin( DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT))) + ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)) + ) ).to.be.revertedWith("_updateAndCheckDailyLimit/daily-limit-exceeded"); await time.increase(1); await expect( stableSwapModule.swapStablecoinToToken( DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT))) + ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)) + ) ).to.be.revertedWith("_updateAndCheckDailyLimit/daily-limit-exceeded"); await time.increase(1); const ONE_DAY = 86400; @@ -280,9 +287,9 @@ describe("StableSwapModule", () => { it("Should revert when SingleSwap Limit is reached", async () => { //first swap which takes all the allowance await stableSwapModule.setDecentralizedStatesStatus(true); - await expect( - stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT.add(1)) - ).to.be.revertedWith("_checkSingleSwapLimit/single-swap-exceeds-limit"); + await expect(stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT.add(1))).to.be.revertedWith( + "_checkSingleSwapLimit/single-swap-exceeds-limit" + ); }); }); }); @@ -297,7 +304,8 @@ describe("StableSwapModule", () => { await expect( stableSwapModule.swapTokenToStablecoin( DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT))) + ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)) + ) ).to.be.revertedWith("_updateAndCheckNumberOfSwapsInBlocksPerLimit/swap-limit-exceeded"); }); }); @@ -317,12 +325,14 @@ describe("StableSwapModule", () => { await stableSwapModule.swapStablecoinToToken( DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT))); + ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)) + ); await expect( stableSwapModule.swapTokenToStablecoin( DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT))) + ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)) + ) ).to.be.revertedWith("_updateAndCheckNumberOfSwapsInBlocksPerLimit/swap-limit-exceeded"); }); }); @@ -339,15 +349,18 @@ describe("StableSwapModule", () => { await stableSwapModule.swapStablecoinToToken( DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT))); + ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)) + ); await stableSwapModule.swapStablecoinToToken( DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT))); + ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)) + ); await stableSwapModule.swapStablecoinToToken( DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT))); + ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)) + ); }); }); context("check for block limit", async () => { @@ -363,23 +376,27 @@ describe("StableSwapModule", () => { await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT); await stableSwapModule.swapStablecoinToToken( DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT))); + ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)) + ); await stableSwapModule.swapStablecoinToToken( DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT))); + ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)) + ); //This should fail because its 4th swap within 500 block window await expect( stableSwapModule.swapTokenToStablecoin( DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT))) + ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)) + ) ).to.be.revertedWith("_updateAndCheckNumberOfSwapsInBlocksPerLimit/swap-limit-exceeded"); for (let i = 0; i < blockNumbersToReachForNextSwap; i++) { - await TimeHelpers.advanceBlock(); + await hre.network.provider.send("hardhat_mine", ["0x01"]); } await stableSwapModule.swapStablecoinToToken( DeployerAddress, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT))); + ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(DIVIDER_TO_FIT_SINGLE_SWAP_LIMIT)) + ); }); }); }); @@ -407,7 +424,8 @@ describe("StableSwapModule", () => { stableswapMultipleSwapsMock.twoStablecoinToTokenSwapAtSameBlock( stableSwapModule.address, fathomStablecoin.address, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(5000))) + ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(5000)) + ) ).to.be.revertedWith("_updateAndCheckNumberOfSwapsInBlocksPerLimit/swap-limit-exceeded"); }); }); @@ -420,7 +438,8 @@ describe("StableSwapModule", () => { stableswapMultipleSwapsMock.twoTokenToStablecoinSwapAtSameBlock( stableSwapModule.address, USDT.address, - ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.div(5000))) + ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.div(5000)) + ) ).to.be.revertedWith("_updateAndCheckNumberOfSwapsInBlocksPerLimit/swap-limit-exceeded"); }); }); @@ -436,7 +455,8 @@ describe("StableSwapModule", () => { await stableswapMultipleSwapsMock.twoStablecoinToTokenSwapAtSameBlock( stableSwapModule.address, fathomStablecoin.address, - ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(4000))); + ONE_PERCENT_OF_TOTAL_DEPOSIT.sub(ONE_PERCENT_OF_TOTAL_DEPOSIT.div(4000)) + ); }); }); @@ -461,16 +481,16 @@ describe("StableSwapModule", () => { describe("#stableswapNotWhitelistedUserSwaps", async () => { context("not whitelisted-swapTokenToStablecoin", () => { it("should revert - fail if the decentralized state is not activated and sender is not whitelisted", async () => { - await expect(stableSwapModule.connect(provider.getSigner(accounts[2].address)).swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT)).to.be.revertedWith( - "user-not-whitelisted" - ); + await expect( + stableSwapModule.connect(provider.getSigner(accounts[2].address)).swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT) + ).to.be.revertedWith("user-not-whitelisted"); }); }); context("not whitelisted-swapStablecoinToToken", () => { it("should revert - fail if the decentralized state is not activated and sender is not whitelisted", async () => { - await expect(stableSwapModule.connect(provider.getSigner(accounts[2].address)).swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT)).to.be.revertedWith( - "user-not-whitelisted" - ); + await expect( + stableSwapModule.connect(provider.getSigner(accounts[2].address)).swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT) + ).to.be.revertedWith("user-not-whitelisted"); }); }); }); @@ -506,18 +526,18 @@ describe("StableSwapModule", () => { context("exceed single swap limit", () => { it("should revert after setting decentralized state - single swap limit - swapStablecoinToToken", async () => { await stableSwapModule.setDecentralizedStatesStatus(true); - await expect( - stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT.add(1)) - ).to.be.revertedWith("_checkSingleSwapLimit/single-swap-exceeds-limit"); + await expect(stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT.add(1))).to.be.revertedWith( + "_checkSingleSwapLimit/single-swap-exceeds-limit" + ); }); }); context("exceed single swap limit", () => { it("should revert after setting decentralized state - single swap limit - swapTokenToStablecoin", async () => { await stableSwapModule.setDecentralizedStatesStatus(true); - await expect( - stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.add(1)) - ).to.be.revertedWith("_checkSingleSwapLimit/single-swap-exceeds-limit"); + await expect(stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS.add(1))).to.be.revertedWith( + "_checkSingleSwapLimit/single-swap-exceeds-limit" + ); }); }); }); diff --git a/scripts/tests/integration/StableSwapModuleWrapper.test.js b/test/integration/StableSwapModuleWrapper.test.js similarity index 63% rename from scripts/tests/integration/StableSwapModuleWrapper.test.js rename to test/integration/StableSwapModuleWrapper.test.js index 23c05315..112cfd28 100644 --- a/scripts/tests/integration/StableSwapModuleWrapper.test.js +++ b/test/integration/StableSwapModuleWrapper.test.js @@ -1,16 +1,12 @@ -const chai = require("chai"); -const { BigNumber, ethers } = require("ethers"); -const { MaxUint256 } = require("@ethersproject/constants"); -const TimeHelpers = require("../helper/time"); +const { ethers } = require("hardhat"); +const provider = ethers.provider; +const { expect } = require("chai"); +const { BigNumber } = ethers; +const { MaxUint256 } = ethers.constants; +const { time } = require("@nomicfoundation/hardhat-network-helpers"); -const { solidity } = require("ethereum-waffle"); -chai.use(solidity); - -const { DeployerAddress, AliceAddress } = require("../helper/address"); -const { loadFixture } = require("../helper/fixtures"); const { getProxy } = require("../../common/proxies"); const { WeiPerWad } = require("../helper/unit"); -const { expect } = chai; const WeiPerSixDecimals = BigNumber.from(`1${"0".repeat(6)}`); @@ -45,72 +41,69 @@ const _convertSixDecimalsToEtherBalance = (balance) => { return balance.mul(1e12); }; -const setup = async () => { - const proxyFactory = await artifacts.initializeInterfaceAt("FathomProxyFactory", "FathomProxyFactory"); - const stableswapMultipleSwapsMock = await artifacts.initializeInterfaceAt("StableswapMultipleSwapsMock", "StableswapMultipleSwapsMock"); +describe("StableSwapModuleWrapper", () => { + // Contracts + let USDT; + let stableSwapModule; + let fathomStablecoin; + let stableSwapModuleWrapper; + let stableswapMultipleSwapsMock; - const stableSwapModule = await getProxy(proxyFactory, "StableSwapModule"); - const fathomStablecoin = await getProxy(proxyFactory, "FathomStablecoin"); - const stableSwapModuleWrapper = await getProxy(proxyFactory, "StableSwapModuleWrapper"); + let accounts; + let DeployerAddress; + let AliceAddress; - const usdtAddr = await stableSwapModule.token(); - const USDT = await artifacts.initializeInterfaceAt("ERC20MintableStableSwap", usdtAddr); + beforeEach(async () => { + await deployments.fixture(["DeployTestFixture"]); + const { deployer, allice } = await getNamedAccounts(); + accounts = await ethers.getSigners(); + DeployerAddress = deployer; + AliceAddress = allice; - await USDT.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000 }); - await fathomStablecoin.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000 }); + const ProxyFactory = await deployments.get("FathomProxyFactory"); + const proxyFactory = await ethers.getContractAt("FathomProxyFactory", ProxyFactory.address); - await USDT.mint(DeployerAddress, TO_DEPOSIT_USD.mul(2), { gasLimit: 1000000 }); - await fathomStablecoin.mint(DeployerAddress, TO_DEPOSIT.mul(2), { gasLimit: 1000000 }); + const StableswapMultipleSwapsMock = await deployments.get("StableswapMultipleSwapsMock"); + stableswapMultipleSwapsMock = await ethers.getContractAt("StableswapMultipleSwapsMock", StableswapMultipleSwapsMock.address); - await stableSwapModuleWrapper.depositTokens(TO_DEPOSIT, { gasLimit: 1000000 }); + stableSwapModule = await getProxy(proxyFactory, "StableSwapModule"); + fathomStablecoin = await getProxy(proxyFactory, "FathomStablecoin"); + stableSwapModuleWrapper = await getProxy(proxyFactory, "StableSwapModuleWrapper"); - await USDT.approve(stableSwapModule.address, MaxUint256, { gasLimit: 1000000 }); - await fathomStablecoin.approve(stableSwapModule.address, MaxUint256, { gasLimit: 1000000 }); - await USDT.mint(DeployerAddress, TO_MINT_USD, { gasLimit: 1000000 }); - await fathomStablecoin.mint(DeployerAddress, TO_MINT, { gasLimit: 1000000 }); + const usdtAddr = await stableSwapModule.token(); + USDT = await ethers.getContractAt("ERC20MintableStableSwap", usdtAddr); - await USDT.mint(AliceAddress, TO_MINT_USD, { gasLimit: 1000000 }); - await fathomStablecoin.mint(AliceAddress, TO_MINT, { gasLimit: 1000000 }); + await USDT.approve(stableSwapModuleWrapper.address, MaxUint256); + await fathomStablecoin.approve(stableSwapModuleWrapper.address, MaxUint256); - return { - USDT, - stableSwapModule, - fathomStablecoin, - stableswapMultipleSwapsMock, - stableSwapModuleWrapper, - }; -}; + await USDT.mint(DeployerAddress, TO_DEPOSIT_USD.mul(2)); + await fathomStablecoin.mint(DeployerAddress, TO_DEPOSIT.mul(2)); -describe("StableSwapModuleWrapper", () => { - // Contracts - let USDT; - let stableSwapModule; - let fathomStablecoin; - let stableSwapModuleWrapper; - let stableswapMultipleSwapsMock; + await stableSwapModuleWrapper.depositTokens(TO_DEPOSIT); - before(async () => { - await snapshot.revertToSnapshot(); - }); + await USDT.approve(stableSwapModule.address, MaxUint256); + await fathomStablecoin.approve(stableSwapModule.address, MaxUint256); + await USDT.mint(DeployerAddress, TO_MINT_USD); + await fathomStablecoin.mint(DeployerAddress, TO_MINT); - beforeEach(async () => { - ({ USDT, stableSwapModule, fathomStablecoin, stableswapMultipleSwapsMock, stableSwapModuleWrapper } = await loadFixture(setup)); + await USDT.mint(AliceAddress, TO_MINT_USD); + await fathomStablecoin.mint(AliceAddress, TO_MINT); }); describe("#ShouldDepositTokens", async () => { context("Should deposit tokens", () => { it("Should deposit", async () => { - await stableSwapModuleWrapper.depositTokens(TO_DEPOSIT, { gasLimit: 1000000 }); + await stableSwapModuleWrapper.depositTokens(TO_DEPOSIT); }); }); context("Should not deposit tokens and revert for not whitelisted people", () => { it("Should deposit", async () => { - await USDT.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[2] }); - await fathomStablecoin.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[2] }); - await USDT.mint(accounts[2], TO_DEPOSIT_USD, { gasLimit: 1000000 }); - await fathomStablecoin.mint(accounts[2], TO_DEPOSIT, { gasLimit: 1000000 }); - await expect(stableSwapModuleWrapper.depositTokens(TO_DEPOSIT, { gasLimit: 1000000, from: accounts[2] })).to.be.revertedWith( + await USDT.connect(provider.getSigner(accounts[2].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await fathomStablecoin.connect(provider.getSigner(accounts[2].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await USDT.mint(accounts[2].address, TO_DEPOSIT_USD); + await fathomStablecoin.mint(accounts[2].address, TO_DEPOSIT); + await expect(stableSwapModuleWrapper.connect(provider.getSigner(accounts[2].address)).depositTokens(TO_DEPOSIT)).to.be.revertedWith( "user-not-whitelisted" ); }); @@ -118,23 +111,23 @@ describe("StableSwapModuleWrapper", () => { context("Should let whitelisted people deposit Tokens", () => { it("Should deposit from whitelisted address", async () => { - await stableSwapModuleWrapper.addToWhitelist(accounts[2], { gasLimit: 1000000 }); - await USDT.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[2] }); - await fathomStablecoin.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[2] }); - await USDT.mint(accounts[2], TO_DEPOSIT_USD, { gasLimit: 1000000 }); - await fathomStablecoin.mint(accounts[2], TO_DEPOSIT, { gasLimit: 1000000 }); - await stableSwapModuleWrapper.depositTokens(TO_DEPOSIT, { gasLimit: 1000000, from: accounts[2] }); + await stableSwapModuleWrapper.addToWhitelist(accounts[2].address); + await USDT.connect(provider.getSigner(accounts[2].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await fathomStablecoin.connect(provider.getSigner(accounts[2].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await USDT.mint(accounts[2].address, TO_DEPOSIT_USD); + await fathomStablecoin.mint(accounts[2].address, TO_DEPOSIT); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[2].address)).depositTokens(TO_DEPOSIT); }); it("Should deposit from whitelisted address and after its removed from whitelist, should revert", async () => { - await stableSwapModuleWrapper.addToWhitelist(accounts[2], { gasLimit: 1000000 }); - await USDT.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[2] }); - await fathomStablecoin.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[2] }); - await USDT.mint(accounts[2], TO_DEPOSIT_USD, { gasLimit: 1000000 }); - await fathomStablecoin.mint(accounts[2], TO_DEPOSIT, { gasLimit: 1000000 }); - await stableSwapModuleWrapper.depositTokens(TO_DEPOSIT, { gasLimit: 1000000, from: accounts[2] }); - await stableSwapModuleWrapper.removeFromWhitelist(accounts[2], { gasLimit: 1000000 }); - await expect(stableSwapModuleWrapper.depositTokens(TO_DEPOSIT, { gasLimit: 1000000, from: accounts[2] })).to.be.revertedWith( + await stableSwapModuleWrapper.addToWhitelist(accounts[2].address); + await USDT.connect(provider.getSigner(accounts[2].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await fathomStablecoin.connect(provider.getSigner(accounts[2].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await USDT.mint(accounts[2].address, TO_DEPOSIT_USD); + await fathomStablecoin.mint(accounts[2].address, TO_DEPOSIT); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[2].address)).depositTokens(TO_DEPOSIT); + await stableSwapModuleWrapper.removeFromWhitelist(accounts[2].address); + await expect(stableSwapModuleWrapper.connect(provider.getSigner(accounts[2].address)).depositTokens(TO_DEPOSIT)).to.be.revertedWith( "user-not-whitelisted" ); }); @@ -144,14 +137,14 @@ describe("StableSwapModuleWrapper", () => { describe("#ShouldDepositTokensAndSwap", async () => { context("Should let whitelisted people deposit Tokens and then swap", () => { it("Should deposit", async () => { - await stableSwapModuleWrapper.addToWhitelist(accounts[2], { gasLimit: 1000000 }); - await USDT.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[2] }); - await fathomStablecoin.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[2] }); - await USDT.mint(accounts[2], TO_DEPOSIT_USD, { gasLimit: 1000000 }); - await fathomStablecoin.mint(accounts[2], TO_DEPOSIT, { gasLimit: 1000000 }); - await stableSwapModuleWrapper.depositTokens(TO_DEPOSIT, { gasLimit: 1000000 }); - await stableSwapModule.swapStablecoinToToken(accounts[2], ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT, { gasLimit: 1000000 }); - await stableSwapModule.swapStablecoinToToken(accounts[2], ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT, { gasLimit: 1000000 }); + await stableSwapModuleWrapper.addToWhitelist(accounts[2].address); + await USDT.connect(provider.getSigner(accounts[2].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await fathomStablecoin.connect(provider.getSigner(accounts[2].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await USDT.mint(accounts[2].address, TO_DEPOSIT_USD); + await fathomStablecoin.mint(accounts[2].address, TO_DEPOSIT); + await stableSwapModuleWrapper.depositTokens(TO_DEPOSIT); + await stableSwapModule.swapStablecoinToToken(accounts[2].address, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT); + await stableSwapModule.swapStablecoinToToken(accounts[2].address, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT); }); }); }); @@ -168,53 +161,51 @@ describe("StableSwapModuleWrapper", () => { for (let i = 1; i < 5; i++) { console.log(`depositing for account [${i}]`); - await stableSwapModuleWrapper.addToWhitelist(accounts[i], { gasLimit: 1000000 }); - await USDT.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[i] }); - await fathomStablecoin.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[i] }); - await USDT.mint(accounts[i], TOTAL_DEPOSIT_FOR_EACH_ACCOUNT_USD, { gasLimit: 1000000 }); - await fathomStablecoin.mint(accounts[i], TOTAL_DEPOSIT_FOR_EACH_ACCOUNT, { gasLimit: 1000000 }); - - await stableSwapModuleWrapper.depositTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT, { gasLimit: 1000000, from: accounts[i] }); - TOTAL_FXD_BALANCE_AFTER_DEPOSIT[i] = await fathomStablecoin.balanceOf(accounts[i]); - TOTAL_TOKEN_BALANCE_AFTER_DEPOSIT[i] = await USDT.balanceOf(accounts[i]); + await stableSwapModuleWrapper.addToWhitelist(accounts[i].address); + await USDT.connect(provider.getSigner(accounts[i].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await fathomStablecoin.connect(provider.getSigner(accounts[i].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await USDT.mint(accounts[i].address, TOTAL_DEPOSIT_FOR_EACH_ACCOUNT_USD); + await fathomStablecoin.mint(accounts[i].address, TOTAL_DEPOSIT_FOR_EACH_ACCOUNT); + + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[i].address)).depositTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT); + TOTAL_FXD_BALANCE_AFTER_DEPOSIT[i] = await fathomStablecoin.balanceOf(accounts[i].address); + TOTAL_TOKEN_BALANCE_AFTER_DEPOSIT[i] = await USDT.balanceOf(accounts[i].address); } for (let i = 1; i <= 5; i++) { console.log("Swapping Token to Stablecoin - No...........", i); - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT, { - gasLimit: 1000000, - }); + await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT); //increase block time so that a block is mined before swapping - await TimeHelpers.increase(1); + await time.increase(1); } for (let i = 1; i <= 5; i++) { console.log("Swapping Stablecoin to Token - No...........", i); - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT, { gasLimit: 1000000 }); + await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT); //increase block time so that a block is mined before swapping - await TimeHelpers.increase(1); + await time.increase(1); } for (let i = 1; i < 5; i++) { - const feesFromGetter = await stableSwapModuleWrapper.getClaimableFeesPerUser(accounts[i]); + const feesFromGetter = await stableSwapModuleWrapper.getClaimableFeesPerUser(accounts[i].address); console.log("Total FXD from getter that can be claimed: ", feesFromGetter[0].toString()); console.log(`claiming for account [${i}]`); - await stableSwapModuleWrapper.claimFeesRewards({ from: accounts[i], gasLimit: 8000000 }); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[i].address)).claimFeesRewards(); } - let accountsBalanceBeforeFeesWithdraw = await fathomStablecoin.balanceOf(accounts[1]); - await stableSwapModuleWrapper.withdrawClaimedFees({ from: accounts[1], gasLimit: 8000000 }); - let accountsBalanceAfterFeesWithdraw = await fathomStablecoin.balanceOf(accounts[1]); + let accountsBalanceBeforeFeesWithdraw = await fathomStablecoin.balanceOf(accounts[1].address); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[1].address)).withdrawClaimedFees(); + let accountsBalanceAfterFeesWithdraw = await fathomStablecoin.balanceOf(accounts[1].address); let totalFXDWithdrawnAsFeesAccounts = accountsBalanceAfterFeesWithdraw.sub(accountsBalanceBeforeFeesWithdraw).toString(); let currentAccountFXDFeesWithdrawn = totalFXDWithdrawnAsFeesAccounts; let previousCurrentAccountFXDFeesWithdrawn; for (let i = 2; i < 5; i++) { previousCurrentAccountFXDFeesWithdrawn = currentAccountFXDFeesWithdrawn; - const accountsBalanceBeforeFeesWithdraw = await fathomStablecoin.balanceOf(accounts[i]); - await stableSwapModuleWrapper.withdrawClaimedFees({ from: accounts[i], gasLimit: 8000000 }); - const accountsBalanceAfterFeesWithdraw = await fathomStablecoin.balanceOf(accounts[i]); + const accountsBalanceBeforeFeesWithdraw = await fathomStablecoin.balanceOf(accounts[i].address); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[i].address)).withdrawClaimedFees(); + const accountsBalanceAfterFeesWithdraw = await fathomStablecoin.balanceOf(accounts[i].address); const totalFXDWithdrawnAsFeesAccounts = accountsBalanceAfterFeesWithdraw.sub(accountsBalanceBeforeFeesWithdraw).toString(); expect(previousCurrentAccountFXDFeesWithdrawn).to.be.eq(currentAccountFXDFeesWithdrawn); currentAccountFXDFeesWithdrawn = totalFXDWithdrawnAsFeesAccounts; @@ -228,15 +219,15 @@ describe("StableSwapModuleWrapper", () => { const totalValueDepositedAfterUpdate = await stableSwapModule.totalValueDeposited(); expect(totalValueDepositedAfterUpdate).to.be.equal(totalValueDepositedBeforeUpdate); - await stableSwapModuleWrapper.claimFeesRewards({ from: accounts[0], gasLimit: 8000000 }); - await stableSwapModuleWrapper.withdrawClaimedFees({ from: accounts[0], gasLimit: 8000000 }); - await stableSwapModuleWrapper.withdrawTokens(TO_DEPOSIT.mul(2), { from: accounts[0], gasLimit: 8000000 }); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[0].address)).claimFeesRewards(); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[0].address)).withdrawClaimedFees(); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[0].address)).withdrawTokens(TO_DEPOSIT.mul(2)); for (let i = 1; i < 5; i++) { console.log(`withdrawing whole liquidity of accounts[${i}]`); - await stableSwapModuleWrapper.withdrawTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT.mul(2), { from: accounts[i], gasLimit: 8000000 }); - const TOTAL_FXD_BALANCE_AFTER_WITHDRAW = await fathomStablecoin.balanceOf(accounts[i]); - const TOTAL_TOKEN_BALANCE_AFTER_WITHDRAW = await USDT.balanceOf(accounts[i]); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[i].address)).withdrawTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT.mul(2)); + const TOTAL_FXD_BALANCE_AFTER_WITHDRAW = await fathomStablecoin.balanceOf(accounts[i].address); + const TOTAL_TOKEN_BALANCE_AFTER_WITHDRAW = await USDT.balanceOf(accounts[i].address); const TOTAL_TOKEN_BALANCE_AFTER_WITHDRAW_SCALED = _convertSixDecimalsToEtherBalance(TOTAL_TOKEN_BALANCE_AFTER_WITHDRAW); const TOTAL_TOKEN_BALANCE_AFTER_DEPOSIT_SCALED = _convertSixDecimalsToEtherBalance(TOTAL_TOKEN_BALANCE_AFTER_DEPOSIT[i]); @@ -267,42 +258,40 @@ describe("StableSwapModuleWrapper", () => { const TOTAL_DEPOSIT_FOR_EACH_ACCOUNT_USD = WeiPerSixDecimals.mul(1000); for (let i = 1; i < 5; i++) { console.log(`depositing for account [${i}]`); - await stableSwapModuleWrapper.addToWhitelist(accounts[i], { gasLimit: 1000000 }); - await USDT.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[i] }); - await fathomStablecoin.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[i] }); - await USDT.mint(accounts[i], TOTAL_DEPOSIT_FOR_EACH_ACCOUNT_USD, { gasLimit: 1000000 }); - await fathomStablecoin.mint(accounts[i], TOTAL_DEPOSIT_FOR_EACH_ACCOUNT, { gasLimit: 1000000 }); - await stableSwapModuleWrapper.depositTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT, { gasLimit: 1000000, from: accounts[i] }); + await stableSwapModuleWrapper.addToWhitelist(accounts[i].address); + await USDT.connect(provider.getSigner(accounts[i].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await fathomStablecoin.connect(provider.getSigner(accounts[i].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await USDT.mint(accounts[i].address, TOTAL_DEPOSIT_FOR_EACH_ACCOUNT_USD); + await fathomStablecoin.mint(accounts[i].address, TOTAL_DEPOSIT_FOR_EACH_ACCOUNT); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[i].address)).depositTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT); } for (let i = 1; i <= 5; i++) { console.log("Swapping Token to Stablecoin - No...........", i); - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT, { - gasLimit: 1000000, - }); + await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT); //increase block time so that a block is mined before swapping - await TimeHelpers.increase(1); + await time.increase(1); } for (let i = 1; i <= 5; i++) { console.log("Swapping Stablecoin to Token - No...........", i); - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT, { gasLimit: 1000000 }); + await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT); //increase block time so that a block is mined before swapping - await TimeHelpers.increase(1); + await time.increase(1); } - const accounts1BalanceBeforeFeesWithdraw = await fathomStablecoin.balanceOf(accounts[1]); - await stableSwapModuleWrapper.withdrawTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT, { from: accounts[1], gasLimit: 8000000 }); - const accounts1BalanceAfterFeesWithdraw = await fathomStablecoin.balanceOf(accounts[1]); + const accounts1BalanceBeforeFeesWithdraw = await fathomStablecoin.balanceOf(accounts[1].address); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[1].address)).withdrawTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT); + const accounts1BalanceAfterFeesWithdraw = await fathomStablecoin.balanceOf(accounts[1].address); const totalFXDWithdrawnAsFeesAccounts = accounts1BalanceAfterFeesWithdraw.sub(accounts1BalanceBeforeFeesWithdraw).toString(); let currentAccountFXDFeesWithdrawn = totalFXDWithdrawnAsFeesAccounts; let previousAccountFXDFeesWithdrawn; for (let i = 2; i < 5; i++) { previousAccountFXDFeesWithdrawn = currentAccountFXDFeesWithdrawn; - const accountsBalanceBeforeFeesWithdraw = await fathomStablecoin.balanceOf(accounts[i]); - await stableSwapModuleWrapper.withdrawTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT, { from: accounts[i], gasLimit: 8000000 }); - const accountsBalanceAfterFeesWithdraw = await fathomStablecoin.balanceOf(accounts[i]); + const accountsBalanceBeforeFeesWithdraw = await fathomStablecoin.balanceOf(accounts[i].address); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[i].address)).withdrawTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT); + const accountsBalanceAfterFeesWithdraw = await fathomStablecoin.balanceOf(accounts[i].address); const totalFXDWithdrawnAsFeesAccounts = accountsBalanceAfterFeesWithdraw.sub(accountsBalanceBeforeFeesWithdraw).toString(); currentAccountFXDFeesWithdrawn = totalFXDWithdrawnAsFeesAccounts; expect(parseInt(currentAccountFXDFeesWithdrawn)).to.be.gt(parseInt(previousAccountFXDFeesWithdrawn)); @@ -324,78 +313,72 @@ describe("StableSwapModuleWrapper", () => { //whitelist and deposit for 3 accounts for (let i = 1; i < 4; i++) { console.log(`depositing for account [${i}]`); - await stableSwapModuleWrapper.addToWhitelist(accounts[i], { gasLimit: 1000000 }); - await USDT.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[i] }); - await fathomStablecoin.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[i] }); - await USDT.mint(accounts[i], TOTAL_DEPOSIT_FOR_EACH_ACCOUNT_USD, { gasLimit: 1000000 }); - await fathomStablecoin.mint(accounts[i], TOTAL_DEPOSIT_FOR_EACH_ACCOUNT, { gasLimit: 1000000 }); - await stableSwapModuleWrapper.depositTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT, { gasLimit: 1000000, from: accounts[i] }); + await stableSwapModuleWrapper.addToWhitelist(accounts[i].address); + await USDT.connect(provider.getSigner(accounts[i].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await fathomStablecoin.connect(provider.getSigner(accounts[i].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await USDT.mint(accounts[i].address, TOTAL_DEPOSIT_FOR_EACH_ACCOUNT_USD); + await fathomStablecoin.mint(accounts[i].address, TOTAL_DEPOSIT_FOR_EACH_ACCOUNT); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[i].address)).depositTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT); } //swap to generate fees for (let i = 1; i <= 2; i++) { console.log("Swapping Token to Stablecoin - No...........", i); - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT, { - gasLimit: 1000000, - }); + await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT); //increase block time so that a block is mined before swapping - await TimeHelpers.increase(1); + await time.increase(1); } for (let i = 1; i <= 2; i++) { console.log("Swapping Stablecoin to Token - No...........", i); - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT, { gasLimit: 1000000 }); + await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT); //increase block time so that a block is mined before swapping - await TimeHelpers.increase(1); + await time.increase(1); } - await stableSwapModuleWrapper.withdrawTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT.mul(2), { from: accounts[1], gasLimit: 8000000 }); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[1].address)).withdrawTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT.mul(2)); - await stableSwapModuleWrapper.addToWhitelist(accounts[4], { gasLimit: 1000000 }); - await USDT.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[4] }); - await fathomStablecoin.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[4] }); - await USDT.mint(accounts[4], TOTAL_DEPOSIT_FOR_EACH_ACCOUNT_USD, { gasLimit: 1000000 }); - await fathomStablecoin.mint(accounts[4], TOTAL_DEPOSIT_FOR_EACH_ACCOUNT, { gasLimit: 1000000 }); - await stableSwapModuleWrapper.depositTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT, { gasLimit: 1000000, from: accounts[4] }); + await stableSwapModuleWrapper.addToWhitelist(accounts[4].address); + await USDT.connect(provider.getSigner(accounts[4].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await fathomStablecoin.connect(provider.getSigner(accounts[4].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await USDT.mint(accounts[4].address, TOTAL_DEPOSIT_FOR_EACH_ACCOUNT_USD); + await fathomStablecoin.mint(accounts[4].address, TOTAL_DEPOSIT_FOR_EACH_ACCOUNT); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[4].address)).depositTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT); //swap to generate fees for (let i = 1; i <= 2; i++) { console.log("Swapping Token to Stablecoin - No...........", i); - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT, { - gasLimit: 1000000, - }); + await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT); //increase block time so that a block is mined before swapping - await TimeHelpers.increase(1); + await time.increase(1); } for (let i = 1; i <= 2; i++) { console.log("Swapping Stablecoin to Token - No...........", i); - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT, { gasLimit: 1000000 }); + await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT); //increase block time so that a block is mined before swapping - await TimeHelpers.increase(1); + await time.increase(1); } - await stableSwapModuleWrapper.withdrawTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT.mul(2), { from: accounts[2], gasLimit: 8000000 }); - await stableSwapModuleWrapper.withdrawTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT.mul(2), { from: accounts[3], gasLimit: 8000000 }); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[2].address)).withdrawTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT.mul(2)); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[3].address)).withdrawTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT.mul(2)); //swap to generate fees for (let i = 1; i <= 2; i++) { console.log("Swapping Token to Stablecoin - No...........", i); - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT, { - gasLimit: 1000000, - }); + await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT); //increase block time so that a block is mined before swapping - await TimeHelpers.increase(1); + await time.increase(1); } for (let i = 1; i <= 2; i++) { console.log("Swapping Stablecoin to Token - No...........", i); - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT, { gasLimit: 1000000 }); + await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT); //increase block time so that a block is mined before swapping - await TimeHelpers.increase(1); + await time.increase(1); } - await stableSwapModuleWrapper.withdrawTokens(TO_DEPOSIT.mul(2), { from: accounts[0], gasLimit: 8000000 }); - await stableSwapModuleWrapper.withdrawTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT.mul(2), { from: accounts[4], gasLimit: 8000000 }); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[0].address)).withdrawTokens(TO_DEPOSIT.mul(2)); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[4].address)).withdrawTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT.mul(2)); const totalValueLockedInStableswap = await stableSwapModule.totalValueLocked(); expect(totalValueLockedInStableswap.toString()).to.be.equal("0"); }); @@ -405,31 +388,25 @@ describe("StableSwapModuleWrapper", () => { describe("#withdrawTokens from Stableswap with stableswapWrapper", async () => { context("Should withdraw tokens from stableswap", () => { it("Should withdraw", async () => { - await stableSwapModuleWrapper.withdrawTokens(WeiPerWad, { - from: DeployerAddress, - gasLimit: 8000000, - }); + await stableSwapModuleWrapper.connect(provider.getSigner(DeployerAddress)).withdrawTokens(WeiPerWad); }); }); context("Should withdraw tokens from stableswap as per the ratio with swap stablecoin to token", () => { it("Should withdraw", async () => { - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT, { gasLimit: 1000000 }); + await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT); - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT, { gasLimit: 1000000 }); + await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT); - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT, { gasLimit: 1000000 }); + await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT); - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT, { gasLimit: 1000000 }); + await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT); const balanceOfStablecoinBeforeWithdraw = await fathomStablecoin.balanceOf(DeployerAddress); let balanceOfTokenBeforeWithdraw = await USDT.balanceOf(DeployerAddress); balanceOfTokenBeforeWithdraw = _convertSixDecimalsToEtherBalance(balanceOfTokenBeforeWithdraw); const amountToWithdraw = WeiPerWad.mul(200); - await stableSwapModuleWrapper.withdrawTokens(amountToWithdraw, { - from: DeployerAddress, - gasLimit: 8000000, - }); + await stableSwapModuleWrapper.connect(provider.getSigner(DeployerAddress)).withdrawTokens(amountToWithdraw); const balanceOfStablecoinAfterWithdraw = await fathomStablecoin.balanceOf(DeployerAddress); let balanceOfTokenAfterWithdraw = await USDT.balanceOf(DeployerAddress); @@ -473,21 +450,13 @@ describe("StableSwapModuleWrapper", () => { context("Should withdraw tokens from stableswap as per the ratio with swap token to stablecoin", () => { it("Should withdraw", async () => { - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT, { - gasLimit: 1000000, - }); + await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT); - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT, { - gasLimit: 1000000, - }); + await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT); - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT, { - gasLimit: 1000000, - }); + await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT); - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT, { - gasLimit: 1000000, - }); + await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT); const balanceOfStablecoinBeforeWithdraw = await fathomStablecoin.balanceOf(DeployerAddress); @@ -495,10 +464,7 @@ describe("StableSwapModuleWrapper", () => { balanceOfTokenBeforeWithdraw = _convertSixDecimalsToEtherBalance(balanceOfTokenBeforeWithdraw); const amountToWithdraw = WeiPerWad.mul(200); - await stableSwapModuleWrapper.withdrawTokens(WeiPerWad.mul(200), { - from: DeployerAddress, - gasLimit: 8000000, - }); + await stableSwapModuleWrapper.connect(provider.getSigner(DeployerAddress)).withdrawTokens(WeiPerWad.mul(200)); const balanceOfStablecoinAfterWithdraw = await fathomStablecoin.balanceOf(DeployerAddress); let balanceOfTokenAfterWithdraw = await USDT.balanceOf(DeployerAddress); @@ -542,35 +508,24 @@ describe("StableSwapModuleWrapper", () => { context("Should withdraw tokens from stableswap as per the ratio with swap token to stablecoin and swap stablecoin to token", () => { it("Should withdraw", async () => { - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT, { - gasLimit: 1000000, - }); + await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT); - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT, { - gasLimit: 1000000, - }); + await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT); - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT, { - gasLimit: 1000000, - }); + await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT); - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT, { - gasLimit: 1000000, - }); + await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT); - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT, { gasLimit: 1000000 }); + await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT); - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT, { gasLimit: 1000000 }); + await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT); const balanceOfStablecoinBeforeWithdraw = await fathomStablecoin.balanceOf(DeployerAddress); let balanceOfTokenBeforeWithdraw = await USDT.balanceOf(DeployerAddress); balanceOfTokenBeforeWithdraw = _convertSixDecimalsToEtherBalance(balanceOfTokenBeforeWithdraw); const amountToWithdraw = WeiPerWad.mul(1000); - await stableSwapModuleWrapper.withdrawTokens(amountToWithdraw, { - from: DeployerAddress, - gasLimit: 8000000, - }); + await stableSwapModuleWrapper.connect(provider.getSigner(DeployerAddress)).withdrawTokens(amountToWithdraw); const balanceOfStablecoinAfterWithdraw = await fathomStablecoin.balanceOf(DeployerAddress); let balanceOfTokenAfterWithdraw = await USDT.balanceOf(DeployerAddress); @@ -605,78 +560,74 @@ describe("StableSwapModuleWrapper", () => { actualTransferOfBalanceOfToken.toString() ); //this because it is reverting due to some reason - await TimeHelpers.increase(1); - await stableSwapModuleWrapper.withdrawTokens(TO_DEPOSIT.mul(2).sub(WeiPerWad.mul(1000)), { from: DeployerAddress, gasLimit: 8000000 }); + await time.increase(1); + await stableSwapModuleWrapper.connect(provider.getSigner(DeployerAddress)).withdrawTokens(TO_DEPOSIT.mul(2).sub(WeiPerWad.mul(1000))); }); }); context("1. Whitelist one account, 2. swap tokens to generate fees, 3. withdraw tokens, 4. repeat steps 2 and 3", async () => { it("Should withdraw correct fees and check the console for verfication ", async () => { - await stableSwapModuleWrapper.addToWhitelist(accounts[2], { gasLimit: 1000000 }); - await USDT.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[2] }); - await fathomStablecoin.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[2] }); - await USDT.mint(accounts[2], TO_DEPOSIT_USD, { gasLimit: 1000000 }); - await fathomStablecoin.mint(accounts[2], TO_DEPOSIT, { gasLimit: 1000000 }); - await stableSwapModuleWrapper.depositTokens(TO_DEPOSIT, { gasLimit: 1000000, from: accounts[2] }); + await stableSwapModuleWrapper.addToWhitelist(accounts[2].address); + await USDT.connect(provider.getSigner(accounts[2].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await fathomStablecoin.connect(provider.getSigner(accounts[2].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await USDT.mint(accounts[2].address, TO_DEPOSIT_USD); + await fathomStablecoin.mint(accounts[2].address, TO_DEPOSIT); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[2].address)).depositTokens(TO_DEPOSIT); for (let i = 1; i <= 5; i++) { console.log("Swapping Token to Stablecoin - No...........", i); - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT, { - gasLimit: 1000000, - }); + await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT); //increase block time so that a block is mined before swapping - await TimeHelpers.increase(1); + await time.increase(1); } for (let i = 1; i <= 5; i++) { console.log("Swapping Stablecoin to Token - No...........", i); - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT, { gasLimit: 1000000 }); + await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT); //increase block time so that a block is mined before swapping - await TimeHelpers.increase(1); + await time.increase(1); } - await stableSwapModuleWrapper.claimFeesRewards({ from: accounts[2], gasLimit: 8000000 }); - await stableSwapModuleWrapper.claimFeesRewards({ from: DeployerAddress, gasLimit: 8000000 }); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[2].address)).claimFeesRewards(); + await stableSwapModuleWrapper.connect(provider.getSigner(DeployerAddress)).claimFeesRewards(); //What is happening: WHen I switch it is not working correctly let DeployerBalanceBeforeFeesWithdraw = await fathomStablecoin.balanceOf(DeployerAddress); - await stableSwapModuleWrapper.withdrawClaimedFees({ from: DeployerAddress, gasLimit: 8000000 }); + await stableSwapModuleWrapper.connect(provider.getSigner(DeployerAddress)).withdrawClaimedFees(); let DeployerBalanceAfterFeesWithdraw = await fathomStablecoin.balanceOf(DeployerAddress); let totalFXDWithdrawnAsFeesDeployer = DeployerBalanceAfterFeesWithdraw.sub(DeployerBalanceBeforeFeesWithdraw).toString(); console.log("Total FXD withdrawn as fees for deployer: \n", totalFXDWithdrawnAsFeesDeployer); - let accounts2BalanceBeforeFeesWithdraw = await fathomStablecoin.balanceOf(accounts[2]); - await stableSwapModuleWrapper.withdrawClaimedFees({ from: accounts[2], gasLimit: 8000000 }); - let accounts2BalanceAfterFeesWithdraw = await fathomStablecoin.balanceOf(accounts[2]); + let accounts2BalanceBeforeFeesWithdraw = await fathomStablecoin.balanceOf(accounts[2].address); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[2].address)).withdrawClaimedFees(); + let accounts2BalanceAfterFeesWithdraw = await fathomStablecoin.balanceOf(accounts[2].address); let totalFXDWithdrawnAsFeesAccounts2 = accounts2BalanceAfterFeesWithdraw.sub(accounts2BalanceBeforeFeesWithdraw).toString(); console.log("Total FXD withdrawn as fees for accounts2: \n", totalFXDWithdrawnAsFeesAccounts2); for (let i = 1; i <= 5; i++) { console.log("Swapping Token to Stablecoin - No...........", i); - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT, { - gasLimit: 1000000, - }); + await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT); //increase block time so that a block is mined before swapping - await TimeHelpers.increase(1); + await time.increase(1); } for (let i = 1; i <= 5; i++) { console.log("Swapping Stablecoin to Token - No...........", i); - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT, { gasLimit: 1000000 }); + await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT); //increase block time so that a block is mined before swapping - await TimeHelpers.increase(1); + await time.increase(1); } - accounts2BalanceBeforeFeesWithdraw = await fathomStablecoin.balanceOf(accounts[2]); - await stableSwapModuleWrapper.withdrawTokens(TO_DEPOSIT.mul(2), { from: accounts[2], gasLimit: 8000000 }); - accounts2BalanceAfterFeesWithdraw = await fathomStablecoin.balanceOf(accounts[2]); + accounts2BalanceBeforeFeesWithdraw = await fathomStablecoin.balanceOf(accounts[2].address); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[2].address)).withdrawTokens(TO_DEPOSIT.mul(2)); + accounts2BalanceAfterFeesWithdraw = await fathomStablecoin.balanceOf(accounts[2].address); totalFXDWithdrawnAsFeesAccounts2 = accounts2BalanceAfterFeesWithdraw.sub(accounts2BalanceBeforeFeesWithdraw).toString(); console.log("Total FXD withdrawn as fees for accounts2: \n", totalFXDWithdrawnAsFeesAccounts2); - await TimeHelpers.increase(1); + await time.increase(1); DeployerBalanceBeforeFeesWithdraw = await fathomStablecoin.balanceOf(DeployerAddress); - await stableSwapModuleWrapper.withdrawTokens(TO_DEPOSIT.mul(2), { from: DeployerAddress, gasLimit: 8000000 }); + await stableSwapModuleWrapper.connect(provider.getSigner(DeployerAddress)).withdrawTokens(TO_DEPOSIT.mul(2)); DeployerBalanceAfterFeesWithdraw = await fathomStablecoin.balanceOf(DeployerAddress); totalFXDWithdrawnAsFeesDeployer = DeployerBalanceAfterFeesWithdraw.sub(DeployerBalanceBeforeFeesWithdraw).toString(); @@ -688,22 +639,24 @@ describe("StableSwapModuleWrapper", () => { describe("#decentralizedState", async () => { context("set decentralized state and deposit tokens by anybody", async () => { it("Should succeed", async () => { - await stableSwapModuleWrapper.setIsDecentralizedState(true, { from: DeployerAddress }); - await fathomStablecoin.approve(stableSwapModuleWrapper.address, MaxUint256, { from: AliceAddress, gasLimit: 8000000 }); - await USDT.approve(stableSwapModuleWrapper.address, MaxUint256, { from: AliceAddress, gasLimit: 8000000 }); - await stableSwapModuleWrapper.depositTokens(TO_DEPOSIT, { from: AliceAddress }); + await stableSwapModuleWrapper.connect(provider.getSigner(DeployerAddress)).setIsDecentralizedState(true); + await fathomStablecoin.connect(provider.getSigner(AliceAddress)).approve(stableSwapModuleWrapper.address, MaxUint256); + await USDT.connect(provider.getSigner(AliceAddress)).approve(stableSwapModuleWrapper.address, MaxUint256); + await stableSwapModuleWrapper.connect(provider.getSigner(AliceAddress)).depositTokens(TO_DEPOSIT); }); }); context("set decentralized state and deposit tokens should succeed then, set decentralized state as false and should fail", async () => { it("Should succeed", async () => { - await stableSwapModuleWrapper.setIsDecentralizedState(true, { from: DeployerAddress }); - await fathomStablecoin.approve(stableSwapModuleWrapper.address, MaxUint256, { from: accounts[1], gasLimit: 8000000 }); - await USDT.approve(stableSwapModuleWrapper.address, MaxUint256, { from: accounts[1], gasLimit: 8000000 }); + await stableSwapModuleWrapper.connect(provider.getSigner(DeployerAddress)).setIsDecentralizedState(true); + await fathomStablecoin.connect(provider.getSigner(accounts[1].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await USDT.connect(provider.getSigner(accounts[1].address)).approve(stableSwapModuleWrapper.address, MaxUint256); - await stableSwapModuleWrapper.depositTokens(TO_DEPOSIT, { from: accounts[1] }); - await stableSwapModuleWrapper.setIsDecentralizedState(false, { from: DeployerAddress }); - await expect(stableSwapModuleWrapper.depositTokens(TO_DEPOSIT, { from: accounts[1] })).to.be.revertedWith("user-not-whitelisted"); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[1].address)).depositTokens(TO_DEPOSIT); + await stableSwapModuleWrapper.connect(provider.getSigner(DeployerAddress)).setIsDecentralizedState(false); + await expect(stableSwapModuleWrapper.connect(provider.getSigner(accounts[1].address)).depositTokens(TO_DEPOSIT)).to.be.revertedWith( + "user-not-whitelisted" + ); }); }); }); @@ -711,9 +664,9 @@ describe("StableSwapModuleWrapper", () => { describe("#depositTokens", async () => { context("deposit USDT and FXD as not whiteListed account", async () => { it("should fail", async () => { - await fathomStablecoin.approve(stableSwapModuleWrapper.address, MaxUint256, { from: accounts[1], gasLimit: 8000000 }); - await USDT.approve(stableSwapModule.address, MaxUint256, { from: accounts[1], gasLimit: 8000000 }); - await expect(stableSwapModuleWrapper.depositTokens(TO_DEPOSIT, { from: accounts[1], gasLimit: 8000000 })).to.be.revertedWith( + await fathomStablecoin.connect(provider.getSigner(accounts[1].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await USDT.connect(provider.getSigner(accounts[1].address)).approve(stableSwapModule.address, MaxUint256); + await expect(stableSwapModuleWrapper.connect(provider.getSigner(accounts[1].address)).depositTokens(TO_DEPOSIT)).to.be.revertedWith( "user-not-whitelisted" ); }); @@ -721,7 +674,7 @@ describe("StableSwapModuleWrapper", () => { context("deposit USDT and FXD as whiteListed account", async () => { it("should succeed", async () => { - await stableSwapModuleWrapper.depositTokens(TO_DEPOSIT, { gasLimit: 8000000 }); + await stableSwapModuleWrapper.depositTokens(TO_DEPOSIT); const depositTracker1 = await stableSwapModuleWrapper.depositTracker(DeployerAddress); expect(depositTracker1).to.be.equal(TO_DEPOSIT.mul(4)); }); @@ -739,9 +692,7 @@ describe("StableSwapModuleWrapper", () => { context("#getAmounts", async () => { it("should return the correct amount of tokens after swap", async () => { - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT, { - gasLimit: 1000000, - }); + await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT); const amounts = await stableSwapModuleWrapper.getAmounts(TO_DEPOSIT); expect(amounts[0]).to.be.lte(TO_DEPOSIT.div(2)); expect(amounts[1]).to.be.gte(TO_DEPOSIT.div(2)); @@ -766,43 +717,41 @@ describe("StableSwapModuleWrapper", () => { const TOTAL_DEPOSIT_FOR_EACH_ACCOUNT_USD = WeiPerSixDecimals.mul(1000); for (let i = 1; i < 5; i++) { console.log(`depositing for account [${i}]`); - await stableSwapModuleWrapper.addToWhitelist(accounts[i], { gasLimit: 1000000 }); - await USDT.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[i] }); - await fathomStablecoin.approve(stableSwapModuleWrapper.address, MaxUint256, { gasLimit: 1000000, from: accounts[i] }); - await USDT.mint(accounts[i], TOTAL_DEPOSIT_FOR_EACH_ACCOUNT_USD, { gasLimit: 1000000 }); - await fathomStablecoin.mint(accounts[i], TOTAL_DEPOSIT_FOR_EACH_ACCOUNT, { gasLimit: 1000000 }); - await stableSwapModuleWrapper.depositTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT, { gasLimit: 1000000, from: accounts[i] }); + await stableSwapModuleWrapper.addToWhitelist(accounts[i].address); + await USDT.connect(provider.getSigner(accounts[i].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await fathomStablecoin.connect(provider.getSigner(accounts[i].address)).approve(stableSwapModuleWrapper.address, MaxUint256); + await USDT.mint(accounts[i].address, TOTAL_DEPOSIT_FOR_EACH_ACCOUNT_USD); + await fathomStablecoin.mint(accounts[i].address, TOTAL_DEPOSIT_FOR_EACH_ACCOUNT); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[i].address)).depositTokens(TOTAL_DEPOSIT_FOR_EACH_ACCOUNT); } for (let i = 1; i <= 5; i++) { console.log("Swapping Token to Stablecoin - No...........", i); - await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT, { - gasLimit: 1000000, - }); + await stableSwapModule.swapTokenToStablecoin(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SIX_DECIMALS_SINGLE_SWAP_FIT); //increase block time so that a block is mined before swapping - await TimeHelpers.increase(1); + await time.increase(1); } for (let i = 1; i <= 5; i++) { console.log("Swapping Stablecoin to Token - No...........", i); - await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT, { gasLimit: 1000000 }); + await stableSwapModule.swapStablecoinToToken(DeployerAddress, ONE_PERCENT_OF_TOTAL_DEPOSIT_SINGLE_SWAP_FIT); //increase block time so that a block is mined before swapping - await TimeHelpers.increase(1); + await time.increase(1); } for (let i = 0; i < 5; i++) { console.log(`claiming for account [${i}]`); - await stableSwapModuleWrapper.claimFeesRewards({ from: accounts[i], gasLimit: 8000000 }); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[i].address)).claimFeesRewards(); console.log(`withdrawing claimed fees for account [${i}]`); - await stableSwapModuleWrapper.withdrawClaimedFees({ from: accounts[i], gasLimit: 8000000 }); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[i].address)).withdrawClaimedFees(); } - await stableSwapModuleWrapper.pause({ gasLimit: 1000000 }); - await stableSwapModule.pause({ gasLimit: 1000000 }); + await stableSwapModuleWrapper.pause(); + await stableSwapModule.pause(); for (let i = 0; i < 5; i++) { console.log(`emergency withdraw for account [${i}]`); - await stableSwapModuleWrapper.emergencyWithdraw({ gasLimit: 1000000, from: accounts[i] }); + await stableSwapModuleWrapper.connect(provider.getSigner(accounts[i].address)).emergencyWithdraw(); } const totalValueLockedInStableswap = await stableSwapModule.totalValueLocked(); diff --git a/test/unit/adapter/StablecoinAdapter.test.js b/test/unit/adapter/StablecoinAdapter.test.js index 5ed2dbc2..fdd981e2 100644 --- a/test/unit/adapter/StablecoinAdapter.test.js +++ b/test/unit/adapter/StablecoinAdapter.test.js @@ -21,18 +21,18 @@ describe("StablecoinAdapter", async () => { mockedBookKeeper = await smock.fake("BookKeeper"); mockedToken = await smock.fake("ERC20Mintable"); - + mockedToken.decimals.returns(18); mockedAccessControlConfig.OWNER_ROLE.returns(formatBytes32String("OWNER_ROLE")); mockedAccessControlConfig.GOV_ROLE.returns(formatBytes32String("GOV_ROLE")); mockedAccessControlConfig.SHOW_STOPPER_ROLE.returns(formatBytes32String("SHOW_STOPPER_ROLE")); mockedAccessControlConfig.hasRole.returns(true); mockedBookKeeper.collateralPoolConfig.returns(mockedCollateralPoolConfig.address); - + const StablecoinAdapterFactory = await ethers.getContractFactory("MockStablecoinAdapter"); stablecoinAdapter = await StablecoinAdapterFactory.deploy(); await stablecoinAdapter.deployed(); - + await stablecoinAdapter.initialize(mockedBookKeeper.address, mockedToken.address); const { deployer, allice } = await getNamedAccounts(); @@ -61,4 +61,4 @@ describe("StablecoinAdapter", async () => { ); }); }); -}); \ No newline at end of file +}); diff --git a/test/unit/adapter/TokenAdapter.test.js b/test/unit/adapter/TokenAdapter.test.js index 8bb3edaf..b6b07431 100644 --- a/test/unit/adapter/TokenAdapter.test.js +++ b/test/unit/adapter/TokenAdapter.test.js @@ -27,22 +27,22 @@ describe("TokenAdapter", () => { mockedAccessControlConfig = await smock.fake("AccessControlConfig"); mockedCollateralPoolConfig = await smock.fake("CollateralPoolConfig"); mockedVault = await smock.fake("Vault"); - + mockedBookKeeper = await smock.fake("BookKeeper"); mockedToken = await smock.fake("ERC20Mintable"); - + mockedToken.decimals.returns(18); mockedAccessControlConfig.OWNER_ROLE.returns(formatBytes32String("OWNER_ROLE")); mockedAccessControlConfig.GOV_ROLE.returns(formatBytes32String("GOV_ROLE")); mockedAccessControlConfig.SHOW_STOPPER_ROLE.returns(formatBytes32String("SHOW_STOPPER_ROLE")); mockedAccessControlConfig.hasRole.returns(true); - + const TokenAdapterFactory = await ethers.getContractFactory("TokenAdapter"); tokenAdapter = await TokenAdapterFactory.deploy(); await tokenAdapter.deployed(); - + tokenAdapterAsAlice = tokenAdapter.connect(provider.getSigner(AliceAddress)); - + await tokenAdapter.initialize(mockedBookKeeper.address, formatBytes32String("BTCB"), mockedToken.address); }); @@ -244,4 +244,4 @@ describe("TokenAdapter", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/unit/config/CollateralPoolConfig.test.js b/test/unit/config/CollateralPoolConfig.test.js index 7335c0e1..5ecb555c 100644 --- a/test/unit/config/CollateralPoolConfig.test.js +++ b/test/unit/config/CollateralPoolConfig.test.js @@ -837,4 +837,4 @@ describe("CollateralPoolConfig", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/unit/fathom-bridge/FathomBridge.test.js b/test/unit/fathom-bridge/FathomBridge.test.js index f81cd631..327c4512 100644 --- a/test/unit/fathom-bridge/FathomBridge.test.js +++ b/test/unit/fathom-bridge/FathomBridge.test.js @@ -52,9 +52,7 @@ describe("FathomBridge", () => { context("when the caller is the owner", async () => { it("should work", async () => { mockedAccessControlConfig.hasRole.returns(true); - await expect(fathomBridge.addToWhitelist(AliceAddress)) - .to.be.emit(fathomBridge, "LogAddToWhitelist") - .withArgs(AliceAddress); + await expect(fathomBridge.addToWhitelist(AliceAddress)).to.be.emit(fathomBridge, "LogAddToWhitelist").withArgs(AliceAddress); }); }); context("when the caller is the owner but trying to add ZeroAddress", async () => { @@ -76,9 +74,7 @@ describe("FathomBridge", () => { it("should work", async () => { mockedAccessControlConfig.hasRole.returns(true); await fathomBridge.addToWhitelist(AliceAddress); - await expect(fathomBridge.removeFromWhitelist(AliceAddress)) - .to.be.emit(fathomBridge, "LogRemoveFromWhitelist") - .withArgs(AliceAddress); + await expect(fathomBridge.removeFromWhitelist(AliceAddress)).to.be.emit(fathomBridge, "LogRemoveFromWhitelist").withArgs(AliceAddress); }); }); context("when the caller is the owner but trying to add ZeroAddress", async () => { @@ -101,9 +97,7 @@ describe("FathomBridge", () => { mockedAccessControlConfig.hasRole.returns(true); const decentralizedModeBefore = await fathomBridge.isDecentralizedMode(); expect(decentralizedModeBefore).to.be.equal(false); - await expect(fathomBridge.setDecentralizedMode(true)) - .to.be.emit(fathomBridge, "LogSetDecentralizedMode") - .withArgs(true); + await expect(fathomBridge.setDecentralizedMode(true)).to.be.emit(fathomBridge, "LogSetDecentralizedMode").withArgs(true); const decentralizedModeAfter = await fathomBridge.isDecentralizedMode(); expect(decentralizedModeAfter).to.be.equal(true); }); @@ -122,9 +116,7 @@ describe("FathomBridge", () => { mockedAccessControlConfig.hasRole.returns(true); const feeBefore = await fathomBridge.fixedBridgeFee(); expect(feeBefore).to.be.equal(0); - await expect(fathomBridge.setFee(WeiPerRad)) - .to.be.emit(fathomBridge, "LogSetFee") - .withArgs(WeiPerRad); + await expect(fathomBridge.setFee(WeiPerRad)).to.be.emit(fathomBridge, "LogSetFee").withArgs(WeiPerRad); const feeAfter = await fathomBridge.fixedBridgeFee(); expect(feeAfter).to.be.equal(WeiPerRad); }); diff --git a/test/unit/flash-mint/FlashMintModule.test.js b/test/unit/flash-mint/FlashMintModule.test.js index fdd3dd14..1b00ceba 100644 --- a/test/unit/flash-mint/FlashMintModule.test.js +++ b/test/unit/flash-mint/FlashMintModule.test.js @@ -375,4 +375,4 @@ describe("FlashMintModule", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/unit/liquidation-strategies/FixedSpreadLiquidationStrategy.test.js b/test/unit/liquidation-strategies/FixedSpreadLiquidationStrategy.test.js index 1d9e4383..68ba82b3 100644 --- a/test/unit/liquidation-strategies/FixedSpreadLiquidationStrategy.test.js +++ b/test/unit/liquidation-strategies/FixedSpreadLiquidationStrategy.test.js @@ -232,12 +232,7 @@ describe("FixedSpreadLiquidationStrategy", () => { ) .returns(); mockedBookKeeper.moveCollateral - .whenCalledWith( - formatBytes32String("WXDC"), - fixedSpreadLiquidationStrategy.address, - DeployerAddress, - ethers.utils.parseEther("2.0375") - ) + .whenCalledWith(formatBytes32String("WXDC"), fixedSpreadLiquidationStrategy.address, DeployerAddress, ethers.utils.parseEther("2.0375")) .returns(); mockedBookKeeper.moveCollateral .whenCalledWith( @@ -429,4 +424,4 @@ describe("FixedSpreadLiquidationStrategy", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/unit/managers/PositionManager.test.js b/test/unit/managers/PositionManager.test.js index b4667044..ac42dc34 100644 --- a/test/unit/managers/PositionManager.test.js +++ b/test/unit/managers/PositionManager.test.js @@ -93,9 +93,7 @@ describe("PositionManager", () => { context("when collateral pool doesn't init", () => { it("should revert", async () => { mockedCollateralPoolConfig.getDebtAccumulatedRate.returns(0); - await expect(positionManager.open(formatBytes32String("WXDC"), AliceAddress)).to.be.revertedWith( - "PositionManager/collateralPool-not-init" - ); + await expect(positionManager.open(formatBytes32String("WXDC"), AliceAddress)).to.be.revertedWith("PositionManager/collateralPool-not-init"); }); }); context("when parameters are valid", () => { @@ -659,4 +657,4 @@ describe("PositionManager", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/unit/price-feeds/CentralizedOraclePriceFeed.test.js b/test/unit/price-feeds/CentralizedOraclePriceFeed.test.js index c75d387d..39a9617e 100644 --- a/test/unit/price-feeds/CentralizedOraclePriceFeed.test.js +++ b/test/unit/price-feeds/CentralizedOraclePriceFeed.test.js @@ -230,4 +230,4 @@ describe("CentralizedOraclePriceFeed", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/unit/price-oracles/DexPriceOracle.test.js b/test/unit/price-oracles/DexPriceOracle.test.js index dfd77140..484107eb 100644 --- a/test/unit/price-oracles/DexPriceOracle.test.js +++ b/test/unit/price-oracles/DexPriceOracle.test.js @@ -23,7 +23,7 @@ describe("DexPriceOracle", () => { mockedPair = await smock.fake("IFathomSwapPair"); mockedToken = await smock.fake("ERC20Mintable"); mockedUSD = await smock.fake("ERC20Mintable"); - + await dexPriceOracle.initialize(mockedFactory.address); }); diff --git a/test/unit/price-oracles/SlidingWindowDexOracle.test.js b/test/unit/price-oracles/SlidingWindowDexOracle.test.js index 46401148..2af82721 100644 --- a/test/unit/price-oracles/SlidingWindowDexOracle.test.js +++ b/test/unit/price-oracles/SlidingWindowDexOracle.test.js @@ -27,7 +27,7 @@ describe("SlidingWindowDexOracle", () => { mockedToken = await smock.fake("ERC20Mintable"); mockedUSD = await smock.fake("ERC20Mintable"); await slidingWindowDexOracle.initialize(mockedFactory.address, 900, 3); - + mockedToken.decimals.returns(18); mockedUSD.decimals.returns(18); }); diff --git a/test/unit/stablecoin-core/AdminControls.test.js b/test/unit/stablecoin-core/AdminControls.test.js index e0725f94..a050a78c 100644 --- a/test/unit/stablecoin-core/AdminControls.test.js +++ b/test/unit/stablecoin-core/AdminControls.test.js @@ -268,4 +268,4 @@ describe("AdminControls", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/unit/stablecoin-core/BookKeeper.test.js b/test/unit/stablecoin-core/BookKeeper.test.js index d9420d97..2c2c1096 100644 --- a/test/unit/stablecoin-core/BookKeeper.test.js +++ b/test/unit/stablecoin-core/BookKeeper.test.js @@ -1640,4 +1640,4 @@ describe("BookKeeper", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/unit/stablecoin-core/FathomStablecoin.test.js b/test/unit/stablecoin-core/FathomStablecoin.test.js index aac83564..7cee9575 100644 --- a/test/unit/stablecoin-core/FathomStablecoin.test.js +++ b/test/unit/stablecoin-core/FathomStablecoin.test.js @@ -276,4 +276,4 @@ describe("FathomStablecoin", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/unit/stablecoin-core/LiquidationEngine.test.js b/test/unit/stablecoin-core/LiquidationEngine.test.js index 3c0cd80e..3ad21bf0 100644 --- a/test/unit/stablecoin-core/LiquidationEngine.test.js +++ b/test/unit/stablecoin-core/LiquidationEngine.test.js @@ -350,4 +350,4 @@ describe("LiquidationEngine", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/unit/stablecoin-core/PriceOracle.test.js b/test/unit/stablecoin-core/PriceOracle.test.js index e0c8c9b4..cb48e43a 100644 --- a/test/unit/stablecoin-core/PriceOracle.test.js +++ b/test/unit/stablecoin-core/PriceOracle.test.js @@ -380,4 +380,4 @@ describe("PriceOracle", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/unit/stablecoin-core/ShowStopper.test.js b/test/unit/stablecoin-core/ShowStopper.test.js index 2d05485e..c2224dd6 100644 --- a/test/unit/stablecoin-core/ShowStopper.test.js +++ b/test/unit/stablecoin-core/ShowStopper.test.js @@ -279,9 +279,9 @@ describe("ShowStopper", () => { mockedBookKeeper.positions.returns([WeiPerRay, BigNumber.from("1")]); - await expect( - showStopper.redeemLockedCollateral(formatBytes32String("XDC"), DeployerAddress, DeployerAddress, "0x") - ).to.be.revertedWith("ShowStopper/debtShare-not-zero"); + await expect(showStopper.redeemLockedCollateral(formatBytes32String("XDC"), DeployerAddress, DeployerAddress, "0x")).to.be.revertedWith( + "ShowStopper/debtShare-not-zero" + ); }); }); @@ -291,9 +291,9 @@ describe("ShowStopper", () => { mockedBookKeeper.positions.returns([ethers.constants.MaxUint256, BigNumber.from("0")]); - await expect( - showStopper.redeemLockedCollateral(formatBytes32String("XDC"), DeployerAddress, DeployerAddress, "0x") - ).to.be.revertedWith("ShowStopper/overflow"); + await expect(showStopper.redeemLockedCollateral(formatBytes32String("XDC"), DeployerAddress, DeployerAddress, "0x")).to.be.revertedWith( + "ShowStopper/overflow" + ); }); }); @@ -734,4 +734,4 @@ describe("ShowStopper", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/unit/stablecoin-core/StabilityFeeCollector.test.js b/test/unit/stablecoin-core/StabilityFeeCollector.test.js index 84d1e503..6785be76 100644 --- a/test/unit/stablecoin-core/StabilityFeeCollector.test.js +++ b/test/unit/stablecoin-core/StabilityFeeCollector.test.js @@ -192,4 +192,4 @@ describe("StabilityFeeCollector", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/unit/stablecoin-core/StableSwapModuleWrapper.test.js b/test/unit/stablecoin-core/StableSwapModuleWrapper.test.js index b5009dfd..80adeac7 100644 --- a/test/unit/stablecoin-core/StableSwapModuleWrapper.test.js +++ b/test/unit/stablecoin-core/StableSwapModuleWrapper.test.js @@ -66,7 +66,7 @@ describe("StableSwapModuleWrapper", () => { stableSwapModule = await StableSwapModule.deploy(); await stableSwapModule.deployed(); stableSwapModuleAsAlice = stableSwapModule.connect(provider.getSigner(AliceAddress)); - + const StableSwapModuleWrapper = await ethers.getContractFactory("MockStableSwapModuleWrapper"); stableSwapModuleWrapper = await StableSwapModuleWrapper.deploy(); await stableSwapModuleWrapper.deployed(); @@ -81,7 +81,7 @@ describe("StableSwapModuleWrapper", () => { numberOfSwapsLimitPerUser, blocksPerLimit ); - + await stableSwapModuleWrapper.initialize(mockBookKeeper.address, stableSwapModule.address); await stableSwapModule.addToWhitelist(DeployerAddress); diff --git a/test/unit/stablecoin-core/SystemDebtEngine.test.js b/test/unit/stablecoin-core/SystemDebtEngine.test.js index 9bf57945..290cff0e 100644 --- a/test/unit/stablecoin-core/SystemDebtEngine.test.js +++ b/test/unit/stablecoin-core/SystemDebtEngine.test.js @@ -295,4 +295,4 @@ describe("SystemDebtEngine", () => { }); }); }); -}); \ No newline at end of file +});