@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.
Files changed (124) hide show
  1. package/.turbo/turbo-build.log +131 -114
  2. package/CHANGELOG.md +40 -0
  3. package/abis/BaseCoin.json +26 -118
  4. package/abis/BaseTest.json +47 -0
  5. package/abis/Coin.json +171 -63
  6. package/abis/CoinDopplerMultiCurve.json +38 -0
  7. package/abis/CoinRewardsV4.json +54 -0
  8. package/abis/CoinTest.json +53 -20
  9. package/abis/CoinUniV4Test.json +1053 -0
  10. package/abis/CoinV4.json +234 -211
  11. package/abis/DeployScript.json +47 -0
  12. package/abis/DeployedCoinVersionLookup.json +21 -0
  13. package/abis/DeployedCoinVersionLookupTest.json +716 -0
  14. package/abis/DifferentNamespaceVersionLookup.json +39 -0
  15. package/abis/DopplerUniswapV3Test.json +49 -93
  16. package/abis/ERC20.json +310 -0
  17. package/abis/FactoryTest.json +85 -7
  18. package/abis/FeeEstimatorHook.json +1528 -0
  19. package/abis/HooksDeployment.json +23 -0
  20. package/abis/HooksTest.json +47 -0
  21. package/abis/ICoin.json +40 -71
  22. package/abis/ICoinV3.json +879 -0
  23. package/abis/ICoinV4.json +915 -0
  24. package/abis/IDeployedCoinVersionLookup.json +21 -0
  25. package/abis/IERC721.json +36 -36
  26. package/abis/IHasPoolKey.json +42 -0
  27. package/abis/IHasRewardsRecipients.json +54 -0
  28. package/abis/IHasSwapPath.json +60 -0
  29. package/abis/IMsgSender.json +15 -0
  30. package/abis/IPoolConfigEncoding.json +46 -0
  31. package/abis/ISwapPathRouter.json +92 -0
  32. package/abis/IUniversalRouter.json +61 -0
  33. package/abis/IUnlockCallback.json +21 -0
  34. package/abis/IV4Quoter.json +310 -0
  35. package/abis/IZoraFactory.json +191 -11
  36. package/abis/IZoraV4CoinHook.json +348 -4
  37. package/abis/MockERC20.json +21 -0
  38. package/abis/MultiOwnableTest.json +47 -0
  39. package/abis/{CoinConfigurationVersions.json → Position.json} +1 -1
  40. package/abis/PrintUpgradeCommand.json +9 -0
  41. package/abis/ProxyShim.json +24 -0
  42. package/abis/StateLibrary.json +80 -0
  43. package/abis/TestDeployedCoinVersionLookupImplementation.json +39 -0
  44. package/abis/TestV4Swap.json +9 -0
  45. package/abis/UpgradeCoinImpl.json +47 -0
  46. package/abis/UpgradesTest.json +67 -0
  47. package/abis/Vm.json +1482 -111
  48. package/abis/VmSafe.json +856 -32
  49. package/abis/ZoraFactoryImpl.json +339 -1
  50. package/abis/ZoraV4CoinHook.json +455 -5
  51. package/addresses/8453.json +8 -4
  52. package/addresses/84532.json +8 -4
  53. package/dist/index.cjs +1920 -169
  54. package/dist/index.cjs.map +1 -1
  55. package/dist/index.js +1916 -169
  56. package/dist/index.js.map +1 -1
  57. package/dist/wagmiGenerated.d.ts +2599 -183
  58. package/dist/wagmiGenerated.d.ts.map +1 -1
  59. package/package/wagmiGenerated.ts +1928 -165
  60. package/package.json +8 -3
  61. package/remappings.txt +6 -1
  62. package/script/CoinsDeployerBase.sol +74 -11
  63. package/script/DeployDevFactory.s.sol +21 -0
  64. package/script/PrintUpgradeCommand.s.sol +13 -0
  65. package/script/Simulate.s.sol +1 -10
  66. package/script/TestBackingCoinSwap.s.sol +146 -0
  67. package/script/TestV4Swap.s.sol +136 -0
  68. package/script/UpgradeFactoryImpl.s.sol +1 -1
  69. package/src/BaseCoin.sol +176 -0
  70. package/src/Coin.sol +87 -202
  71. package/src/CoinV4.sol +121 -0
  72. package/src/ZoraFactoryImpl.sol +208 -36
  73. package/src/hooks/ZoraV4CoinHook.sol +195 -0
  74. package/src/hooks/{BaseCoinDeployHook.sol → deployment/BaseCoinDeployHook.sol} +3 -3
  75. package/src/hooks/{BuySupplyWithSwapRouterHook.sol → deployment/BuySupplyWithSwapRouterHook.sol} +7 -5
  76. package/src/interfaces/ICoin.sol +31 -39
  77. package/src/interfaces/ICoinV3.sol +71 -0
  78. package/src/interfaces/ICoinV4.sol +69 -0
  79. package/src/interfaces/IDeployedCoinVersionLookup.sol +11 -0
  80. package/src/interfaces/IMsgSender.sol +9 -0
  81. package/src/interfaces/IPoolConfigEncoding.sol +14 -0
  82. package/src/interfaces/ISwapPathRouter.sol +14 -0
  83. package/src/interfaces/IZoraFactory.sol +65 -27
  84. package/src/interfaces/IZoraV4CoinHook.sol +116 -0
  85. package/src/libs/CoinCommon.sol +15 -0
  86. package/src/libs/CoinConfigurationVersions.sol +116 -1
  87. package/src/libs/CoinConstants.sol +5 -0
  88. package/src/libs/CoinDopplerMultiCurve.sol +134 -0
  89. package/src/libs/CoinDopplerUniV3.sol +19 -171
  90. package/src/libs/CoinRewards.sol +195 -0
  91. package/src/libs/CoinRewardsV4.sol +180 -0
  92. package/src/libs/CoinSetup.sol +57 -0
  93. package/src/libs/CoinSetupV3.sol +6 -67
  94. package/src/libs/DopplerMath.sol +156 -0
  95. package/src/libs/HooksDeployment.sol +84 -0
  96. package/src/libs/MarketConstants.sol +4 -0
  97. package/src/libs/PoolStateReader.sol +22 -0
  98. package/src/libs/UniV3BuySell.sol +74 -292
  99. package/src/libs/UniV4SwapHelper.sol +65 -0
  100. package/src/libs/UniV4SwapToCurrency.sol +109 -0
  101. package/src/libs/V4Liquidity.sol +129 -0
  102. package/src/types/PoolConfiguration.sol +15 -0
  103. package/src/utils/DeployedCoinVersionLookup.sol +52 -0
  104. package/src/version/ContractVersionBase.sol +1 -1
  105. package/test/Coin.t.sol +78 -88
  106. package/test/CoinDopplerUniV3.t.sol +32 -171
  107. package/test/CoinUniV4.t.sol +752 -0
  108. package/test/{Hooks.t.sol → DeploymentHooks.t.sol} +2 -6
  109. package/test/Factory.t.sol +80 -47
  110. package/test/MultiOwnable.t.sol +6 -3
  111. package/test/Upgrades.t.sol +6 -5
  112. package/test/mocks/MockERC20.sol +12 -0
  113. package/test/utils/BaseTest.sol +106 -56
  114. package/test/utils/DeployedCoinVersionLookup.t.sol +127 -0
  115. package/test/utils/FeeEstimatorHook.sol +84 -0
  116. package/test/utils/ProxyShim.sol +17 -0
  117. package/wagmi.config.ts +4 -0
  118. package/.env +0 -1
  119. package/.turbo/turbo-update-contract-version.log +0 -22
  120. package/abis/CoinSetupV3.json +0 -7
  121. package/abis/HookDeployer.json +0 -68
  122. package/abis/IHookDeployer.json +0 -42
  123. package/src/libs/CoinLegacy.sol +0 -48
  124. package/src/libs/CoinLegacyMarket.sol +0 -182
