@zoralabs/coins 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/.turbo/turbo-build.log +76 -0
  2. package/CHANGELOG.md +14 -0
  3. package/LICENSE +21 -0
  4. package/abis/Address.json +29 -0
  5. package/abis/BaseTest.json +691 -0
  6. package/abis/Clones.json +7 -0
  7. package/abis/Coin.json +1693 -0
  8. package/abis/CoinConstants.json +93 -0
  9. package/abis/CoinTest.json +998 -0
  10. package/abis/ContextUpgradeable.json +25 -0
  11. package/abis/ContractVersionBase.json +15 -0
  12. package/abis/Deploy.json +29 -0
  13. package/abis/ECDSA.json +29 -0
  14. package/abis/EIP712.json +67 -0
  15. package/abis/EIP712Upgradeable.json +74 -0
  16. package/abis/ERC1967Proxy.json +67 -0
  17. package/abis/ERC1967Utils.json +85 -0
  18. package/abis/ERC20PermitUpgradeable.json +527 -0
  19. package/abis/ERC20Upgradeable.json +333 -0
  20. package/abis/FactoryTest.json +845 -0
  21. package/abis/IBeacon.json +15 -0
  22. package/abis/ICoin.json +541 -0
  23. package/abis/ICoinComments.json +53 -0
  24. package/abis/IERC1155Errors.json +104 -0
  25. package/abis/IERC165.json +21 -0
  26. package/abis/IERC1822Proxiable.json +15 -0
  27. package/abis/IERC20.json +221 -0
  28. package/abis/IERC20Errors.json +88 -0
  29. package/abis/IERC20Metadata.json +224 -0
  30. package/abis/IERC20Permit.json +77 -0
  31. package/abis/IERC5267.json +51 -0
  32. package/abis/IERC721.json +287 -0
  33. package/abis/IERC721Enumerable.json +343 -0
  34. package/abis/IERC721Errors.json +105 -0
  35. package/abis/IERC721Metadata.json +332 -0
  36. package/abis/IERC721Receiver.json +36 -0
  37. package/abis/IERC721TokenReceiver.json +36 -0
  38. package/abis/IERC7572.json +21 -0
  39. package/abis/IMulticall3.json +440 -0
  40. package/abis/INonfungiblePositionManager.json +366 -0
  41. package/abis/IProtocolRewards.json +348 -0
  42. package/abis/ISwapRouter.json +137 -0
  43. package/abis/IUniswapV3Pool.json +148 -0
  44. package/abis/IUniswapV3SwapCallback.json +25 -0
  45. package/abis/IVersionedContract.json +15 -0
  46. package/abis/IWETH.json +118 -0
  47. package/abis/IZoraFactory.json +138 -0
  48. package/abis/Initializable.json +25 -0
  49. package/abis/Math.json +7 -0
  50. package/abis/MockERC20.json +322 -0
  51. package/abis/MockERC721.json +350 -0
  52. package/abis/MultiOwnable.json +171 -0
  53. package/abis/MultiOwnableTest.json +796 -0
  54. package/abis/NoncesUpgradeable.json +60 -0
  55. package/abis/OwnableUpgradeable.json +99 -0
  56. package/abis/ProtocolRewards.json +494 -0
  57. package/abis/Proxy.json +6 -0
  58. package/abis/ReentrancyGuardUpgradeable.json +30 -0
  59. package/abis/SafeERC20.json +34 -0
  60. package/abis/Script.json +15 -0
  61. package/abis/ShortStrings.json +18 -0
  62. package/abis/StdAssertions.json +379 -0
  63. package/abis/StdInvariant.json +180 -0
  64. package/abis/Strings.json +18 -0
  65. package/abis/Test.json +570 -0
  66. package/abis/UUPSUpgradeable.json +130 -0
  67. package/abis/Vm.json +8627 -0
  68. package/abis/VmSafe.json +7297 -0
  69. package/abis/ZoraFactory.json +67 -0
  70. package/abis/ZoraFactoryImpl.json +422 -0
  71. package/abis/stdError.json +119 -0
  72. package/abis/stdStorageSafe.json +52 -0
  73. package/addresses/1.json +4 -0
  74. package/addresses/8453.json +9 -0
  75. package/addresses/84532.json +9 -0
  76. package/dist/index.cjs +1236 -0
  77. package/dist/index.cjs.map +1 -0
  78. package/dist/index.d.ts +2 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +1208 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/wagmiGenerated.d.ts +1645 -0
  83. package/dist/wagmiGenerated.d.ts.map +1 -0
  84. package/foundry.toml +9 -0
  85. package/package/index.ts +1 -0
  86. package/package/wagmiGenerated.ts +1211 -0
  87. package/package.json +48 -0
  88. package/remappings.txt +4 -0
  89. package/script/Deploy.s.sol +14 -0
  90. package/slither.config.json +6 -0
  91. package/src/Coin.sol +579 -0
  92. package/src/ZoraFactoryImpl.sol +142 -0
  93. package/src/interfaces/ICoin.sol +194 -0
  94. package/src/interfaces/ICoinComments.sol +8 -0
  95. package/src/interfaces/IERC7572.sol +12 -0
  96. package/src/interfaces/INonfungiblePositionManager.sol +104 -0
  97. package/src/interfaces/IProtocolRewards.sol +12 -0
  98. package/src/interfaces/ISwapRouter.sol +38 -0
  99. package/src/interfaces/IUniswapV3Pool.sol +43 -0
  100. package/src/interfaces/IUniswapV3SwapCallback.sol +17 -0
  101. package/src/interfaces/IWETH.sol +16 -0
  102. package/src/interfaces/IZoraFactory.sol +56 -0
  103. package/src/proxy/ZoraFactory.sol +26 -0
  104. package/src/utils/CoinConstants.sol +67 -0
  105. package/src/utils/MultiOwnable.sol +126 -0
  106. package/src/utils/TickMath.sol +210 -0
  107. package/src/version/ContractVersionBase.sol +14 -0
  108. package/test/Coin.t.sol +443 -0
  109. package/test/Factory.t.sol +298 -0
  110. package/test/MultiOwnable.t.sol +156 -0
  111. package/test/utils/BaseTest.sol +178 -0
  112. package/test/utils/ProtocolRewards.sol +1499 -0
  113. package/tsconfig.build.json +10 -0
  114. package/tsconfig.json +9 -0
  115. package/tsup.config.ts +11 -0
  116. package/wagmi.config.ts +16 -0
