@zoralabs/coins 1.0.0 → 1.0.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.
Files changed (43) hide show
  1. package/.turbo/turbo-build.log +123 -75
  2. package/CHANGELOG.md +6 -0
  3. package/abis/BuySupplyWithSwapRouterHook.json +40 -0
  4. package/abis/CoinUniV4Test.json +42 -4
  5. package/abis/FeeEstimatorHook.json +0 -13
  6. package/abis/HooksTest.json +13 -0
  7. package/abis/IZoraFactory.json +19 -0
  8. package/abis/UpgradesTest.json +14 -0
  9. package/abis/ZoraV4CoinHook.json +0 -13
  10. package/addresses/8453.json +7 -8
  11. package/addresses/84532.json +8 -9
  12. package/addresses/dev/8453.json +10 -0
  13. package/dist/index.cjs +15 -1
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.js +15 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/wagmiGenerated.d.ts +30 -0
  18. package/dist/wagmiGenerated.d.ts.map +1 -1
  19. package/foundry.toml +1 -0
  20. package/package/wagmiGenerated.ts +14 -0
  21. package/package.json +1 -1
  22. package/script/Deploy.s.sol +1 -1
  23. package/script/DeployDevFactory.s.sol +2 -2
  24. package/script/DeployHooks.s.sol +1 -1
  25. package/script/PrintUpgradeCommand.s.sol +1 -1
  26. package/script/TestBackingCoinSwap.s.sol +25 -24
  27. package/script/TestV4Swap.s.sol +6 -6
  28. package/script/UpgradeCoinImpl.sol +2 -2
  29. package/script/UpgradeFactoryImpl.s.sol +1 -1
  30. package/src/BaseCoin.sol +14 -0
  31. package/{script → src/deployment}/CoinsDeployerBase.sol +59 -28
  32. package/src/hooks/ZoraV4CoinHook.sol +32 -15
  33. package/src/hooks/deployment/BuySupplyWithSwapRouterHook.sol +64 -4
  34. package/src/interfaces/IZoraFactory.sol +2 -1
  35. package/src/libs/CoinRewardsV4.sol +0 -1
  36. package/src/libs/HooksDeployment.sol +51 -7
  37. package/src/libs/UniV4SwapToCurrency.sol +3 -3
  38. package/src/libs/V4Liquidity.sol +2 -9
  39. package/src/version/ContractVersionBase.sol +1 -1
  40. package/test/CoinUniV4.t.sol +85 -60
  41. package/test/DeploymentHooks.t.sol +51 -10
  42. package/test/Upgrades.t.sol +92 -1
  43. package/test/utils/BaseTest.sol +56 -1
@@ -8,6 +8,10 @@ export declare const buySupplyWithSwapRouterHookABI: readonly [{
8
8
  readonly name: "_swapRouter";
9
9
  readonly internalType: "address";
10
10
  readonly type: "address";
11
+ }, {
12
+ readonly name: "_poolManager";
13
+ readonly internalType: "address";
14
+ readonly type: "address";
11
15
  }];
12
16
  readonly stateMutability: "nonpayable";
