@zoralabs/coins 0.9.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +179 -114
- package/CHANGELOG.md +46 -0
- package/abis/BaseCoin.json +26 -118
- package/abis/BaseTest.json +47 -0
- package/abis/BuySupplyWithSwapRouterHook.json +40 -0
- package/abis/Coin.json +171 -63
- package/abis/CoinDopplerMultiCurve.json +38 -0
- package/abis/CoinRewardsV4.json +54 -0
- package/abis/CoinTest.json +53 -20
- package/abis/CoinUniV4Test.json +1091 -0
- package/abis/CoinV4.json +234 -211
- package/abis/DeployScript.json +47 -0
- package/abis/DeployedCoinVersionLookup.json +21 -0
- package/abis/DeployedCoinVersionLookupTest.json +716 -0
- package/abis/DifferentNamespaceVersionLookup.json +39 -0
- package/abis/DopplerUniswapV3Test.json +49 -93
- package/abis/ERC20.json +310 -0
- package/abis/FactoryTest.json +85 -7
- package/abis/FeeEstimatorHook.json +1515 -0
- package/abis/HooksDeployment.json +23 -0
- package/abis/HooksTest.json +60 -0
- package/abis/ICoin.json +40 -71
- package/abis/ICoinV3.json +879 -0
- package/abis/ICoinV4.json +915 -0
- package/abis/IDeployedCoinVersionLookup.json +21 -0
- package/abis/IERC721.json +36 -36
- package/abis/IHasPoolKey.json +42 -0
- package/abis/IHasRewardsRecipients.json +54 -0
- package/abis/IHasSwapPath.json +60 -0
- package/abis/IMsgSender.json +15 -0
- package/abis/IPoolConfigEncoding.json +46 -0
- package/abis/ISwapPathRouter.json +92 -0
- package/abis/IUniversalRouter.json +61 -0
- package/abis/IUnlockCallback.json +21 -0
- package/abis/IV4Quoter.json +310 -0
- package/abis/IZoraFactory.json +210 -11
- package/abis/IZoraV4CoinHook.json +348 -4
- package/abis/MockERC20.json +21 -0
- package/abis/MultiOwnableTest.json +47 -0
- package/abis/{CoinConfigurationVersions.json → Position.json} +1 -1
- package/abis/PrintUpgradeCommand.json +9 -0
- package/abis/ProxyShim.json +24 -0
- package/abis/StateLibrary.json +80 -0
- package/abis/TestDeployedCoinVersionLookupImplementation.json +39 -0
- package/abis/TestV4Swap.json +9 -0
- package/abis/UpgradeCoinImpl.json +47 -0
- package/abis/UpgradesTest.json +81 -0
- package/abis/Vm.json +1482 -111
- package/abis/VmSafe.json +856 -32
- package/abis/ZoraFactoryImpl.json +339 -1
- package/abis/ZoraV4CoinHook.json +442 -5
- package/addresses/8453.json +7 -4
- package/addresses/84532.json +8 -5
- package/addresses/dev/8453.json +10 -0
- package/dist/index.cjs +1932 -167
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1928 -167
- package/dist/index.js.map +1 -1
- package/dist/wagmiGenerated.d.ts +2606 -160
- package/dist/wagmiGenerated.d.ts.map +1 -1
- package/foundry.toml +1 -0
- package/package/wagmiGenerated.ts +1941 -164
- package/package.json +8 -3
- package/remappings.txt +6 -1
- package/script/Deploy.s.sol +1 -1
- package/script/DeployDevFactory.s.sol +21 -0
- package/script/DeployHooks.s.sol +1 -1
- package/script/PrintUpgradeCommand.s.sol +13 -0
- package/script/Simulate.s.sol +1 -10
- package/script/TestBackingCoinSwap.s.sol +147 -0
- package/script/TestV4Swap.s.sol +136 -0
- package/script/UpgradeCoinImpl.sol +2 -2
- package/script/UpgradeFactoryImpl.s.sol +2 -2
- package/src/BaseCoin.sol +190 -0
- package/src/Coin.sol +87 -202
- package/src/CoinV4.sol +121 -0
- package/src/ZoraFactoryImpl.sol +208 -36
- package/{script → src/deployment}/CoinsDeployerBase.sol +111 -17
- package/src/hooks/ZoraV4CoinHook.sol +212 -0
- package/src/hooks/{BaseCoinDeployHook.sol → deployment/BaseCoinDeployHook.sol} +3 -3
- package/src/hooks/deployment/BuySupplyWithSwapRouterHook.sol +140 -0
- package/src/interfaces/ICoin.sol +31 -39
- package/src/interfaces/ICoinV3.sol +71 -0
- package/src/interfaces/ICoinV4.sol +69 -0
- package/src/interfaces/IDeployedCoinVersionLookup.sol +11 -0
- package/src/interfaces/IMsgSender.sol +9 -0
- package/src/interfaces/IPoolConfigEncoding.sol +14 -0
- package/src/interfaces/ISwapPathRouter.sol +14 -0
- package/src/interfaces/IZoraFactory.sol +67 -28
- package/src/interfaces/IZoraV4CoinHook.sol +116 -0
- package/src/libs/CoinCommon.sol +15 -0
- package/src/libs/CoinConfigurationVersions.sol +116 -1
- package/src/libs/CoinConstants.sol +5 -0
- package/src/libs/CoinDopplerMultiCurve.sol +134 -0
- package/src/libs/CoinDopplerUniV3.sol +19 -171
- package/src/libs/CoinRewards.sol +195 -0
- package/src/libs/CoinRewardsV4.sol +179 -0
- package/src/libs/CoinSetup.sol +57 -0
- package/src/libs/CoinSetupV3.sol +6 -67
- package/src/libs/DopplerMath.sol +156 -0
- package/src/libs/HooksDeployment.sol +128 -0
- package/src/libs/MarketConstants.sol +4 -0
- package/src/libs/PoolStateReader.sol +22 -0
- package/src/libs/UniV3BuySell.sol +74 -292
- package/src/libs/UniV4SwapHelper.sol +65 -0
- package/src/libs/UniV4SwapToCurrency.sol +109 -0
- package/src/libs/V4Liquidity.sol +122 -0
- package/src/types/PoolConfiguration.sol +15 -0
- package/src/utils/DeployedCoinVersionLookup.sol +52 -0
- package/src/version/ContractVersionBase.sol +1 -1
- package/test/Coin.t.sol +78 -88
- package/test/CoinDopplerUniV3.t.sol +32 -171
- package/test/CoinUniV4.t.sol +777 -0
- package/test/{Hooks.t.sol → DeploymentHooks.t.sol} +53 -16
- package/test/Factory.t.sol +80 -47
- package/test/MultiOwnable.t.sol +6 -3
- package/test/Upgrades.t.sol +97 -5
- package/test/mocks/MockERC20.sol +12 -0
- package/test/utils/BaseTest.sol +162 -57
- package/test/utils/DeployedCoinVersionLookup.t.sol +127 -0
- package/test/utils/FeeEstimatorHook.sol +84 -0
- package/test/utils/ProxyShim.sol +17 -0
- package/wagmi.config.ts +4 -0
- package/.env +0 -1
- package/.turbo/turbo-update-contract-version.log +0 -22
- package/abis/CoinSetupV3.json +0 -7
- package/abis/HookDeployer.json +0 -68
- package/abis/IHookDeployer.json +0 -42
- package/src/hooks/BuySupplyWithSwapRouterHook.sol +0 -78
- package/src/libs/CoinLegacy.sol +0 -48
- package/src/libs/CoinLegacyMarket.sol +0 -182
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.23;
|
|
3
|
+
|
|
4
|
+
import {BaseHook} from "@uniswap/v4-periphery/src/utils/BaseHook.sol";
|
|
5
|
+
import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol";
|
|
6
|
+
import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
|
|
7
|
+
import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
|
|
8
|
+
import {BalanceDelta, BalanceDeltaLibrary} from "@uniswap/v4-core/src/types/BalanceDelta.sol";
|
|
9
|
+
import {SwapParams} from "@uniswap/v4-core/src/types/PoolOperation.sol";
|
|
10
|
+
import {IZoraV4CoinHook} from "../interfaces/IZoraV4CoinHook.sol";
|
|
11
|
+
import {IMsgSender} from "../interfaces/IMsgSender.sol";
|
|
12
|
+
import {IHasSwapPath} from "../interfaces/ICoinV4.sol";
|
|
13
|
+
import {LpPosition} from "../types/LpPosition.sol";
|
|
14
|
+
import {V4Liquidity} from "../libs/V4Liquidity.sol";
|
|
15
|
+
import {CoinRewardsV4} from "../libs/CoinRewardsV4.sol";
|
|
16
|
+
import {ICoinV4} from "../interfaces/ICoinV4.sol";
|
|
17
|
+
import {IDeployedCoinVersionLookup} from "../interfaces/IDeployedCoinVersionLookup.sol";
|
|
18
|
+
import {Currency} from "@uniswap/v4-core/src/types/Currency.sol";
|
|
19
|
+
import {CoinCommon} from "../libs/CoinCommon.sol";
|
|
20
|
+
import {PoolConfiguration} from "../types/PoolConfiguration.sol";
|
|
21
|
+
import {CoinDopplerMultiCurve} from "../libs/CoinDopplerMultiCurve.sol";
|
|
22
|
+
import {PoolStateReader} from "../libs/PoolStateReader.sol";
|
|
23
|
+
import {IHasSwapPath} from "../interfaces/ICoinV4.sol";
|
|
24
|
+
import {CoinConfigurationVersions} from "../libs/CoinConfigurationVersions.sol";
|
|
25
|
+
|
|
26
|
+
/// @title ZoraV4CoinHook
|
|
27
|
+
/// @notice Uniswap V4 hook that automatically handles fee collection and reward distributions on every swap,
|
|
28
|
+
/// paying out all rewards in a backing currency.
|
|
29
|
+
/// @dev This hook executes on afterSwap withdraw fees, swap for a backing currency, and distribute rewards.
|
|
30
|
+
/// On pool initialization, it creates multiple liquidity positions based on the coin's pool configuration.
|
|
31
|
+
/// On every swap, it automatically:
|
|
32
|
+
/// 1. Collects accrued LP fees from all positions
|
|
33
|
+
/// 2. Swaps collected fees to the backing currency through multi-hop paths
|
|
34
|
+
/// 3. Distributes converted fees as rewards
|
|
35
|
+
/// @author oveddan
|
|
36
|
+
contract ZoraV4CoinHook is BaseHook, IZoraV4CoinHook {
|
|
37
|
+
using BalanceDeltaLibrary for BalanceDelta;
|
|
38
|
+
|
|
39
|
+
/// @notice Mapping of trusted message senders - these are addresses that are trusted to provide a
|
|
40
|
+
/// an original msg.sender
|
|
41
|
+
mapping(address => bool) internal trustedMessageSender;
|
|
42
|
+
|
|
43
|
+
/// @notice Mapping of pool keys to coins.
|
|
44
|
+
mapping(bytes32 => IZoraV4CoinHook.PoolCoin) internal poolCoins;
|
|
45
|
+
|
|
46
|
+
/// @notice The coin version lookup contract - used to determine if an address is a coin and what version it is.
|
|
47
|
+
IDeployedCoinVersionLookup internal immutable coinVersionLookup;
|
|
48
|
+
|
|
49
|
+
/// @notice The constructor for the ZoraV4CoinHook.
|
|
50
|
+
/// @param poolManager_ The Uniswap V4 pool manager
|
|
51
|
+
/// @param coinVersionLookup_ The coin version lookup contract - used to determine if an address is a coin and what version it is.
|
|
52
|
+
/// @param trustedMessageSenders_ The addresses of the trusted message senders - these are addresses that are trusted to provide a
|
|
53
|
+
constructor(IPoolManager poolManager_, IDeployedCoinVersionLookup coinVersionLookup_, address[] memory trustedMessageSenders_) BaseHook(poolManager_) {
|
|
54
|
+
if (address(coinVersionLookup_) == address(0)) {
|
|
55
|
+
revert CoinVersionLookupCannotBeZeroAddress();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
coinVersionLookup = coinVersionLookup_;
|
|
59
|
+
|
|
60
|
+
for (uint256 i = 0; i < trustedMessageSenders_.length; i++) {
|
|
61
|
+
trustedMessageSender[trustedMessageSenders_[i]] = true;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/// @notice Returns the uniswap v4 hook settings / permissions.
|
|
66
|
+
/// @dev The permissions currently requested are: afterInitialize and afterSwap.
|
|
67
|
+
function getHookPermissions() public pure override returns (Hooks.Permissions memory) {
|
|
68
|
+
return
|
|
69
|
+
Hooks.Permissions({
|
|
70
|
+
beforeInitialize: false,
|
|
71
|
+
afterInitialize: true,
|
|
72
|
+
beforeAddLiquidity: false,
|
|
73
|
+
afterAddLiquidity: false,
|
|
74
|
+
beforeRemoveLiquidity: false,
|
|
75
|
+
afterRemoveLiquidity: false,
|
|
76
|
+
beforeSwap: false,
|
|
77
|
+
afterSwap: true,
|
|
78
|
+
beforeDonate: false,
|
|
79
|
+
afterDonate: false,
|
|
80
|
+
beforeSwapReturnDelta: false,
|
|
81
|
+
afterSwapReturnDelta: false,
|
|
82
|
+
afterAddLiquidityReturnDelta: false,
|
|
83
|
+
afterRemoveLiquidityReturnDelta: false
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/// @inheritdoc IZoraV4CoinHook
|
|
88
|
+
function isTrustedMessageSender(address sender) external view returns (bool) {
|
|
89
|
+
return trustedMessageSender[sender];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/// @inheritdoc IZoraV4CoinHook
|
|
93
|
+
function getPoolCoinByHash(bytes23 poolKeyHash) external view returns (IZoraV4CoinHook.PoolCoin memory) {
|
|
94
|
+
return poolCoins[poolKeyHash];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/// @inheritdoc IZoraV4CoinHook
|
|
98
|
+
function getPoolCoin(PoolKey memory key) external view returns (IZoraV4CoinHook.PoolCoin memory) {
|
|
99
|
+
return poolCoins[CoinCommon.hashPoolKey(key)];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/// @notice Internal fn generating the positions for a given pool key.
|
|
103
|
+
/// @param coin The coin address.
|
|
104
|
+
/// @param key The pool key for the coin.
|
|
105
|
+
/// @return positions The contract-created liquidity positions the positions for the coin's pool.
|
|
106
|
+
function _generatePositions(ICoinV4 coin, PoolKey memory key) internal view returns (LpPosition[] memory positions) {
|
|
107
|
+
bool isCoinToken0 = Currency.unwrap(key.currency0) == address(coin);
|
|
108
|
+
|
|
109
|
+
positions = CoinDopplerMultiCurve.calculatePositions(isCoinToken0, coin.getPoolConfiguration());
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/// @notice Internal fn called when a pool is initialized.
|
|
113
|
+
/// @dev This hook is called from BaseHook library from uniswap v4.
|
|
114
|
+
/// @param sender The address of the sender.
|
|
115
|
+
/// @param key The pool key.
|
|
116
|
+
/// @return selector The selector of the afterInitialize hook to confirm the action.
|
|
117
|
+
function _afterInitialize(address sender, PoolKey calldata key, uint160, int24) internal override returns (bytes4) {
|
|
118
|
+
address coin = sender;
|
|
119
|
+
if (!CoinConfigurationVersions.isV4(coinVersionLookup.getVersionForDeployedCoin(coin))) {
|
|
120
|
+
revert NotACoin(coin);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
LpPosition[] memory positions = _generatePositions(ICoinV4(coin), key);
|
|
124
|
+
|
|
125
|
+
poolCoins[CoinCommon.hashPoolKey(key)] = PoolCoin({coin: coin, positions: positions});
|
|
126
|
+
|
|
127
|
+
V4Liquidity.lockAndMint(poolManager, key, positions);
|
|
128
|
+
|
|
129
|
+
return BaseHook.afterInitialize.selector;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/// @notice Internal fn called when a swap is executed.
|
|
133
|
+
/// @dev This hook is called from BaseHook library from uniswap v4.
|
|
134
|
+
/// This hook:
|
|
135
|
+
/// 1. Collects accrued LP fees from all positions
|
|
136
|
+
/// 2. Swaps collected fees to the backing currency through multi-hop paths
|
|
137
|
+
/// 3. Distributes converted fees as rewards
|
|
138
|
+
/// @param sender The address of the sender.
|
|
139
|
+
/// @param key The pool key.
|
|
140
|
+
/// @param params The swap parameters.
|
|
141
|
+
/// @param delta The balance delta.
|
|
142
|
+
/// @param hookData The hook data.
|
|
143
|
+
/// @return selector The selector of the afterSwap hook to confirm the action.
|
|
144
|
+
function _afterSwap(
|
|
145
|
+
address sender,
|
|
146
|
+
PoolKey calldata key,
|
|
147
|
+
SwapParams calldata params,
|
|
148
|
+
BalanceDelta delta,
|
|
149
|
+
bytes calldata hookData
|
|
150
|
+
) internal virtual override returns (bytes4, int128) {
|
|
151
|
+
bytes32 poolKeyHash = CoinCommon.hashPoolKey(key);
|
|
152
|
+
|
|
153
|
+
// get the coin address and positions for the pool key; they must have been set in the afterInitialize callback
|
|
154
|
+
address coin = poolCoins[poolKeyHash].coin;
|
|
155
|
+
require(coin != address(0), NoCoinForHook(key));
|
|
156
|
+
|
|
157
|
+
// get path for swapping the payout to a single currency
|
|
158
|
+
IHasSwapPath.PayoutSwapPath memory payoutSwapPath = IHasSwapPath(coin).getPayoutSwapPath(coinVersionLookup);
|
|
159
|
+
|
|
160
|
+
// Collect accrued LP fees from all positions, swap them to the target payout currency,
|
|
161
|
+
// and transfer the converted amount to this hook contract for distribution
|
|
162
|
+
(, , Currency receivedCurrency, uint128 receivedAmount) = CoinRewardsV4.collectFeesAndConvertToPayout(
|
|
163
|
+
poolManager,
|
|
164
|
+
key,
|
|
165
|
+
poolCoins[poolKeyHash].positions,
|
|
166
|
+
payoutSwapPath
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
// Distribute the collected and converted fees to all reward recipients (creator, referrers, protocol, etc.)
|
|
170
|
+
CoinRewardsV4.distributeMarketRewards(receivedCurrency, receivedAmount, ICoinV4(coin), CoinRewardsV4.getTradeReferral(hookData));
|
|
171
|
+
|
|
172
|
+
{
|
|
173
|
+
(address swapper, bool isTrustedSwapSenderAddress) = _getOriginalMsgSender(sender);
|
|
174
|
+
bool isCoinBuy = params.zeroForOne ? Currency.unwrap(key.currency1) == address(coin) : Currency.unwrap(key.currency0) == address(coin);
|
|
175
|
+
emit Swapped(
|
|
176
|
+
sender,
|
|
177
|
+
swapper,
|
|
178
|
+
isTrustedSwapSenderAddress,
|
|
179
|
+
key,
|
|
180
|
+
poolKeyHash,
|
|
181
|
+
params,
|
|
182
|
+
delta.amount0(),
|
|
183
|
+
delta.amount1(),
|
|
184
|
+
isCoinBuy,
|
|
185
|
+
hookData,
|
|
186
|
+
PoolStateReader.getSqrtPriceX96(key, poolManager)
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return (BaseHook.afterSwap.selector, 0);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/// @notice Internal fn called when the PoolManager is unlocked. Used to mint initial liquidity positions.
|
|
194
|
+
function unlockCallback(bytes calldata data) external onlyPoolManager returns (bytes memory) {
|
|
195
|
+
V4Liquidity.handleMintPositionsCallback(poolManager, data);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/// @notice Internal fn to get the original message sender.
|
|
199
|
+
/// @param sender The address of the sender.
|
|
200
|
+
/// @return swapper The original message sender.
|
|
201
|
+
/// @return senderIsTrusted Whether the sender is a trusted message sender.
|
|
202
|
+
function _getOriginalMsgSender(address sender) internal view returns (address swapper, bool senderIsTrusted) {
|
|
203
|
+
senderIsTrusted = trustedMessageSender[sender];
|
|
204
|
+
|
|
205
|
+
// If getter function reverts, we return a 0 address by default and continue execution.
|
|
206
|
+
try IMsgSender(sender).msgSender() returns (address _swapper) {
|
|
207
|
+
swapper = _swapper;
|
|
208
|
+
} catch {
|
|
209
|
+
swapper = address(0);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
pragma solidity ^0.8.13;
|
|
3
3
|
|
|
4
|
-
import {ICoin} from "
|
|
5
|
-
import {IZoraFactory} from "
|
|
6
|
-
import {ICoinDeployHook} from "
|
|
4
|
+
import {ICoin} from "../../interfaces/ICoin.sol";
|
|
5
|
+
import {IZoraFactory} from "../../interfaces/IZoraFactory.sol";
|
|
6
|
+
import {ICoinDeployHook} from "../../interfaces/ICoinDeployHook.sol";
|
|
7
7
|
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
|
|
8
8
|
|
|
9
9
|
/// @title Immutable State
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.23;
|
|
3
|
+
|
|
4
|
+
import {BaseCoinDeployHook} from "./BaseCoinDeployHook.sol";
|
|
5
|
+
import {ICoin} from "../../interfaces/ICoin.sol";
|
|
6
|
+
import {IZoraFactory} from "../../interfaces/IZoraFactory.sol";
|
|
7
|
+
import {ISwapRouter} from "../../interfaces/ISwapRouter.sol";
|
|
8
|
+
import {IWETH} from "../../interfaces/IWETH.sol";
|
|
9
|
+
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
10
|
+
import {Coin} from "../../Coin.sol";
|
|
11
|
+
import {ICoinV3} from "../../interfaces/ICoinV3.sol";
|
|
12
|
+
import {ICoinV4} from "../../interfaces/ICoinV4.sol";
|
|
13
|
+
import {CoinConfigurationVersions} from "../../libs/CoinConfigurationVersions.sol";
|
|
14
|
+
import {Currency} from "@uniswap/v4-core/src/types/Currency.sol";
|
|
15
|
+
import {IPoolManager, SwapParams} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
|
|
16
|
+
import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol";
|
|
17
|
+
import {BalanceDelta, BalanceDeltaLibrary} from "@uniswap/v4-core/src/types/BalanceDelta.sol";
|
|
18
|
+
|
|
19
|
+
/// @title BuySupplyWithSwapRouter
|
|
20
|
+
/// @notice A hook that buys supply for a coin that is priced in an erc20 token a backing currency, using a Uniswap V3 SwapRouter.
|
|
21
|
+
/// Supports both single-hop and multi-hop swaps using uniswap v3. Supports buying the coin supply whether the coin is a v3 or v4 coin.
|
|
22
|
+
/// @author @oveddan
|
|
23
|
+
contract BuySupplyWithSwapRouterHook is BaseCoinDeployHook {
|
|
24
|
+
ISwapRouter immutable swapRouter;
|
|
25
|
+
IPoolManager immutable poolManager;
|
|
26
|
+
using BalanceDeltaLibrary for BalanceDelta;
|
|
27
|
+
|
|
28
|
+
error Erc20NotReceived();
|
|
29
|
+
error InvalidSwapRouterCall();
|
|
30
|
+
error SwapReverted(bytes error);
|
|
31
|
+
error CoinBalanceNot0(uint256 balance);
|
|
32
|
+
error CurrencyBalanceNot0(uint256 balance);
|
|
33
|
+
|
|
34
|
+
constructor(IZoraFactory _factory, address _swapRouter, address _poolManager) BaseCoinDeployHook(_factory) {
|
|
35
|
+
swapRouter = ISwapRouter(_swapRouter);
|
|
36
|
+
poolManager = IPoolManager(_poolManager);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/// @notice Hook that buys supply for a coin that is priced in an erc20 token with ETH, using a Uniswap SwapRouter.
|
|
40
|
+
/// Returns abi encoded (uint256 amountCurrency, uint256 coinsPurchased) - amountCurrency is the amount of currency received from the swap and sent to the coin for the purchase,
|
|
41
|
+
/// and coinsPurchased is the amount of coins purchased using the amountCurrency that was received from the swap
|
|
42
|
+
function _afterCoinDeploy(address, ICoin coin, bytes calldata hookData) internal override returns (bytes memory) {
|
|
43
|
+
address currency = coin.currency();
|
|
44
|
+
|
|
45
|
+
(address buyRecipient, bytes memory swapRouterCall) = abi.decode(hookData, (address, bytes));
|
|
46
|
+
|
|
47
|
+
uint256 amountCurrency = _handleSwap(currency, swapRouterCall);
|
|
48
|
+
|
|
49
|
+
uint256 coinsPurchased = _handleBuy(buyRecipient, coin, amountCurrency);
|
|
50
|
+
|
|
51
|
+
return abi.encode(amountCurrency, coinsPurchased);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function _handleSwap(address currency_, bytes memory swapRouterCall) internal returns (uint256 amountCurrency) {
|
|
55
|
+
// call the swap router, with the msg.value
|
|
56
|
+
_validateSwapRouterCall(swapRouterCall);
|
|
57
|
+
|
|
58
|
+
(bool success, bytes memory result) = address(swapRouter).call{value: msg.value}(swapRouterCall);
|
|
59
|
+
|
|
60
|
+
require(success, SwapReverted(result));
|
|
61
|
+
|
|
62
|
+
amountCurrency = abi.decode(result, (uint256));
|
|
63
|
+
|
|
64
|
+
// validate that this contract received the correct amount of currency
|
|
65
|
+
require(IERC20(currency_).balanceOf(address(this)) == amountCurrency, Erc20NotReceived());
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function _validateSwapRouterCall(bytes memory swapRouterCall) internal pure {
|
|
69
|
+
// validate that the swap router call is valid - only exactInput and exactInputSingle are supported
|
|
70
|
+
|
|
71
|
+
bytes4 selector = _getSelectorFromCall(swapRouterCall);
|
|
72
|
+
|
|
73
|
+
require(selector == ISwapRouter.exactInput.selector || selector == ISwapRouter.exactInputSingle.selector, InvalidSwapRouterCall());
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function _getSelectorFromCall(bytes memory _call) internal pure returns (bytes4 selector) {
|
|
77
|
+
assembly {
|
|
78
|
+
selector := mload(add(_call, 32))
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function _handleBuy(address buyRecipient, ICoin coin, uint256 amountCurrency) internal returns (uint256 coinsPurchased) {
|
|
83
|
+
IERC20(coin.currency()).approve(address(coin), amountCurrency);
|
|
84
|
+
|
|
85
|
+
if (CoinConfigurationVersions.isV4(factory.getVersionForDeployedCoin(address(coin)))) {
|
|
86
|
+
coinsPurchased = _executeV4Buy(buyRecipient, ICoinV4(payable(address(coin))), amountCurrency);
|
|
87
|
+
} else {
|
|
88
|
+
coinsPurchased = _executeV3Buy(buyRecipient, ICoinV3(payable(address(coin))), amountCurrency);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// make sure that this contract has no balance of the coin remaining
|
|
92
|
+
uint256 coinBalance = IERC20(address(coin)).balanceOf(address(this));
|
|
93
|
+
require(coinBalance == 0, CoinBalanceNot0(coinBalance));
|
|
94
|
+
// make sure that this contract has no balance of the currency remaining
|
|
95
|
+
uint256 currencyBalance = IERC20(coin.currency()).balanceOf(address(this));
|
|
96
|
+
require(currencyBalance == 0, CurrencyBalanceNot0(currencyBalance));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function _executeV3Buy(address buyRecipient, ICoinV3 coin, uint256 amountCurrency) internal returns (uint256 coinsPurchased) {
|
|
100
|
+
(, coinsPurchased) = ICoinV3(payable(address(coin))).buy(buyRecipient, amountCurrency, 0, 0, address(0));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function _executeV4Buy(address buyRecipient, ICoinV4 coin, uint256 amountCurrency) internal returns (uint256 coinsPurchased) {
|
|
104
|
+
bytes memory data = abi.encode(buyRecipient, coin, amountCurrency);
|
|
105
|
+
|
|
106
|
+
bytes memory result = poolManager.unlock(data);
|
|
107
|
+
|
|
108
|
+
coinsPurchased = abi.decode(result, (uint256));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
error OnlyPoolManager();
|
|
112
|
+
|
|
113
|
+
/// @notice Internal fn called when the PoolManager is unlocked. Used to swap the backing currency for the coin.
|
|
114
|
+
function unlockCallback(bytes calldata data) external returns (bytes memory) {
|
|
115
|
+
require(msg.sender == address(poolManager), OnlyPoolManager());
|
|
116
|
+
|
|
117
|
+
(address buyRecipient, ICoinV4 coin, uint256 amountCurrency) = abi.decode(data, (address, ICoinV4, uint256));
|
|
118
|
+
|
|
119
|
+
bool zeroForOne = coin.currency() == Currency.unwrap(coin.getPoolKey().currency0);
|
|
120
|
+
|
|
121
|
+
BalanceDelta delta = poolManager.swap(
|
|
122
|
+
coin.getPoolKey(),
|
|
123
|
+
SwapParams(zeroForOne, -(int128(uint128(amountCurrency))), zeroForOne ? TickMath.MIN_SQRT_PRICE + 1 : TickMath.MAX_SQRT_PRICE - 1),
|
|
124
|
+
""
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
int128 amountCoin = zeroForOne ? delta.amount1() : delta.amount0();
|
|
128
|
+
|
|
129
|
+
// sync the currency balance before transferring to the pool manager
|
|
130
|
+
poolManager.sync(Currency.wrap(coin.currency()));
|
|
131
|
+
// transfer the currency to the pool manager for the swap
|
|
132
|
+
IERC20(coin.currency()).transfer(address(poolManager), uint256(uint128(amountCurrency)));
|
|
133
|
+
// collect the coin from the pool manager
|
|
134
|
+
poolManager.take(Currency.wrap(address(coin)), buyRecipient, uint256(uint128(amountCoin)));
|
|
135
|
+
|
|
136
|
+
poolManager.settle();
|
|
137
|
+
|
|
138
|
+
return abi.encode(uint256(uint128(amountCoin)));
|
|
139
|
+
}
|
|
140
|
+
}
|
package/src/interfaces/ICoin.sol
CHANGED
|
@@ -4,18 +4,34 @@ pragma solidity ^0.8.23;
|
|
|
4
4
|
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
|
|
5
5
|
import {IERC7572} from "./IERC7572.sol";
|
|
6
6
|
import {IDopplerErrors} from "./IDopplerErrors.sol";
|
|
7
|
+
import {PoolKey} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
|
|
8
|
+
import {PoolConfiguration} from "../types/PoolConfiguration.sol";
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
/// @dev This is used to configure the pool's liquidity positions
|
|
10
|
-
struct PoolConfiguration {
|
|
10
|
+
struct PoolConfigurationV4 {
|
|
11
11
|
uint8 version;
|
|
12
|
-
|
|
13
|
-
int24
|
|
14
|
-
uint16 numPositions;
|
|
15
|
-
uint256 maxDiscoverySupplyShare;
|
|
12
|
+
PoolKey poolKey;
|
|
13
|
+
int24 tick;
|
|
16
14
|
}
|
|
17
15
|
|
|
18
|
-
|
|
16
|
+
struct PoolKeyStruct {
|
|
17
|
+
address currency0;
|
|
18
|
+
address currency1;
|
|
19
|
+
uint24 fee;
|
|
20
|
+
int24 tickSpacing;
|
|
21
|
+
address hooks;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface IHasRewardsRecipients {
|
|
25
|
+
function payoutRecipient() external view returns (address);
|
|
26
|
+
|
|
27
|
+
function platformReferrer() external view returns (address);
|
|
28
|
+
|
|
29
|
+
function protocolRewardRecipient() external view returns (address);
|
|
30
|
+
|
|
31
|
+
function dopplerFeeRecipient() external view returns (address);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface ICoin is IERC165, IERC7572, IDopplerErrors, IHasRewardsRecipients {
|
|
19
35
|
/// @notice Thrown when an operation is attempted with a zero address
|
|
20
36
|
error AddressZero();
|
|
21
37
|
|
|
@@ -73,6 +89,9 @@ interface ICoin is IERC165, IERC7572, IDopplerErrors {
|
|
|
73
89
|
/// @notice Thrown when a Doppler pool does not have more than 2 discovery positions
|
|
74
90
|
error DopplerPoolMustHaveMoreThan2DiscoveryPositions();
|
|
75
91
|
|
|
92
|
+
/// @notice Thrown when an invalid pool version is specified
|
|
93
|
+
error InvalidPoolVersion();
|
|
94
|
+
|
|
76
95
|
/// @notice The rewards accrued from the market's liquidity position
|
|
77
96
|
struct MarketRewards {
|
|
78
97
|
uint256 totalAmountCurrency;
|
|
@@ -177,33 +196,6 @@ interface ICoin is IERC165, IERC7572, IDopplerErrors {
|
|
|
177
196
|
/// @param name The coin name
|
|
178
197
|
event ContractMetadataUpdated(address indexed caller, string newURI, string name);
|
|
179
198
|
|
|
180
|
-
/// @notice Executes a buy order
|
|
181
|
-
/// @param recipient The recipient address of the coins
|
|
182
|
-
/// @param orderSize The amount of coins to buy
|
|
183
|
-
/// @param tradeReferrer The address of the trade referrer
|
|
184
|
-
/// @param sqrtPriceLimitX96 The price limit for Uniswap V3 pool swap
|
|
185
|
-
function buy(
|
|
186
|
-
address recipient,
|
|
187
|
-
uint256 orderSize,
|
|
188
|
-
uint256 minAmountOut,
|
|
189
|
-
uint160 sqrtPriceLimitX96,
|
|
190
|
-
address tradeReferrer
|
|
191
|
-
) external payable returns (uint256, uint256);
|
|
192
|
-
|
|
193
|
-
/// @notice Executes a sell order
|
|
194
|
-
/// @param recipient The recipient of the currency
|
|
195
|
-
/// @param orderSize The amount of coins to sell
|
|
196
|
-
/// @param minAmountOut The minimum amount of currency to receive
|
|
197
|
-
/// @param sqrtPriceLimitX96 The price limit for the swap
|
|
198
|
-
/// @param tradeReferrer The address of the trade referrer
|
|
199
|
-
function sell(
|
|
200
|
-
address recipient,
|
|
201
|
-
uint256 orderSize,
|
|
202
|
-
uint256 minAmountOut,
|
|
203
|
-
uint160 sqrtPriceLimitX96,
|
|
204
|
-
address tradeReferrer
|
|
205
|
-
) external returns (uint256, uint256);
|
|
206
|
-
|
|
207
199
|
/// @notice Enables a user to burn their tokens
|
|
208
200
|
/// @param amount The amount of tokens to burn
|
|
209
201
|
function burn(uint256 amount) external;
|
|
@@ -212,11 +204,11 @@ interface ICoin is IERC165, IERC7572, IDopplerErrors {
|
|
|
212
204
|
/// @return The token URI
|
|
213
205
|
function tokenURI() external view returns (string memory);
|
|
214
206
|
|
|
215
|
-
/// @notice Returns the address of the platform referrer
|
|
216
|
-
/// @return The platform referrer's address
|
|
217
|
-
function platformReferrer() external view returns (address);
|
|
218
|
-
|
|
219
207
|
/// @notice Returns the address of the currency
|
|
220
208
|
/// @return The currency's address
|
|
221
209
|
function currency() external view returns (address);
|
|
210
|
+
|
|
211
|
+
/// @notice Returns the address of the Airlock
|
|
212
|
+
/// @return The Airlock's address
|
|
213
|
+
function airlock() external view returns (address);
|
|
222
214
|
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.23;
|
|
3
|
+
|
|
4
|
+
import {ICoin} from "./ICoin.sol";
|
|
5
|
+
import {LpPosition} from "../types/LpPosition.sol";
|
|
6
|
+
import {PoolConfiguration} from "./ICoin.sol";
|
|
7
|
+
|
|
8
|
+
interface ICoinV3 is ICoin {
|
|
9
|
+
/// @notice Returns the WETH address
|
|
10
|
+
function WETH() external view returns (address);
|
|
11
|
+
|
|
12
|
+
/// @notice Returns the address of the Uniswap V3 factory
|
|
13
|
+
function v3Factory() external view returns (address);
|
|
14
|
+
|
|
15
|
+
/// @notice Initializes a new coin
|
|
16
|
+
/// @param payoutRecipient_ The address of the coin creator
|
|
17
|
+
/// @param tokenURI_ The metadata URI
|
|
18
|
+
/// @param name_ The coin name
|
|
19
|
+
/// @param symbol_ The coin symbol
|
|
20
|
+
/// @param platformReferrer_ The address of the platform referrer
|
|
21
|
+
/// @param currency_ The address of the currency
|
|
22
|
+
/// @param poolAddress_ The address of the pool
|
|
23
|
+
/// @param poolConfiguration_ The configuration of the pool
|
|
24
|
+
function initialize(
|
|
25
|
+
address payoutRecipient_,
|
|
26
|
+
address[] memory owners_,
|
|
27
|
+
string memory tokenURI_,
|
|
28
|
+
string memory name_,
|
|
29
|
+
string memory symbol_,
|
|
30
|
+
address platformReferrer_,
|
|
31
|
+
address currency_,
|
|
32
|
+
address poolAddress_,
|
|
33
|
+
PoolConfiguration memory poolConfiguration_,
|
|
34
|
+
LpPosition[] memory positions_
|
|
35
|
+
) external;
|
|
36
|
+
|
|
37
|
+
/// @notice Executes a buy order
|
|
38
|
+
/// @param recipient The recipient address of the coins
|
|
39
|
+
/// @param orderSize The amount of coins to buy
|
|
40
|
+
/// @param tradeReferrer The address of the trade referrer
|
|
41
|
+
/// @param sqrtPriceLimitX96 The price limit for Uniswap V3 pool swap
|
|
42
|
+
function buy(
|
|
43
|
+
address recipient,
|
|
44
|
+
uint256 orderSize,
|
|
45
|
+
uint256 minAmountOut,
|
|
46
|
+
uint160 sqrtPriceLimitX96,
|
|
47
|
+
address tradeReferrer
|
|
48
|
+
) external payable returns (uint256, uint256);
|
|
49
|
+
|
|
50
|
+
/// @notice Executes a sell order
|
|
51
|
+
/// @param recipient The recipient of the currency
|
|
52
|
+
/// @param orderSize The amount of coins to sell
|
|
53
|
+
/// @param minAmountOut The minimum amount of currency to receive
|
|
54
|
+
/// @param sqrtPriceLimitX96 The price limit for the swap
|
|
55
|
+
/// @param tradeReferrer The address of the trade referrer
|
|
56
|
+
function sell(
|
|
57
|
+
address recipient,
|
|
58
|
+
uint256 orderSize,
|
|
59
|
+
uint256 minAmountOut,
|
|
60
|
+
uint160 sqrtPriceLimitX96,
|
|
61
|
+
address tradeReferrer
|
|
62
|
+
) external returns (uint256, uint256);
|
|
63
|
+
|
|
64
|
+
/// @notice Force claim any accrued secondary rewards from the market's liquidity position.
|
|
65
|
+
/// @dev This function is a fallback, secondary rewards will be claimed automatically on each buy and sell.
|
|
66
|
+
/// @param pushEthRewards Whether to push the ETH directly to the recipients.
|
|
67
|
+
function claimSecondaryRewards(bool pushEthRewards) external;
|
|
68
|
+
|
|
69
|
+
/// @notice Returns the address of the Uniswap V3 pool
|
|
70
|
+
function poolAddress() external view returns (address);
|
|
71
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.23;
|
|
3
|
+
|
|
4
|
+
import {ICoin} from "./ICoin.sol";
|
|
5
|
+
import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
|
|
6
|
+
import {PoolConfiguration} from "../types/PoolConfiguration.sol";
|
|
7
|
+
import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol";
|
|
8
|
+
import {PathKey} from "@uniswap/v4-periphery/src/libraries/PathKey.sol";
|
|
9
|
+
import {Currency} from "@uniswap/v4-core/src/types/Currency.sol";
|
|
10
|
+
import {IDeployedCoinVersionLookup} from "./IDeployedCoinVersionLookup.sol";
|
|
11
|
+
|
|
12
|
+
/// @notice Returns the pool key for the coin
|
|
13
|
+
interface IHasPoolKey {
|
|
14
|
+
/// @notice Returns the Uniswap V4 pool key associated with this coin
|
|
15
|
+
/// @return The PoolKey struct containing pool identification parameters
|
|
16
|
+
function getPoolKey() external view returns (PoolKey memory);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/// @notice Returns the pool configuration for the coin
|
|
20
|
+
interface IHasSwapPath {
|
|
21
|
+
/// @notice Struct containing the swap path configuration for converting fees to payout currency
|
|
22
|
+
/// @param path Array of PathKey structs defining the multi-hop swap route
|
|
23
|
+
/// @param currencyIn The input currency to start the swap path from
|
|
24
|
+
struct PayoutSwapPath {
|
|
25
|
+
PathKey[] path;
|
|
26
|
+
Currency currencyIn;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/// @notice Returns the swap path configuration for converting this coin to its final payout currency
|
|
30
|
+
/// @dev This enables multi-hop swaps through intermediate currencies to reach the target payout token
|
|
31
|
+
/// @param coinVersionLookup Contract for looking up deployed coin versions to build recursive paths
|
|
32
|
+
/// @return PayoutSwapPath struct containing the complete swap route configuration
|
|
33
|
+
function getPayoutSwapPath(IDeployedCoinVersionLookup coinVersionLookup) external view returns (PayoutSwapPath memory);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface ICoinV4 is ICoin, IHasPoolKey, IHasSwapPath {
|
|
37
|
+
/// @notice Returns the pool configuration settings for this coin's Uniswap V4 pool
|
|
38
|
+
/// @return PoolConfiguration struct containing pool-specific settings and parameters
|
|
39
|
+
function getPoolConfiguration() external view returns (PoolConfiguration memory);
|
|
40
|
+
|
|
41
|
+
/// @notice Returns the hooks contract used by this coin's Uniswap V4 pool
|
|
42
|
+
/// @return The IHooks contract interface that handles pool lifecycle events
|
|
43
|
+
function hooks() external view returns (IHooks);
|
|
44
|
+
|
|
45
|
+
/// @notice Initializes the coin
|
|
46
|
+
/// @dev Called by the factory contract when the contract is deployed.
|
|
47
|
+
/// @param payoutRecipient_ The address of the payout recipient. Can be updated by the owner. Cannot be 0 address.
|
|
48
|
+
/// @param owners_ The addresses of the owners. All owners have the same full admin access. Cannot be 0 address.
|
|
49
|
+
/// @param tokenURI_ The URI of the token. Can be updated by the owner.
|
|
50
|
+
/// @param name_ The name of the token. Cannot be updated.
|
|
51
|
+
/// @param symbol_ The symbol of the token. Cannot be updated.
|
|
52
|
+
/// @param platformReferrer_ The address of the platform referrer. Cannot be updated.
|
|
53
|
+
/// @param currency_ The currency of the coin. Cannot be updated. Can be the zero address for ETH.
|
|
54
|
+
/// @param poolKey_ The pool key for the coin. Derived in the factory.
|
|
55
|
+
/// @param sqrtPriceX96 The initial sqrt price for the pool
|
|
56
|
+
/// @param poolConfiguration_ The configuration for the pool
|
|
57
|
+
function initialize(
|
|
58
|
+
address payoutRecipient_,
|
|
59
|
+
address[] memory owners_,
|
|
60
|
+
string memory tokenURI_,
|
|
61
|
+
string memory name_,
|
|
62
|
+
string memory symbol_,
|
|
63
|
+
address platformReferrer_,
|
|
64
|
+
address currency_,
|
|
65
|
+
PoolKey memory poolKey_,
|
|
66
|
+
uint160 sqrtPriceX96,
|
|
67
|
+
PoolConfiguration memory poolConfiguration_
|
|
68
|
+
) external;
|
|
69
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.23;
|
|
3
|
+
|
|
4
|
+
/// @title IDeployedCoinVersionLookup
|
|
5
|
+
/// @notice Interface for querying the version of a deployed coin
|
|
6
|
+
interface IDeployedCoinVersionLookup {
|
|
7
|
+
/// @notice Gets the version for a deployed coin
|
|
8
|
+
/// @param coin The address of the coin
|
|
9
|
+
/// @return version The version of the coin (0 if not found)
|
|
10
|
+
function getVersionForDeployedCoin(address coin) external view returns (uint8);
|
|
11
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.23;
|
|
3
|
+
|
|
4
|
+
/// @notice Interface for getting the correct message sender.
|
|
5
|
+
interface IMsgSender {
|
|
6
|
+
/// @notice Returns the address of the message sender.
|
|
7
|
+
/// @return The address of the message sender.
|
|
8
|
+
function msgSender() external view returns (address);
|
|
9
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.23;
|
|
3
|
+
|
|
4
|
+
/// @dev contract to enable encoding pool config from the client
|
|
5
|
+
interface IPoolConfigEncoding {
|
|
6
|
+
function encodeMultiCurvePoolConfig(
|
|
7
|
+
uint8 version,
|
|
8
|
+
address currency,
|
|
9
|
+
int24[] memory tickLower,
|
|
10
|
+
int24[] memory tickUpper,
|
|
11
|
+
uint16[] memory numDiscoveryPositions,
|
|
12
|
+
uint256[] memory maxDiscoverySupplyShare
|
|
13
|
+
) external pure returns (bytes memory);
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.25;
|
|
3
|
+
|
|
4
|
+
import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
|
|
5
|
+
import {Currency} from "@uniswap/v4-core/src/types/Currency.sol";
|
|
6
|
+
|
|
7
|
+
interface ISwapPathRouter {
|
|
8
|
+
struct Path {
|
|
9
|
+
PoolKey key;
|
|
10
|
+
Currency currencyIn;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function getSwapPath(PoolKey memory key, Currency toSwapOut) external view returns (Path[] memory path);
|
|
14
|
+
}
|