@zoralabs/coins 0.6.1 → 0.7.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.
Files changed (66) hide show
  1. package/.turbo/turbo-build.log +69 -55
  2. package/CHANGELOG.md +12 -0
  3. package/abis/BaseTest.json +0 -23
  4. package/abis/Coin.json +186 -77
  5. package/abis/CoinConfigurationVersions.json +7 -0
  6. package/abis/CoinSetup.json +7 -0
  7. package/abis/CoinTest.json +5 -49
  8. package/abis/CustomRevert.json +28 -0
  9. package/abis/DopplerUniswapV3Test.json +891 -0
  10. package/abis/FactoryTest.json +7 -23
  11. package/abis/IAirlock.json +15 -0
  12. package/abis/ICoin.json +52 -34
  13. package/abis/IDopplerErrors.json +44 -0
  14. package/abis/INonfungiblePositionManager.json +13 -0
  15. package/abis/IUniswapV3Factory.json +198 -0
  16. package/abis/IUniswapV3Pool.json +135 -0
  17. package/abis/MultiOwnableTest.json +0 -23
  18. package/abis/SafeCast.json +7 -0
  19. package/abis/Simulate.json +120 -0
  20. package/abis/SqrtPriceMath.json +22 -0
  21. package/abis/TickMath.json +24 -0
  22. package/abis/ZoraFactoryImpl.json +59 -0
  23. package/addresses/8453.json +3 -3
  24. package/dist/index.cjs +160 -39
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.js +160 -39
  27. package/dist/index.js.map +1 -1
  28. package/dist/wagmiGenerated.d.ts +349 -67
  29. package/dist/wagmiGenerated.d.ts.map +1 -1
  30. package/package/wagmiGenerated.ts +161 -40
  31. package/package.json +3 -3
  32. package/script/CoinsDeployerBase.sol +1 -1
  33. package/script/Simulate.s.sol +67 -0
  34. package/src/Coin.sol +159 -90
  35. package/src/ZoraFactoryImpl.sol +47 -1
  36. package/src/interfaces/IAirlock.sol +6 -0
  37. package/src/interfaces/ICoin.sol +18 -2
  38. package/src/interfaces/IDopplerErrors.sol +14 -0
  39. package/src/interfaces/INonfungiblePositionManager.sol +2 -0
  40. package/src/interfaces/IUniswapV3Factory.sol +64 -0
  41. package/src/interfaces/IUniswapV3Pool.sol +48 -0
  42. package/src/libs/CoinConfigurationVersions.sol +9 -0
  43. package/src/libs/CoinDopplerUniV3.sol +202 -0
  44. package/src/libs/CoinLegacy.sol +48 -0
  45. package/src/libs/CoinSetup.sol +37 -0
  46. package/src/libs/MarketConstants.sol +25 -0
  47. package/src/types/LpPosition.sol +8 -0
  48. package/src/types/PoolState.sol +24 -0
  49. package/src/utils/CoinConstants.sol +5 -12
  50. package/src/utils/uniswap/BitMath.sol +55 -0
  51. package/src/utils/uniswap/CustomRevert.sol +111 -0
  52. package/src/utils/uniswap/FixedPoint96.sol +11 -0
  53. package/src/utils/uniswap/FullMath.sol +118 -0
  54. package/src/utils/uniswap/LiquidityAmounts.sol +117 -0
  55. package/src/utils/uniswap/SafeCast.sol +61 -0
  56. package/src/utils/uniswap/SqrtPriceMath.sol +249 -0
  57. package/src/utils/uniswap/TickMath.sol +244 -0
  58. package/src/utils/uniswap/UnsafeMath.sol +30 -0
  59. package/src/version/ContractVersionBase.sol +1 -1
  60. package/test/Coin.t.sol +65 -65
  61. package/test/CoinDopplerUniV3.t.sol +452 -0
  62. package/test/Factory.t.sol +49 -7
  63. package/test/utils/BaseTest.sol +26 -7
  64. package/wagmi.config.ts +1 -1
  65. package/abis/IERC721Receiver.json +0 -36
  66. package/src/utils/TickMath.sol +0 -210
@@ -13,12 +13,9 @@ export const coinABI = [
13
13
  },