@@ -2,11 +2,13 @@
2
2
  pragma solidity ^0.8.23;
3
3
 
4
4
  import {BaseCoinDeployHook} from "./BaseCoinDeployHook.sol";
5
- import {ICoin} from "../interfaces/ICoin.sol";
6
- import {IZoraFactory} from "../interfaces/IZoraFactory.sol";
7
- import {ISwapRouter} from "../interfaces/ISwapRouter.sol";
8
- import {IWETH} from "../interfaces/IWETH.sol";
5
+ import {ICoin} from "../../interfaces/ICoin.sol";
6
+ import {IZoraFactory} from "../../interfaces/IZoraFactory.sol";
7
+ import {ISwapRouter} from "../../interfaces/ISwapRouter.sol";
8
+ import {IWETH} from "../../interfaces/IWETH.sol";
9
9
  import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
10
+ import {Coin} from "../../Coin.sol";
11
+ import {ICoinV3} from "../../interfaces/ICoinV3.sol";
10
12
 
11
13
  /// @title BuySupplyWithSwapRouter
12
14
  /// @notice A hook that buys supply for a coin that is priced in an erc20 token with ETH, using a Uniswap SwapRouter.
@@ -69,7 +71,7 @@ contract BuySupplyWithSwapRouterHook is BaseCoinDeployHook {
69
71
  function _handleBuy(address buyRecipient, ICoin coin, uint256 amountCurrency) internal returns (uint256 coinsPurchased) {
70
72
  IERC20(coin.currency()).approve(address(coin), amountCurrency);
71
73
 
72
- (, coinsPurchased) = coin.buy(buyRecipient, amountCurrency, 0, 0, address(0));
74
+ (, coinsPurchased) = ICoinV3(payable(address(coin))).buy(buyRecipient, amountCurrency, 0, 0, address(0));
73
75
 
74
76
  // make sure that this contract has no balance of the coin remaining
75
77
  uint256 coinBalance = IERC20(address(coin)).balanceOf(address(this));
@@ -4,18 +4,34 @@ pragma solidity ^0.8.23;
4
4
  import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
5
5
  import {IERC7572} from "./IERC7572.sol";
6
6
  import {IDopplerErrors} from "./IDopplerErrors.sol";
7
+ import {PoolKey} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
8
+ import {PoolConfiguration} from "../types/PoolConfiguration.sol";
7
9
 
8
- /// @notice The configuration of the pool
9
- /// @dev This is used to configure the pool's liquidity positions
10
- struct PoolConfiguration {
10
+ struct PoolConfigurationV4 {
11
11
  uint8 version;
12
- int24 tickLower;
13
- int24 tickUpper;
14
- uint16 numPositions;
15
- uint256 maxDiscoverySupplyShare;
12
+ PoolKey poolKey;
13
+ int24 tick;
16
14
  }
17
15
 
18
- interface ICoin is IERC165, IERC7572, IDopplerErrors {
16
+ struct PoolKeyStruct {
17
+ address currency0;
18
+ address currency1;
19
+ uint24 fee;
20
+ int24 tickSpacing;
21
+ address hooks;
22
+ }
23
+
24
+ interface IHasRewardsRecipients {
25
+ function payoutRecipient() external view returns (address);
26
+
27
+ function platformReferrer() external view returns (address);
28
+
29
+ function protocolRewardRecipient() external view returns (address);
30
+
31
+ function dopplerFeeRecipient() external view returns (address);
32
+ }
33
+
34
+ interface ICoin is IERC165, IERC7572, IDopplerErrors, IHasRewardsRecipients {
19
35
  /// @notice Thrown when an operation is attempted with a zero address
20
36
  error AddressZero();
21
37
 
@@ -73,6 +89,9 @@ interface ICoin is IERC165, IERC7572, IDopplerErrors {
73
89
  /// @notice Thrown when a Doppler pool does not have more than 2 discovery positions
74
90
  error DopplerPoolMustHaveMoreThan2DiscoveryPositions();
75
91
 
92
+ /// @notice Thrown when an invalid pool version is specified
93
+ error InvalidPoolVersion();
94
+
76
95
  /// @notice The rewards accrued from the market's liquidity position
77
96
  struct MarketRewards {
78
97
  uint256 totalAmountCurrency;
@@ -177,33 +196,6 @@ interface ICoin is IERC165, IERC7572, IDopplerErrors {
177
196
  /// @param name The coin name
178
197
  event ContractMetadataUpdated(address indexed caller, string newURI, string name);
179
198
 
180
- /// @notice Executes a buy order
181
- /// @param recipient The recipient address of the coins
182
- /// @param orderSize The amount of coins to buy
183
- /// @param tradeReferrer The address of the trade referrer
184
- /// @param sqrtPriceLimitX96 The price limit for Uniswap V3 pool swap
185
- function buy(
186
- address recipient,
187
- uint256 orderSize,
188
- uint256 minAmountOut,
189
- uint160 sqrtPriceLimitX96,
190
- address tradeReferrer
191
- ) external payable returns (uint256, uint256);
192
-
193
- /// @notice Executes a sell order
194
- /// @param recipient The recipient of the currency
195
- /// @param orderSize The amount of coins to sell
196
- /// @param minAmountOut The minimum amount of currency to receive
197
- /// @param sqrtPriceLimitX96 The price limit for the swap
198
- /// @param tradeReferrer The address of the trade referrer
199
- function sell(
200
- address recipient,
201
- uint256 orderSize,
202
- uint256 minAmountOut,
203
- uint160 sqrtPriceLimitX96,
204
- address tradeReferrer
205
- ) external returns (uint256, uint256);
206
-
207
199
  /// @notice Enables a user to burn their tokens
208
200
  /// @param amount The amount of tokens to burn
209
201
  function burn(uint256 amount) external;
@@ -212,11 +204,11 @@ interface ICoin is IERC165, IERC7572, IDopplerErrors {
212
204
  /// @return The token URI
213
205
  function tokenURI() external view returns (string memory);
214
206
 
215
- /// @notice Returns the address of the platform referrer
216
- /// @return The platform referrer's address
217
- function platformReferrer() external view returns (address);
218
-
219
207
  /// @notice Returns the address of the currency
220
208
  /// @return The currency's address
221
209
  function currency() external view returns (address);
210
+
211
+ /// @notice Returns the address of the Airlock
212
+ /// @return The Airlock's address
213
+ function airlock() external view returns (address);
222
214
  }
@@ -0,0 +1,71 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ import {ICoin} from "./ICoin.sol";
5
+ import {LpPosition} from "../types/LpPosition.sol";
6
+ import {PoolConfiguration} from "./ICoin.sol";
7
+
8
+ interface ICoinV3 is ICoin {
9
+ /// @notice Returns the WETH address
10
+ function WETH() external view returns (address);
11
+
12
+ /// @notice Returns the address of the Uniswap V3 factory
13
+ function v3Factory() external view returns (address);
14
+
15
+ /// @notice Initializes a new coin
16
+ /// @param payoutRecipient_ The address of the coin creator
17
+ /// @param tokenURI_ The metadata URI
18
+ /// @param name_ The coin name
19
+ /// @param symbol_ The coin symbol
20
+ /// @param platformReferrer_ The address of the platform referrer
21
+ /// @param currency_ The address of the currency
22
+ /// @param poolAddress_ The address of the pool
23
+ /// @param poolConfiguration_ The configuration of the pool
24
+ function initialize(
25
+ address payoutRecipient_,
26
+ address[] memory owners_,
27
+ string memory tokenURI_,
28
+ string memory name_,
29
+ string memory symbol_,
30
+ address platformReferrer_,
31
+ address currency_,
32
+ address poolAddress_,
33
+ PoolConfiguration memory poolConfiguration_,
34
+ LpPosition[] memory positions_
35
+ ) external;
36
+
37
+ /// @notice Executes a buy order
38
+ /// @param recipient The recipient address of the coins
39
+ /// @param orderSize The amount of coins to buy
40
+ /// @param tradeReferrer The address of the trade referrer
41
+ /// @param sqrtPriceLimitX96 The price limit for Uniswap V3 pool swap
42
+ function buy(
43
+ address recipient,
44
+ uint256 orderSize,
45
+ uint256 minAmountOut,
46
+ uint160 sqrtPriceLimitX96,
47
+ address tradeReferrer
48
+ ) external payable returns (uint256, uint256);
49
+
50
+ /// @notice Executes a sell order
51
+ /// @param recipient The recipient of the currency
52
+ /// @param orderSize The amount of coins to sell
53
+ /// @param minAmountOut The minimum amount of currency to receive
54
+ /// @param sqrtPriceLimitX96 The price limit for the swap
55
+ /// @param tradeReferrer The address of the trade referrer
56
+ function sell(
57
+ address recipient,
58
+ uint256 orderSize,
59
+ uint256 minAmountOut,
60
+ uint160 sqrtPriceLimitX96,
61
+ address tradeReferrer
62
+ ) external returns (uint256, uint256);
63
+
64
+ /// @notice Force claim any accrued secondary rewards from the market's liquidity position.
65
+ /// @dev This function is a fallback, secondary rewards will be claimed automatically on each buy and sell.
66
+ /// @param pushEthRewards Whether to push the ETH directly to the recipients.
67
+ function claimSecondaryRewards(bool pushEthRewards) external;
68
+
69
+ /// @notice Returns the address of the Uniswap V3 pool
70
+ function poolAddress() external view returns (address);
71
+ }
@@ -0,0 +1,69 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ import {ICoin} from "./ICoin.sol";
5
+ import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
6
+ import {PoolConfiguration} from "../types/PoolConfiguration.sol";
7
+ import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol";
8
+ import {PathKey} from "@uniswap/v4-periphery/src/libraries/PathKey.sol";
9
+ import {Currency} from "@uniswap/v4-core/src/types/Currency.sol";
10
+ import {IDeployedCoinVersionLookup} from "./IDeployedCoinVersionLookup.sol";
11
+
12
+ /// @notice Returns the pool key for the coin
13
+ interface IHasPoolKey {
14
+ /// @notice Returns the Uniswap V4 pool key associated with this coin
15
+ /// @return The PoolKey struct containing pool identification parameters
16
+ function getPoolKey() external view returns (PoolKey memory);
17
+ }
18
+
19
+ /// @notice Returns the pool configuration for the coin
20
+ interface IHasSwapPath {
21
+ /// @notice Struct containing the swap path configuration for converting fees to payout currency
22
+ /// @param path Array of PathKey structs defining the multi-hop swap route
23
+ /// @param currencyIn The input currency to start the swap path from
24
+ struct PayoutSwapPath {
25
+ PathKey[] path;
26
+ Currency currencyIn;
27
+ }
28
+
29
+ /// @notice Returns the swap path configuration for converting this coin to its final payout currency
30
+ /// @dev This enables multi-hop swaps through intermediate currencies to reach the target payout token
31
+ /// @param coinVersionLookup Contract for looking up deployed coin versions to build recursive paths
32
+ /// @return PayoutSwapPath struct containing the complete swap route configuration
33
+ function getPayoutSwapPath(IDeployedCoinVersionLookup coinVersionLookup) external view returns (PayoutSwapPath memory);
34
+ }
35
+
36
+ interface ICoinV4 is ICoin, IHasPoolKey, IHasSwapPath {
37
+ /// @notice Returns the pool configuration settings for this coin's Uniswap V4 pool
38
+ /// @return PoolConfiguration struct containing pool-specific settings and parameters
39
+ function getPoolConfiguration() external view returns (PoolConfiguration memory);
40
+
41
+ /// @notice Returns the hooks contract used by this coin's Uniswap V4 pool
42
+ /// @return The IHooks contract interface that handles pool lifecycle events
43
+ function hooks() external view returns (IHooks);
44
+
45
+ /// @notice Initializes the coin
46
+ /// @dev Called by the factory contract when the contract is deployed.
47
+ /// @param payoutRecipient_ The address of the payout recipient. Can be updated by the owner. Cannot be 0 address.
48
+ /// @param owners_ The addresses of the owners. All owners have the same full admin access. Cannot be 0 address.
49
+ /// @param tokenURI_ The URI of the token. Can be updated by the owner.
50
+ /// @param name_ The name of the token. Cannot be updated.
51
+ /// @param symbol_ The symbol of the token. Cannot be updated.
52
+ /// @param platformReferrer_ The address of the platform referrer. Cannot be updated.
53
+ /// @param currency_ The currency of the coin. Cannot be updated. Can be the zero address for ETH.
54
+ /// @param poolKey_ The pool key for the coin. Derived in the factory.
55
+ /// @param sqrtPriceX96 The initial sqrt price for the pool
56
+ /// @param poolConfiguration_ The configuration for the pool
57
+ function initialize(
58
+ address payoutRecipient_,
59
+ address[] memory owners_,
60
+ string memory tokenURI_,
61
+ string memory name_,
62
+ string memory symbol_,
63
+ address platformReferrer_,
64
+ address currency_,
65
+ PoolKey memory poolKey_,
66
+ uint160 sqrtPriceX96,
67
+ PoolConfiguration memory poolConfiguration_
68
+ ) external;
69
+ }
@@ -0,0 +1,11 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ /// @title IDeployedCoinVersionLookup
5
+ /// @notice Interface for querying the version of a deployed coin
6
+ interface IDeployedCoinVersionLookup {
7
+ /// @notice Gets the version for a deployed coin
8
+ /// @param coin The address of the coin
9
+ /// @return version The version of the coin (0 if not found)
10
+ function getVersionForDeployedCoin(address coin) external view returns (uint8);
11
+ }
@@ -0,0 +1,9 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ /// @notice Interface for getting the correct message sender.
5
+ interface IMsgSender {
6
+ /// @notice Returns the address of the message sender.
7
+ /// @return The address of the message sender.
8
+ function msgSender() external view returns (address);
9
+ }
@@ -0,0 +1,14 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ /// @dev contract to enable encoding pool config from the client
5
+ interface IPoolConfigEncoding {
6
+ function encodeMultiCurvePoolConfig(
7
+ uint8 version,
8
+ address currency,
9
+ int24[] memory tickLower,
10
+ int24[] memory tickUpper,
11
+ uint16[] memory numDiscoveryPositions,
12
+ uint256[] memory maxDiscoverySupplyShare
13
+ ) external pure returns (bytes memory);
14
+ }
@@ -0,0 +1,14 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.25;
3
+
4
+ import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
5
+ import {Currency} from "@uniswap/v4-core/src/types/Currency.sol";
6
+
7
+ interface ISwapPathRouter {
8
+ struct Path {
9
+ PoolKey key;
10
+ Currency currencyIn;
11
+ }
12
+
13
+ function getSwapPath(PoolKey memory key, Currency toSwapOut) external view returns (Path[] memory path);
14
+ }
@@ -1,6 +1,9 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity ^0.8.23;
3
3
 
4
+ import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
5
+ import {PoolKeyStruct} from "./ICoin.sol";
6
+
4
7
  interface IZoraFactory {
5
8
  /// @notice Emitted when a coin is created
6
9
  /// @param caller The msg.sender address
@@ -26,21 +29,51 @@ interface IZoraFactory {
26
29
  string version
27
30
  );
28
31
 
32
+ /// @notice Emitted when a coin is created
33
+ /// @param caller The msg.sender address
34
+ /// @param payoutRecipient The address of the creator payout recipient
35
+ /// @param platformReferrer The address of the platform referrer
36
+ /// @param currency The address of the currency
37
+ /// @param uri The URI of the coin
38
+ /// @param name The name of the coin
39
+ /// @param symbol The symbol of the coin
40
+ /// @param coin The address of the coin
41
+ /// @param poolKey The uniswap v4 pool key
42
+ /// @param version The coin contract version
43
+ event CoinCreatedV4(
44
+ address indexed caller,
45
+ address indexed payoutRecipient,
46
+ address indexed platformReferrer,
47
+ address currency,
48
+ string uri,
49
+ string name,
50
+ string symbol,
51
+ address coin,
52
+ PoolKey poolKey,
53
+ bytes32 poolKeyHash,
54
+ string version
55
+ );
56
+
29
57
  /// @notice Thrown when the amount of ERC20 tokens transferred does not match the expected amount
30
58
  error ERC20TransferAmountMismatch();
31
59
 
32
60
  /// @notice Thrown when ETH is sent with a transaction but the currency is not WETH
33
61
  error EthTransferInvalid();
34
62
 
35
- /// @notice Creates a new coin contract
63
+ /// @notice Creates a new coin contract with an optional hook that runs after the coin is deployed.
64
+ /// Requires a salt to be specified, which enabled the coin to be deployed deterministically, and at
65
+ /// a predictable address.
36
66
  /// @param payoutRecipient The recipient of creator reward payouts; this can be updated by an owner
37
67
  /// @param owners The list of addresses that will be able to manage the coin's payout address and metadata uri
38
68
  /// @param uri The coin metadata uri
39
69
  /// @param name The name of the coin
40
70
  /// @param symbol The symbol of the coin
41
- /// @param poolConfig The config parameters for the Uniswap v3 pool; `abi.encode(address currency, int24 tickLower, int24 tickUpper, uint16 numDiscoveryPositions, uint256 maxDiscoverySupplyShare)`
71
+ /// @param poolConfig The config parameters for the coin's pool
42
72
  /// @param platformReferrer The address of the platform referrer
43
- /// @param orderSize The order size for the first buy; must match msg.value for ETH/WETH pairs
73
+ /// @param postDeployHook The address of the hook to run after the coin is deployed
74
+ /// @param postDeployHookData The data to pass to the hook
75
+ /// @return coin The address of the deployed coin
76
+ /// @return postDeployHookDataOut The data returned by the hook
44
77
  function deploy(
45
78
  address payoutRecipient,
46
79
  address[] memory owners,
@@ -49,43 +82,41 @@ interface IZoraFactory {
49
82
  string memory symbol,
50
83
  bytes memory poolConfig,
51
84
  address platformReferrer,
52
- uint256 orderSize
53
- ) external payable returns (address, uint256);
85
+ address postDeployHook,
86
+ bytes calldata postDeployHookData,
87
+ bytes32 coinSalt
88
+ ) external payable returns (address coin, bytes memory postDeployHookDataOut);
54
89
 
55
- /// @notice Creates a new coin contract
56
- /// @param payoutRecipient The recipient of creator reward payouts; this can be updated by an owner
57
- /// @param owners The list of addresses that will be able to manage the coin's payout address and metadata uri
58
- /// @param uri The coin metadata uri
90
+ /// @notice Predicts the address of a coin contract that will be deployed with the given parameters
91
+ /// @param msgSender The address of the msg.sender
59
92
  /// @param name The name of the coin
60
93
  /// @param symbol The symbol of the coin
61
- /// @param platformReferrer The address to receive platform referral rewards
62
- /// @param currency The address of the trading currency; address(0) for ETH/WETH
63
- /// @param tickLower The lower tick for the Uniswap V3 LP position; ignored for ETH/WETH pairs
64
- /// @param orderSize The order size for the first buy; must match msg.value for ETH/WETH pairs
94
+ /// @param poolConfig The pool config
95
+ /// @param platformReferrer The platform referrer
96
+ /// @param coinSalt The salt used to deploy the coin
97
+ /// @return The address of the coin contract
98
+ function coinAddress(
99
+ address msgSender,
100
+ string memory name,
101
+ string memory symbol,
102
+ bytes memory poolConfig,
103
+ address platformReferrer,
104
+ bytes32 coinSalt
105
+ ) external view returns (address);
106
+
107
+ /// @dev Deprecated: use `deploy` instead that has a salt and hook specified
65
108
  function deploy(
66
109
  address payoutRecipient,
67
110
  address[] memory owners,
68
111
  string memory uri,
69
112
  string memory name,
70
113
  string memory symbol,
114
+ bytes memory poolConfig,
71
115
  address platformReferrer,
72
- address currency,
73
- int24 tickLower,
74
116
  uint256 orderSize
75
117
  ) external payable returns (address, uint256);
76
118
 
77
- /// @notice Creates a new coin contract with an optional hook that runs after the coin is deployed
78
- /// @param payoutRecipient The recipient of creator reward payouts; this can be updated by an owner
79
- /// @param owners The list of addresses that will be able to manage the coin's payout address and metadata uri
80
- /// @param uri The coin metadata uri
81
- /// @param name The name of the coin
82
- /// @param symbol The symbol of the coin
83
- /// @param poolConfig The config parameters for the Uniswap v3 pool; `abi.encode(address currency, int24 tickLower, int24 tickUpper, uint16 numDiscoveryPositions, uint256 maxDiscoverySupplyShare)`
84
- /// @param platformReferrer The address of the platform referrer
85
- /// @param hook The address of the hook to run after the coin is deployed
86
- /// @param hookData The data to pass to the hook
87
- /// @return coin The address of the deployed coin
88
- /// @return hookDataOut The data returned by the hook
119
+ /// @dev Deprecated: use `deploy` instead that has a salt and hook specified
89
120
  function deployWithHook(
90
121
  address payoutRecipient,
91
122
  address[] memory owners,
@@ -98,6 +129,10 @@ interface IZoraFactory {
98
129
  bytes calldata hookData
99
130
  ) external payable returns (address coin, bytes memory hookDataOut);
100
131
 
132
+ function coinImpl() external view returns (address);
133
+
134
+ function implementation() external view returns (address);
135
+
101
136
  /// @notice Thrown when the hook is invalid
102
137
  error InvalidHook();
103
138
 
@@ -105,4 +140,7 @@ interface IZoraFactory {
105
140
  /// @param currentName The name of the current contract
106
141
  /// @param newName The name of the contract being upgraded to
107
142
  error UpgradeToMismatchedContractName(string currentName, string newName);
143
+
144
+ /// @notice Thrown when a method is deprecated
145
+ error Deprecated();
108
146
  }
@@ -0,0 +1,116 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
5
+ import {SwapParams} from "@uniswap/v4-core/src/types/PoolOperation.sol";
6
+ import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol";
7
+ import {LpPosition} from "../types/LpPosition.sol";
8
+ import {ICoin} from "./ICoin.sol";
9
+
10
+ interface IZoraV4CoinHook {
11
+ /// @notice Emitted when a swap is executed.
12
+ /// @param sender The address of the sender.
13
+ /// @param swapSender The address of the swap sender.
14
+ /// @param isTrustedSwapSenderAddress Whether the swap sender is a trusted address. (Based on a registry of trusted addresses)
15
+ /// @param key The pool key struct to identify the pool.
16
+ /// @param poolKeyHash The hash of the pool key for indexing.
17
+ /// @param params The swap parameters.
18
+ /// @param amount0 The amount of token0.
19
+ /// @param amount1 The amount of token1.
20
+ /// @param isCoinBuy Whether the swap is a coin buy.
21
+ /// @param hookData The data passed into the hook for the swap.
22
+ event Swapped(
23
+ address indexed sender,
24
+ address indexed swapSender,
25
+ bool isTrustedSwapSenderAddress,
26
+ PoolKey key,
27
+ bytes32 indexed poolKeyHash,
28
+ SwapParams params,
29
+ int128 amount0,
30
+ int128 amount1,
31
+ bool isCoinBuy,
32
+ bytes hookData,
33
+ uint160 sqrtPriceX96
34
+ );
35
+
36
+ /// @notice Thrown when a non-coin is used to initialize a pool with this hook.
37
+ /// @param coin The address of the coin.
38
+ error NotACoin(address coin);
39
+
40
+ /// @notice Coin version lookup cannot be the zero address.
41
+ error CoinVersionLookupCannotBeZeroAddress();
42
+
43
+ /// @notice Thrown when a pool is not initialized for the hook.
44
+ /// @param key The pool key struct to identify the pool.
45
+ error NoCoinForHook(PoolKey key);
46
+
47
+ /// @notice Thrown when a attempting to swap with a path that has no steps.
48
+ error PathMustHaveAtLeastOneStep();
49
+
50
+ /// @notice The pool coin struct. Lists all the contract-created positions for the coin.
51
+ struct PoolCoin {
52
+ /// @notice The address of the coin.
53
+ address coin;
54
+ /// @notice The positions of the pool coin.
55
+ LpPosition[] positions;
56
+ }
57
+
58
+ /// @notice The rewards accrued from the market's liquidity position
59
+ /// @param creatorPayoutAmountCurrency The amount of currency payed out to the creator
60
+ /// @param creatorPayoutAmountCoin The amount of coin payed out to the creator
61
+ /// @param platformReferrerAmountCurrency The amount of currency payed out to the platform referrer
62
+ /// @param platformReferrerAmountCoin The amount of coin payed out to the platform referrer
63
+ /// @param tradeReferrerAmountCurrency The amount of currency payed out to the trade referrer
64
+ /// @param tradeReferrerAmountCoin The amount of coin to pay to the trade referrer
65
+ /// @param protocolAmountCurrency The amount of currency to pay to the protocol
66
+ /// @param protocolAmountCoin The amount of coin to pay to the protocol
67
+ /// @param dopplerAmountCurrency The amount of currency to pay to doppler
68
+ /// @param dopplerAmountCoin The amount of coin to pay to doppler
69
+ struct MarketRewardsV4 {
70
+ uint256 creatorPayoutAmountCurrency;
71
+ uint256 creatorPayoutAmountCoin;
72
+ uint256 platformReferrerAmountCurrency;
73
+ uint256 platformReferrerAmountCoin;
74
+ uint256 tradeReferrerAmountCurrency;
75
+ uint256 tradeReferrerAmountCoin;
76
+ uint256 protocolAmountCurrency;
77
+ uint256 protocolAmountCoin;
78
+ uint256 dopplerAmountCurrency;
79
+ uint256 dopplerAmountCoin;
80
+ }
81
+
82
+ /// @notice Emitted when market rewards are distributed
83
+ /// @param coin The address of the coin
84
+ /// @param currency The address of the currency
85
+ /// @param payoutRecipient The address of the creator rewards payout recipient
86
+ /// @param platformReferrer The address of the platform referrer
87
+ /// @param protocolRewardRecipient The address of the protocol reward recipient
88
+ /// @param dopplerRecipient The address of the doppler recipient
89
+ /// @param tradeReferrer The address of the trade referrer
90
+ /// @param marketRewards The rewards accrued from the market's liquidity position
91
+ event CoinMarketRewardsV4(
92
+ address coin,
93
+ address currency,
94
+ address payoutRecipient,
95
+ address platformReferrer,
96
+ address tradeReferrer,
97
+ address protocolRewardRecipient,
98
+ address dopplerRecipient,
99
+ MarketRewardsV4 marketRewards
100
+ );
101
+
102
+ /// @notice Returns the pool coin for a given pool key hash.
103
+ /// @param poolKeyHash The hash of the pool key for indexing.
104
+ /// @return poolCoin The pool coin confirmation data.
105
+ function getPoolCoinByHash(bytes23 poolKeyHash) external view returns (IZoraV4CoinHook.PoolCoin memory);
106
+
107
+ /// @notice Returns the pool coin for a given pool key.
108
+ /// @param key The pool key.
109
+ /// @return poolCoin The pool coin confirmation data.
110
+ function getPoolCoin(PoolKey memory key) external view returns (IZoraV4CoinHook.PoolCoin memory);
111
+
112
+ /// @notice Returns whether the sender is a trusted message sender.
113
+ /// @param sender The address of the sender.
114
+ /// @return isTrusted Whether the sender is a trusted message sender.
115
+ function isTrustedMessageSender(address sender) external view returns (bool);
116
+ }
@@ -0,0 +1,15 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
5
+
6
+ library CoinCommon {
7
+ // Helper function to sort tokens and determine if coin is token0
8
+ function sortTokens(address coin, address currency) internal pure returns (bool isCoinToken0) {
9
+ return coin < currency;
10
+ }
11
+
12
+ function hashPoolKey(PoolKey memory key) internal pure returns (bytes32) {
13
+ return keccak256(abi.encode(key));
14
+ }
15
+ }