13
17
  }, {
@@ -56,6 +60,20 @@ export declare const buySupplyWithSwapRouterHookABI: readonly [{
56
60
  readonly type: "bool";
57
61
  }];
58
62
  readonly stateMutability: "pure";
63
+ }, {
64
+ readonly type: "function";
65
+ readonly inputs: readonly [{
66
+ readonly name: "data";
67
+ readonly internalType: "bytes";
68
+ readonly type: "bytes";
69
+ }];
70
+ readonly name: "unlockCallback";
71
+ readonly outputs: readonly [{
72
+ readonly name: "";
73
+ readonly internalType: "bytes";
74
+ readonly type: "bytes";
75
+ }];
76
+ readonly stateMutability: "nonpayable";
59
77
  }, {
60
78
  readonly type: "error";
61
79
  readonly inputs: readonly [];
@@ -68,6 +86,14 @@ export declare const buySupplyWithSwapRouterHookABI: readonly [{
68
86
  readonly type: "uint256";
69
87
  }];
70
88
  readonly name: "CoinBalanceNot0";
89
+ }, {
90
+ readonly type: "error";
91
+ readonly inputs: readonly [{
92
+ readonly name: "balance";
93
+ readonly internalType: "uint256";
94
+ readonly type: "uint256";
95
+ }];
96
+ readonly name: "CurrencyBalanceNot0";
71
97
  }, {
72
98
  readonly type: "error";
73
99
  readonly inputs: readonly [];
@@ -84,6 +110,10 @@ export declare const buySupplyWithSwapRouterHookABI: readonly [{
84
110
  readonly type: "error";
85
111
  readonly inputs: readonly [];
86
112
  readonly name: "NotFactory";
113
+ }, {
114
+ readonly type: "error";
115
+ readonly inputs: readonly [];
116
+ readonly name: "OnlyPoolManager";
87
117
  }, {
88
118
  readonly type: "error";
89
119
  readonly inputs: readonly [{
@@ -1 +1 @@
1
- {"version":3,"file":"wagmiGenerated.d.ts","sourceRoot":"","sources":["../package/wagmiGenerated.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuDjC,CAAA;AAMV,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmgCV,CAAA;AAMV,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAi9BZ,CAAA;AAMV,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyfd,CAAA;AAMV,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuBzB,CAAA;AAMV,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkIpB,CAAA;AAMV,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwBtB,CAAA;AAMV,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0crB,CAAA"}
1
+ {"version":3,"file":"wagmiGenerated.d.ts","sourceRoot":"","sources":["../package/wagmiGenerated.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqEjC,CAAA;AAMV,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmgCV,CAAA;AAMV,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAi9BZ,CAAA;AAMV,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyfd,CAAA;AAMV,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuBzB,CAAA;AAMV,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkIpB,CAAA;AAMV,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwBtB,CAAA;AAMV,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0crB,CAAA"}
package/foundry.toml CHANGED
@@ -8,6 +8,7 @@ solc_version = '0.8.28'
8
8
  optimizer_runs = 200
9
9
  fs_permissions = [
10
10
  { access = "readwrite", path = "./addresses" },
11
+ { access = "readwrite", path = "./addresses/dev" },
11
12
  { access = "read", path = "./package.json" },
12
13
  { access = "readwrite", path = "./deterministicConfig" },
13
14
  { access = "read", path = "../shared-contracts/chainConfigs" },
@@ -12,6 +12,7 @@ export const buySupplyWithSwapRouterHookABI = [
12
12
  type: 'address',
13
13
  },
14
14
  { name: '_swapRouter', internalType: 'address', type: 'address' },
15
+ { name: '_poolManager', internalType: 'address', type: 'address' },
15
16
  ],
16
17
  stateMutability: 'nonpayable',
17
18
  },
@@ -42,16 +43,29 @@ export const buySupplyWithSwapRouterHookABI = [
42
43
  outputs: [{ name: '', internalType: 'bool', type: 'bool' }],
43
44
  stateMutability: 'pure',
44
45
  },
46
+ {
47
+ type: 'function',
48
+ inputs: [{ name: 'data', internalType: 'bytes', type: 'bytes' }],
49
+ name: 'unlockCallback',
50
+ outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }],
51
+ stateMutability: 'nonpayable',
52
+ },
45
53
  { type: 'error', inputs: [], name: 'AddressZero' },
46
54
  {
47
55
  type: 'error',
48
56
  inputs: [{ name: 'balance', internalType: 'uint256', type: 'uint256' }],
49
57
  name: 'CoinBalanceNot0',
50
58
  },
59
+ {
60
+ type: 'error',
61
+ inputs: [{ name: 'balance', internalType: 'uint256', type: 'uint256' }],
62
+ name: 'CurrencyBalanceNot0',
63
+ },
51
64
  { type: 'error', inputs: [], name: 'Erc20NotReceived' },
52
65
  { type: 'error', inputs: [], name: 'HookNotImplemented' },
53
66
  { type: 'error', inputs: [], name: 'InvalidSwapRouterCall' },
54
67
  { type: 'error', inputs: [], name: 'NotFactory' },
68
+ { type: 'error', inputs: [], name: 'OnlyPoolManager' },
55
69
  {
56
70
  type: 'error',
57
71
  inputs: [{ name: 'error', internalType: 'bytes', type: 'bytes' }],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zoralabs/coins",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -2,7 +2,7 @@
2
2
  pragma solidity ^0.8.28;
3
3
 
4
4
  import {ProxyDeployerScript, DeterministicDeployerAndCaller} from "@zoralabs/shared-contracts/deployment/ProxyDeployerScript.sol";
5
- import {CoinsDeployerBase} from "./CoinsDeployerBase.sol";
5
+ import {CoinsDeployerBase} from "../src/deployment/CoinsDeployerBase.sol";
6
6
 
7
7
  contract DeployScript is CoinsDeployerBase {
8
8
  function run() public {
@@ -2,11 +2,11 @@
2
2
  pragma solidity ^0.8.28;
3
3
 
4
4
  import {ProxyDeployerScript, DeterministicDeployerAndCaller} from "@zoralabs/shared-contracts/deployment/ProxyDeployerScript.sol";
5
- import {CoinsDeployerBase} from "./CoinsDeployerBase.sol";
5
+ import {CoinsDeployerBase} from "../src/deployment/CoinsDeployerBase.sol";
6
6
 
7
7
  contract DeployScript is CoinsDeployerBase {
8
8
  function run() public {
9
- CoinsDeployment memory deployment = readDeployment();
9
+ CoinsDeployment memory deployment = readDeployment(true);
10
10
 
11
11
  vm.startBroadcast();
12
12
 
@@ -1,7 +1,7 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity ^0.8.28;
3
3
 
4
- import {CoinsDeployerBase} from "./CoinsDeployerBase.sol";
4
+ import {CoinsDeployerBase} from "../src/deployment/CoinsDeployerBase.sol";
5
5
  import {ZoraFactoryImpl} from "../src/ZoraFactoryImpl.sol";
6
6
 
7
7
  contract DeployHooks is CoinsDeployerBase {
@@ -2,7 +2,7 @@
2
2
  pragma solidity ^0.8.26;
3
3
 
4
4
  import {ProxyDeployerScript, DeterministicDeployerAndCaller} from "@zoralabs/shared-contracts/deployment/ProxyDeployerScript.sol";
5
- import {CoinsDeployerBase} from "./CoinsDeployerBase.sol";
5
+ import {CoinsDeployerBase} from "../src/deployment/CoinsDeployerBase.sol";
6
6
 
7
7
  contract PrintUpgradeCommand is CoinsDeployerBase {
8
8
  function run() public {
@@ -2,7 +2,7 @@
2
2
  pragma solidity ^0.8.28;
3
3
 
4
4
  import {ProxyDeployerScript, DeterministicDeployerAndCaller} from "@zoralabs/shared-contracts/deployment/ProxyDeployerScript.sol";
5
- import {CoinsDeployerBase} from "./CoinsDeployerBase.sol";
5
+ import {CoinsDeployerBase} from "../src/deployment/CoinsDeployerBase.sol";
6
6
 
7
7
  import {IZoraFactory} from "../src/interfaces/IZoraFactory.sol";
8
8
  import {CoinConfigurationVersions} from "../src/libs/CoinConfigurationVersions.sol";
@@ -41,7 +41,7 @@ contract TestV4Swap is CoinsDeployerBase {
41
41
 
42
42
  bytes memory poolConfig = CoinConfigurationVersions.defaultDopplerMultiCurveUniV4(address(currency));
43
43
 
44
- (address coinAddress, ) = IZoraFactory(deployment.devFactory).deploy(
44
+ (address coinAddress, ) = IZoraFactory(deployment.zoraFactory).deploy(
45
45
  creator,
46
46
  owners,
47
47
  uri,
@@ -103,20 +103,21 @@ contract TestV4Swap is CoinsDeployerBase {
103
103
 
104
104
  vm.startBroadcast(trader);
105
105
 
106
- // address createReferral = 0xC077e4cC02fa01A5b7fAca1acE9BBe9f5ac5Af9F;
106
+ address createReferral = 0xC077e4cC02fa01A5b7fAca1acE9BBe9f5ac5Af9F;
107
107
  address tradeReferral = 0xC077e4cC02fa01A5b7fAca1acE9BBe9f5ac5Af9F;
108
- // ICoinV4 backingCoin = _deployCoin(zora, trader, "TestCCoin", "CRE", "https://testc.com", createReferral, bytes32("creator"));
109
- // ICoinV4 contentCoin = _deployCoin(
110
- // address(backingCoin),
111
- // trader,
112
- // "Content Coin",
113
- // "CONTENT",
114
- // "https://content.com",
115
- // createReferral,
116
- // bytes32("content coin")
117
- // );
118
- ICoinV4 backingCoin = ICoinV4(0xeA734b5997F35cD469921cCa7BB9A03C104f2f64);
119
- ICoinV4 contentCoin = ICoinV4(0x72218BFEEc7D556BD3Dd8eFf2a317CEd49533769);
108
+
109
+ ICoinV4 backingCoin = _deployCoin(zora, trader, "Backing Coin", "BACK", "https://testc.com", createReferral, bytes32("creator"));
110
+ ICoinV4 contentCoin = _deployCoin(
111
+ address(backingCoin),
112
+ trader,
113
+ "Content Coin",
114
+ "CONTENT",
115
+ "https://content.com",
116
+ createReferral,
117
+ bytes32("content coin")
118
+ );
119
+ // ICoinV4 backingCoin = ICoinV4(0xeA734b5997F35cD469921cCa7BB9A03C104f2f64);
120
+ // ICoinV4 contentCoin = ICoinV4(0x72218BFEEc7D556BD3Dd8eFf2a317CEd49533769);
120
121
 
121
122
  console.log("backingCoin", address(backingCoin));
122
123
  console.log("contentCoin", address(contentCoin));
@@ -128,18 +129,18 @@ contract TestV4Swap is CoinsDeployerBase {
128
129
  // console.log("currency", address(currency));
129
130
  // console.log("coinAddress", coinAddress);
130
131
 
131
- // swap in 2 ether of currency into the coin
132
- uint128 amountIn = uint128(IERC20(zora).balanceOf(trader));
133
- // currency.mint(trader, amountIn);
132
+ // // swap in 2 ether of currency into the coin
133
+ // uint128 amountIn = uint128(IERC20(zora).balanceOf(trader));
134
+ // // currency.mint(trader, amountIn);
134
135
 
135
- // // swap some currency into the backing coin
136
- uint256 backingCoinReceived = _swap(zora, amountIn, backingCoin, trader, tradeReferral);
136
+ // // // swap some currency into the backing coin
137
+ // uint256 backingCoinReceived = _swap(zora, amountIn, backingCoin, trader, tradeReferral);
137
138
 
138
- // // swap balance of backing coin into the content coin
139
- uint256 contentCoinReceived = _swap(address(backingCoin), uint128(backingCoinReceived), contentCoin, trader, tradeReferral);
139
+ // // // swap balance of backing coin into the content coin
140
+ // uint256 contentCoinReceived = _swap(address(backingCoin), uint128(backingCoinReceived), contentCoin, trader, tradeReferral);
140
141
 
141
- // swap balance of content coin into the currency
142
- _swap(address(contentCoin), uint128(contentCoinReceived), contentCoin, trader, tradeReferral);
142
+ // // swap balance of content coin into the currency
143
+ // _swap(address(contentCoin), uint128(contentCoinReceived), contentCoin, trader, tradeReferral);
143
144
 
144
145
  vm.stopBroadcast();
145
146
  }
@@ -2,7 +2,7 @@
2
2
  pragma solidity ^0.8.28;
3
3
 
4
4
  import {ProxyDeployerScript, DeterministicDeployerAndCaller} from "@zoralabs/shared-contracts/deployment/ProxyDeployerScript.sol";
5
- import {CoinsDeployerBase} from "./CoinsDeployerBase.sol";
5
+ import {CoinsDeployerBase} from "../src/deployment/CoinsDeployerBase.sol";
6
6
 
7
7
  import {IZoraFactory} from "../src/interfaces/IZoraFactory.sol";
8
8
  import {CoinConfigurationVersions} from "../src/libs/CoinConfigurationVersions.sol";
@@ -96,7 +96,7 @@ contract TestV4Swap is CoinsDeployerBase {
96
96
 
97
97
  vm.startBroadcast(trader);
98
98
 
99
- // address createReferral = 0xC077e4cC02fa01A5b7fAca1acE9BBe9f5ac5Af9F;
99
+ address createReferral = 0xC077e4cC02fa01A5b7fAca1acE9BBe9f5ac5Af9F;
100
100
  address tradeReferral = 0xC077e4cC02fa01A5b7fAca1acE9BBe9f5ac5Af9F;
101
101
 
102
102
  // MockERC20 currency = _deployMockCurrency();
@@ -104,13 +104,13 @@ contract TestV4Swap is CoinsDeployerBase {
104
104
  // ICoinV4 backingCoin = _deployMockCoin(address(currency), trader, createReferral, bytes32("backing coin"));
105
105
  // ICoinV4 contentCoin = _deployMockCoin(address(backingCoin), trader, createReferral, bytes32("content coin"));
106
106
 
107
- MockERC20 currency = MockERC20(0x21E3bde504fF56C440851ACB6A16e7E35405B278);
108
- ICoinV4 backingCoin = ICoinV4(0xa8bb679A2be09eCCabdb76700170ec387C896570);
109
- ICoinV4 contentCoin = ICoinV4(0x3cfE4CE87A821FB2c7eAB4359dD6eA6F9e492c61);
107
+ MockERC20 currency = MockERC20(0x1b183Bd0E2c03Fc830F4d813bA37E82F9F97cA21);
108
+ ICoinV4 backingCoin = ICoinV4(0x7D74416C4c295A592Fc6F9232911C945354b253C);
109
+ ICoinV4 contentCoin = ICoinV4(0xf6d6660bcdA588F7f99e2961f279f500fB501730);
110
110
 
111
+ console.log("currency", address(currency));
111
112
  console.log("backingCoin", address(backingCoin));
112
113
  console.log("contentCoin", address(contentCoin));
113
- console.log("currency", address(currency));
114
114
 
115
115
  // (MockERC20 currency, address coinAddress) = _deployMockCurrencyAndCoin(trader, createReferral);
116
116
 
@@ -2,11 +2,11 @@
2
2
  pragma solidity ^0.8.26;
3
3
 
4
4
  import {ProxyDeployerScript, DeterministicDeployerAndCaller} from "@zoralabs/shared-contracts/deployment/ProxyDeployerScript.sol";
5
- import {CoinsDeployerBase} from "./CoinsDeployerBase.sol";
5
+ import {CoinsDeployerBase} from "../src/deployment/CoinsDeployerBase.sol";
6
6
 
7
7
  contract UpgradeCoinImpl is CoinsDeployerBase {
8
8
  function run() public {
9
- CoinsDeployment memory deployment = readDeployment();
9
+ CoinsDeployment memory deployment = readDeployment(false);
10
10
 
11
11
  vm.startBroadcast();
12
12
 
@@ -1,7 +1,7 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity ^0.8.28;
3
3
 
4
- import {CoinsDeployerBase} from "./CoinsDeployerBase.sol";
4
+ import {CoinsDeployerBase} from "../src/deployment/CoinsDeployerBase.sol";
5
5
  import {ZoraFactoryImpl} from "../src/ZoraFactoryImpl.sol";
6
6
 
7
7
  contract UpgradeFactoryImpl is CoinsDeployerBase {
package/src/BaseCoin.sol CHANGED
@@ -6,14 +6,28 @@ import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
6
6
  import {ICoin, IHasRewardsRecipients} from "./interfaces/ICoin.sol";
7
7
  import {ICoinComments} from "./interfaces/ICoinComments.sol";
8
8
  import {IERC7572} from "./interfaces/IERC7572.sol";
9
+ import {IUniswapV3Factory} from "./interfaces/IUniswapV3Factory.sol";
10
+ import {IUniswapV3Pool} from "./interfaces/IUniswapV3Pool.sol";
11
+ import {ISwapRouter} from "./interfaces/ISwapRouter.sol";
9
12
  import {IAirlock} from "./interfaces/IAirlock.sol";
13
+ import {IProtocolRewards} from "./interfaces/IProtocolRewards.sol";
14
+ import {IWETH} from "./interfaces/IWETH.sol";
10
15
 
16
+ import {Address} from "@openzeppelin/contracts/utils/Address.sol";
11
17
  import {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol";
12
18
  import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
13
19
  import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
14
20
  import {ContractVersionBase} from "./version/ContractVersionBase.sol";
15
21
  import {MultiOwnable} from "./utils/MultiOwnable.sol";
22
+ import {FullMath} from "./utils/uniswap/FullMath.sol";
23
+ import {TickMath} from "./utils/uniswap/TickMath.sol";
24
+ import {LiquidityAmounts} from "./utils/uniswap/LiquidityAmounts.sol";
16
25
  import {CoinConstants} from "./libs/CoinConstants.sol";
26
+ import {MarketConstants} from "./libs/MarketConstants.sol";
27
+ import {LpPosition} from "./types/LpPosition.sol";
28
+ import {PoolState} from "./types/PoolState.sol";
29
+ import {CoinSetupV3, UniV3Config, CoinV3Config} from "./libs/CoinSetupV3.sol";
30
+ import {UniV3BuySell, CoinConfig} from "./libs/UniV3BuySell.sol";
17
31
 
18
32
  /*
19
33
  $$$$$$\ $$$$$$\ $$$$$$\ $$\ $$\
@@ -5,21 +5,22 @@ import "forge-std/Script.sol";
5
5
 
6
6
  import {ProxyDeployerScript, DeterministicContractConfig, DeterministicDeployerAndCaller} from "@zoralabs/shared-contracts/deployment/ProxyDeployerScript.sol";
7
7
  import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
8
- import {ZoraFactoryImpl} from "../src/ZoraFactoryImpl.sol";
9
- import {Coin} from "../src/Coin.sol";
8
+ import {ZoraFactoryImpl} from "../ZoraFactoryImpl.sol";
9
+ import {Coin} from "../Coin.sol";
10
10
  import {IVersionedContract} from "@zoralabs/shared-contracts/interfaces/IVersionedContract.sol";
11
- import {BuySupplyWithSwapRouterHook} from "../src/hooks/deployment/BuySupplyWithSwapRouterHook.sol";
12
- import {IZoraFactory} from "../src/interfaces/IZoraFactory.sol";
13
- import {CoinV4} from "../src/CoinV4.sol";
11
+ import {BuySupplyWithSwapRouterHook} from "../hooks/deployment/BuySupplyWithSwapRouterHook.sol";
12
+ import {IZoraFactory} from "../interfaces/IZoraFactory.sol";
13
+ import {CoinV4} from "../CoinV4.sol";
14
14
  import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol";
15
- import {ZoraV4CoinHook} from "../src/hooks/ZoraV4CoinHook.sol";
15
+ import {ZoraV4CoinHook} from "../hooks/ZoraV4CoinHook.sol";
16
16
  import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
17
- import {ZoraFactory} from "../src/proxy/ZoraFactory.sol";
18
- import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol";
19
- import {HooksDeployment} from "../src/libs/HooksDeployment.sol";
17
+ import {ZoraFactory} from "../proxy/ZoraFactory.sol";
18
+ import {HooksDeployment} from "../libs/HooksDeployment.sol";
19
+ import {ProxyShim} from "../../test/utils/ProxyShim.sol";
20
20
 
21
21
  contract CoinsDeployerBase is ProxyDeployerScript {
22
22
  address internal constant PROTOCOL_REWARDS = 0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B;
23
+ address internal constant ZORA = 0x1111111111166b7FE7bd91427724B487980aFc69;
23
24
 
24
25
  using stdJson for string;
25
26
 
@@ -34,11 +35,19 @@ contract CoinsDeployerBase is ProxyDeployerScript {
34
35
  // hooks
35
36
  address buySupplyWithSwapRouterHook;
36
37
  address zoraV4CoinHook;
37
- address devFactory;
38
- address trustedMessageSenders;
38
+ // Hook deployment salt (for deterministic deployment)
39
+ bytes32 zoraV4CoinHookSalt;
40
+ bool isDev;
39
41
  }
40
42
 
41
43
  function addressesFile() internal view returns (string memory) {
44
+ return addressesFile(false);
45
+ }
46
+
47
+ function addressesFile(bool dev) internal view returns (string memory) {
48
+ if (dev) {
49
+ return string.concat("./addresses/dev/", vm.toString(block.chainid), ".json");
50
+ }
42
51
  return string.concat("./addresses/", vm.toString(block.chainid), ".json");
43
52
  }
44
53
 
@@ -50,16 +59,20 @@ contract CoinsDeployerBase is ProxyDeployerScript {
50
59
  vm.serializeString(objectKey, "COIN_VERSION", deployment.coinVersion);
51
60
  vm.serializeAddress(objectKey, "BUY_SUPPLY_WITH_SWAP_ROUTER_HOOK", deployment.buySupplyWithSwapRouterHook);
52
61
  vm.serializeAddress(objectKey, "COIN_V3_IMPL", deployment.coinV3Impl);
53
- vm.serializeAddress(objectKey, "DEV_FACTORY", deployment.devFactory);
54
62
  vm.serializeAddress(objectKey, "ZORA_V4_COIN_HOOK", deployment.zoraV4CoinHook);
55
- vm.serializeAddress(objectKey, "TRUSTED_MESSAGE_SENDERS", deployment.trustedMessageSenders);
63
+ vm.serializeBytes32(objectKey, "ZORA_V4_COIN_HOOK_SALT", deployment.zoraV4CoinHookSalt);
56
64
  string memory result = vm.serializeAddress(objectKey, "COIN_V4_IMPL", deployment.coinV4Impl);
57
65
 
58
- vm.writeJson(result, addressesFile());
66
+ vm.writeJson(result, addressesFile(deployment.isDev));
59
67
  }
60
68
 
61
69
  function readDeployment() internal returns (CoinsDeployment memory deployment) {
62
- string memory file = addressesFile();
70
+ return readDeployment(false);
71
+ }
72
+
73
+ function readDeployment(bool dev) internal returns (CoinsDeployment memory deployment) {
74
+ string memory file = addressesFile(dev);
75
+ deployment.isDev = dev;
63
76
  if (!vm.exists(file)) {
64
77
  return deployment;
65
78
  }
@@ -72,8 +85,7 @@ contract CoinsDeployerBase is ProxyDeployerScript {
72
85
  deployment.coinVersion = readStringOrDefaultToEmpty(json, "COIN_VERSION");
73
86
  deployment.buySupplyWithSwapRouterHook = readAddressOrDefaultToZero(json, "BUY_SUPPLY_WITH_SWAP_ROUTER_HOOK");
74
87
  deployment.zoraV4CoinHook = readAddressOrDefaultToZero(json, "ZORA_V4_COIN_HOOK");
75
- deployment.devFactory = readAddressOrDefaultToZero(json, "DEV_FACTORY");
76
- deployment.trustedMessageSenders = readAddressOrDefaultToZero(json, "TRUSTED_MESSAGE_SENDERS");
88
+ deployment.zoraV4CoinHookSalt = readBytes32OrDefaultToZero(json, "ZORA_V4_COIN_HOOK_SALT");
77
89
  }
78
90
 
79
91
  function deployCoinV3Impl() internal returns (Coin) {
@@ -104,11 +116,21 @@ contract CoinsDeployerBase is ProxyDeployerScript {
104
116
  }
105
117
 
106
118
  function deployBuySupplyWithSwapRouterHook(CoinsDeployment memory deployment) internal returns (BuySupplyWithSwapRouterHook) {
107
- return new BuySupplyWithSwapRouterHook(IZoraFactory(deployment.zoraFactory), getUniswapSwapRouter());
119
+ return new BuySupplyWithSwapRouterHook(IZoraFactory(deployment.zoraFactory), getUniswapSwapRouter(), getUniswapV4PoolManager());
108
120
  }
109
121
 
110
- function deployZoraV4CoinHook(address zoraFactory) internal returns (IHooks) {
111
- return HooksDeployment.deployZoraV4CoinHookFromScript(getUniswapV4PoolManager(), zoraFactory, getDefaultTrustedMessageSenders());
122
+ function deployZoraV4CoinHook(CoinsDeployment memory deployment) internal returns (IHooks, bytes32) {
123
+ // Read existing deployment to get stored salt
124
+
125
+ require(deployment.zoraFactory != address(0), "Zora factory is not set");
126
+
127
+ return
128
+ HooksDeployment.deployZoraV4CoinHookFromScript(
129
+ getUniswapV4PoolManager(),
130
+ deployment.zoraFactory,
131
+ getDefaultTrustedMessageSenders(),
132
+ deployment.zoraV4CoinHookSalt
133
+ );
112
134
  }
113
135
 
114
136
  function getDefaultTrustedMessageSenders() internal view returns (address[] memory) {
@@ -119,14 +141,17 @@ contract CoinsDeployerBase is ProxyDeployerScript {
119
141
  }
120
142
 
121
143
  function deployImpls(CoinsDeployment memory deployment) internal returns (CoinsDeployment memory) {
122
- address zoraFactoryImpl = address(deployZoraFactoryImpl(deployment.coinV3Impl, deployment.coinV4Impl));
123
-
124
144
  // Deploy implementation contracts
125
145
  deployment.coinV3Impl = address(deployCoinV3Impl());
126
- deployment.zoraV4CoinHook = address(deployZoraV4CoinHook(zoraFactoryImpl));
146
+
147
+ // Deploy hook first, then use its address for coin v4 impl
148
+ (IHooks zoraV4CoinHook, bytes32 usedSalt) = deployZoraV4CoinHook(deployment);
149
+ deployment.zoraV4CoinHook = address(zoraV4CoinHook);
150
+ deployment.zoraV4CoinHookSalt = usedSalt;
151
+
127
152
  deployment.coinV4Impl = address(deployCoinV4Impl(deployment.zoraV4CoinHook));
128
- deployment.zoraFactoryImpl = zoraFactoryImpl;
129
- deployment.coinVersion = IVersionedContract(deployment.coinV3Impl).contractVersion();
153
+ deployment.zoraFactoryImpl = address(deployZoraFactoryImpl(deployment.coinV3Impl, deployment.coinV4Impl));
154
+ deployment.coinVersion = IVersionedContract(deployment.coinV4Impl).contractVersion();
130
155
  deployment.buySupplyWithSwapRouterHook = address(deployBuySupplyWithSwapRouterHook(deployment));
131
156
 
132
157
  return deployment;
@@ -169,11 +194,17 @@ contract CoinsDeployerBase is ProxyDeployerScript {
169
194
  function deployDevFactory(CoinsDeployment memory deployment) internal returns (ZoraFactory devFactory) {
170
195
  address owner = 0x63545B401283c993320A5b886ecF0fc6CB5668a9;
171
196
 
172
- devFactory = new ZoraFactory(deployment.zoraFactoryImpl);
197
+ ProxyShim shim = new ProxyShim();
198
+
199
+ deployment.zoraFactory = address(new ZoraFactory(address(shim)));
200
+
201
+ deployment = deployImpls(deployment);
202
+
203
+ UUPSUpgradeable(deployment.zoraFactory).upgradeToAndCall(deployment.zoraFactoryImpl, "");
173
204
 
174
- ZoraFactoryImpl(address(devFactory)).initialize(owner);
205
+ ZoraFactoryImpl(deployment.zoraFactory).initialize(owner);
175
206
 
176
- deployment.devFactory = address(devFactory);
207
+ saveDeployment(deployment);
177
208
  }
178
209
 
179
210
  function printUpgradeFactoryCommand(CoinsDeployment memory deployment) internal view {
@@ -21,24 +21,35 @@ import {PoolConfiguration} from "../types/PoolConfiguration.sol";
21
21
  import {CoinDopplerMultiCurve} from "../libs/CoinDopplerMultiCurve.sol";
22
22
  import {PoolStateReader} from "../libs/PoolStateReader.sol";
23
23
  import {IHasSwapPath} from "../interfaces/ICoinV4.sol";
24
- import {ContractVersionBase} from "../version/ContractVersionBase.sol";
25
24
  import {CoinConfigurationVersions} from "../libs/CoinConfigurationVersions.sol";
26
25
 
27
- contract ZoraV4CoinHook is BaseHook, ContractVersionBase, IZoraV4CoinHook {
26
+ /// @title ZoraV4CoinHook
27
+ /// @notice Uniswap V4 hook that automatically handles fee collection and reward distributions on every swap,
28
+ /// paying out all rewards in a backing currency.
29
+ /// @dev This hook executes on afterSwap withdraw fees, swap for a backing currency, and distribute rewards.
30
+ /// On pool initialization, it creates multiple liquidity positions based on the coin's pool configuration.
31
+ /// On every swap, it automatically:
32
+ /// 1. Collects accrued LP fees from all positions
33
+ /// 2. Swaps collected fees to the backing currency through multi-hop paths
34
+ /// 3. Distributes converted fees as rewards
35
+ /// @author oveddan
36
+ contract ZoraV4CoinHook is BaseHook, IZoraV4CoinHook {
28
37
  using BalanceDeltaLibrary for BalanceDelta;
29
38
 
39
+ /// @notice Mapping of trusted message senders - these are addresses that are trusted to provide a
40
+ /// an original msg.sender
30
41
  mapping(address => bool) internal trustedMessageSender;
31
42
 
32
- IDeployedCoinVersionLookup internal immutable coinVersionLookup;
43
+ /// @notice Mapping of pool keys to coins.
44
+ mapping(bytes32 => IZoraV4CoinHook.PoolCoin) internal poolCoins;
33
45
 
34
- /// @inheritdoc IZoraV4CoinHook
35
- function isTrustedMessageSender(address sender) external view returns (bool) {
36
- return trustedMessageSender[sender];
37
- }
46
+ /// @notice The coin version lookup contract - used to determine if an address is a coin and what version it is.
47
+ IDeployedCoinVersionLookup internal immutable coinVersionLookup;
38
48
 
39
49
  /// @notice The constructor for the ZoraV4CoinHook.
40
- /// @param poolManager_ The pool manager for the coin.
41
- /// @param trustedMessageSenders_ The addresses of the trusted message senders.
50
+ /// @param poolManager_ The Uniswap V4 pool manager
51
+ /// @param coinVersionLookup_ The coin version lookup contract - used to determine if an address is a coin and what version it is.
52
+ /// @param trustedMessageSenders_ The addresses of the trusted message senders - these are addresses that are trusted to provide a
42
53
  constructor(IPoolManager poolManager_, IDeployedCoinVersionLookup coinVersionLookup_, address[] memory trustedMessageSenders_) BaseHook(poolManager_) {
43
54
  if (address(coinVersionLookup_) == address(0)) {
44
55
  revert CoinVersionLookupCannotBeZeroAddress();
@@ -73,12 +84,17 @@ contract ZoraV4CoinHook is BaseHook, ContractVersionBase, IZoraV4CoinHook {
73
84
  });
74
85
  }
75
86
 
76
- mapping(bytes32 => IZoraV4CoinHook.PoolCoin) internal poolCoins;
87
+ /// @inheritdoc IZoraV4CoinHook
88
+ function isTrustedMessageSender(address sender) external view returns (bool) {
89
+ return trustedMessageSender[sender];
90
+ }
77
91
 
92
+ /// @inheritdoc IZoraV4CoinHook
78
93
  function getPoolCoinByHash(bytes23 poolKeyHash) external view returns (IZoraV4CoinHook.PoolCoin memory) {
79
94
  return poolCoins[poolKeyHash];
80
95
  }
81
96
 
97
+ /// @inheritdoc IZoraV4CoinHook
82
98
  function getPoolCoin(PoolKey memory key) external view returns (IZoraV4CoinHook.PoolCoin memory) {
83
99
  return poolCoins[CoinCommon.hashPoolKey(key)];
84
100
  }
@@ -115,6 +131,10 @@ contract ZoraV4CoinHook is BaseHook, ContractVersionBase, IZoraV4CoinHook {
115
131
 
116
132
  /// @notice Internal fn called when a swap is executed.
117
133
  /// @dev This hook is called from BaseHook library from uniswap v4.
134
+ /// This hook:
135
+ /// 1. Collects accrued LP fees from all positions
136
+ /// 2. Swaps collected fees to the backing currency through multi-hop paths
137
+ /// 3. Distributes converted fees as rewards
118
138
  /// @param sender The address of the sender.
119
139
  /// @param key The pool key.
120
140
  /// @param params The swap parameters.
@@ -170,12 +190,9 @@ contract ZoraV4CoinHook is BaseHook, ContractVersionBase, IZoraV4CoinHook {
170
190
  return (BaseHook.afterSwap.selector, 0);
171
191
  }
172
192
 
173
- /// @notice Internal fn called when a liquidity is unlocked. Only callable from the PoolManager.
174
- /// @dev This hook is called from BaseHook library from uniswap v4.
175
- /// @param data The data.
176
- /// @return selector The selector of the unlockCallback hook to confirm the action.
193
+ /// @notice Internal fn called when the PoolManager is unlocked. Used to mint initial liquidity positions.
177
194
  function unlockCallback(bytes calldata data) external onlyPoolManager returns (bytes memory) {
178
- return abi.encode(V4Liquidity.handleMintPositionsCallback(poolManager, data));
195
+ V4Liquidity.handleMintPositionsCallback(poolManager, data);
179
196
  }
180
197
 
181
198
  /// @notice Internal fn to get the original message sender.