14
14
  { name: '_protocolRewards', internalType: 'address', type: 'address' },
15
15
  { name: '_weth', internalType: 'address', type: 'address' },
16
- {
17
- name: '_nonfungiblePositionManager',
18
- internalType: 'address',
19
- type: 'address',
20
- },
16
+ { name: '_v3Factory', internalType: 'address', type: 'address' },
21
17
  { name: '_swapRouter', internalType: 'address', type: 'address' },
18
+ { name: '_airlock', internalType: 'address', type: 'address' },
22
19
  ],
23
20
  stateMutability: 'nonpayable',
24
21
  },
@@ -102,6 +99,13 @@ export const coinABI = [
102
99
  outputs: [],
103
100
  stateMutability: 'nonpayable',
104
101
  },
102
+ {
103
+ type: 'function',
104
+ inputs: [],
105
+ name: 'airlock',
106
+ outputs: [{ name: '', internalType: 'address', type: 'address' }],
107
+ stateMutability: 'view',
108
+ },
105
109
  {
106
110
  type: 'function',
107
111
  inputs: [
@@ -210,9 +214,8 @@ export const coinABI = [
210
214
  { name: 'tokenURI_', internalType: 'string', type: 'string' },
211
215
  { name: 'name_', internalType: 'string', type: 'string' },
212
216
  { name: 'symbol_', internalType: 'string', type: 'string' },
217
+ { name: 'poolConfig_', internalType: 'bytes', type: 'bytes' },
213
218
  { name: 'platformReferrer_', internalType: 'address', type: 'address' },
214
- { name: 'currency_', internalType: 'address', type: 'address' },
215
- { name: 'tickLower_', internalType: 'int24', type: 'int24' },
216
219
  ],
217
220
  name: 'initialize',
218
221
  outputs: [],
@@ -225,13 +228,6 @@ export const coinABI = [
225
228
  outputs: [{ name: '', internalType: 'bool', type: 'bool' }],
226
229
  stateMutability: 'view',
227
230
  },
228
- {
229
- type: 'function',
230
- inputs: [],
231
- name: 'lpTokenId',
232
- outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],
233
- stateMutability: 'view',
234
- },
235
231
  {
236
232
  type: 'function',
237
233
  inputs: [],
@@ -246,25 +242,6 @@ export const coinABI = [
246
242
  outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],
247
243
  stateMutability: 'view',
248
244
  },
249
- {
250
- type: 'function',
251
- inputs: [],
252
- name: 'nonfungiblePositionManager',
253
- outputs: [{ name: '', internalType: 'address', type: 'address' }],
254
- stateMutability: 'view',
255
- },
256
- {
257
- type: 'function',
258
- inputs: [
259
- { name: '', internalType: 'address', type: 'address' },
260
- { name: '', internalType: 'address', type: 'address' },
261
- { name: '', internalType: 'uint256', type: 'uint256' },
262
- { name: '', internalType: 'bytes', type: 'bytes' },
263
- ],
264
- name: 'onERC721Received',
265
- outputs: [{ name: '', internalType: 'bytes4', type: 'bytes4' }],
266
- stateMutability: 'view',
267
- },
268
245
  {
269
246
  type: 'function',
270
247
  inputs: [],
@@ -308,6 +285,44 @@ export const coinABI = [
308
285
  outputs: [{ name: '', internalType: 'address', type: 'address' }],
309
286
  stateMutability: 'view',
310
287
  },
288
+ {
289
+ type: 'function',
290
+ inputs: [],
291
+ name: 'poolConfiguration',
292
+ outputs: [
293
+ { name: 'version', internalType: 'uint8', type: 'uint8' },
294
+ { name: 'tickLower', internalType: 'int24', type: 'int24' },
295
+ { name: 'tickUpper', internalType: 'int24', type: 'int24' },
296
+ { name: 'numPositions', internalType: 'uint16', type: 'uint16' },
297
+ {
298
+ name: 'maxDiscoverySupplyShare',
299
+ internalType: 'uint256',
300
+ type: 'uint256',
301
+ },
302
+ ],
303
+ stateMutability: 'view',
304
+ },
305
+ {
306
+ type: 'function',
307
+ inputs: [],
308
+ name: 'poolState',
309
+ outputs: [
310
+ { name: 'asset', internalType: 'address', type: 'address' },
311
+ { name: 'numeraire', internalType: 'address', type: 'address' },
312
+ { name: 'tickLower', internalType: 'int24', type: 'int24' },
313
+ { name: 'tickUpper', internalType: 'int24', type: 'int24' },
314
+ { name: 'numPositions', internalType: 'uint16', type: 'uint16' },
315
+ { name: 'isInitialized', internalType: 'bool', type: 'bool' },
316
+ { name: 'isExited', internalType: 'bool', type: 'bool' },
317
+ { name: 'maxShareToBeSold', internalType: 'uint256', type: 'uint256' },
318
+ {
319
+ name: 'totalTokensOnBondingCurve',
320
+ internalType: 'uint256',
321
+ type: 'uint256',
322
+ },
323
+ ],
324
+ stateMutability: 'view',
325
+ },
311
326
  {
312
327
  type: 'function',
313
328
  inputs: [],
@@ -436,14 +451,21 @@ export const coinABI = [
436
451
  {
437
452
  type: 'function',
438
453
  inputs: [
439
- { name: 'amount0Delta', internalType: 'int256', type: 'int256' },
440
- { name: 'amount1Delta', internalType: 'int256', type: 'int256' },
454
+ { name: 'amount0Owed', internalType: 'uint256', type: 'uint256' },
455
+ { name: 'amount1Owed', internalType: 'uint256', type: 'uint256' },
441
456
  { name: '', internalType: 'bytes', type: 'bytes' },
442
457
  ],
443
- name: 'uniswapV3SwapCallback',
458
+ name: 'uniswapV3MintCallback',
444
459
  outputs: [],
445
460
  stateMutability: 'nonpayable',
446
461
  },
462
+ {
463
+ type: 'function',
464
+ inputs: [],
465
+ name: 'v3Factory',
466
+ outputs: [{ name: '', internalType: 'address', type: 'address' }],
467
+ stateMutability: 'view',
468
+ },
447
469
  {
448
470
  type: 'event',
449
471
  anonymous: false,
@@ -852,6 +874,12 @@ export const coinABI = [
852
874
  },
853
875
  { type: 'error', inputs: [], name: 'AddressZero' },
854
876
  { type: 'error', inputs: [], name: 'AlreadyOwner' },
877
+ { type: 'error', inputs: [], name: 'CannotMintZeroLiquidity' },
878
+ {
879
+ type: 'error',
880
+ inputs: [],
881
+ name: 'DopplerPoolMustHaveMoreThan2DiscoveryPositions',
882
+ },
855
883
  { type: 'error', inputs: [], name: 'ECDSAInvalidSignature' },
856
884
  {
857
885
  type: 'error',
@@ -934,11 +962,30 @@ export const coinABI = [
934
962
  { type: 'error', inputs: [], name: 'InvalidCurrencyLowerTick' },
935
963
  { type: 'error', inputs: [], name: 'InvalidInitialization' },
936
964
  { type: 'error', inputs: [], name: 'InvalidMarketType' },
965
+ { type: 'error', inputs: [], name: 'InvalidPoolVersion' },
966
+ {
967
+ type: 'error',
968
+ inputs: [
969
+ { name: 'tickLower', internalType: 'int24', type: 'int24' },
970
+ { name: 'tickUpper', internalType: 'int24', type: 'int24' },
971
+ ],
972
+ name: 'InvalidTickRangeMisordered',
973
+ },
937
974
  { type: 'error', inputs: [], name: 'InvalidWethLowerTick' },
975
+ { type: 'error', inputs: [], name: 'LegacyPoolMustHaveOneDiscoveryPosition' },
938
976
  { type: 'error', inputs: [], name: 'MarketAlreadyGraduated' },
939
977
  { type: 'error', inputs: [], name: 'MarketNotGraduated' },
978
+ {
979
+ type: 'error',
980
+ inputs: [
981
+ { name: 'value', internalType: 'uint256', type: 'uint256' },
982
+ { name: 'limit', internalType: 'uint256', type: 'uint256' },
983
+ ],
984
+ name: 'MaxShareToBeSoldExceeded',
985
+ },
940
986
  { type: 'error', inputs: [], name: 'NotInitializing' },
941
987
  { type: 'error', inputs: [], name: 'NotOwner' },
988
+ { type: 'error', inputs: [], name: 'NumDiscoveryPositionsOutOfRange' },
942
989
  { type: 'error', inputs: [], name: 'OneOwnerRequired' },
943
990
  { type: 'error', inputs: [], name: 'OnlyOwner' },
944
991
  { type: 'error', inputs: [], name: 'OnlyPool' },
@@ -959,6 +1006,36 @@ export const coinABI = [
959
1006
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
960
1007
 
961
1008
  export const iUniswapV3PoolABI = [
1009
+ {
1010
+ type: 'function',
1011
+ inputs: [
1012
+ { name: 'tickLower', internalType: 'int24', type: 'int24' },
1013
+ { name: 'tickUpper', internalType: 'int24', type: 'int24' },
1014
+ { name: 'amount', internalType: 'uint128', type: 'uint128' },
1015
+ ],
1016
+ name: 'burn',
1017
+ outputs: [
1018
+ { name: 'amount0', internalType: 'uint256', type: 'uint256' },
1019
+ { name: 'amount1', internalType: 'uint256', type: 'uint256' },
1020
+ ],
1021
+ stateMutability: 'nonpayable',
1022
+ },
1023
+ {
1024
+ type: 'function',
1025
+ inputs: [
1026
+ { name: 'recipient', internalType: 'address', type: 'address' },
1027
+ { name: 'tickLower', internalType: 'int24', type: 'int24' },
1028
+ { name: 'tickUpper', internalType: 'int24', type: 'int24' },
1029
+ { name: 'amount0Requested', internalType: 'uint128', type: 'uint128' },
1030
+ { name: 'amount1Requested', internalType: 'uint128', type: 'uint128' },
1031
+ ],
1032
+ name: 'collect',
1033
+ outputs: [
1034
+ { name: 'amount0', internalType: 'uint128', type: 'uint128' },
1035
+ { name: 'amount1', internalType: 'uint128', type: 'uint128' },
1036
+ ],
1037
+ stateMutability: 'nonpayable',
1038
+ },
962
1039
  {
963
1040
  type: 'function',
964
1041
  inputs: [],
@@ -973,6 +1050,31 @@ export const iUniswapV3PoolABI = [
973
1050
  outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],
974
1051
  stateMutability: 'view',
975
1052
  },
1053
+ {
1054
+ type: 'function',
1055
+ inputs: [
1056
+ { name: 'sqrtPriceX96', internalType: 'uint160', type: 'uint160' },
1057
+ ],
1058
+ name: 'initialize',
1059
+ outputs: [],
1060
+ stateMutability: 'nonpayable',
1061
+ },
1062
+ {
1063
+ type: 'function',
1064
+ inputs: [
1065
+ { name: 'recipient', internalType: 'address', type: 'address' },
1066
+ { name: 'tickLower', internalType: 'int24', type: 'int24' },
1067
+ { name: 'tickUpper', internalType: 'int24', type: 'int24' },
1068
+ { name: 'amount', internalType: 'uint128', type: 'uint128' },
1069
+ { name: 'data', internalType: 'bytes', type: 'bytes' },
1070
+ ],
1071
+ name: 'mint',
1072
+ outputs: [
1073
+ { name: 'amount0', internalType: 'uint256', type: 'uint256' },
1074
+ { name: 'amount1', internalType: 'uint256', type: 'uint256' },
1075
+ ],
1076
+ stateMutability: 'nonpayable',
1077
+ },
976
1078
  {
977
1079
  type: 'function',
978
1080
  inputs: [],
@@ -1040,7 +1142,7 @@ export const iUniswapV3PoolABI = [
1040
1142
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1041
1143
 
1042
1144
  /**
1043
- * - [__View Contract on Base Basescan__](https://basescan.org/address/0x777777751622c0d3258f214F9DF38E35BF45baF3)
1145
+ * - [__View Contract on Base Basescan__](https://basescan.org/address/0x02B2705500096Ff83F9eF78873ca5DFB06C00Ddc)
1044
1146
  * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x777777751622c0d3258f214F9DF38E35BF45baF3)
1045
1147
  */
1046
1148
  export const zoraFactoryImplABI = [
@@ -1083,6 +1185,25 @@ export const zoraFactoryImplABI = [
1083
1185
  ],
1084
1186
  stateMutability: 'payable',
1085
1187
  },
1188
+ {
1189
+ type: 'function',
1190
+ inputs: [
1191
+ { name: 'payoutRecipient', internalType: 'address', type: 'address' },
1192
+ { name: 'owners', internalType: 'address[]', type: 'address[]' },
1193
+ { name: 'uri', internalType: 'string', type: 'string' },
1194
+ { name: 'name', internalType: 'string', type: 'string' },
1195
+ { name: 'symbol', internalType: 'string', type: 'string' },
1196
+ { name: 'poolConfig', internalType: 'bytes', type: 'bytes' },
1197
+ { name: 'platformReferrer', internalType: 'address', type: 'address' },
1198
+ { name: 'orderSize', internalType: 'uint256', type: 'uint256' },
1199
+ ],
1200
+ name: 'deploy',
1201
+ outputs: [
1202
+ { name: '', internalType: 'address', type: 'address' },
1203
+ { name: '', internalType: 'uint256', type: 'uint256' },
1204
+ ],
1205
+ stateMutability: 'payable',
1206
+ },
1086
1207
  {
1087
1208
  type: 'function',
1088
1209
  inputs: [],
@@ -1288,16 +1409,16 @@ export const zoraFactoryImplABI = [
1288
1409
  ] as const
1289
1410
 
1290
1411
  /**
1291
- * - [__View Contract on Base Basescan__](https://basescan.org/address/0x777777751622c0d3258f214F9DF38E35BF45baF3)
1412
+ * - [__View Contract on Base Basescan__](https://basescan.org/address/0x02B2705500096Ff83F9eF78873ca5DFB06C00Ddc)
1292
1413
  * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x777777751622c0d3258f214F9DF38E35BF45baF3)
1293
1414
  */
1294
1415
  export const zoraFactoryImplAddress = {
1295
- 8453: '0x777777751622c0d3258f214F9DF38E35BF45baF3',
1416
+ 8453: '0x02B2705500096Ff83F9eF78873ca5DFB06C00Ddc',
1296
1417
  84532: '0x777777751622c0d3258f214F9DF38E35BF45baF3',
1297
1418
  } as const
1298
1419
 
1299
1420
  /**
1300
- * - [__View Contract on Base Basescan__](https://basescan.org/address/0x777777751622c0d3258f214F9DF38E35BF45baF3)
1421
+ * - [__View Contract on Base Basescan__](https://basescan.org/address/0x02B2705500096Ff83F9eF78873ca5DFB06C00Ddc)
1301
1422
  * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x777777751622c0d3258f214F9DF38E35BF45baF3)
1302
1423
  */
1303
1424
  export const zoraFactoryImplConfig = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zoralabs/coins",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -30,15 +30,15 @@
30
30
  "tsx": "^3.13.0",
31
31
  "typescript": "^5.2.2",
32
32
  "viem": "^2.21.18",
33
+ "@zoralabs/shared-contracts": "^0.0.2",
33
34
  "@zoralabs/shared-scripts": "^0.0.0",
34
- "@zoralabs/shared-contracts": "^0.0.1",
35
35
  "@zoralabs/tsconfig": "^0.0.1"
36
36
  },
37
37
  "scripts": {
38
38
  "build": "pnpm run wagmi:generate && pnpm run copy-abis && pnpm run prettier:write && tsup",
39
39
  "build:sizes": "forge build src/ --sizes",
40
40
  "copy-abis": "pnpm exec bundle-abis",
41
- "coverage": "forge coverage --report lcov --ir-minimum --no-match-coverage '(test/|src/utils/TickMath.sol|script/)'",
41
+ "coverage": "forge coverage --report lcov --ir-minimum --no-match-coverage '(test/|src/utils/uniswap/|script/)'",
42
42
  "prettier:check": "prettier --check 'src/**/*.sol' 'test/**/*.sol' 'script/**/*.sol'",
43
43
  "prettier:write": "prettier --write 'src/**/*.sol' 'test/**/*.sol' 'script/**/*.sol'",
44
44
  "test": "forge test -vv",
@@ -52,7 +52,7 @@ contract CoinsDeployerBase is ProxyDeployerScript {
52
52
  }
53
53
 
54
54
  function deployCoinImpl() internal returns (Coin) {
55
- return new Coin(getZoraRecipient(), PROTOCOL_REWARDS, getWeth(), getNonFungiblePositionManager(), getUniswapSwapRouter());
55
+ return new Coin(getZoraRecipient(), PROTOCOL_REWARDS, getWeth(), getUniswapV3Factory(), getUniswapSwapRouter(), getDopplerAirlock());
56
56
  }
57
57
 
58
58
  function deployZoraFactoryImpl(address coinImpl) internal returns (ZoraFactoryImpl) {
@@ -0,0 +1,67 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.13;
3
+
4
+ import {Script, console} from "forge-std/Script.sol";
5
+
6
+ import {Coin, CoinConstants} from "../src/Coin.sol";
7
+ import {ZoraFactoryImpl} from "../src/ZoraFactoryImpl.sol";
8
+ import {ZoraFactory} from "../src/proxy/ZoraFactory.sol";
9
+
10
+ /// @dev For simulating pre-buys -- eg `forge script script/Simulate.s.sol --private-key $DEPLOYER_PK --rpc-url $BASE_MAINNET_RPC_URL -vvvv`
11
+ contract Simulate is Script, CoinConstants {
12
+ // https://basescan.org/address/0x02B2705500096Ff83F9eF78873ca5DFB06C00Ddc
13
+ address internal constant TEST_ZORA_FACTORY_ADDRESS_BASE_MAINNET = 0x02B2705500096Ff83F9eF78873ca5DFB06C00Ddc;
14
+ address internal constant WETH_ADDRESS = 0x4200000000000000000000000000000000000006;
15
+
16
+ ZoraFactoryImpl internal factory;
17
+ Coin internal coin;
18
+
19
+ function setUp() public {
20
+ factory = ZoraFactoryImpl(TEST_ZORA_FACTORY_ADDRESS_BASE_MAINNET);
21
+ }
22
+
23
+ function run() public {
24
+ vm.startBroadcast();
25
+
26
+ // Filler
27
+ address payoutAddress = 0x12125c8a52B8E4ed1A28e1f964023b4477f11300;
28
+ address[] memory owners = new address[](1);
29
+ owners[0] = 0x12125c8a52B8E4ed1A28e1f964023b4477f11300;
30
+ string memory uri = "ipfs://bafybeigxwyzkb5rg2tcur4abyaeps56c4vcxytnz7ktrg3nr5dkgrgje7a";
31
+ string memory name = "testcoin";
32
+ string memory symbol = "testcoin";
33
+
34
+ // Pool config
35
+ int24 tickLower = -163600; // Starting price * 1B = Starting mcap
36
+ int24 tickUpper = -170000; // Price when tail position liquidity is entered
37
+ uint16 numDisoveryPositions = 99; // More positions = smoother price curve to tickUpper but higher gas cost
38
+ uint256 maxDiscoverySupplyShare = 0.1e18; // Pct of supply to allocate equally across `numDisoveryPositions` between `tickLower` and `tickUpper` above
39
+
40
+ bytes memory poolConfig = _generatePoolConfig(WETH_ADDRESS, tickLower, tickUpper, numDisoveryPositions, maxDiscoverySupplyShare);
41
+
42
+ // Prebuy order size
43
+ uint256 orderSize = 0.000111 ether;
44
+ (address coinAddress, uint256 coinsPurchased) = factory.deploy{value: orderSize}(
45
+ payoutAddress,
46
+ owners,
47
+ uri,
48
+ name,
49
+ symbol,
50
+ poolConfig,
51
+ payoutAddress,
52
+ orderSize
53
+ );
54
+
55
+ vm.stopBroadcast();
56
+ }
57
+
58
+ function _generatePoolConfig(
59
+ address currency_,
60
+ int24 tickLower_,
61
+ int24 tickUpper_,
62
+ uint16 numDiscoveryPositions_,
63
+ uint256 maxDiscoverySupplyShare_
64
+ ) internal pure returns (bytes memory) {
65
+ return abi.encode(currency_, tickLower_, tickUpper_, numDiscoveryPositions_, maxDiscoverySupplyShare_);
66
+ }
67
+ }