Skip to content

Commit

Permalink
chore: update v4-core:latest (#105)
Browse files Browse the repository at this point in the history
* update core

* rename lockAcquired to unlockCallback

* update core; temporary path hack in remappings

* update v4-core; remove remapping

* wip: fix compatibility

* update core; fix renaming of swap fee to lp fee

* update core; fix events

* update core; address liquidity salt and modify liquidity return values

* fix incorrect delta accounting when modifying liquidity

* fix todo, use CurrencySettleTake

* remove deadcode

* update core; use StateLibrary; update sqrtRatio to sqrtPrice

* fix beforeSwap return signatures

* forge fmt; remove commented out code

* update core (wow gas savings)

* update core

* update core

* update core; hook flags LSB

* update core

* update core
  • Loading branch information
saucepoint authored May 23, 2024
1 parent 6616b12 commit ad7976a
Show file tree
Hide file tree
Showing 26 changed files with 282 additions and 226 deletions.
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeAddInitialLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
384735
311243
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeAddLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
179102
123052
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeFirstSwap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
128152
82356
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeInitialize.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1017530
1016091
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeRemoveLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
169304
110705
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeRemoveLiquidityAndRebalance.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
345919
240800
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeSecondSwap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
89081
47770
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeSwap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
126954
81129
2 changes: 1 addition & 1 deletion .forge-snapshots/TWAMMSubmitOrder.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
122845
122417
11 changes: 6 additions & 5 deletions contracts/BaseHook.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol";
import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol";
import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
import {BeforeSwapDelta} from "@uniswap/v4-core/src/types/BeforeSwapDelta.sol";

abstract contract BaseHook is IHooks {
error NotPoolManager();
Expand Down Expand Up @@ -49,7 +50,7 @@ abstract contract BaseHook is IHooks {
Hooks.validateHookPermissions(_this, getHookPermissions());
}

function lockAcquired(bytes calldata data) external virtual poolManagerOnly returns (bytes memory) {
function unlockCallback(bytes calldata data) external virtual poolManagerOnly returns (bytes memory) {
(bool success, bytes memory returnData) = address(this).call(data);
if (success) return returnData;
if (returnData.length == 0) revert LockFailure();
Expand Down Expand Up @@ -95,7 +96,7 @@ abstract contract BaseHook is IHooks {
IPoolManager.ModifyLiquidityParams calldata,
BalanceDelta,
bytes calldata
) external virtual returns (bytes4) {
) external virtual returns (bytes4, BalanceDelta) {
revert HookNotImplemented();
}

Expand All @@ -105,22 +106,22 @@ abstract contract BaseHook is IHooks {
IPoolManager.ModifyLiquidityParams calldata,
BalanceDelta,
bytes calldata
) external virtual returns (bytes4) {
) external virtual returns (bytes4, BalanceDelta) {
revert HookNotImplemented();
}

function beforeSwap(address, PoolKey calldata, IPoolManager.SwapParams calldata, bytes calldata)
external
virtual
returns (bytes4)
returns (bytes4, BeforeSwapDelta, uint24)
{
revert HookNotImplemented();
}

function afterSwap(address, PoolKey calldata, IPoolManager.SwapParams calldata, BalanceDelta, bytes calldata)
external
virtual
returns (bytes4)
returns (bytes4, int128)
{
revert HookNotImplemented();
}
Expand Down
70 changes: 35 additions & 35 deletions contracts/hooks/examples/FullRange.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ 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";
import {ILockCallback} from "@uniswap/v4-core/src/interfaces/callback/ILockCallback.sol";
import {IUnlockCallback} from "@uniswap/v4-core/src/interfaces/callback/IUnlockCallback.sol";
import {PoolId, PoolIdLibrary} from "@uniswap/v4-core/src/types/PoolId.sol";
import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
import {FullMath} from "@uniswap/v4-core/src/libraries/FullMath.sol";
Expand All @@ -20,14 +21,18 @@ import {FixedPoint96} from "@uniswap/v4-core/src/libraries/FixedPoint96.sol";
import {FixedPointMathLib} from "solmate/utils/FixedPointMathLib.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/interfaces/IERC20Metadata.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol";
import {BeforeSwapDelta, BeforeSwapDeltaLibrary} from "@uniswap/v4-core/src/types/BeforeSwapDelta.sol";

import "../../libraries/LiquidityAmounts.sol";

contract FullRange is BaseHook, ILockCallback {
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;
using StateLibrary for IPoolManager;

/// @notice Thrown when trying to interact with a non-initialized pool
error PoolNotInitialized();
Expand Down Expand Up @@ -98,7 +103,11 @@ contract FullRange is BaseHook, ILockCallback {
beforeSwap: true,
afterSwap: false,
beforeDonate: false,
afterDonate: false
afterDonate: false,
beforeSwapReturnDelta: false,
afterSwapReturnDelta: false,
afterAddLiquidityReturnDelta: false,
afterRemoveLiquidityReturnDelta: false
});
}

Expand Down Expand Up @@ -127,8 +136,8 @@ contract FullRange is BaseHook, ILockCallback {

liquidity = LiquidityAmounts.getLiquidityForAmounts(
sqrtPriceX96,
TickMath.getSqrtRatioAtTick(MIN_TICK),
TickMath.getSqrtRatioAtTick(MAX_TICK),
TickMath.getSqrtPriceAtTick(MIN_TICK),
TickMath.getSqrtPriceAtTick(MAX_TICK),
params.amount0Desired,
params.amount1Desired
);
Expand All @@ -141,7 +150,8 @@ contract FullRange is BaseHook, ILockCallback {
IPoolManager.ModifyLiquidityParams({
tickLower: MIN_TICK,
tickUpper: MAX_TICK,
liquidityDelta: liquidity.toInt256()
liquidityDelta: liquidity.toInt256(),
salt: 0
})
);

Expand Down Expand Up @@ -185,7 +195,8 @@ contract FullRange is BaseHook, ILockCallback {
IPoolManager.ModifyLiquidityParams({
tickLower: MIN_TICK,
tickUpper: MAX_TICK,
liquidityDelta: -(params.liquidity.toInt256())
liquidityDelta: -(params.liquidity.toInt256()),
salt: 0
})
);

Expand Down Expand Up @@ -233,7 +244,7 @@ contract FullRange is BaseHook, ILockCallback {
function beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata, bytes calldata)
external
override
returns (bytes4)
returns (bytes4, BeforeSwapDelta, uint24)
{
PoolId poolId = key.toId();

Expand All @@ -242,32 +253,19 @@ contract FullRange is BaseHook, ILockCallback {
pool.hasAccruedFees = true;
}

return IHooks.beforeSwap.selector;
return (IHooks.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0);
}

function modifyLiquidity(PoolKey memory key, IPoolManager.ModifyLiquidityParams memory params)
internal
returns (BalanceDelta delta)
{
delta = abi.decode(poolManager.lock(abi.encode(CallbackData(msg.sender, key, params))), (BalanceDelta));
delta = abi.decode(poolManager.unlock(abi.encode(CallbackData(msg.sender, key, params))), (BalanceDelta));
}

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

function _settleDelta(address sender, Currency currency, uint128 amount) internal {
if (currency.isNative()) {
poolManager.settle{value: amount}(currency);
} else {
if (sender == address(this)) {
currency.transfer(address(poolManager), amount);
} else {
IERC20Minimal(Currency.unwrap(currency)).transferFrom(sender, address(poolManager), amount);
}
poolManager.settle(currency);
}
key.currency0.settle(poolManager, sender, uint256(int256(-delta.amount0())), false);
key.currency1.settle(poolManager, sender, uint256(int256(-delta.amount1())), false);
}

function _takeDeltas(address sender, PoolKey memory key, BalanceDelta delta) internal {
Expand All @@ -293,13 +291,13 @@ contract FullRange is BaseHook, ILockCallback {
);

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

function lockAcquired(bytes calldata rawData)
function unlockCallback(bytes calldata rawData)
external
override(ILockCallback, BaseHook)
override(IUnlockCallback, BaseHook)
poolManagerOnly
returns (bytes memory)
{
Expand All @@ -310,20 +308,21 @@ contract FullRange is BaseHook, ILockCallback {
delta = _removeLiquidity(data.key, data.params);
_takeDeltas(data.sender, data.key, delta);
} else {
delta = poolManager.modifyLiquidity(data.key, data.params, ZERO_BYTES);
(delta,) = poolManager.modifyLiquidity(data.key, data.params, ZERO_BYTES);
_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 balanceDelta,) = poolManager.modifyLiquidity(
key,
IPoolManager.ModifyLiquidityParams({
tickLower: MIN_TICK,
tickUpper: MAX_TICK,
liquidityDelta: -(poolManager.getLiquidity(poolId).toInt256())
liquidityDelta: -(poolManager.getLiquidity(poolId).toInt256()),
salt: 0
}),
ZERO_BYTES
);
Expand All @@ -348,18 +347,19 @@ contract FullRange is BaseHook, ILockCallback {

uint128 liquidity = LiquidityAmounts.getLiquidityForAmounts(
newSqrtPriceX96,
TickMath.getSqrtRatioAtTick(MIN_TICK),
TickMath.getSqrtRatioAtTick(MAX_TICK),
TickMath.getSqrtPriceAtTick(MIN_TICK),
TickMath.getSqrtPriceAtTick(MAX_TICK),
uint256(uint128(balanceDelta.amount0())),
uint256(uint128(balanceDelta.amount1()))
);

BalanceDelta balanceDeltaAfter = poolManager.modifyLiquidity(
(BalanceDelta balanceDeltaAfter,) = poolManager.modifyLiquidity(
key,
IPoolManager.ModifyLiquidityParams({
tickLower: MIN_TICK,
tickUpper: MAX_TICK,
liquidityDelta: liquidity.toInt256()
liquidityDelta: liquidity.toInt256(),
salt: 0
}),
ZERO_BYTES
);
Expand Down
13 changes: 10 additions & 3 deletions contracts/hooks/examples/GeomeanOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol";
import {Oracle} from "../../libraries/Oracle.sol";
import {BaseHook} from "../../BaseHook.sol";
import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol";
import {BeforeSwapDelta, BeforeSwapDeltaLibrary} from "@uniswap/v4-core/src/types/BeforeSwapDelta.sol";

/// @notice A hook for a pool that allows a Uniswap pool to act as an oracle. Pools that use this hook must have full range
/// tick spacing and liquidity is always permanently locked in these pools. This is the suggested configuration
/// for protocols that wish to use a V3 style geomean oracle.
contract GeomeanOracle is BaseHook {
using Oracle for Oracle.Observation[65535];
using PoolIdLibrary for PoolKey;
using StateLibrary for IPoolManager;

/// @notice Oracle pools do not have fees because they exist to serve as an oracle for a pair of tokens
error OnlyOneOraclePoolAllowed();
Expand Down Expand Up @@ -71,7 +74,11 @@ contract GeomeanOracle is BaseHook {
beforeSwap: true,
afterSwap: false,
beforeDonate: false,
afterDonate: false
afterDonate: false,
beforeSwapReturnDelta: false,
afterSwapReturnDelta: false,
afterAddLiquidityReturnDelta: false,
afterRemoveLiquidityReturnDelta: false
});
}

Expand Down Expand Up @@ -140,10 +147,10 @@ contract GeomeanOracle is BaseHook {
external
override
poolManagerOnly
returns (bytes4)
returns (bytes4, BeforeSwapDelta, uint24)
{
_updatePool(key);
return GeomeanOracle.beforeSwap.selector;
return (GeomeanOracle.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0);
}

/// @notice Observe the given pool for the timestamps
Expand Down
Loading

0 comments on commit ad7976a

Please sign in to comment.