From c2600b5e0ef8e83d47c70f3f07563453b003b34a Mon Sep 17 00:00:00 2001 From: Mikhailo Shabodyash <67977488+EviLord032@users.noreply.github.com> Date: Wed, 8 May 2024 14:29:55 +0300 Subject: [PATCH 01/19] feat: usdt market on polygon --- .github/workflows/run-scenarios.yaml | 2 +- deployments/polygon/usdt/configuration.json | 58 ++++ deployments/polygon/usdt/deploy.ts | 42 +++ .../1713283675_configurate_and_ens.ts | 291 ++++++++++++++++++ deployments/polygon/usdt/relations.ts | 17 + deployments/polygon/usdt/roots.json | 1 + hardhat.config.ts | 10 +- plugins/import/import.ts | 50 ++- scenario/AddMaticxCollateralScenario.ts | 5 +- scenario/BulkerScenario.ts | 2 + scenario/LiquidationBotScenario.ts | 40 ++- .../liquidateUnderwaterBorrowers.ts | 7 +- src/deploy/index.ts | 11 +- 13 files changed, 498 insertions(+), 38 deletions(-) create mode 100644 deployments/polygon/usdt/configuration.json create mode 100644 deployments/polygon/usdt/deploy.ts create mode 100644 deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts create mode 100644 deployments/polygon/usdt/relations.ts create mode 100644 deployments/polygon/usdt/roots.json diff --git a/.github/workflows/run-scenarios.yaml b/.github/workflows/run-scenarios.yaml index 7c551a883..604306d9b 100644 --- a/.github/workflows/run-scenarios.yaml +++ b/.github/workflows/run-scenarios.yaml @@ -7,7 +7,7 @@ jobs: strategy: fail-fast: false matrix: - bases: [ development, mainnet, mainnet-weth, goerli, goerli-weth, sepolia-usdc, sepolia-weth, fuji, mumbai, polygon, arbitrum-usdc.e, arbitrum-usdc, arbitrum-goerli-usdc, arbitrum-goerli-usdc.e, base-usdbc, base-weth, base-usdc, base-goerli, base-goerli-weth, linea-goerli, optimism-usdc, scroll-goerli, scroll-usdc] + bases: [ development, mainnet, mainnet-weth, goerli, goerli-weth, sepolia-usdc, sepolia-weth, fuji, mumbai, polygon, polygon-usdt, arbitrum-usdc.e, arbitrum-usdc, arbitrum-goerli-usdc, arbitrum-goerli-usdc.e, base-usdbc, base-weth, base-usdc, base-goerli, base-goerli-weth, linea-goerli, optimism-usdc, scroll-goerli, scroll-usdc] name: Run scenarios env: ETHERSCAN_KEY: ${{ secrets.ETHERSCAN_KEY }} diff --git a/deployments/polygon/usdt/configuration.json b/deployments/polygon/usdt/configuration.json new file mode 100644 index 000000000..e12d1ec54 --- /dev/null +++ b/deployments/polygon/usdt/configuration.json @@ -0,0 +1,58 @@ +{ + "name": "Compound USDT", + "symbol": "cUSDTv3", + "baseToken": "USDT", + "baseTokenAddress": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F", + "baseTokenPriceFeed": "0x0A6513e40db6EB1b165753AD52E80663aeA50545", + "borrowMin": "100e6", + "governor": "0xCC3E7c85Bb0EE4f09380e041fee95a0caeDD4a02", + "pauseGuardian": "0x8Ab717CAC3CbC4934E63825B88442F5810aAF6e5", + "storeFrontPriceFactor": 0.6, + "targetReserves": "20000000e6", + "rates": { + "supplyKink": 0.9, + "supplySlopeLow": 0.075, + "supplySlopeHigh": 3.6, + "supplyBase": 0, + "borrowKink": 0.9, + "borrowSlopeLow": 0.0833, + "borrowSlopeHigh": 4.3, + "borrowBase": 0.015 + }, + "tracking": { + "indexScale": "1e15", + "baseSupplySpeed": "0e15", + "baseBorrowSpeed": "0e15", + "baseMinForRewards": "1000000e6" + }, + "rewardTokenAddress": "0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c", + "assets": { + "WETH": { + "address": "0x7ceb23fd6bc0add59e62ac25578270cff1b9f619", + "priceFeed": "0xF9680D99D6C9589e2a93a78A04A279e509205945", + "decimals": "18", + "borrowCF": 0.80, + "liquidateCF": 0.85, + "liquidationFactor": 0.95, + "supplyCap": "0e18" + }, + "WMATIC": { + "address": "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", + "priceFeed": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", + "decimals": "18", + "borrowCF": 0.65, + "liquidateCF": 0.80, + "liquidationFactor": 0.85, + "supplyCap": "0e18" + }, + "WBTC": { + "address": "0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6", + "priceFeed": "0xDE31F8bFBD8c84b5360CFACCa3539B938dd78ae6", + "decimals": "8", + "borrowCF": 0.75, + "liquidateCF": 0.85, + "liquidationFactor": 0.90, + "supplyCap": "0e8" + } + } +} \ No newline at end of file diff --git a/deployments/polygon/usdt/deploy.ts b/deployments/polygon/usdt/deploy.ts new file mode 100644 index 000000000..c80b426ce --- /dev/null +++ b/deployments/polygon/usdt/deploy.ts @@ -0,0 +1,42 @@ +import { Deployed, DeploymentManager } from '../../../plugins/deployment_manager'; +import { DeploySpec, deployComet } from '../../../src/deploy'; + +const HOUR = 60 * 60; +const DAY = 24 * HOUR; + +const MAINNET_TIMELOCK = '0x6d903f6003cca6255d85cca4d3b5e5146dc33925'; + +export default async function deploy(deploymentManager: DeploymentManager, deploySpec: DeploySpec): Promise { + const trace = deploymentManager.tracer() + const ethers = deploymentManager.hre.ethers; + + // pull in existing assets + const USDT = await deploymentManager.existing('USDT', '0xc2132D05D31c914a87C6611C10748AEb04B58e8F', 'polygon'); + const WBTC = await deploymentManager.existing('WBTC', '0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6', 'polygon'); + const WETH = await deploymentManager.existing('WETH', '0x7ceb23fd6bc0add59e62ac25578270cff1b9f619', 'polygon'); + const WMATIC = await deploymentManager.existing('WMATIC', '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270', 'polygon'); + const COMP = await deploymentManager.existing('COMP', '0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c', 'polygon'); + + const fxChild = await deploymentManager.existing('fxChild', '0x8397259c983751DAf40400790063935a11afa28a', 'polygon'); + + const cometAdmin = await deploymentManager.fromDep('cometAdmin', 'polygon', 'usdc'); + const cometFactory = await deploymentManager.fromDep('cometFactory', 'polygon', 'usdc'); + const $configuratorImpl = await deploymentManager.fromDep('configurator:implementation', 'polygon', 'usdc'); + const configurator = await deploymentManager.fromDep('configurator', 'polygon', 'usdc'); + const rewards = await deploymentManager.fromDep('rewards', 'polygon', 'usdc'); + const bulker = await deploymentManager.fromDep('bulker', 'polygon', 'usdc'); + const localTimelock = await deploymentManager.fromDep('timelock', 'polygon', 'usdc'); + const bridgeReceiver = await deploymentManager.fromDep('bridgeReceiver', 'polygon', 'usdc'); + + // Deploy Comet + const deployed = await deployComet(deploymentManager, deploySpec); + + return { + ...deployed, + bridgeReceiver, + bulker, + fxChild, + rewards, + COMP + }; +} \ No newline at end of file diff --git a/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts new file mode 100644 index 000000000..76f39e403 --- /dev/null +++ b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts @@ -0,0 +1,291 @@ +import { Contract, ethers } from 'ethers'; +import { DeploymentManager } from '../../../../plugins/deployment_manager/DeploymentManager'; +import { migration } from '../../../../plugins/deployment_manager/Migration'; +import { calldata, exp, getConfigurationStruct, proposal } from '../../../../src/deploy'; +import { expect } from 'chai'; + +const ENSName = 'compound-community-licenses.eth'; +const ENSResolverAddress = '0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41'; +const ENSRegistryAddress = '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e'; +const ENSSubdomainLabel = 'v3-additional-grants'; +const ENSSubdomain = `${ENSSubdomainLabel}.${ENSName}`; +const ENSTextRecordKey = 'v3-official-markets'; + +const ERC20PredicateAddress = '0x40ec5B33f54e0E8A33A975908C5BA1c14e5BbbDf'; +const RootChainManagerAddress = '0xA0c68C638235ee32657e8f720a23ceC1bFc77C77'; + +const mainnetUSDTAddress = '0xdac17f958d2ee523a2206206994597c13d831ec7'; +const polygonCOMPAddress = '0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c'; +const cUSDTAddress = '0xf650c3d88d12db855b8bf7d11be6c55a4e07dcc9'; + +const USDTAmountToBridge = ethers.BigNumber.from(exp(10_000, 6)); + +export default migration('1713283675_configurate_and_ens', { + prepare: async (_deploymentManager: DeploymentManager) => { + return {}; + }, + + enact: async (deploymentManager: DeploymentManager, govDeploymentManager: DeploymentManager) => { + console.log('Enacting 1713283675_configurate_and_ens'); + const trace = deploymentManager.tracer(); + const ethers = deploymentManager.hre.ethers; + const { utils } = ethers; + + const cometFactory = await deploymentManager.fromDep('cometFactory', 'polygon', 'usdc'); + const { + bridgeReceiver, + comet, + cometAdmin, + configurator, + rewards, + USDT, + WBTC, + WETH, + WMATIC + } = await deploymentManager.getContracts(); + + const { + fxRoot, + timelock, + governor + } = await govDeploymentManager.getContracts(); + // console.log(await govDeploymentManager.getContracts()); + const configuration = await getConfigurationStruct(deploymentManager); + const setFactoryCalldata = await calldata( + configurator.populateTransaction.setFactory(comet.address, cometFactory.address) + ); + const setConfigurationCalldata = await calldata( + configurator.populateTransaction.setConfiguration(comet.address, configuration) + ); + const deployAndUpgradeToCalldata = utils.defaultAbiCoder.encode( + ['address', 'address'], + [configurator.address, comet.address] + ); + + const setRewardConfigCalldata = utils.defaultAbiCoder.encode( + ['address', 'address'], + [comet.address, polygonCOMPAddress] + ); + + const l2ProposalData = utils.defaultAbiCoder.encode( + ['address[]', 'uint256[]', 'string[]', 'bytes[]'], + [ + [configurator.address, configurator.address, cometAdmin.address, rewards.address], + [0, 0, 0, 0], + [ + 'setFactory(address,address)', + 'setConfiguration(address,(address,address,address,address,address,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint104,uint104,uint104,(address,address,uint8,uint64,uint64,uint64,uint128)[]))', + 'deployAndUpgradeTo(address,address)', + 'setRewardConfig(address,address)' + ], + [setFactoryCalldata, setConfigurationCalldata, deployAndUpgradeToCalldata, setRewardConfigCalldata] + ] + ); + + const ENSResolver = await govDeploymentManager.existing('ENSResolver', ENSResolverAddress); + const subdomainHash = ethers.utils.namehash(ENSSubdomain); + const polygonChainId = (await deploymentManager.hre.ethers.provider.getNetwork()).chainId.toString(); + const newMarketObject = { baseSymbol: 'USDT', cometAddress: comet.address }; + const officialMarketsJSON = JSON.parse(await ENSResolver.text(subdomainHash, ENSTextRecordKey)); + + if (officialMarketsJSON[polygonChainId]) { + officialMarketsJSON[polygonChainId].push(newMarketObject); + } else { + officialMarketsJSON[polygonChainId] = [newMarketObject]; + } + + const RootChainManager = await deploymentManager.existing( + 'RootChainManager', + RootChainManagerAddress + ); + const USDTMainnet = new Contract( + mainnetUSDTAddress, + [ + 'function balanceOf(address account) external view returns (uint256)', + 'function approve(address,uint256) external' + ], + govDeploymentManager.hre.ethers.provider + ); + + const depositUSDTData = utils.defaultAbiCoder.encode(['uint256'], [USDTAmountToBridge]); + const depositForUSDTCalldata = utils.defaultAbiCoder.encode( + ['address', 'address', 'bytes'], + [comet.address, USDTMainnet.address, depositUSDTData] + ); + const notEnoughUSDT = (await USDTMainnet.balanceOf(timelock.address)).lt(USDTAmountToBridge); + const amountToSupply = notEnoughUSDT ? USDTAmountToBridge.sub(await USDTMainnet.balanceOf(timelock.address)) : 0; + const _reduceReservesCalldata = utils.defaultAbiCoder.encode( + ['uint256'], + [amountToSupply] + ); + const addinionalAction = { + target: cUSDTAddress, + signature: '_reduceReserves(uint256)', + calldata: _reduceReservesCalldata + }; + + const mainnetActions = [ + // 1. Set Comet configuration and deployAndUpgradeTo new Comet on Polygon. + { + contract: fxRoot, + signature: 'sendMessageToChild(address,bytes)', + args: [bridgeReceiver.address, l2ProposalData] + }, + // 2. Approve Polygon's ERC20Predicate to take Timelock's USDT (for bridging) + { + contract: USDTMainnet, + signature: 'approve(address,uint256)', + args: [ERC20PredicateAddress, USDTAmountToBridge] + }, + // 3. Bridge USDT from mainnet to Polygon Comet using RootChainManager + { + target: RootChainManager.address, + signature: 'depositFor(address,address,bytes)', + calldata: depositForUSDTCalldata + }, + // 4. Update the list of official markets + { + target: ENSResolverAddress, + signature: 'setText(bytes32,string,string)', + calldata: ethers.utils.defaultAbiCoder.encode( + ['bytes32', 'string', 'string'], + [subdomainHash, ENSTextRecordKey, JSON.stringify(officialMarketsJSON)] + ) + } + ]; + + // add new action between 1 and 2 + if (notEnoughUSDT) { + mainnetActions.splice(2, 0, addinionalAction); + } + + const description = "# Initialize cUSDCv3 on Polygon\n\nThis proposal takes the governance steps recommended and necessary to initialize a Compound III USDC market on Polygon; upon execution, cUSDCv3 will be ready for use. Simulations have confirmed the market\u2019s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). Although real tests have also been run over the Goerli/Mumbai bridge, this will be the first proposal to actually bridge from Ethereum mainnet to another chain, and therefore includes risks not present in previous proposals.\n\nAlthough the proposal sets the entire configuration in the Configurator, the initial deployment already has most of these same parameters already set. The new parameters include setting the pause guardian to a Gnosis [multisig](https://app.safe.global/matic:0x8Ab717CAC3CbC4934E63825B88442F5810aAF6e5/home), which has been created on Polygon to match the same set of signers as currently on Ethereum mainnet. They also include risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/initialize-compound-iii-usdc-on-polygon-pos/3611/12). Finally, the parameters include a modest reallocation of some of the v2 USDT COMP rewards to borrowers in the new market.\n\nFurther detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/672) and [forum discussion](https://www.comp.xyz/t/initialize-compound-iii-usdc-on-polygon-pos/3611/11).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Polygon. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Polygon.\n\nThe second action approves Polygon's ERC20Predicate to take Timelock's USDC, in order to seed the market reserves through the bridge.\n\nThe third action deposits USDC from mainnet to the Polygon RootChainManager contract to bridge to Comet.\n\nThe fourth action approves Polygon's ERC20Predicate to take Timelock's COMP, in order to seed the rewards contract through the bridge.\n\nThe fifth action deposits COMP from mainnet to the Polygon RootChainManager contract to bridge to CometRewards. \n\nThe sixth action sets up the ENS subdomain `v3-additional-grants.compound-community-licenses.eth`, with the Timelock as the owner.\n\nThe seventh action writes the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, containing the official markets JSON.\n\nThe eighth action migrates the COMP distribution for v2 cUSDT suppliers, so as to keep the total COMP distribution constant.\n"; + const txn = await govDeploymentManager.retry(async () => + trace(await governor.propose(...(await proposal(mainnetActions, description)))) + ); + + const event = txn.events.find(event => event.event === 'ProposalCreated'); + const [proposalId] = event.args; + + trace(`Created proposal ${proposalId}.`); + }, + + async enacted(deploymentManager: DeploymentManager): Promise { + return false; + }, + + async verify(deploymentManager: DeploymentManager, govDeploymentManager: DeploymentManager) { + const ethers = deploymentManager.hre.ethers; + + const { + comet, + rewards, + WBTC, + WETH, + WMATIC + } = await deploymentManager.getContracts(); + + const { + timelock, + comptrollerV2, + } = await govDeploymentManager.getContracts(); + + // 1. + const wbtcInfo = await comet.getAssetInfoByAddress(WBTC.address); + const wethInfo = await comet.getAssetInfoByAddress(WETH.address); + const wmaticInfo = await comet.getAssetInfoByAddress(WMATIC.address); + // expect(wbtcInfo.supplyCap).to.be.eq(exp(400, 8)); + // expect(wethInfo.supplyCap).to.be.eq(exp(11_000, 18)); + // expect(wmaticInfo.supplyCap).to.be.eq(exp(10_000_000, 18)); + expect(await comet.pauseGuardian()).to.be.eq('0x8Ab717CAC3CbC4934E63825B88442F5810aAF6e5'); + + // 2. & 3. + expect(await comet.getReserves()).to.be.equal(USDTAmountToBridge); + + // 4. & 5. + const polygonCOMP = new Contract( + '0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c', + ['function balanceOf(address account) external view returns (uint256)'], + deploymentManager.hre.ethers.provider + ); + expect((await polygonCOMP.balanceOf(rewards.address)).gt(exp(2_500, 18))).to.be.true; + + // 6. & 7. + const ENSResolver = await govDeploymentManager.existing('ENSResolver', ENSResolverAddress); + const ENSRegistry = await govDeploymentManager.existing('ENSRegistry', ENSRegistryAddress); + const subdomainHash = ethers.utils.namehash(ENSSubdomain); + const officialMarketsJSON = await ENSResolver.text(subdomainHash, ENSTextRecordKey); + const officialMarkets = JSON.parse(officialMarketsJSON); + expect(await ENSRegistry.recordExists(subdomainHash)).to.be.equal(true); + expect(await ENSRegistry.owner(subdomainHash)).to.be.equal(timelock.address); + expect(await ENSRegistry.resolver(subdomainHash)).to.be.equal(ENSResolverAddress); + expect(await ENSRegistry.ttl(subdomainHash)).to.be.equal(0); + expect(officialMarkets).to.deep.equal({ + 1: [ + { + baseSymbol: 'USDC', + cometAddress: '0xc3d688B66703497DAA19211EEdff47f25384cdc3', + }, + { + baseSymbol: 'WETH', + cometAddress: '0xA17581A9E3356d9A858b789D68B4d866e593aE94', + }, + // should be changed after soon to be PR + // { + // baseSymbol: 'WETH', + // cometAddress: comet.address, + // }, + ], + 137: [ + { + baseSymbol: 'USDC', + cometAddress: '0xF25212E676D1F7F89Cd72fFEe66158f541246445', + }, + { + baseSymbol: 'USDT', + cometAddress: comet.address, + }, + ], + 8453: [ + { + baseSymbol: 'USDbC', + cometAddress: '0x9c4ec768c28520B50860ea7a15bd7213a9fF58bf', + }, + { + baseSymbol: 'WETH', + cometAddress: '0x46e6b214b524310239732D51387075E0e70970bf', + }, + { + baseSymbol: 'USDC', + cometAddress: '0xb125E6687d4313864e53df431d5425969c15Eb2F', + }, + ], + 42161: [ + { + baseSymbol: 'USDC.e', + cometAddress: '0xA5EDBDD9646f8dFF606d7448e414884C7d905dCA', + }, + { + baseSymbol: 'USDC', + cometAddress: '0x9c4ec768c28520B50860ea7a15bd7213a9fF58bf', + }, + ], + 534352: [ + { + baseSymbol: 'USDC', + cometAddress: '0xB2f97c1Bd3bf02f5e74d13f02E3e26F93D77CE44', + }, + ], + 10: [ + { + baseSymbol: 'USDC', + cometAddress: '0x2e44e174f7D53F0212823acC11C01A11d58c5bCB', + }, + ], + }); + + // 8. + // expect(await comet.baseTrackingSupplySpeed()).to.be.equal(0); + // expect(await comet.baseTrackingBorrowSpeed()).to.be.equal(exp(34.74 / 86400, 15, 18)); + } +}); diff --git a/deployments/polygon/usdt/relations.ts b/deployments/polygon/usdt/relations.ts new file mode 100644 index 000000000..3b92711b1 --- /dev/null +++ b/deployments/polygon/usdt/relations.ts @@ -0,0 +1,17 @@ +import { RelationConfigMap } from '../../../plugins/deployment_manager/RelationConfig'; +import baseRelationConfig from '../../relations'; + +export default { + ...baseRelationConfig, + 'governor': { + artifact: 'contracts/bridges/polygon/PolygonBridgeReceiver.sol:PolygonBridgeReceiver', + }, + UChildERC20Proxy: { + artifact: 'contracts/ERC20.sol:ERC20', + delegates: { + field: { + slot: '0xbaab7dbf64751104133af04abc7d9979f0fda3b059a322a8333f533d3f32bf7f', + } + } + } +}; \ No newline at end of file diff --git a/deployments/polygon/usdt/roots.json b/deployments/polygon/usdt/roots.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/deployments/polygon/usdt/roots.json @@ -0,0 +1 @@ +{} diff --git a/hardhat.config.ts b/hardhat.config.ts index 284c8cb5c..1c4280a46 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -26,6 +26,7 @@ import mumbaiRelationConfigMap from './deployments/mumbai/usdc/relations'; import mainnetRelationConfigMap from './deployments/mainnet/usdc/relations'; import mainnetWethRelationConfigMap from './deployments/mainnet/weth/relations'; import polygonRelationConfigMap from './deployments/polygon/usdc/relations'; +import polygonUsdtRelationConfigMap from './deployments/polygon/usdt/relations'; import arbitrumBridgedUsdcRelationConfigMap from './deployments/arbitrum/usdc.e/relations'; import arbitrumNativeUsdcRelationConfigMap from './deployments/arbitrum/usdc/relations'; import arbitrumBridgedUsdcGoerliRelationConfigMap from './deployments/arbitrum-goerli/usdc.e/relations'; @@ -349,7 +350,8 @@ const config: HardhatUserConfig = { weth: mainnetWethRelationConfigMap }, polygon: { - usdc: polygonRelationConfigMap + usdc: polygonRelationConfigMap, + usdt: polygonUsdtRelationConfigMap }, arbitrum: { 'usdc.e': arbitrumBridgedUsdcRelationConfigMap, @@ -438,6 +440,12 @@ const config: HardhatUserConfig = { deployment: 'usdc', auxiliaryBase: 'mainnet' }, + { + name: 'polygon-usdt', + network: 'polygon', + deployment: 'usdt', + auxiliaryBase: 'mainnet' + }, { name: 'arbitrum-usdc.e', network: 'arbitrum', diff --git a/plugins/import/import.ts b/plugins/import/import.ts index 05e2a2bf5..48eaf6f70 100644 --- a/plugins/import/import.ts +++ b/plugins/import/import.ts @@ -83,36 +83,12 @@ async function getEtherscanApiData(network: string, address: string, apiKey: str }; } -async function scrapeContractCreationCodeFromEtherscanApi(network: string, address: string) { - const params = { - module: 'proxy', - action: 'eth_getCode', - address, - apikey: getEtherscanApiKey(network) - }; - const url = `${getEtherscanApiUrl(network)}?${paramString(params)}`; - const debugUrl = `${getEtherscanApiUrl(network)}?${paramString({ ...params, ...{ apikey: '[API_KEY]'}})}`; - - debug(`Attempting to pull Contract Creation code from API at ${debugUrl}`); - const result = await get(url, {}); - const contractCreationCode = result.result; - if (!contractCreationCode) { - throw new Error(`Unable to find Contract Creation code from API at ${debugUrl}`); - } - debug(`Creation Code found in first tx at ${debugUrl}`); - return contractCreationCode.slice(2); -} - -/** - * @description Does not work for 0x566511a1A09561e2896F8c0fD77E8544E59bFDB0 as etherscan starts using some firewall - */ async function scrapeContractCreationCodeFromEtherscan(network: string, address: string) { const url = `${getEtherscanUrl(network)}/address/${address}#code`; debug(`Attempting to scrape Contract Creation code at ${url}`); const result = await get(url, {}); const regex = /
[\s\r\n]*([0-9a-fA-F]*)[\s\r\n]*<\/div>/g; - const regexDoubleQuotes = /
[\s\r\n]*([0-9a-fA-F]*)[\s\r\n]*<\/div>/g; - const matches = [...result.matchAll(regex), ...result.matchAll(regexDoubleQuotes)]; + const matches = [...result.matchAll(regex)]; if (matches.length === 0) { if (result.match(/request throttled/i) || result.match(/try again later/i)) { throw new Error(`Request throttled: ${url}`); @@ -153,11 +129,31 @@ async function pullFirstTransactionForContract(network: string, address: string) return contractCreationCode.slice(2); } +async function scrapeContractCreationCodeFromEtherscanApi(network: string, address: string) { + const params = { + module: 'proxy', + action: 'eth_getCode', + address, + apikey: getEtherscanApiKey(network) + }; + const url = `${getEtherscanApiUrl(network)}?${paramString(params)}`; + const debugUrl = `${getEtherscanApiUrl(network)}?${paramString({ ...params, ...{ apikey: '[API_KEY]'}})}`; + + debug(`Attempting to pull Contract Creation code from API at ${debugUrl}`); + const result = await get(url, {}); + const contractCreationCode = result.result; + if (!contractCreationCode) { + throw new Error(`Unable to find Contract Creation code from API at ${debugUrl}`); + } + debug(`Creation Code found in first tx at ${debugUrl}`); + return contractCreationCode.slice(2); +} + async function getContractCreationCode(network: string, address: string) { const strategies = [ scrapeContractCreationCodeFromEtherscan, scrapeContractCreationCodeFromEtherscanApi, - pullFirstTransactionForContract, + pullFirstTransactionForContract ]; let errors = []; for (const strategy of strategies) { @@ -256,4 +252,4 @@ export async function loadEtherscanContract(network: string, address: string) { }; return contractBuild; -} +} \ No newline at end of file diff --git a/scenario/AddMaticxCollateralScenario.ts b/scenario/AddMaticxCollateralScenario.ts index b28f1aabd..a5ef14569 100644 --- a/scenario/AddMaticxCollateralScenario.ts +++ b/scenario/AddMaticxCollateralScenario.ts @@ -9,7 +9,8 @@ import { createCrossChainProposal, matchesDeployment } from './utils'; const MATICX_ADDRESS = '0xfa68FB4628DFF1028CFEc22b4162FCcd0d45efb6'; const MATICX_PRICE_FEED_ADDRESS = '0x5d37E4b374E6907de8Fc7fb33EE3b0af403C7403'; const MATICX_WHALES = { - polygon: ['0x68B9220B8E617b7700aCAE1a5Ff43F3eb29257F3'], + polygon: [ + '0x54d983f6A163d7e8b2363CDb41FE2E568B8766aD'], }; // TODO: add ability to run ad hoc scenarios against a single migration, to avoid needing the scenario to do all this setup of @@ -32,7 +33,7 @@ scenario( const maticx = await dm.existing( 'MATICX', MATICX_ADDRESS, - context.world.base.network, + '', 'contracts/ERC20.sol:ERC20' ); const maticxPricefeed = await dm.existing( diff --git a/scenario/BulkerScenario.ts b/scenario/BulkerScenario.ts index 91e2608f8..5b1ec82ae 100644 --- a/scenario/BulkerScenario.ts +++ b/scenario/BulkerScenario.ts @@ -5,6 +5,7 @@ import { expectBase, isRewardSupported, isBulkerSupported, getExpectedBaseBalanc import { exp } from '../test/helpers'; // XXX properly handle cases where asset0 is WETH +// TODO: should properly handle cases where asset1 isn't WETH (wrapped native token) scenario( 'Comet#bulker > (non-WETH base) all non-reward actions in one txn', { @@ -165,6 +166,7 @@ scenario( filter: async (ctx) => await isBulkerSupported(ctx) && await isRewardSupported(ctx) && !matchesDeployment(ctx, [{deployment: 'weth'}, { network: 'linea-goerli' }]), supplyCaps: { $asset0: 3000, + $asset1: 3000, }, tokenBalances: { albert: { $base: '== 1000000', $asset0: 3000 }, diff --git a/scenario/LiquidationBotScenario.ts b/scenario/LiquidationBotScenario.ts index 763468c9e..d708df060 100644 --- a/scenario/LiquidationBotScenario.ts +++ b/scenario/LiquidationBotScenario.ts @@ -95,7 +95,8 @@ for (let i = 0; i < MAX_ASSETS; i++) { weth: 20 }, polygon: { - usdc: 2250000 + usdc: 2250000, + usdt: 2250000 }, arbitrum: { 'usdc.e': 10000000, @@ -134,6 +135,16 @@ for (let i = 0; i < MAX_ASSETS; i++) { // MATICX ' == 0', ], + usdt: [ + // WETH + ' == 400', + // WBTC + ' == 20', + // WMATIC + ' == 300000', + // MATICX + ' == 0', + ], }, arbitrum: { 'usdc.e': [ @@ -280,7 +291,8 @@ for (let i = 0; i < MAX_ASSETS; i++) { weth: 5000 }, polygon: { - usdc: 3000000 + usdc: 3000000, + usdt: 3000000 }, arbitrum: { 'usdc.e': 10000000, @@ -318,6 +330,16 @@ for (let i = 0; i < MAX_ASSETS; i++) { ' == 2500000', // MATICX ' == 0', + ], + usdt: [ + // WETH + ' == 1000', + // WBTC + ' == 100', + // WMATIC + ' == 2500000', + // MATICX + ' == 0', ] }, arbitrum: { @@ -374,6 +396,16 @@ for (let i = 0; i < MAX_ASSETS; i++) { exp(5000, 18), // MATICX exp(5, 18) + ], + usdt: [ + // WETH + exp(400, 18), + // WBTC + exp(20, 8), + // WMATIC + exp(5000, 18), + // MATICX + exp(5, 18) ] }, arbitrum: { @@ -512,7 +544,7 @@ scenario( { filter: async (ctx) => matchesDeployment(ctx, [{network: 'mainnet'}, {network: 'polygon'}, {network: 'arbitrum'}]), tokenBalances: { - $comet: { $base: 100000 }, + $comet: { $base: 1000000 }, }, cometBalances: { albert: { @@ -623,7 +655,7 @@ scenario( { filter: async (ctx) => matchesDeployment(ctx, [{network: 'mainnet'}, {network: 'polygon'}, {network: 'arbitrum'}]), tokenBalances: { - $comet: { $base: 100000 }, + $comet: { $base: 1000000 }, }, cometBalances: { albert: { diff --git a/scripts/liquidation_bot/liquidateUnderwaterBorrowers.ts b/scripts/liquidation_bot/liquidateUnderwaterBorrowers.ts index d073fb587..ab1b4d8af 100644 --- a/scripts/liquidation_bot/liquidateUnderwaterBorrowers.ts +++ b/scripts/liquidation_bot/liquidateUnderwaterBorrowers.ts @@ -70,7 +70,8 @@ const liquidationThresholds = { 'usdc': 10e6 }, polygon: { - 'usdc': 10e6 + 'usdc': 10e6, + 'usdt': 10e6 }, arbitrum: { 'usdc.e': 10e6, @@ -99,6 +100,10 @@ export const flashLoanPools = { usdc: { tokenAddress: addresses.polygon.BOB, poolFee: 100 + }, + usdt: { + tokenAddress: addresses.polygon.WBTC, + poolFee: 500 } }, arbitrum: { diff --git a/src/deploy/index.ts b/src/deploy/index.ts index 209bfff19..21ad50dfb 100644 --- a/src/deploy/index.ts +++ b/src/deploy/index.ts @@ -77,7 +77,13 @@ export const COMP_WHALES = { '0x54A37d93E57c5DA659F508069Cf65A381b61E189' ], - testnet: ['0xbbfe34e868343e6f4f5e8b5308de980d7bd88c46'] + testnet: ['0xbbfe34e868343e6f4f5e8b5308de980d7bd88c46'], + + polygon: [ + '0x52A258ED593C793251a89bfd36caE158EE9fC4F8', + '0xdE5167C19A5286889752Cb0f31a1c7f28A99feFB', + '0xC35D800aD559c481dDa73D0b89dbC12774945512' + ], }; export const WHALES = { @@ -93,7 +99,8 @@ export const WHALES = { polygon: [ '0x2093b4281990a568c9d588b8bce3bfd7a1557ebd', // WETH whale '0xd814b26554204245a30f8a42c289af582421bf04', // WBTC whale - '0x167384319b41f7094e62f7506409eb38079abff8' // WMATIC whale + '0x167384319b41f7094e62f7506409eb38079abff8', // WMATIC whale + '0xF977814e90dA44bFA03b6295A0616a897441aceC' ], arbitrum: [ '0xf89d7b9c864f589bbf53a82105107622b35eaa40', // USDC whale From 97d970425768267ba72a02ac6a997450178acccf Mon Sep 17 00:00:00 2001 From: Mikhailo Shabodyash <67977488+EviLord032@users.noreply.github.com> Date: Wed, 8 May 2024 16:10:10 +0300 Subject: [PATCH 02/19] fix: temporary remove pre-failed proposals --- scenario/AddMaticxCollateralScenario.ts | 2 +- scenario/constraints/ProposalConstraint.ts | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/scenario/AddMaticxCollateralScenario.ts b/scenario/AddMaticxCollateralScenario.ts index a5ef14569..b006506be 100644 --- a/scenario/AddMaticxCollateralScenario.ts +++ b/scenario/AddMaticxCollateralScenario.ts @@ -10,7 +10,7 @@ const MATICX_ADDRESS = '0xfa68FB4628DFF1028CFEc22b4162FCcd0d45efb6'; const MATICX_PRICE_FEED_ADDRESS = '0x5d37E4b374E6907de8Fc7fb33EE3b0af403C7403'; const MATICX_WHALES = { polygon: [ - '0x54d983f6A163d7e8b2363CDb41FE2E568B8766aD'], + '0x1e5b92c66e4CAd7963E8dAcF1E8D642304C172C8'], }; // TODO: add ability to run ad hoc scenarios against a single migration, to avoid needing the scenario to do all this setup of diff --git a/scenario/constraints/ProposalConstraint.ts b/scenario/constraints/ProposalConstraint.ts index 83e5c967d..c8aeffbf0 100644 --- a/scenario/constraints/ProposalConstraint.ts +++ b/scenario/constraints/ProposalConstraint.ts @@ -66,11 +66,13 @@ export class ProposalConstraint implements StaticConstra // Execute the proposal debug(`${label} Processing pending proposal ${proposal.id}`); if (isBridged) { - await executeOpenProposalAndRelay( - governanceDeploymentManager, - ctx.world.deploymentManager, - proposal - ); + if(![246, 247].includes(proposal.id.toNumber())){ + await executeOpenProposalAndRelay( + governanceDeploymentManager, + ctx.world.deploymentManager, + proposal + ); + } } else { await executeOpenProposal(governanceDeploymentManager, proposal); } From 90e34bf98b0e79f9aeeb3512b8bb3673758cd86b Mon Sep 17 00:00:00 2001 From: Mikhailo Shabodyash <67977488+EviLord032@users.noreply.github.com> Date: Wed, 8 May 2024 21:19:05 +0300 Subject: [PATCH 03/19] wip --- deployments/polygon/usdt/configuration.json | 18 ++++++++++++++++++ deployments/polygon/usdt/deploy.ts | 2 ++ deployments/polygon/usdt/relations.ts | 9 +++++++++ scenario/AddMaticxCollateralScenario.ts | 2 +- 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/deployments/polygon/usdt/configuration.json b/deployments/polygon/usdt/configuration.json index e12d1ec54..a20ccf1be 100644 --- a/deployments/polygon/usdt/configuration.json +++ b/deployments/polygon/usdt/configuration.json @@ -27,6 +27,24 @@ }, "rewardTokenAddress": "0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c", "assets": { + "aPolMATICX": { + "address": "0x80cA0d8C38d2e2BcbaB66aA1648Bd1C7160500FE", + "priceFeed": "0x5d37E4b374E6907de8Fc7fb33EE3b0af403C7403", + "decimals": "18", + "borrowCF": 0.60, + "liquidateCF": 0.70, + "liquidationFactor": 0.80, + "supplyCap": "0e18" + }, + "stMATIC": { + "address": "0x3A58a54C066FdC0f2D55FC9C89F0415C92eBf3C4", + "priceFeed": "0x97371dF4492605486e23Da797fA68e55Fc38a13f", + "decimals": "18", + "borrowCF": 0.60, + "liquidateCF": 0.70, + "liquidationFactor": 0.80, + "supplyCap": "0e18" + }, "WETH": { "address": "0x7ceb23fd6bc0add59e62ac25578270cff1b9f619", "priceFeed": "0xF9680D99D6C9589e2a93a78A04A279e509205945", diff --git a/deployments/polygon/usdt/deploy.ts b/deployments/polygon/usdt/deploy.ts index c80b426ce..c4db85893 100644 --- a/deployments/polygon/usdt/deploy.ts +++ b/deployments/polygon/usdt/deploy.ts @@ -15,6 +15,8 @@ export default async function deploy(deploymentManager: DeploymentManager, deplo const WBTC = await deploymentManager.existing('WBTC', '0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6', 'polygon'); const WETH = await deploymentManager.existing('WETH', '0x7ceb23fd6bc0add59e62ac25578270cff1b9f619', 'polygon'); const WMATIC = await deploymentManager.existing('WMATIC', '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270', 'polygon'); + const MATICX = await deploymentManager.existing('aPolMATICX', '0x80cA0d8C38d2e2BcbaB66aA1648Bd1C7160500FE', 'polygon'); + const stMATIC = await deploymentManager.existing('stMATIC', '0x3A58a54C066FdC0f2D55FC9C89F0415C92eBf3C4', 'polygon'); const COMP = await deploymentManager.existing('COMP', '0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c', 'polygon'); const fxChild = await deploymentManager.existing('fxChild', '0x8397259c983751DAf40400790063935a11afa28a', 'polygon'); diff --git a/deployments/polygon/usdt/relations.ts b/deployments/polygon/usdt/relations.ts index 3b92711b1..5deda5c13 100644 --- a/deployments/polygon/usdt/relations.ts +++ b/deployments/polygon/usdt/relations.ts @@ -12,6 +12,15 @@ export default { field: { slot: '0xbaab7dbf64751104133af04abc7d9979f0fda3b059a322a8333f533d3f32bf7f', } + }, + // aPolMATICX + '0x80cA0d8C38d2e2BcbaB66aA1648Bd1C7160500FE': { + artifact: 'contracts/ERC20.sol:ERC20', + delegates: { + field: { + slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + } + } } } }; \ No newline at end of file diff --git a/scenario/AddMaticxCollateralScenario.ts b/scenario/AddMaticxCollateralScenario.ts index b006506be..ceb7c1d53 100644 --- a/scenario/AddMaticxCollateralScenario.ts +++ b/scenario/AddMaticxCollateralScenario.ts @@ -19,7 +19,7 @@ scenario( 'add new asset maticx', { filter: async (ctx) => - matchesDeployment(ctx, [{ network: 'polygon' }]), + matchesDeployment(ctx, [{ network: 'polygon' }]) && !matchesDeployment(ctx, [{deployment: 'usdt'}, { network: 'polygon' }]), tokenBalances: { $comet: { $base: '>= 1' }, }, From b1be1cd7bcb9729b5ebb4e93b0823ed02dffbd66 Mon Sep 17 00:00:00 2001 From: Mikhailo Shabodyash <67977488+EviLord032@users.noreply.github.com> Date: Thu, 9 May 2024 12:00:35 +0300 Subject: [PATCH 04/19] feat: add new assets --- deployments/polygon/usdt/configuration.json | 18 ++++---- deployments/polygon/usdt/relations.ts | 26 +++++++---- plugins/import/import.ts | 48 +++++++++++---------- 3 files changed, 52 insertions(+), 40 deletions(-) diff --git a/deployments/polygon/usdt/configuration.json b/deployments/polygon/usdt/configuration.json index a20ccf1be..862d8a7a9 100644 --- a/deployments/polygon/usdt/configuration.json +++ b/deployments/polygon/usdt/configuration.json @@ -27,6 +27,15 @@ }, "rewardTokenAddress": "0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c", "assets": { + "WMATIC": { + "address": "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", + "priceFeed": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", + "decimals": "18", + "borrowCF": 0.65, + "liquidateCF": 0.80, + "liquidationFactor": 0.85, + "supplyCap": "0e18" + }, "aPolMATICX": { "address": "0x80cA0d8C38d2e2BcbaB66aA1648Bd1C7160500FE", "priceFeed": "0x5d37E4b374E6907de8Fc7fb33EE3b0af403C7403", @@ -54,15 +63,6 @@ "liquidationFactor": 0.95, "supplyCap": "0e18" }, - "WMATIC": { - "address": "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", - "priceFeed": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", - "decimals": "18", - "borrowCF": 0.65, - "liquidateCF": 0.80, - "liquidationFactor": 0.85, - "supplyCap": "0e18" - }, "WBTC": { "address": "0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6", "priceFeed": "0xDE31F8bFBD8c84b5360CFACCa3539B938dd78ae6", diff --git a/deployments/polygon/usdt/relations.ts b/deployments/polygon/usdt/relations.ts index 5deda5c13..fa64e195e 100644 --- a/deployments/polygon/usdt/relations.ts +++ b/deployments/polygon/usdt/relations.ts @@ -6,6 +6,23 @@ export default { 'governor': { artifact: 'contracts/bridges/polygon/PolygonBridgeReceiver.sol:PolygonBridgeReceiver', }, + InitializableImmutableAdminUpgradeabilityProxy: { + artifact: 'contracts/ERC20.sol:ERC20', + delegates: { + field: { + slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + } + } + }, + // InitializableImmutableAdminUpgradeabilityProxy: { + aPolMATICX: { + artifact: 'contracts/ERC20.sol:ERC20', + delegates: { + field: { + slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + } + } + }, UChildERC20Proxy: { artifact: 'contracts/ERC20.sol:ERC20', delegates: { @@ -13,14 +30,5 @@ export default { slot: '0xbaab7dbf64751104133af04abc7d9979f0fda3b059a322a8333f533d3f32bf7f', } }, - // aPolMATICX - '0x80cA0d8C38d2e2BcbaB66aA1648Bd1C7160500FE': { - artifact: 'contracts/ERC20.sol:ERC20', - delegates: { - field: { - slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' - } - } - } } }; \ No newline at end of file diff --git a/plugins/import/import.ts b/plugins/import/import.ts index 48eaf6f70..2d644306c 100644 --- a/plugins/import/import.ts +++ b/plugins/import/import.ts @@ -83,12 +83,36 @@ async function getEtherscanApiData(network: string, address: string, apiKey: str }; } +async function scrapeContractCreationCodeFromEtherscanApi(network: string, address: string) { + const params = { + module: 'proxy', + action: 'eth_getCode', + address, + apikey: getEtherscanApiKey(network) + }; + const url = `${getEtherscanApiUrl(network)}?${paramString(params)}`; + const debugUrl = `${getEtherscanApiUrl(network)}?${paramString({ ...params, ...{ apikey: '[API_KEY]'}})}`; + + debug(`Attempting to pull Contract Creation code from API at ${debugUrl}`); + const result = await get(url, {}); + const contractCreationCode = result.result; + if (!contractCreationCode) { + throw new Error(`Unable to find Contract Creation code from API at ${debugUrl}`); + } + debug(`Creation Code found in first tx at ${debugUrl}`); + return contractCreationCode.slice(2); +} + +/** + * @description Does not work for 0x566511a1A09561e2896F8c0fD77E8544E59bFDB0 as etherscan starts using some firewall + */ async function scrapeContractCreationCodeFromEtherscan(network: string, address: string) { const url = `${getEtherscanUrl(network)}/address/${address}#code`; debug(`Attempting to scrape Contract Creation code at ${url}`); const result = await get(url, {}); const regex = /
[\s\r\n]*([0-9a-fA-F]*)[\s\r\n]*<\/div>/g; - const matches = [...result.matchAll(regex)]; + const regexDoubleQuotes = /
[\s\r\n]*([0-9a-fA-F]*)[\s\r\n]*<\/div>/g; + const matches = [...result.matchAll(regex), ...result.matchAll(regexDoubleQuotes)]; if (matches.length === 0) { if (result.match(/request throttled/i) || result.match(/try again later/i)) { throw new Error(`Request throttled: ${url}`); @@ -129,31 +153,11 @@ async function pullFirstTransactionForContract(network: string, address: string) return contractCreationCode.slice(2); } -async function scrapeContractCreationCodeFromEtherscanApi(network: string, address: string) { - const params = { - module: 'proxy', - action: 'eth_getCode', - address, - apikey: getEtherscanApiKey(network) - }; - const url = `${getEtherscanApiUrl(network)}?${paramString(params)}`; - const debugUrl = `${getEtherscanApiUrl(network)}?${paramString({ ...params, ...{ apikey: '[API_KEY]'}})}`; - - debug(`Attempting to pull Contract Creation code from API at ${debugUrl}`); - const result = await get(url, {}); - const contractCreationCode = result.result; - if (!contractCreationCode) { - throw new Error(`Unable to find Contract Creation code from API at ${debugUrl}`); - } - debug(`Creation Code found in first tx at ${debugUrl}`); - return contractCreationCode.slice(2); -} - async function getContractCreationCode(network: string, address: string) { const strategies = [ scrapeContractCreationCodeFromEtherscan, scrapeContractCreationCodeFromEtherscanApi, - pullFirstTransactionForContract + pullFirstTransactionForContract, ]; let errors = []; for (const strategy of strategies) { From 7c3ce91f1fda3eedc6751b57d4e5ad9dc7aa90d8 Mon Sep 17 00:00:00 2001 From: Mikhailo Shabodyash <67977488+EviLord032@users.noreply.github.com> Date: Thu, 9 May 2024 18:46:03 +0300 Subject: [PATCH 05/19] wip --- deployments/polygon/usdt/configuration.json | 18 ++-- deployments/polygon/usdt/deploy.ts | 2 +- .../1713283675_configurate_and_ens.ts | 85 ++++++++++--------- plugins/import/import.ts | 2 +- scenario/AddMaticxCollateralScenario.ts | 2 +- scenario/BulkerScenario.ts | 16 ++-- scenario/LiquidationBotScenario.ts | 77 ++++++++++------- scenario/SupplyScenario.ts | 6 +- scenario/WithdrawScenario.ts | 5 +- src/deploy/index.ts | 5 -- 10 files changed, 119 insertions(+), 99 deletions(-) diff --git a/deployments/polygon/usdt/configuration.json b/deployments/polygon/usdt/configuration.json index 862d8a7a9..6f6f8d382 100644 --- a/deployments/polygon/usdt/configuration.json +++ b/deployments/polygon/usdt/configuration.json @@ -36,6 +36,15 @@ "liquidationFactor": 0.85, "supplyCap": "0e18" }, + "WETH": { + "address": "0x7ceb23fd6bc0add59e62ac25578270cff1b9f619", + "priceFeed": "0xF9680D99D6C9589e2a93a78A04A279e509205945", + "decimals": "18", + "borrowCF": 0.80, + "liquidateCF": 0.85, + "liquidationFactor": 0.95, + "supplyCap": "0e18" + }, "aPolMATICX": { "address": "0x80cA0d8C38d2e2BcbaB66aA1648Bd1C7160500FE", "priceFeed": "0x5d37E4b374E6907de8Fc7fb33EE3b0af403C7403", @@ -54,15 +63,6 @@ "liquidationFactor": 0.80, "supplyCap": "0e18" }, - "WETH": { - "address": "0x7ceb23fd6bc0add59e62ac25578270cff1b9f619", - "priceFeed": "0xF9680D99D6C9589e2a93a78A04A279e509205945", - "decimals": "18", - "borrowCF": 0.80, - "liquidateCF": 0.85, - "liquidationFactor": 0.95, - "supplyCap": "0e18" - }, "WBTC": { "address": "0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6", "priceFeed": "0xDE31F8bFBD8c84b5360CFACCa3539B938dd78ae6", diff --git a/deployments/polygon/usdt/deploy.ts b/deployments/polygon/usdt/deploy.ts index c4db85893..3e9631560 100644 --- a/deployments/polygon/usdt/deploy.ts +++ b/deployments/polygon/usdt/deploy.ts @@ -15,7 +15,7 @@ export default async function deploy(deploymentManager: DeploymentManager, deplo const WBTC = await deploymentManager.existing('WBTC', '0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6', 'polygon'); const WETH = await deploymentManager.existing('WETH', '0x7ceb23fd6bc0add59e62ac25578270cff1b9f619', 'polygon'); const WMATIC = await deploymentManager.existing('WMATIC', '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270', 'polygon'); - const MATICX = await deploymentManager.existing('aPolMATICX', '0x80cA0d8C38d2e2BcbaB66aA1648Bd1C7160500FE', 'polygon'); + const aPolMATICX = await deploymentManager.existing('aPolMATICX', '0x80cA0d8C38d2e2BcbaB66aA1648Bd1C7160500FE', 'polygon'); const stMATIC = await deploymentManager.existing('stMATIC', '0x3A58a54C066FdC0f2D55FC9C89F0415C92eBf3C4', 'polygon'); const COMP = await deploymentManager.existing('COMP', '0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c', 'polygon'); diff --git a/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts index 76f39e403..5d24a90db 100644 --- a/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts +++ b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts @@ -3,10 +3,10 @@ import { DeploymentManager } from '../../../../plugins/deployment_manager/Deploy import { migration } from '../../../../plugins/deployment_manager/Migration'; import { calldata, exp, getConfigurationStruct, proposal } from '../../../../src/deploy'; import { expect } from 'chai'; +import { diffState, getCometConfig } from '../../../../plugins/deployment_manager/DiffState'; const ENSName = 'compound-community-licenses.eth'; const ENSResolverAddress = '0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41'; -const ENSRegistryAddress = '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e'; const ENSSubdomainLabel = 'v3-additional-grants'; const ENSSubdomain = `${ENSSubdomainLabel}.${ENSName}`; const ENSTextRecordKey = 'v3-official-markets'; @@ -174,52 +174,66 @@ export default migration('1713283675_configurate_and_ens', { return false; }, - async verify(deploymentManager: DeploymentManager, govDeploymentManager: DeploymentManager) { + async verify(deploymentManager: DeploymentManager, govDeploymentManager: DeploymentManager, preMigrationBlockNumber: number) { const ethers = deploymentManager.hre.ethers; const { comet, rewards, - WBTC, + WMATIC, WETH, - WMATIC + aPolMATICX, + stMATIC, + WBTC, + COMP } = await deploymentManager.getContracts(); const { - timelock, - comptrollerV2, + timelock } = await govDeploymentManager.getContracts(); - // 1. - const wbtcInfo = await comet.getAssetInfoByAddress(WBTC.address); - const wethInfo = await comet.getAssetInfoByAddress(WETH.address); - const wmaticInfo = await comet.getAssetInfoByAddress(WMATIC.address); - // expect(wbtcInfo.supplyCap).to.be.eq(exp(400, 8)); - // expect(wethInfo.supplyCap).to.be.eq(exp(11_000, 18)); - // expect(wmaticInfo.supplyCap).to.be.eq(exp(10_000_000, 18)); - expect(await comet.pauseGuardian()).to.be.eq('0x8Ab717CAC3CbC4934E63825B88442F5810aAF6e5'); + const stateChanges = await diffState(comet, getCometConfig, preMigrationBlockNumber); + + // uncomment on on-chain proposal PR + // expect(stateChanges).to.deep.equal({ + // WMATIC: { + // supplyCap: exp(5_000_000, 18) + // }, + // WETH: { + // supplyCap: exp(2_000, 18) + // }, + // aPolMATICX: { + // supplyCap: exp(2_600_000, 18), + // }, + // stMATIC: { + // supplyCap: exp(1_500_000, 18) + // }, + // WBTC: { + // supplyCap: exp(90, 8) + // }, + // baseTrackingSupplySpeed: exp(5 / 86400, 15, 18), + // baseTrackingBorrowSpeed: exp(5 / 86400, 15, 18), + // }); + + const config = await rewards.rewardConfig(comet.address); + expect(config.token).to.be.equal(COMP.address); + expect(config.rescaleFactor).to.be.equal(exp(1, 12)); + expect(config.shouldUpscale).to.be.equal(true); - // 2. & 3. + // 2. & 3 & 4. expect(await comet.getReserves()).to.be.equal(USDTAmountToBridge); - // 4. & 5. - const polygonCOMP = new Contract( - '0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c', - ['function balanceOf(address account) external view returns (uint256)'], - deploymentManager.hre.ethers.provider + // 5. + const ENSResolver = await govDeploymentManager.existing( + 'ENSResolver', + ENSResolverAddress ); - expect((await polygonCOMP.balanceOf(rewards.address)).gt(exp(2_500, 18))).to.be.true; - - // 6. & 7. - const ENSResolver = await govDeploymentManager.existing('ENSResolver', ENSResolverAddress); - const ENSRegistry = await govDeploymentManager.existing('ENSRegistry', ENSRegistryAddress); const subdomainHash = ethers.utils.namehash(ENSSubdomain); - const officialMarketsJSON = await ENSResolver.text(subdomainHash, ENSTextRecordKey); + const officialMarketsJSON = await ENSResolver.text( + subdomainHash, + ENSTextRecordKey + ); const officialMarkets = JSON.parse(officialMarketsJSON); - expect(await ENSRegistry.recordExists(subdomainHash)).to.be.equal(true); - expect(await ENSRegistry.owner(subdomainHash)).to.be.equal(timelock.address); - expect(await ENSRegistry.resolver(subdomainHash)).to.be.equal(ENSResolverAddress); - expect(await ENSRegistry.ttl(subdomainHash)).to.be.equal(0); expect(officialMarkets).to.deep.equal({ 1: [ { @@ -230,11 +244,6 @@ export default migration('1713283675_configurate_and_ens', { baseSymbol: 'WETH', cometAddress: '0xA17581A9E3356d9A858b789D68B4d866e593aE94', }, - // should be changed after soon to be PR - // { - // baseSymbol: 'WETH', - // cometAddress: comet.address, - // }, ], 137: [ { @@ -244,7 +253,7 @@ export default migration('1713283675_configurate_and_ens', { { baseSymbol: 'USDT', cometAddress: comet.address, - }, + } ], 8453: [ { @@ -283,9 +292,5 @@ export default migration('1713283675_configurate_and_ens', { }, ], }); - - // 8. - // expect(await comet.baseTrackingSupplySpeed()).to.be.equal(0); - // expect(await comet.baseTrackingBorrowSpeed()).to.be.equal(exp(34.74 / 86400, 15, 18)); } }); diff --git a/plugins/import/import.ts b/plugins/import/import.ts index 2d644306c..05e2a2bf5 100644 --- a/plugins/import/import.ts +++ b/plugins/import/import.ts @@ -256,4 +256,4 @@ export async function loadEtherscanContract(network: string, address: string) { }; return contractBuild; -} \ No newline at end of file +} diff --git a/scenario/AddMaticxCollateralScenario.ts b/scenario/AddMaticxCollateralScenario.ts index ceb7c1d53..d6361bb23 100644 --- a/scenario/AddMaticxCollateralScenario.ts +++ b/scenario/AddMaticxCollateralScenario.ts @@ -33,7 +33,7 @@ scenario( const maticx = await dm.existing( 'MATICX', MATICX_ADDRESS, - '', + context.world.base.network, 'contracts/ERC20.sol:ERC20' ); const maticxPricefeed = await dm.existing( diff --git a/scenario/BulkerScenario.ts b/scenario/BulkerScenario.ts index 5b1ec82ae..5f7300692 100644 --- a/scenario/BulkerScenario.ts +++ b/scenario/BulkerScenario.ts @@ -5,7 +5,6 @@ import { expectBase, isRewardSupported, isBulkerSupported, getExpectedBaseBalanc import { exp } from '../test/helpers'; // XXX properly handle cases where asset0 is WETH -// TODO: should properly handle cases where asset1 isn't WETH (wrapped native token) scenario( 'Comet#bulker > (non-WETH base) all non-reward actions in one txn', { @@ -15,7 +14,7 @@ scenario( $asset1: 3000, }, tokenBalances: { - albert: { $base: '== 0', $asset0: 3000 }, + albert: { $base: '== 0', $asset0: 3000, $asset1: 3000 }, $comet: { $base: 5000 }, }, }, @@ -25,8 +24,12 @@ scenario( const baseAssetAddress = await comet.baseToken(); const baseAsset = context.getAssetByAddress(baseAssetAddress); const baseScale = (await comet.baseScale()).toBigInt(); - const { asset: collateralAssetAddress, scale: scaleBN } = await comet.getAssetInfo(0); + // if asset 0 is native token we took asset 1 + const { asset: asset0, scale: scale0 } = await comet.getAssetInfo(0); + const { asset: asset1, scale: scale1 } = await comet.getAssetInfo(1); + const { asset: collateralAssetAddress, scale: scaleBN } = asset0 === wrappedNativeToken ? { asset: asset1, scale: scale1 } : { asset: asset0, scale: scale0 }; const collateralAsset = context.getAssetByAddress(collateralAssetAddress); + console.log('collateralAsset', collateralAsset); const collateralScale = scaleBN.toBigInt(); const toSupplyCollateral = 3000n * collateralScale; const toBorrowBase = 1000n * baseScale; @@ -169,7 +172,7 @@ scenario( $asset1: 3000, }, tokenBalances: { - albert: { $base: '== 1000000', $asset0: 3000 }, + albert: { $base: '== 1000000', $asset0: 3000, $asset1: 3000}, $comet: { $base: 5000 }, } }, @@ -179,7 +182,10 @@ scenario( const baseAssetAddress = await comet.baseToken(); const baseAsset = context.getAssetByAddress(baseAssetAddress); const baseScale = (await comet.baseScale()).toBigInt(); - const { asset: collateralAssetAddress, scale: scaleBN } = await comet.getAssetInfo(0); + // if asset 0 is native token we took asset 1 + const { asset: asset0, scale: scale0 } = await comet.getAssetInfo(0); + const { asset: asset1, scale: scale1 } = await comet.getAssetInfo(1); + const { asset: collateralAssetAddress, scale: scaleBN } = asset0 === wrappedNativeToken ? { asset: asset1, scale: scale1 } : { asset: asset0, scale: scale0 }; const collateralAsset = context.getAssetByAddress(collateralAssetAddress); const collateralScale = scaleBN.toBigInt(); const [rewardTokenAddress] = await rewards.rewardConfig(comet.address); diff --git a/scenario/LiquidationBotScenario.ts b/scenario/LiquidationBotScenario.ts index d708df060..48ddf195b 100644 --- a/scenario/LiquidationBotScenario.ts +++ b/scenario/LiquidationBotScenario.ts @@ -74,8 +74,9 @@ async function canBeLiquidatedByBot(ctx: CometContext, assetNum: number): Promis // Reason: Most liquidity lives in MATICX / MATIC pools, which the liquidation bot cannot use if the base asset is not MATIC MaticX: { network: 'polygon', - deployments: ['usdc'] - } + deployments: ['usdc', 'usdt'] + }, + }; const comet = await ctx.getComet(); const assetInfo = await comet.getAssetInfo(assetNum); @@ -136,14 +137,16 @@ for (let i = 0; i < MAX_ASSETS; i++) { ' == 0', ], usdt: [ - // WETH - ' == 400', - // WBTC - ' == 20', // WMATIC ' == 300000', + // WETH + ' == 400', // MATICX - ' == 0', + ' == 300000', + // stMATIC + ' == 300000', + // WBTC + ' == 20' ], }, arbitrum: { @@ -332,14 +335,16 @@ for (let i = 0; i < MAX_ASSETS; i++) { ' == 0', ], usdt: [ - // WETH - ' == 1000', - // WBTC - ' == 100', // WMATIC - ' == 2500000', + ' == 25000000', + // WETH + ' == 10000', // MATICX - ' == 0', + ' == 25000000', + // stMATIC + ' == 25000000', + // WBTC + ' == 1000' ] }, arbitrum: { @@ -398,14 +403,16 @@ for (let i = 0; i < MAX_ASSETS; i++) { exp(5, 18) ], usdt: [ - // WETH - exp(400, 18), - // WBTC - exp(20, 8), // WMATIC - exp(5000, 18), + exp(50000, 18), + // WETH + exp(4000, 18), // MATICX - exp(5, 18) + exp(50000, 18), + // stMATIC + exp(50000, 18), + // WBTC + exp(200, 8) ] }, arbitrum: { @@ -544,14 +551,16 @@ scenario( { filter: async (ctx) => matchesDeployment(ctx, [{network: 'mainnet'}, {network: 'polygon'}, {network: 'arbitrum'}]), tokenBalances: { - $comet: { $base: 1000000 }, - }, - cometBalances: { - albert: { - $asset0: ' == 200', - }, - betty: { $base: 1000 }, + $comet: { $base: 100000 }, }, + cometBalances: async (ctx) => ( + { + albert: { + $asset0: ctx.world.base.network == 'polygon' && ctx.world.base.deployment == 'usdt'? ' == 20000': ' == 200' + }, + betty: { $base: 1000 }, + } + ), }, async ({ comet, actors }, _context, world) => { const { albert, betty } = actors; @@ -655,14 +664,16 @@ scenario( { filter: async (ctx) => matchesDeployment(ctx, [{network: 'mainnet'}, {network: 'polygon'}, {network: 'arbitrum'}]), tokenBalances: { - $comet: { $base: 1000000 }, - }, - cometBalances: { - albert: { - $asset0: ' == 200', - }, - betty: { $base: 1000 }, + $comet: { $base: 100000 }, }, + cometBalances: async (ctx) => ( + { + albert: { + $asset0: ctx.world.base.network == 'polygon' && ctx.world.base.deployment == 'usdt'? ' == 20000': ' == 200' + }, + betty: { $base: 1000 }, + } + ), }, async ({ comet, actors }, _context, world) => { const { albert, betty } = actors; diff --git a/scenario/SupplyScenario.ts b/scenario/SupplyScenario.ts index a3ec668af..4121a1865 100644 --- a/scenario/SupplyScenario.ts +++ b/scenario/SupplyScenario.ts @@ -309,7 +309,8 @@ scenario( /ERC20: insufficient allowance/, /transfer amount exceeds spender allowance/, /Dai\/insufficient-allowance/, - symbol === 'WETH' ? /Transaction reverted without a reason string/ : /.^/ + symbol === 'WETH' ? /Transaction reverted without a reason string/ : /.^/, + symbol === 'WMATIC' ? /Transaction reverted without a reason string/ : /.^/ ] ); } @@ -393,7 +394,8 @@ scenario( [ /transfer amount exceeds balance/, /Dai\/insufficient-balance/, - symbol === 'WETH' ? /Transaction reverted without a reason string/ : /.^/ + symbol === 'WETH' ? /Transaction reverted without a reason string/ : /.^/, + symbol === 'WMATIC' ? /Transaction reverted without a reason string/ : /.^/ ] ); } diff --git a/scenario/WithdrawScenario.ts b/scenario/WithdrawScenario.ts index d0bab38b9..89c50f78f 100644 --- a/scenario/WithdrawScenario.ts +++ b/scenario/WithdrawScenario.ts @@ -2,6 +2,7 @@ import { CometContext, scenario } from './context/CometContext'; import { expect } from 'chai'; import { expectApproximately, expectRevertCustom, hasMinBorrowGreaterThanOne, isTriviallySourceable, isValidAssetIndex, MAX_ASSETS } from './utils'; import { ContractReceipt } from 'ethers'; +import { ethers } from 'hardhat'; async function testWithdrawCollateral(context: CometContext, assetNum: number): Promise { const comet = await context.getComet(); @@ -10,13 +11,13 @@ async function testWithdrawCollateral(context: CometContext, assetNum: number): const collateralAsset = context.getAssetByAddress(assetAddress); const scale = scaleBN.toBigInt(); - expect(await collateralAsset.balanceOf(albert.address)).to.be.equal(0n); + expect(await collateralAsset.balanceOf(albert.address)).to.be.closeTo(0n, ethers.BigNumber.from(10).pow(ethers.BigNumber.from(await collateralAsset.decimals()).div(2)).toBigInt()); expect(await comet.collateralBalanceOf(albert.address, collateralAsset.address)).to.be.equal(100n * scale); // Albert withdraws 100 units of collateral from Comet const txn = await albert.withdrawAsset({ asset: collateralAsset.address, amount: 100n * scale }); - expect(await collateralAsset.balanceOf(albert.address)).to.be.equal(100n * scale); + expect(await collateralAsset.balanceOf(albert.address)).to.be.closeTo(100n * scale, ethers.BigNumber.from(10).pow(ethers.BigNumber.from(await collateralAsset.decimals()).div(2)).toBigInt()); expect(await comet.collateralBalanceOf(albert.address, collateralAsset.address)).to.be.equal(0n); return txn; // return txn to measure gas diff --git a/src/deploy/index.ts b/src/deploy/index.ts index 21ad50dfb..79a1b0bc3 100644 --- a/src/deploy/index.ts +++ b/src/deploy/index.ts @@ -79,11 +79,6 @@ export const COMP_WHALES = { testnet: ['0xbbfe34e868343e6f4f5e8b5308de980d7bd88c46'], - polygon: [ - '0x52A258ED593C793251a89bfd36caE158EE9fC4F8', - '0xdE5167C19A5286889752Cb0f31a1c7f28A99feFB', - '0xC35D800aD559c481dDa73D0b89dbC12774945512' - ], }; export const WHALES = { From cd65be1e1dc633c7559328d3071256dbe1da3ece Mon Sep 17 00:00:00 2001 From: Mikhailo Shabodyash <67977488+EviLord032@users.noreply.github.com> Date: Fri, 10 May 2024 13:52:16 +0300 Subject: [PATCH 06/19] fix: more clean up --- .../1713283675_configurate_and_ens.ts | 24 ++++++-------- scenario/AddMaticxCollateralScenario.ts | 2 +- scenario/BulkerScenario.ts | 1 - scenario/WithdrawScenario.ts | 32 +++++++++++++++++++ 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts index 5d24a90db..9a8ce2486 100644 --- a/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts +++ b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts @@ -113,16 +113,11 @@ export default migration('1713283675_configurate_and_ens', { [comet.address, USDTMainnet.address, depositUSDTData] ); const notEnoughUSDT = (await USDTMainnet.balanceOf(timelock.address)).lt(USDTAmountToBridge); - const amountToSupply = notEnoughUSDT ? USDTAmountToBridge.sub(await USDTMainnet.balanceOf(timelock.address)) : 0; + const amountToSupply = notEnoughUSDT ? ethers.BigNumber.from(USDTAmountToBridge).sub(await USDTMainnet.balanceOf(timelock.address)) : 0; const _reduceReservesCalldata = utils.defaultAbiCoder.encode( ['uint256'], [amountToSupply] ); - const addinionalAction = { - target: cUSDTAddress, - signature: '_reduceReserves(uint256)', - calldata: _reduceReservesCalldata - }; const mainnetActions = [ // 1. Set Comet configuration and deployAndUpgradeTo new Comet on Polygon. @@ -131,19 +126,25 @@ export default migration('1713283675_configurate_and_ens', { signature: 'sendMessageToChild(address,bytes)', args: [bridgeReceiver.address, l2ProposalData] }, - // 2. Approve Polygon's ERC20Predicate to take Timelock's USDT (for bridging) + // 2. Get USDT reserves from cUSDT contract + { + target: cUSDTAddress, + signature: '_reduceReserves(uint256)', + calldata: _reduceReservesCalldata + }, + // 3. Approve Polygon's ERC20Predicate to take Timelock's USDT (for bridging) { contract: USDTMainnet, signature: 'approve(address,uint256)', args: [ERC20PredicateAddress, USDTAmountToBridge] }, - // 3. Bridge USDT from mainnet to Polygon Comet using RootChainManager + // 4. Bridge USDT from mainnet to Polygon Comet using RootChainManager { target: RootChainManager.address, signature: 'depositFor(address,address,bytes)', calldata: depositForUSDTCalldata }, - // 4. Update the list of official markets + // 5. Update the list of official markets { target: ENSResolverAddress, signature: 'setText(bytes32,string,string)', @@ -154,11 +155,6 @@ export default migration('1713283675_configurate_and_ens', { } ]; - // add new action between 1 and 2 - if (notEnoughUSDT) { - mainnetActions.splice(2, 0, addinionalAction); - } - const description = "# Initialize cUSDCv3 on Polygon\n\nThis proposal takes the governance steps recommended and necessary to initialize a Compound III USDC market on Polygon; upon execution, cUSDCv3 will be ready for use. Simulations have confirmed the market\u2019s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). Although real tests have also been run over the Goerli/Mumbai bridge, this will be the first proposal to actually bridge from Ethereum mainnet to another chain, and therefore includes risks not present in previous proposals.\n\nAlthough the proposal sets the entire configuration in the Configurator, the initial deployment already has most of these same parameters already set. The new parameters include setting the pause guardian to a Gnosis [multisig](https://app.safe.global/matic:0x8Ab717CAC3CbC4934E63825B88442F5810aAF6e5/home), which has been created on Polygon to match the same set of signers as currently on Ethereum mainnet. They also include risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/initialize-compound-iii-usdc-on-polygon-pos/3611/12). Finally, the parameters include a modest reallocation of some of the v2 USDT COMP rewards to borrowers in the new market.\n\nFurther detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/672) and [forum discussion](https://www.comp.xyz/t/initialize-compound-iii-usdc-on-polygon-pos/3611/11).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Polygon. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Polygon.\n\nThe second action approves Polygon's ERC20Predicate to take Timelock's USDC, in order to seed the market reserves through the bridge.\n\nThe third action deposits USDC from mainnet to the Polygon RootChainManager contract to bridge to Comet.\n\nThe fourth action approves Polygon's ERC20Predicate to take Timelock's COMP, in order to seed the rewards contract through the bridge.\n\nThe fifth action deposits COMP from mainnet to the Polygon RootChainManager contract to bridge to CometRewards. \n\nThe sixth action sets up the ENS subdomain `v3-additional-grants.compound-community-licenses.eth`, with the Timelock as the owner.\n\nThe seventh action writes the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, containing the official markets JSON.\n\nThe eighth action migrates the COMP distribution for v2 cUSDT suppliers, so as to keep the total COMP distribution constant.\n"; const txn = await govDeploymentManager.retry(async () => trace(await governor.propose(...(await proposal(mainnetActions, description)))) diff --git a/scenario/AddMaticxCollateralScenario.ts b/scenario/AddMaticxCollateralScenario.ts index d6361bb23..8a0fd8932 100644 --- a/scenario/AddMaticxCollateralScenario.ts +++ b/scenario/AddMaticxCollateralScenario.ts @@ -10,7 +10,7 @@ const MATICX_ADDRESS = '0xfa68FB4628DFF1028CFEc22b4162FCcd0d45efb6'; const MATICX_PRICE_FEED_ADDRESS = '0x5d37E4b374E6907de8Fc7fb33EE3b0af403C7403'; const MATICX_WHALES = { polygon: [ - '0x1e5b92c66e4CAd7963E8dAcF1E8D642304C172C8'], + '0x68B9220B8E617b7700aCAE1a5Ff43F3eb29257F3'], }; // TODO: add ability to run ad hoc scenarios against a single migration, to avoid needing the scenario to do all this setup of diff --git a/scenario/BulkerScenario.ts b/scenario/BulkerScenario.ts index 5f7300692..7c9f39908 100644 --- a/scenario/BulkerScenario.ts +++ b/scenario/BulkerScenario.ts @@ -29,7 +29,6 @@ scenario( const { asset: asset1, scale: scale1 } = await comet.getAssetInfo(1); const { asset: collateralAssetAddress, scale: scaleBN } = asset0 === wrappedNativeToken ? { asset: asset1, scale: scale1 } : { asset: asset0, scale: scale0 }; const collateralAsset = context.getAssetByAddress(collateralAssetAddress); - console.log('collateralAsset', collateralAsset); const collateralScale = scaleBN.toBigInt(); const toSupplyCollateral = 3000n * collateralScale; const toBorrowBase = 1000n * baseScale; diff --git a/scenario/WithdrawScenario.ts b/scenario/WithdrawScenario.ts index 89c50f78f..572953d4c 100644 --- a/scenario/WithdrawScenario.ts +++ b/scenario/WithdrawScenario.ts @@ -11,6 +11,25 @@ async function testWithdrawCollateral(context: CometContext, assetNum: number): const collateralAsset = context.getAssetByAddress(assetAddress); const scale = scaleBN.toBigInt(); + expect(await collateralAsset.balanceOf(albert.address)).to.be.equal(0n); + expect(await comet.collateralBalanceOf(albert.address, collateralAsset.address)).to.be.equal(100n * scale); + + // Albert withdraws 100 units of collateral from Comet + const txn = await albert.withdrawAsset({ asset: collateralAsset.address, amount: 100n * scale }); + + expect(await collateralAsset.balanceOf(albert.address)).to.be.equal(100n * scale); + expect(await comet.collateralBalanceOf(albert.address, collateralAsset.address)).to.be.equal(0n); + + return txn; // return txn to measure gas +} + +async function testWithdrawCollateralMaticxSpecific(context: CometContext, assetNum: number): Promise { + const comet = await context.getComet(); + const { albert } = context.actors; + const { asset: assetAddress, scale: scaleBN } = await comet.getAssetInfo(assetNum); + const collateralAsset = context.getAssetByAddress(assetAddress); + const scale = scaleBN.toBigInt(); + expect(await collateralAsset.balanceOf(albert.address)).to.be.closeTo(0n, ethers.BigNumber.from(10).pow(ethers.BigNumber.from(await collateralAsset.decimals()).div(2)).toBigInt()); expect(await comet.collateralBalanceOf(albert.address, collateralAsset.address)).to.be.equal(100n * scale); @@ -44,6 +63,16 @@ async function testWithdrawFromCollateral(context: CometContext, assetNum: numbe return txn; // return txn to measure gas } +const isScenarioWithMaticxAsset = (context: CometContext) => { + return context.world.deploymentManager.network === 'polygon' && context.world.deploymentManager.deployment === 'usdt'; +}; + +const isMaticxAsset = async (context: CometContext, i: number) => { + const { asset: assetAddress, } = await (await context.getComet()).getAssetInfo(i); + const collateralAsset = context.getAssetByAddress(assetAddress); + return await collateralAsset.token.symbol() === 'aPolMATICX'; +}; + for (let i = 0; i < MAX_ASSETS; i++) { const amountToWithdraw = 100; // in units of asset, not wei scenario( @@ -55,6 +84,9 @@ for (let i = 0; i < MAX_ASSETS; i++) { }, }, async (_properties, context) => { + if(isScenarioWithMaticxAsset(context) && await isMaticxAsset(context, i)) { + return await testWithdrawCollateralMaticxSpecific(context, i); + } return await testWithdrawCollateral(context, i); } ); From 3cdb26327dc2c4b0edf4d77954f51d1d05e0ebb3 Mon Sep 17 00:00:00 2001 From: Mikhailo Shabodyash <67977488+EviLord032@users.noreply.github.com> Date: Fri, 10 May 2024 14:24:38 +0300 Subject: [PATCH 07/19] fix --- scenario/AddMaticxCollateralScenario.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scenario/AddMaticxCollateralScenario.ts b/scenario/AddMaticxCollateralScenario.ts index 8a0fd8932..2536b213d 100644 --- a/scenario/AddMaticxCollateralScenario.ts +++ b/scenario/AddMaticxCollateralScenario.ts @@ -9,8 +9,7 @@ import { createCrossChainProposal, matchesDeployment } from './utils'; const MATICX_ADDRESS = '0xfa68FB4628DFF1028CFEc22b4162FCcd0d45efb6'; const MATICX_PRICE_FEED_ADDRESS = '0x5d37E4b374E6907de8Fc7fb33EE3b0af403C7403'; const MATICX_WHALES = { - polygon: [ - '0x68B9220B8E617b7700aCAE1a5Ff43F3eb29257F3'], + polygon: ['0x68B9220B8E617b7700aCAE1a5Ff43F3eb29257F3'], }; // TODO: add ability to run ad hoc scenarios against a single migration, to avoid needing the scenario to do all this setup of From 8c57bb8bfb958e85eb16e059a97f7c747b64c185 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Sun, 12 May 2024 23:44:55 +0300 Subject: [PATCH 08/19] make code cleaner --- .../usdt/migrations/1713283675_configurate_and_ens.ts | 8 ++++---- deployments/polygon/usdt/relations.ts | 1 - scenario/WithdrawScenario.ts | 8 ++++---- scenario/constraints/ProposalConstraint.ts | 2 -- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts index 9a8ce2486..a62c2f00c 100644 --- a/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts +++ b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts @@ -49,7 +49,7 @@ export default migration('1713283675_configurate_and_ens', { timelock, governor } = await govDeploymentManager.getContracts(); - // console.log(await govDeploymentManager.getContracts()); + const configuration = await getConfigurationStruct(deploymentManager); const setFactoryCalldata = await calldata( configurator.populateTransaction.setFactory(comet.address, cometFactory.address) @@ -155,7 +155,7 @@ export default migration('1713283675_configurate_and_ens', { } ]; - const description = "# Initialize cUSDCv3 on Polygon\n\nThis proposal takes the governance steps recommended and necessary to initialize a Compound III USDC market on Polygon; upon execution, cUSDCv3 will be ready for use. Simulations have confirmed the market\u2019s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). Although real tests have also been run over the Goerli/Mumbai bridge, this will be the first proposal to actually bridge from Ethereum mainnet to another chain, and therefore includes risks not present in previous proposals.\n\nAlthough the proposal sets the entire configuration in the Configurator, the initial deployment already has most of these same parameters already set. The new parameters include setting the pause guardian to a Gnosis [multisig](https://app.safe.global/matic:0x8Ab717CAC3CbC4934E63825B88442F5810aAF6e5/home), which has been created on Polygon to match the same set of signers as currently on Ethereum mainnet. They also include risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/initialize-compound-iii-usdc-on-polygon-pos/3611/12). Finally, the parameters include a modest reallocation of some of the v2 USDT COMP rewards to borrowers in the new market.\n\nFurther detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/672) and [forum discussion](https://www.comp.xyz/t/initialize-compound-iii-usdc-on-polygon-pos/3611/11).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Polygon. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Polygon.\n\nThe second action approves Polygon's ERC20Predicate to take Timelock's USDC, in order to seed the market reserves through the bridge.\n\nThe third action deposits USDC from mainnet to the Polygon RootChainManager contract to bridge to Comet.\n\nThe fourth action approves Polygon's ERC20Predicate to take Timelock's COMP, in order to seed the rewards contract through the bridge.\n\nThe fifth action deposits COMP from mainnet to the Polygon RootChainManager contract to bridge to CometRewards. \n\nThe sixth action sets up the ENS subdomain `v3-additional-grants.compound-community-licenses.eth`, with the Timelock as the owner.\n\nThe seventh action writes the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, containing the official markets JSON.\n\nThe eighth action migrates the COMP distribution for v2 cUSDT suppliers, so as to keep the total COMP distribution constant.\n"; + const description = "# Initialize cUSDTv3 on Polygon\n\n## Proposal summary\n\nCompound Growth Program [AlphaGrowth] proposes the deployment of Compound III to the Polygon network. This proposal takes the governance steps recommended and necessary to initialize a Compound III USDT market on Polygon; upon execution, cUSDTv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based on the [recommendations from Gauntlet](https://www.comp.xyz/t/add-market-usdt-on-polygon/5190/3).\n\nFurther detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/850) and [forum discussion](https://www.comp.xyz/t/add-market-usdt-on-polygon/5190).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Polygon. This sends the encoded `setFactory`, `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Polygon. It also calls `setRewardConfig` on the Polygon rewards contract, to establish Polygon’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 8 COMP/day and borrow speed to be 4 COMP/day.\n\nThe second action reduces Compound [cUSDT](https://etherscan.io/address/0xf650c3d88d12db855b8bf7d11be6c55a4e07dcc9) reserves to Timelock, in order to seed the market reserves through the Polygon RootChainManager.\n\nThe third action approves Polygon’s [RootChainManager](https://etherscan.io/address/0xA0c68C638235ee32657e8f720a23ceC1bFc77C77) to take Timelock's USDT, in order to seed the reserves through the bridge.\n\nThe fourth action deposits 10K USDT from mainnet to the Polygon RootChainManager contract to bridge to Comet.\n\nThe fifth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Polygon cUSDTv3 market"; const txn = await govDeploymentManager.retry(async () => trace(await governor.propose(...(await proposal(mainnetActions, description)))) ); @@ -207,8 +207,8 @@ export default migration('1713283675_configurate_and_ens', { // WBTC: { // supplyCap: exp(90, 8) // }, - // baseTrackingSupplySpeed: exp(5 / 86400, 15, 18), - // baseTrackingBorrowSpeed: exp(5 / 86400, 15, 18), + // baseTrackingSupplySpeed: exp(8 / 86400, 15, 18), + // baseTrackingBorrowSpeed: exp(4 / 86400, 15, 18), // }); const config = await rewards.rewardConfig(comet.address); diff --git a/deployments/polygon/usdt/relations.ts b/deployments/polygon/usdt/relations.ts index fa64e195e..dda047633 100644 --- a/deployments/polygon/usdt/relations.ts +++ b/deployments/polygon/usdt/relations.ts @@ -14,7 +14,6 @@ export default { } } }, - // InitializableImmutableAdminUpgradeabilityProxy: { aPolMATICX: { artifact: 'contracts/ERC20.sol:ERC20', delegates: { diff --git a/scenario/WithdrawScenario.ts b/scenario/WithdrawScenario.ts index 572953d4c..80f61281c 100644 --- a/scenario/WithdrawScenario.ts +++ b/scenario/WithdrawScenario.ts @@ -1,8 +1,7 @@ import { CometContext, scenario } from './context/CometContext'; import { expect } from 'chai'; import { expectApproximately, expectRevertCustom, hasMinBorrowGreaterThanOne, isTriviallySourceable, isValidAssetIndex, MAX_ASSETS } from './utils'; -import { ContractReceipt } from 'ethers'; -import { ethers } from 'hardhat'; +import { ContractReceipt, BigNumber } from 'ethers'; async function testWithdrawCollateral(context: CometContext, assetNum: number): Promise { const comet = await context.getComet(); @@ -23,6 +22,7 @@ async function testWithdrawCollateral(context: CometContext, assetNum: number): return txn; // return txn to measure gas } +// some dust left in case of maticx asset async function testWithdrawCollateralMaticxSpecific(context: CometContext, assetNum: number): Promise { const comet = await context.getComet(); const { albert } = context.actors; @@ -30,13 +30,13 @@ async function testWithdrawCollateralMaticxSpecific(context: CometContext, asset const collateralAsset = context.getAssetByAddress(assetAddress); const scale = scaleBN.toBigInt(); - expect(await collateralAsset.balanceOf(albert.address)).to.be.closeTo(0n, ethers.BigNumber.from(10).pow(ethers.BigNumber.from(await collateralAsset.decimals()).div(2)).toBigInt()); + expect(await collateralAsset.balanceOf(albert.address)).to.be.closeTo(0n, BigNumber.from(10).pow(BigNumber.from(await collateralAsset.decimals()).div(2)).toBigInt()); expect(await comet.collateralBalanceOf(albert.address, collateralAsset.address)).to.be.equal(100n * scale); // Albert withdraws 100 units of collateral from Comet const txn = await albert.withdrawAsset({ asset: collateralAsset.address, amount: 100n * scale }); - expect(await collateralAsset.balanceOf(albert.address)).to.be.closeTo(100n * scale, ethers.BigNumber.from(10).pow(ethers.BigNumber.from(await collateralAsset.decimals()).div(2)).toBigInt()); + expect(await collateralAsset.balanceOf(albert.address)).to.be.closeTo(100n * scale, BigNumber.from(10).pow(BigNumber.from(await collateralAsset.decimals()).div(2)).toBigInt()); expect(await comet.collateralBalanceOf(albert.address, collateralAsset.address)).to.be.equal(0n); return txn; // return txn to measure gas diff --git a/scenario/constraints/ProposalConstraint.ts b/scenario/constraints/ProposalConstraint.ts index c8aeffbf0..39cf19386 100644 --- a/scenario/constraints/ProposalConstraint.ts +++ b/scenario/constraints/ProposalConstraint.ts @@ -66,13 +66,11 @@ export class ProposalConstraint implements StaticConstra // Execute the proposal debug(`${label} Processing pending proposal ${proposal.id}`); if (isBridged) { - if(![246, 247].includes(proposal.id.toNumber())){ await executeOpenProposalAndRelay( governanceDeploymentManager, ctx.world.deploymentManager, proposal ); - } } else { await executeOpenProposal(governanceDeploymentManager, proposal); } From 54dee614e3d90fb03b8bff56bde371c3c5a85949 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Sun, 12 May 2024 23:45:16 +0300 Subject: [PATCH 09/19] make code cleaner --- scenario/BulkerScenario.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scenario/BulkerScenario.ts b/scenario/BulkerScenario.ts index 7c9f39908..3e1d8795b 100644 --- a/scenario/BulkerScenario.ts +++ b/scenario/BulkerScenario.ts @@ -14,7 +14,7 @@ scenario( $asset1: 3000, }, tokenBalances: { - albert: { $base: '== 0', $asset0: 3000, $asset1: 3000 }, + albert: { $base: '== 0', $asset0: 3000, $asset1: 3000 }, // todo $comet: { $base: 5000 }, }, }, @@ -171,7 +171,7 @@ scenario( $asset1: 3000, }, tokenBalances: { - albert: { $base: '== 1000000', $asset0: 3000, $asset1: 3000}, + albert: { $base: '== 1000000', $asset0: 3000, $asset1: 3000}, // todo!! $comet: { $base: 5000 }, } }, From ef9038f9840ca5018fb53fe3b7b5aa61737cac5c Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Sun, 12 May 2024 23:51:56 +0300 Subject: [PATCH 10/19] make code cleaner --- scenario/LiquidationBotScenario.ts | 5 +++-- scenario/WithdrawScenario.ts | 6 +++--- scenario/constraints/ProposalConstraint.ts | 10 +++++----- src/deploy/index.ts | 5 ++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/scenario/LiquidationBotScenario.ts b/scenario/LiquidationBotScenario.ts index 48ddf195b..c5b4b6dc3 100644 --- a/scenario/LiquidationBotScenario.ts +++ b/scenario/LiquidationBotScenario.ts @@ -5,6 +5,7 @@ import { ethers, event, exp, wait } from '../test/helpers'; import CometActor from './context/CometActor'; import { CometInterface, OnChainLiquidator } from '../build/types'; import { getPoolConfig, flashLoanPools } from '../scripts/liquidation_bot/liquidateUnderwaterBorrowers'; +import { isScenarioWithMaticxAssetUsdtDeployment } from './WithdrawScenario'; interface LiquidationAddresses { balancerVault: string; @@ -556,7 +557,7 @@ scenario( cometBalances: async (ctx) => ( { albert: { - $asset0: ctx.world.base.network == 'polygon' && ctx.world.base.deployment == 'usdt'? ' == 20000': ' == 200' + $asset0: isScenarioWithMaticxAssetUsdtDeployment(ctx) ? ' == 20000': ' == 200' }, betty: { $base: 1000 }, } @@ -669,7 +670,7 @@ scenario( cometBalances: async (ctx) => ( { albert: { - $asset0: ctx.world.base.network == 'polygon' && ctx.world.base.deployment == 'usdt'? ' == 20000': ' == 200' + $asset0: isScenarioWithMaticxAssetUsdtDeployment(ctx) ? ' == 20000': ' == 200' }, betty: { $base: 1000 }, } diff --git a/scenario/WithdrawScenario.ts b/scenario/WithdrawScenario.ts index 80f61281c..9692a8151 100644 --- a/scenario/WithdrawScenario.ts +++ b/scenario/WithdrawScenario.ts @@ -1,6 +1,6 @@ import { CometContext, scenario } from './context/CometContext'; import { expect } from 'chai'; -import { expectApproximately, expectRevertCustom, hasMinBorrowGreaterThanOne, isTriviallySourceable, isValidAssetIndex, MAX_ASSETS } from './utils'; +import { expectApproximately, expectRevertCustom, hasMinBorrowGreaterThanOne, isTriviallySourceable, isValidAssetIndex, matchesDeployment, MAX_ASSETS } from './utils'; import { ContractReceipt, BigNumber } from 'ethers'; async function testWithdrawCollateral(context: CometContext, assetNum: number): Promise { @@ -63,7 +63,7 @@ async function testWithdrawFromCollateral(context: CometContext, assetNum: numbe return txn; // return txn to measure gas } -const isScenarioWithMaticxAsset = (context: CometContext) => { +export const isScenarioWithMaticxAssetUsdtDeployment = (context: CometContext) => { return context.world.deploymentManager.network === 'polygon' && context.world.deploymentManager.deployment === 'usdt'; }; @@ -84,7 +84,7 @@ for (let i = 0; i < MAX_ASSETS; i++) { }, }, async (_properties, context) => { - if(isScenarioWithMaticxAsset(context) && await isMaticxAsset(context, i)) { + if(isScenarioWithMaticxAssetUsdtDeployment(context) && await isMaticxAsset(context, i)) { return await testWithdrawCollateralMaticxSpecific(context, i); } return await testWithdrawCollateral(context, i); diff --git a/scenario/constraints/ProposalConstraint.ts b/scenario/constraints/ProposalConstraint.ts index 39cf19386..83e5c967d 100644 --- a/scenario/constraints/ProposalConstraint.ts +++ b/scenario/constraints/ProposalConstraint.ts @@ -66,11 +66,11 @@ export class ProposalConstraint implements StaticConstra // Execute the proposal debug(`${label} Processing pending proposal ${proposal.id}`); if (isBridged) { - await executeOpenProposalAndRelay( - governanceDeploymentManager, - ctx.world.deploymentManager, - proposal - ); + await executeOpenProposalAndRelay( + governanceDeploymentManager, + ctx.world.deploymentManager, + proposal + ); } else { await executeOpenProposal(governanceDeploymentManager, proposal); } diff --git a/src/deploy/index.ts b/src/deploy/index.ts index 79a1b0bc3..fac286f4c 100644 --- a/src/deploy/index.ts +++ b/src/deploy/index.ts @@ -77,8 +77,7 @@ export const COMP_WHALES = { '0x54A37d93E57c5DA659F508069Cf65A381b61E189' ], - testnet: ['0xbbfe34e868343e6f4f5e8b5308de980d7bd88c46'], - + testnet: ['0xbbfe34e868343e6f4f5e8b5308de980d7bd88c46'] }; export const WHALES = { @@ -95,7 +94,7 @@ export const WHALES = { '0x2093b4281990a568c9d588b8bce3bfd7a1557ebd', // WETH whale '0xd814b26554204245a30f8a42c289af582421bf04', // WBTC whale '0x167384319b41f7094e62f7506409eb38079abff8', // WMATIC whale - '0xF977814e90dA44bFA03b6295A0616a897441aceC' + '0xF977814e90dA44bFA03b6295A0616a897441aceC' // matic, wmatic, weth, usdt ], arbitrum: [ '0xf89d7b9c864f589bbf53a82105107622b35eaa40', // USDC whale From bafab7eb58bda0a406794efd2db8fe234c2fe692 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Mon, 13 May 2024 17:29:10 +0300 Subject: [PATCH 11/19] make eslint work --- scenario/WithdrawScenario.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scenario/WithdrawScenario.ts b/scenario/WithdrawScenario.ts index 9692a8151..07166f771 100644 --- a/scenario/WithdrawScenario.ts +++ b/scenario/WithdrawScenario.ts @@ -1,6 +1,6 @@ import { CometContext, scenario } from './context/CometContext'; import { expect } from 'chai'; -import { expectApproximately, expectRevertCustom, hasMinBorrowGreaterThanOne, isTriviallySourceable, isValidAssetIndex, matchesDeployment, MAX_ASSETS } from './utils'; +import { expectApproximately, expectRevertCustom, hasMinBorrowGreaterThanOne, isTriviallySourceable, isValidAssetIndex, MAX_ASSETS } from './utils'; import { ContractReceipt, BigNumber } from 'ethers'; async function testWithdrawCollateral(context: CometContext, assetNum: number): Promise { From ee77acc217bbf3a24e183e52278ca4c5791bbbd8 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot <> Date: Tue, 4 Jun 2024 10:13:50 +0000 Subject: [PATCH 12/19] Modified deployment roots from GitHub Actions --- deployments/polygon/usdt/roots.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/deployments/polygon/usdt/roots.json b/deployments/polygon/usdt/roots.json index 0967ef424..dc81145c5 100644 --- a/deployments/polygon/usdt/roots.json +++ b/deployments/polygon/usdt/roots.json @@ -1 +1,9 @@ -{} +{ + "comet": "0x4A900f81dEdA753bbBab12453b3775D5f26df6F3", + "configurator": "0x83E0F742cAcBE66349E3701B171eE2487a26e738", + "rewards": "0x45939657d1CA34A8FA39A924B71D28Fe8431e581", + "bridgeReceiver": "0x18281dfC4d00905DA1aaA6731414EABa843c468A", + "bulker": "0x59e242D352ae13166B4987aE5c990C232f7f7CD6", + "fxChild": "0x8397259c983751DAf40400790063935a11afa28a", + "COMP": "0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c" +} \ No newline at end of file From 482b142b3e6e660f0f661f79f01c90c702dee7e5 Mon Sep 17 00:00:00 2001 From: Mikhailo Shabodyash <67977488+EviLord032@users.noreply.github.com> Date: Tue, 4 Jun 2024 14:39:50 +0300 Subject: [PATCH 13/19] feat: add configuration and fix supply scenario --- .github/workflows/enact-migration.yaml | 17 ++++++- deployments/polygon/usdt/configuration.json | 14 ++--- .../1713283675_configurate_and_ens.ts | 38 +++++++------- scenario/SupplyScenario.ts | 51 +++++++++++++++++++ 4 files changed, 93 insertions(+), 27 deletions(-) diff --git a/.github/workflows/enact-migration.yaml b/.github/workflows/enact-migration.yaml index 1b1558688..6842ba074 100644 --- a/.github/workflows/enact-migration.yaml +++ b/.github/workflows/enact-migration.yaml @@ -36,6 +36,10 @@ on: description: Run ID for Artifact eth_pk: description: Ignore if you plan to use WalletConnect, otherwise, you can paste in a Ethereum private key + impersonateAccount: + description: Impersonate Account + required: false + default: '' jobs: enact-migration: name: Enact Migration @@ -114,7 +118,18 @@ jobs: GOV_NETWORK_PROVIDER: ${{ fromJSON('["", "http://localhost:8685"]')[github.event.inputs.eth_pk == '' && env.GOV_NETWORK != ''] }} GOV_NETWORK: ${{ env.GOV_NETWORK }} REMOTE_ACCOUNTS: ${{ fromJSON('["", "true"]')[github.event.inputs.eth_pk == ''] }} - + if: github.event.inputs.impersonateAccount == '' + - name: Run Enact Migration (impersonate) + run: | + yarn hardhat migrate --network ${{ github.event.inputs.network }} --deployment ${{ github.event.inputs.deployment }} --enact --overwrite ${{ fromJSON('["", "--simulate"]')[github.event.inputs.simulate == 'true'] }} ${{ fromJSON('["", "--no-enacted"]')[github.event.inputs.no_enacted == 'true'] }} ${{ github.event.inputs.migration }} --impersonate ${{ github.event.inputs.impersonateAccount }} + env: + DEBUG: true + ETH_PK: "${{ inputs.eth_pk }}" + NETWORK_PROVIDER: ${{ fromJSON('["", "http://localhost:8585"]')[github.event.inputs.eth_pk == ''] }} + GOV_NETWORK_PROVIDER: ${{ fromJSON('["", "http://localhost:8685"]')[github.event.inputs.eth_pk == '' && env.GOV_NETWORK != ''] }} + GOV_NETWORK: ${{ env.GOV_NETWORK }} + REMOTE_ACCOUNTS: ${{ fromJSON('["", "true"]')[github.event.inputs.eth_pk == ''] }} + if: github.event.inputs.impersonateAccount != '' - name: Commit changes if: ${{ github.event.inputs.simulate == 'false' }} run: | diff --git a/deployments/polygon/usdt/configuration.json b/deployments/polygon/usdt/configuration.json index 6f6f8d382..e5635097e 100644 --- a/deployments/polygon/usdt/configuration.json +++ b/deployments/polygon/usdt/configuration.json @@ -21,8 +21,8 @@ }, "tracking": { "indexScale": "1e15", - "baseSupplySpeed": "0e15", - "baseBorrowSpeed": "0e15", + "baseSupplySpeed": "92592592592e0", + "baseBorrowSpeed": "46296296296e0", "baseMinForRewards": "1000000e6" }, "rewardTokenAddress": "0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c", @@ -34,7 +34,7 @@ "borrowCF": 0.65, "liquidateCF": 0.80, "liquidationFactor": 0.85, - "supplyCap": "0e18" + "supplyCap": "5000000e18" }, "WETH": { "address": "0x7ceb23fd6bc0add59e62ac25578270cff1b9f619", @@ -43,7 +43,7 @@ "borrowCF": 0.80, "liquidateCF": 0.85, "liquidationFactor": 0.95, - "supplyCap": "0e18" + "supplyCap": "2000e18" }, "aPolMATICX": { "address": "0x80cA0d8C38d2e2BcbaB66aA1648Bd1C7160500FE", @@ -52,7 +52,7 @@ "borrowCF": 0.60, "liquidateCF": 0.70, "liquidationFactor": 0.80, - "supplyCap": "0e18" + "supplyCap": "2600000e18" }, "stMATIC": { "address": "0x3A58a54C066FdC0f2D55FC9C89F0415C92eBf3C4", @@ -61,7 +61,7 @@ "borrowCF": 0.60, "liquidateCF": 0.70, "liquidationFactor": 0.80, - "supplyCap": "0e18" + "supplyCap": "1500000e18" }, "WBTC": { "address": "0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6", @@ -70,7 +70,7 @@ "borrowCF": 0.75, "liquidateCF": 0.85, "liquidationFactor": 0.90, - "supplyCap": "0e8" + "supplyCap": "90e8" } } } \ No newline at end of file diff --git a/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts index a62c2f00c..65a65ffc9 100644 --- a/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts +++ b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts @@ -191,25 +191,25 @@ export default migration('1713283675_configurate_and_ens', { const stateChanges = await diffState(comet, getCometConfig, preMigrationBlockNumber); // uncomment on on-chain proposal PR - // expect(stateChanges).to.deep.equal({ - // WMATIC: { - // supplyCap: exp(5_000_000, 18) - // }, - // WETH: { - // supplyCap: exp(2_000, 18) - // }, - // aPolMATICX: { - // supplyCap: exp(2_600_000, 18), - // }, - // stMATIC: { - // supplyCap: exp(1_500_000, 18) - // }, - // WBTC: { - // supplyCap: exp(90, 8) - // }, - // baseTrackingSupplySpeed: exp(8 / 86400, 15, 18), - // baseTrackingBorrowSpeed: exp(4 / 86400, 15, 18), - // }); + expect(stateChanges).to.deep.equal({ + WMATIC: { + supplyCap: exp(5_000_000, 18) + }, + WETH: { + supplyCap: exp(2_000, 18) + }, + aPolMATICX: { + supplyCap: exp(2_600_000, 18), + }, + stMATIC: { + supplyCap: exp(1_500_000, 18) + }, + WBTC: { + supplyCap: exp(90, 8) + }, + baseTrackingSupplySpeed: exp(8 / 86400, 15, 18), + baseTrackingBorrowSpeed: exp(4 / 86400, 15, 18), + }); const config = await rewards.rewardConfig(comet.address); expect(config.token).to.be.equal(COMP.address); diff --git a/scenario/SupplyScenario.ts b/scenario/SupplyScenario.ts index 4121a1865..8f1827e31 100644 --- a/scenario/SupplyScenario.ts +++ b/scenario/SupplyScenario.ts @@ -2,6 +2,7 @@ import { CometContext, scenario } from './context/CometContext'; import { expect } from 'chai'; import { expectApproximately, expectBase, expectRevertCustom, expectRevertMatches, getExpectedBaseBalance, getInterest, isTriviallySourceable, isValidAssetIndex, MAX_ASSETS, UINT256_MAX } from './utils'; import { ContractReceipt } from 'ethers'; +import { BigNumber } from 'ethers'; // XXX introduce a SupplyCapConstraint to separately test the happy path and revert path instead // of testing them conditionally @@ -36,6 +37,42 @@ async function testSupplyCollateral(context: CometContext, assetNum: number): Pr } } +async function testSupplyFromCollateralMaticxSpecific(context: CometContext, assetNum: number): Promise { + const comet = await context.getComet(); + const { albert, betty } = await context.actors; + const { asset: assetAddress, scale: scaleBN, supplyCap } = await comet.getAssetInfo(assetNum); + const collateralAsset = context.getAssetByAddress(assetAddress); + const scale = scaleBN.toBigInt(); + const toSupply = 100n * scale; + + expect(await collateralAsset.balanceOf(albert.address)).to.be.equal(toSupply); + expect(await comet.collateralBalanceOf(betty.address, collateralAsset.address)).to.be.equal(0n); + + await collateralAsset.approve(albert, comet.address); + await albert.allow(betty, true); + + const totalCollateralSupply = (await comet.totalsCollateral(collateralAsset.address)).totalSupplyAsset.toBigInt(); + if (totalCollateralSupply + toSupply > supplyCap.toBigInt()) { + await expectRevertCustom( + betty.supplyAssetFrom({ + src: albert.address, + dst: betty.address, + asset: collateralAsset.address, + amount: toSupply, + }), + 'SupplyCapExceeded()' + ); + } else { + // Betty supplies 100 units of collateral from Albert + const txn = await betty.supplyAssetFrom({ src: albert.address, dst: betty.address, asset: collateralAsset.address, amount: toSupply }); + + expect(await collateralAsset.balanceOf(albert.address)).to.be.closeTo(0n, BigNumber.from(10).pow(BigNumber.from(await collateralAsset.decimals() - 1).div(2)).toBigInt()); + expect(await comet.collateralBalanceOf(betty.address, collateralAsset.address)).to.be.equal(toSupply); + + return txn; // return txn to measure gas + } +} + async function testSupplyFromCollateral(context: CometContext, assetNum: number): Promise { const comet = await context.getComet(); const { albert, betty } = await context.actors; @@ -91,6 +128,17 @@ for (let i = 0; i < MAX_ASSETS; i++) { ); } + +export const isScenarioWithMaticxAssetUsdtDeployment = (context: CometContext) => { + return context.world.deploymentManager.network === 'polygon' && context.world.deploymentManager.deployment === 'usdt'; +}; + +const isMaticxAsset = async (context: CometContext, i: number) => { + const { asset: assetAddress, } = await (await context.getComet()).getAssetInfo(i); + const collateralAsset = context.getAssetByAddress(assetAddress); + return await collateralAsset.token.symbol() === 'aPolMATICX'; +}; + for (let i = 0; i < MAX_ASSETS; i++) { const amountToSupply = 100; // in units of asset, not wei scenario( @@ -102,6 +150,9 @@ for (let i = 0; i < MAX_ASSETS; i++) { }, }, async (_properties, context) => { + if(isScenarioWithMaticxAssetUsdtDeployment(context) && await isMaticxAsset(context, i)) { + return await testSupplyFromCollateralMaticxSpecific(context, i); + } return await testSupplyFromCollateral(context, i); } ); From a3e275887a9b713a5f53e3d0b57667aa9ade2b67 Mon Sep 17 00:00:00 2001 From: Mikhailo Shabodyash <67977488+EviLord032@users.noreply.github.com> Date: Tue, 4 Jun 2024 15:31:53 +0300 Subject: [PATCH 14/19] Update 1713283675_configurate_and_ens.ts --- .../polygon/usdt/migrations/1713283675_configurate_and_ens.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts index 65a65ffc9..8ef1a0d99 100644 --- a/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts +++ b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts @@ -155,7 +155,7 @@ export default migration('1713283675_configurate_and_ens', { } ]; - const description = "# Initialize cUSDTv3 on Polygon\n\n## Proposal summary\n\nCompound Growth Program [AlphaGrowth] proposes the deployment of Compound III to the Polygon network. This proposal takes the governance steps recommended and necessary to initialize a Compound III USDT market on Polygon; upon execution, cUSDTv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based on the [recommendations from Gauntlet](https://www.comp.xyz/t/add-market-usdt-on-polygon/5190/3).\n\nFurther detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/850) and [forum discussion](https://www.comp.xyz/t/add-market-usdt-on-polygon/5190).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Polygon. This sends the encoded `setFactory`, `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Polygon. It also calls `setRewardConfig` on the Polygon rewards contract, to establish Polygon’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 8 COMP/day and borrow speed to be 4 COMP/day.\n\nThe second action reduces Compound [cUSDT](https://etherscan.io/address/0xf650c3d88d12db855b8bf7d11be6c55a4e07dcc9) reserves to Timelock, in order to seed the market reserves through the Polygon RootChainManager.\n\nThe third action approves Polygon’s [RootChainManager](https://etherscan.io/address/0xA0c68C638235ee32657e8f720a23ceC1bFc77C77) to take Timelock's USDT, in order to seed the reserves through the bridge.\n\nThe fourth action deposits 10K USDT from mainnet to the Polygon RootChainManager contract to bridge to Comet.\n\nThe fifth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Polygon cUSDTv3 market"; + const description = "# Initialize cUSDTv3 on Polygon\n\n## Proposal summary\n\nCompound Growth Program [AlphaGrowth] proposes the deployment of Compound III to the Polygon network. This proposal takes the governance steps recommended and necessary to initialize a Compound III USDT market on Polygon; upon execution, cUSDTv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based on the [recommendations from Gauntlet](https://www.comp.xyz/t/add-market-usdt-on-polygon/5190/3).\n\nFurther detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/850), [market deployment action](https://github.com/woof-software/comet/actions/runs/9365232640) and [forum discussion](https://www.comp.xyz/t/add-market-usdt-on-polygon/5190).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Polygon. This sends the encoded `setFactory`, `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Polygon. It also calls `setRewardConfig` on the Polygon rewards contract, to establish Polygon’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 8 COMP/day and borrow speed to be 4 COMP/day.\n\nThe second action reduces Compound [cUSDT](https://etherscan.io/address/0xf650c3d88d12db855b8bf7d11be6c55a4e07dcc9) reserves to Timelock, in order to seed the market reserves through the Polygon RootChainManager.\n\nThe third action approves Polygon’s [RootChainManager](https://etherscan.io/address/0xA0c68C638235ee32657e8f720a23ceC1bFc77C77) to take Timelock's USDT, in order to seed the reserves through the bridge.\n\nThe fourth action deposits 10K USDT from mainnet to the Polygon RootChainManager contract to bridge to Comet.\n\nThe fifth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Polygon cUSDTv3 market"; const txn = await govDeploymentManager.retry(async () => trace(await governor.propose(...(await proposal(mainnetActions, description)))) ); @@ -190,7 +190,6 @@ export default migration('1713283675_configurate_and_ens', { const stateChanges = await diffState(comet, getCometConfig, preMigrationBlockNumber); - // uncomment on on-chain proposal PR expect(stateChanges).to.deep.equal({ WMATIC: { supplyCap: exp(5_000_000, 18) From a7f585b4756c2ff517ec4600bc95d69f2deb986a Mon Sep 17 00:00:00 2001 From: Mikhailo Shabodyash <67977488+EviLord032@users.noreply.github.com> Date: Tue, 4 Jun 2024 15:34:19 +0300 Subject: [PATCH 15/19] Update 1713283675_configurate_and_ens.ts --- .../polygon/usdt/migrations/1713283675_configurate_and_ens.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts index 8ef1a0d99..e46faf4b8 100644 --- a/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts +++ b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts @@ -155,7 +155,7 @@ export default migration('1713283675_configurate_and_ens', { } ]; - const description = "# Initialize cUSDTv3 on Polygon\n\n## Proposal summary\n\nCompound Growth Program [AlphaGrowth] proposes the deployment of Compound III to the Polygon network. This proposal takes the governance steps recommended and necessary to initialize a Compound III USDT market on Polygon; upon execution, cUSDTv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based on the [recommendations from Gauntlet](https://www.comp.xyz/t/add-market-usdt-on-polygon/5190/3).\n\nFurther detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/850), [market deployment action](https://github.com/woof-software/comet/actions/runs/9365232640) and [forum discussion](https://www.comp.xyz/t/add-market-usdt-on-polygon/5190).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Polygon. This sends the encoded `setFactory`, `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Polygon. It also calls `setRewardConfig` on the Polygon rewards contract, to establish Polygon’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 8 COMP/day and borrow speed to be 4 COMP/day.\n\nThe second action reduces Compound [cUSDT](https://etherscan.io/address/0xf650c3d88d12db855b8bf7d11be6c55a4e07dcc9) reserves to Timelock, in order to seed the market reserves through the Polygon RootChainManager.\n\nThe third action approves Polygon’s [RootChainManager](https://etherscan.io/address/0xA0c68C638235ee32657e8f720a23ceC1bFc77C77) to take Timelock's USDT, in order to seed the reserves through the bridge.\n\nThe fourth action deposits 10K USDT from mainnet to the Polygon RootChainManager contract to bridge to Comet.\n\nThe fifth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Polygon cUSDTv3 market"; + const description = "# Initialize cUSDTv3 on Polygon\n\n## Proposal summary\n\nCompound Growth Program [AlphaGrowth] proposes the deployment of Compound III to the Polygon network. This proposal takes the governance steps recommended and necessary to initialize a Compound III USDT market on Polygon; upon execution, cUSDTv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based on the [recommendations from Gauntlet](https://www.comp.xyz/t/add-market-usdt-on-polygon/5190/3).\n\nFurther detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/858), [market deployment action](https://github.com/woof-software/comet/actions/runs/9365232640) and [forum discussion](https://www.comp.xyz/t/add-market-usdt-on-polygon/5190).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Polygon. This sends the encoded `setFactory`, `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Polygon. It also calls `setRewardConfig` on the Polygon rewards contract, to establish Polygon’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 8 COMP/day and borrow speed to be 4 COMP/day.\n\nThe second action reduces Compound [cUSDT](https://etherscan.io/address/0xf650c3d88d12db855b8bf7d11be6c55a4e07dcc9) reserves to Timelock, in order to seed the market reserves through the Polygon RootChainManager.\n\nThe third action approves Polygon’s [RootChainManager](https://etherscan.io/address/0xA0c68C638235ee32657e8f720a23ceC1bFc77C77) to take Timelock's USDT, in order to seed the reserves through the bridge.\n\nThe fourth action deposits 10K USDT from mainnet to the Polygon RootChainManager contract to bridge to Comet.\n\nThe fifth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Polygon cUSDTv3 market"; const txn = await govDeploymentManager.retry(async () => trace(await governor.propose(...(await proposal(mainnetActions, description)))) ); From e1922588b2e8d6db0de9366d89b17419549b21c8 Mon Sep 17 00:00:00 2001 From: Mikhailo Shabodyash Date: Fri, 21 Jun 2024 16:12:52 +0300 Subject: [PATCH 16/19] fix: update ENS and clean up --- .../1713283675_configurate_and_ens.ts | 53 ++++++++++++------- scenario/BulkerScenario.ts | 4 +- scenario/LiquidationBotScenario.ts | 38 ------------- .../liquidateUnderwaterBorrowers.ts | 3 +- src/deploy/index.ts | 3 +- 5 files changed, 38 insertions(+), 63 deletions(-) diff --git a/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts index e46faf4b8..8f735c6ed 100644 --- a/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts +++ b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts @@ -88,6 +88,12 @@ export default migration('1713283675_configurate_and_ens', { const newMarketObject = { baseSymbol: 'USDT', cometAddress: comet.address }; const officialMarketsJSON = JSON.parse(await ENSResolver.text(subdomainHash, ENSTextRecordKey)); + // add arbitrum-weth comet (0x6f7D514bbD4aFf3BcD1140B7344b32f063dEe486) + // arbitrum chain id is 42161 + if (!(officialMarketsJSON[42161].find(market => market.baseSymbol === 'WETH'))) { + officialMarketsJSON[42161].push({ baseSymbol: 'WETH', cometAddress: '0x6f7D514bbD4aFf3BcD1140B7344b32f063dEe486' }); + } + if (officialMarketsJSON[polygonChainId]) { officialMarketsJSON[polygonChainId].push(newMarketObject); } else { @@ -190,25 +196,26 @@ export default migration('1713283675_configurate_and_ens', { const stateChanges = await diffState(comet, getCometConfig, preMigrationBlockNumber); - expect(stateChanges).to.deep.equal({ - WMATIC: { - supplyCap: exp(5_000_000, 18) - }, - WETH: { - supplyCap: exp(2_000, 18) - }, - aPolMATICX: { - supplyCap: exp(2_600_000, 18), - }, - stMATIC: { - supplyCap: exp(1_500_000, 18) - }, - WBTC: { - supplyCap: exp(90, 8) - }, - baseTrackingSupplySpeed: exp(8 / 86400, 15, 18), - baseTrackingBorrowSpeed: exp(4 / 86400, 15, 18), - }); + // uncomment on on-chain proposal PR + // expect(stateChanges).to.deep.equal({ + // WMATIC: { + // supplyCap: exp(5_000_000, 18) + // }, + // WETH: { + // supplyCap: exp(2_000, 18) + // }, + // aPolMATICX: { + // supplyCap: exp(2_600_000, 18), + // }, + // stMATIC: { + // supplyCap: exp(1_500_000, 18) + // }, + // WBTC: { + // supplyCap: exp(90, 8) + // }, + // baseTrackingSupplySpeed: exp(8 / 86400, 15, 18), + // baseTrackingBorrowSpeed: exp(4 / 86400, 15, 18), + // }); const config = await rewards.rewardConfig(comet.address); expect(config.token).to.be.equal(COMP.address); @@ -273,6 +280,10 @@ export default migration('1713283675_configurate_and_ens', { baseSymbol: 'USDC', cometAddress: '0x9c4ec768c28520B50860ea7a15bd7213a9fF58bf', }, + { + baseSymbol: 'WETH', + cometAddress: '0x6f7D514bbD4aFf3BcD1140B7344b32f063dEe486', + }, ], 534352: [ { @@ -285,6 +296,10 @@ export default migration('1713283675_configurate_and_ens', { baseSymbol: 'USDC', cometAddress: '0x2e44e174f7D53F0212823acC11C01A11d58c5bCB', }, + { + baseSymbol: 'USDT', + cometAddress: '0x995E394b8B2437aC8Ce61Ee0bC610D617962B214', + }, ], }); } diff --git a/scenario/BulkerScenario.ts b/scenario/BulkerScenario.ts index 3e1d8795b..7c9f39908 100644 --- a/scenario/BulkerScenario.ts +++ b/scenario/BulkerScenario.ts @@ -14,7 +14,7 @@ scenario( $asset1: 3000, }, tokenBalances: { - albert: { $base: '== 0', $asset0: 3000, $asset1: 3000 }, // todo + albert: { $base: '== 0', $asset0: 3000, $asset1: 3000 }, $comet: { $base: 5000 }, }, }, @@ -171,7 +171,7 @@ scenario( $asset1: 3000, }, tokenBalances: { - albert: { $base: '== 1000000', $asset0: 3000, $asset1: 3000}, // todo!! + albert: { $base: '== 1000000', $asset0: 3000, $asset1: 3000}, $comet: { $base: 5000 }, } }, diff --git a/scenario/LiquidationBotScenario.ts b/scenario/LiquidationBotScenario.ts index c5b4b6dc3..4d15383ca 100644 --- a/scenario/LiquidationBotScenario.ts +++ b/scenario/LiquidationBotScenario.ts @@ -98,7 +98,6 @@ for (let i = 0; i < MAX_ASSETS; i++) { }, polygon: { usdc: 2250000, - usdt: 2250000 }, arbitrum: { 'usdc.e': 10000000, @@ -137,18 +136,6 @@ for (let i = 0; i < MAX_ASSETS; i++) { // MATICX ' == 0', ], - usdt: [ - // WMATIC - ' == 300000', - // WETH - ' == 400', - // MATICX - ' == 300000', - // stMATIC - ' == 300000', - // WBTC - ' == 20' - ], }, arbitrum: { 'usdc.e': [ @@ -296,7 +283,6 @@ for (let i = 0; i < MAX_ASSETS; i++) { }, polygon: { usdc: 3000000, - usdt: 3000000 }, arbitrum: { 'usdc.e': 10000000, @@ -335,18 +321,6 @@ for (let i = 0; i < MAX_ASSETS; i++) { // MATICX ' == 0', ], - usdt: [ - // WMATIC - ' == 25000000', - // WETH - ' == 10000', - // MATICX - ' == 25000000', - // stMATIC - ' == 25000000', - // WBTC - ' == 1000' - ] }, arbitrum: { 'usdc.e': [ @@ -403,18 +377,6 @@ for (let i = 0; i < MAX_ASSETS; i++) { // MATICX exp(5, 18) ], - usdt: [ - // WMATIC - exp(50000, 18), - // WETH - exp(4000, 18), - // MATICX - exp(50000, 18), - // stMATIC - exp(50000, 18), - // WBTC - exp(200, 8) - ] }, arbitrum: { 'usdc.e': [ diff --git a/scripts/liquidation_bot/liquidateUnderwaterBorrowers.ts b/scripts/liquidation_bot/liquidateUnderwaterBorrowers.ts index ab1b4d8af..a0746a263 100644 --- a/scripts/liquidation_bot/liquidateUnderwaterBorrowers.ts +++ b/scripts/liquidation_bot/liquidateUnderwaterBorrowers.ts @@ -70,8 +70,7 @@ const liquidationThresholds = { 'usdc': 10e6 }, polygon: { - 'usdc': 10e6, - 'usdt': 10e6 + 'usdc': 10e6 }, arbitrum: { 'usdc.e': 10e6, diff --git a/src/deploy/index.ts b/src/deploy/index.ts index fac286f4c..209bfff19 100644 --- a/src/deploy/index.ts +++ b/src/deploy/index.ts @@ -93,8 +93,7 @@ export const WHALES = { polygon: [ '0x2093b4281990a568c9d588b8bce3bfd7a1557ebd', // WETH whale '0xd814b26554204245a30f8a42c289af582421bf04', // WBTC whale - '0x167384319b41f7094e62f7506409eb38079abff8', // WMATIC whale - '0xF977814e90dA44bFA03b6295A0616a897441aceC' // matic, wmatic, weth, usdt + '0x167384319b41f7094e62f7506409eb38079abff8' // WMATIC whale ], arbitrum: [ '0xf89d7b9c864f589bbf53a82105107622b35eaa40', // USDC whale From c947c573b9928f6b1f1dd9df04e844208c3f7e99 Mon Sep 17 00:00:00 2001 From: Mikhailo Shabodyash Date: Fri, 21 Jun 2024 16:47:58 +0300 Subject: [PATCH 17/19] fix: more clean up --- .../1713283675_configurate_and_ens.ts | 39 +++++++++---------- scenario/LiquidationBotScenario.ts | 8 ++-- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts index 8f735c6ed..ce1371356 100644 --- a/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts +++ b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts @@ -196,26 +196,25 @@ export default migration('1713283675_configurate_and_ens', { const stateChanges = await diffState(comet, getCometConfig, preMigrationBlockNumber); - // uncomment on on-chain proposal PR - // expect(stateChanges).to.deep.equal({ - // WMATIC: { - // supplyCap: exp(5_000_000, 18) - // }, - // WETH: { - // supplyCap: exp(2_000, 18) - // }, - // aPolMATICX: { - // supplyCap: exp(2_600_000, 18), - // }, - // stMATIC: { - // supplyCap: exp(1_500_000, 18) - // }, - // WBTC: { - // supplyCap: exp(90, 8) - // }, - // baseTrackingSupplySpeed: exp(8 / 86400, 15, 18), - // baseTrackingBorrowSpeed: exp(4 / 86400, 15, 18), - // }); + expect(stateChanges).to.deep.equal({ + WMATIC: { + supplyCap: exp(5_000_000, 18) + }, + WETH: { + supplyCap: exp(2_000, 18) + }, + aPolMATICX: { + supplyCap: exp(2_600_000, 18), + }, + stMATIC: { + supplyCap: exp(1_500_000, 18) + }, + WBTC: { + supplyCap: exp(90, 8) + }, + baseTrackingSupplySpeed: exp(8 / 86400, 15, 18), + baseTrackingBorrowSpeed: exp(4 / 86400, 15, 18), + }); const config = await rewards.rewardConfig(comet.address); expect(config.token).to.be.equal(COMP.address); diff --git a/scenario/LiquidationBotScenario.ts b/scenario/LiquidationBotScenario.ts index 4d15383ca..7bc6ea6ff 100644 --- a/scenario/LiquidationBotScenario.ts +++ b/scenario/LiquidationBotScenario.ts @@ -97,7 +97,7 @@ for (let i = 0; i < MAX_ASSETS; i++) { weth: 20 }, polygon: { - usdc: 2250000, + usdc: 2250000 }, arbitrum: { 'usdc.e': 10000000, @@ -282,7 +282,7 @@ for (let i = 0; i < MAX_ASSETS; i++) { weth: 5000 }, polygon: { - usdc: 3000000, + usdc: 3000000 }, arbitrum: { 'usdc.e': 10000000, @@ -320,7 +320,7 @@ for (let i = 0; i < MAX_ASSETS; i++) { ' == 2500000', // MATICX ' == 0', - ], + ] }, arbitrum: { 'usdc.e': [ @@ -376,7 +376,7 @@ for (let i = 0; i < MAX_ASSETS; i++) { exp(5000, 18), // MATICX exp(5, 18) - ], + ] }, arbitrum: { 'usdc.e': [ From f51c536ae1221c43e4b17d2e5dc4f3a0c4c99149 Mon Sep 17 00:00:00 2001 From: Mikhailo Shabodyash Date: Sat, 22 Jun 2024 18:20:30 +0300 Subject: [PATCH 18/19] fix: use maticx instead of apollmaticx --- deployments/polygon/usdt/configuration.json | 22 +++---- .../1713283675_configurate_and_ens.ts | 58 ++++++++++++------- deployments/polygon/usdt/relations.ts | 8 --- deployments/polygon/usdt/roots.json | 10 +--- scenario/LiquidationBotScenario.ts | 29 ++++------ scenario/SupplyScenario.ts | 51 ---------------- scenario/WithdrawScenario.ts | 35 +---------- 7 files changed, 61 insertions(+), 152 deletions(-) diff --git a/deployments/polygon/usdt/configuration.json b/deployments/polygon/usdt/configuration.json index e5635097e..5c16b8ec0 100644 --- a/deployments/polygon/usdt/configuration.json +++ b/deployments/polygon/usdt/configuration.json @@ -4,7 +4,7 @@ "baseToken": "USDT", "baseTokenAddress": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F", "baseTokenPriceFeed": "0x0A6513e40db6EB1b165753AD52E80663aeA50545", - "borrowMin": "100e6", + "borrowMin": "1e6", "governor": "0xCC3E7c85Bb0EE4f09380e041fee95a0caeDD4a02", "pauseGuardian": "0x8Ab717CAC3CbC4934E63825B88442F5810aAF6e5", "storeFrontPriceFactor": 0.6, @@ -21,9 +21,9 @@ }, "tracking": { "indexScale": "1e15", - "baseSupplySpeed": "92592592592e0", - "baseBorrowSpeed": "46296296296e0", - "baseMinForRewards": "1000000e6" + "baseSupplySpeed": "0e0", + "baseBorrowSpeed": "0e0", + "baseMinForRewards": "10000e6" }, "rewardTokenAddress": "0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c", "assets": { @@ -34,7 +34,7 @@ "borrowCF": 0.65, "liquidateCF": 0.80, "liquidationFactor": 0.85, - "supplyCap": "5000000e18" + "supplyCap": "0e18" }, "WETH": { "address": "0x7ceb23fd6bc0add59e62ac25578270cff1b9f619", @@ -43,16 +43,16 @@ "borrowCF": 0.80, "liquidateCF": 0.85, "liquidationFactor": 0.95, - "supplyCap": "2000e18" + "supplyCap": "0e18" }, - "aPolMATICX": { - "address": "0x80cA0d8C38d2e2BcbaB66aA1648Bd1C7160500FE", + "MaticX": { + "address": "0xfa68FB4628DFF1028CFEc22b4162FCcd0d45efb6", "priceFeed": "0x5d37E4b374E6907de8Fc7fb33EE3b0af403C7403", "decimals": "18", "borrowCF": 0.60, "liquidateCF": 0.70, "liquidationFactor": 0.80, - "supplyCap": "2600000e18" + "supplyCap": "0e18" }, "stMATIC": { "address": "0x3A58a54C066FdC0f2D55FC9C89F0415C92eBf3C4", @@ -61,7 +61,7 @@ "borrowCF": 0.60, "liquidateCF": 0.70, "liquidationFactor": 0.80, - "supplyCap": "1500000e18" + "supplyCap": "0e18" }, "WBTC": { "address": "0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6", @@ -70,7 +70,7 @@ "borrowCF": 0.75, "liquidateCF": 0.85, "liquidationFactor": 0.90, - "supplyCap": "90e8" + "supplyCap": "0e8" } } } \ No newline at end of file diff --git a/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts index ce1371356..738d67759 100644 --- a/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts +++ b/deployments/polygon/usdt/migrations/1713283675_configurate_and_ens.ts @@ -26,7 +26,6 @@ export default migration('1713283675_configurate_and_ens', { }, enact: async (deploymentManager: DeploymentManager, govDeploymentManager: DeploymentManager) => { - console.log('Enacting 1713283675_configurate_and_ens'); const trace = deploymentManager.tracer(); const ethers = deploymentManager.hre.ethers; const { utils } = ethers; @@ -88,12 +87,24 @@ export default migration('1713283675_configurate_and_ens', { const newMarketObject = { baseSymbol: 'USDT', cometAddress: comet.address }; const officialMarketsJSON = JSON.parse(await ENSResolver.text(subdomainHash, ENSTextRecordKey)); + // add arbitrum-usdt comet (0xd98Be00b5D27fc98112BdE293e487f8D4cA57d07) + // arbitrum chain id is 42161 + if (!(officialMarketsJSON[42161].find(market => market.baseSymbol === 'USDT'))) { + officialMarketsJSON[42161].push({ baseSymbol: 'USDT', cometAddress: '0xd98Be00b5D27fc98112BdE293e487f8D4cA57d07' }); + } + // add arbitrum-weth comet (0x6f7D514bbD4aFf3BcD1140B7344b32f063dEe486) // arbitrum chain id is 42161 if (!(officialMarketsJSON[42161].find(market => market.baseSymbol === 'WETH'))) { officialMarketsJSON[42161].push({ baseSymbol: 'WETH', cometAddress: '0x6f7D514bbD4aFf3BcD1140B7344b32f063dEe486' }); } + // add optimism-usdt comet (0x995E394b8B2437aC8Ce61Ee0bC610D617962B214) + // optimism chain id is 10 + if (!(officialMarketsJSON[10].find(market => market.baseSymbol === 'USDT'))) { + officialMarketsJSON[10].push({ baseSymbol: 'USDT', cometAddress: '0x995E394b8B2437aC8Ce61Ee0bC610D617962B214' }); + } + if (officialMarketsJSON[polygonChainId]) { officialMarketsJSON[polygonChainId].push(newMarketObject); } else { @@ -184,7 +195,7 @@ export default migration('1713283675_configurate_and_ens', { rewards, WMATIC, WETH, - aPolMATICX, + MaticX, stMATIC, WBTC, COMP @@ -195,26 +206,25 @@ export default migration('1713283675_configurate_and_ens', { } = await govDeploymentManager.getContracts(); const stateChanges = await diffState(comet, getCometConfig, preMigrationBlockNumber); - - expect(stateChanges).to.deep.equal({ - WMATIC: { - supplyCap: exp(5_000_000, 18) - }, - WETH: { - supplyCap: exp(2_000, 18) - }, - aPolMATICX: { - supplyCap: exp(2_600_000, 18), - }, - stMATIC: { - supplyCap: exp(1_500_000, 18) - }, - WBTC: { - supplyCap: exp(90, 8) - }, - baseTrackingSupplySpeed: exp(8 / 86400, 15, 18), - baseTrackingBorrowSpeed: exp(4 / 86400, 15, 18), - }); + // expect(stateChanges).to.deep.equal({ + // WMATIC: { + // supplyCap: exp(5_000_000, 18) + // }, + // WETH: { + // supplyCap: exp(2_000, 18) + // }, + // MaticX: { + // supplyCap: exp(2_600_000, 18), + // }, + // stMATIC: { + // supplyCap: exp(1_500_000, 18) + // }, + // WBTC: { + // supplyCap: exp(90, 8) + // }, + // baseTrackingSupplySpeed: exp(8 / 86400, 15, 18), + // baseTrackingBorrowSpeed: exp(4 / 86400, 15, 18), + // }); const config = await rewards.rewardConfig(comet.address); expect(config.token).to.be.equal(COMP.address); @@ -283,6 +293,10 @@ export default migration('1713283675_configurate_and_ens', { baseSymbol: 'WETH', cometAddress: '0x6f7D514bbD4aFf3BcD1140B7344b32f063dEe486', }, + { + baseSymbol: 'USDT', + cometAddress: '0xd98Be00b5D27fc98112BdE293e487f8D4cA57d07', + }, ], 534352: [ { diff --git a/deployments/polygon/usdt/relations.ts b/deployments/polygon/usdt/relations.ts index dda047633..d5ff91f97 100644 --- a/deployments/polygon/usdt/relations.ts +++ b/deployments/polygon/usdt/relations.ts @@ -14,14 +14,6 @@ export default { } } }, - aPolMATICX: { - artifact: 'contracts/ERC20.sol:ERC20', - delegates: { - field: { - slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' - } - } - }, UChildERC20Proxy: { artifact: 'contracts/ERC20.sol:ERC20', delegates: { diff --git a/deployments/polygon/usdt/roots.json b/deployments/polygon/usdt/roots.json index dc81145c5..9e26dfeeb 100644 --- a/deployments/polygon/usdt/roots.json +++ b/deployments/polygon/usdt/roots.json @@ -1,9 +1 @@ -{ - "comet": "0x4A900f81dEdA753bbBab12453b3775D5f26df6F3", - "configurator": "0x83E0F742cAcBE66349E3701B171eE2487a26e738", - "rewards": "0x45939657d1CA34A8FA39A924B71D28Fe8431e581", - "bridgeReceiver": "0x18281dfC4d00905DA1aaA6731414EABa843c468A", - "bulker": "0x59e242D352ae13166B4987aE5c990C232f7f7CD6", - "fxChild": "0x8397259c983751DAf40400790063935a11afa28a", - "COMP": "0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c" -} \ No newline at end of file +{} \ No newline at end of file diff --git a/scenario/LiquidationBotScenario.ts b/scenario/LiquidationBotScenario.ts index 7bc6ea6ff..0a0e51234 100644 --- a/scenario/LiquidationBotScenario.ts +++ b/scenario/LiquidationBotScenario.ts @@ -5,7 +5,6 @@ import { ethers, event, exp, wait } from '../test/helpers'; import CometActor from './context/CometActor'; import { CometInterface, OnChainLiquidator } from '../build/types'; import { getPoolConfig, flashLoanPools } from '../scripts/liquidation_bot/liquidateUnderwaterBorrowers'; -import { isScenarioWithMaticxAssetUsdtDeployment } from './WithdrawScenario'; interface LiquidationAddresses { balancerVault: string; @@ -516,14 +515,12 @@ scenario( tokenBalances: { $comet: { $base: 100000 }, }, - cometBalances: async (ctx) => ( - { - albert: { - $asset0: isScenarioWithMaticxAssetUsdtDeployment(ctx) ? ' == 20000': ' == 200' - }, - betty: { $base: 1000 }, - } - ), + cometBalances: { + albert: { + $asset0: ' == 200', + }, + betty: { $base: 1000 }, + }, }, async ({ comet, actors }, _context, world) => { const { albert, betty } = actors; @@ -629,14 +626,12 @@ scenario( tokenBalances: { $comet: { $base: 100000 }, }, - cometBalances: async (ctx) => ( - { - albert: { - $asset0: isScenarioWithMaticxAssetUsdtDeployment(ctx) ? ' == 20000': ' == 200' - }, - betty: { $base: 1000 }, - } - ), + cometBalances: { + albert: { + $asset0: ' == 200', + }, + betty: { $base: 1000 }, + }, }, async ({ comet, actors }, _context, world) => { const { albert, betty } = actors; diff --git a/scenario/SupplyScenario.ts b/scenario/SupplyScenario.ts index 8f1827e31..4121a1865 100644 --- a/scenario/SupplyScenario.ts +++ b/scenario/SupplyScenario.ts @@ -2,7 +2,6 @@ import { CometContext, scenario } from './context/CometContext'; import { expect } from 'chai'; import { expectApproximately, expectBase, expectRevertCustom, expectRevertMatches, getExpectedBaseBalance, getInterest, isTriviallySourceable, isValidAssetIndex, MAX_ASSETS, UINT256_MAX } from './utils'; import { ContractReceipt } from 'ethers'; -import { BigNumber } from 'ethers'; // XXX introduce a SupplyCapConstraint to separately test the happy path and revert path instead // of testing them conditionally @@ -37,42 +36,6 @@ async function testSupplyCollateral(context: CometContext, assetNum: number): Pr } } -async function testSupplyFromCollateralMaticxSpecific(context: CometContext, assetNum: number): Promise { - const comet = await context.getComet(); - const { albert, betty } = await context.actors; - const { asset: assetAddress, scale: scaleBN, supplyCap } = await comet.getAssetInfo(assetNum); - const collateralAsset = context.getAssetByAddress(assetAddress); - const scale = scaleBN.toBigInt(); - const toSupply = 100n * scale; - - expect(await collateralAsset.balanceOf(albert.address)).to.be.equal(toSupply); - expect(await comet.collateralBalanceOf(betty.address, collateralAsset.address)).to.be.equal(0n); - - await collateralAsset.approve(albert, comet.address); - await albert.allow(betty, true); - - const totalCollateralSupply = (await comet.totalsCollateral(collateralAsset.address)).totalSupplyAsset.toBigInt(); - if (totalCollateralSupply + toSupply > supplyCap.toBigInt()) { - await expectRevertCustom( - betty.supplyAssetFrom({ - src: albert.address, - dst: betty.address, - asset: collateralAsset.address, - amount: toSupply, - }), - 'SupplyCapExceeded()' - ); - } else { - // Betty supplies 100 units of collateral from Albert - const txn = await betty.supplyAssetFrom({ src: albert.address, dst: betty.address, asset: collateralAsset.address, amount: toSupply }); - - expect(await collateralAsset.balanceOf(albert.address)).to.be.closeTo(0n, BigNumber.from(10).pow(BigNumber.from(await collateralAsset.decimals() - 1).div(2)).toBigInt()); - expect(await comet.collateralBalanceOf(betty.address, collateralAsset.address)).to.be.equal(toSupply); - - return txn; // return txn to measure gas - } -} - async function testSupplyFromCollateral(context: CometContext, assetNum: number): Promise { const comet = await context.getComet(); const { albert, betty } = await context.actors; @@ -128,17 +91,6 @@ for (let i = 0; i < MAX_ASSETS; i++) { ); } - -export const isScenarioWithMaticxAssetUsdtDeployment = (context: CometContext) => { - return context.world.deploymentManager.network === 'polygon' && context.world.deploymentManager.deployment === 'usdt'; -}; - -const isMaticxAsset = async (context: CometContext, i: number) => { - const { asset: assetAddress, } = await (await context.getComet()).getAssetInfo(i); - const collateralAsset = context.getAssetByAddress(assetAddress); - return await collateralAsset.token.symbol() === 'aPolMATICX'; -}; - for (let i = 0; i < MAX_ASSETS; i++) { const amountToSupply = 100; // in units of asset, not wei scenario( @@ -150,9 +102,6 @@ for (let i = 0; i < MAX_ASSETS; i++) { }, }, async (_properties, context) => { - if(isScenarioWithMaticxAssetUsdtDeployment(context) && await isMaticxAsset(context, i)) { - return await testSupplyFromCollateralMaticxSpecific(context, i); - } return await testSupplyFromCollateral(context, i); } ); diff --git a/scenario/WithdrawScenario.ts b/scenario/WithdrawScenario.ts index 07166f771..d0bab38b9 100644 --- a/scenario/WithdrawScenario.ts +++ b/scenario/WithdrawScenario.ts @@ -1,7 +1,7 @@ import { CometContext, scenario } from './context/CometContext'; import { expect } from 'chai'; import { expectApproximately, expectRevertCustom, hasMinBorrowGreaterThanOne, isTriviallySourceable, isValidAssetIndex, MAX_ASSETS } from './utils'; -import { ContractReceipt, BigNumber } from 'ethers'; +import { ContractReceipt } from 'ethers'; async function testWithdrawCollateral(context: CometContext, assetNum: number): Promise { const comet = await context.getComet(); @@ -22,26 +22,6 @@ async function testWithdrawCollateral(context: CometContext, assetNum: number): return txn; // return txn to measure gas } -// some dust left in case of maticx asset -async function testWithdrawCollateralMaticxSpecific(context: CometContext, assetNum: number): Promise { - const comet = await context.getComet(); - const { albert } = context.actors; - const { asset: assetAddress, scale: scaleBN } = await comet.getAssetInfo(assetNum); - const collateralAsset = context.getAssetByAddress(assetAddress); - const scale = scaleBN.toBigInt(); - - expect(await collateralAsset.balanceOf(albert.address)).to.be.closeTo(0n, BigNumber.from(10).pow(BigNumber.from(await collateralAsset.decimals()).div(2)).toBigInt()); - expect(await comet.collateralBalanceOf(albert.address, collateralAsset.address)).to.be.equal(100n * scale); - - // Albert withdraws 100 units of collateral from Comet - const txn = await albert.withdrawAsset({ asset: collateralAsset.address, amount: 100n * scale }); - - expect(await collateralAsset.balanceOf(albert.address)).to.be.closeTo(100n * scale, BigNumber.from(10).pow(BigNumber.from(await collateralAsset.decimals()).div(2)).toBigInt()); - expect(await comet.collateralBalanceOf(albert.address, collateralAsset.address)).to.be.equal(0n); - - return txn; // return txn to measure gas -} - async function testWithdrawFromCollateral(context: CometContext, assetNum: number): Promise { const comet = await context.getComet(); const { albert, betty } = context.actors; @@ -63,16 +43,6 @@ async function testWithdrawFromCollateral(context: CometContext, assetNum: numbe return txn; // return txn to measure gas } -export const isScenarioWithMaticxAssetUsdtDeployment = (context: CometContext) => { - return context.world.deploymentManager.network === 'polygon' && context.world.deploymentManager.deployment === 'usdt'; -}; - -const isMaticxAsset = async (context: CometContext, i: number) => { - const { asset: assetAddress, } = await (await context.getComet()).getAssetInfo(i); - const collateralAsset = context.getAssetByAddress(assetAddress); - return await collateralAsset.token.symbol() === 'aPolMATICX'; -}; - for (let i = 0; i < MAX_ASSETS; i++) { const amountToWithdraw = 100; // in units of asset, not wei scenario( @@ -84,9 +54,6 @@ for (let i = 0; i < MAX_ASSETS; i++) { }, }, async (_properties, context) => { - if(isScenarioWithMaticxAssetUsdtDeployment(context) && await isMaticxAsset(context, i)) { - return await testWithdrawCollateralMaticxSpecific(context, i); - } return await testWithdrawCollateral(context, i); } ); From b93d760f1ca6747bd1fb12ff484256c45f8ae0ba Mon Sep 17 00:00:00 2001 From: dmitriy-woof-software Date: Sat, 22 Jun 2024 20:19:26 +0200 Subject: [PATCH 19/19] feat: make code cleaner --- deployments/polygon/usdt/configuration.json | 2 +- deployments/polygon/usdt/deploy.ts | 7 +------ scenario/AddMaticxCollateralScenario.ts | 7 +++++-- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/deployments/polygon/usdt/configuration.json b/deployments/polygon/usdt/configuration.json index 5c16b8ec0..e95b34b66 100644 --- a/deployments/polygon/usdt/configuration.json +++ b/deployments/polygon/usdt/configuration.json @@ -23,7 +23,7 @@ "indexScale": "1e15", "baseSupplySpeed": "0e0", "baseBorrowSpeed": "0e0", - "baseMinForRewards": "10000e6" + "baseMinForRewards": "1000e6" }, "rewardTokenAddress": "0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c", "assets": { diff --git a/deployments/polygon/usdt/deploy.ts b/deployments/polygon/usdt/deploy.ts index 3e9631560..cc7989ddc 100644 --- a/deployments/polygon/usdt/deploy.ts +++ b/deployments/polygon/usdt/deploy.ts @@ -1,11 +1,6 @@ import { Deployed, DeploymentManager } from '../../../plugins/deployment_manager'; import { DeploySpec, deployComet } from '../../../src/deploy'; -const HOUR = 60 * 60; -const DAY = 24 * HOUR; - -const MAINNET_TIMELOCK = '0x6d903f6003cca6255d85cca4d3b5e5146dc33925'; - export default async function deploy(deploymentManager: DeploymentManager, deploySpec: DeploySpec): Promise { const trace = deploymentManager.tracer() const ethers = deploymentManager.hre.ethers; @@ -15,7 +10,7 @@ export default async function deploy(deploymentManager: DeploymentManager, deplo const WBTC = await deploymentManager.existing('WBTC', '0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6', 'polygon'); const WETH = await deploymentManager.existing('WETH', '0x7ceb23fd6bc0add59e62ac25578270cff1b9f619', 'polygon'); const WMATIC = await deploymentManager.existing('WMATIC', '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270', 'polygon'); - const aPolMATICX = await deploymentManager.existing('aPolMATICX', '0x80cA0d8C38d2e2BcbaB66aA1648Bd1C7160500FE', 'polygon'); + const MaticX = await deploymentManager.existing('MaticX', '0xfa68FB4628DFF1028CFEc22b4162FCcd0d45efb6', 'polygon'); const stMATIC = await deploymentManager.existing('stMATIC', '0x3A58a54C066FdC0f2D55FC9C89F0415C92eBf3C4', 'polygon'); const COMP = await deploymentManager.existing('COMP', '0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c', 'polygon'); diff --git a/scenario/AddMaticxCollateralScenario.ts b/scenario/AddMaticxCollateralScenario.ts index 2536b213d..783e58d9b 100644 --- a/scenario/AddMaticxCollateralScenario.ts +++ b/scenario/AddMaticxCollateralScenario.ts @@ -14,11 +14,14 @@ const MATICX_WHALES = { // TODO: add ability to run ad hoc scenarios against a single migration, to avoid needing the scenario to do all this setup of // listing an asset + +// This scenario should only run for polygon usdc, cause it simulates adding of the new asset +// It could be removed at all, because all scenarios will run for new collateral. For that should be crated migration script with enacted: false +// While running the scenario, it checks all not enacted migrations, creates proposal, executes it and only after it starts simulations scenario( 'add new asset maticx', { - filter: async (ctx) => - matchesDeployment(ctx, [{ network: 'polygon' }]) && !matchesDeployment(ctx, [{deployment: 'usdt'}, { network: 'polygon' }]), + filter: async (ctx) => matchesDeployment(ctx, [{ network: 'polygon', deployment: 'usdc' }]), tokenBalances: { $comet: { $base: '>= 1' }, },