@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.
- package/.turbo/turbo-build.log +76 -0
- package/CHANGELOG.md +14 -0
- package/LICENSE +21 -0
- package/abis/Address.json +29 -0
- package/abis/BaseTest.json +691 -0
- package/abis/Clones.json +7 -0
- package/abis/Coin.json +1693 -0
- package/abis/CoinConstants.json +93 -0
- package/abis/CoinTest.json +998 -0
- package/abis/ContextUpgradeable.json +25 -0
- package/abis/ContractVersionBase.json +15 -0
- package/abis/Deploy.json +29 -0
- package/abis/ECDSA.json +29 -0
- package/abis/EIP712.json +67 -0
- package/abis/EIP712Upgradeable.json +74 -0
- package/abis/ERC1967Proxy.json +67 -0
- package/abis/ERC1967Utils.json +85 -0
- package/abis/ERC20PermitUpgradeable.json +527 -0
- package/abis/ERC20Upgradeable.json +333 -0
- package/abis/FactoryTest.json +845 -0
- package/abis/IBeacon.json +15 -0
- package/abis/ICoin.json +541 -0
- package/abis/ICoinComments.json +53 -0
- package/abis/IERC1155Errors.json +104 -0
- package/abis/IERC165.json +21 -0
- package/abis/IERC1822Proxiable.json +15 -0
- package/abis/IERC20.json +221 -0
- package/abis/IERC20Errors.json +88 -0
- package/abis/IERC20Metadata.json +224 -0
- package/abis/IERC20Permit.json +77 -0
- package/abis/IERC5267.json +51 -0
- package/abis/IERC721.json +287 -0
- package/abis/IERC721Enumerable.json +343 -0
- package/abis/IERC721Errors.json +105 -0
- package/abis/IERC721Metadata.json +332 -0
- package/abis/IERC721Receiver.json +36 -0
- package/abis/IERC721TokenReceiver.json +36 -0
- package/abis/IERC7572.json +21 -0
- package/abis/IMulticall3.json +440 -0
- package/abis/INonfungiblePositionManager.json +366 -0
- package/abis/IProtocolRewards.json +348 -0
- package/abis/ISwapRouter.json +137 -0
- package/abis/IUniswapV3Pool.json +148 -0
- package/abis/IUniswapV3SwapCallback.json +25 -0
- package/abis/IVersionedContract.json +15 -0
- package/abis/IWETH.json +118 -0
- package/abis/IZoraFactory.json +138 -0
- package/abis/Initializable.json +25 -0
- package/abis/Math.json +7 -0
- package/abis/MockERC20.json +322 -0
- package/abis/MockERC721.json +350 -0
- package/abis/MultiOwnable.json +171 -0
- package/abis/MultiOwnableTest.json +796 -0
- package/abis/NoncesUpgradeable.json +60 -0
- package/abis/OwnableUpgradeable.json +99 -0
- package/abis/ProtocolRewards.json +494 -0
- package/abis/Proxy.json +6 -0
- package/abis/ReentrancyGuardUpgradeable.json +30 -0
- package/abis/SafeERC20.json +34 -0
- package/abis/Script.json +15 -0
- package/abis/ShortStrings.json +18 -0
- package/abis/StdAssertions.json +379 -0
- package/abis/StdInvariant.json +180 -0
- package/abis/Strings.json +18 -0
- package/abis/Test.json +570 -0
- package/abis/UUPSUpgradeable.json +130 -0
- package/abis/Vm.json +8627 -0
- package/abis/VmSafe.json +7297 -0
- package/abis/ZoraFactory.json +67 -0
- package/abis/ZoraFactoryImpl.json +422 -0
- package/abis/stdError.json +119 -0
- package/abis/stdStorageSafe.json +52 -0
- package/addresses/1.json +4 -0
- package/addresses/8453.json +9 -0
- package/addresses/84532.json +9 -0
- package/dist/index.cjs +1236 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1208 -0
- package/dist/index.js.map +1 -0
- package/dist/wagmiGenerated.d.ts +1645 -0
- package/dist/wagmiGenerated.d.ts.map +1 -0
- package/foundry.toml +9 -0
- package/package/index.ts +1 -0
- package/package/wagmiGenerated.ts +1211 -0
- package/package.json +48 -0
- package/remappings.txt +4 -0
- package/script/Deploy.s.sol +14 -0
- package/slither.config.json +6 -0
- package/src/Coin.sol +579 -0
- package/src/ZoraFactoryImpl.sol +142 -0
- package/src/interfaces/ICoin.sol +194 -0
- package/src/interfaces/ICoinComments.sol +8 -0
- package/src/interfaces/IERC7572.sol +12 -0
- package/src/interfaces/INonfungiblePositionManager.sol +104 -0
- package/src/interfaces/IProtocolRewards.sol +12 -0
- package/src/interfaces/ISwapRouter.sol +38 -0
- package/src/interfaces/IUniswapV3Pool.sol +43 -0
- package/src/interfaces/IUniswapV3SwapCallback.sol +17 -0
- package/src/interfaces/IWETH.sol +16 -0
- package/src/interfaces/IZoraFactory.sol +56 -0
- package/src/proxy/ZoraFactory.sol +26 -0
- package/src/utils/CoinConstants.sol +67 -0
- package/src/utils/MultiOwnable.sol +126 -0
- package/src/utils/TickMath.sol +210 -0
- package/src/version/ContractVersionBase.sol +14 -0
- package/test/Coin.t.sol +443 -0
- package/test/Factory.t.sol +298 -0
- package/test/MultiOwnable.t.sol +156 -0
- package/test/utils/BaseTest.sol +178 -0
- package/test/utils/ProtocolRewards.sol +1499 -0
- package/tsconfig.build.json +10 -0
- package/tsconfig.json +9 -0
- package/tsup.config.ts +11 -0
- 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
|
+
}
|