@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,783 @@
|
|
1
|
+
// SPDX-License-Identifier: UNLICENSED
|
2
|
+
|
3
|
+
import { time, loadFixture } from '@nomicfoundation/hardhat-network-helpers'
|
4
|
+
import { ethers, upgrades, run } from 'hardhat'
|
5
|
+
import * as hre from 'hardhat'
|
6
|
+
import { BigNumberish, BigNumber, ContractTransaction, ContractReceipt, BaseContract } from 'ethers'
|
7
|
+
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'
|
8
|
+
|
9
|
+
import {
|
10
|
+
FundFactory__factory,
|
11
|
+
UFarmFund,
|
12
|
+
PriceOracle__factory,
|
13
|
+
WETH9,
|
14
|
+
PoolFactory__factory,
|
15
|
+
AggregationRouterV5__factory,
|
16
|
+
OneInchToUfarmTestEnv__factory,
|
17
|
+
UniswapV2Factory,
|
18
|
+
UniswapV2Router02,
|
19
|
+
UFarmPool,
|
20
|
+
UnoswapV2Controller,
|
21
|
+
UFarmPool__factory,
|
22
|
+
UFarmCore,
|
23
|
+
UFarmCore__factory,
|
24
|
+
PoolAdmin__factory,
|
25
|
+
PriceOracle,
|
26
|
+
IERC20Metadata,
|
27
|
+
UniswapV2ControllerUFarm__factory,
|
28
|
+
AggregatorV2V3Interface,
|
29
|
+
UFarmFund__factory,
|
30
|
+
UniswapV2Pair__factory,
|
31
|
+
MockV3wstETHstETHAgg,
|
32
|
+
StableCoin,
|
33
|
+
DepositContractMock,
|
34
|
+
NodeOperatorsRegistry,
|
35
|
+
Lido,
|
36
|
+
WstETH,
|
37
|
+
AggregationRouterV5,
|
38
|
+
UniswapV3Factory,
|
39
|
+
SwapRouter,
|
40
|
+
NonfungiblePositionManager,
|
41
|
+
QuoterV2,
|
42
|
+
PoolAdmin,
|
43
|
+
PoolFactory,
|
44
|
+
FundFactory,
|
45
|
+
WstETHOracle,
|
46
|
+
UnoswapV3Controller,
|
47
|
+
OneInchV5Controller,
|
48
|
+
} from '../typechain-types'
|
49
|
+
|
50
|
+
import {
|
51
|
+
constants,
|
52
|
+
deployPool,
|
53
|
+
encodePoolSwapDataUniswapV2,
|
54
|
+
getReceipt,
|
55
|
+
protocolToBytes32,
|
56
|
+
getEventFromTx,
|
57
|
+
AssetWithPriceFeed,
|
58
|
+
addLiquidityUniswapV3,
|
59
|
+
packPerformanceCommission,
|
60
|
+
getInitCodeHash,
|
61
|
+
} from './_helpers'
|
62
|
+
import { _BNsqrt, bitsToBigNumber, PoolCreationStruct } from './_helpers'
|
63
|
+
import { _loadFixture, _tokensFixture } from './_deployed_fixtures'
|
64
|
+
import {
|
65
|
+
getSignersByNames,
|
66
|
+
getTokenDeployments,
|
67
|
+
getInstanceFromDeployment,
|
68
|
+
getInstanceOfDeployed,
|
69
|
+
runDeployTag,
|
70
|
+
mockedAggregatorName,
|
71
|
+
getTokenFeed,
|
72
|
+
isTestnet,
|
73
|
+
getNetworkType,
|
74
|
+
} from '../scripts/_deploy_helpers'
|
75
|
+
|
76
|
+
export async function getCostOfToken(
|
77
|
+
stable: string,
|
78
|
+
token: string,
|
79
|
+
account: string,
|
80
|
+
core: UFarmCore,
|
81
|
+
): Promise<BigNumberish> {
|
82
|
+
const tokenInstance = (await ethers.getContractAt(
|
83
|
+
'@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol:IERC20Metadata',
|
84
|
+
token,
|
85
|
+
)) as IERC20Metadata
|
86
|
+
|
87
|
+
const amountIn = await tokenInstance.balanceOf(account)
|
88
|
+
|
89
|
+
const priceOracle = await ethers.getContractAt('PriceOracle', await core.priceOracle())
|
90
|
+
const cost = await priceOracle.getCostERC20(token, amountIn, stable)
|
91
|
+
return cost
|
92
|
+
}
|
93
|
+
|
94
|
+
export async function getPriceRate(
|
95
|
+
tokenPriceOf: string,
|
96
|
+
tokenPriceFrom: string,
|
97
|
+
univ2_factory: UniswapV2Factory,
|
98
|
+
): Promise<BigNumber> {
|
99
|
+
const pairAddr = await univ2_factory.getPair(tokenPriceOf, tokenPriceFrom)
|
100
|
+
const pair = await ethers.getContractAt('UniswapV2Pair', pairAddr)
|
101
|
+
|
102
|
+
const priceOf0 = tokenPriceOf == (await pair.token0())
|
103
|
+
const [token0_addr, token1_addr] = [await pair.token0(), await pair.token1()]
|
104
|
+
const [token0_instance, token1_instance] = [
|
105
|
+
(await ethers.getContractAt(
|
106
|
+
'@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol:IERC20Metadata',
|
107
|
+
token0_addr,
|
108
|
+
)) as IERC20Metadata,
|
109
|
+
(await ethers.getContractAt(
|
110
|
+
'@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol:IERC20Metadata',
|
111
|
+
token1_addr,
|
112
|
+
)) as IERC20Metadata,
|
113
|
+
]
|
114
|
+
const [token0_decimals, token1_decimals] = [
|
115
|
+
await token0_instance.decimals(),
|
116
|
+
await token1_instance.decimals(),
|
117
|
+
]
|
118
|
+
|
119
|
+
const reserves = await pair.getReserves()
|
120
|
+
|
121
|
+
if (priceOf0) {
|
122
|
+
return reserves[1]
|
123
|
+
.mul(BigNumber.from(10).pow(token0_decimals).mul(997))
|
124
|
+
.div(reserves[0].mul(1000))
|
125
|
+
} else {
|
126
|
+
return reserves[0]
|
127
|
+
.mul(BigNumber.from(10).pow(token1_decimals).mul(997))
|
128
|
+
.div(reserves[1].mul(1000))
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
export async function executeAndGetTimestamp(tx: Promise<ContractTransaction>): Promise<BigNumber> {
|
133
|
+
const receipt = await getReceipt(tx)
|
134
|
+
const block = await ethers.provider.getBlock(receipt.blockNumber)
|
135
|
+
return BigNumber.from(block.timestamp)
|
136
|
+
}
|
137
|
+
|
138
|
+
export async function _poolSwapUniV2(
|
139
|
+
pool: UFarmPool,
|
140
|
+
unoswapV2Controller: UnoswapV2Controller,
|
141
|
+
amountIn: BigNumber,
|
142
|
+
path: string[],
|
143
|
+
) {
|
144
|
+
const amountOutMin = await unoswapV2Controller.getAmountOut(amountIn, path)
|
145
|
+
const deadline = Date.now() + 100
|
146
|
+
const tx = pool.protocolAction(
|
147
|
+
constants.UFarm.prtocols.UniswapV2ProtocolString,
|
148
|
+
encodePoolSwapDataUniswapV2(amountIn, amountOutMin, deadline, path),
|
149
|
+
)
|
150
|
+
// Find swap event:
|
151
|
+
const event = await getEventFromTx(tx, unoswapV2Controller, 'SwapUnoV2')
|
152
|
+
|
153
|
+
return {
|
154
|
+
amountOut: event.args.amountOut as BigNumber,
|
155
|
+
tx: tx,
|
156
|
+
}
|
157
|
+
}
|
158
|
+
|
159
|
+
// FIXTURES
|
160
|
+
|
161
|
+
export async function blankPoolWithRatesFixture() {
|
162
|
+
const {
|
163
|
+
blankPool_instance,
|
164
|
+
UFarmFund_instance,
|
165
|
+
UFarmCore_instance,
|
166
|
+
UniswapV2Router02_instance,
|
167
|
+
bob,
|
168
|
+
tokens,
|
169
|
+
MockedAggregator_wstETHstETH,
|
170
|
+
...rest
|
171
|
+
} = await loadFixture(ETHPoolFixture)
|
172
|
+
|
173
|
+
const performanceCommission = constants.Pool.Commission.ONE_HUNDRED_PERCENT / 10
|
174
|
+
const packedPerformanceCommission = packPerformanceCommission([
|
175
|
+
{ step: 0, commission: performanceCommission },
|
176
|
+
])
|
177
|
+
const managementCommission = constants.FIVE_PERCENTS
|
178
|
+
const protocolCommission = constants.ZERO_POINT_3_PERCENTS
|
179
|
+
|
180
|
+
await UFarmCore_instance.setProtocolCommission(protocolCommission)
|
181
|
+
await blankPool_instance.admin.setCommissions(managementCommission, packedPerformanceCommission)
|
182
|
+
|
183
|
+
const increaseWstETHRate = async (notUpdateOracle?: boolean) => {
|
184
|
+
if (tokens.stETH) {
|
185
|
+
await tokens.stETH['simulateBeaconRewards()']()
|
186
|
+
|
187
|
+
if (notUpdateOracle) {
|
188
|
+
return
|
189
|
+
}
|
190
|
+
await MockedAggregator_wstETHstETH.updateAnswerWithChainlinkPrice()
|
191
|
+
}
|
192
|
+
}
|
193
|
+
|
194
|
+
return {
|
195
|
+
blankPool_instance,
|
196
|
+
UFarmFund_instance,
|
197
|
+
UFarmCore_instance,
|
198
|
+
UniswapV2Router02_instance,
|
199
|
+
bob,
|
200
|
+
tokens,
|
201
|
+
performanceCommission,
|
202
|
+
managementCommission,
|
203
|
+
protocolCommission,
|
204
|
+
MockedAggregator_wstETHstETH,
|
205
|
+
increaseWstETHRate,
|
206
|
+
...rest,
|
207
|
+
}
|
208
|
+
}
|
209
|
+
|
210
|
+
export async function ETHPoolFixture() {
|
211
|
+
const {
|
212
|
+
UFarmCore_instance,
|
213
|
+
alice,
|
214
|
+
deployer,
|
215
|
+
UFarmFund_instance,
|
216
|
+
poolArgs,
|
217
|
+
tokens,
|
218
|
+
UnoswapV2Controller_instance,
|
219
|
+
...rest
|
220
|
+
} = await loadFixture(fundWithPoolFixture)
|
221
|
+
const ETHPoolArgs = poolArgs
|
222
|
+
|
223
|
+
const ethPool_instance = await deployPool(ETHPoolArgs, UFarmFund_instance.connect(alice))
|
224
|
+
|
225
|
+
// Pool init
|
226
|
+
const MANAGERS_INVESTMENT = constants.ONE_HUNDRED_BUCKS
|
227
|
+
|
228
|
+
await tokens.USDT.mint(UFarmFund_instance.address, MANAGERS_INVESTMENT)
|
229
|
+
|
230
|
+
await UFarmFund_instance.approveAssetTo(
|
231
|
+
tokens.USDT.address,
|
232
|
+
ethPool_instance.pool.address,
|
233
|
+
MANAGERS_INVESTMENT,
|
234
|
+
)
|
235
|
+
|
236
|
+
await UFarmFund_instance.depositToPool(ethPool_instance.pool.address, MANAGERS_INVESTMENT)
|
237
|
+
|
238
|
+
await ethPool_instance.admin.changePoolStatus(constants.Pool.State.Active)
|
239
|
+
|
240
|
+
await _poolSwapUniV2(ethPool_instance.pool, UnoswapV2Controller_instance, MANAGERS_INVESTMENT, [
|
241
|
+
tokens.USDT.address,
|
242
|
+
tokens.WETH.address,
|
243
|
+
])
|
244
|
+
|
245
|
+
return {
|
246
|
+
UFarmCore_instance,
|
247
|
+
alice,
|
248
|
+
deployer,
|
249
|
+
UFarmFund_instance,
|
250
|
+
poolArgs,
|
251
|
+
tokens,
|
252
|
+
ethPool_instance,
|
253
|
+
ETHPoolArgs,
|
254
|
+
MANAGERS_INVESTMENT,
|
255
|
+
UnoswapV2Controller_instance,
|
256
|
+
...rest,
|
257
|
+
}
|
258
|
+
}
|
259
|
+
|
260
|
+
export async function fundWithPoolFixture() {
|
261
|
+
const {
|
262
|
+
UFarmCore_instance,
|
263
|
+
alice,
|
264
|
+
deployer,
|
265
|
+
UFarmFund_instance,
|
266
|
+
poolArgs,
|
267
|
+
tokens,
|
268
|
+
emptyPoolArgs,
|
269
|
+
...rest
|
270
|
+
} = await loadFixture(UFarmFundFixture)
|
271
|
+
|
272
|
+
await UFarmFund_instance.connect(alice).changeStatus(1)
|
273
|
+
|
274
|
+
const UFarmPool_instance = await deployPool({ ...poolArgs }, UFarmFund_instance.connect(alice))
|
275
|
+
|
276
|
+
await UFarmFund_instance.connect(alice).approveAssetTo(
|
277
|
+
tokens.USDT.address,
|
278
|
+
UFarmPool_instance.pool.address,
|
279
|
+
ethers.constants.MaxUint256,
|
280
|
+
)
|
281
|
+
|
282
|
+
await UFarmPool_instance.admin.changePoolStatus(constants.Pool.State.Active)
|
283
|
+
|
284
|
+
const blankPool_instance = await deployPool(
|
285
|
+
{ ...emptyPoolArgs, name: 'Blank Pool' },
|
286
|
+
UFarmFund_instance.connect(alice),
|
287
|
+
)
|
288
|
+
|
289
|
+
const initialized_pool_instance = await deployPool(
|
290
|
+
{ ...poolArgs, name: 'Initialized Pool' },
|
291
|
+
UFarmFund_instance.connect(alice),
|
292
|
+
)
|
293
|
+
|
294
|
+
await tokens.USDT.mint(UFarmFund_instance.address, constants.ONE_HUNDRED_BUCKS)
|
295
|
+
|
296
|
+
// await initialized_pool_instance.whitelistProtocols([constants.UFarm.prtocols.UniswapV2ProtocolString])
|
297
|
+
|
298
|
+
await UFarmFund_instance.approveAssetTo(
|
299
|
+
tokens.USDT.address,
|
300
|
+
initialized_pool_instance.pool.address,
|
301
|
+
constants.ONE_HUNDRED_BUCKS,
|
302
|
+
)
|
303
|
+
|
304
|
+
await initialized_pool_instance.admin.changePoolStatus(constants.Pool.State.Active)
|
305
|
+
|
306
|
+
return {
|
307
|
+
...rest,
|
308
|
+
alice,
|
309
|
+
deployer,
|
310
|
+
UFarmCore_instance,
|
311
|
+
UFarmFund_instance,
|
312
|
+
UFarmPool_instance,
|
313
|
+
poolArgs,
|
314
|
+
emptyPoolArgs,
|
315
|
+
blankPool_instance,
|
316
|
+
initialized_pool_instance,
|
317
|
+
tokens,
|
318
|
+
}
|
319
|
+
}
|
320
|
+
|
321
|
+
export async function UFarmFundFixture() {
|
322
|
+
const { UFarmCore_instance, deployer, alice, bob, USDT, ...rest } = await loadFixture(
|
323
|
+
UFarmCoreFixture,
|
324
|
+
)
|
325
|
+
|
326
|
+
const UnoswapV3Controller_instance = await getInstanceOfDeployed<UnoswapV3Controller>(
|
327
|
+
hre,
|
328
|
+
'UniV3Controller',
|
329
|
+
deployer,
|
330
|
+
)
|
331
|
+
const OneInchController_instance = await getInstanceOfDeployed<OneInchV5Controller>(
|
332
|
+
hre,
|
333
|
+
'OneInchV5Controller',
|
334
|
+
deployer,
|
335
|
+
)
|
336
|
+
await runDeployTag(hre, 'WhiteListTokens')
|
337
|
+
|
338
|
+
const firstFundId = 0
|
339
|
+
|
340
|
+
await UFarmCore_instance.connect(deployer).createFund(
|
341
|
+
alice.address,
|
342
|
+
protocolToBytes32('AnyValue'),
|
343
|
+
)
|
344
|
+
|
345
|
+
const address_UFarmFund = await UFarmCore_instance.getFund(firstFundId)
|
346
|
+
|
347
|
+
const UFarmFund_instance: UFarmFund = await ethers.getContractAt(
|
348
|
+
'UFarmFund',
|
349
|
+
address_UFarmFund,
|
350
|
+
alice,
|
351
|
+
)
|
352
|
+
|
353
|
+
const allPoolPermissionsMask = bitsToBigNumber(
|
354
|
+
Array.from(Object.values(constants.Pool.Permissions)),
|
355
|
+
)
|
356
|
+
|
357
|
+
const poolArgs: PoolCreationStruct = {
|
358
|
+
minInvestment: 1 as BigNumberish,
|
359
|
+
maxInvestment: ethers.utils.parseUnits('1000000', 6),
|
360
|
+
managementCommission: 2 as BigNumberish,
|
361
|
+
packedPerformanceCommission: packPerformanceCommission([{ step: 0, commission: 3 }]),
|
362
|
+
withdrawalLockupPeriod: 0 as BigNumberish,
|
363
|
+
valueToken: USDT.address,
|
364
|
+
staff: [
|
365
|
+
{
|
366
|
+
addr: bob.address,
|
367
|
+
permissionsMask: bitsToBigNumber([
|
368
|
+
constants.Pool.Permissions.Member,
|
369
|
+
constants.Pool.Permissions.UpdateLockupPeriods,
|
370
|
+
]),
|
371
|
+
},
|
372
|
+
{
|
373
|
+
addr: alice.address,
|
374
|
+
permissionsMask: bitsToBigNumber(Array.from(Object.values(constants.Pool.Permissions))),
|
375
|
+
},
|
376
|
+
],
|
377
|
+
name: 'UFarmPool',
|
378
|
+
symbol: 'Pool symbol',
|
379
|
+
}
|
380
|
+
|
381
|
+
const emptyPoolArgs: PoolCreationStruct = {
|
382
|
+
minInvestment: 0 as BigNumberish,
|
383
|
+
maxInvestment: ethers.constants.MaxUint256 as BigNumberish,
|
384
|
+
managementCommission: 0 as BigNumberish,
|
385
|
+
packedPerformanceCommission: 0 as BigNumberish,
|
386
|
+
withdrawalLockupPeriod: 0 as BigNumberish,
|
387
|
+
valueToken: USDT.address,
|
388
|
+
staff: [],
|
389
|
+
name: 'Pool name',
|
390
|
+
symbol: 'Pool symbol',
|
391
|
+
}
|
392
|
+
|
393
|
+
return {
|
394
|
+
...rest,
|
395
|
+
alice,
|
396
|
+
bob,
|
397
|
+
deployer,
|
398
|
+
UFarmCore_instance,
|
399
|
+
UFarmFund_instance,
|
400
|
+
poolArgs,
|
401
|
+
emptyPoolArgs,
|
402
|
+
USDT,
|
403
|
+
UnoswapV3Controller_instance,
|
404
|
+
OneInchController_instance,
|
405
|
+
}
|
406
|
+
}
|
407
|
+
|
408
|
+
export async function UFarmCoreFixture() {
|
409
|
+
const { deployer, PriceOracle_instance, tokens, UnoswapV2Controller_instance, ...rest } =
|
410
|
+
await loadFixture(UniswapV3Fixture)
|
411
|
+
|
412
|
+
const Pool_implementation_factory = (await ethers.getContractFactory(
|
413
|
+
'UFarmPool',
|
414
|
+
)) as UFarmPool__factory
|
415
|
+
|
416
|
+
const PoolAdmin_implementation_factory = (await ethers.getContractFactory(
|
417
|
+
'PoolAdmin',
|
418
|
+
)) as PoolAdmin__factory
|
419
|
+
|
420
|
+
const Fund_implementation_factory = (await ethers.getContractFactory(
|
421
|
+
'UFarmFund',
|
422
|
+
)) as UFarmFund__factory
|
423
|
+
|
424
|
+
const Core_implementation_factory = (await ethers.getContractFactory(
|
425
|
+
'UFarmCore',
|
426
|
+
)) as UFarmCore__factory
|
427
|
+
|
428
|
+
await runDeployTag(hre, 'InitializeUFarm')
|
429
|
+
await runDeployTag(hre, 'WhitelistControllers')
|
430
|
+
|
431
|
+
const Pool_beacon = await getInstanceOfDeployed<UFarmPool>(hre, 'UFarmPool', deployer)
|
432
|
+
|
433
|
+
const PoolAdmin_beacon = await getInstanceOfDeployed<PoolAdmin>(hre, 'PoolAdmin', deployer)
|
434
|
+
const Fund_beacon = await getInstanceOfDeployed<UFarmFund>(hre, 'UFarmFund', deployer)
|
435
|
+
|
436
|
+
const UFarmCore_instance = await getInstanceOfDeployed<UFarmCore>(hre, 'UFarmCore', deployer)
|
437
|
+
const PoolFactory_factory = (await ethers.getContractFactory(
|
438
|
+
'PoolFactory',
|
439
|
+
)) as PoolFactory__factory
|
440
|
+
|
441
|
+
const PoolFactory_instance = await getInstanceOfDeployed<PoolFactory>(
|
442
|
+
hre,
|
443
|
+
'PoolFactory',
|
444
|
+
deployer,
|
445
|
+
)
|
446
|
+
|
447
|
+
const FundFactory_factory = (await ethers.getContractFactory(
|
448
|
+
'FundFactory',
|
449
|
+
)) as FundFactory__factory
|
450
|
+
const FundFactory_instance = await getInstanceOfDeployed<FundFactory>(
|
451
|
+
hre,
|
452
|
+
'FundFactory',
|
453
|
+
deployer,
|
454
|
+
)
|
455
|
+
|
456
|
+
const factories = {
|
457
|
+
PoolFactory_factory,
|
458
|
+
FundFactory_factory,
|
459
|
+
}
|
460
|
+
|
461
|
+
return {
|
462
|
+
Pool_beacon,
|
463
|
+
PoolAdmin_beacon,
|
464
|
+
Fund_beacon,
|
465
|
+
deployer,
|
466
|
+
UFarmCore_instance,
|
467
|
+
Pool_implementation_factory,
|
468
|
+
Core_implementation_factory,
|
469
|
+
PriceOracle_instance,
|
470
|
+
UnoswapV2Controller_instance,
|
471
|
+
FundFactory_instance,
|
472
|
+
PoolFactory_instance,
|
473
|
+
factories,
|
474
|
+
tokens,
|
475
|
+
...rest,
|
476
|
+
}
|
477
|
+
}
|
478
|
+
|
479
|
+
export async function UniswapV3Fixture() {
|
480
|
+
const { deployer, wallet, tokens, PriceOracle_instance, ...rest } = await loadFixture(
|
481
|
+
OneInchFixture,
|
482
|
+
)
|
483
|
+
await runDeployTag(hre, 'UniV3Pairs')
|
484
|
+
|
485
|
+
const uniswapV3Factory_instance = await getInstanceOfDeployed<UniswapV3Factory>(
|
486
|
+
hre,
|
487
|
+
'UniswapV3Factory',
|
488
|
+
)
|
489
|
+
|
490
|
+
const uniswapv3Router_instance = await getInstanceOfDeployed<SwapRouter>(hre, 'SwapRouter')
|
491
|
+
|
492
|
+
const nonFungPosManager_instance = await getInstanceOfDeployed<NonfungiblePositionManager>(
|
493
|
+
hre,
|
494
|
+
'NonfungiblePositionManager',
|
495
|
+
)
|
496
|
+
|
497
|
+
const quoter_instance = await getInstanceOfDeployed<QuoterV2>(hre, 'QuoterV2')
|
498
|
+
|
499
|
+
return {
|
500
|
+
deployer,
|
501
|
+
wallet,
|
502
|
+
tokens,
|
503
|
+
uniswapV3Factory_instance,
|
504
|
+
uniswapv3Router_instance,
|
505
|
+
quoter_instance,
|
506
|
+
PriceOracle_instance,
|
507
|
+
nonFungPosManager_instance,
|
508
|
+
...rest,
|
509
|
+
}
|
510
|
+
}
|
511
|
+
|
512
|
+
export async function OneInchFixture() {
|
513
|
+
const { deployer, tokens, ...rest } = await loadFixture(PriceOracleFixture)
|
514
|
+
|
515
|
+
await runDeployTag(hre, 'OneInch')
|
516
|
+
|
517
|
+
const oneInchAggrV5_factory = (await ethers.getContractFactory(
|
518
|
+
'AggregationRouterV5',
|
519
|
+
)) as AggregationRouterV5__factory
|
520
|
+
|
521
|
+
const oneInchAggrV5_instance = await getInstanceOfDeployed<AggregationRouterV5>(
|
522
|
+
hre,
|
523
|
+
'AggregationRouterV5',
|
524
|
+
)
|
525
|
+
|
526
|
+
const inchConverter_factory = (await ethers.getContractFactory(
|
527
|
+
'OneInchToUfarmTestEnv',
|
528
|
+
)) as OneInchToUfarmTestEnv__factory
|
529
|
+
|
530
|
+
const inchConverter_instance = await inchConverter_factory.deploy(tokens.WETH.address)
|
531
|
+
|
532
|
+
return {
|
533
|
+
oneInchAggrV5_instance,
|
534
|
+
oneInchAggrV5_factory,
|
535
|
+
inchConverter_instance,
|
536
|
+
deployer,
|
537
|
+
tokens,
|
538
|
+
...rest,
|
539
|
+
}
|
540
|
+
}
|
541
|
+
|
542
|
+
export async function PriceOracleFixture() {
|
543
|
+
const { deployer, tokens, ...rest } = await loadFixture(MockedAggregatorFixture)
|
544
|
+
|
545
|
+
await runDeployTag(hre, 'PriceOracle')
|
546
|
+
const PriceOracle_factory = (await ethers.getContractFactory(
|
547
|
+
'PriceOracle',
|
548
|
+
)) as PriceOracle__factory
|
549
|
+
|
550
|
+
const PriceOracle_instance = await getInstanceOfDeployed<PriceOracle>(hre, 'PriceOracle')
|
551
|
+
|
552
|
+
const UnoswapV2Controller_factory = (await ethers.getContractFactory(
|
553
|
+
'UniswapV2ControllerUFarm',
|
554
|
+
)) as UniswapV2ControllerUFarm__factory
|
555
|
+
|
556
|
+
const UnoswapV2Controller_instance = await UnoswapV2Controller_factory.deploy(
|
557
|
+
rest.UniswapV2Factory_instance.address,
|
558
|
+
rest.UniswapV2Router02_instance.address,
|
559
|
+
PriceOracle_instance.address,
|
560
|
+
getInitCodeHash(UniswapV2Pair__factory.bytecode),
|
561
|
+
)
|
562
|
+
await UnoswapV2Controller_instance.deployed()
|
563
|
+
|
564
|
+
return {
|
565
|
+
deployer,
|
566
|
+
tokens,
|
567
|
+
PriceOracle_instance,
|
568
|
+
PriceOracle_factory,
|
569
|
+
UnoswapV2Controller_instance,
|
570
|
+
...rest,
|
571
|
+
}
|
572
|
+
}
|
573
|
+
|
574
|
+
export async function MockedAggregatorFixture() {
|
575
|
+
const { tokens, deployer, allTokenDeployments, ...rest } = await loadFixture(UniswapFixture)
|
576
|
+
|
577
|
+
await runDeployTag(hre, 'MockedAggregators')
|
578
|
+
|
579
|
+
const tokenFeeds: Array<AssetWithPriceFeed> = []
|
580
|
+
|
581
|
+
const MockedAggregator_wstETHstETH = await getInstanceOfDeployed<MockV3wstETHstETHAgg>(
|
582
|
+
hre,
|
583
|
+
'LidoRateOracle',
|
584
|
+
deployer,
|
585
|
+
)
|
586
|
+
|
587
|
+
await runDeployTag(hre, 'WstETHOracle')
|
588
|
+
const WstETHOracle = await getInstanceOfDeployed<WstETHOracle>(hre, 'WSTETHOracle', deployer)
|
589
|
+
|
590
|
+
const WETH_feed = await getTokenFeed(hre, 'WETH')
|
591
|
+
tokenFeeds.push(WETH_feed)
|
592
|
+
console.log('WETH_feed', WETH_feed)
|
593
|
+
|
594
|
+
if (hre.network.tags['arbitrum']) {
|
595
|
+
} else {
|
596
|
+
const stETH_feed = await getTokenFeed(hre, 'STETH')
|
597
|
+
tokenFeeds.push(stETH_feed)
|
598
|
+
console.log('stETH_feed', stETH_feed)
|
599
|
+
}
|
600
|
+
|
601
|
+
const WstETH_feed = await getTokenFeed(hre, 'WSTETH')
|
602
|
+
tokenFeeds.push(WstETH_feed)
|
603
|
+
console.log('WstETH_feed', WstETH_feed)
|
604
|
+
|
605
|
+
const DAI_feed = await getTokenFeed(hre, 'DAI')
|
606
|
+
tokenFeeds.push(DAI_feed)
|
607
|
+
|
608
|
+
const USDC_feed = await getTokenFeed(hre, 'USDC')
|
609
|
+
tokenFeeds.push(USDC_feed)
|
610
|
+
|
611
|
+
const USDT_feed = await getTokenFeed(hre, 'USDT')
|
612
|
+
tokenFeeds.push(USDT_feed)
|
613
|
+
|
614
|
+
const feedInstancesTokenToUSDT = {
|
615
|
+
WETH: await getInstanceOfDeployed<AggregatorV2V3Interface>(
|
616
|
+
hre,
|
617
|
+
mockedAggregatorName('WETH', hre.network),
|
618
|
+
),
|
619
|
+
DAI: await getInstanceOfDeployed<AggregatorV2V3Interface>(
|
620
|
+
hre,
|
621
|
+
mockedAggregatorName('DAI', hre.network),
|
622
|
+
),
|
623
|
+
USDC: await getInstanceOfDeployed<AggregatorV2V3Interface>(
|
624
|
+
hre,
|
625
|
+
mockedAggregatorName('USDC', hre.network),
|
626
|
+
),
|
627
|
+
USDT: await getInstanceOfDeployed<AggregatorV2V3Interface>(
|
628
|
+
hre,
|
629
|
+
mockedAggregatorName('USDT', hre.network),
|
630
|
+
),
|
631
|
+
stETH: hre.network.tags['arbitrum']
|
632
|
+
? null
|
633
|
+
: await getInstanceOfDeployed<AggregatorV2V3Interface>(
|
634
|
+
hre,
|
635
|
+
mockedAggregatorName('stETH', hre.network),
|
636
|
+
),
|
637
|
+
WstETH: WstETHOracle,
|
638
|
+
}
|
639
|
+
|
640
|
+
return {
|
641
|
+
feedInstancesTokenToUSDT,
|
642
|
+
MockedAggregator_wstETHstETH,
|
643
|
+
tokens,
|
644
|
+
tokenFeeds,
|
645
|
+
deployer,
|
646
|
+
...rest,
|
647
|
+
}
|
648
|
+
}
|
649
|
+
|
650
|
+
export async function UniswapFixture() {
|
651
|
+
const { deployer, ...rest } = await loadFixture(lidoFixture)
|
652
|
+
|
653
|
+
await runDeployTag(hre, 'UniV2Pairs')
|
654
|
+
|
655
|
+
const UniswapV2Factory_instance = await getInstanceOfDeployed<UniswapV2Factory>(
|
656
|
+
hre,
|
657
|
+
'UniswapV2Factory',
|
658
|
+
deployer,
|
659
|
+
)
|
660
|
+
|
661
|
+
const UniswapV2Router02_instance = await getInstanceOfDeployed<UniswapV2Router02>(
|
662
|
+
hre,
|
663
|
+
'UniswapV2Router02',
|
664
|
+
deployer,
|
665
|
+
)
|
666
|
+
|
667
|
+
return {
|
668
|
+
deployer,
|
669
|
+
UniswapV2Factory_instance,
|
670
|
+
UniswapV2Router02_instance,
|
671
|
+
...rest,
|
672
|
+
}
|
673
|
+
}
|
674
|
+
|
675
|
+
export async function lidoFixture() {
|
676
|
+
const { deployer, wallet, tokens, ...rest } = await loadFixture(tokensFixture)
|
677
|
+
|
678
|
+
const wsteth_instance = await getInstanceOfDeployed<WstETH>(hre, 'WSTETH', deployer)
|
679
|
+
|
680
|
+
const getWstETHstETHRate = async () => {
|
681
|
+
return await wsteth_instance.stEthPerToken()
|
682
|
+
}
|
683
|
+
|
684
|
+
if (isTestnet(hre.network)) {
|
685
|
+
const lido_deposit_contract_instance = await getInstanceOfDeployed<DepositContractMock>(
|
686
|
+
hre,
|
687
|
+
'DepositContractMock',
|
688
|
+
deployer,
|
689
|
+
)
|
690
|
+
const lido_registry_instance = await getInstanceOfDeployed<NodeOperatorsRegistry>(
|
691
|
+
hre,
|
692
|
+
'NodeOperatorsRegistry',
|
693
|
+
deployer,
|
694
|
+
)
|
695
|
+
|
696
|
+
const lido_instance = await getInstanceOfDeployed<Lido>(hre, 'STETH', deployer)
|
697
|
+
|
698
|
+
const testMint = await lido_instance.submit(ethers.constants.AddressZero, {
|
699
|
+
value: ethers.utils.parseEther('1000000'),
|
700
|
+
})
|
701
|
+
|
702
|
+
return {
|
703
|
+
deployer,
|
704
|
+
wallet,
|
705
|
+
tokens: {
|
706
|
+
...tokens,
|
707
|
+
WstETH: wsteth_instance,
|
708
|
+
stETH: lido_instance,
|
709
|
+
},
|
710
|
+
...rest,
|
711
|
+
getWstETHstETHRate,
|
712
|
+
lido_instance,
|
713
|
+
wsteth_instance,
|
714
|
+
lido_registry_instance,
|
715
|
+
lido_deposit_contract_instance,
|
716
|
+
}
|
717
|
+
}
|
718
|
+
return {
|
719
|
+
deployer,
|
720
|
+
wallet,
|
721
|
+
tokens: {
|
722
|
+
...tokens,
|
723
|
+
WstETH: wsteth_instance,
|
724
|
+
stETH: null,
|
725
|
+
},
|
726
|
+
...rest,
|
727
|
+
getWstETHstETHRate,
|
728
|
+
lido_instance: null,
|
729
|
+
wsteth_instance,
|
730
|
+
lido_registry_instance: null,
|
731
|
+
lido_deposit_contract_instance: null,
|
732
|
+
}
|
733
|
+
}
|
734
|
+
|
735
|
+
export async function tokensFixture() {
|
736
|
+
if (isTestnet(hre.network)) {
|
737
|
+
await runDeployTag(hre, 'Tokens')
|
738
|
+
} else {
|
739
|
+
switch (getNetworkType(hre.network)) {
|
740
|
+
case 'arbitrum':
|
741
|
+
await runDeployTag(hre, 'PrepareEnvARB')
|
742
|
+
break
|
743
|
+
}
|
744
|
+
}
|
745
|
+
|
746
|
+
const [deployer, alice, bob, carol, wallet] = await getSignersByNames(hre, [
|
747
|
+
'deployer',
|
748
|
+
'alice',
|
749
|
+
'bob',
|
750
|
+
'carol',
|
751
|
+
'david',
|
752
|
+
])
|
753
|
+
|
754
|
+
// deployer
|
755
|
+
|
756
|
+
const allTokenDeployments = await getTokenDeployments(hre)
|
757
|
+
|
758
|
+
const tokens = {
|
759
|
+
DAI: getInstanceFromDeployment<StableCoin>(hre, allTokenDeployments['DAI'], deployer),
|
760
|
+
USDC: getInstanceFromDeployment<StableCoin>(hre, allTokenDeployments['USDC'], deployer),
|
761
|
+
USDT: getInstanceFromDeployment<StableCoin>(hre, allTokenDeployments['USDT'], deployer),
|
762
|
+
WETH: getInstanceFromDeployment<WETH9>(hre, allTokenDeployments['WETH'], deployer),
|
763
|
+
}
|
764
|
+
|
765
|
+
const tokensAddresses = Object.values(tokens).map((token) => token.address)
|
766
|
+
|
767
|
+
return {
|
768
|
+
deployer,
|
769
|
+
alice,
|
770
|
+
bob,
|
771
|
+
carol,
|
772
|
+
wallet,
|
773
|
+
DAI: tokens.DAI,
|
774
|
+
USDC: tokens.USDC,
|
775
|
+
USDT: tokens.USDT,
|
776
|
+
WETH: tokens.WETH,
|
777
|
+
tokens,
|
778
|
+
tokensAddresses,
|
779
|
+
allTokenDeployments,
|
780
|
+
}
|
781
|
+
}
|
782
|
+
|
783
|
+
export { addLiquidityUniswapV3 }
|