@zoralabs/coins 0.9.0 → 1.0.0
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/.turbo/turbo-build.log +131 -114
- package/CHANGELOG.md +40 -0
- package/abis/BaseCoin.json +26 -118
- package/abis/BaseTest.json +47 -0
- package/abis/Coin.json +171 -63
- package/abis/CoinDopplerMultiCurve.json +38 -0
- package/abis/CoinRewardsV4.json +54 -0
- package/abis/CoinTest.json +53 -20
- package/abis/CoinUniV4Test.json +1053 -0
- package/abis/CoinV4.json +234 -211
- package/abis/DeployScript.json +47 -0
- package/abis/DeployedCoinVersionLookup.json +21 -0
- package/abis/DeployedCoinVersionLookupTest.json +716 -0
- package/abis/DifferentNamespaceVersionLookup.json +39 -0
- package/abis/DopplerUniswapV3Test.json +49 -93
- package/abis/ERC20.json +310 -0
- package/abis/FactoryTest.json +85 -7
- package/abis/FeeEstimatorHook.json +1528 -0
- package/abis/HooksDeployment.json +23 -0
- package/abis/HooksTest.json +47 -0
- package/abis/ICoin.json +40 -71
- package/abis/ICoinV3.json +879 -0
- package/abis/ICoinV4.json +915 -0
- package/abis/IDeployedCoinVersionLookup.json +21 -0
- package/abis/IERC721.json +36 -36
- package/abis/IHasPoolKey.json +42 -0
- package/abis/IHasRewardsRecipients.json +54 -0
- package/abis/IHasSwapPath.json +60 -0
- package/abis/IMsgSender.json +15 -0
- package/abis/IPoolConfigEncoding.json +46 -0
- package/abis/ISwapPathRouter.json +92 -0
- package/abis/IUniversalRouter.json +61 -0
- package/abis/IUnlockCallback.json +21 -0
- package/abis/IV4Quoter.json +310 -0
- package/abis/IZoraFactory.json +191 -11
- package/abis/IZoraV4CoinHook.json +348 -4
- package/abis/MockERC20.json +21 -0
- package/abis/MultiOwnableTest.json +47 -0
- package/abis/{CoinConfigurationVersions.json → Position.json} +1 -1
- package/abis/PrintUpgradeCommand.json +9 -0
- package/abis/ProxyShim.json +24 -0
- package/abis/StateLibrary.json +80 -0
- package/abis/TestDeployedCoinVersionLookupImplementation.json +39 -0
- package/abis/TestV4Swap.json +9 -0
- package/abis/UpgradeCoinImpl.json +47 -0
- package/abis/UpgradesTest.json +67 -0
- package/abis/Vm.json +1482 -111
- package/abis/VmSafe.json +856 -32
- package/abis/ZoraFactoryImpl.json +339 -1
- package/abis/ZoraV4CoinHook.json +455 -5
- package/addresses/8453.json +8 -4
- package/addresses/84532.json +8 -4
- package/dist/index.cjs +1920 -169
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1916 -169
- package/dist/index.js.map +1 -1
- package/dist/wagmiGenerated.d.ts +2599 -183
- package/dist/wagmiGenerated.d.ts.map +1 -1
- package/package/wagmiGenerated.ts +1928 -165
- package/package.json +8 -3
- package/remappings.txt +6 -1
- package/script/CoinsDeployerBase.sol +74 -11
- package/script/DeployDevFactory.s.sol +21 -0
- package/script/PrintUpgradeCommand.s.sol +13 -0
- package/script/Simulate.s.sol +1 -10
- package/script/TestBackingCoinSwap.s.sol +146 -0
- package/script/TestV4Swap.s.sol +136 -0
- package/script/UpgradeFactoryImpl.s.sol +1 -1
- package/src/BaseCoin.sol +176 -0
- package/src/Coin.sol +87 -202
- package/src/CoinV4.sol +121 -0
- package/src/ZoraFactoryImpl.sol +208 -36
- package/src/hooks/ZoraV4CoinHook.sol +195 -0
- package/src/hooks/{BaseCoinDeployHook.sol → deployment/BaseCoinDeployHook.sol} +3 -3
- package/src/hooks/{BuySupplyWithSwapRouterHook.sol → deployment/BuySupplyWithSwapRouterHook.sol} +7 -5
- package/src/interfaces/ICoin.sol +31 -39
- package/src/interfaces/ICoinV3.sol +71 -0
- package/src/interfaces/ICoinV4.sol +69 -0
- package/src/interfaces/IDeployedCoinVersionLookup.sol +11 -0
- package/src/interfaces/IMsgSender.sol +9 -0
- package/src/interfaces/IPoolConfigEncoding.sol +14 -0
- package/src/interfaces/ISwapPathRouter.sol +14 -0
- package/src/interfaces/IZoraFactory.sol +65 -27
- package/src/interfaces/IZoraV4CoinHook.sol +116 -0
- package/src/libs/CoinCommon.sol +15 -0
- package/src/libs/CoinConfigurationVersions.sol +116 -1
- package/src/libs/CoinConstants.sol +5 -0
- package/src/libs/CoinDopplerMultiCurve.sol +134 -0
- package/src/libs/CoinDopplerUniV3.sol +19 -171
- package/src/libs/CoinRewards.sol +195 -0
- package/src/libs/CoinRewardsV4.sol +180 -0
- package/src/libs/CoinSetup.sol +57 -0
- package/src/libs/CoinSetupV3.sol +6 -67
- package/src/libs/DopplerMath.sol +156 -0
- package/src/libs/HooksDeployment.sol +84 -0
- package/src/libs/MarketConstants.sol +4 -0
- package/src/libs/PoolStateReader.sol +22 -0
- package/src/libs/UniV3BuySell.sol +74 -292
- package/src/libs/UniV4SwapHelper.sol +65 -0
- package/src/libs/UniV4SwapToCurrency.sol +109 -0
- package/src/libs/V4Liquidity.sol +129 -0
- package/src/types/PoolConfiguration.sol +15 -0
- package/src/utils/DeployedCoinVersionLookup.sol +52 -0
- package/src/version/ContractVersionBase.sol +1 -1
- package/test/Coin.t.sol +78 -88
- package/test/CoinDopplerUniV3.t.sol +32 -171
- package/test/CoinUniV4.t.sol +752 -0
- package/test/{Hooks.t.sol → DeploymentHooks.t.sol} +2 -6
- package/test/Factory.t.sol +80 -47
- package/test/MultiOwnable.t.sol +6 -3
- package/test/Upgrades.t.sol +6 -5
- package/test/mocks/MockERC20.sol +12 -0
- package/test/utils/BaseTest.sol +106 -56
- package/test/utils/DeployedCoinVersionLookup.t.sol +127 -0
- package/test/utils/FeeEstimatorHook.sol +84 -0
- package/test/utils/ProxyShim.sol +17 -0
- package/wagmi.config.ts +4 -0
- package/.env +0 -1
- package/.turbo/turbo-update-contract-version.log +0 -22
- package/abis/CoinSetupV3.json +0 -7
- package/abis/HookDeployer.json +0 -68
- package/abis/IHookDeployer.json +0 -42
- package/src/libs/CoinLegacy.sol +0 -48
- package/src/libs/CoinLegacyMarket.sol +0 -182
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
pragma solidity ^0.8.13;
|
|
3
3
|
|
|
4
4
|
import {BaseTest} from "./utils/BaseTest.sol";
|
|
5
|
-
import {BuySupplyWithSwapRouterHook} from "../src/hooks/BuySupplyWithSwapRouterHook.sol";
|
|
5
|
+
import {BuySupplyWithSwapRouterHook} from "../src/hooks/deployment/BuySupplyWithSwapRouterHook.sol";
|
|
6
6
|
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
7
7
|
import {IUniswapV3Pool} from "../src/interfaces/IUniswapV3Pool.sol";
|
|
8
8
|
import {Coin} from "../src/Coin.sol";
|
|
9
9
|
import {CoinConfigurationVersions} from "../src/libs/CoinConfigurationVersions.sol";
|
|
10
10
|
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
|
|
11
11
|
import {ICoin} from "../src/interfaces/ICoin.sol";
|
|
12
|
-
import {IHasAfterCoinDeploy} from "../src/hooks/BaseCoinDeployHook.sol";
|
|
12
|
+
import {IHasAfterCoinDeploy} from "../src/hooks/deployment/BaseCoinDeployHook.sol";
|
|
13
13
|
import {IZoraFactory} from "../src/interfaces/IZoraFactory.sol";
|
|
14
14
|
import {ISwapRouter} from "../src/interfaces/ISwapRouter.sol";
|
|
15
15
|
import {CoinConstants} from "../src/libs/CoinConstants.sol";
|
|
@@ -22,10 +22,6 @@ contract FakeHookNoInterface {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
contract HooksTest is BaseTest {
|
|
25
|
-
int24 internal constant DEFAULT_DISCOVERY_TICK_LOWER = -777000;
|
|
26
|
-
int24 internal constant DEFAULT_DISCOVERY_TICK_UPPER = 222000;
|
|
27
|
-
uint16 internal constant DEFAULT_NUM_DISCOVERY_POSITIONS = 10; // will be 11 total with tail position
|
|
28
|
-
uint256 internal constant DEFAULT_DISCOVERY_SUPPLY_SHARE = 0.495e18; // half of the 990m total pool supply
|
|
29
25
|
address constant zora = 0x1111111111166b7FE7bd91427724B487980aFc69;
|
|
30
26
|
|
|
31
27
|
function _generateDefaultPoolConfig(address currency) internal pure returns (bytes memory) {
|
package/test/Factory.t.sol
CHANGED
|
@@ -10,8 +10,9 @@ contract FactoryTest is BaseTest {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
function test_constructor() public view {
|
|
13
|
-
assertEq(factory.coinImpl(), address(
|
|
14
|
-
assertEq(factory.owner(), users.factoryOwner);
|
|
13
|
+
assertEq(ZoraFactoryImpl(address(factory)).coinImpl(), address(coinV3Impl));
|
|
14
|
+
assertEq(ZoraFactoryImpl(address(factory)).owner(), users.factoryOwner);
|
|
15
|
+
assertEq(ZoraFactoryImpl(address(factory)).coinV4Impl(), address(coinV4Impl));
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
function test_deploy_no_eth() public {
|
|
@@ -24,9 +25,8 @@ contract FactoryTest is BaseTest {
|
|
|
24
25
|
"https://test2.com",
|
|
25
26
|
"Test2 Token",
|
|
26
27
|
"TEST2",
|
|
28
|
+
_generatePoolConfig(address(weth)),
|
|
27
29
|
users.platformReferrer,
|
|
28
|
-
address(weth),
|
|
29
|
-
MarketConstants.LP_TICK_LOWER_WETH,
|
|
30
30
|
0
|
|
31
31
|
);
|
|
32
32
|
coin = Coin(payable(coinAddress));
|
|
@@ -73,9 +73,8 @@ contract FactoryTest is BaseTest {
|
|
|
73
73
|
"https://test2.com",
|
|
74
74
|
"Test2 Token",
|
|
75
75
|
"TEST2",
|
|
76
|
+
_generatePoolConfig(address(weth)),
|
|
76
77
|
users.platformReferrer,
|
|
77
|
-
address(weth),
|
|
78
|
-
MarketConstants.LP_TICK_LOWER_WETH,
|
|
79
78
|
initialOrderSize
|
|
80
79
|
);
|
|
81
80
|
coin = Coin(payable(coinAddress));
|
|
@@ -119,9 +118,8 @@ contract FactoryTest is BaseTest {
|
|
|
119
118
|
"https://test2.com",
|
|
120
119
|
"Test2 Token",
|
|
121
120
|
"TEST2",
|
|
121
|
+
_generatePoolConfig(address(weth)),
|
|
122
122
|
users.platformReferrer,
|
|
123
|
-
address(weth),
|
|
124
|
-
MarketConstants.LP_TICK_LOWER_WETH,
|
|
125
123
|
initialOrderSize
|
|
126
124
|
);
|
|
127
125
|
}
|
|
@@ -139,9 +137,8 @@ contract FactoryTest is BaseTest {
|
|
|
139
137
|
"https://test2.com",
|
|
140
138
|
"Test2 Token",
|
|
141
139
|
"TEST2",
|
|
140
|
+
_generatePoolConfig(address(weth)),
|
|
142
141
|
users.platformReferrer,
|
|
143
|
-
address(weth),
|
|
144
|
-
MarketConstants.LP_TICK_LOWER_WETH,
|
|
145
142
|
orderSize
|
|
146
143
|
);
|
|
147
144
|
coin = Coin(payable(coinAddress));
|
|
@@ -160,9 +157,8 @@ contract FactoryTest is BaseTest {
|
|
|
160
157
|
"https://testcoinusdcpair.com",
|
|
161
158
|
"Testcoinusdcpair",
|
|
162
159
|
"TESTCOINUSDCPAIR",
|
|
160
|
+
_generatePoolConfig(USDC_ADDRESS),
|
|
163
161
|
users.platformReferrer,
|
|
164
|
-
USDC_ADDRESS,
|
|
165
|
-
USDC_TICK_LOWER,
|
|
166
162
|
0
|
|
167
163
|
);
|
|
168
164
|
coin = Coin(payable(coinAddress));
|
|
@@ -193,9 +189,8 @@ contract FactoryTest is BaseTest {
|
|
|
193
189
|
"https://testcoinusdcpair.com",
|
|
194
190
|
"Testcoinusdcpair",
|
|
195
191
|
"TESTCOINUSDCPAIR",
|
|
192
|
+
_generatePoolConfig(USDC_ADDRESS),
|
|
196
193
|
users.platformReferrer,
|
|
197
|
-
USDC_ADDRESS,
|
|
198
|
-
USDC_TICK_LOWER,
|
|
199
194
|
orderSize
|
|
200
195
|
);
|
|
201
196
|
coin = Coin(payable(coinAddress));
|
|
@@ -218,9 +213,8 @@ contract FactoryTest is BaseTest {
|
|
|
218
213
|
"https://testcoinusdcpair.com",
|
|
219
214
|
"Testcoinusdcpair",
|
|
220
215
|
"TESTCOINUSDCPAIR",
|
|
216
|
+
_generatePoolConfig(USDC_ADDRESS),
|
|
221
217
|
users.platformReferrer,
|
|
222
|
-
USDC_ADDRESS,
|
|
223
|
-
USDC_TICK_LOWER,
|
|
224
218
|
0
|
|
225
219
|
);
|
|
226
220
|
}
|
|
@@ -235,9 +229,8 @@ contract FactoryTest is BaseTest {
|
|
|
235
229
|
"https://testcoinusdcpair.com",
|
|
236
230
|
"Testcoinusdcpair",
|
|
237
231
|
"TESTCOINUSDCPAIR",
|
|
232
|
+
_generatePoolConfig(USDC_ADDRESS),
|
|
238
233
|
users.platformReferrer,
|
|
239
|
-
USDC_ADDRESS,
|
|
240
|
-
USDC_TICK_LOWER,
|
|
241
234
|
0
|
|
242
235
|
);
|
|
243
236
|
}
|
|
@@ -252,9 +245,8 @@ contract FactoryTest is BaseTest {
|
|
|
252
245
|
"https://testcoinusdcpair.com",
|
|
253
246
|
"Testcoinusdcpair",
|
|
254
247
|
"TESTCOINUSDCPAIR",
|
|
248
|
+
_generatePoolConfig(USDC_ADDRESS),
|
|
255
249
|
address(0),
|
|
256
|
-
USDC_ADDRESS,
|
|
257
|
-
USDC_TICK_LOWER,
|
|
258
250
|
0
|
|
259
251
|
);
|
|
260
252
|
|
|
@@ -263,24 +255,6 @@ contract FactoryTest is BaseTest {
|
|
|
263
255
|
assertEq(coin.platformReferrer(), coin.protocolRewardRecipient(), "platformReferrer");
|
|
264
256
|
}
|
|
265
257
|
|
|
266
|
-
function test_revert_deploy_with_invalid_currency_tick() public {
|
|
267
|
-
address[] memory owners = new address[](1);
|
|
268
|
-
owners[0] = users.creator;
|
|
269
|
-
|
|
270
|
-
vm.expectRevert(abi.encodeWithSelector(ICoin.InvalidWethLowerTick.selector));
|
|
271
|
-
factory.deploy(
|
|
272
|
-
users.creator,
|
|
273
|
-
owners,
|
|
274
|
-
"https://testcoin.com",
|
|
275
|
-
"Testcoin",
|
|
276
|
-
"TESTCOIN",
|
|
277
|
-
users.platformReferrer,
|
|
278
|
-
address(0),
|
|
279
|
-
MarketConstants.LP_TICK_LOWER_WETH + 1,
|
|
280
|
-
0
|
|
281
|
-
);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
258
|
function test_deploy_with_usdc_revert_invalid_eth_transfer() public {
|
|
285
259
|
address[] memory owners = new address[](1);
|
|
286
260
|
owners[0] = users.creator;
|
|
@@ -298,9 +272,8 @@ contract FactoryTest is BaseTest {
|
|
|
298
272
|
"https://testcoinusdcpair.com",
|
|
299
273
|
"Testcoinusdcpair",
|
|
300
274
|
"TESTCOINUSDCPAIR",
|
|
275
|
+
_generatePoolConfig(USDC_ADDRESS),
|
|
301
276
|
users.platformReferrer,
|
|
302
|
-
USDC_ADDRESS,
|
|
303
|
-
USDC_TICK_LOWER,
|
|
304
277
|
0
|
|
305
278
|
);
|
|
306
279
|
}
|
|
@@ -315,9 +288,8 @@ contract FactoryTest is BaseTest {
|
|
|
315
288
|
"https://test.com",
|
|
316
289
|
"Test Token",
|
|
317
290
|
"TEST",
|
|
291
|
+
_generatePoolConfig(address(weth)),
|
|
318
292
|
users.platformReferrer,
|
|
319
|
-
address(weth),
|
|
320
|
-
MarketConstants.LP_TICK_LOWER_WETH,
|
|
321
293
|
0
|
|
322
294
|
);
|
|
323
295
|
coin = Coin(payable(coinAddress));
|
|
@@ -326,10 +298,10 @@ contract FactoryTest is BaseTest {
|
|
|
326
298
|
}
|
|
327
299
|
|
|
328
300
|
function test_upgrade() public {
|
|
329
|
-
ZoraFactoryImpl newImpl = new ZoraFactoryImpl(address(
|
|
301
|
+
ZoraFactoryImpl newImpl = new ZoraFactoryImpl(address(coinV3Impl), address(coinV4Impl));
|
|
330
302
|
|
|
331
303
|
vm.prank(users.factoryOwner);
|
|
332
|
-
factory.upgradeToAndCall(address(newImpl), "");
|
|
304
|
+
ZoraFactoryImpl(address(factory)).upgradeToAndCall(address(newImpl), "");
|
|
333
305
|
|
|
334
306
|
assertEq(factory.implementation(), address(newImpl), "implementation");
|
|
335
307
|
}
|
|
@@ -343,14 +315,75 @@ contract FactoryTest is BaseTest {
|
|
|
343
315
|
|
|
344
316
|
vm.prank(users.factoryOwner);
|
|
345
317
|
vm.expectRevert(abi.encodeWithSelector(ERC1967Utils.ERC1967InvalidImplementation.selector, address(newImpl)));
|
|
346
|
-
factory.upgradeToAndCall(address(newImpl), "");
|
|
318
|
+
ZoraFactoryImpl(address(factory)).upgradeToAndCall(address(newImpl), "");
|
|
347
319
|
}
|
|
348
320
|
|
|
349
321
|
function test_revert_invalid_owner() public {
|
|
350
|
-
ZoraFactoryImpl newImpl = new ZoraFactoryImpl(address(
|
|
322
|
+
ZoraFactoryImpl newImpl = new ZoraFactoryImpl(address(coinV3Impl), address(coinV4Impl));
|
|
351
323
|
|
|
352
324
|
vm.prank(users.creator);
|
|
353
325
|
vm.expectRevert(abi.encodeWithSelector(OwnableUpgradeable.OwnableUnauthorizedAccount.selector, users.creator));
|
|
354
|
-
factory.upgradeToAndCall(address(newImpl), "");
|
|
326
|
+
ZoraFactoryImpl(address(factory)).upgradeToAndCall(address(newImpl), "");
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function test_coinAddress_canBePredicted(
|
|
330
|
+
bool msgSenderChanged,
|
|
331
|
+
bool saltChanged,
|
|
332
|
+
bool poolConfigChanged,
|
|
333
|
+
bool platformReferrerChanged,
|
|
334
|
+
bool nameChanged,
|
|
335
|
+
bool symbolChanged
|
|
336
|
+
) public {
|
|
337
|
+
address[] memory owners = new address[](1);
|
|
338
|
+
owners[0] = users.creator;
|
|
339
|
+
|
|
340
|
+
address payoutRecipient = users.creator;
|
|
341
|
+
|
|
342
|
+
bytes32 salt = keccak256(abi.encode(bytes("randomSalt")));
|
|
343
|
+
|
|
344
|
+
address msgSender = makeAddr("msgSender");
|
|
345
|
+
|
|
346
|
+
string memory uri = "https://test.com";
|
|
347
|
+
string memory name = "Testcoin";
|
|
348
|
+
string memory symbol = "TEST";
|
|
349
|
+
|
|
350
|
+
address platformReferrer = users.platformReferrer;
|
|
351
|
+
|
|
352
|
+
bytes memory poolConfig = CoinConfigurationVersions.defaultDopplerMultiCurveUniV4(address(weth));
|
|
353
|
+
bytes memory poolConfigForGettingAddress = poolConfigChanged ? CoinConfigurationVersions.defaultDopplerUniV3(address(weth)) : poolConfig;
|
|
354
|
+
|
|
355
|
+
address expectedCoinAddress = factory.coinAddress(msgSender, name, symbol, poolConfigForGettingAddress, platformReferrer, salt);
|
|
356
|
+
|
|
357
|
+
if (msgSenderChanged) {
|
|
358
|
+
msgSender = makeAddr("msgSender2");
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (saltChanged) {
|
|
362
|
+
salt = keccak256(abi.encode(bytes("randomSalt2")));
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (platformReferrerChanged) {
|
|
366
|
+
platformReferrer = makeAddr("platformReferrer2");
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (nameChanged) {
|
|
370
|
+
name = "Testcoin2";
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
if (symbolChanged) {
|
|
374
|
+
symbol = "TEST2";
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// now deploy the coin
|
|
378
|
+
vm.prank(msgSender);
|
|
379
|
+
(address coinAddress, ) = factory.deploy(payoutRecipient, owners, uri, name, symbol, poolConfig, platformReferrer, address(0), bytes(""), salt);
|
|
380
|
+
|
|
381
|
+
bool addressShouldMismatch = msgSenderChanged || saltChanged || poolConfigChanged || platformReferrerChanged || nameChanged || symbolChanged;
|
|
382
|
+
|
|
383
|
+
if (addressShouldMismatch) {
|
|
384
|
+
assertNotEq(coinAddress, expectedCoinAddress, "coinAddress should mismatch");
|
|
385
|
+
} else {
|
|
386
|
+
assertEq(coinAddress, expectedCoinAddress, "coinAddress should match");
|
|
387
|
+
}
|
|
355
388
|
}
|
|
356
389
|
}
|
package/test/MultiOwnable.t.sol
CHANGED
|
@@ -135,22 +135,25 @@ contract MultiOwnableTest is BaseTest {
|
|
|
135
135
|
|
|
136
136
|
function test_revert_init_with_zero_owners() public {
|
|
137
137
|
address[] memory emptyOwners = new address[](0);
|
|
138
|
+
bytes memory poolConfig_ = _generatePoolConfig(address(weth));
|
|
138
139
|
vm.expectRevert(MultiOwnable.OneOwnerRequired.selector);
|
|
139
|
-
factory.deploy(users.creator, emptyOwners, "https://test.com", "Test Token", "TEST", users.platformReferrer,
|
|
140
|
+
factory.deploy(users.creator, emptyOwners, "https://test.com", "Test Token", "TEST", poolConfig_, users.platformReferrer, 0);
|
|
140
141
|
}
|
|
141
142
|
|
|
142
143
|
function test_revert_init_with_zero_address() public {
|
|
143
144
|
address[] memory owners = new address[](1);
|
|
144
145
|
owners[0] = address(0);
|
|
146
|
+
bytes memory poolConfig_ = _generatePoolConfig(address(weth));
|
|
145
147
|
vm.expectRevert(MultiOwnable.OwnerCannotBeAddressZero.selector);
|
|
146
|
-
factory.deploy(users.creator, owners, "https://test.com", "Test Token", "TEST", users.platformReferrer,
|
|
148
|
+
factory.deploy(users.creator, owners, "https://test.com", "Test Token", "TEST", poolConfig_, users.platformReferrer, 0);
|
|
147
149
|
}
|
|
148
150
|
|
|
149
151
|
function test_revert_init_with_duplicate_owner() public {
|
|
150
152
|
address[] memory owners = new address[](2);
|
|
151
153
|
owners[0] = users.creator;
|
|
152
154
|
owners[1] = users.creator;
|
|
155
|
+
bytes memory poolConfig_ = _generatePoolConfig(address(weth));
|
|
153
156
|
vm.expectRevert(MultiOwnable.AlreadyOwner.selector);
|
|
154
|
-
factory.deploy(users.creator, owners, "https://test.com", "Test Token", "TEST", users.platformReferrer,
|
|
157
|
+
factory.deploy(users.creator, owners, "https://test.com", "Test Token", "TEST", poolConfig_, users.platformReferrer, 0);
|
|
155
158
|
}
|
|
156
159
|
}
|
package/test/Upgrades.t.sol
CHANGED
|
@@ -3,6 +3,7 @@ pragma solidity ^0.8.13;
|
|
|
3
3
|
import {Test} from "forge-std/Test.sol";
|
|
4
4
|
import {IZoraFactory} from "../src/interfaces/IZoraFactory.sol";
|
|
5
5
|
import {ZoraFactoryImpl} from "../src/ZoraFactoryImpl.sol";
|
|
6
|
+
import {BaseTest} from "./utils/BaseTest.sol";
|
|
6
7
|
|
|
7
8
|
contract BadImpl {
|
|
8
9
|
function contractName() public pure returns (string memory) {
|
|
@@ -10,7 +11,7 @@ contract BadImpl {
|
|
|
10
11
|
}
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
contract UpgradesTest is
|
|
14
|
+
contract UpgradesTest is BaseTest {
|
|
14
15
|
ZoraFactoryImpl public factoryProxy;
|
|
15
16
|
|
|
16
17
|
function test_canUpgradeFromVersionWithoutContractName() public {
|
|
@@ -19,7 +20,7 @@ contract UpgradesTest is Test {
|
|
|
19
20
|
|
|
20
21
|
factoryProxy = ZoraFactoryImpl(0x777777751622c0d3258f214F9DF38E35BF45baF3);
|
|
21
22
|
|
|
22
|
-
ZoraFactoryImpl newImpl = new ZoraFactoryImpl(factoryProxy.
|
|
23
|
+
ZoraFactoryImpl newImpl = new ZoraFactoryImpl(factoryProxy.coinImpl(), address(coinV4Impl));
|
|
23
24
|
|
|
24
25
|
vm.prank(factoryProxy.owner());
|
|
25
26
|
factoryProxy.upgradeToAndCall(address(newImpl), "");
|
|
@@ -34,7 +35,7 @@ contract UpgradesTest is Test {
|
|
|
34
35
|
|
|
35
36
|
factoryProxy = ZoraFactoryImpl(0x777777751622c0d3258f214F9DF38E35BF45baF3);
|
|
36
37
|
|
|
37
|
-
ZoraFactoryImpl newImpl = new ZoraFactoryImpl(factoryProxy.
|
|
38
|
+
ZoraFactoryImpl newImpl = new ZoraFactoryImpl(factoryProxy.coinImpl(), address(coinV4Impl));
|
|
38
39
|
|
|
39
40
|
vm.prank(factoryProxy.owner());
|
|
40
41
|
factoryProxy.upgradeToAndCall(address(newImpl), "");
|
|
@@ -52,12 +53,12 @@ contract UpgradesTest is Test {
|
|
|
52
53
|
|
|
53
54
|
factoryProxy = ZoraFactoryImpl(0x777777751622c0d3258f214F9DF38E35BF45baF3);
|
|
54
55
|
|
|
55
|
-
ZoraFactoryImpl newImpl = new ZoraFactoryImpl(factoryProxy.
|
|
56
|
+
ZoraFactoryImpl newImpl = new ZoraFactoryImpl(factoryProxy.coinImpl(), address(coinV4Impl));
|
|
56
57
|
|
|
57
58
|
vm.prank(factoryProxy.owner());
|
|
58
59
|
factoryProxy.upgradeToAndCall(address(newImpl), "");
|
|
59
60
|
|
|
60
|
-
ZoraFactoryImpl newImpl2 = new ZoraFactoryImpl(factoryProxy.
|
|
61
|
+
ZoraFactoryImpl newImpl2 = new ZoraFactoryImpl(factoryProxy.coinImpl(), factoryProxy.coinV4Impl());
|
|
61
62
|
|
|
62
63
|
vm.prank(factoryProxy.owner());
|
|
63
64
|
factoryProxy.upgradeToAndCall(address(newImpl2), "");
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.23;
|
|
3
|
+
|
|
4
|
+
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
|
5
|
+
|
|
6
|
+
contract MockERC20 is ERC20 {
|
|
7
|
+
constructor(string memory name, string memory symbol) ERC20(name, symbol) {}
|
|
8
|
+
|
|
9
|
+
function mint(address to, uint256 amount) external {
|
|
10
|
+
_mint(to, amount);
|
|
11
|
+
}
|
|
12
|
+
}
|
package/test/utils/BaseTest.sol
CHANGED
|
@@ -8,10 +8,12 @@ import {Address} from "@openzeppelin/contracts/utils/Address.sol";
|
|
|
8
8
|
import {ERC1967Utils} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";
|
|
9
9
|
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
|
|
10
10
|
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
|
|
11
|
-
|
|
11
|
+
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
|
12
|
+
import {IZoraFactory} from "../../src/interfaces/IZoraFactory.sol";
|
|
12
13
|
import {ZoraFactoryImpl} from "../../src/ZoraFactoryImpl.sol";
|
|
13
14
|
import {ZoraFactory} from "../../src/proxy/ZoraFactory.sol";
|
|
14
15
|
import {Coin} from "../../src/Coin.sol";
|
|
16
|
+
import {CoinV4} from "../../src/CoinV4.sol";
|
|
15
17
|
import {MultiOwnable} from "../../src/utils/MultiOwnable.sol";
|
|
16
18
|
import {ICoin} from "../../src/interfaces/ICoin.sol";
|
|
17
19
|
import {IERC7572} from "../../src/interfaces/IERC7572.sol";
|
|
@@ -24,6 +26,12 @@ import {IUniswapV3Pool} from "../../src/interfaces/IUniswapV3Pool.sol";
|
|
|
24
26
|
import {IProtocolRewards} from "../../src/interfaces/IProtocolRewards.sol";
|
|
25
27
|
import {ProtocolRewards} from "../utils/ProtocolRewards.sol";
|
|
26
28
|
import {MarketConstants} from "../../src/libs/MarketConstants.sol";
|
|
29
|
+
import {CoinConfigurationVersions} from "../../src/libs/CoinConfigurationVersions.sol";
|
|
30
|
+
import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
|
|
31
|
+
import {ZoraV4CoinHook} from "../../src/hooks/ZoraV4CoinHook.sol";
|
|
32
|
+
import {HooksDeployment} from "../../src/libs/HooksDeployment.sol";
|
|
33
|
+
import {CoinConstants} from "../../src/libs/CoinConstants.sol";
|
|
34
|
+
import {ProxyShim} from "./ProxyShim.sol";
|
|
27
35
|
|
|
28
36
|
contract BaseTest is Test {
|
|
29
37
|
using stdStorage for StdStorage;
|
|
@@ -35,6 +43,11 @@ contract BaseTest is Test {
|
|
|
35
43
|
address internal constant SWAP_ROUTER = 0x2626664c2603336E57B271c5C0b26F421741e481;
|
|
36
44
|
address internal constant DOPPLER_AIRLOCK = 0x660eAaEdEBc968f8f3694354FA8EC0b4c5Ba8D12;
|
|
37
45
|
address internal constant USDC_ADDRESS = 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913;
|
|
46
|
+
address internal constant V4_POOL_MANAGER = 0x498581fF718922c3f8e6A244956aF099B2652b2b;
|
|
47
|
+
address internal constant V4_POSITION_MANAGER = 0x7C5f5A4bBd8fD63184577525326123B519429bDc;
|
|
48
|
+
address internal constant V4_PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;
|
|
49
|
+
address internal constant V4_QUOTER = 0x0d5e0F971ED27FBfF6c2837bf31316121532048D;
|
|
50
|
+
address internal constant UNIVERSAL_ROUTER = 0x6fF5693b99212Da76ad316178A184AB56D299b43;
|
|
38
51
|
int24 internal constant USDC_TICK_LOWER = 57200;
|
|
39
52
|
|
|
40
53
|
struct Users {
|
|
@@ -54,15 +67,79 @@ contract BaseTest is Test {
|
|
|
54
67
|
ProtocolRewards internal protocolRewards;
|
|
55
68
|
IUniswapV3Factory internal v3Factory;
|
|
56
69
|
INonfungiblePositionManager internal nonfungiblePositionManager;
|
|
70
|
+
|
|
57
71
|
ISwapRouter internal swapRouter;
|
|
58
72
|
IAirlock internal airlock;
|
|
59
73
|
Users internal users;
|
|
60
74
|
|
|
61
|
-
Coin internal
|
|
75
|
+
Coin internal coinV3Impl;
|
|
76
|
+
CoinV4 internal coinV4Impl;
|
|
62
77
|
ZoraFactoryImpl internal factoryImpl;
|
|
63
|
-
|
|
78
|
+
IZoraFactory internal factory;
|
|
79
|
+
ZoraV4CoinHook internal zoraV4CoinHook;
|
|
64
80
|
Coin internal coin;
|
|
81
|
+
|
|
65
82
|
IUniswapV3Pool internal pool;
|
|
83
|
+
int24 internal constant DEFAULT_DISCOVERY_TICK_LOWER = CoinConstants.DEFAULT_DISCOVERY_TICK_LOWER;
|
|
84
|
+
int24 internal constant DEFAULT_DISCOVERY_TICK_UPPER = CoinConstants.DEFAULT_DISCOVERY_TICK_UPPER;
|
|
85
|
+
uint16 internal constant DEFAULT_NUM_DISCOVERY_POSITIONS = CoinConstants.DEFAULT_NUM_DISCOVERY_POSITIONS;
|
|
86
|
+
uint256 internal constant DEFAULT_DISCOVERY_SUPPLY_SHARE = CoinConstants.DEFAULT_DISCOVERY_SUPPLY_SHARE;
|
|
87
|
+
|
|
88
|
+
function _deployCoin() internal {
|
|
89
|
+
bytes memory poolConfig_ = _generatePoolConfig(
|
|
90
|
+
CoinConfigurationVersions.DOPPLER_UNI_V3_POOL_VERSION,
|
|
91
|
+
address(weth),
|
|
92
|
+
DEFAULT_DISCOVERY_TICK_LOWER,
|
|
93
|
+
DEFAULT_DISCOVERY_TICK_UPPER,
|
|
94
|
+
DEFAULT_NUM_DISCOVERY_POSITIONS,
|
|
95
|
+
DEFAULT_DISCOVERY_SUPPLY_SHARE
|
|
96
|
+
);
|
|
97
|
+
vm.prank(users.creator);
|
|
98
|
+
(address coinAddress, ) = factory.deploy(
|
|
99
|
+
users.creator,
|
|
100
|
+
_getDefaultOwners(),
|
|
101
|
+
"https://test.com",
|
|
102
|
+
"Testcoin",
|
|
103
|
+
"TEST",
|
|
104
|
+
poolConfig_,
|
|
105
|
+
users.platformReferrer,
|
|
106
|
+
0
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
coin = Coin(payable(coinAddress));
|
|
110
|
+
pool = IUniswapV3Pool(coin.poolAddress());
|
|
111
|
+
|
|
112
|
+
vm.label(address(coin), "COIN");
|
|
113
|
+
vm.label(address(pool), "POOL");
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function _deployCoinUSDCPair() internal {
|
|
117
|
+
bytes memory poolConfig_ = _generatePoolConfig(
|
|
118
|
+
CoinConfigurationVersions.DOPPLER_UNI_V3_POOL_VERSION,
|
|
119
|
+
USDC_ADDRESS,
|
|
120
|
+
DEFAULT_DISCOVERY_TICK_LOWER,
|
|
121
|
+
DEFAULT_DISCOVERY_TICK_UPPER,
|
|
122
|
+
DEFAULT_NUM_DISCOVERY_POSITIONS,
|
|
123
|
+
DEFAULT_DISCOVERY_SUPPLY_SHARE
|
|
124
|
+
);
|
|
125
|
+
vm.prank(users.creator);
|
|
126
|
+
(address coinAddress, ) = factory.deploy(
|
|
127
|
+
users.creator,
|
|
128
|
+
_getDefaultOwners(),
|
|
129
|
+
"https://test.com",
|
|
130
|
+
"Testcoin",
|
|
131
|
+
"TEST",
|
|
132
|
+
poolConfig_,
|
|
133
|
+
users.platformReferrer,
|
|
134
|
+
0
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
coin = Coin(payable(coinAddress));
|
|
138
|
+
pool = IUniswapV3Pool(coin.poolAddress());
|
|
139
|
+
|
|
140
|
+
vm.label(address(coin), "COIN");
|
|
141
|
+
vm.label(address(pool), "POOL");
|
|
142
|
+
}
|
|
66
143
|
|
|
67
144
|
function setUp() public virtual {
|
|
68
145
|
setUpWithBlockNumber(28415528);
|
|
@@ -78,7 +155,6 @@ contract BaseTest is Test {
|
|
|
78
155
|
swapRouter = ISwapRouter(SWAP_ROUTER);
|
|
79
156
|
airlock = IAirlock(DOPPLER_AIRLOCK);
|
|
80
157
|
protocolRewards = new ProtocolRewards();
|
|
81
|
-
|
|
82
158
|
users = Users({
|
|
83
159
|
factoryOwner: makeAddr("factoryOwner"),
|
|
84
160
|
feeRecipient: makeAddr("feeRecipient"),
|
|
@@ -90,11 +166,21 @@ contract BaseTest is Test {
|
|
|
90
166
|
tradeReferrer: makeAddr("tradeReferrer")
|
|
91
167
|
});
|
|
92
168
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
169
|
+
address[] memory trustedMessageSenders = new address[](2);
|
|
170
|
+
trustedMessageSenders[0] = UNIVERSAL_ROUTER;
|
|
171
|
+
trustedMessageSenders[1] = V4_POSITION_MANAGER;
|
|
96
172
|
|
|
97
|
-
|
|
173
|
+
ProxyShim mockUpgradeableImpl = new ProxyShim();
|
|
174
|
+
factory = IZoraFactory(address(new ZoraFactory(address(mockUpgradeableImpl))));
|
|
175
|
+
zoraV4CoinHook = ZoraV4CoinHook(address(HooksDeployment.deployZoraV4CoinHookFromContract(V4_POOL_MANAGER, address(factory), trustedMessageSenders)));
|
|
176
|
+
coinV3Impl = new Coin(users.feeRecipient, address(protocolRewards), WETH_ADDRESS, V3_FACTORY, SWAP_ROUTER, DOPPLER_AIRLOCK);
|
|
177
|
+
coinV4Impl = new CoinV4(users.feeRecipient, address(protocolRewards), IPoolManager(V4_POOL_MANAGER), DOPPLER_AIRLOCK, zoraV4CoinHook);
|
|
178
|
+
factoryImpl = new ZoraFactoryImpl(address(coinV3Impl), address(coinV4Impl));
|
|
179
|
+
UUPSUpgradeable(address(factory)).upgradeToAndCall(address(factoryImpl), "");
|
|
180
|
+
factory = IZoraFactory(address(factory));
|
|
181
|
+
// factory = ZoraFactoryImpl(address(new ZoraFactory(address(factoryImpl))));
|
|
182
|
+
|
|
183
|
+
ZoraFactoryImpl(address(factory)).initialize(users.factoryOwner);
|
|
98
184
|
|
|
99
185
|
vm.label(address(factory), "ZORA_FACTORY");
|
|
100
186
|
vm.label(address(protocolRewards), "PROTOCOL_REWARDS");
|
|
@@ -120,54 +206,6 @@ contract BaseTest is Test {
|
|
|
120
206
|
uint256 protocol;
|
|
121
207
|
}
|
|
122
208
|
|
|
123
|
-
function _deployCoin() internal {
|
|
124
|
-
address[] memory owners = new address[](1);
|
|
125
|
-
owners[0] = users.creator;
|
|
126
|
-
|
|
127
|
-
vm.prank(users.creator);
|
|
128
|
-
(address coinAddress, ) = factory.deploy(
|
|
129
|
-
users.creator,
|
|
130
|
-
owners,
|
|
131
|
-
"https://test.com",
|
|
132
|
-
"Testcoin",
|
|
133
|
-
"TEST",
|
|
134
|
-
users.platformReferrer,
|
|
135
|
-
address(weth),
|
|
136
|
-
MarketConstants.LP_TICK_LOWER_WETH,
|
|
137
|
-
0
|
|
138
|
-
);
|
|
139
|
-
|
|
140
|
-
coin = Coin(payable(coinAddress));
|
|
141
|
-
pool = IUniswapV3Pool(coin.poolAddress());
|
|
142
|
-
|
|
143
|
-
vm.label(address(coin), "COIN");
|
|
144
|
-
vm.label(address(pool), "POOL");
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function _deployCoinUSDCPair() internal {
|
|
148
|
-
address[] memory owners = new address[](1);
|
|
149
|
-
owners[0] = users.creator;
|
|
150
|
-
|
|
151
|
-
vm.prank(users.creator);
|
|
152
|
-
(address coinAddress, ) = factory.deploy(
|
|
153
|
-
users.creator,
|
|
154
|
-
owners,
|
|
155
|
-
"https://testusdccoin.com",
|
|
156
|
-
"Testusdccoin",
|
|
157
|
-
"TESTUSDCCOIN",
|
|
158
|
-
users.platformReferrer,
|
|
159
|
-
USDC_ADDRESS,
|
|
160
|
-
USDC_TICK_LOWER,
|
|
161
|
-
0
|
|
162
|
-
);
|
|
163
|
-
|
|
164
|
-
coin = Coin(payable(coinAddress));
|
|
165
|
-
pool = IUniswapV3Pool(coin.poolAddress());
|
|
166
|
-
|
|
167
|
-
vm.label(address(coin), "COIN");
|
|
168
|
-
vm.label(address(pool), "POOL");
|
|
169
|
-
}
|
|
170
|
-
|
|
171
209
|
function _calculateTradeRewards(uint256 ethAmount) internal pure returns (TradeRewards memory) {
|
|
172
210
|
return
|
|
173
211
|
TradeRewards({
|
|
@@ -207,6 +245,18 @@ contract BaseTest is Test {
|
|
|
207
245
|
return airlock.owner();
|
|
208
246
|
}
|
|
209
247
|
|
|
248
|
+
function _generatePoolConfig(address currency_) internal pure returns (bytes memory) {
|
|
249
|
+
return
|
|
250
|
+
_generatePoolConfig(
|
|
251
|
+
CoinConfigurationVersions.DOPPLER_UNI_V3_POOL_VERSION,
|
|
252
|
+
currency_,
|
|
253
|
+
DEFAULT_DISCOVERY_TICK_LOWER,
|
|
254
|
+
DEFAULT_DISCOVERY_TICK_UPPER,
|
|
255
|
+
DEFAULT_NUM_DISCOVERY_POSITIONS,
|
|
256
|
+
DEFAULT_DISCOVERY_SUPPLY_SHARE
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
|
|
210
260
|
function _generatePoolConfig(
|
|
211
261
|
uint8 version_,
|
|
212
262
|
address currency_,
|