@oldzeppelin/contract 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.docker/Dockerfile +17 -0
- package/.dockerignore +7 -0
- package/.env.sample +24 -0
- package/.gitlab-ci.yml +51 -0
- package/.gitmodules +15 -0
- package/.prettierrc +10 -0
- package/.solcover.js +4 -0
- package/.vscode/settings.json +23 -0
- package/LICENSE.MD +51 -0
- package/README.md +135 -0
- package/contracts/arbitrum/contracts/controllers/UniswapV2ControllerArbitrum.sol +37 -0
- package/contracts/arbitrum/contracts/controllers/UniswapV3ControllerArbitrum.sol +46 -0
- package/contracts/arbitrum/contracts/oracle/PriceOracleArbitrum.sol +51 -0
- package/contracts/main/contracts/controllers/Controller.sol +61 -0
- package/contracts/main/contracts/controllers/IController.sol +81 -0
- package/contracts/main/contracts/controllers/OneInchV5Controller.sol +332 -0
- package/contracts/main/contracts/controllers/UnoswapV2Controller.sol +789 -0
- package/contracts/main/contracts/controllers/UnoswapV3Controller.sol +1018 -0
- package/contracts/main/contracts/core/CoreWhitelist.sol +192 -0
- package/contracts/main/contracts/core/ICoreWhitelist.sol +92 -0
- package/contracts/main/contracts/core/IUFarmCore.sol +95 -0
- package/contracts/main/contracts/core/UFarmCore.sol +402 -0
- package/contracts/main/contracts/fund/FundFactory.sol +59 -0
- package/contracts/main/contracts/fund/IUFarmFund.sol +68 -0
- package/contracts/main/contracts/fund/UFarmFund.sol +504 -0
- package/contracts/main/contracts/oracle/ChainlinkedOracle.sol +71 -0
- package/contracts/main/contracts/oracle/IChainlinkAggregator.sol +18 -0
- package/contracts/main/contracts/oracle/IPriceOracle.sol +55 -0
- package/contracts/main/contracts/oracle/PriceOracle.sol +20 -0
- package/contracts/main/contracts/oracle/PriceOracleCore.sol +212 -0
- package/contracts/main/contracts/oracle/WstETHOracle.sol +64 -0
- package/contracts/main/contracts/permissions/Permissions.sol +54 -0
- package/contracts/main/contracts/permissions/UFarmPermissionsModel.sol +136 -0
- package/contracts/main/contracts/pool/IPoolAdmin.sol +57 -0
- package/contracts/main/contracts/pool/IUFarmPool.sol +304 -0
- package/contracts/main/contracts/pool/PerformanceFeeLib.sol +81 -0
- package/contracts/main/contracts/pool/PoolAdmin.sol +437 -0
- package/contracts/main/contracts/pool/PoolFactory.sol +74 -0
- package/contracts/main/contracts/pool/PoolWhitelist.sol +70 -0
- package/contracts/main/contracts/pool/UFarmPool.sol +959 -0
- package/contracts/main/shared/AssetController.sol +194 -0
- package/contracts/main/shared/ECDSARecover.sol +91 -0
- package/contracts/main/shared/NZGuard.sol +99 -0
- package/contracts/main/shared/SafeOPS.sol +128 -0
- package/contracts/main/shared/UFarmCoreLink.sol +83 -0
- package/contracts/main/shared/UFarmErrors.sol +16 -0
- package/contracts/main/shared/UFarmMathLib.sol +80 -0
- package/contracts/main/shared/UFarmOwnableUUPS.sol +59 -0
- package/contracts/main/shared/UFarmOwnableUUPSBeacon.sol +34 -0
- package/contracts/test/Block.sol +15 -0
- package/contracts/test/InchSwapTestProxy.sol +292 -0
- package/contracts/test/MockPoolAdmin.sol +8 -0
- package/contracts/test/MockUFarmPool.sol +8 -0
- package/contracts/test/MockV3wstETHstETHAgg.sol +128 -0
- package/contracts/test/MockedWETH9.sol +72 -0
- package/contracts/test/OneInchToUFarmTestEnv.sol +466 -0
- package/contracts/test/StableCoin.sol +25 -0
- package/contracts/test/UFarmMockSequencerUptimeFeed.sol +44 -0
- package/contracts/test/UFarmMockV3Aggregator.sol +145 -0
- package/contracts/test/UUPSBlock.sol +19 -0
- package/contracts/test/ufarmLocal/MulticallV3.sol +220 -0
- package/contracts/test/ufarmLocal/controllers/UniswapV2ControllerUFarm.sol +27 -0
- package/contracts/test/ufarmLocal/controllers/UniswapV3ControllerUFarm.sol +43 -0
- package/deploy/100_test_env_setup.ts +483 -0
- package/deploy/20_deploy_uniV2.ts +48 -0
- package/deploy/21_create_pairs_uniV2.ts +149 -0
- package/deploy/22_deploy_mocked_aggregators.ts +123 -0
- package/deploy/22_deploy_wsteth_oracle.ts +65 -0
- package/deploy/23_deploy_uniV3.ts +80 -0
- package/deploy/24_create_pairs_uniV3.ts +140 -0
- package/deploy/25_deploy_oneInch.ts +38 -0
- package/deploy/2_deploy_multicall.ts +34 -0
- package/deploy/30_deploy_price_oracle.ts +33 -0
- package/deploy/3_deploy_lido.ts +114 -0
- package/deploy/40_deploy_pool_beacon.ts +19 -0
- package/deploy/41_deploy_poolAdmin_beacon.ts +19 -0
- package/deploy/42_deploy_ufarmcore.ts +29 -0
- package/deploy/43_deploy_fund_beacon.ts +19 -0
- package/deploy/4_deploy_tokens.ts +76 -0
- package/deploy/50_deploy_poolFactory.ts +35 -0
- package/deploy/51_deploy_fundFactory.ts +29 -0
- package/deploy/60_init_contracts.ts +101 -0
- package/deploy/61_whitelist_tokens.ts +18 -0
- package/deploy/70_deploy_uniV2Controller.ts +70 -0
- package/deploy/71_deploy_uniV3Controller.ts +67 -0
- package/deploy/72_deploy_oneInchController.ts +25 -0
- package/deploy/79_whitelist_controllers.ts +125 -0
- package/deploy/ufarm/arbitrum/1_prepare_env.ts +82 -0
- package/deploy/ufarm/arbitrum/2_deploy_ufarm.ts +178 -0
- package/deploy/ufarm/arbitrum-sepolia/1000_prepare_arb_sepolia_env.ts +308 -0
- package/deploy-config.json +112 -0
- package/deploy-data/oracles.csv +32 -0
- package/deploy-data/protocols.csv +10 -0
- package/deploy-data/tokens.csv +32 -0
- package/docker-compose.yml +67 -0
- package/hardhat.config.ts +449 -0
- package/index.js +93 -0
- package/package.json +82 -0
- package/scripts/_deploy_helpers.ts +992 -0
- package/scripts/_deploy_network_options.ts +49 -0
- package/scripts/activatePool.ts +51 -0
- package/scripts/createPool.ts +62 -0
- package/scripts/deploy_1inch_proxy.ts +98 -0
- package/scripts/pool-data.ts +420 -0
- package/scripts/post-deploy.sh +24 -0
- package/scripts/setUniV2Rate.ts +252 -0
- package/scripts/swapOneInchV5.ts +94 -0
- package/scripts/swapUniswapV2.ts +65 -0
- package/scripts/swapUniswapV3.ts +71 -0
- package/scripts/test.ts +61 -0
- package/scripts/typings-copy-artifacts.ts +83 -0
- package/tasks/boostPool.ts +39 -0
- package/tasks/createFund.ts +44 -0
- package/tasks/deboostPool.ts +48 -0
- package/tasks/grantUFarmPermissions.ts +57 -0
- package/tasks/index.ts +7 -0
- package/tasks/mintUSDT.ts +62 -0
- package/test/Periphery.test.ts +640 -0
- package/test/PriceOracle.test.ts +82 -0
- package/test/TestCases.MD +109 -0
- package/test/UFarmCore.test.ts +331 -0
- package/test/UFarmFund.test.ts +406 -0
- package/test/UFarmPool.test.ts +4736 -0
- package/test/_fixtures.ts +783 -0
- package/test/_helpers.ts +2195 -0
- package/test/_oneInchTestData.ts +632 -0
- package/tsconfig.json +12 -0
@@ -0,0 +1,178 @@
|
|
1
|
+
// SPDX-License-Identifier: BUSL-1.1
|
2
|
+
|
3
|
+
import { DeployFunction } from 'hardhat-deploy/types'
|
4
|
+
import { HardhatRuntimeEnvironment } from 'hardhat/types'
|
5
|
+
import {
|
6
|
+
getDeployerSigner,
|
7
|
+
getInstanceFromDeployment,
|
8
|
+
retryOperation,
|
9
|
+
checkMinFundDep,
|
10
|
+
_deployTags,
|
11
|
+
} from '../../../scripts/_deploy_helpers'
|
12
|
+
import {
|
13
|
+
constants,
|
14
|
+
bitsToBigNumber,
|
15
|
+
} from '../../../test/_helpers'
|
16
|
+
import { UFarmCore } from '../../../typechain-types'
|
17
|
+
|
18
|
+
const deployUFarm: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
19
|
+
if (!hre.network.tags['arbitrum']) {
|
20
|
+
console.log('Not Arbitrum network, skipping UFarm Arbitrum deployment')
|
21
|
+
return
|
22
|
+
}
|
23
|
+
|
24
|
+
const { ufarmPanicManager, ufarmFundApprover, ufarmManager, fundOwner, ufarmOwner } =
|
25
|
+
hre.namedAddresses
|
26
|
+
|
27
|
+
for (const [name, value] of Object.entries([
|
28
|
+
ufarmPanicManager,
|
29
|
+
ufarmFundApprover,
|
30
|
+
ufarmManager,
|
31
|
+
fundOwner,
|
32
|
+
ufarmOwner,
|
33
|
+
])) {
|
34
|
+
if (!hre.ethers.utils.isAddress(value) || value === hre.ethers.constants.AddressZero) {
|
35
|
+
console.log(`Address of ${name} is not set, ending script`)
|
36
|
+
return
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
const deployerSigner = await getDeployerSigner(hre)
|
41
|
+
|
42
|
+
const ufarmCore_deployment = await hre.deployments.get('UFarmCore')
|
43
|
+
|
44
|
+
const ufarmCore_instance = getInstanceFromDeployment<UFarmCore>(
|
45
|
+
hre,
|
46
|
+
ufarmCore_deployment,
|
47
|
+
deployerSigner,
|
48
|
+
)
|
49
|
+
const deplyerIsOwner = await ufarmCore_instance.hasPermissionsMask(
|
50
|
+
deployerSigner.address,
|
51
|
+
constants.UFarm.Permissions.Owner,
|
52
|
+
)
|
53
|
+
|
54
|
+
if (!deplyerIsOwner) {
|
55
|
+
console.log(`Deployer is not owner, ending script`)
|
56
|
+
return
|
57
|
+
}
|
58
|
+
const minFundDep = await ufarmCore_instance.connect(deployerSigner).minimumFundDeposit()
|
59
|
+
if (minFundDep.eq(0)){
|
60
|
+
await checkMinFundDep(ufarmCore_instance.connect(deployerSigner), constants.ONE_BUCKS.mul(1000))
|
61
|
+
}
|
62
|
+
|
63
|
+
// set protocol fee
|
64
|
+
const currentProtocolCommission = await ufarmCore_instance.protocolCommission()
|
65
|
+
if (!currentProtocolCommission.eq(constants.ZERO_POINT_3_PERCENTS)) {
|
66
|
+
console.log(`Current protocol commission is ${currentProtocolCommission}, setting to 0.3%`)
|
67
|
+
await ufarmCore_instance.setProtocolCommission(constants.ZERO_POINT_3_PERCENTS)
|
68
|
+
console.log(`Protocol commission set to 0.3%`)
|
69
|
+
} else {
|
70
|
+
console.log(`Current protocol commission is ${currentProtocolCommission}`)
|
71
|
+
}
|
72
|
+
|
73
|
+
// grant UFarm permissions
|
74
|
+
{
|
75
|
+
const ufarmPermissions = constants.UFarm.Permissions
|
76
|
+
const ufarmRoles = constants.UFarm.Roles
|
77
|
+
|
78
|
+
if (ufarmPanicManager !== '') {
|
79
|
+
const mask = bitsToBigNumber(ufarmRoles.MemberRole.concat(ufarmPermissions.TurnPauseOn))
|
80
|
+
const currentPermissions = await ufarmCore_instance.hasPermissionsMask(
|
81
|
+
ufarmPanicManager,
|
82
|
+
mask,
|
83
|
+
)
|
84
|
+
await retryOperation(async () => {
|
85
|
+
if (!currentPermissions) {
|
86
|
+
await hre.deployments.execute(
|
87
|
+
'UFarmCore',
|
88
|
+
{ from: deployerSigner.address },
|
89
|
+
'updatePermissions',
|
90
|
+
ufarmPanicManager,
|
91
|
+
bitsToBigNumber(ufarmRoles.MemberRole.concat(ufarmPermissions.TurnPauseOn)),
|
92
|
+
)
|
93
|
+
console.log(`Panic manager permissions set for ${ufarmPanicManager}`)
|
94
|
+
} else {
|
95
|
+
console.log(`Panic manager permissions already set`)
|
96
|
+
}
|
97
|
+
}, 3)
|
98
|
+
}
|
99
|
+
|
100
|
+
if (ufarmFundApprover !== '') {
|
101
|
+
const mask = bitsToBigNumber(
|
102
|
+
ufarmRoles.MemberRole.concat(
|
103
|
+
Object.values(ufarmRoles.ModeratorRole),
|
104
|
+
Object.values(ufarmRoles.CrisisManagerRole),
|
105
|
+
),
|
106
|
+
)
|
107
|
+
const currentPermissions = await ufarmCore_instance.hasPermissionsMask(
|
108
|
+
ufarmFundApprover,
|
109
|
+
mask,
|
110
|
+
)
|
111
|
+
if (!currentPermissions) {
|
112
|
+
await retryOperation(async () => {
|
113
|
+
await hre.deployments.execute(
|
114
|
+
'UFarmCore',
|
115
|
+
{ from: deployerSigner.address },
|
116
|
+
'updatePermissions',
|
117
|
+
ufarmFundApprover,
|
118
|
+
mask,
|
119
|
+
)
|
120
|
+
}, 3)
|
121
|
+
console.log(`Fund approver permissions set`)
|
122
|
+
}
|
123
|
+
}
|
124
|
+
|
125
|
+
if (ufarmManager !== '') {
|
126
|
+
const mask = bitsToBigNumber(
|
127
|
+
ufarmRoles.MemberRole.concat(...ufarmRoles.TeamManagerRole, ...ufarmRoles.ModeratorRole),
|
128
|
+
)
|
129
|
+
const currentPermissions = await ufarmCore_instance.hasPermissionsMask(ufarmManager, mask)
|
130
|
+
if (!currentPermissions) {
|
131
|
+
await retryOperation(async () => {
|
132
|
+
await hre.deployments.execute(
|
133
|
+
'UFarmCore',
|
134
|
+
{ from: deployerSigner.address },
|
135
|
+
'updatePermissions',
|
136
|
+
ufarmManager,
|
137
|
+
mask,
|
138
|
+
)
|
139
|
+
}, 3)
|
140
|
+
console.log(`Manager permissions set`)
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
if (ufarmOwner !== '') {
|
145
|
+
const ownerMask = hre.ethers.constants.MaxUint256
|
146
|
+
const currentPermissions = await ufarmCore_instance.hasPermissionsMask(ufarmOwner, ownerMask)
|
147
|
+
if (!currentPermissions) {
|
148
|
+
await retryOperation(async () => {
|
149
|
+
await hre.deployments.execute(
|
150
|
+
'UFarmCore',
|
151
|
+
{ from: deployerSigner.address },
|
152
|
+
'updatePermissions',
|
153
|
+
ufarmOwner,
|
154
|
+
ownerMask,
|
155
|
+
)
|
156
|
+
}, 3)
|
157
|
+
console.log(`Owner permissions set`)
|
158
|
+
}
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
162
|
+
console.log(`Deployer: ${deployerSigner.address}`)
|
163
|
+
console.log(
|
164
|
+
`Deployers final balance: ${hre.ethers.utils.formatEther(
|
165
|
+
await deployerSigner.getBalance(),
|
166
|
+
)} ETH`,
|
167
|
+
)
|
168
|
+
|
169
|
+
console.log(`\n\nDone!`)
|
170
|
+
}
|
171
|
+
deployUFarm.dependencies = [
|
172
|
+
'PrepareEnvARB',
|
173
|
+
'InitializeUFarm',
|
174
|
+
'WhitelistControllers',
|
175
|
+
'WhiteListTokens',
|
176
|
+
]
|
177
|
+
deployUFarm.tags = _deployTags(['ArbitrumENV'])
|
178
|
+
export default deployUFarm
|
@@ -0,0 +1,308 @@
|
|
1
|
+
// SPDX-License-Identifier: BUSL-1.1
|
2
|
+
|
3
|
+
import { ABI, DeployFunction } from 'hardhat-deploy/types'
|
4
|
+
import { HardhatRuntimeEnvironment } from 'hardhat/types'
|
5
|
+
import {
|
6
|
+
getDeployerSigner,
|
7
|
+
getInstanceFromDeployment,
|
8
|
+
retryOperation,
|
9
|
+
getOrDeployPoolInstance,
|
10
|
+
deployOrGetFund,
|
11
|
+
activatePool,
|
12
|
+
checkMinFundDep,
|
13
|
+
_deployTags,
|
14
|
+
} from '../../../scripts/_deploy_helpers'
|
15
|
+
import {
|
16
|
+
PoolCreationStruct,
|
17
|
+
bitsToBigNumber,
|
18
|
+
constants,
|
19
|
+
packPerformanceCommission,
|
20
|
+
} from '../../../test/_helpers'
|
21
|
+
import { StableCoin, UFarmCore } from '../../../typechain-types'
|
22
|
+
import { ethers } from 'hardhat'
|
23
|
+
import { BigNumber } from '@ethersproject/bignumber'
|
24
|
+
import { _poolSwapUniV2 } from '../../../test/_fixtures'
|
25
|
+
|
26
|
+
const sepoliaEnvSetup: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
27
|
+
if (!hre.network.tags['arbitrumSepolia']) {
|
28
|
+
console.log('Not Arbitrum Sepolia network, skipping Sepolia environment setup')
|
29
|
+
return
|
30
|
+
}
|
31
|
+
|
32
|
+
const { ufarmPanicManager, ufarmFundApprover, ufarmManager, fundOwner, ufarmOwner } =
|
33
|
+
hre.namedAddresses
|
34
|
+
|
35
|
+
const deployerSigner = await getDeployerSigner(hre)
|
36
|
+
|
37
|
+
const usdt_deployment = await hre.deployments.get('USDT')
|
38
|
+
const ufarmCore_deployment = await hre.deployments.get('UFarmCore')
|
39
|
+
|
40
|
+
const ufarmCore_instance = await getInstanceFromDeployment<UFarmCore>(
|
41
|
+
hre,
|
42
|
+
ufarmCore_deployment,
|
43
|
+
deployerSigner,
|
44
|
+
)
|
45
|
+
const usdt_instance = await getInstanceFromDeployment<StableCoin>(
|
46
|
+
hre,
|
47
|
+
usdt_deployment,
|
48
|
+
deployerSigner,
|
49
|
+
)
|
50
|
+
|
51
|
+
const deplyerIsOwner = await ufarmCore_instance.hasPermissionsMask(
|
52
|
+
deployerSigner.address,
|
53
|
+
constants.ONE,
|
54
|
+
)
|
55
|
+
|
56
|
+
if (!deplyerIsOwner) {
|
57
|
+
console.log(`Deployer is not owner, ending script`)
|
58
|
+
return
|
59
|
+
}
|
60
|
+
|
61
|
+
const fund_instance = (
|
62
|
+
await deployOrGetFund('TestFund', deployerSigner.address, ufarmCore_instance, hre)
|
63
|
+
).connect(deployerSigner)
|
64
|
+
|
65
|
+
const fundOwnerBalance = await hre.ethers.provider.getBalance(fundOwner)
|
66
|
+
if (fundOwnerBalance.lt(constants.ONE.div(10))) {
|
67
|
+
const diff = constants.ONE.div(10).sub(fundOwnerBalance)
|
68
|
+
console.log(`Sending ${ethers.utils.formatEther(diff)} ETH to fund owner`)
|
69
|
+
await deployerSigner.sendTransaction({
|
70
|
+
to: fundOwner,
|
71
|
+
value: diff,
|
72
|
+
})
|
73
|
+
}
|
74
|
+
|
75
|
+
const initialFundStatus = await fund_instance.status()
|
76
|
+
if (initialFundStatus < constants.Fund.State.Active) {
|
77
|
+
console.log(`Current fund status is ${initialFundStatus}, setting to Active`)
|
78
|
+
await fund_instance.changeStatus(constants.Fund.State.Active)
|
79
|
+
} else {
|
80
|
+
console.log(`Current fund status is ${initialFundStatus}`)
|
81
|
+
}
|
82
|
+
|
83
|
+
const emptyPoolArgs: PoolCreationStruct = {
|
84
|
+
minInvestment: 0,
|
85
|
+
maxInvestment: hre.ethers.constants.MaxUint256,
|
86
|
+
managementCommission: 0,
|
87
|
+
packedPerformanceCommission: 0,
|
88
|
+
withdrawalLockupPeriod: 0,
|
89
|
+
valueToken: usdt_deployment.address,
|
90
|
+
staff: [],
|
91
|
+
name: 'Initialized Pool',
|
92
|
+
symbol: 'IP-1',
|
93
|
+
}
|
94
|
+
|
95
|
+
const pool_instance_1 = await getOrDeployPoolInstance(
|
96
|
+
'TestPool',
|
97
|
+
{
|
98
|
+
...emptyPoolArgs,
|
99
|
+
staff: [],
|
100
|
+
},
|
101
|
+
fund_instance,
|
102
|
+
hre,
|
103
|
+
)
|
104
|
+
|
105
|
+
// Activate pool
|
106
|
+
await retryOperation(async () => {
|
107
|
+
await activatePool(pool_instance_1, usdt_instance, deployerSigner, hre)
|
108
|
+
}, 3)
|
109
|
+
|
110
|
+
const anotherPool_instance = await getOrDeployPoolInstance(
|
111
|
+
'TestPool2',
|
112
|
+
{
|
113
|
+
...emptyPoolArgs,
|
114
|
+
minInvestment: constants.ONE_HUNDRED_BUCKS.mul(5),
|
115
|
+
maxInvestment: constants.ONE_HUNDRED_BUCKS.mul(100),
|
116
|
+
managementCommission: constants.FIVE_PERCENTS,
|
117
|
+
packedPerformanceCommission: packPerformanceCommission([
|
118
|
+
{ step: 0, commission: constants.Pool.Commission.MAX_PERFORMANCE_COMMISION / 100 },
|
119
|
+
]),
|
120
|
+
},
|
121
|
+
fund_instance,
|
122
|
+
hre,
|
123
|
+
)
|
124
|
+
|
125
|
+
const simplePool_instance = await getOrDeployPoolInstance(
|
126
|
+
'TestPool3',
|
127
|
+
{
|
128
|
+
...emptyPoolArgs,
|
129
|
+
name: 'Simple Pool',
|
130
|
+
symbol: 'SP',
|
131
|
+
staff: [],
|
132
|
+
},
|
133
|
+
fund_instance,
|
134
|
+
hre,
|
135
|
+
)
|
136
|
+
|
137
|
+
await retryOperation(async () => {
|
138
|
+
await activatePool(anotherPool_instance, usdt_instance, deployerSigner, hre)
|
139
|
+
}, 3)
|
140
|
+
|
141
|
+
// mint to fund
|
142
|
+
const desiredBalance = constants.ONE_HUNDRED_BUCKS.mul(77777777777777)
|
143
|
+
const deployer_USDT_balance = await usdt_instance.balanceOf(deployerSigner.address)
|
144
|
+
const difference = desiredBalance.gt(deployer_USDT_balance)
|
145
|
+
? desiredBalance.sub(deployer_USDT_balance)
|
146
|
+
: BigNumber.from(0)
|
147
|
+
if (difference.gt(BigNumber.from(0))) {
|
148
|
+
await (await usdt_instance.mint(deployerSigner.address, difference)).wait()
|
149
|
+
}
|
150
|
+
|
151
|
+
await checkMinFundDep(ufarmCore_instance.connect(deployerSigner), constants.ONE_BUCKS.mul(100))
|
152
|
+
|
153
|
+
// set protocol fee
|
154
|
+
const currentProtocolCommission = await ufarmCore_instance.protocolCommission()
|
155
|
+
if (!currentProtocolCommission.eq(constants.ZERO_POINT_3_PERCENTS)) {
|
156
|
+
console.log(`Current protocol commission is ${currentProtocolCommission}, setting to 0.3%`)
|
157
|
+
await ufarmCore_instance.setProtocolCommission(constants.ZERO_POINT_3_PERCENTS)
|
158
|
+
console.log(`Protocol commission set to 0.3%`)
|
159
|
+
} else {
|
160
|
+
console.log(`Current protocol commission is ${currentProtocolCommission}`)
|
161
|
+
}
|
162
|
+
|
163
|
+
// grant UFarm permissions
|
164
|
+
{
|
165
|
+
const ufarmPermissions = constants.UFarm.Permissions
|
166
|
+
const ufarmRoles = constants.UFarm.Roles
|
167
|
+
|
168
|
+
if (ufarmPanicManager !== '') {
|
169
|
+
const mask = bitsToBigNumber(ufarmRoles.MemberRole.concat(ufarmPermissions.TurnPauseOn))
|
170
|
+
const currentPermissions = await ufarmCore_instance.hasPermissionsMask(
|
171
|
+
ufarmPanicManager,
|
172
|
+
mask,
|
173
|
+
)
|
174
|
+
await retryOperation(async () => {
|
175
|
+
if (!currentPermissions) {
|
176
|
+
await hre.deployments.execute(
|
177
|
+
'UFarmCore',
|
178
|
+
{ from: deployerSigner.address },
|
179
|
+
'updatePermissions',
|
180
|
+
ufarmPanicManager,
|
181
|
+
bitsToBigNumber(ufarmRoles.MemberRole.concat(ufarmPermissions.TurnPauseOn)),
|
182
|
+
)
|
183
|
+
console.log(`Panic manager permissions set for ${ufarmPanicManager}`)
|
184
|
+
} else {
|
185
|
+
console.log(`Panic manager permissions already set`)
|
186
|
+
}
|
187
|
+
}, 3)
|
188
|
+
}
|
189
|
+
|
190
|
+
if (ufarmFundApprover !== '') {
|
191
|
+
const mask = bitsToBigNumber(
|
192
|
+
ufarmRoles.MemberRole.concat(Object.values(ufarmRoles.ModeratorRole)),
|
193
|
+
)
|
194
|
+
const currentPermissions = await ufarmCore_instance.hasPermissionsMask(
|
195
|
+
ufarmFundApprover,
|
196
|
+
mask,
|
197
|
+
)
|
198
|
+
if (!currentPermissions) {
|
199
|
+
await retryOperation(async () => {
|
200
|
+
await hre.deployments.execute(
|
201
|
+
'UFarmCore',
|
202
|
+
{ from: deployerSigner.address },
|
203
|
+
'updatePermissions',
|
204
|
+
ufarmFundApprover,
|
205
|
+
mask,
|
206
|
+
)
|
207
|
+
}, 3)
|
208
|
+
console.log(`Fund approver permissions set`)
|
209
|
+
}
|
210
|
+
}
|
211
|
+
|
212
|
+
if (ufarmManager !== '') {
|
213
|
+
const mask = bitsToBigNumber(
|
214
|
+
ufarmRoles.MemberRole.concat(...ufarmRoles.TeamManagerRole, ...ufarmRoles.ModeratorRole),
|
215
|
+
)
|
216
|
+
const currentPermissions = await ufarmCore_instance.hasPermissionsMask(ufarmManager, mask)
|
217
|
+
if (!currentPermissions) {
|
218
|
+
await retryOperation(async () => {
|
219
|
+
await hre.deployments.execute(
|
220
|
+
'UFarmCore',
|
221
|
+
{ from: deployerSigner.address },
|
222
|
+
'updatePermissions',
|
223
|
+
ufarmManager,
|
224
|
+
mask,
|
225
|
+
)
|
226
|
+
}, 3)
|
227
|
+
console.log(`Manager permissions set`)
|
228
|
+
}
|
229
|
+
}
|
230
|
+
|
231
|
+
if (ufarmOwner !== '') {
|
232
|
+
const ownerMask = hre.ethers.constants.MaxUint256
|
233
|
+
const currentPermissions = await ufarmCore_instance.hasPermissionsMask(ufarmOwner, ownerMask)
|
234
|
+
if (!currentPermissions) {
|
235
|
+
await retryOperation(async () => {
|
236
|
+
await hre.deployments.execute(
|
237
|
+
'UFarmCore',
|
238
|
+
{ from: deployerSigner.address },
|
239
|
+
'updatePermissions',
|
240
|
+
ufarmOwner,
|
241
|
+
ownerMask,
|
242
|
+
)
|
243
|
+
}, 3)
|
244
|
+
console.log(`Owner permissions set`)
|
245
|
+
}
|
246
|
+
}
|
247
|
+
}
|
248
|
+
|
249
|
+
{
|
250
|
+
console.log('Topup demo balances')
|
251
|
+
|
252
|
+
const demoTopups = [
|
253
|
+
{
|
254
|
+
address: ufarmFundApprover,
|
255
|
+
usdt: constants.ONE_BUCKS.mul(100_000_000),
|
256
|
+
eth: constants.ONE.mul(5),
|
257
|
+
},
|
258
|
+
{
|
259
|
+
address: ufarmManager,
|
260
|
+
usdt: constants.ONE_BUCKS.mul(1_000_000),
|
261
|
+
eth: constants.ONE.div(10),
|
262
|
+
},
|
263
|
+
]
|
264
|
+
|
265
|
+
for (const topup of demoTopups) {
|
266
|
+
if (topup.address === '') {
|
267
|
+
continue
|
268
|
+
}
|
269
|
+
|
270
|
+
const addr = topup.address
|
271
|
+
const addrUSDTBalance = await usdt_instance.balanceOf(addr)
|
272
|
+
const addrETHBalance = await hre.ethers.provider.getBalance(addr)
|
273
|
+
|
274
|
+
const desiredUsdtBalance = topup.usdt
|
275
|
+
const desiredEthBalance = topup.eth
|
276
|
+
|
277
|
+
if (addrUSDTBalance.lt(desiredUsdtBalance)) {
|
278
|
+
await (await usdt_instance.mint(addr, desiredUsdtBalance.sub(addrUSDTBalance))).wait()
|
279
|
+
console.log(`Sent some USDT to ${addr}`)
|
280
|
+
}
|
281
|
+
if (addrETHBalance.lt(desiredEthBalance)) {
|
282
|
+
await deployerSigner.sendTransaction({
|
283
|
+
to: addr,
|
284
|
+
value: desiredEthBalance.sub(addrETHBalance),
|
285
|
+
})
|
286
|
+
console.log(`Sent some ETH to ${addr}`)
|
287
|
+
}
|
288
|
+
}
|
289
|
+
}
|
290
|
+
|
291
|
+
console.log(`Deployer: ${deployerSigner.address}`)
|
292
|
+
console.log(
|
293
|
+
`Deployers final balance: ${ethers.utils.formatEther(await deployerSigner.getBalance())} ETH`,
|
294
|
+
)
|
295
|
+
|
296
|
+
console.log(`\n\nDone!`)
|
297
|
+
}
|
298
|
+
|
299
|
+
export default sepoliaEnvSetup
|
300
|
+
sepoliaEnvSetup.dependencies = _deployTags([
|
301
|
+
'Multicall3',
|
302
|
+
'UniV2Pairs',
|
303
|
+
'UniV3Pairs',
|
304
|
+
'InitializeUFarm',
|
305
|
+
'WhitelistControllers',
|
306
|
+
'WhiteListTokens',
|
307
|
+
])
|
308
|
+
sepoliaEnvSetup.tags = _deployTags(['SepoliaEnv'])
|
@@ -0,0 +1,112 @@
|
|
1
|
+
{
|
2
|
+
"tokens": {
|
3
|
+
"testnet": [
|
4
|
+
{
|
5
|
+
"name": "WBitcoin",
|
6
|
+
"rawName": "WBTC",
|
7
|
+
"symbol": "0xBTC",
|
8
|
+
"decimals": 8
|
9
|
+
},
|
10
|
+
{
|
11
|
+
"name": "Maker",
|
12
|
+
"rawName": "MKR",
|
13
|
+
"symbol": "MKR",
|
14
|
+
"decimals": 18
|
15
|
+
},
|
16
|
+
{
|
17
|
+
"name": "USDC",
|
18
|
+
"rawName": "USDC",
|
19
|
+
"symbol": "USDC",
|
20
|
+
"decimals": 6
|
21
|
+
},
|
22
|
+
{
|
23
|
+
"name": "DAI",
|
24
|
+
"rawName": "DAI",
|
25
|
+
"symbol": "DAI",
|
26
|
+
"decimals": 18
|
27
|
+
},
|
28
|
+
{
|
29
|
+
"name": "Tether USD",
|
30
|
+
"rawName": "USDT",
|
31
|
+
"symbol": "USDT",
|
32
|
+
"decimals": 6
|
33
|
+
},
|
34
|
+
{
|
35
|
+
"name": "Wrapped Ether",
|
36
|
+
"rawName": "WETH",
|
37
|
+
"symbol": "WETH",
|
38
|
+
"decimals": 18
|
39
|
+
},
|
40
|
+
{
|
41
|
+
"name": "Liquid staked Ether",
|
42
|
+
"rawName": "STETH",
|
43
|
+
"symbol": "stETH",
|
44
|
+
"decimals": 18
|
45
|
+
},
|
46
|
+
{
|
47
|
+
"name": "Wrapped Liquid staked Ether",
|
48
|
+
"rawName": "WSTETH",
|
49
|
+
"symbol": "WstETH",
|
50
|
+
"decimals": 18
|
51
|
+
}
|
52
|
+
]
|
53
|
+
},
|
54
|
+
"initialRates": [
|
55
|
+
{
|
56
|
+
"rawName1": "DAI",
|
57
|
+
"rawName0": "USDT",
|
58
|
+
"amount1": "100000000000000000000000000",
|
59
|
+
"amount0": "100000000000000"
|
60
|
+
},
|
61
|
+
{
|
62
|
+
"rawName1": "DAI",
|
63
|
+
"rawName0": "USDC",
|
64
|
+
"amount1": "100000000000000000000000000",
|
65
|
+
"amount0": "100000000000000"
|
66
|
+
},
|
67
|
+
{
|
68
|
+
"rawName1": "USDC",
|
69
|
+
"rawName0": "USDT",
|
70
|
+
"amount1": "100000000000000",
|
71
|
+
"amount0": "100000000000000"
|
72
|
+
},
|
73
|
+
{
|
74
|
+
|
75
|
+
"rawName1": "WBTC",
|
76
|
+
"rawName0": "USDT",
|
77
|
+
"amount1": "100000000000",
|
78
|
+
"amount0": "40000000000000"
|
79
|
+
},
|
80
|
+
{
|
81
|
+
"rawName1": "WETH",
|
82
|
+
"rawName0": "USDT",
|
83
|
+
"amount1": "1000000000000000000000",
|
84
|
+
"amount0": "1800000000000"
|
85
|
+
},
|
86
|
+
{
|
87
|
+
"rawName1": "WETH",
|
88
|
+
"rawName0": "DAI",
|
89
|
+
"amount1": "1000000000000000000000",
|
90
|
+
"amount0": "1800000000000000000000000"
|
91
|
+
},
|
92
|
+
|
93
|
+
{
|
94
|
+
"rawName1": "STETH",
|
95
|
+
"rawName0": "USDT",
|
96
|
+
"amount1": "1000000000000000000000",
|
97
|
+
"amount0": "1800000000000"
|
98
|
+
},
|
99
|
+
{
|
100
|
+
"rawName1": "WSTETH",
|
101
|
+
"rawName0": "USDT",
|
102
|
+
"amount1": "1000000000000000000000",
|
103
|
+
"amount0": "1800000000000"
|
104
|
+
},
|
105
|
+
{
|
106
|
+
"rawName1": "MKR",
|
107
|
+
"rawName0": "USDT",
|
108
|
+
"amount1": "1000000000000000000000000",
|
109
|
+
"amount0": "4000000000000000"
|
110
|
+
}
|
111
|
+
]
|
112
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
ticker,contract_name,address_chain_42161,address_chain_421614,address_chain_31338,address_chain_31339
|
2
|
+
USDT,AggregatorV2V3Interface,0x3f3f5dF88dC9F13eac63DF89EC16ef6e7E25DdE7,,,
|
3
|
+
USDC,AggregatorV2V3Interface,0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3,,,
|
4
|
+
WBTC,AggregatorV2V3Interface,0xd0C7101eACbB49F3deCcCc166d238410D6D46d57,,,
|
5
|
+
LINK,AggregatorV2V3Interface,0x86E53CF1B870786351Da77A57575e79CB55812CB,,,
|
6
|
+
UNI,AggregatorV2V3Interface,0x9C917083fDb403ab5ADbEC26Ee294f6EcAda2720,,,
|
7
|
+
DAI,AggregatorV2V3Interface,0xc5C8E77B397E531B8EC06BFb0048328B30E9eCfB,,,
|
8
|
+
PEPE,AggregatorV2V3Interface,0x02DEd5a7EDDA750E3Eb240b54437a54d57b74dBE,,,
|
9
|
+
ARB,AggregatorV2V3Interface,0xb2A824043730FE05F3DA2efaFa1CBbe83fa548D6,,,
|
10
|
+
GRT,AggregatorV2V3Interface,0x0F38D86FceF4955B705F35c9e41d1A16e0637c73,,,
|
11
|
+
LDO,AggregatorV2V3Interface,0xA43A34030088E6510FecCFb77E88ee5e7ed0fE64,,,
|
12
|
+
AXL,AggregatorV2V3Interface,0x84e8237CC1418Ea1B4A1e0C3e7F48c3A5fbC81AF,,,
|
13
|
+
USDD,AggregatorV2V3Interface,0x4Ee1f9ec1048979930aC832a3C1d18a0b4955a02,,,
|
14
|
+
FRAX,AggregatorV2V3Interface,0x0809E3d38d1B4214958faf06D8b1B1a2b73f2ab8,,,
|
15
|
+
WOO,AggregatorV2V3Interface,0x5e2b5C5C07cCA3437c4D724225Bb42c7E55d1597,,,
|
16
|
+
CRV,AggregatorV2V3Interface,0xaebDA2c976cfd1eE1977Eac079B4382acb849325,,,
|
17
|
+
TUSD,AggregatorV2V3Interface,0x6fAbee62266Da6686EE2744C6f15bb8352d2f28D,,,
|
18
|
+
PENDLE,AggregatorV2V3Interface,0x66853E19d73c0F9301fe099c324A1E9726953433,,,
|
19
|
+
COMP,AggregatorV2V3Interface,0xe7C53FFd03Eb6ceF7d208bC4C13446c76d1E5884,,,
|
20
|
+
GMX,AggregatorV2V3Interface,0xDB98056FecFff59D032aB628337A4887110df3dB,,,
|
21
|
+
YFI,AggregatorV2V3Interface,0x745Ab5b69E01E2BE1104Ca84937Bb71f96f5fB21,,,
|
22
|
+
SUSHI,AggregatorV2V3Interface,0xb2A8BA74cbca38508BA1632761b56C897060147C,,,
|
23
|
+
BAL,AggregatorV2V3Interface,0xBE5eA816870D11239c543F84b71439511D70B94f,,,
|
24
|
+
JOE,AggregatorV2V3Interface,0x04180965a782E487d0632013ABa488A472243542,,,
|
25
|
+
DODO,AggregatorV2V3Interface,0xA33a06c119EC08F92735F9ccA37e07Af08C4f281,,,
|
26
|
+
GNS,AggregatorV2V3Interface,0xE89E98CE4E19071E59Ed4780E0598b541CE76486,,,
|
27
|
+
KNC,AggregatorV2V3Interface,0xbF539d4c2106dd4D9AB6D56aed3d9023529Db145,,,
|
28
|
+
STG,AggregatorV2V3Interface,0xe74d69E233faB0d8F48921f2D93aDfDe44cEb3B7,,,
|
29
|
+
RDNT,AggregatorV2V3Interface,0x20d0Fcab0ECFD078B036b6CAf1FaC69A6453b352,,,
|
30
|
+
SPELL,AggregatorV2V3Interface,0x383b3624478124697BEF675F07cA37570b73992f,,,
|
31
|
+
WETH,AggregatorV2V3Interface,0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612,,,
|
32
|
+
stETH,AggregatorV2V3Interface,0x07C5b924399cc23c24a95c8743DE4006a32b7f2a,,,
|
@@ -0,0 +1,10 @@
|
|
1
|
+
name,abi,address_chain_42161,address_chain_421614,address_chain_31338,address_chain_31339
|
2
|
+
UniswapV2Factory,UniswapV2Factory,0xf1D7CC64Fb4452F05c498126312eBE29f30Fbcf9,,,
|
3
|
+
UniswapV2Router02,UniswapV2Router02,0x4752ba5dbc23f44d87826276bf6fd6b1c372ad24,,,
|
4
|
+
UniswapV3Factory,UniswapV3Factory,0x1F98431c8aD98523631AE4a59f267346ea31F984,0x248AB79Bbb9bC29bB72f7Cd42F17e054Fc40188e,,
|
5
|
+
SwapRouter,SwapRouter,0xE592427A0AEce92De3Edee1F18E0157C05861564,,,
|
6
|
+
NonfungiblePositionManager,NonfungiblePositionManager,0xC36442b4a4522E871399CD717aBDD847Ab11FE88,,,
|
7
|
+
QuoterV2,QuoterV2,0x61fFE014bA17989E743c5F6cB21bF9697530B21e,,,
|
8
|
+
AggregationRouterV5,AggregationRouterV5,0x1111111254EEB25477B68fb85Ed929f73A960582,,,
|
9
|
+
Multicall3,Multicall3,0xcA11bde05977b3631167028862bE2a173976CA11,,,
|
10
|
+
LidoRateOracle,IChainlinkAggregator,0xB1552C5e96B312d0Bf8b554186F846C40614a540,,,
|
@@ -0,0 +1,32 @@
|
|
1
|
+
name,ticker,logo,decimals,popular,address_chain_42161,address_chain_421614,address_chain_31338,address_chain_31339
|
2
|
+
Tether USDt,USDT,https://s2.coinmarketcap.com/static/img/coins/64x64/825.png,6,TRUE,0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9,,,
|
3
|
+
USDC,USDC,https://s2.coinmarketcap.com/static/img/coins/64x64/3408.png,6,TRUE,0xaf88d065e77c8cC2239327C5EDb3A432268e5831,,,
|
4
|
+
Wrapped Bitcoin,WBTC,https://s2.coinmarketcap.com/static/img/coins/64x64/3717.png,8,TRUE,0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f,,,
|
5
|
+
Chainlink,LINK,https://s2.coinmarketcap.com/static/img/coins/64x64/1975.png,18,,0xf97f4df75117a78c1A5a0DBb814Af92458539FB4,,,
|
6
|
+
Uniswap,UNI,https://s2.coinmarketcap.com/static/img/coins/64x64/7083.png,18,,0xFa7F8980b0f1E64A2062791cc3b0871572f1F7f0,,,
|
7
|
+
Dai,DAI,https://s2.coinmarketcap.com/static/img/coins/64x64/4943.png,18,,0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1,,,
|
8
|
+
Pepe,PEPE,https://s2.coinmarketcap.com/static/img/coins/64x64/24478.png,18,,0x25d887ce7a35172c62febfd67a1856f20faebb00,,,
|
9
|
+
Arbitrum,ARB,https://s2.coinmarketcap.com/static/img/coins/64x64/11841.png,18,,0x912CE59144191C1204E64559FE8253a0e49E6548,,,
|
10
|
+
The Graph,GRT,https://s2.coinmarketcap.com/static/img/coins/64x64/6719.png,18,,0x9623063377AD1B27544C965cCd7342f7EA7e88C7,,,
|
11
|
+
Lido DAO,LDO,https://s2.coinmarketcap.com/static/img/coins/64x64/8000.png,18,,0x13Ad51ed4F1B7e9Dc168d8a00cB3f4dDD85EfA60,,,
|
12
|
+
Axelar,AXL,https://s2.coinmarketcap.com/static/img/coins/64x64/17799.png,6,,0x23ee2343B892b1BB63503a4FAbc840E0e2C6810f,,,
|
13
|
+
USDD,USDD,https://s2.coinmarketcap.com/static/img/coins/64x64/19891.png,18,,0x680447595e8b7b3aa1b43beb9f6098c79ac2ab3f,,,
|
14
|
+
Frax,FRAX,https://s2.coinmarketcap.com/static/img/coins/64x64/6952.png,18,,0x17FC002b466eEc40DaE837Fc4bE5c67993ddBd6F,,,
|
15
|
+
WOO,WOO,https://s2.coinmarketcap.com/static/img/coins/64x64/7501.png,18,,0xcafcd85d8ca7ad1e1c6f82f651fa15e33aefd07b,,,
|
16
|
+
Curve DAO Token,CRV,https://s2.coinmarketcap.com/static/img/coins/64x64/6538.png,18,,0x11cDb42B0EB46D95f990BeDD4695A6e3fA034978,,,
|
17
|
+
TrueUSD,TUSD,https://s2.coinmarketcap.com/static/img/coins/64x64/2563.png,18,,0x4D15a3A2286D883AF0AA1B3f21367843FAc63E07,,,
|
18
|
+
Pendle,PENDLE,https://s2.coinmarketcap.com/static/img/coins/64x64/9481.png,18,,0x0c880f6761f1af8d9aa9c466984b80dab9a8c9e8,,,
|
19
|
+
Compound,COMP,https://s2.coinmarketcap.com/static/img/coins/64x64/5692.png,18,,0x354a6da3fcde098f8389cad84b0182725c6c91de,,,
|
20
|
+
GMX,GMX,https://s2.coinmarketcap.com/static/img/coins/64x64/11857.png,18,,0xfc5a1a6eb076a2c7ad06ed22c90d7e710e35ad0a,,,
|
21
|
+
yearn.finance,YFI,https://s2.coinmarketcap.com/static/img/coins/64x64/5864.png,18,,0x82e3A8F066a6989666b031d916c43672085b1582,,,
|
22
|
+
SushiSwap,SUSHI,https://s2.coinmarketcap.com/static/img/coins/64x64/6758.png,18,,0xd4d42f0b6def4ce0383636770ef773390d85c61a,,,
|
23
|
+
Balancer,BAL,https://s2.coinmarketcap.com/static/img/coins/64x64/5728.png,18,,0x040d1edc9569d4bab2d15287dc5a4f10f56a56b8,,,
|
24
|
+
JOE,JOE,https://s2.coinmarketcap.com/static/img/coins/64x64/11396.png,18,,0x371c7ec6D8039ff7933a2AA28EB827Ffe1F52f07,,,
|
25
|
+
DODO,DODO,https://s2.coinmarketcap.com/static/img/coins/64x64/7224.png,18,,0x69Eb4FA4a2fbd498C257C57Ea8b7655a2559A581,,,
|
26
|
+
Gains Network,GNS,https://s2.coinmarketcap.com/static/img/coins/64x64/13663.png,18,,0x18c11FD286C5EC11c3b683Caa813B77f5163A122,,,
|
27
|
+
Kyber Network Crystal v2,KNC,https://s2.coinmarketcap.com/static/img/coins/64x64/9444.png,18,,0xe4dddfe67e7164b0fe14e218d80dc4c08edc01cb,,,
|
28
|
+
Stargate Finance,STG,https://s2.coinmarketcap.com/static/img/coins/64x64/18934.png,18,,0x6694340fc020c5e6b96567843da2df01b2ce1eb6,,,
|
29
|
+
Radiant Capital,RDNT,https://s2.coinmarketcap.com/static/img/coins/64x64/21106.png,18,,0x3082CC23568eA640225c2467653dB90e9250AaA0,,,
|
30
|
+
Spell Token,SPELL,https://s2.coinmarketcap.com/static/img/coins/64x64/11289.png,18,,0x3e6648c5a70a150a88bce65f4ad4d506fe15d2af,,,
|
31
|
+
Wrapped Ether,WETH,https://s2.coinmarketcap.com/static/img/coins/64x64/1027.png,18,TRUE,0x82af49447d8a07e3bd95bd0d56f35241523fbab1,,,
|
32
|
+
Wrapped Lido Staked ETH,wstETH,https://s2.coinmarketcap.com/static/img/coins/64x64/12409.png,18,,0x5979d7b546e38e414f7e9822514be443a4800529,,,
|