@zoralabs/coins 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +7 -0
- package/.turbo/turbo-build.log +51 -37
- package/CHANGELOG.md +12 -0
- package/README.md +29 -0
- package/abis/Coin.json +10 -0
- package/abis/CoinTest.json +48 -0
- package/abis/Create2.json +28 -0
- package/abis/DeployScript.json +9 -0
- package/abis/DeterministicDeployerAndCaller.json +315 -0
- package/abis/DeterministicUUPSProxyDeployer.json +167 -0
- package/abis/FactoryTest.json +20 -0
- package/abis/GenerateDeterministicParams.json +9 -0
- package/abis/ICoin.json +10 -0
- package/abis/IERC165.json +1 -1
- package/abis/IERC20.json +42 -39
- package/abis/IImmutableCreate2Factory.json +93 -0
- package/abis/ISafe.json +15 -0
- package/abis/ISymbol.json +15 -0
- package/abis/ImmutableCreate2FactoryUtils.json +15 -0
- package/abis/LibString.json +7 -0
- package/abis/ProxyShim.json +112 -0
- package/abis/UUPSUpgradeable.json +15 -14
- package/abis/ZoraFactory.json +0 -5
- package/addresses/8453.json +5 -8
- package/addresses/84532.json +5 -8
- package/deterministicConfig/deployerAndCaller.json +5 -0
- package/deterministicConfig/zoraFactory.json +8 -0
- package/dist/index.cjs +8 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/wagmiGenerated.d.ts +8 -0
- package/dist/wagmiGenerated.d.ts.map +1 -1
- package/foundry.toml +14 -0
- package/package/wagmiGenerated.ts +8 -2
- package/package.json +2 -1
- package/remappings.txt +2 -1
- package/script/CoinsDeployerBase.sol +98 -0
- package/script/Deploy.s.sol +14 -5
- package/script/GenerateDeterministicParams.s.sol +43 -0
- package/src/Coin.sol +26 -8
- package/src/ZoraFactoryImpl.sol +2 -2
- package/src/interfaces/ICoin.sol +8 -2
- package/src/proxy/ZoraFactory.sol +7 -1
- package/src/utils/CoinConstants.sol +2 -2
- package/src/version/ContractVersionBase.sol +1 -1
- package/test/Coin.t.sol +150 -4
- package/test/Factory.t.sol +34 -11
- package/test/utils/BaseTest.sol +4 -4
- package/abis/Deploy.json +0 -29
- package/addresses/1.json +0 -4
package/src/Coin.sol
CHANGED
|
@@ -138,7 +138,7 @@ contract Coin is ICoin, CoinConstants, ContractVersionBase, ERC20PermitUpgradeab
|
|
|
138
138
|
uint256 minAmountOut,
|
|
139
139
|
uint160 sqrtPriceLimitX96,
|
|
140
140
|
address tradeReferrer
|
|
141
|
-
) public payable nonReentrant returns (uint256) {
|
|
141
|
+
) public payable nonReentrant returns (uint256, uint256) {
|
|
142
142
|
// Ensure the recipient is not the zero address
|
|
143
143
|
if (recipient == address(0)) {
|
|
144
144
|
revert AddressZero();
|
|
@@ -173,7 +173,7 @@ contract Coin is ICoin, CoinConstants, ContractVersionBase, ERC20PermitUpgradeab
|
|
|
173
173
|
|
|
174
174
|
emit CoinBuy(msg.sender, recipient, tradeReferrer, amountOut, currency, tradeReward, trueOrderSize);
|
|
175
175
|
|
|
176
|
-
return amountOut;
|
|
176
|
+
return (orderSize, amountOut);
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
/// @notice Executes a sell order
|
|
@@ -188,12 +188,15 @@ contract Coin is ICoin, CoinConstants, ContractVersionBase, ERC20PermitUpgradeab
|
|
|
188
188
|
uint256 minAmountOut,
|
|
189
189
|
uint160 sqrtPriceLimitX96,
|
|
190
190
|
address tradeReferrer
|
|
191
|
-
) public nonReentrant returns (uint256) {
|
|
191
|
+
) public nonReentrant returns (uint256, uint256) {
|
|
192
192
|
// Ensure the recipient is not the zero address
|
|
193
193
|
if (recipient == address(0)) {
|
|
194
194
|
revert AddressZero();
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
+
// Record the coin balance of this contract before the swap
|
|
198
|
+
uint256 beforeCoinBalance = balanceOf(address(this));
|
|
199
|
+
|
|
197
200
|
// Transfer the coins from the seller to this contract
|
|
198
201
|
transfer(address(this), orderSize);
|
|
199
202
|
|
|
@@ -214,6 +217,21 @@ contract Coin is ICoin, CoinConstants, ContractVersionBase, ERC20PermitUpgradeab
|
|
|
214
217
|
// Execute the swap
|
|
215
218
|
uint256 amountOut = ISwapRouter(swapRouter).exactInputSingle(params);
|
|
216
219
|
|
|
220
|
+
// Record the coin balance of this contract after the swap
|
|
221
|
+
uint256 afterCoinBalance = balanceOf(address(this));
|
|
222
|
+
|
|
223
|
+
// If the swap was partially executed:
|
|
224
|
+
if (afterCoinBalance > beforeCoinBalance) {
|
|
225
|
+
// Calculate the refund
|
|
226
|
+
uint256 coinRefund = afterCoinBalance - beforeCoinBalance;
|
|
227
|
+
|
|
228
|
+
// Update the order size
|
|
229
|
+
orderSize -= coinRefund;
|
|
230
|
+
|
|
231
|
+
// Transfer the refund back to the seller
|
|
232
|
+
_transfer(address(this), recipient, coinRefund);
|
|
233
|
+
}
|
|
234
|
+
|
|
217
235
|
// If currency is WETH, convert to ETH
|
|
218
236
|
if (currency == WETH) {
|
|
219
237
|
IWETH(WETH).withdraw(amountOut);
|
|
@@ -225,7 +243,7 @@ contract Coin is ICoin, CoinConstants, ContractVersionBase, ERC20PermitUpgradeab
|
|
|
225
243
|
// Calculate the payout after the fee
|
|
226
244
|
uint256 payoutSize = amountOut - tradeReward;
|
|
227
245
|
|
|
228
|
-
|
|
246
|
+
_handlePayout(payoutSize, recipient);
|
|
229
247
|
|
|
230
248
|
_handleTradeRewards(tradeReward, tradeReferrer);
|
|
231
249
|
|
|
@@ -233,7 +251,7 @@ contract Coin is ICoin, CoinConstants, ContractVersionBase, ERC20PermitUpgradeab
|
|
|
233
251
|
|
|
234
252
|
emit CoinSell(msg.sender, recipient, tradeReferrer, orderSize, currency, tradeReward, payoutSize);
|
|
235
253
|
|
|
236
|
-
return
|
|
254
|
+
return (orderSize, payoutSize);
|
|
237
255
|
}
|
|
238
256
|
|
|
239
257
|
/// @notice Enables a user to burn their tokens
|
|
@@ -332,7 +350,7 @@ contract Coin is ICoin, CoinConstants, ContractVersionBase, ERC20PermitUpgradeab
|
|
|
332
350
|
/// @dev Deploy the pool
|
|
333
351
|
function _deployPool(int24 tickLower_) internal {
|
|
334
352
|
// If WETH is the pool's currency, validate the lower tick
|
|
335
|
-
if (currency == WETH && tickLower_
|
|
353
|
+
if (currency == WETH && tickLower_ < LP_TICK_LOWER_WETH) {
|
|
336
354
|
revert InvalidWethLowerTick();
|
|
337
355
|
}
|
|
338
356
|
|
|
@@ -415,10 +433,10 @@ contract Coin is ICoin, CoinConstants, ContractVersionBase, ERC20PermitUpgradeab
|
|
|
415
433
|
}
|
|
416
434
|
}
|
|
417
435
|
|
|
418
|
-
/// @dev Handles sending ETH and ERC20 payouts
|
|
436
|
+
/// @dev Handles sending ETH and ERC20 payouts and refunds to recipients
|
|
419
437
|
/// @param orderPayout The amount of currency to pay out
|
|
420
438
|
/// @param recipient The address to receive the payout
|
|
421
|
-
function
|
|
439
|
+
function _handlePayout(uint256 orderPayout, address recipient) internal {
|
|
422
440
|
if (currency == WETH) {
|
|
423
441
|
Address.sendValue(payable(recipient), orderPayout);
|
|
424
442
|
} else {
|
package/src/ZoraFactoryImpl.sol
CHANGED
|
@@ -102,9 +102,9 @@ contract ZoraFactoryImpl is IZoraFactory, UUPSUpgradeable, ReentrancyGuardUpgrad
|
|
|
102
102
|
|
|
103
103
|
IERC20(currency).approve(address(coin), orderSize);
|
|
104
104
|
|
|
105
|
-
coinsPurchased = coin.buy(payoutRecipient, orderSize, 0, 0, address(0));
|
|
105
|
+
(, coinsPurchased) = coin.buy(payoutRecipient, orderSize, 0, 0, address(0));
|
|
106
106
|
} else {
|
|
107
|
-
coinsPurchased = coin.buy{value: msg.value}(payoutRecipient, orderSize, 0, 0, address(0));
|
|
107
|
+
(, coinsPurchased) = coin.buy{value: msg.value}(payoutRecipient, orderSize, 0, 0, address(0));
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
}
|
package/src/interfaces/ICoin.sol
CHANGED
|
@@ -172,7 +172,7 @@ interface ICoin is IERC165, IERC721Receiver, IERC7572 {
|
|
|
172
172
|
uint256 minAmountOut,
|
|
173
173
|
uint160 sqrtPriceLimitX96,
|
|
174
174
|
address tradeReferrer
|
|
175
|
-
) external payable returns (uint256);
|
|
175
|
+
) external payable returns (uint256, uint256);
|
|
176
176
|
|
|
177
177
|
/// @notice Executes a sell order
|
|
178
178
|
/// @param recipient The recipient of the currency
|
|
@@ -180,7 +180,13 @@ interface ICoin is IERC165, IERC721Receiver, IERC7572 {
|
|
|
180
180
|
/// @param minAmountOut The minimum amount of currency to receive
|
|
181
181
|
/// @param sqrtPriceLimitX96 The price limit for the swap
|
|
182
182
|
/// @param tradeReferrer The address of the trade referrer
|
|
183
|
-
function sell(
|
|
183
|
+
function sell(
|
|
184
|
+
address recipient,
|
|
185
|
+
uint256 orderSize,
|
|
186
|
+
uint256 minAmountOut,
|
|
187
|
+
uint160 sqrtPriceLimitX96,
|
|
188
|
+
address tradeReferrer
|
|
189
|
+
) external returns (uint256, uint256);
|
|
184
190
|
|
|
185
191
|
/// @notice Enables a user to burn their tokens
|
|
186
192
|
/// @param amount The amount of tokens to burn
|
|
@@ -22,5 +22,11 @@ import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.s
|
|
|
22
22
|
OURS TRULY,
|
|
23
23
|
*/
|
|
24
24
|
contract ZoraFactory is ERC1967Proxy {
|
|
25
|
-
|
|
25
|
+
bytes32 internal immutable name;
|
|
26
|
+
|
|
27
|
+
constructor(address _logic) ERC1967Proxy(_logic, "") {
|
|
28
|
+
// added to create unique bytecode for this contract
|
|
29
|
+
// so that it can be properly verified as its own contract.
|
|
30
|
+
name = keccak256("ZoraFactory");
|
|
31
|
+
}
|
|
26
32
|
}
|
|
@@ -50,9 +50,9 @@ abstract contract CoinConstants {
|
|
|
50
50
|
/// @dev 10000 basis points = 1%
|
|
51
51
|
uint24 internal constant LP_FEE = 10000;
|
|
52
52
|
|
|
53
|
-
/// @notice The LP's lower tick
|
|
53
|
+
/// @notice The LP's minimum lower tick
|
|
54
54
|
/// @dev This is only used if the currency is WETH
|
|
55
|
-
int24 internal constant LP_TICK_LOWER_WETH = -
|
|
55
|
+
int24 internal constant LP_TICK_LOWER_WETH = -208200;
|
|
56
56
|
|
|
57
57
|
/// @notice The LP's upper tick
|
|
58
58
|
int24 internal constant LP_TICK_UPPER = 887200;
|
|
@@ -9,6 +9,6 @@ import {IVersionedContract} from "@zoralabs/shared-contracts/interfaces/IVersion
|
|
|
9
9
|
contract ContractVersionBase is IVersionedContract {
|
|
10
10
|
/// @notice The version of the contract
|
|
11
11
|
function contractVersion() external pure override returns (string memory) {
|
|
12
|
-
return "0.
|
|
12
|
+
return "0.6.0";
|
|
13
13
|
}
|
|
14
14
|
}
|
package/test/Coin.t.sol
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
pragma solidity ^0.8.13;
|
|
3
3
|
|
|
4
4
|
import "./utils/BaseTest.sol";
|
|
5
|
+
import {ISwapRouter} from "../src/interfaces/ISwapRouter.sol";
|
|
5
6
|
|
|
6
7
|
contract CoinTest is BaseTest {
|
|
7
8
|
function setUp() public override {
|
|
@@ -10,6 +11,10 @@ contract CoinTest is BaseTest {
|
|
|
10
11
|
_deployCoin();
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
function test_contract_version() public view {
|
|
15
|
+
assertEq(coin.contractVersion(), "0.6.0");
|
|
16
|
+
}
|
|
17
|
+
|
|
13
18
|
function test_supply_constants() public view {
|
|
14
19
|
assertEq(MAX_TOTAL_SUPPLY, POOL_LAUNCH_SUPPLY + CREATOR_LAUNCH_REWARD);
|
|
15
20
|
|
|
@@ -183,6 +188,94 @@ contract CoinTest is BaseTest {
|
|
|
183
188
|
coin.buy(users.coinRecipient, 100e6, 0, 0, users.tradeReferrer);
|
|
184
189
|
}
|
|
185
190
|
|
|
191
|
+
function test_buy_validate_return_amounts(uint256 orderSize) public {
|
|
192
|
+
vm.assume(orderSize >= MIN_ORDER_SIZE);
|
|
193
|
+
vm.assume(orderSize < 10 ether);
|
|
194
|
+
|
|
195
|
+
vm.deal(users.buyer, orderSize);
|
|
196
|
+
vm.prank(users.buyer);
|
|
197
|
+
(uint256 amountIn, uint256 amountOut) = coin.buy{value: orderSize}(users.coinRecipient, orderSize, 0, 0, users.tradeReferrer);
|
|
198
|
+
|
|
199
|
+
assertEq(amountIn, orderSize, "amountIn");
|
|
200
|
+
assertGe(coin.balanceOf(users.coinRecipient), amountOut, "coinRecipient coin balance");
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function test_sell_for_eth_direct_and_claim_secondary() public {
|
|
204
|
+
vm.deal(users.buyer, 1 ether);
|
|
205
|
+
|
|
206
|
+
vm.prank(users.buyer);
|
|
207
|
+
weth.deposit{value: 100_000}();
|
|
208
|
+
|
|
209
|
+
vm.prank(users.buyer);
|
|
210
|
+
weth.approve(address(swapRouter), 100_000);
|
|
211
|
+
|
|
212
|
+
// Set up the swap parameters
|
|
213
|
+
ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
|
|
214
|
+
tokenIn: WETH_ADDRESS,
|
|
215
|
+
tokenOut: address(coin),
|
|
216
|
+
fee: LP_FEE,
|
|
217
|
+
recipient: address(users.buyer),
|
|
218
|
+
amountIn: 100_000,
|
|
219
|
+
amountOutMinimum: 0,
|
|
220
|
+
sqrtPriceLimitX96: 0
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// Execute the swap
|
|
224
|
+
vm.prank(users.buyer);
|
|
225
|
+
uint256 amountOut = ISwapRouter(swapRouter).exactInputSingle(params);
|
|
226
|
+
|
|
227
|
+
assertEq(coin.balanceOf(users.buyer), 108941722423358, "buyer coin balance");
|
|
228
|
+
assertEq(amountOut, 108941722423358);
|
|
229
|
+
assertGt(users.buyer.balance, 0, "seller eth balance");
|
|
230
|
+
|
|
231
|
+
// now we have unclaimed secondary rewards to claim
|
|
232
|
+
vm.prank(users.buyer);
|
|
233
|
+
|
|
234
|
+
// don't push ETH
|
|
235
|
+
coin.claimSecondaryRewards(false);
|
|
236
|
+
assertEq(protocolRewards.balanceOf(users.creator), 499);
|
|
237
|
+
assertEq(protocolRewards.balanceOf(users.platformReferrer), 249);
|
|
238
|
+
assertEq(protocolRewards.balanceOf(users.feeRecipient), 251);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function test_sell_for_eth_direct_and_claim_secondary_push_eth() public {
|
|
242
|
+
vm.deal(users.buyer, 1 ether);
|
|
243
|
+
|
|
244
|
+
vm.prank(users.buyer);
|
|
245
|
+
weth.deposit{value: 100_000}();
|
|
246
|
+
|
|
247
|
+
vm.prank(users.buyer);
|
|
248
|
+
weth.approve(address(swapRouter), 100_000);
|
|
249
|
+
|
|
250
|
+
// Set up the swap parameters
|
|
251
|
+
ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
|
|
252
|
+
tokenIn: WETH_ADDRESS,
|
|
253
|
+
tokenOut: address(coin),
|
|
254
|
+
fee: LP_FEE,
|
|
255
|
+
recipient: address(users.buyer),
|
|
256
|
+
amountIn: 100_000,
|
|
257
|
+
amountOutMinimum: 0,
|
|
258
|
+
sqrtPriceLimitX96: 0
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
// Execute the swap
|
|
262
|
+
vm.prank(users.buyer);
|
|
263
|
+
uint256 amountOut = ISwapRouter(swapRouter).exactInputSingle(params);
|
|
264
|
+
|
|
265
|
+
assertEq(coin.balanceOf(users.buyer), 108941722423358, "buyer coin balance");
|
|
266
|
+
assertEq(amountOut, 108941722423358);
|
|
267
|
+
assertGt(users.buyer.balance, 0, "seller eth balance");
|
|
268
|
+
|
|
269
|
+
// Now we have unclaimed secondary rewards to claim
|
|
270
|
+
vm.prank(users.buyer);
|
|
271
|
+
|
|
272
|
+
uint256 initialBalance = users.creator.balance;
|
|
273
|
+
|
|
274
|
+
// Push ETH
|
|
275
|
+
coin.claimSecondaryRewards(true);
|
|
276
|
+
assertEq(users.creator.balance - initialBalance, 499);
|
|
277
|
+
}
|
|
278
|
+
|
|
186
279
|
function test_sell_for_eth() public {
|
|
187
280
|
vm.deal(users.buyer, 1 ether);
|
|
188
281
|
vm.prank(users.buyer);
|
|
@@ -262,6 +355,27 @@ contract CoinTest is BaseTest {
|
|
|
262
355
|
coin.sell(users.coinRecipient, balance + 1, 0, 0, users.tradeReferrer);
|
|
263
356
|
}
|
|
264
357
|
|
|
358
|
+
function test_sell_partial_execution() public {
|
|
359
|
+
vm.deal(users.creator, 1 ether);
|
|
360
|
+
vm.prank(users.creator);
|
|
361
|
+
coin.buy{value: 0.001 ether}(users.creator, 0.001 ether, 0, 0, users.tradeReferrer);
|
|
362
|
+
|
|
363
|
+
uint256 beforeBalance = coin.balanceOf(users.creator);
|
|
364
|
+
assertEq(beforeBalance, 11077349369032224007213331); // 11,077,349 coins
|
|
365
|
+
|
|
366
|
+
vm.prank(users.creator);
|
|
367
|
+
(uint256 amountSold, ) = coin.sell(users.creator, beforeBalance, 0, 0, users.tradeReferrer);
|
|
368
|
+
assertEq(amountSold, 1088231685891135360821548); // 1,088,232 coins (max that could be sold)
|
|
369
|
+
|
|
370
|
+
uint256 afterBalance = coin.balanceOf(users.creator);
|
|
371
|
+
assertEq(afterBalance, 9994558841570544323195890); // 9,994,559 coins
|
|
372
|
+
|
|
373
|
+
uint256 expectedMarketReward = 5441158429455676804107; // 5,441 coins
|
|
374
|
+
|
|
375
|
+
// 9,994,559 = 11,077,349 order size - 1,088,232 true order size + 5,441 creator market reward
|
|
376
|
+
assertEq(afterBalance, ((beforeBalance - amountSold) + expectedMarketReward), "amountSold");
|
|
377
|
+
}
|
|
378
|
+
|
|
265
379
|
function test_burn() public {
|
|
266
380
|
vm.deal(users.buyer, 1 ether);
|
|
267
381
|
vm.prank(users.buyer);
|
|
@@ -324,6 +438,42 @@ contract CoinTest is BaseTest {
|
|
|
324
438
|
assertGt(protocolRewards.balanceOf(users.feeRecipient), expectedFees.platformReferrer, "feeRecipient eth balance");
|
|
325
439
|
}
|
|
326
440
|
|
|
441
|
+
function test_invalid_weth_tick() public {
|
|
442
|
+
address[] memory owners = new address[](1);
|
|
443
|
+
owners[0] = users.creator;
|
|
444
|
+
|
|
445
|
+
vm.expectRevert(ICoin.InvalidWethLowerTick.selector);
|
|
446
|
+
(address newCoinAddr, ) = factory.deploy(
|
|
447
|
+
users.creator,
|
|
448
|
+
owners,
|
|
449
|
+
"https://test.com",
|
|
450
|
+
"Test Token",
|
|
451
|
+
"TEST",
|
|
452
|
+
users.platformReferrer,
|
|
453
|
+
address(weth),
|
|
454
|
+
LP_TICK_LOWER_WETH - 1,
|
|
455
|
+
0
|
|
456
|
+
);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
function test_invalid_currency_tick() public {
|
|
460
|
+
address[] memory owners = new address[](1);
|
|
461
|
+
owners[0] = users.creator;
|
|
462
|
+
|
|
463
|
+
vm.expectRevert(ICoin.InvalidCurrencyLowerTick.selector);
|
|
464
|
+
(address newCoinAddr, ) = factory.deploy(
|
|
465
|
+
users.creator,
|
|
466
|
+
owners,
|
|
467
|
+
"https://test.com",
|
|
468
|
+
"Test Token",
|
|
469
|
+
"TEST",
|
|
470
|
+
users.platformReferrer,
|
|
471
|
+
address(0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913),
|
|
472
|
+
20,
|
|
473
|
+
0
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
|
|
327
477
|
function test_default_order_referrer() public {
|
|
328
478
|
vm.deal(users.buyer, 1 ether);
|
|
329
479
|
vm.prank(users.buyer);
|
|
@@ -459,8 +609,4 @@ contract CoinTest is BaseTest {
|
|
|
459
609
|
vm.expectRevert(abi.encodeWithSelector(MultiOwnable.OnlyOwner.selector));
|
|
460
610
|
coin.setPayoutRecipient(newPayoutRecipient);
|
|
461
611
|
}
|
|
462
|
-
|
|
463
|
-
function test_contract_version() public view {
|
|
464
|
-
assertEq(coin.contractVersion(), "0.4.0");
|
|
465
|
-
}
|
|
466
612
|
}
|
package/test/Factory.t.sol
CHANGED
|
@@ -96,6 +96,35 @@ contract FactoryTest is BaseTest {
|
|
|
96
96
|
console.log("BUYER_COIN_BALANCE ", coin.balanceOf(users.creator) - 10_000_000e18);
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
function test_deploy_with_weth(uint256 initialOrderSize) public {
|
|
100
|
+
vm.assume(initialOrderSize > MIN_ORDER_SIZE);
|
|
101
|
+
vm.assume(initialOrderSize < 10 ether);
|
|
102
|
+
|
|
103
|
+
address[] memory owners = new address[](1);
|
|
104
|
+
owners[0] = users.creator;
|
|
105
|
+
|
|
106
|
+
vm.deal(users.creator, initialOrderSize);
|
|
107
|
+
|
|
108
|
+
vm.startPrank(users.creator);
|
|
109
|
+
weth.deposit{value: initialOrderSize}();
|
|
110
|
+
|
|
111
|
+
weth.approve(address(factory), type(uint256).max);
|
|
112
|
+
|
|
113
|
+
// Expect this to revert because WETH needs to be sent with msg.value.
|
|
114
|
+
vm.expectRevert();
|
|
115
|
+
factory.deploy(
|
|
116
|
+
users.creator,
|
|
117
|
+
owners,
|
|
118
|
+
"https://test2.com",
|
|
119
|
+
"Test2 Token",
|
|
120
|
+
"TEST2",
|
|
121
|
+
users.platformReferrer,
|
|
122
|
+
address(weth),
|
|
123
|
+
LP_TICK_LOWER_WETH,
|
|
124
|
+
initialOrderSize
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
99
128
|
function test_deploy_with_one_eth() public {
|
|
100
129
|
address[] memory owners = new address[](1);
|
|
101
130
|
owners[0] = users.creator;
|
|
@@ -206,17 +235,7 @@ contract FactoryTest is BaseTest {
|
|
|
206
235
|
|
|
207
236
|
vm.expectRevert(abi.encodeWithSelector(ICoin.InvalidWethLowerTick.selector));
|
|
208
237
|
|
|
209
|
-
factory.deploy(
|
|
210
|
-
users.creator,
|
|
211
|
-
owners,
|
|
212
|
-
"https://testcoinusdcpair.com",
|
|
213
|
-
"Testcoinusdcpair",
|
|
214
|
-
"TESTCOINUSDCPAIR",
|
|
215
|
-
users.platformReferrer,
|
|
216
|
-
address(0),
|
|
217
|
-
USDC_TICK_LOWER,
|
|
218
|
-
0
|
|
219
|
-
);
|
|
238
|
+
factory.deploy(users.creator, owners, "https://testcoin.com", "Testcoin", "TESTCOIN", users.platformReferrer, address(0), LP_TICK_LOWER_WETH - 1, 0);
|
|
220
239
|
}
|
|
221
240
|
|
|
222
241
|
function test_deploy_with_usdc_revert_invalid_eth_transfer() public {
|
|
@@ -272,6 +291,10 @@ contract FactoryTest is BaseTest {
|
|
|
272
291
|
assertEq(factory.implementation(), address(newImpl), "implementation");
|
|
273
292
|
}
|
|
274
293
|
|
|
294
|
+
function test_implementation_address() public view {
|
|
295
|
+
assertEq(factory.implementation(), address(factoryImpl));
|
|
296
|
+
}
|
|
297
|
+
|
|
275
298
|
function test_revert_invalid_upgrade_impl() public {
|
|
276
299
|
address newImpl = address(this);
|
|
277
300
|
|
package/test/utils/BaseTest.sol
CHANGED
|
@@ -59,7 +59,7 @@ contract BaseTest is Test, CoinConstants {
|
|
|
59
59
|
IUniswapV3Pool internal pool;
|
|
60
60
|
|
|
61
61
|
function setUp() public virtual {
|
|
62
|
-
forkId = vm.createSelectFork("
|
|
62
|
+
forkId = vm.createSelectFork("base", 21179722);
|
|
63
63
|
|
|
64
64
|
weth = IWETH(WETH_ADDRESS);
|
|
65
65
|
usdc = IERC20Metadata(USDC_ADDRESS);
|
|
@@ -80,9 +80,9 @@ contract BaseTest is Test, CoinConstants {
|
|
|
80
80
|
|
|
81
81
|
coinImpl = new Coin(users.feeRecipient, address(protocolRewards), WETH_ADDRESS, NONFUNGIBLE_POSITION_MANAGER, SWAP_ROUTER);
|
|
82
82
|
factoryImpl = new ZoraFactoryImpl(address(coinImpl));
|
|
83
|
-
factory = ZoraFactoryImpl(
|
|
84
|
-
|
|
85
|
-
);
|
|
83
|
+
factory = ZoraFactoryImpl(address(new ZoraFactory(address(factoryImpl))));
|
|
84
|
+
|
|
85
|
+
ZoraFactoryImpl(factory).initialize(users.factoryOwner);
|
|
86
86
|
|
|
87
87
|
vm.label(address(factory), "ZORA_FACTORY");
|
|
88
88
|
vm.label(address(protocolRewards), "PROTOCOL_REWARDS");
|
package/abis/Deploy.json
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"type": "function",
|
|
4
|
-
"name": "IS_SCRIPT",
|
|
5
|
-
"inputs": [],
|
|
6
|
-
"outputs": [
|
|
7
|
-
{
|
|
8
|
-
"name": "",
|
|
9
|
-
"type": "bool",
|
|
10
|
-
"internalType": "bool"
|
|
11
|
-
}
|
|
12
|
-
],
|
|
13
|
-
"stateMutability": "view"
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
"type": "function",
|
|
17
|
-
"name": "run",
|
|
18
|
-
"inputs": [],
|
|
19
|
-
"outputs": [],
|
|
20
|
-
"stateMutability": "nonpayable"
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
"type": "function",
|
|
24
|
-
"name": "setUp",
|
|
25
|
-
"inputs": [],
|
|
26
|
-
"outputs": [],
|
|
27
|
-
"stateMutability": "nonpayable"
|
|
28
|
-
}
|
|
29
|
-
]
|
package/addresses/1.json
DELETED