Skip to content

Commit e269474

Browse files
committed
merge in upstream; fix conflicts
2 parents 519aced + 3f2ff64 commit e269474

File tree

7 files changed

+89
-9
lines changed

7 files changed

+89
-9
lines changed

TODO

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
! document that periphery depends on non-malicious eulerSwap instances
44
! limitations of getLimits
55
* update deploy scripts
6-
* TODOs in UniswapHook.sol
76
* small cleanups in CurveLib
87
? tighten up getLimits bounds
98

src/QuoteLib.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ library QuoteLib {
2929
view
3030
returns (uint256)
3131
{
32+
if (amount == 0) return 0;
33+
3234
require(IEVC(evc).isAccountOperatorAuthorized(p.eulerAccount, address(this)), OperatorNotInstalled());
3335
require(amount <= type(uint112).max, SwapLimitExceeded());
3436

src/UniswapHook.sol

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ contract UniswapHook is BaseHook {
2727

2828
PoolKey internal _poolKey;
2929

30+
error NativeConcentratedLiquidityUnsupported();
31+
3032
constructor(address evc_, address _poolManager) BaseHook(IPoolManager(_poolManager)) {
3133
evc = evc_;
3234
}
@@ -42,7 +44,7 @@ contract UniswapHook is BaseHook {
4244
currency0: Currency.wrap(asset0Addr),
4345
currency1: Currency.wrap(asset1Addr),
4446
fee: fee,
45-
tickSpacing: 60, // TODO: fix arbitrary tick spacing
47+
tickSpacing: 1, // hard-coded tick spacing, as its unused
4648
hooks: IHooks(address(this))
4749
});
4850

@@ -90,7 +92,6 @@ contract UniswapHook is BaseHook {
9092

9193
// take the input token, from the PoolManager to the Euler vault
9294
// the debt will be paid by the swapper via the swap router
93-
// TODO: can we optimize the transfer by pulling from PoolManager directly to Euler?
9495
poolManager.take(params.zeroForOne ? key.currency0 : key.currency1, address(this), amountIn);
9596
amountInWithoutFee = FundsLib.depositAssets(evc, p, params.zeroForOne ? p.vault0 : p.vault1);
9697

@@ -117,7 +118,31 @@ contract UniswapHook is BaseHook {
117118
return (BaseHook.beforeSwap.selector, returnDelta, 0);
118119
}
119120

120-
// TODO: fix salt mining & verification for the hook
121-
function getHookPermissions() public pure override returns (Hooks.Permissions memory) {}
122-
function validateHookAddress(BaseHook) internal pure override {}
121+
function _beforeAddLiquidity(address, PoolKey calldata, IPoolManager.ModifyLiquidityParams calldata, bytes calldata)
122+
internal
123+
pure
124+
override
125+
returns (bytes4)
126+
{
127+
revert NativeConcentratedLiquidityUnsupported();
128+
}
129+
130+
function getHookPermissions() public pure override returns (Hooks.Permissions memory) {
131+
return Hooks.Permissions({
132+
beforeInitialize: false,
133+
afterInitialize: false,
134+
beforeAddLiquidity: true,
135+
afterAddLiquidity: false,
136+
beforeRemoveLiquidity: false,
137+
afterRemoveLiquidity: false,
138+
beforeSwap: true,
139+
afterSwap: false,
140+
beforeDonate: false,
141+
afterDonate: false,
142+
beforeSwapReturnDelta: true,
143+
afterSwapReturnDelta: false,
144+
afterAddLiquidityReturnDelta: false,
145+
afterRemoveLiquidityReturnDelta: false
146+
});
147+
}
123148
}

test/EulerSwapTestBase.t.sol

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {EulerSwapFactory} from "../src/EulerSwapFactory.sol";
99
import {EulerSwapPeriphery} from "../src/EulerSwapPeriphery.sol";
1010
import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
1111
import {HookMiner} from "./utils/HookMiner.sol";
12+
import {HookMiner as v4HookMiner} from "v4-periphery/src/utils/HookMiner.sol";
1213
import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol";
1314
import {MetaProxyDeployer} from "../src/MetaProxyDeployer.sol";
1415

@@ -37,7 +38,15 @@ contract EulerSwapTestBase is EVaultTestBase {
3738
}
3839

3940
function deployEulerSwap(address poolManager_) public {
40-
eulerSwapImpl = address(new EulerSwap(address(evc), poolManager_));
41+
// use the canonical miner to find a valid 'implementation' address
42+
(, bytes32 salt) = v4HookMiner.find(
43+
address(this),
44+
uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG | Hooks.BEFORE_ADD_LIQUIDITY_FLAG),
45+
type(EulerSwap).creationCode,
46+
abi.encode(address(evc), poolManager_)
47+
);
48+
49+
eulerSwapImpl = address(new EulerSwap{salt: salt}(address(evc), poolManager_));
4150
eulerSwapFactory = new EulerSwapFactory(address(evc), address(factory), eulerSwapImpl, address(this));
4251
periphery = new EulerSwapPeriphery();
4352
}
@@ -199,7 +208,7 @@ contract EulerSwapTestBase is EVaultTestBase {
199208
(address predictedAddr, bytes32 salt) = HookMiner.find(
200209
address(eulerSwapFactory),
201210
holder,
202-
uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG),
211+
uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG | Hooks.BEFORE_ADD_LIQUIDITY_FLAG),
203212
creationCode
204213
);
205214