@@ -0,0 +1,142 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
5
+ import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
6
+ import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
7
+ import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
8
+ import {ERC1967Utils} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";
9
+ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
10
+ import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
11
+
12
+ import {IZoraFactory} from "./interfaces/IZoraFactory.sol";
13
+ import {Coin} from "./Coin.sol";
14
+
15
+ contract ZoraFactoryImpl is IZoraFactory, UUPSUpgradeable, ReentrancyGuardUpgradeable, OwnableUpgradeable {
16
+ using SafeERC20 for IERC20;
17
+
18
+ /// @notice The coin contract implementation address
19
+ address public immutable coinImpl;
20
+
21
+ constructor(address _coinImpl) initializer {
22
+ coinImpl = _coinImpl;
23
+ }
24
+
25
+ /// @notice Creates a new coin contract
26
+ /// @param payoutRecipient The recipient of creator reward payouts; this can be updated by an owner
27
+ /// @param owners The list of addresses that will be able to manage the coin's payout address and metadata uri
28
+ /// @param uri The coin metadata uri
29
+ /// @param name The name of the coin
30
+ /// @param symbol The symbol of the coin
31
+ /// @param platformReferrer The address to receive platform referral rewards
32
+ /// @param currency The address of the trading currency; address(0) for ETH/WETH
33
+ /// @param tickLower The lower tick for the Uniswap V3 LP position; ignored for ETH/WETH pairs
34
+ /// @param orderSize The order size for the first buy; must match msg.value for ETH/WETH pairs
35
+ function deploy(
36
+ address payoutRecipient,
37
+ address[] memory owners,
38
+ string memory uri,
39
+ string memory name,
40
+ string memory symbol,
41
+ address platformReferrer,
42
+ address currency,
43
+ int24 tickLower,
44
+ uint256 orderSize
45
+ ) public payable nonReentrant returns (address) {
46
+ bytes32 salt = _generateSalt(payoutRecipient, uri);
47
+
48
+ Coin coin = Coin(payable(Clones.cloneDeterministic(coinImpl, salt)));
49
+
50
+ coin.initialize(payoutRecipient, owners, uri, name, symbol, platformReferrer, currency, tickLower);
51
+
52
+ _handleFirstOrder(coin, orderSize);
53
+
54
+ emit CoinCreated(
55
+ msg.sender,
56
+ payoutRecipient,
57
+ payoutRecipient,
58
+ coin.platformReferrer(),
59
+ coin.currency(),
60
+ uri,
61
+ name,
62
+ symbol,
63
+ address(coin),
64
+ coin.poolAddress()
65
+ );
66
+
67
+ return address(coin);
68
+ }
69
+
70
+ /// @dev Generates a unique salt for deterministic deployment
71
+ function _generateSalt(address _creator, string memory _tokenURI) internal view returns (bytes32) {
72
+ return
73
+ keccak256(
74
+ abi.encodePacked(
75
+ msg.sender,
76
+ _creator,
77
+ keccak256(abi.encodePacked(_tokenURI)),
78
+ block.coinbase,
79
+ block.number,
80
+ block.prevrandao,
81
+ block.timestamp,
82
+ tx.gasprice,
83
+ tx.origin
84
+ )
85
+ );
86
+ }
87
+
88
+ /// @dev Handles the first buy of a newly created coin
89
+ /// @param coin The newly created coin contract
90
+ /// @param orderSize The size of the first buy order; must match msg.value for ETH/WETH pairs
91
+ function _handleFirstOrder(Coin coin, uint256 orderSize) internal {
92
+ if (msg.value > 0 || orderSize > 0) {
93
+ address currency = coin.currency();
94
+ address payoutRecipient = coin.payoutRecipient();
95
+
96
+ if (currency != coin.WETH()) {
97
+ if (msg.value != 0) {
98
+ revert EthTransferInvalid();
99
+ }
100
+
101
+ _handleIncomingCurrency(currency, orderSize);
102
+
103
+ IERC20(currency).approve(address(coin), orderSize);
104
+
105
+ coin.buy(payoutRecipient, orderSize, 0, 0, address(0));
106
+ } else {
107
+ coin.buy{value: msg.value}(payoutRecipient, orderSize, 0, 0, address(0));
108
+ }
109
+ }
110
+ }
111
+
112
+ /// @dev Safely transfers ERC20 tokens from the caller to this contract to be sent to the newly created coin
113
+ /// @param currency The ERC20 token address to transfer
114
+ /// @param orderSize The amount of tokens to transfer for the order
115
+ function _handleIncomingCurrency(address currency, uint256 orderSize) internal {
116
+ uint256 beforeBalance = IERC20(currency).balanceOf(address(this));
117
+ IERC20(currency).safeTransferFrom(msg.sender, address(this), orderSize);
118
+ uint256 afterBalance = IERC20(currency).balanceOf(address(this));
119
+
120
+ if ((afterBalance - beforeBalance) != orderSize) {
121
+ revert ERC20TransferAmountMismatch();
122
+ }
123
+ }
124
+
125
+ /// @notice Initializes the factory proxy contract
126
+ /// @param initialOwner Address of the contract owner
127
+ /// @dev Can only be called once due to initializer modifier
128
+ function initialize(address initialOwner) external initializer {
129
+ __UUPSUpgradeable_init();
130
+ __ReentrancyGuard_init();
131
+ __Ownable_init(initialOwner);
132
+ }
133
+
134
+ /// @notice The implementation address of the factory contract
135
+ function implementation() external view returns (address) {
136
+ return ERC1967Utils.getImplementation();
137
+ }
138
+
139
+ /// @dev Authorizes an upgrade to a new implementation
140
+ /// @param newImpl The new implementation address
141
+ function _authorizeUpgrade(address newImpl) internal override onlyOwner {}
142
+ }
@@ -0,0 +1,194 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ interface ICoin {
5
+ /// @notice Thrown when an operation is attempted with a zero address
6
+ error AddressZero();
7
+
8
+ /// @notice Thrown when an invalid market type is specified
9
+ error InvalidMarketType();
10
+
11
+ /// @notice Thrown when there are insufficient funds for an operation
12
+ error InsufficientFunds();
13
+
14
+ /// @notice Thrown when there is insufficient liquidity for a transaction
15
+ error InsufficientLiquidity();
16
+
17
+ /// @notice Thrown when the slippage bounds are exceeded during a transaction
18
+ error SlippageBoundsExceeded();
19
+
20
+ /// @notice Thrown when the initial order size is too large
21
+ error InitialOrderSizeTooLarge();
22
+
23
+ /// @notice Thrown when the msg.value amount does not match the amount of currency sent
24
+ error EthAmountMismatch();
25
+
26
+ /// @notice Thrown when the ETH amount is too small for a transaction
27
+ error EthAmountTooSmall();
28
+
29
+ /// @notice Thrown when the expected amount of ERC20s transferred does not match the amount received
30
+ error ERC20TransferAmountMismatch();
31
+
32
+ /// @notice Thrown when ETH is sent with a buy or sell but the currency is not WETH
33
+ error EthTransferInvalid();
34
+
35
+ /// @notice Thrown when an ETH transfer fails
36
+ error EthTransferFailed();
37
+
38
+ /// @notice Thrown when an operation is attempted by an entity other than the pool
39
+ error OnlyPool();
40
+
41
+ /// @notice Thrown when an operation is attempted by an entity other than WETH
42
+ error OnlyWeth();
43
+
44
+ /// @notice Thrown when a market is not yet graduated
45
+ error MarketNotGraduated();
46
+
47
+ /// @notice Thrown when a market is already graduated
48
+ error MarketAlreadyGraduated();
49
+
50
+ /// @notice Thrown when the lower tick is not less than the maximum tick or not a multiple of 200
51
+ error InvalidCurrencyLowerTick();
52
+
53
+ /// @notice Thrown when the lower tick is not set to the default value
54
+ error InvalidWethLowerTick();
55
+
56
+ /// @notice The rewards accrued from the market's liquidity position
57
+ struct MarketRewards {
58
+ uint256 totalAmountCurrency;
59
+ uint256 totalAmountCoin;
60
+ uint256 creatorPayoutAmountCurrency;
61
+ uint256 creatorPayoutAmountCoin;
62
+ uint256 platformReferrerAmountCurrency;
63
+ uint256 platformReferrerAmountCoin;
64
+ uint256 protocolAmountCurrency;
65
+ uint256 protocolAmountCoin;
66
+ }
67
+
68
+ /// @notice Emitted when market rewards are distributed
69
+ /// @param creatorPayoutAddress The address of the creator payout recipient
70
+ /// @param platformReferrer The address of the platform referrer
71
+ /// @param protocolRewardRecipient The address of the protocol reward recipient
72
+ /// @param currency The address of the currency
73
+ /// @param marketRewards The rewards accrued from the market's liquidity position
74
+ event CoinMarketRewards(
75
+ address indexed creatorPayoutAddress,
76
+ address indexed platformReferrer,
77
+ address protocolRewardRecipient,
78
+ address currency,
79
+ MarketRewards marketRewards
80
+ );
81
+
82
+ /// @notice Emitted when coins are bought
83
+ /// @param buyer The address of the buyer
84
+ /// @param recipient The address of the recipient
85
+ /// @param tradeReferrer The address of the trade referrer
86
+ /// @param coinsPurchased The number of coins purchased
87
+ /// @param currency The address of the currency
88
+ /// @param amountFee The fee for the purchase
89
+ /// @param amountSold The amount of the currency sold
90
+ event CoinBuy(
91
+ address indexed buyer,
92
+ address indexed recipient,
93
+ address indexed tradeReferrer,
94
+ uint256 coinsPurchased,
95
+ address currency,
96
+ uint256 amountFee,
97
+ uint256 amountSold,
98
+ string comment // TODO remove after backend approval
99
+ );
100
+
101
+ /// @notice Emitted when coins are sold
102
+ /// @param seller The address of the seller
103
+ /// @param recipient The address of the recipient
104
+ /// @param tradeReferrer The address of the trade referrer
105
+ /// @param coinsSold The number of coins sold
106
+ /// @param currency The address of the currency
107
+ /// @param amountFee The fee for the sale
108
+ /// @param amountPurchased The amount of the currency purchased
109
+ event CoinSell(
110
+ address indexed seller,
111
+ address indexed recipient,
112
+ address indexed tradeReferrer,
113
+ uint256 coinsSold,
114
+ address currency,
115
+ uint256 amountFee,
116
+ uint256 amountPurchased,
117
+ string comment // TODO remove after backend approval
118
+ );
119
+
120
+ /// @notice Emitted when a coin is transferred
121
+ /// @param sender The address of the sender
122
+ /// @param recipient The address of the recipient
123
+ /// @param amount The amount of coins
124
+ /// @param senderBalance The balance of the sender after the transfer
125
+ /// @param recipientBalance The balance of the recipient after the transfer
126
+ event CoinTransfer(address indexed sender, address indexed recipient, uint256 amount, uint256 senderBalance, uint256 recipientBalance);
127
+
128
+ /// @notice Emitted when trade rewards are distributed
129
+ /// @param creatorPayoutRecipient The address of the creator payout recipient
130
+ /// @param platformReferrer The address of the platform referrer
131
+ /// @param tradeReferrer The address of the trade referrer
132
+ /// @param protocolRewardRecipient The address of the protocol reward recipient
133
+ /// @param creatorReward The reward for the creator
134
+ /// @param platformReferrerReward The reward for the platform referrer
135
+ /// @param traderReferrerReward The reward for the trade referrer
136
+ /// @param protocolReward The reward for the protocol
137
+ /// @param currency The address of the currency
138
+ event CoinTradeRewards(
139
+ address indexed creatorPayoutRecipient,
140
+ address indexed platformReferrer,
141
+ address indexed tradeReferrer,
142
+ address protocolRewardRecipient,
143
+ uint256 creatorReward,
144
+ uint256 platformReferrerReward,
145
+ uint256 traderReferrerReward,
146
+ uint256 protocolReward,
147
+ address currency
148
+ );
149
+
150
+ /// @notice Emitted when the creator's payout address is updated
151
+ /// @param caller The msg.sender address
152
+ /// @param prevRecipient The previous payout recipient address
153
+ /// @param newRecipient The new payout recipient address
154
+ event CoinPayoutRecipientUpdated(address indexed caller, address indexed prevRecipient, address indexed newRecipient);
155
+
156
+ /// @notice Emitted when the contract URI is updated
157
+ /// @param caller The msg.sender address
158
+ /// @param newURI The new contract URI
159
+ /// @param name The coin name
160
+ event ContractMetadataUpdated(address indexed caller, string newURI, string name);
161
+
162
+ /// @notice Executes a buy order
163
+ /// @param recipient The recipient address of the coins
164
+ /// @param orderSize The amount of coins to buy
165
+ /// @param tradeReferrer The address of the trade referrer
166
+ /// @param sqrtPriceLimitX96 The price limit for Uniswap V3 pool swap
167
+ function buy(
168
+ address recipient,
169
+ uint256 orderSize,
170
+ uint256 minAmountOut,
171
+ uint160 sqrtPriceLimitX96,
172
+ address tradeReferrer
173
+ ) external payable returns (uint256);
174
+
175
+ /// @notice Executes a sell order
176
+ /// @param recipient The recipient of the currency
177
+ /// @param orderSize The amount of coins to sell
178
+ /// @param minAmountOut The minimum amount of currency to receive
179
+ /// @param sqrtPriceLimitX96 The price limit for the swap
180
+ /// @param tradeReferrer The address of the trade referrer
181
+ function sell(address recipient, uint256 orderSize, uint256 minAmountOut, uint160 sqrtPriceLimitX96, address tradeReferrer) external returns (uint256);
182
+
183
+ /// @notice Enables a user to burn their tokens
184
+ /// @param amount The amount of tokens to burn
185
+ function burn(uint256 amount) external;
186
+
187
+ /// @notice Returns the URI of the token
188
+ /// @return The token URI
189
+ function tokenURI() external view returns (string memory);
190
+
191
+ /// @notice Returns the address of the platform referrer
192
+ /// @return The platform referrer's address
193
+ function platformReferrer() external view returns (address);
194
+ }
@@ -0,0 +1,8 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ interface ICoinComments {
5
+ function isOwner(address) external view returns (bool);
6
+ function payoutRecipient() external view returns (address);
7
+ function balanceOf(address) external view returns (uint256);
8
+ }
@@ -0,0 +1,12 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ /// @notice For compatibility with ERC7572 - the interface for contract-level metadata
5
+ /// @dev https://eips.ethereum.org/EIPS/eip-7572
6
+ interface IERC7572 {
7
+ /// @notice Emitted when the contract URI is updated
8
+ event ContractURIUpdated();
9
+
10
+ /// @notice Returns the contract-level metadata
11
+ function contractURI() external view returns (string memory);
12
+ }
@@ -0,0 +1,104 @@
1
+ // SPDX-License-Identifier: GPL-2.0-or-later
2
+ pragma solidity ^0.8.0;
3
+
4
+ interface INonfungiblePositionManager {
5
+ struct MintParams {
6
+ address token0;
7
+ address token1;
8
+ uint24 fee;
9
+ int24 tickLower;
10
+ int24 tickUpper;
11
+ uint256 amount0Desired;
12
+ uint256 amount1Desired;
13
+ uint256 amount0Min;
14
+ uint256 amount1Min;
15
+ address recipient;
16
+ uint256 deadline;
17
+ }
18
+
19
+ struct CollectParams {
20
+ uint256 tokenId;
21
+ address recipient;
22
+ uint128 amount0Max;
23
+ uint128 amount1Max;
24
+ }
25
+
26
+ /// @notice Creates a new pool if it does not exist, then initializes if not initialized
27
+ /// @dev This method can be bundled with others via IMulticall for the first action (e.g. mint) performed against a pool
28
+ /// @param token0 The contract address of token0 of the pool
29
+ /// @param token1 The contract address of token1 of the pool
30
+ /// @param fee The fee amount of the v3 pool for the specified token pair
31
+ /// @param sqrtPriceX96 The initial square root price of the pool as a Q64.96 value
32
+ /// @return pool Returns the pool address based on the pair of tokens and fee, will return the newly created pool address if necessary
33
+ function createAndInitializePoolIfNecessary(address token0, address token1, uint24 fee, uint160 sqrtPriceX96) external payable returns (address pool);
34
+
35
+ /// @notice Creates a new position wrapped in a NFT
36
+ /// @dev Call this when the pool does exist and is initialized. Note that if the pool is created but not initialized
37
+ /// a method does not exist, i.e. the pool is assumed to be initialized.
38
+ /// @param params The params necessary to mint a position, encoded as `MintParams` in calldata
39
+ /// @return tokenId The ID of the token that represents the minted position
40
+ /// @return liquidity The amount of liquidity for this position
41
+ /// @return amount0 The amount of token0
42
+ /// @return amount1 The amount of token1
43
+ function mint(MintParams calldata params) external payable returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1);
44
+
45
+ /// @notice Collects up to a maximum amount of fees owed to a specific position to the recipient
46
+ /// @param params tokenId The ID of the NFT for which tokens are being collected,
47
+ /// recipient The account that should receive the tokens,
48
+ /// amount0Max The maximum amount of token0 to collect,
49
+ /// amount1Max The maximum amount of token1 to collect
50
+ /// @return amount0 The amount of fees collected in token0
51
+ /// @return amount1 The amount of fees collected in token1
52
+ function collect(CollectParams calldata params) external payable returns (uint256 amount0, uint256 amount1);
53
+
54
+ /// @notice Returns the position information associated with a given token ID.
55
+ /// @dev Throws if the token ID is not valid.
56
+ /// @param tokenId The ID of the token that represents the position
57
+ /// @return nonce The nonce for permits
58
+ /// @return operator The address that is approved for spending
59
+ /// @return token0 The address of the token0 for a specific pool
60
+ /// @return token1 The address of the token1 for a specific pool
61
+ /// @return fee The fee associated with the pool
62
+ /// @return tickLower The lower end of the tick range for the position
63
+ /// @return tickUpper The higher end of the tick range for the position
64
+ /// @return liquidity The liquidity of the position
65
+ /// @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position
66
+ /// @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position
67
+ /// @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation
68
+ /// @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation
69
+ function positions(
70
+ uint256 tokenId
71
+ )
72
+ external
73
+ view
74
+ returns (
75
+ uint96 nonce,
76
+ address operator,
77
+ address token0,
78
+ address token1,
79
+ uint24 fee,
80
+ int24 tickLower,
81
+ int24 tickUpper,
82
+ uint128 liquidity,
83
+ uint256 feeGrowthInside0LastX128,
84
+ uint256 feeGrowthInside1LastX128,
85
+ uint128 tokensOwed0,
86
+ uint128 tokensOwed1
87
+ );
88
+
89
+ function approve(address to, uint256 tokenId) external;
90
+
91
+ function ownerOf(uint256 tokenId) external view returns (address);
92
+
93
+ function transferFrom(address from, address to, uint256 tokenId) external;
94
+
95
+ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
96
+
97
+ /// @notice Emitted when tokens are collected for a position NFT
98
+ /// @dev The amounts reported may not be exactly equivalent to the amounts transferred, due to rounding behavior
99
+ /// @param tokenId The ID of the token for which underlying tokens were collected
100
+ /// @param recipient The address of the account that received the collected tokens
101
+ /// @param amount0 The amount of token0 owed to the position that was collected
102
+ /// @param amount1 The amount of token1 owed to the position that was collected
103
+ event Collect(uint256 indexed tokenId, address recipient, uint256 amount0, uint256 amount1);
104
+ }
@@ -0,0 +1,12 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ interface IProtocolRewards {
5
+ function balanceOf(address account) external view returns (uint256);
6
+
7
+ function deposit(address to, bytes4 why, string calldata comment) external payable;
8
+
9
+ function depositBatch(address[] calldata recipients, uint256[] calldata amounts, bytes4[] calldata reasons, string calldata comment) external payable;
10
+
11
+ function withdrawFor(address to, uint256 amount) external;
12
+ }
@@ -0,0 +1,38 @@
1
+ // SPDX-License-Identifier: GPL-2.0-or-later
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {IUniswapV3SwapCallback} from "./IUniswapV3SwapCallback.sol";
5
+
6
+ /// @title Router token swapping functionality
7
+ /// @notice Functions for swapping tokens via Uniswap V3
8
+ interface ISwapRouter is IUniswapV3SwapCallback {
9
+ struct ExactInputSingleParams {
10
+ address tokenIn;
11
+ address tokenOut;
12
+ uint24 fee;
13
+ address recipient;
14
+ uint256 amountIn;
15
+ uint256 amountOutMinimum;
16
+ uint160 sqrtPriceLimitX96;
17
+ }
18
+
19
+ struct ExactOutputSingleParams {
20
+ address tokenIn;
21
+ address tokenOut;
22
+ uint24 fee;
23
+ address recipient;
24
+ uint256 amountOut;
25
+ uint256 amountInMaximum;
26
+ uint160 sqrtPriceLimitX96;
27
+ }
28
+
29
+ /// @notice Swaps `amountIn` of one token for as much as possible of another token
30
+ /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata
31
+ /// @return amountOut The amount of the received token
32
+ function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);
33
+
34
+ /// @notice Swaps as little as possible of one token for `amountOut` of another token
35
+ /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata
36
+ /// @return amountIn The amount of the input token
37
+ function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);
38
+ }
@@ -0,0 +1,43 @@
1
+ // SPDX-License-Identifier: GPL-2.0-or-later
2
+ pragma solidity ^0.8.0;
3
+
4
+ interface IUniswapV3Pool {
5
+ /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool
6
+ /// @dev This value can overflow the uint256
7
+ function feeGrowthGlobal0X128() external view returns (uint256);
8
+
9
+ /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool
10
+ /// @dev This value can overflow the uint256
11
+ function feeGrowthGlobal1X128() external view returns (uint256);
12
+
13
+ function swap(
14
+ address recipient,
15
+ bool zeroForOne,
16
+ int256 amountSpecified,
17
+ uint160 sqrtPriceLimitX96,
18
+ bytes memory data
19
+ ) external returns (int256 amount0, int256 amount1);
20
+
21
+ function token0() external returns (address);
22
+ function token1() external returns (address);
23
+
24
+ struct Slot0 {
25
+ // the current price
26
+ uint160 sqrtPriceX96;
27
+ // the current tick
28
+ int24 tick;
29
+ // the most-recently updated index of the observations array
30
+ uint16 observationIndex;
31
+ // the current maximum number of observations that are being stored
32
+ uint16 observationCardinality;
33
+ // the next maximum number of observations to store, triggered in observations.write
34
+ uint16 observationCardinalityNext;
35
+ // the current protocol fee as a percentage of the swap fee taken on withdrawal
36
+ // represented as an integer denominator (1/x)%
37
+ uint8 feeProtocol;
38
+ // whether the pool is locked
39
+ bool unlocked;
40
+ }
41
+
42
+ function slot0() external view returns (Slot0 memory slot0);
43
+ }
@@ -0,0 +1,17 @@
1
+ // SPDX-License-Identifier: GPL-2.0-or-later
2
+ pragma solidity ^0.8.0;
3
+
4
+ /// @title Callback for IUniswapV3PoolActions#swap
5
+ /// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface
6
+ interface IUniswapV3SwapCallback {
7
+ /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap.
8
+ /// @dev In the implementation you must pay the pool tokens owed for the swap.
9
+ /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory.
10
+ /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.
11
+ /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by
12
+ /// the end of the swap. If positive, the callback must send that amount of token0 to the pool.
13
+ /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by
14
+ /// the end of the swap. If positive, the callback must send that amount of token1 to the pool.
15
+ /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call
16
+ function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external;
17
+ }
@@ -0,0 +1,16 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ interface IWETH {
5
+ function deposit() external payable;
6
+
7
+ function withdraw(uint256 wad) external;
8
+
9
+ function approve(address guy, uint256 wad) external returns (bool);
10
+
11
+ function transfer(address dst, uint256 wad) external returns (bool);
12
+
13
+ function transferFrom(address src, address dst, uint256 wad) external returns (bool);
14
+
15
+ function balanceOf(address guy) external view returns (uint256);
16
+ }
@@ -0,0 +1,56 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ interface IZoraFactory {
5
+ /// @notice Emitted when a coin is created
6
+ /// @param deployer The msg.sender address of coin creation
7
+ /// @param creator The address of the creator of the coin
8
+ /// @param payoutRecipient The address of the creator payout recipient
9
+ /// @param platformReferrer The address of the platform referrer
10
+ /// @param currency The address of the currency
11
+ /// @param tokenURI The URI of the coin
12
+ /// @param name The name of the coin
13
+ /// @param symbol The symbol of the coin
14
+ /// @param coin The address of the coin
15
+ /// @param pool The address of the pool
16
+ event CoinCreated(
17
+ address indexed deployer,
18
+ address indexed creator, // TODO remove after backend approval
19
+ address indexed payoutRecipient,
20
+ address platformReferrer,
21
+ address currency,
22
+ string tokenURI,
23
+ string name,
24
+ string symbol,
25
+ address coin,
26
+ address pool
27
+ );
28
+
29
+ /// @notice Thrown when the amount of ERC20 tokens transferred does not match the expected amount
30
+ error ERC20TransferAmountMismatch();
31
+
32
+ /// @notice Thrown when ETH is sent with a transaction but the currency is not WETH
33
+ error EthTransferInvalid();
34
+
35
+ /// @notice Creates a new coin contract
36
+ /// @param payoutRecipient The recipient of creator reward payouts; this can be updated by an owner
37
+ /// @param owners The list of addresses that will be able to manage the coin's payout address and metadata uri
38
+ /// @param uri The coin metadata uri
39
+ /// @param name The name of the coin
40
+ /// @param symbol The symbol of the coin
41
+ /// @param platformReferrer The address to receive platform referral rewards
42
+ /// @param currency The address of the trading currency; address(0) for ETH/WETH
43
+ /// @param tickLower The lower tick for the Uniswap V3 LP position; ignored for ETH/WETH pairs
44
+ /// @param orderSize The order size for the first buy; must match msg.value for ETH/WETH pairs
45
+ function deploy(
46
+ address payoutRecipient,
47
+ address[] memory owners,
48
+ string memory uri,
49
+ string memory name,
50
+ string memory symbol,
51
+ address platformReferrer,
52
+ address currency,
53
+ int24 tickLower,
54
+ uint256 orderSize
55
+ ) external payable returns (address);
56
+ }