From 6127e7dac348a8ab6ec30305372c85164f1eaaae Mon Sep 17 00:00:00 2001 From: blockgroot <170620375+blockgroot@users.noreply.github.com> Date: Mon, 12 Aug 2024 15:48:51 +0530 Subject: [PATCH 1/3] feat: add wmatic market to polygon network --- .github/workflows/run-scenarios.yaml | 2 +- deployments/polygon/wmatic/configuration.json | 40 +++++++++++++++++++ deployments/polygon/wmatic/deploy.ts | 39 ++++++++++++++++++ deployments/polygon/wmatic/relations.ts | 25 ++++++++++++ deployments/polygon/wmatic/roots.json | 1 + hardhat.config.ts | 10 ++++- 6 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 deployments/polygon/wmatic/configuration.json create mode 100644 deployments/polygon/wmatic/deploy.ts create mode 100644 deployments/polygon/wmatic/relations.ts create mode 100644 deployments/polygon/wmatic/roots.json diff --git a/.github/workflows/run-scenarios.yaml b/.github/workflows/run-scenarios.yaml index 0fecdd98c..3afa53533 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, mainnet-usdt, goerli, goerli-weth, sepolia-usdc, sepolia-weth, fuji, mumbai, polygon, polygon-usdt, arbitrum-usdc.e, arbitrum-usdc, arbitrum-weth, arbitrum-usdt, arbitrum-goerli-usdc, arbitrum-goerli-usdc.e, base-usdbc, base-weth, base-usdc, base-goerli, base-goerli-weth, linea-goerli, optimism-usdc, optimism-usdt, optimism-weth, scroll-goerli, scroll-usdc] + bases: [ development, mainnet, mainnet-weth, mainnet-usdt, goerli, goerli-weth, sepolia-usdc, sepolia-weth, fuji, mumbai, polygon, polygon-usdt, polygon-wmatic, arbitrum-usdc.e, arbitrum-usdc, arbitrum-weth, arbitrum-usdt, arbitrum-goerli-usdc, arbitrum-goerli-usdc.e, base-usdbc, base-weth, base-usdc, base-goerli, base-goerli-weth, linea-goerli, optimism-usdc, optimism-usdt, optimism-weth, scroll-goerli, scroll-usdc] name: Run scenarios env: ETHERSCAN_KEY: ${{ secrets.ETHERSCAN_KEY }} diff --git a/deployments/polygon/wmatic/configuration.json b/deployments/polygon/wmatic/configuration.json new file mode 100644 index 000000000..f2f09ce4a --- /dev/null +++ b/deployments/polygon/wmatic/configuration.json @@ -0,0 +1,40 @@ +{ + "name": "Compound WMATIC", + "symbol": "cWMATICv3", + "baseToken": "WMATIC", + "baseTokenAddress": "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", + "baseTokenPriceFeed": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", + "borrowMin": "1e18", + "governor": "0xCC3E7c85Bb0EE4f09380e041fee95a0caeDD4a02", + "pauseGuardian": "0x8Ab717CAC3CbC4934E63825B88442F5810aAF6e5", + "storeFrontPriceFactor": "TBD", + "targetReserves": "TBD", + "rates": { + "supplyKink": 0.9, + "supplySlopeLow": 0.025, + "supplySlopeHigh": 3, + "supplyBase": 0, + "borrowKink": 0.9, + "borrowSlopeLow": 0.035, + "borrowSlopeHigh": 3.5, + "borrowBase": 0.005 + }, + "tracking": { + "indexScale": "1e15", + "baseSupplySpeed": "34722222222", + "baseBorrowSpeed": "0", + "baseMinForRewards": "TBD" + }, + "rewardTokenAddress": "0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c", + "assets": { + "MaticX": { + "address": "0xfa68FB4628DFF1028CFEc22b4162FCcd0d45efb6", + "priceFeed": "0x5d37E4b374E6907de8Fc7fb33EE3b0af403C7403", + "decimals": "18", + "borrowCF": 0.80, + "liquidateCF": 0.85, + "liquidationFactor": 0.90, + "supplyCap": "0" + } + } +} \ No newline at end of file diff --git a/deployments/polygon/wmatic/deploy.ts b/deployments/polygon/wmatic/deploy.ts new file mode 100644 index 000000000..cc7989ddc --- /dev/null +++ b/deployments/polygon/wmatic/deploy.ts @@ -0,0 +1,39 @@ +import { Deployed, DeploymentManager } from '../../../plugins/deployment_manager'; +import { DeploySpec, deployComet } from '../../../src/deploy'; + +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 MaticX = await deploymentManager.existing('MaticX', '0xfa68FB4628DFF1028CFEc22b4162FCcd0d45efb6', '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'); + + 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/wmatic/relations.ts b/deployments/polygon/wmatic/relations.ts new file mode 100644 index 000000000..d5ff91f97 --- /dev/null +++ b/deployments/polygon/wmatic/relations.ts @@ -0,0 +1,25 @@ +import { RelationConfigMap } from '../../../plugins/deployment_manager/RelationConfig'; +import baseRelationConfig from '../../relations'; + +export default { + ...baseRelationConfig, + 'governor': { + artifact: 'contracts/bridges/polygon/PolygonBridgeReceiver.sol:PolygonBridgeReceiver', + }, + InitializableImmutableAdminUpgradeabilityProxy: { + artifact: 'contracts/ERC20.sol:ERC20', + delegates: { + field: { + slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + } + } + }, + UChildERC20Proxy: { + artifact: 'contracts/ERC20.sol:ERC20', + delegates: { + field: { + slot: '0xbaab7dbf64751104133af04abc7d9979f0fda3b059a322a8333f533d3f32bf7f', + } + }, + } +}; \ No newline at end of file diff --git a/deployments/polygon/wmatic/roots.json b/deployments/polygon/wmatic/roots.json new file mode 100644 index 000000000..9e26dfeeb --- /dev/null +++ b/deployments/polygon/wmatic/roots.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/hardhat.config.ts b/hardhat.config.ts index c532b5ef2..a05e5eb0b 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -28,6 +28,7 @@ import mainnetWethRelationConfigMap from './deployments/mainnet/weth/relations'; import mainnetUsdtRelationConfigMap from './deployments/mainnet/usdt/relations'; import polygonRelationConfigMap from './deployments/polygon/usdc/relations'; import polygonUsdtRelationConfigMap from './deployments/polygon/usdt/relations'; +import polygonWmatictRelationConfigMap from './deployments/polygon/wmatic/relations'; import arbitrumBridgedUsdcRelationConfigMap from './deployments/arbitrum/usdc.e/relations'; import arbitrumNativeUsdcRelationConfigMap from './deployments/arbitrum/usdc/relations'; import arbitrumWETHRelationConfigMap from './deployments/arbitrum/weth/relations'; @@ -357,7 +358,8 @@ const config: HardhatUserConfig = { }, polygon: { usdc: polygonRelationConfigMap, - usdt: polygonUsdtRelationConfigMap + usdt: polygonUsdtRelationConfigMap, + wmatic: polygonWmatictRelationConfigMap }, arbitrum: { 'usdc.e': arbitrumBridgedUsdcRelationConfigMap, @@ -461,6 +463,12 @@ const config: HardhatUserConfig = { deployment: 'usdt', auxiliaryBase: 'mainnet' }, + { + name: 'polygon-wmatic', + network: 'polygon', + deployment: 'wmatic', + auxiliaryBase: 'mainnet' + }, { name: 'arbitrum-usdc.e', network: 'arbitrum', From 5e19cb96f7cbc51ab8d588668107f4897126edcf Mon Sep 17 00:00:00 2001 From: blockgroot <170620375+blockgroot@users.noreply.github.com> Date: Tue, 13 Aug 2024 15:57:31 +0530 Subject: [PATCH 2/3] chore: update min reward and speed --- deployments/polygon/wmatic/configuration.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deployments/polygon/wmatic/configuration.json b/deployments/polygon/wmatic/configuration.json index f2f09ce4a..9ae835018 100644 --- a/deployments/polygon/wmatic/configuration.json +++ b/deployments/polygon/wmatic/configuration.json @@ -21,9 +21,9 @@ }, "tracking": { "indexScale": "1e15", - "baseSupplySpeed": "34722222222", + "baseSupplySpeed": "0", "baseBorrowSpeed": "0", - "baseMinForRewards": "TBD" + "baseMinForRewards": "10000e18" }, "rewardTokenAddress": "0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c", "assets": { From 29be1aa06021511f5fb6b7a070df8e5e84ebc0a2 Mon Sep 17 00:00:00 2001 From: blockgroot <170620375+blockgroot@users.noreply.github.com> Date: Wed, 14 Aug 2024 17:10:15 +0530 Subject: [PATCH 3/3] feat: add migration for new market setup --- deployments/polygon/wmatic/deploy.ts | 3 +- .../1723545141_configurate_and_ens.ts | 325 ++++++++++++++++++ 2 files changed, 327 insertions(+), 1 deletion(-) create mode 100644 deployments/polygon/wmatic/migrations/1723545141_configurate_and_ens.ts diff --git a/deployments/polygon/wmatic/deploy.ts b/deployments/polygon/wmatic/deploy.ts index cc7989ddc..5690490c0 100644 --- a/deployments/polygon/wmatic/deploy.ts +++ b/deployments/polygon/wmatic/deploy.ts @@ -34,6 +34,7 @@ export default async function deploy(deploymentManager: DeploymentManager, deplo bulker, fxChild, rewards, - COMP + COMP, + localTimelock }; } \ No newline at end of file diff --git a/deployments/polygon/wmatic/migrations/1723545141_configurate_and_ens.ts b/deployments/polygon/wmatic/migrations/1723545141_configurate_and_ens.ts new file mode 100644 index 000000000..ad2a27410 --- /dev/null +++ b/deployments/polygon/wmatic/migrations/1723545141_configurate_and_ens.ts @@ -0,0 +1,325 @@ +import { Contract, ethers } from 'ethers'; +import { DeploymentManager } from '../../../../plugins/deployment_manager/DeploymentManager'; +import { migration } from '../../../../plugins/deployment_manager/Migration'; +import { calldata, exp, getBlock, 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 ENSSubdomainLabel = 'v3-additional-grants'; +const ENSSubdomain = `${ENSSubdomainLabel}.${ENSName}`; +const ENSTextRecordKey = 'v3-official-markets'; + +const ERC20PredicateAddress = '0x40ec5B33f54e0E8A33A975908C5BA1c14e5BbbDf'; +const RootChainManagerAddress = '0xA0c68C638235ee32657e8f720a23ceC1bFc77C77'; + +const mainnetUSDTAddress = '0xdac17f958d2ee523a2206206994597c13d831ec7'; +const mainnetMATICAddress = '0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0' +const polygonCOMPAddress = '0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c'; +const cUSDTAddress = '0xf650c3d88d12db855b8bf7d11be6c55a4e07dcc9'; + +const uniswapRouterV2Address = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D"; + +const USDTAmountToSwap = ethers.BigNumber.from(exp(10_000, 6)); +let MATICAmountToWrap; + +export default migration('1723545141_configurate_and_ens', { + prepare: async (_deploymentManager: DeploymentManager) => { + return {}; + }, + + enact: async (deploymentManager: DeploymentManager, govDeploymentManager: DeploymentManager) => { + 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, + WMATIC, + localTimelock + } = await deploymentManager.getContracts(); + + const { + fxRoot, + timelock, + governor + } = await govDeploymentManager.getContracts(); + + const uniswapRouterV2 = new Contract( + uniswapRouterV2Address, + [ + 'function swapExactTokensForTokens(uint amountIn,uint amountOutMin,address[] calldata path,address to,uint deadline) external returns (uint[] memory amounts)', + 'function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts)', + ], + govDeploymentManager.hre.ethers.provider + ); + + MATICAmountToWrap = (await uniswapRouterV2.getAmountsOut(USDTAmountToSwap, [mainnetUSDTAddress, mainnetMATICAddress]))[1] + + 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] + ); + + // Note: There is no way to directly bridge WMATIC, so we have to bridge MATIC to the Timelock, wrap it, then transfer it to Comet + const transferWMATICCalldata = utils.defaultAbiCoder.encode( + ['address', 'uint256'], + [comet.address, MATICAmountToWrap] + ); + + const l2ProposalData = utils.defaultAbiCoder.encode( + ['address[]', 'uint256[]', 'string[]', 'bytes[]'], + [ + [configurator.address, configurator.address, cometAdmin.address, rewards.address, WMATIC.address, WMATIC.address], + [0, 0, 0, 0, MATICAmountToWrap, 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)', + 'deposit()', + 'transfer(address,uint256)' + ], + [setFactoryCalldata, setConfigurationCalldata, deployAndUpgradeToCalldata, setRewardConfigCalldata, '0x', transferWMATICCalldata] + ] + ); + + 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: 'WMATIC', 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 depositMATICData = utils.defaultAbiCoder.encode(['uint256'], [MATICAmountToWrap]); + const depositForMATICCalldata = utils.defaultAbiCoder.encode( + ['address', 'address', 'bytes'], + [localTimelock.address, mainnetMATICAddress, depositMATICData] + ); + + const notEnoughUSDT = (await USDTMainnet.balanceOf(timelock.address)).lt(USDTAmountToSwap); + const amountToSupply = notEnoughUSDT ? ethers.BigNumber.from(USDTAmountToSwap).sub(await USDTMainnet.balanceOf(timelock.address)) : 0; + const _reduceReservesCalldata = utils.defaultAbiCoder.encode( + ['uint256'], + [amountToSupply] + ); + + const mainnetActions = [ + // 1. Set Comet configuration and deployAndUpgradeTo new Comet on Polygon. + { + contract: fxRoot, + signature: 'sendMessageToChild(address,bytes)', + args: [bridgeReceiver.address, l2ProposalData] + }, + // 2. Get USDT reserves from cUSDT contract + { + target: cUSDTAddress, + signature: '_reduceReserves(uint256)', + calldata: _reduceReservesCalldata + }, + // 3. Approve Uniswap Router to take Timelock's USDT (for swapping) + { + contract: mainnetUSDTAddress, + signature: 'approve(address,uint256)', + args: [uniswapRouterV2Address, USDTAmountToSwap] + }, + // 4. Swap USDT for MATIC + { + contract: uniswapRouterV2Address, + signature: 'swapExactTokensForTokens(uint amountIn,uint amountOutMin,address[] calldata path,address to,uint deadline)', + args: [USDTAmountToSwap, MATICAmountToWrap, [mainnetUSDTAddress, mainnetMATICAddress], timelock.address, (await getBlock()).timestamp] + }, + // 5. Approve Polygon's ERC20Predicate to take Timelock's MATIC (for bridging) + { + contract: mainnetMATICAddress, + signature: 'approve(address,uint256)', + args: [ERC20PredicateAddress, MATICAmountToWrap] + }, + // 6. Bridge MATIC from mainnet to Polygon using RootChainManager + { + target: RootChainManager.address, + signature: 'depositFor(address,address,bytes)', + calldata: depositForMATICCalldata + }, + // 7. 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)] + ) + } + ]; + + const description = "# Initialize cWMATICv3 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 WMATIC market on Polygon; upon execution, cWMATICv3 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-matic-market-on-the-matic-network/5159/5).\n\nFurther detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/906), [market deployment action](https://github.com/woof-software/comet/actions/runs/9627561011) and [forum discussion](https://www.comp.xyz/t/add-matic-market-on-the-matic-network/5159).\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 3 COMP/day and borrow speed to be 0 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 cWMATICv3 market."; + 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 true; + }, + + async verify(deploymentManager: DeploymentManager, govDeploymentManager: DeploymentManager, preMigrationBlockNumber: number) { + const ethers = deploymentManager.hre.ethers; + + const { + comet, + rewards, + COMP + } = await deploymentManager.getContracts(); + + const stateChanges = await diffState(comet, getCometConfig, preMigrationBlockNumber); + expect(stateChanges).to.deep.equal({ + MaticX: { + supplyCap: exp(0, 18), + }, + baseTrackingSupplySpeed: exp(0), + baseTrackingBorrowSpeed: exp(0), + }); + + 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); + + expect(await comet.getReserves()).to.be.equal(MATICAmountToWrap); + + const ENSResolver = await govDeploymentManager.existing( + 'ENSResolver', + ENSResolverAddress + ); + const subdomainHash = ethers.utils.namehash(ENSSubdomain); + const officialMarketsJSON = await ENSResolver.text( + subdomainHash, + ENSTextRecordKey + ); + const officialMarkets = JSON.parse(officialMarketsJSON); + expect(officialMarkets).to.deep.equal({ + 1: [ + { + baseSymbol: 'USDC', + cometAddress: '0xc3d688B66703497DAA19211EEdff47f25384cdc3', + }, + { + baseSymbol: 'WETH', + cometAddress: '0xA17581A9E3356d9A858b789D68B4d866e593aE94', + }, + { + baseSymbol: 'USDT', + cometAddress: '0x3Afdc9BCA9213A35503b077a6072F3D0d5AB0840', + }, + ], + 137: [ + { + baseSymbol: 'USDC', + cometAddress: '0xF25212E676D1F7F89Cd72fFEe66158f541246445', + }, + { + baseSymbol: 'USDT', + cometAddress: "0xaeB318360f27748Acb200CE616E389A6C9409a07", + }, + { + baseSymbol: 'WMATIC', + 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', + }, + { + baseSymbol: 'WETH', + cometAddress: '0x6f7D514bbD4aFf3BcD1140B7344b32f063dEe486', + }, + { + baseSymbol: 'USDT', + cometAddress: '0xd98Be00b5D27fc98112BdE293e487f8D4cA57d07', + }, + ], + 534352: [ + { + baseSymbol: 'USDC', + cometAddress: '0xB2f97c1Bd3bf02f5e74d13f02E3e26F93D77CE44', + }, + ], + 10: [ + { + baseSymbol: 'USDC', + cometAddress: '0x2e44e174f7D53F0212823acC11C01A11d58c5bCB', + }, + { + baseSymbol: 'USDT', + cometAddress: '0x995E394b8B2437aC8Ce61Ee0bC610D617962B214', + }, + { + baseSymbol: 'WETH', + cometAddress: '0xE36A30D249f7761327fd973001A32010b521b6Fd', + }, + ], + }); + } +});