test/FactoryTest.t.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ contract FactoryTest is EulerSwapTestBase {
3333
}
3434

3535
function mineSalt(IEulerSwap.Params memory poolParams) internal view returns (address hookAddress, bytes32 salt) {
36-
uint160 flags = uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG);
36+
uint160 flags =
37+
uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG | Hooks.BEFORE_ADD_LIQUIDITY_FLAG);
3738
bytes memory creationCode = MetaProxyDeployer.creationCodeMetaProxy(eulerSwapImpl, abi.encode(poolParams));
3839
(hookAddress, salt) = HookMiner.find(address(eulerSwapFactory), holder, flags, creationCode);
3940
}

test/HookSwaps.t.sol

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,20 @@ pragma solidity ^0.8.24;
44
import {EulerSwapTestBase, EulerSwap, EulerSwapPeriphery, IEulerSwap} from "./EulerSwapTestBase.t.sol";
55
import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol";
66
import {EulerSwap} from "../src/EulerSwap.sol";
7+
import {UniswapHook} from "../src/UniswapHook.sol";
78

89
import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
910
import {IPoolManager, PoolManagerDeployer} from "./utils/PoolManagerDeployer.sol";
1011
import {PoolSwapTest} from "@uniswap/v4-core/src/test/PoolSwapTest.sol";
1112
import {MinimalRouter} from "./utils/MinimalRouter.sol";
13+
import {PoolModifyLiquidityTest} from "@uniswap/v4-core/src/test/PoolModifyLiquidityTest.sol";
1214
import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol";
1315
import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol";
1416
import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol";
1517
import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol";
18+
import {CustomRevert} from "@uniswap/v4-core/src/libraries/CustomRevert.sol";
19+
import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol";
20+
import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol";
1621

1722
contract HookSwapsTest is EulerSwapTestBase {
1823
using StateLibrary for IPoolManager;
@@ -22,6 +27,7 @@ contract HookSwapsTest is EulerSwapTestBase {
2227
IPoolManager public poolManager;
2328
PoolSwapTest public swapRouter;
2429
MinimalRouter public minimalRouter;
30+
PoolModifyLiquidityTest public liquidityManager;
2531

2632
PoolSwapTest.TestSettings public settings = PoolSwapTest.TestSettings({takeClaims: false, settleUsingBurn: false});
2733

@@ -31,6 +37,7 @@ contract HookSwapsTest is EulerSwapTestBase {
3137
poolManager = PoolManagerDeployer.deploy(address(this));
3238
swapRouter = new PoolSwapTest(poolManager);
3339
minimalRouter = new MinimalRouter(poolManager);
40+
liquidityManager = new PoolModifyLiquidityTest(poolManager);
3441

3542
deployEulerSwap(address(poolManager));
3643

@@ -119,6 +126,35 @@ contract HookSwapsTest is EulerSwapTestBase {
119126
vm.stopPrank();
120127
}
121128

129+
/// @dev adding liquidity as a concentrated liquidity position will revert
130+
function test_revertAddConcentratedLiquidity() public {
131+
assetTST.mint(anyone, 10000e18);
132+
assetTST2.mint(anyone, 10000e18);
133+
134+
vm.startPrank(anyone);
135+
assetTST.approve(address(liquidityManager), 1e18);
136+
assetTST2.approve(address(liquidityManager), 1e18);
137+
138+
PoolKey memory poolKey = eulerSwap.poolKey();
139+
140+
// hook intentionally reverts to prevent v3-CLAMM positions
141+
vm.expectRevert(
142+
abi.encodeWithSelector(
143+
CustomRevert.WrappedError.selector,
144+
address(eulerSwap),
145+
IHooks.beforeAddLiquidity.selector,
146+
abi.encodeWithSelector(UniswapHook.NativeConcentratedLiquidityUnsupported.selector),
147+
abi.encodeWithSelector(Hooks.HookCallFailed.selector)
148+
)
149+
);
150+
liquidityManager.modifyLiquidity(
151+
poolKey,
152+
IPoolManager.ModifyLiquidityParams({tickLower: -10, tickUpper: 10, liquidityDelta: 1000, salt: bytes32(0)}),
153+
""
154+
);
155+
vm.stopPrank();
156+
}
157+
122158
function _swap(PoolKey memory key, bool zeroForOne, bool exactInput, uint256 amount) internal {
123159
IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({
124160
zeroForOne: zeroForOne,

test/Periphery.t.sol

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,4 +120,12 @@ contract PeripheryTest is EulerSwapTestBase {
120120

121121
assertEq(assetTST2.balanceOf(anyone), amountOut);
122122
}
123+
124+
function test_SwapZeroAmounts() public view {
125+
assertEq(periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), 0), 0);
126+
assertEq(periphery.quoteExactInput(address(eulerSwap), address(assetTST2), address(assetTST), 0), 0);
127+
128+
assertEq(periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), 0), 0);
129+
assertEq(periphery.quoteExactOutput(address(eulerSwap), address(assetTST2), address(assetTST), 0), 0);
130+
}
123131
}

0 commit comments

Comments
 (0)