Skip to content

Commit

Permalink
wip: fix compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
saucepoint committed Apr 18, 2024
1 parent f59eae7 commit 095fb31
Show file tree
Hide file tree
Showing 13 changed files with 70 additions and 58 deletions.
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeAddInitialLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
335072
313314
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeAddLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
129455
124785
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeFirstSwap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
82400
84215
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeRemoveLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
122043
112118
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeRemoveLiquidityAndRebalance.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
245873
246098
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeSecondSwap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
47402
49217
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeSwap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
81202
83017
20 changes: 14 additions & 6 deletions contracts/hooks/examples/FullRange.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {BaseHook} from "../../BaseHook.sol";
import {SafeCast} from "@uniswap/v4-core/src/libraries/SafeCast.sol";
import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol";
import {CurrencyLibrary, Currency} from "@uniswap/v4-core/src/types/Currency.sol";
import {CurrencySettleTake} from "@uniswap/v4-core/src/libraries/CurrencySettleTake.sol";
import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol";
import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol";
import {IERC20Minimal} from "@uniswap/v4-core/src/interfaces/external/IERC20Minimal.sol";
Expand All @@ -25,6 +26,7 @@ import "../../libraries/LiquidityAmounts.sol";

contract FullRange is BaseHook, IUnlockCallback {
using CurrencyLibrary for Currency;
using CurrencySettleTake for Currency;
using PoolIdLibrary for PoolKey;
using SafeCast for uint256;
using SafeCast for uint128;
Expand Down Expand Up @@ -253,8 +255,10 @@ contract FullRange is BaseHook, IUnlockCallback {
}

function _settleDeltas(address sender, PoolKey memory key, BalanceDelta delta) internal {
_settleDelta(sender, key.currency0, uint128(-delta.amount0()));
_settleDelta(sender, key.currency1, uint128(-delta.amount1()));
// _settleDelta(sender, key.currency0, uint128(-delta.amount0()));
key.currency0.settle(poolManager, sender, uint256(int256(-delta.amount0())), false);
key.currency1.settle(poolManager, sender, uint256(int256(-delta.amount1())), false);
// _settleDelta(sender, key.currency1, uint128(-delta.amount1()));
}

function _settleDelta(address sender, Currency currency, uint128 amount) internal {
Expand Down Expand Up @@ -293,7 +297,8 @@ contract FullRange is BaseHook, IUnlockCallback {
);

params.liquidityDelta = -(liquidityToRemove.toInt256());
delta = poolManager.modifyLiquidity(key, params, ZERO_BYTES);
(BalanceDelta _delta, BalanceDelta _feeDelta) = poolManager.modifyLiquidity(key, params, ZERO_BYTES);
delta = _delta + _feeDelta;
pool.hasAccruedFees = false;
}

Expand All @@ -310,15 +315,17 @@ contract FullRange is BaseHook, IUnlockCallback {
delta = _removeLiquidity(data.key, data.params);
_takeDeltas(data.sender, data.key, delta);
} else {
delta = poolManager.modifyLiquidity(data.key, data.params, ZERO_BYTES);
(BalanceDelta _delta, BalanceDelta _feeDelta) =
poolManager.modifyLiquidity(data.key, data.params, ZERO_BYTES);
delta = _delta + _feeDelta;
_settleDeltas(data.sender, data.key, delta);
}
return abi.encode(delta);
}

function _rebalance(PoolKey memory key) public {
PoolId poolId = key.toId();
BalanceDelta balanceDelta = poolManager.modifyLiquidity(
(BalanceDelta _delta, BalanceDelta _feeDelta) = poolManager.modifyLiquidity(
key,
IPoolManager.ModifyLiquidityParams({
tickLower: MIN_TICK,
Expand All @@ -327,6 +334,7 @@ contract FullRange is BaseHook, IUnlockCallback {
}),
ZERO_BYTES
);
BalanceDelta balanceDelta = _delta + _feeDelta;

uint160 newSqrtPriceX96 = (
FixedPointMathLib.sqrt(
Expand Down Expand Up @@ -354,7 +362,7 @@ contract FullRange is BaseHook, IUnlockCallback {
uint256(uint128(balanceDelta.amount1()))
);

BalanceDelta balanceDeltaAfter = poolManager.modifyLiquidity(
(BalanceDelta balanceDeltaAfter,) = poolManager.modifyLiquidity(
key,
IPoolManager.ModifyLiquidityParams({
tickLower: MIN_TICK,
Expand Down
40 changes: 17 additions & 23 deletions contracts/hooks/examples/LimitOrder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {IERC20Minimal} from "@uniswap/v4-core/src/interfaces/external/IERC20Mini
import {IERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
import {BaseHook} from "../../BaseHook.sol";
import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol";
import {CurrencySettleTake} from "@uniswap/v4-core/src/libraries/CurrencySettleTake.sol";
import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol";
import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";

Expand All @@ -31,6 +32,7 @@ contract LimitOrder is BaseHook {
using EpochLibrary for Epoch;
using PoolIdLibrary for PoolKey;
using CurrencyLibrary for Currency;
using CurrencySettleTake for Currency;

error ZeroLiquidity();
error InRange();
Expand Down Expand Up @@ -192,7 +194,7 @@ contract LimitOrder is BaseHook {
poolManagerOnly
returns (uint128 amount0, uint128 amount1)
{
BalanceDelta delta = poolManager.modifyLiquidity(
(BalanceDelta _delta, BalanceDelta _feeDelta) = poolManager.modifyLiquidity(
key,
IPoolManager.ModifyLiquidityParams({
tickLower: tickLower,
Expand All @@ -201,6 +203,7 @@ contract LimitOrder is BaseHook {
}),
ZERO_BYTES
);
BalanceDelta delta = _delta + _feeDelta;

if (delta.amount0() > 0) {
poolManager.mint(address(this), key.currency0.toId(), amount0 = uint128(delta.amount0()));
Expand Down Expand Up @@ -254,7 +257,7 @@ contract LimitOrder is BaseHook {
int256 liquidityDelta,
address owner
) external selfOnly {
BalanceDelta delta = poolManager.modifyLiquidity(
(BalanceDelta _delta, BalanceDelta _feeDelta) = poolManager.modifyLiquidity(
key,
IPoolManager.ModifyLiquidityParams({
tickLower: tickLower,
Expand All @@ -263,30 +266,20 @@ contract LimitOrder is BaseHook {
}),
ZERO_BYTES
);
BalanceDelta delta = _delta + _feeDelta;

if (delta.amount0() < 0) {
if (delta.amount1() != 0) revert InRange();
if (!zeroForOne) revert CrossedRange();
// TODO use safeTransferFrom
IERC20Minimal(Currency.unwrap(key.currency0)).transferFrom(
owner, address(poolManager), uint256(uint128(-delta.amount0()))
);
poolManager.settle(key.currency0);
key.currency0.settle(poolManager, owner, uint256(uint128(-delta.amount0())), false);
} else {
if (delta.amount0() != 0) revert InRange();
if (zeroForOne) revert CrossedRange();
// TODO use safeTransferFrom
IERC20Minimal(Currency.unwrap(key.currency1)).transferFrom(
owner, address(poolManager), uint256(uint128(-delta.amount1()))
);
poolManager.settle(key.currency1);
key.currency1.settle(poolManager, owner, uint256(uint128(-delta.amount1())), false);
}
}

function kill(PoolKey calldata key, int24 tickLower, bool zeroForOne, address to)
external
returns (uint256 amount0, uint256 amount1)
{
function kill(PoolKey calldata key, int24 tickLower, bool zeroForOne, address to) external {
Epoch epoch = getEpoch(key, tickLower, zeroForOne);
EpochInfo storage epochInfo = epochInfos[epoch];

Expand All @@ -298,14 +291,14 @@ contract LimitOrder is BaseHook {

uint256 amount0Fee;
uint256 amount1Fee;
(amount0, amount1, amount0Fee, amount1Fee) = abi.decode(
(amount0Fee, amount1Fee) = abi.decode(
poolManager.unlock(
abi.encodeCall(
this.unlockCallbackKill,
(key, tickLower, -int256(uint256(liquidity)), to, liquidity == epochInfo.liquidityTotal)
)
),
(uint256, uint256, uint256, uint256)
(uint256, uint256)
);
epochInfo.liquidityTotal -= liquidity;
unchecked {
Expand All @@ -322,15 +315,15 @@ contract LimitOrder is BaseHook {
int256 liquidityDelta,
address to,
bool removingAllLiquidity
) external selfOnly returns (uint256 amount0, uint256 amount1, uint128 amount0Fee, uint128 amount1Fee) {
) external selfOnly returns (uint128 amount0Fee, uint128 amount1Fee) {
int24 tickUpper = tickLower + key.tickSpacing;

// because `modifyPosition` includes not just principal value but also fees, we cannot allocate
// the proceeds pro-rata. if we were to do so, users who have been in a limit order that's partially filled
// could be unfairly diluted by a user sychronously placing then killing a limit order to skim off fees.
// to prevent this, we allocate all fee revenue to remaining limit order placers, unless this is the last order.
if (!removingAllLiquidity) {
BalanceDelta deltaFee = poolManager.modifyLiquidity(
(, BalanceDelta deltaFee) = poolManager.modifyLiquidity(
key,
IPoolManager.ModifyLiquidityParams({tickLower: tickLower, tickUpper: tickUpper, liquidityDelta: 0}),
ZERO_BYTES
Expand All @@ -344,7 +337,7 @@ contract LimitOrder is BaseHook {
}
}

BalanceDelta delta = poolManager.modifyLiquidity(
(BalanceDelta _delta, BalanceDelta _feeDelta) = poolManager.modifyLiquidity(
key,
IPoolManager.ModifyLiquidityParams({
tickLower: tickLower,
Expand All @@ -353,12 +346,13 @@ contract LimitOrder is BaseHook {
}),
ZERO_BYTES
);
BalanceDelta delta = _delta + _feeDelta;

if (delta.amount0() > 0) {
poolManager.take(key.currency0, to, amount0 = uint128(delta.amount0()));
key.currency0.take(poolManager, to, uint256(uint128(delta.amount0())), false);
}
if (delta.amount1() > 0) {
poolManager.take(key.currency1, to, amount1 = uint128(delta.amount1()));
key.currency1.take(poolManager, to, uint256(uint128(delta.amount1())), false);
}
}

Expand Down
12 changes: 6 additions & 6 deletions contracts/hooks/examples/TWAMM.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol
import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol";
import {PoolGetters} from "../../libraries/PoolGetters.sol";
import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
import {CurrencySettleTake} from "@uniswap/v4-core/src/libraries/CurrencySettleTake.sol";

contract TWAMM is BaseHook, ITWAMM {
using TransferHelper for IERC20Minimal;
using CurrencyLibrary for Currency;
using CurrencySettleTake for Currency;
using OrderPool for OrderPool.State;
using PoolIdLibrary for PoolKey;
using TickMath for int24;
Expand Down Expand Up @@ -308,19 +310,17 @@ contract TWAMM is BaseHook, ITWAMM {

if (swapParams.zeroForOne) {
if (delta.amount0() < 0) {
key.currency0.transfer(address(poolManager), uint256(uint128(-delta.amount0())));
poolManager.settle(key.currency0);
key.currency0.settle(poolManager, uint256(uint128(-delta.amount0())), false);
}
if (delta.amount1() > 0) {
poolManager.take(key.currency1, address(this), uint256(uint128(delta.amount1())));
key.currency1.take(poolManager, address(this), uint256(uint128(delta.amount1())), false);
}
} else {
if (delta.amount1() < 0) {
key.currency1.transfer(address(poolManager), uint256(uint128(-delta.amount1())));
poolManager.settle(key.currency1);
key.currency1.settle(poolManager, uint256(uint128(-delta.amount1())), false);
}
if (delta.amount0() > 0) {
poolManager.take(key.currency0, address(this), uint256(uint128(delta.amount0())));
key.currency0.take(poolManager, address(this), uint256(uint128(delta.amount0())), false);
}
}
return bytes("");
Expand Down
14 changes: 7 additions & 7 deletions test/FullRange.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot {
IPoolManager.SwapParams memory params =
IPoolManager.SwapParams({zeroForOne: true, amountSpecified: -1 ether, sqrtPriceLimitX96: SQRT_RATIO_1_2});
HookEnabledSwapRouter.TestSettings memory settings =
HookEnabledSwapRouter.TestSettings({withdrawTokens: true, settleUsingTransfer: true});
HookEnabledSwapRouter.TestSettings({takeClaims: false, settleUsingBurn: false});

snapStart("FullRangeSwap");
router.swap(key, params, settings, ZERO_BYTES);
Expand Down Expand Up @@ -309,7 +309,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot {
IPoolManager.SwapParams memory params =
IPoolManager.SwapParams({zeroForOne: true, amountSpecified: 1000 ether, sqrtPriceLimitX96: SQRT_RATIO_1_2});
HookEnabledSwapRouter.TestSettings memory settings =
HookEnabledSwapRouter.TestSettings({withdrawTokens: true, settleUsingTransfer: true});
HookEnabledSwapRouter.TestSettings({takeClaims: false, settleUsingBurn: false});

router.swap(key, params, settings, ZERO_BYTES);

Expand All @@ -334,7 +334,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot {
IPoolManager.SwapParams memory params =
IPoolManager.SwapParams({zeroForOne: true, amountSpecified: 1 ether, sqrtPriceLimitX96: SQRT_RATIO_1_2});
HookEnabledSwapRouter.TestSettings memory settings =
HookEnabledSwapRouter.TestSettings({withdrawTokens: true, settleUsingTransfer: true});
HookEnabledSwapRouter.TestSettings({takeClaims: false, settleUsingBurn: false});

snapStart("FullRangeFirstSwap");
router.swap(testKey, params, settings, ZERO_BYTES);
Expand Down Expand Up @@ -370,7 +370,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot {
IPoolManager.SwapParams({zeroForOne: true, amountSpecified: 10000000, sqrtPriceLimitX96: SQRT_RATIO_1_2});

HookEnabledSwapRouter.TestSettings memory testSettings =
HookEnabledSwapRouter.TestSettings({withdrawTokens: true, settleUsingTransfer: true});
HookEnabledSwapRouter.TestSettings({takeClaims: false, settleUsingBurn: false});

router.swap(key, params, testSettings, ZERO_BYTES);
router.swap(key2, params, testSettings, ZERO_BYTES);
Expand Down Expand Up @@ -553,7 +553,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot {
IPoolManager.SwapParams({zeroForOne: true, amountSpecified: 1 ether, sqrtPriceLimitX96: SQRT_RATIO_1_2});

HookEnabledSwapRouter.TestSettings memory testSettings =
HookEnabledSwapRouter.TestSettings({withdrawTokens: true, settleUsingTransfer: true});
HookEnabledSwapRouter.TestSettings({takeClaims: false, settleUsingBurn: false});

router.swap(keyWithLiq, params, testSettings, ZERO_BYTES);

Expand Down Expand Up @@ -680,7 +680,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot {
IPoolManager.SwapParams({zeroForOne: true, amountSpecified: 100 ether, sqrtPriceLimitX96: SQRT_RATIO_1_4});

HookEnabledSwapRouter.TestSettings memory testSettings =
HookEnabledSwapRouter.TestSettings({withdrawTokens: true, settleUsingTransfer: true});
HookEnabledSwapRouter.TestSettings({takeClaims: false, settleUsingBurn: false});

router.swap(key, params, testSettings, ZERO_BYTES);

Expand Down Expand Up @@ -735,7 +735,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot {
});

HookEnabledSwapRouter.TestSettings memory testSettings =
HookEnabledSwapRouter.TestSettings({withdrawTokens: true, settleUsingTransfer: true});
HookEnabledSwapRouter.TestSettings({takeClaims: false, settleUsingBurn: false});

router.swap(key, params, testSettings, ZERO_BYTES);

Expand Down
6 changes: 3 additions & 3 deletions test/LimitOrder.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ contract TestLimitOrder is Test, Deployers {
router.swap(
key,
IPoolManager.SwapParams(false, -1 ether, SQRT_RATIO_1_1 + 1),
HookEnabledSwapRouter.TestSettings(true, true),
HookEnabledSwapRouter.TestSettings(false, false),
ZERO_BYTES
);
vm.expectRevert(LimitOrder.InRange.selector);
Expand All @@ -130,7 +130,7 @@ contract TestLimitOrder is Test, Deployers {
router.swap(
key,
IPoolManager.SwapParams(true, -1 ether, SQRT_RATIO_1_1 - 1),
HookEnabledSwapRouter.TestSettings(true, true),
HookEnabledSwapRouter.TestSettings(false, false),
ZERO_BYTES
);
vm.expectRevert(LimitOrder.InRange.selector);
Expand Down Expand Up @@ -192,7 +192,7 @@ contract TestLimitOrder is Test, Deployers {
router.swap(
key,
IPoolManager.SwapParams(false, -1e18, TickMath.getSqrtRatioAtTick(60)),
HookEnabledSwapRouter.TestSettings(true, true),
HookEnabledSwapRouter.TestSettings(false, false),
ZERO_BYTES
);

Expand Down
Loading

0 comments on commit 095fb31

Please sign in to comment.