From 50ca2a27da05fdcb0769d123065405425f42a724 Mon Sep 17 00:00:00 2001 From: Gonzalo Othacehe Date: Fri, 5 Dec 2025 20:10:52 -0300 Subject: [PATCH] update uniswap hooks API Reference, Overview & generate-changelog --- content/uniswap-hooks/api/base.mdx | 163 +--- content/uniswap-hooks/api/fee.mdx | 288 +++++-- content/uniswap-hooks/api/general.mdx | 859 ++++++++++++++++++-- content/uniswap-hooks/api/index.mdx | 2 +- content/uniswap-hooks/api/interfaces.mdx | 7 +- content/uniswap-hooks/api/oracles.mdx | 976 +++++++++++++++++++++++ content/uniswap-hooks/api/utils.mdx | 7 +- content/uniswap-hooks/changelog.mdx | 119 ++- content/uniswap-hooks/index.mdx | 46 +- package.json | 5 +- pnpm-lock.yaml | 11 +- scripts/generate-changelog.js | 28 +- 12 files changed, 2172 insertions(+), 339 deletions(-) create mode 100644 content/uniswap-hooks/api/oracles.mdx diff --git a/content/uniswap-hooks/api/base.mdx b/content/uniswap-hooks/api/base.mdx index 59157b8f..b1522089 100644 --- a/content/uniswap-hooks/api/base.mdx +++ b/content/uniswap-hooks/api/base.mdx @@ -7,16 +7,16 @@ description: "Smart contract base utilities and implementations"
-## `BaseAsyncSwap` +## `BaseAsyncSwap` - +
```solidity -import "uniswap-hooks/src/base/BaseAsyncSwap.sol"; +import "@openzeppelin/src/base/BaseAsyncSwap.sol"; ``` Base implementation for async swaps, which skip the v3-like swap implementation of the `PoolManager` @@ -51,7 +51,6 @@ _Available since v0.1.0_

Functions

-- [constructor(_poolManager)](#BaseAsyncSwap-constructor-contract-IPoolManager-) - [_beforeSwap(sender, key, params, )](#BaseAsyncSwap-_beforeSwap-address-struct-PoolKey-struct-SwapParams-bytes-) - [_calculateSwapFee(key, specifiedAmount)](#BaseAsyncSwap-_calculateSwapFee-struct-PoolKey-uint256-) - [getHookPermissions()](#BaseAsyncSwap-getHookPermissions--) @@ -100,31 +99,12 @@ _Available since v0.1.0_
#### IHookEvents [!toc] #### BaseHook [!toc] -- [NotSelf()](#BaseHook-NotSelf--) -- [InvalidPool()](#BaseHook-InvalidPool--) - [HookNotImplemented()](#BaseHook-HookNotImplemented--) - [NotPoolManager()](#BaseHook-NotPoolManager--) #### IHooks [!toc]
- - -
-
-

constructor(contract IPoolManager _poolManager)

-
-

internal

-# -
-
-
- -Set the `PoolManager` address. - -
-
-
@@ -181,16 +161,16 @@ Set the hook permissions, specifically `beforeSwap` and `beforeSwapReturnDelta`.
-## `BaseCustomAccounting` +## `BaseCustomAccounting` - +
```solidity -import "uniswap-hooks/src/base/BaseCustomAccounting.sol"; +import "@openzeppelin/src/base/BaseCustomAccounting.sol"; ``` Base implementation for custom accounting and hook-owned liquidity. @@ -226,7 +206,6 @@ _Available since v0.1.0_

Functions

-- [constructor(_poolManager)](#BaseCustomAccounting-constructor-contract-IPoolManager-) - [poolKey()](#BaseCustomAccounting-poolKey--) - [addLiquidity(params)](#BaseCustomAccounting-addLiquidity-struct-BaseCustomAccounting-AddLiquidityParams-) - [removeLiquidity(params)](#BaseCustomAccounting-removeLiquidity-struct-BaseCustomAccounting-RemoveLiquidityParams-) @@ -293,8 +272,6 @@ _Available since v0.1.0_ #### IUnlockCallback [!toc] #### IHookEvents [!toc] #### BaseHook [!toc] -- [NotSelf()](#BaseHook-NotSelf--) -- [InvalidPool()](#BaseHook-InvalidPool--) - [HookNotImplemented()](#BaseHook-HookNotImplemented--) - [NotPoolManager()](#BaseHook-NotPoolManager--) #### IHooks [!toc] @@ -319,23 +296,6 @@ Ensure the deadline of a liquidity modification request is not expired.
- - -
-
-

constructor(contract IPoolManager _poolManager)

-
-

internal

-# -
-
-
- -Set the pool `PoolManager` address. - -
-
-
@@ -688,16 +648,16 @@ Hook was already initialized.
-## `BaseCustomCurve` +## `BaseCustomCurve` - +
```solidity -import "uniswap-hooks/src/base/BaseCustomCurve.sol"; +import "@openzeppelin/src/base/BaseCustomCurve.sol"; ``` Base implementation for custom curves, inheriting from [`BaseCustomAccounting`](#BaseCustomAccounting). @@ -723,7 +683,6 @@ _Available since v0.1.0_

Functions

-- [constructor(_poolManager)](#BaseCustomCurve-constructor-contract-IPoolManager-) - [_getAddLiquidity(, params)](#BaseCustomCurve-_getAddLiquidity-uint160-struct-BaseCustomAccounting-AddLiquidityParams-) - [_getRemoveLiquidity(params)](#BaseCustomCurve-_getRemoveLiquidity-struct-BaseCustomAccounting-RemoveLiquidityParams-) - [_beforeSwap(sender, key, params, )](#BaseCustomCurve-_beforeSwap-address-struct-PoolKey-struct-SwapParams-bytes-) @@ -797,31 +756,12 @@ _Available since v0.1.0_ #### IUnlockCallback [!toc] #### IHookEvents [!toc] #### BaseHook [!toc] -- [NotSelf()](#BaseHook-NotSelf--) -- [InvalidPool()](#BaseHook-InvalidPool--) - [HookNotImplemented()](#BaseHook-HookNotImplemented--) - [NotPoolManager()](#BaseHook-NotPoolManager--) #### IHooks [!toc]
- - -
-
-

constructor(contract IPoolManager _poolManager)

-
-

internal

-# -
-
-
- -Set the pool `PoolManager` address. - -
-
-
@@ -862,7 +802,7 @@ for a remove liquidity request.
-

_beforeSwap(address sender, struct PoolKey key, struct SwapParams params, bytes) → bytes4, BeforeSwapDelta, uint24

+

_beforeSwap(address sender, struct PoolKey key, struct SwapParams params, bytes) → bytes4, BeforeSwapDelta returnDelta, uint24

internal

# @@ -1007,16 +947,16 @@ Set the hook permissions, specifically `beforeInitialize`, `beforeAddLiquidity`,
-## `BaseHook` +## `BaseHook` - +
```solidity -import "uniswap-hooks/src/base/BaseHook.sol"; +import "@openzeppelin/src/base/BaseHook.sol"; ``` Base hook implementation. @@ -1041,8 +981,6 @@ _Available since v0.1.0_

Modifiers

- [onlyPoolManager()](#BaseHook-onlyPoolManager--) -- [onlySelf()](#BaseHook-onlySelf--) -- [onlyValidPools(hooks)](#BaseHook-onlyValidPools-contract-IHooks-)
@@ -1080,8 +1018,6 @@ _Available since v0.1.0_

Errors

-- [NotSelf()](#BaseHook-NotSelf--) -- [InvalidPool()](#BaseHook-InvalidPool--) - [HookNotImplemented()](#BaseHook-HookNotImplemented--) - [NotPoolManager()](#BaseHook-NotPoolManager--) #### IHooks [!toc] @@ -1104,42 +1040,6 @@ _Available since v0.1.0_
- - -
-
-

onlySelf()

-
-

internal

-# -
-
- -
- -Restrict the function to only be callable by the hook itself. - -
-
- - - -
-
-

onlyValidPools(contract IHooks hooks)

-
-

internal

-# -
-
- -
- -Restrict the function to only be called for a valid pool. - -
-
-
@@ -1152,7 +1052,7 @@ Restrict the function to only be called for a valid pool.
-Set the pool manager and check that the hook address matches the expected permissions and flags. +Check that the hook address matches the expected permissions and flags.
@@ -1538,40 +1438,6 @@ flag must be set to true in the `getHookPermissions` function.
- - -
-
-

NotSelf()

-
-

error

-# -
-
-
- -The hook is not the caller. - -
-
- - - -
-
-

InvalidPool()

-
-

error

-# -
-
-
- -The pool is not authorized to use this hook. - -
-
-
@@ -1603,3 +1469,4 @@ The hook function is not implemented.
+ diff --git a/content/uniswap-hooks/api/fee.mdx b/content/uniswap-hooks/api/fee.mdx index df0131c7..32cb248b 100644 --- a/content/uniswap-hooks/api/fee.mdx +++ b/content/uniswap-hooks/api/fee.mdx @@ -7,22 +7,22 @@ description: "Smart contract fee utilities and implementations"
-## `BaseDynamicAfterFee` +## `BaseDynamicAfterFee` - +
```solidity -import "uniswap-hooks/src/fee/BaseDynamicAfterFee.sol"; +import "@openzeppelin/src/fee/BaseDynamicAfterFee.sol"; ``` Base implementation for dynamic target hook fees applied after swaps. Enables to enforce a dynamic target determined by [`BaseDynamicAfterFee._getTargetUnspecified`](#BaseDynamicAfterFee-_getTargetUnspecified-address-struct-PoolKey-struct-SwapParams-bytes-) for the unspecified currency of the swap -during [`BaseAsyncSwap._beforeSwap`](/uniswap-hooks/api/base#BaseAsyncSwap-_beforeSwap-address-struct-PoolKey-struct-SwapParams-bytes-), where if the swap outcome results better than the target, any positive difference is taken +during [`BaseAsyncSwap._beforeSwap`](base#BaseAsyncSwap-_beforeSwap-address-struct-PoolKey-struct-SwapParams-bytes-), where if the swap outcome results better than the target, any positive difference is taken as a hook fee, being posteriorily handled or distributed by the hook via [`BaseDynamicAfterFee._afterSwapHandler`](#BaseDynamicAfterFee-_afterSwapHandler-struct-PoolKey-struct-SwapParams-BalanceDelta-uint256-uint256-). @@ -45,7 +45,6 @@ _Available since v0.1.0_ - [_transientApplyTarget()](#BaseDynamicAfterFee-_transientApplyTarget--) - [_setTransientTargetUnspecifiedAmount(value)](#BaseDynamicAfterFee-_setTransientTargetUnspecifiedAmount-uint256-) - [_setTransientApplyTarget(value)](#BaseDynamicAfterFee-_setTransientApplyTarget-bool-) -- [constructor(_poolManager)](#BaseDynamicAfterFee-constructor-contract-IPoolManager-) - [_beforeSwap(sender, key, params, hookData)](#BaseDynamicAfterFee-_beforeSwap-address-struct-PoolKey-struct-SwapParams-bytes-) - [_afterSwap(sender, key, params, delta, )](#BaseDynamicAfterFee-_afterSwap-address-struct-PoolKey-struct-SwapParams-BalanceDelta-bytes-) - [_getTargetUnspecified(sender, key, params, hookData)](#BaseDynamicAfterFee-_getTargetUnspecified-address-struct-PoolKey-struct-SwapParams-bytes-) @@ -95,8 +94,6 @@ _Available since v0.1.0_
#### IHookEvents [!toc] #### BaseHook [!toc] -- [NotSelf()](#BaseHook-NotSelf--) -- [InvalidPool()](#BaseHook-InvalidPool--) - [HookNotImplemented()](#BaseHook-HookNotImplemented--) - [NotPoolManager()](#BaseHook-NotPoolManager--) #### IHooks [!toc] @@ -171,23 +168,6 @@ Set the apply flag to be used in the `afterSwap` hook.
- - -
-
-

constructor(contract IPoolManager _poolManager)

-
-

internal

-# -
-
-
- -Set the `PoolManager` address. - -
-
-
@@ -283,7 +263,7 @@ Customizable handler called after `_afterSwap` to handle or distribute the fees.
-Set the hook permissions, specifically [`BaseHook.beforeSwap`](/uniswap-hooks/api/base#BaseHook-beforeSwap-address-struct-PoolKey-struct-SwapParams-bytes-), [`BaseHook.afterSwap`](/uniswap-hooks/api/base#BaseHook-afterSwap-address-struct-PoolKey-struct-SwapParams-BalanceDelta-bytes-) and `afterSwapReturnDelta`. +Set the hook permissions, specifically [`BaseHook.beforeSwap`](base#BaseHook-beforeSwap-address-struct-PoolKey-struct-SwapParams-bytes-), [`BaseHook.afterSwap`](base#BaseHook-afterSwap-address-struct-PoolKey-struct-SwapParams-BalanceDelta-bytes-) and `afterSwapReturnDelta`.
@@ -292,16 +272,16 @@ Set the hook permissions, specifically [`BaseHook.beforeSwap`](/uniswap-hooks/ap
-## `BaseDynamicFee` +## `BaseDynamicFee` - +
```solidity -import "uniswap-hooks/src/fee/BaseDynamicFee.sol"; +import "@openzeppelin/src/fee/BaseDynamicFee.sol"; ``` Base implementation to apply a dynamic fee via the `PoolManager`'s `updateDynamicLPFee` function. @@ -317,10 +297,9 @@ _Available since v0.1.0_

Functions

-- [constructor(_poolManager)](#BaseDynamicFee-constructor-contract-IPoolManager-) - [_getFee(key)](#BaseDynamicFee-_getFee-struct-PoolKey-) - [_afterInitialize(, key, , )](#BaseDynamicFee-_afterInitialize-address-struct-PoolKey-uint160-int24-) -- [poke(key)](#BaseDynamicFee-poke-struct-PoolKey-) +- [_poke(key)](#BaseDynamicFee-_poke-struct-PoolKey-) - [getHookPermissions()](#BaseDynamicFee-getHookPermissions--) #### BaseHook [!toc] - [_validateHookAddress(hook)](#BaseHook-_validateHookAddress-contract-BaseHook-) @@ -353,31 +332,12 @@ _Available since v0.1.0_
- [NotDynamicFee()](#BaseDynamicFee-NotDynamicFee--) #### BaseHook [!toc] -- [NotSelf()](#BaseHook-NotSelf--) -- [InvalidPool()](#BaseHook-InvalidPool--) - [HookNotImplemented()](#BaseHook-HookNotImplemented--) - [NotPoolManager()](#BaseHook-NotPoolManager--) #### IHooks [!toc]
- - -
-
-

constructor(contract IPoolManager _poolManager)

-
-

internal

-# -
-
-
- -Set the `PoolManager` address. - -
-
-
@@ -412,34 +372,27 @@ Set the fee after the pool is initialized.
- +
-

poke(struct PoolKey key)

+

_poke(struct PoolKey key)

-

public

-# +

internal

+#
-Updates the dynamic LP fee for the given pool, which must have a key -that contains this hook's address. +Updates the dynamic LP fee for the given pool - -This function can be called by anyone at any time. If `_getFee` implementation -depends on external conditions (e.g., oracle prices, other pool states, token balances), -it may be vulnerable to manipulation. An attacker could potentially: -1. Manipulate the external conditions that `_getFee` depends on -2. Call `poke()` to update the fee to a more favorable rate -3. Execute trades at the manipulated fee rate + +It can be called internally at any point in the pool's lifecycle to update the fee +given the current market conditions. Alternatively, it can be wrapped and exposed publicly +to be externally called by an authorized party. If exposed, it must be properly protected +and access control is recommended. -Inheriting contracts should consider implementing access controls on this function, -make the logic in `_getFee` resistant to short-term manipulation, or accept the risk -of fee manipulation. -
@@ -477,45 +430,52 @@ The hook was attempted to be initialized with a non-dynamic fee. - +
-## `BaseOverrideFee` +## `BaseHookFee` - +
```solidity -import "uniswap-hooks/src/fee/BaseOverrideFee.sol"; +import "@openzeppelin/src/fee/BaseHookFee.sol"; ``` -Base implementation for automatic dynamic fees applied before swaps. +Base implementation for applying hook fees to the unspecified currency of the swap. +These fees are independent of the pool's LP fee and are charged as a percentage of the output +amount after the swap completes. + + +It is left to the implementing contract to handle the accumulated hook fees, such as distributing +or withdrawing them via ERC-6909 claims. + This is experimental software and is provided on an "as is" and "as available" basis. We do -not give any warranties and will not be liable for any losses incurred through any use of this code -base. +not give any warranties and will not be liable for any losses incurred through any use of this code base. -_Available since v0.1.0_ +_Available since v1.2.0_

Functions

-- [constructor(_poolManager)](#BaseOverrideFee-constructor-contract-IPoolManager-) -- [_afterInitialize(, key, , )](#BaseOverrideFee-_afterInitialize-address-struct-PoolKey-uint160-int24-) -- [_getFee(sender, key, params, hookData)](#BaseOverrideFee-_getFee-address-struct-PoolKey-struct-SwapParams-bytes-) -- [_beforeSwap(sender, key, params, hookData)](#BaseOverrideFee-_beforeSwap-address-struct-PoolKey-struct-SwapParams-bytes-) -- [getHookPermissions()](#BaseOverrideFee-getHookPermissions--) +- [_getHookFee(sender, key, params, delta, hookData)](#BaseHookFee-_getHookFee-address-struct-PoolKey-struct-SwapParams-BalanceDelta-bytes-) +- [_afterSwap(sender, key, params, delta, hookData)](#BaseHookFee-_afterSwap-address-struct-PoolKey-struct-SwapParams-BalanceDelta-bytes-) +- [handleHookFees(currencies)](#BaseHookFee-handleHookFees-Currency---) +- [getHookPermissions()](#BaseHookFee-getHookPermissions--) +#### IHookEvents [!toc] #### BaseHook [!toc] - [_validateHookAddress(hook)](#BaseHook-_validateHookAddress-contract-BaseHook-) - [beforeInitialize(sender, key, sqrtPriceX96)](#BaseHook-beforeInitialize-address-struct-PoolKey-uint160-) - [_beforeInitialize(, , )](#BaseHook-_beforeInitialize-address-struct-PoolKey-uint160-) - [afterInitialize(sender, key, sqrtPriceX96, tick)](#BaseHook-afterInitialize-address-struct-PoolKey-uint160-int24-) +- [_afterInitialize(, , , )](#BaseHook-_afterInitialize-address-struct-PoolKey-uint160-int24-) - [beforeAddLiquidity(sender, key, params, hookData)](#BaseHook-beforeAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-bytes-) - [_beforeAddLiquidity(, , , )](#BaseHook-_beforeAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-bytes-) - [beforeRemoveLiquidity(sender, key, params, hookData)](#BaseHook-beforeRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-bytes-) @@ -525,8 +485,8 @@ _Available since v0.1.0_ - [afterRemoveLiquidity(sender, key, params, delta0, delta1, hookData)](#BaseHook-afterRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) - [_afterRemoveLiquidity(, , , , , )](#BaseHook-_afterRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) - [beforeSwap(sender, key, params, hookData)](#BaseHook-beforeSwap-address-struct-PoolKey-struct-SwapParams-bytes-) +- [_beforeSwap(, , , )](#BaseHook-_beforeSwap-address-struct-PoolKey-struct-SwapParams-bytes-) - [afterSwap(sender, key, params, delta, hookData)](#BaseHook-afterSwap-address-struct-PoolKey-struct-SwapParams-BalanceDelta-bytes-) -- [_afterSwap(, , , , )](#BaseHook-_afterSwap-address-struct-PoolKey-struct-SwapParams-BalanceDelta-bytes-) - [beforeDonate(sender, key, amount0, amount1, hookData)](#BaseHook-beforeDonate-address-struct-PoolKey-uint256-uint256-bytes-) - [_beforeDonate(, , , , )](#BaseHook-_beforeDonate-address-struct-PoolKey-uint256-uint256-bytes-) - [afterDonate(sender, key, amount0, amount1, hookData)](#BaseHook-afterDonate-address-struct-PoolKey-uint256-uint256-bytes-) @@ -536,33 +496,186 @@ _Available since v0.1.0_
+
+

Events

+
+#### IHookEvents [!toc] +- [HookSwap(poolId, sender, amount0, amount1, hookLPfeeAmount0, hookLPfeeAmount1)](#IHookEvents-HookSwap-bytes32-address-int128-int128-uint128-uint128-) +- [HookFee(poolId, sender, feeAmount0, feeAmount1)](#IHookEvents-HookFee-bytes32-address-uint128-uint128-) +- [HookModifyLiquidity(poolId, sender, amount0, amount1)](#IHookEvents-HookModifyLiquidity-bytes32-address-int128-int128-) +- [HookBonus(poolId, amount0, amount1)](#IHookEvents-HookBonus-bytes32-uint128-uint128-) +#### BaseHook [!toc] +#### IHooks [!toc] +
+
+

Errors

-- [NotDynamicFee()](#BaseOverrideFee-NotDynamicFee--) +- [HookFeeTooLarge()](#BaseHookFee-HookFeeTooLarge--) +#### IHookEvents [!toc] #### BaseHook [!toc] -- [NotSelf()](#BaseHook-NotSelf--) -- [InvalidPool()](#BaseHook-InvalidPool--) - [HookNotImplemented()](#BaseHook-HookNotImplemented--) - [NotPoolManager()](#BaseHook-NotPoolManager--) #### IHooks [!toc]
- + + +
+
+

_getHookFee(address sender, struct PoolKey key, struct SwapParams params, BalanceDelta delta, bytes hookData) → uint24 fee

+
+

internal

+# +
+
+
+ +Get the fee to be applied after the swap. Takes the `address` `sender`, a `PoolKey` `key`, +the `SwapParams` `params`, `BalanceDelta` `delta` and `hookData` as arguments and returns the `fee` +to be applied in hundredths of a bip. i.e. 1000000 = 100% + +
+
+ +
-

constructor(contract IPoolManager _poolManager)

+

_afterSwap(address sender, struct PoolKey key, struct SwapParams params, BalanceDelta delta, bytes hookData) → bytes4, int128

internal

-# +# +
+
+
+ +Hooks into the `afterSwap` hook to apply the hook fee to the unspecified currency. + + +The fee is calculated as a percentage of the output amount and taken as ERC-6909 claims. + + +
+
+ + + +
+
+

handleHookFees(Currency[] currencies)

+
+

public

+# +
+
+
+ +
+
+ + + +
+
+

getHookPermissions() → struct Hooks.Permissions permissions

+
+

public

+# +
+
+
+ +Returns the hook permissions, specifically enabling [`BaseHook.afterSwap`](base#BaseHook-afterSwap-address-struct-PoolKey-struct-SwapParams-BalanceDelta-bytes-) and `afterSwapReturnDelta`. + +
+
+ + + +
+
+

HookFeeTooLarge()

+
+

error

+#
-Set the `PoolManager` address. +Fee is higher than the maximum allowed fee. + +
+
+ + + +
+ +## `BaseOverrideFee` + + + + + +
+ +```solidity +import "@openzeppelin/src/fee/BaseOverrideFee.sol"; +``` + +Base implementation for automatic dynamic fees applied before swaps. + + +This is experimental software and is provided on an "as is" and "as available" basis. We do +not give any warranties and will not be liable for any losses incurred through any use of this code +base. + + +_Available since v0.1.0_ + +
+

Functions

+
+- [_afterInitialize(, key, , )](#BaseOverrideFee-_afterInitialize-address-struct-PoolKey-uint160-int24-) +- [_getFee(sender, key, params, hookData)](#BaseOverrideFee-_getFee-address-struct-PoolKey-struct-SwapParams-bytes-) +- [_beforeSwap(sender, key, params, hookData)](#BaseOverrideFee-_beforeSwap-address-struct-PoolKey-struct-SwapParams-bytes-) +- [getHookPermissions()](#BaseOverrideFee-getHookPermissions--) +#### BaseHook [!toc] +- [_validateHookAddress(hook)](#BaseHook-_validateHookAddress-contract-BaseHook-) +- [beforeInitialize(sender, key, sqrtPriceX96)](#BaseHook-beforeInitialize-address-struct-PoolKey-uint160-) +- [_beforeInitialize(, , )](#BaseHook-_beforeInitialize-address-struct-PoolKey-uint160-) +- [afterInitialize(sender, key, sqrtPriceX96, tick)](#BaseHook-afterInitialize-address-struct-PoolKey-uint160-int24-) +- [beforeAddLiquidity(sender, key, params, hookData)](#BaseHook-beforeAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-bytes-) +- [_beforeAddLiquidity(, , , )](#BaseHook-_beforeAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-bytes-) +- [beforeRemoveLiquidity(sender, key, params, hookData)](#BaseHook-beforeRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-bytes-) +- [_beforeRemoveLiquidity(, , , )](#BaseHook-_beforeRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-bytes-) +- [afterAddLiquidity(sender, key, params, delta0, delta1, hookData)](#BaseHook-afterAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) +- [_afterAddLiquidity(, , , , , )](#BaseHook-_afterAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) +- [afterRemoveLiquidity(sender, key, params, delta0, delta1, hookData)](#BaseHook-afterRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) +- [_afterRemoveLiquidity(, , , , , )](#BaseHook-_afterRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) +- [beforeSwap(sender, key, params, hookData)](#BaseHook-beforeSwap-address-struct-PoolKey-struct-SwapParams-bytes-) +- [afterSwap(sender, key, params, delta, hookData)](#BaseHook-afterSwap-address-struct-PoolKey-struct-SwapParams-BalanceDelta-bytes-) +- [_afterSwap(, , , , )](#BaseHook-_afterSwap-address-struct-PoolKey-struct-SwapParams-BalanceDelta-bytes-) +- [beforeDonate(sender, key, amount0, amount1, hookData)](#BaseHook-beforeDonate-address-struct-PoolKey-uint256-uint256-bytes-) +- [_beforeDonate(, , , , )](#BaseHook-_beforeDonate-address-struct-PoolKey-uint256-uint256-bytes-) +- [afterDonate(sender, key, amount0, amount1, hookData)](#BaseHook-afterDonate-address-struct-PoolKey-uint256-uint256-bytes-) +- [_afterDonate(, , , , )](#BaseHook-_afterDonate-address-struct-PoolKey-uint256-uint256-bytes-) +- [poolManager()](#BaseHook-poolManager-contract-IPoolManager) +#### IHooks [!toc] +
+
+
+

Errors

+
+- [NotDynamicFee()](#BaseOverrideFee-NotDynamicFee--) +#### BaseHook [!toc] +- [HookNotImplemented()](#BaseHook-HookNotImplemented--) +- [NotPoolManager()](#BaseHook-NotPoolManager--) +#### IHooks [!toc]
@@ -650,3 +763,4 @@ The hook was attempted to be initialized with a non-dynamic fee. + diff --git a/content/uniswap-hooks/api/general.mdx b/content/uniswap-hooks/api/general.mdx index 703fadb1..91ce2635 100644 --- a/content/uniswap-hooks/api/general.mdx +++ b/content/uniswap-hooks/api/general.mdx @@ -7,16 +7,16 @@ description: "Smart contract general utilities and implementations"
-## `AntiSandwichHook` +## `AntiSandwichHook` - +
```solidity -import "uniswap-hooks/src/general/AntiSandwichHook.sol"; +import "@openzeppelin/src/general/AntiSandwichHook.sol"; ``` This hook implements the sandwich-resistant AMM design introduced @@ -60,7 +60,6 @@ _Available since v1.1.0_

Functions

-- [constructor(_poolManager)](#AntiSandwichHook-constructor-contract-IPoolManager-) - [_beforeSwap(sender, key, params, hookData)](#AntiSandwichHook-_beforeSwap-address-struct-PoolKey-struct-SwapParams-bytes-) - [_getBlockNumber()](#AntiSandwichHook-_getBlockNumber--) - [_getTargetUnspecified(, key, params, )](#AntiSandwichHook-_getTargetUnspecified-address-struct-PoolKey-struct-SwapParams-bytes-) @@ -118,29 +117,12 @@ _Available since v1.1.0_ #### BaseDynamicAfterFee [!toc] #### IHookEvents [!toc] #### BaseHook [!toc] -- [NotSelf()](#BaseHook-NotSelf--) -- [InvalidPool()](#BaseHook-InvalidPool--) - [HookNotImplemented()](#BaseHook-HookNotImplemented--) - [NotPoolManager()](#BaseHook-NotPoolManager--) #### IHooks [!toc]
- - -
-
-

constructor(contract IPoolManager _poolManager)

-
-

internal

-# -
-
-
- -
-
-
@@ -158,7 +140,7 @@ Handles the before swap hook. For the first swap in a block, it saves the current pool state as a checkpoint. For subsequent swaps in the same block, it calculates a target output based on the beginning-of-block state, -and sets the inherited `_targetOutput` and `_applyTargetOutput` variables to enforce price limits in [`BaseHook._afterSwap`](/uniswap-hooks/api/base#BaseHook-_afterSwap-address-struct-PoolKey-struct-SwapParams-BalanceDelta-bytes-). +and sets the inherited `_targetOutput` and `_applyTargetOutput` variables to enforce price limits in [`BaseHook._afterSwap`](base#BaseHook-_afterSwap-address-struct-PoolKey-struct-SwapParams-BalanceDelta-bytes-).
@@ -228,16 +210,16 @@ Set the hook permissions, specifically `beforeSwap`, `afterSwap`, and `afterSwap
-## `OrderIdLibrary` +## `OrderIdLibrary` - +
```solidity -import "uniswap-hooks/src/general/LimitOrderHook.sol"; +import "@openzeppelin/src/general/LimitOrderHook.sol"; ``` The order id library. @@ -289,16 +271,16 @@ Increment the order id `a`. Might overflow.
-## `LimitOrderHook` +## `LimitOrderHook` - +
```solidity -import "uniswap-hooks/src/general/LimitOrderHook.sol"; +import "@openzeppelin/src/general/LimitOrderHook.sol"; ``` Limit Order Mechanism hook. @@ -329,7 +311,6 @@ _Available since v1.1.0_

Functions

-- [constructor(_poolManager)](#LimitOrderHook-constructor-contract-IPoolManager-) - [_afterInitialize(, key, , tick)](#LimitOrderHook-_afterInitialize-address-struct-PoolKey-uint160-int24-) - [_afterSwap(, key, params, , )](#LimitOrderHook-_afterSwap-address-struct-PoolKey-struct-SwapParams-BalanceDelta-bytes-) - [placeOrder(key, tick, zeroForOne, liquidity)](#LimitOrderHook-placeOrder-struct-PoolKey-int24-bool-uint128-) @@ -397,31 +378,12 @@ _Available since v1.1.0_ - [NotFilled()](#LimitOrderHook-NotFilled--) #### IUnlockCallback [!toc] #### BaseHook [!toc] -- [NotSelf()](#BaseHook-NotSelf--) -- [InvalidPool()](#BaseHook-InvalidPool--) - [HookNotImplemented()](#BaseHook-HookNotImplemented--) - [NotPoolManager()](#BaseHook-NotPoolManager--) #### IHooks [!toc]
- - -
-
-

constructor(contract IPoolManager _poolManager)

-
-

public

-# -
-
-
- -Set the `PoolManager` address. - -
-
-
@@ -471,7 +433,7 @@ Hooks into the `afterSwap` hook to get the ticks crossed by the swap and fill th Places a limit order by adding liquidity out of range at a specific tick. The order will be filled when the pool price crosses the specified `tick`. Takes a `PoolKey` `key`, target `tick`, direction `zeroForOne` indicating whether to buy currency0 or currency1, and amount of `liquidity` to place. The interaction with the `poolManager` is done -via the `unlock` function, which will trigger the [`BaseCustomAccounting.unlockCallback`](/uniswap-hooks/api/base#BaseCustomAccounting-unlockCallback-bytes-) function. +via the `unlock` function, which will trigger the `[`BaseCustomAccounting.unlockCallback`](base#BaseCustomAccounting-unlockCallback-bytes-)` function.
@@ -492,7 +454,7 @@ Cancels a limit order by removing liquidity from the pool. Takes a `PoolKey` `ke direction `zeroForOne` indicating whether it was buying currency0 or currency1, and recipient address `to` for the removed liquidity. Note that partial cancellation is not supported - the entire liquidity added by the msg.sender will be removed. Note also that cancelling an order will cancel the order placed by the msg.sender, not orders placed by other users in the same tick range. -The interaction with the `poolManager` is done via the `unlock` function, which will trigger the [`BaseCustomAccounting.unlockCallback`](/uniswap-hooks/api/base#BaseCustomAccounting-unlockCallback-bytes-) function. +The interaction with the `poolManager` is done via the `unlock` function, which will trigger the `[`BaseCustomAccounting.unlockCallback`](base#BaseCustomAccounting-unlockCallback-bytes-)` function. @@ -512,7 +474,7 @@ The interaction with the `poolManager` is done via the `unlock` function, which Withdraws liquidity from a filled order, sending it to address `to`. Takes an `OrderId` `orderId` of the filled order to withdraw from. Returns the withdrawn amounts as `(amount0, amount1)`. Can only be called after the order is filled - use `cancelOrder` to remove liquidity from unfilled orders. The interaction with the `poolManager` is done via the -`unlock` function, which will trigger the [`BaseCustomAccounting.unlockCallback`](/uniswap-hooks/api/base#BaseCustomAccounting-unlockCallback-bytes-) function. +`unlock` function, which will trigger the `[`BaseCustomAccounting.unlockCallback`](base#BaseCustomAccounting-unlockCallback-bytes-)` function. @@ -920,22 +882,22 @@ Limit order is not filled.
-## `LiquidityPenaltyHook` +## `LiquidityPenaltyHook` - +
```solidity -import "uniswap-hooks/src/general/LiquidityPenaltyHook.sol"; +import "@openzeppelin/src/general/LiquidityPenaltyHook.sol"; ``` Just-in-Time (JIT) liquidity provisioning resistant hook. -This hook disincentivizes JIT attacks by penalizing LP fee collection during [`BaseHook._afterRemoveLiquidity`](/uniswap-hooks/api/base#BaseHook-_afterRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-), -and disabling it during [`BaseHook._afterAddLiquidity`](/uniswap-hooks/api/base#BaseHook-_afterAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) if liquidity was recently added to the position. +This hook disincentivizes JIT attacks by penalizing LP fee collection during [`BaseHook._afterRemoveLiquidity`](base#BaseHook-_afterRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-), +and disabling it during [`BaseHook._afterAddLiquidity`](base#BaseHook-_afterAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) if liquidity was recently added to the position. The penalty is donated to the pool's liquidity providers in range at the time of removal. See [`LiquidityPenaltyHook._calculateLiquidityPenalty`](#LiquidityPenaltyHook-_calculateLiquidityPenalty-BalanceDelta-uint48-) for penalty calculation. @@ -970,7 +932,7 @@ _Available since v0.1.1_

Functions

-- [constructor(_poolManager, _blockNumberOffset)](#LiquidityPenaltyHook-constructor-contract-IPoolManager-uint48-) +- [constructor(_blockNumberOffset)](#LiquidityPenaltyHook-constructor-uint48-) - [_afterAddLiquidity(sender, key, params, , feeDelta, )](#LiquidityPenaltyHook-_afterAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) - [_afterRemoveLiquidity(sender, key, params, , feeDelta, )](#LiquidityPenaltyHook-_afterRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) - [_getBlockNumber()](#LiquidityPenaltyHook-_getBlockNumber--) @@ -1014,27 +976,25 @@ _Available since v0.1.1_ - [BlockNumberOffsetTooLow()](#LiquidityPenaltyHook-BlockNumberOffsetTooLow--) - [NoLiquidityToReceiveDonation()](#LiquidityPenaltyHook-NoLiquidityToReceiveDonation--) #### BaseHook [!toc] -- [NotSelf()](#BaseHook-NotSelf--) -- [InvalidPool()](#BaseHook-InvalidPool--) - [HookNotImplemented()](#BaseHook-HookNotImplemented--) - [NotPoolManager()](#BaseHook-NotPoolManager--) #### IHooks [!toc]
- +
-

constructor(contract IPoolManager _poolManager, uint48 _blockNumberOffset)

+

constructor(uint48 _blockNumberOffset)

-

public

-# +

internal

+#
-Sets the `PoolManager` address and the `getBlockNumberOffset`. +Sets the `getBlockNumberOffset` and the [`BaseHook.poolManager`](base#BaseHook-poolManager-contract-IPoolManager) address.
@@ -1054,7 +1014,7 @@ Sets the `PoolManager` address and the `getBlockNumberOffset`. Tracks `lastAddedLiquidityBlock` and withholds `feeDelta` if liquidity was recently added within the `blockNumberOffset` period. -See [`BaseHook._afterRemoveLiquidity`](/uniswap-hooks/api/base#BaseHook-_afterRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) for claiming the withheld fees back. +See [`BaseHook._afterRemoveLiquidity`](base#BaseHook-_afterRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) for claiming the withheld fees back. @@ -1221,7 +1181,7 @@ Returns the `withheldFees` for a liquidity position. `withheldFees` are UniswapV4's `feesAccrued` retained by this hook during liquidity addition if liquidity has been recently added within the `blockNumberOffset` block time window, with the purpose of disabling fee -collection during JIT liquidity provisioning attacks. See [`BaseHook._afterRemoveLiquidity`](/uniswap-hooks/api/base#BaseHook-_afterRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) for claiming the fees back. +collection during JIT liquidity provisioning attacks. See [`BaseHook._afterRemoveLiquidity`](base#BaseHook-_afterRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) for claiming the fees back. @@ -1312,3 +1272,770 @@ A penalty was attempted to be applied and donated to LP's in range, but there ar + + + +
+ +## `ReHypothecationHook` + + + + + +
+ +```solidity +import "@openzeppelin/src/general/ReHypothecationHook.sol"; +``` + +A Uniswap V4 hook that enables rehypothecation of liquidity positions. + +This hook allows users to deposit assets into yield-generating sources (e.g., ERC-4626 vaults) +while providing liquidity to Uniswap pools Just-in-Time (JIT) during swaps. Assets earn yield +when idle and are temporarily injected as pool liquidity only when needed for swap execution, +then immediately withdrawn back to yield sources. + +Conceptually, the hook acts as an intermediary that manages: +- the user-facing ERC20 share token (representing rehypothecated positions), and +- the underlying relationship between yield sources and pool liquidity. + +Key features: +- Users can deposit assets into yield sources via the hook and receive ERC20 shares + that represent their rehypothecated liquidity position. +- The hook dynamically manages pool liquidity based on available yield source assets, + performing JIT provisioning during swaps. +- After swaps, assets are deposited back into yield sources to continue earning yield. +- Supports both ERC20 tokens and native ETH by default. + + +By default, the hook liquidity position is placed in the entire curve range. Override +the `getTickLower` and `getTickUpper` functions to customize the position. + + + +By default, both canonical and rehypothecated liquidity modifications are allowed. Override + `beforeAddLiquidity` and `beforeRemoveLiquidity` to disable canonical liquidity modifications if desired. + + + +This hook relies on the PoolManager singleton token reserves for flash accounting during swaps. +During `afterSwap`, the hook takes tokens from the PoolManager to settle deltas before users transfer +their swap tokens. The PoolManager may lack sufficient reserves for illiquid tokens, preventing +swaps until the PoolManager accumulates enough tokens for these small flash loans. This can be mitigated by +maintaining some permanent pool liquidity alongside rehypothecated liquidity. + + + +This is experimental software and is provided on an "as is" and "as available" basis. +We do not give any warranties and will not be liable for any losses incurred through any use of +this code base. +_Available since v1.2.0_ + + +
+

Functions

+
+- [getPoolKey()](#ReHypothecationHook-getPoolKey--) +- [_beforeInitialize(, key, )](#ReHypothecationHook-_beforeInitialize-address-struct-PoolKey-uint160-) +- [addReHypothecatedLiquidity(shares)](#ReHypothecationHook-addReHypothecatedLiquidity-uint256-) +- [removeReHypothecatedLiquidity(shares)](#ReHypothecationHook-removeReHypothecatedLiquidity-uint256-) +- [_beforeSwap(, , , )](#ReHypothecationHook-_beforeSwap-address-struct-PoolKey-struct-SwapParams-bytes-) +- [_afterSwap(, key, , , )](#ReHypothecationHook-_afterSwap-address-struct-PoolKey-struct-SwapParams-BalanceDelta-bytes-) +- [_resolveHookDelta(currency)](#ReHypothecationHook-_resolveHookDelta-Currency-) +- [previewAmountsForShares(shares)](#ReHypothecationHook-previewAmountsForShares-uint256-) +- [_convertSharesToAmounts(shares)](#ReHypothecationHook-_convertSharesToAmounts-uint256-) +- [_shareToAmount(shares, currency)](#ReHypothecationHook-_shareToAmount-uint256-Currency-) +- [_getLiquidityToUse()](#ReHypothecationHook-_getLiquidityToUse--) +- [_getHookPositionLiquidity()](#ReHypothecationHook-_getHookPositionLiquidity--) +- [getTickLower()](#ReHypothecationHook-getTickLower--) +- [getTickUpper()](#ReHypothecationHook-getTickUpper--) +- [_modifyLiquidity(liquidityDelta)](#ReHypothecationHook-_modifyLiquidity-int256-) +- [_transferFromSenderToHook(currency, amount, sender)](#ReHypothecationHook-_transferFromSenderToHook-Currency-uint256-address-) +- [_transferFromHookToSender(currency, amount, sender)](#ReHypothecationHook-_transferFromHookToSender-Currency-uint256-address-) +- [getCurrencyYieldSource(currency)](#ReHypothecationHook-getCurrencyYieldSource-Currency-) +- [_depositToYieldSource(currency, amount)](#ReHypothecationHook-_depositToYieldSource-Currency-uint256-) +- [_withdrawFromYieldSource(currency, amount)](#ReHypothecationHook-_withdrawFromYieldSource-Currency-uint256-) +- [_getAmountInYieldSource(currency)](#ReHypothecationHook-_getAmountInYieldSource-Currency-) +- [getHookPermissions()](#ReHypothecationHook-getHookPermissions--) +- [receive()](#ReHypothecationHook-receive--) +#### ReentrancyGuardTransient [!toc] +- [_reentrancyGuardEntered()](#ReentrancyGuardTransient-_reentrancyGuardEntered--) +- [_reentrancyGuardStorageSlot()](#ReentrancyGuardTransient-_reentrancyGuardStorageSlot--) +#### ERC20 [!toc] +- [name()](#ERC20-name--) +- [symbol()](#ERC20-symbol--) +- [decimals()](#ERC20-decimals--) +- [totalSupply()](#ERC20-totalSupply--) +- [balanceOf(account)](#ERC20-balanceOf-address-) +- [transfer(to, value)](#ERC20-transfer-address-uint256-) +- [allowance(owner, spender)](#ERC20-allowance-address-address-) +- [approve(spender, value)](#ERC20-approve-address-uint256-) +- [transferFrom(from, to, value)](#ERC20-transferFrom-address-address-uint256-) +- [_transfer(from, to, value)](#ERC20-_transfer-address-address-uint256-) +- [_update(from, to, value)](#ERC20-_update-address-address-uint256-) +- [_mint(account, value)](#ERC20-_mint-address-uint256-) +- [_burn(account, value)](#ERC20-_burn-address-uint256-) +- [_approve(owner, spender, value)](#ERC20-_approve-address-address-uint256-) +- [_approve(owner, spender, value, emitEvent)](#ERC20-_approve-address-address-uint256-bool-) +- [_spendAllowance(owner, spender, value)](#ERC20-_spendAllowance-address-address-uint256-) +#### IERC20Errors [!toc] +#### IERC20Metadata [!toc] +#### IERC20 [!toc] +#### BaseHook [!toc] +- [_validateHookAddress(hook)](#BaseHook-_validateHookAddress-contract-BaseHook-) +- [beforeInitialize(sender, key, sqrtPriceX96)](#BaseHook-beforeInitialize-address-struct-PoolKey-uint160-) +- [afterInitialize(sender, key, sqrtPriceX96, tick)](#BaseHook-afterInitialize-address-struct-PoolKey-uint160-int24-) +- [_afterInitialize(, , , )](#BaseHook-_afterInitialize-address-struct-PoolKey-uint160-int24-) +- [beforeAddLiquidity(sender, key, params, hookData)](#BaseHook-beforeAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-bytes-) +- [_beforeAddLiquidity(, , , )](#BaseHook-_beforeAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-bytes-) +- [beforeRemoveLiquidity(sender, key, params, hookData)](#BaseHook-beforeRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-bytes-) +- [_beforeRemoveLiquidity(, , , )](#BaseHook-_beforeRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-bytes-) +- [afterAddLiquidity(sender, key, params, delta0, delta1, hookData)](#BaseHook-afterAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) +- [_afterAddLiquidity(, , , , , )](#BaseHook-_afterAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) +- [afterRemoveLiquidity(sender, key, params, delta0, delta1, hookData)](#BaseHook-afterRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) +- [_afterRemoveLiquidity(, , , , , )](#BaseHook-_afterRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) +- [beforeSwap(sender, key, params, hookData)](#BaseHook-beforeSwap-address-struct-PoolKey-struct-SwapParams-bytes-) +- [afterSwap(sender, key, params, delta, hookData)](#BaseHook-afterSwap-address-struct-PoolKey-struct-SwapParams-BalanceDelta-bytes-) +- [beforeDonate(sender, key, amount0, amount1, hookData)](#BaseHook-beforeDonate-address-struct-PoolKey-uint256-uint256-bytes-) +- [_beforeDonate(, , , , )](#BaseHook-_beforeDonate-address-struct-PoolKey-uint256-uint256-bytes-) +- [afterDonate(sender, key, amount0, amount1, hookData)](#BaseHook-afterDonate-address-struct-PoolKey-uint256-uint256-bytes-) +- [_afterDonate(, , , , )](#BaseHook-_afterDonate-address-struct-PoolKey-uint256-uint256-bytes-) +- [poolManager()](#BaseHook-poolManager-contract-IPoolManager) +#### IHooks [!toc] +
+
+ +
+

Events

+
+- [ReHypothecatedLiquidityAdded(sender, poolKey, shares, amount0, amount1)](#ReHypothecationHook-ReHypothecatedLiquidityAdded-address-struct-PoolKey-uint256-uint256-uint256-) +- [ReHypothecatedLiquidityRemoved(sender, poolKey, shares, amount0, amount1)](#ReHypothecationHook-ReHypothecatedLiquidityRemoved-address-struct-PoolKey-uint256-uint256-uint256-) +#### ReentrancyGuardTransient [!toc] +#### ERC20 [!toc] +#### IERC20Errors [!toc] +#### IERC20Metadata [!toc] +#### IERC20 [!toc] +- [Transfer(from, to, value)](#IERC20-Transfer-address-address-uint256-) +- [Approval(owner, spender, value)](#IERC20-Approval-address-address-uint256-) +#### BaseHook [!toc] +#### IHooks [!toc] +
+
+ +
+

Errors

+
+- [AlreadyInitialized()](#ReHypothecationHook-AlreadyInitialized--) +- [NotInitialized()](#ReHypothecationHook-NotInitialized--) +- [ZeroShares()](#ReHypothecationHook-ZeroShares--) +- [InvalidMsgValue()](#ReHypothecationHook-InvalidMsgValue--) +- [RefundFailed()](#ReHypothecationHook-RefundFailed--) +#### ReentrancyGuardTransient [!toc] +- [ReentrancyGuardReentrantCall()](#ReentrancyGuardTransient-ReentrancyGuardReentrantCall--) +#### ERC20 [!toc] +#### IERC20Errors [!toc] +- [ERC20InsufficientBalance(sender, balance, needed)](#IERC20Errors-ERC20InsufficientBalance-address-uint256-uint256-) +- [ERC20InvalidSender(sender)](#IERC20Errors-ERC20InvalidSender-address-) +- [ERC20InvalidReceiver(receiver)](#IERC20Errors-ERC20InvalidReceiver-address-) +- [ERC20InsufficientAllowance(spender, allowance, needed)](#IERC20Errors-ERC20InsufficientAllowance-address-uint256-uint256-) +- [ERC20InvalidApprover(approver)](#IERC20Errors-ERC20InvalidApprover-address-) +- [ERC20InvalidSpender(spender)](#IERC20Errors-ERC20InvalidSpender-address-) +#### IERC20Metadata [!toc] +#### IERC20 [!toc] +#### BaseHook [!toc] +- [HookNotImplemented()](#BaseHook-HookNotImplemented--) +- [NotPoolManager()](#BaseHook-NotPoolManager--) +#### IHooks [!toc] +
+
+ + + +
+
+

getPoolKey() → struct PoolKey poolKey

+
+

public

+# +
+
+
+ +Returns the `poolKey` for the hook pool. + +
+
+ + + +
+
+

_beforeInitialize(address, struct PoolKey key, uint160) → bytes4

+
+

internal

+# +
+
+
+ +Initialize the hook's `poolKey`. The stored key by the hook is unique and +should not be modified so that it can safely be used across the hook's lifecycle. + + +Native ETH is supported by default, which can be disabled by overriding `_beforeInitialize` with: +```solidity +function _beforeInitialize(address, PoolKey calldata key, uint160) internal override returns (bytes4) { + if (key.currency0.isAddressZero()) revert UnsupportedCurrency(); + return super._beforeInitialize(key); +} +``` + + +
+
+ + + +
+
+

addReHypothecatedLiquidity(uint256 shares) → BalanceDelta delta

+
+

public

+# +
+
+
+ +Adds rehypothecated liquidity to yield sources and mints shares to the caller. + +Liquidity is added in the ratio determined by the hook's existing balances in yield sources. +Assets are deposited into yield sources where they earn returns when idle and can be +dynamically used as pool liquidity during swaps. + +Returns a balance `delta` representing the assets deposited into the hook. + +Requirements: +- Pool must be initialized +- Sender must have sufficient token balances +- Sender must have approved the hook to spend the required tokens + +
+
+ + + +
+
+

removeReHypothecatedLiquidity(uint256 shares) → BalanceDelta delta

+
+

public

+# +
+
+
+ +Removes rehypothecated liquidity from yield sources and burns caller's shares. + +Liquidity is withdrawn in the ratio determined by the hook's existing balances in yield sources. +Assets are withdrawn from yield sources where they were generating yield, allowing users to +exit their rehypothecated position and reclaim their underlying tokens. + +Returns a balance `delta` representing the assets withdrawn from the hook. + +Requirements: +- Pool must be initialized +- Sender must have sufficient shares for the desired liquidity withdrawal + +
+
+ + + +
+
+

_beforeSwap(address, struct PoolKey, struct SwapParams, bytes) → bytes4, BeforeSwapDelta, uint24

+
+

internal

+# +
+
+
+ +Hook executed before a swap operation to provide liquidity from rehypothecated assets. + +Gets the amount of liquidity to be provided from yield sources and temporarily adds it to the pool, +in a Just-in-Time provision of liquidity. + +Note that at this point there are no actual transfers of tokens happening to the pool, instead, +thanks to the Flash Accounting model, this addition creates a currencyDelta to the hook, which +must be settled during the `_afterSwap` function before locking the poolManager again. + +
+
+ + + +
+
+

_afterSwap(address, struct PoolKey key, struct SwapParams, BalanceDelta, bytes) → bytes4, int128

+
+

internal

+# +
+
+
+ +Hook executed after a swap operation to remove temporary liquidity and rebalance assets. + +Removes the liquidity that was temporarily added in `_beforeSwap`, and resolves the hook's +deltas in each currency in order to neutralize any pending debits or credits. + +
+
+ + + +
+
+

_resolveHookDelta(Currency currency)

+
+

internal

+# +
+
+
+ +Takes or settles any pending `currencyDelta` amount with the poolManager, +neutralizing the Flash Accounting deltas before locking the poolManager again. + +
+
+ + + +
+
+

previewAmountsForShares(uint256 shares) → uint256 amount0, uint256 amount1

+
+

public

+# +
+
+
+ +Preview the amounts of currency0 and currency1 required/obtained for a given amount of shares. + +
+
+ + + +
+
+

_convertSharesToAmounts(uint256 shares) → uint256 amount0, uint256 amount1

+
+

internal

+# +
+
+
+ +Calculates the amounts of currency0 and currency1 required for adding a specific amount of shares. + +If the hook has not emitted shares yet, the initial deposit ratio is determined by the current pool price. +Otherwise, it is determined by ratio of the hook balances in the yield sources. + +
+
+ + + +
+
+

_shareToAmount(uint256 shares, Currency currency) → uint256 amount

+
+

internal

+# +
+
+
+ +Converts a given `shares` amount to the corresponding `currency` amount. + +
+
+ + + +
+
+

_getLiquidityToUse() → uint256

+
+

internal

+# +
+
+
+ +Returns the `liquidity` to be provided just-in-time for incoming swaps. + +By default, returns the maximum liquidity that can be provided with the current +balances of the hook in the yield sources. + + +Since liquidity is provided and withdrawn transiently during flash accounting, it +can be virtually inflated for performing "leveraged liquidity" strategies, which would +give better pricing to swappers at the cost of the profitability of LP's and increased risks. + + +
+
+ + + +
+
+

_getHookPositionLiquidity() → uint128 liquidity

+
+

internal

+# +
+
+
+ +Retrieves the current `liquidity` of the hook owned liquidity position in the `_poolKey` pool. + + +Given that just-in-time liquidity provisioning is performed, this function will only return values +larger than zero between `beforeSwap` and `afterSwap`, where the liquidity is actually inside the pool. +It will return zero in any other point in the hook lifecycle. For determining the hook balances in any other point, +use `_getAmountInYieldSource`. + + +
+
+ + + +
+
+

getTickLower() → int24

+
+

public

+# +
+
+
+ +Returns the lower tick boundary for the hook's liquidity position. + +Can be overridden to customize the tick boundary. + +
+
+ + + +
+
+

getTickUpper() → int24

+
+

public

+# +
+
+
+ +Returns the upper tick boundary for the hook's liquidity position. + +Can be overridden to customize the tick boundary. + +
+
+ + + +
+
+

_modifyLiquidity(int256 liquidityDelta) → BalanceDelta delta

+
+

internal

+# +
+
+
+ +Modifies the hook's liquidity position in the pool. + +Positive liquidityDelta adds liquidity, while negative removes it. + +
+
+ + + +
+
+

_transferFromSenderToHook(Currency currency, uint256 amount, address sender)

+
+

internal

+# +
+
+
+ +
+
+ + + +
+
+

_transferFromHookToSender(Currency currency, uint256 amount, address sender)

+
+

internal

+# +
+
+
+ +Transfers the `amount` of `currency` from the hook to the `sender`. + +
+
+ + + +
+
+

getCurrencyYieldSource(Currency currency) → address yieldSource

+
+

public

+# +
+
+
+ +Returns the `yieldSource` address for a given `currency`. + +Note: Must be implemented and adapted for the desired type of yield sources, such as + ERC-4626 Vaults, or any custom DeFi protocol interface, optionally handling native currency. + +
+
+ + + +
+
+

_depositToYieldSource(Currency currency, uint256 amount)

+
+

internal

+# +
+
+
+ +Deposits a specified `amount` of `currency` into its corresponding yield source. + +Note: Must be implemented and adapted for the desired type of yield sources, such as + ERC-4626 Vaults, or any custom DeFi protocol interface, optionally handling native currency. + +
+
+ + + +
+
+

_withdrawFromYieldSource(Currency currency, uint256 amount)

+
+

internal

+# +
+
+
+ +Withdraws a specified `amount` of `currency` from its corresponding yield source. + +Note: Must be implemented and adapted for the desired type of yield sources, such as + ERC-4626 Vaults, or any custom DeFi protocol interface, optionally handling native currency. + +
+
+ + + +
+
+

_getAmountInYieldSource(Currency currency) → uint256 amount

+
+

internal

+# +
+
+
+ +Gets the `amount` of `currency` deposited in its corresponding yield source. + +Note: Must be implemented and adapted for the desired type of yield sources, such as + ERC-4626 Vaults, or any custom DeFi protocol interface, optionally handling native currency. + +
+
+ + + +
+
+

getHookPermissions() → struct Hooks.Permissions permissions

+
+

public

+# +
+
+
+ +
+
+ + + +
+
+

receive()

+
+

external

+# +
+
+
+ +Allows the hook to receive native ETH from the yield sources. + +
+
+ + + +
+
+

ReHypothecatedLiquidityAdded(address indexed sender, struct PoolKey indexed poolKey, uint256 shares, uint256 amount0, uint256 amount1)

+
+

event

+# +
+
+ +
+ +Emitted when a `sender` adds rehypothecated `shares` to the `poolKey` pool, + transferring `amount0` of `currency0` and `amount1` of `currency1` to the hook. + +
+
+ + +
+
+

ReHypothecatedLiquidityRemoved(address indexed sender, struct PoolKey indexed poolKey, uint256 shares, uint256 amount0, uint256 amount1)

+
+

event

+# +
+
+ +
+ +Emitted when a `sender` removes rehypothecated `liquidity` from the `poolKey` pool, + receiving `amount0` of `currency0` and `amount1` of `currency1` from the hook. + +
+
+ + + +
+
+

AlreadyInitialized()

+
+

error

+# +
+
+
+ +Error thrown when trying to initialize a pool that has already been initialized. + +
+
+ + + +
+
+

NotInitialized()

+
+

error

+# +
+
+
+ +Error thrown when attempting to interact with a pool that has not been initialized. + +
+
+ + + +
+
+

ZeroShares()

+
+

error

+# +
+
+
+ +Error thrown when attempting to add or remove liquidity with zero shares. + +
+
+ + + +
+
+

InvalidMsgValue()

+
+

error

+# +
+
+
+ +Error thrown when the message value doesn't match the expected amount for native ETH deposits. + +
+
+ + + +
+
+

RefundFailed()

+
+

error

+# +
+
+
+ +Error thrown when the refund fails. + +
+
+ diff --git a/content/uniswap-hooks/api/index.mdx b/content/uniswap-hooks/api/index.mdx index aae2e5ac..38812efa 100644 --- a/content/uniswap-hooks/api/index.mdx +++ b/content/uniswap-hooks/api/index.mdx @@ -2,7 +2,7 @@ title: API Reference --- -# API Reference +This API reference is automatically generated from the OpenZeppelin Uniswap Hooks repository. ## Base Implementations diff --git a/content/uniswap-hooks/api/interfaces.mdx b/content/uniswap-hooks/api/interfaces.mdx index b7f5a8c2..2093cf3a 100644 --- a/content/uniswap-hooks/api/interfaces.mdx +++ b/content/uniswap-hooks/api/interfaces.mdx @@ -7,16 +7,16 @@ description: "Smart contract interfaces utilities and implementations"
-## `IHookEvents` +## `IHookEvents` - +
```solidity -import "uniswap-hooks/src/interfaces/IHookEvents.sol"; +import "@openzeppelin/src/interfaces/IHookEvents.sol"; ``` Interface for standard hook events emission. @@ -108,3 +108,4 @@ added in currency0 and currency1, defined by the `poolId`. + diff --git a/content/uniswap-hooks/api/oracles.mdx b/content/uniswap-hooks/api/oracles.mdx new file mode 100644 index 00000000..a798fa5d --- /dev/null +++ b/content/uniswap-hooks/api/oracles.mdx @@ -0,0 +1,976 @@ +--- +title: "Oracles" +description: "Smart contract oracles utilities and implementations" +--- + + + +
+ +## `BaseOracleHook` + + + + + +
+ +```solidity +import "@openzeppelin/src/oracles/panoptic/BaseOracleHook.sol"; +``` + +A hook that enables a Uniswap V4 pool to record price observations and expose an oracle interface + +
+

Functions

+
+- [constructor(_maxAbsTickDelta)](#BaseOracleHook-constructor-int24-) +- [getHookPermissions()](#BaseOracleHook-getHookPermissions--) +- [_afterInitialize(, key, , tick)](#BaseOracleHook-_afterInitialize-address-struct-PoolKey-uint160-int24-) +- [_beforeSwap(, key, , )](#BaseOracleHook-_beforeSwap-address-struct-PoolKey-struct-SwapParams-bytes-) +- [observe(secondsAgos, underlyingPoolId)](#BaseOracleHook-observe-uint32---PoolId-) +- [increaseObservationCardinalityNext(observationCardinalityNext, underlyingPoolId)](#BaseOracleHook-increaseObservationCardinalityNext-uint16-PoolId-) +- [MAX_ABS_TICK_DELTA()](#BaseOracleHook-MAX_ABS_TICK_DELTA-int24) +- [observationsById()](#BaseOracleHook-observationsById-mapping-PoolId----struct-Oracle-Observation-65535--) +- [stateById()](#BaseOracleHook-stateById-mapping-PoolId----struct-BaseOracleHook-ObservationState-) +#### BaseHook [!toc] +- [_validateHookAddress(hook)](#BaseHook-_validateHookAddress-contract-BaseHook-) +- [beforeInitialize(sender, key, sqrtPriceX96)](#BaseHook-beforeInitialize-address-struct-PoolKey-uint160-) +- [_beforeInitialize(, , )](#BaseHook-_beforeInitialize-address-struct-PoolKey-uint160-) +- [afterInitialize(sender, key, sqrtPriceX96, tick)](#BaseHook-afterInitialize-address-struct-PoolKey-uint160-int24-) +- [beforeAddLiquidity(sender, key, params, hookData)](#BaseHook-beforeAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-bytes-) +- [_beforeAddLiquidity(, , , )](#BaseHook-_beforeAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-bytes-) +- [beforeRemoveLiquidity(sender, key, params, hookData)](#BaseHook-beforeRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-bytes-) +- [_beforeRemoveLiquidity(, , , )](#BaseHook-_beforeRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-bytes-) +- [afterAddLiquidity(sender, key, params, delta0, delta1, hookData)](#BaseHook-afterAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) +- [_afterAddLiquidity(, , , , , )](#BaseHook-_afterAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) +- [afterRemoveLiquidity(sender, key, params, delta0, delta1, hookData)](#BaseHook-afterRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) +- [_afterRemoveLiquidity(, , , , , )](#BaseHook-_afterRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) +- [beforeSwap(sender, key, params, hookData)](#BaseHook-beforeSwap-address-struct-PoolKey-struct-SwapParams-bytes-) +- [afterSwap(sender, key, params, delta, hookData)](#BaseHook-afterSwap-address-struct-PoolKey-struct-SwapParams-BalanceDelta-bytes-) +- [_afterSwap(, , , , )](#BaseHook-_afterSwap-address-struct-PoolKey-struct-SwapParams-BalanceDelta-bytes-) +- [beforeDonate(sender, key, amount0, amount1, hookData)](#BaseHook-beforeDonate-address-struct-PoolKey-uint256-uint256-bytes-) +- [_beforeDonate(, , , , )](#BaseHook-_beforeDonate-address-struct-PoolKey-uint256-uint256-bytes-) +- [afterDonate(sender, key, amount0, amount1, hookData)](#BaseHook-afterDonate-address-struct-PoolKey-uint256-uint256-bytes-) +- [_afterDonate(, , , , )](#BaseHook-_afterDonate-address-struct-PoolKey-uint256-uint256-bytes-) +- [poolManager()](#BaseHook-poolManager-contract-IPoolManager) +#### IHooks [!toc] +
+
+ +
+

Events

+
+- [IncreaseObservationCardinalityNext(underlyingPoolId, observationCardinalityNextOld, observationCardinalityNextNew)](#BaseOracleHook-IncreaseObservationCardinalityNext-PoolId-uint16-uint16-) +#### BaseHook [!toc] +#### IHooks [!toc] +
+
+ +
+

Errors

+
+- [PoolNotInitialized()](#BaseOracleHook-PoolNotInitialized--) +#### BaseHook [!toc] +- [HookNotImplemented()](#BaseHook-HookNotImplemented--) +- [NotPoolManager()](#BaseHook-NotPoolManager--) +#### IHooks [!toc] +
+
+ + + +
+
+

constructor(int24 _maxAbsTickDelta)

+
+

internal

+# +
+
+
+ +Initializes a Uniswap V4 pool with this hook, stores baseline observation state, and optionally performs a cardinality increase. + +
+
+ + + +
+
+

getHookPermissions() → struct Hooks.Permissions

+
+

public

+# +
+
+
+ +Get the hook permissions to signal which hook functions are to be implemented. + +Used at deployment to validate the address correctly represents the expected permissions. + +
+
+ + + +
+
+

_afterInitialize(address, struct PoolKey key, uint160, int24 tick) → bytes4

+
+

internal

+# +
+
+
+ +The hook called after the state of a pool is initialized + +
+
+ + + +
+
+

_beforeSwap(address, struct PoolKey key, struct SwapParams, bytes) → bytes4, BeforeSwapDelta, uint24

+
+

internal

+# +
+
+
+ +The hook called before a swap. + + +Note that this hook does not return either a `BeforeSwapDelta` or lp fee override — this call is used exclusively for recording price observations. + + +
+
+ + + +
+
+

observe(uint32[] secondsAgos, PoolId underlyingPoolId) → int56[], int56[]

+
+

external

+# +
+
+
+ +Returns the cumulative tick as of each timestamp `secondsAgo` from the current block timestamp on `underlyingPoolId`. + + +To get a time weighted average tick, you must call this with two values, one representing +the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick, +you must call it with secondsAgos = [3600, 0]. + + + +The time weighted average tick represents the geometric time weighted average price of the pool, in +log base sqrt(1.0001) of currency1 / currency0. The TickMath library can be used to go from a tick value to a ratio. + + +
+
+ + + +
+
+

increaseObservationCardinalityNext(uint16 observationCardinalityNext, PoolId underlyingPoolId)

+
+

public

+# +
+
+
+ +Increase the maximum number of price and liquidity observations that the oracle of `underlyingPoolId`. + +
+
+ + + +
+
+

MAX_ABS_TICK_DELTA() → int24

+
+

public

+# +
+
+
+ +The maximum absolute tick delta that can be observed for the truncated oracle + +
+
+ + + +
+
+

observationsById() → mapping(PoolId => struct Oracle.Observation[65535])

+
+

public

+# +
+
+
+ +The list of observations for a given pool ID + +
+
+ + + +
+
+

stateById() → mapping(PoolId => struct BaseOracleHook.ObservationState)

+
+

public

+# +
+
+
+ +The current observation array state for the given pool ID + +
+
+ + + +
+
+

IncreaseObservationCardinalityNext(PoolId indexed underlyingPoolId, uint16 observationCardinalityNextOld, uint16 observationCardinalityNextNew)

+
+

event

+# +
+
+ +
+ +Emitted by the hook for increases to the number of observations that can be stored. + + +`observationCardinalityNext` is not the observation cardinality until an observation is written at the index +just before a mint/swap/burn. + + +
+
+ + + +
+
+

PoolNotInitialized()

+
+

error

+# +
+
+
+ +Observation cardinality cannot be increased if the pool is not initialized + +
+
+ + + +
+ +## `OracleHookWithV3Adapters` + + + + + +
+ +```solidity +import "@openzeppelin/src/oracles/panoptic/OracleHookWithV3Adapters.sol"; +``` + +A hook that enables a Uniswap V4 pool to record price observations and expose an oracle interface with Uniswap V3-compatible adapters + +
+

Functions

+
+- [constructor(_maxAbsTickDelta)](#OracleHookWithV3Adapters-constructor-int24-) +- [_afterInitialize(, key, , tick)](#OracleHookWithV3Adapters-_afterInitialize-address-struct-PoolKey-uint160-int24-) +- [standardAdapter()](#OracleHookWithV3Adapters-standardAdapter-mapping-PoolId----address-) +- [truncatedAdapter()](#OracleHookWithV3Adapters-truncatedAdapter-mapping-PoolId----address-) +#### BaseOracleHook [!toc] +- [getHookPermissions()](#BaseOracleHook-getHookPermissions--) +- [_beforeSwap(, key, , )](#BaseOracleHook-_beforeSwap-address-struct-PoolKey-struct-SwapParams-bytes-) +- [observe(secondsAgos, underlyingPoolId)](#BaseOracleHook-observe-uint32---PoolId-) +- [increaseObservationCardinalityNext(observationCardinalityNext, underlyingPoolId)](#BaseOracleHook-increaseObservationCardinalityNext-uint16-PoolId-) +- [MAX_ABS_TICK_DELTA()](#BaseOracleHook-MAX_ABS_TICK_DELTA-int24) +- [observationsById()](#BaseOracleHook-observationsById-mapping-PoolId----struct-Oracle-Observation-65535--) +- [stateById()](#BaseOracleHook-stateById-mapping-PoolId----struct-BaseOracleHook-ObservationState-) +#### BaseHook [!toc] +- [_validateHookAddress(hook)](#BaseHook-_validateHookAddress-contract-BaseHook-) +- [beforeInitialize(sender, key, sqrtPriceX96)](#BaseHook-beforeInitialize-address-struct-PoolKey-uint160-) +- [_beforeInitialize(, , )](#BaseHook-_beforeInitialize-address-struct-PoolKey-uint160-) +- [afterInitialize(sender, key, sqrtPriceX96, tick)](#BaseHook-afterInitialize-address-struct-PoolKey-uint160-int24-) +- [beforeAddLiquidity(sender, key, params, hookData)](#BaseHook-beforeAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-bytes-) +- [_beforeAddLiquidity(, , , )](#BaseHook-_beforeAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-bytes-) +- [beforeRemoveLiquidity(sender, key, params, hookData)](#BaseHook-beforeRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-bytes-) +- [_beforeRemoveLiquidity(, , , )](#BaseHook-_beforeRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-bytes-) +- [afterAddLiquidity(sender, key, params, delta0, delta1, hookData)](#BaseHook-afterAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) +- [_afterAddLiquidity(, , , , , )](#BaseHook-_afterAddLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) +- [afterRemoveLiquidity(sender, key, params, delta0, delta1, hookData)](#BaseHook-afterRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) +- [_afterRemoveLiquidity(, , , , , )](#BaseHook-_afterRemoveLiquidity-address-struct-PoolKey-struct-ModifyLiquidityParams-BalanceDelta-BalanceDelta-bytes-) +- [beforeSwap(sender, key, params, hookData)](#BaseHook-beforeSwap-address-struct-PoolKey-struct-SwapParams-bytes-) +- [afterSwap(sender, key, params, delta, hookData)](#BaseHook-afterSwap-address-struct-PoolKey-struct-SwapParams-BalanceDelta-bytes-) +- [_afterSwap(, , , , )](#BaseHook-_afterSwap-address-struct-PoolKey-struct-SwapParams-BalanceDelta-bytes-) +- [beforeDonate(sender, key, amount0, amount1, hookData)](#BaseHook-beforeDonate-address-struct-PoolKey-uint256-uint256-bytes-) +- [_beforeDonate(, , , , )](#BaseHook-_beforeDonate-address-struct-PoolKey-uint256-uint256-bytes-) +- [afterDonate(sender, key, amount0, amount1, hookData)](#BaseHook-afterDonate-address-struct-PoolKey-uint256-uint256-bytes-) +- [_afterDonate(, , , , )](#BaseHook-_afterDonate-address-struct-PoolKey-uint256-uint256-bytes-) +- [poolManager()](#BaseHook-poolManager-contract-IPoolManager) +#### IHooks [!toc] +
+
+ +
+

Events

+
+- [AdaptersDeployed(poolId, standardAdapter, truncatedAdapter)](#OracleHookWithV3Adapters-AdaptersDeployed-PoolId-address-address-) +#### BaseOracleHook [!toc] +- [IncreaseObservationCardinalityNext(underlyingPoolId, observationCardinalityNextOld, observationCardinalityNextNew)](#BaseOracleHook-IncreaseObservationCardinalityNext-PoolId-uint16-uint16-) +#### BaseHook [!toc] +#### IHooks [!toc] +
+
+ +
+

Errors

+
+#### BaseOracleHook [!toc] +- [PoolNotInitialized()](#BaseOracleHook-PoolNotInitialized--) +#### BaseHook [!toc] +- [HookNotImplemented()](#BaseHook-HookNotImplemented--) +- [NotPoolManager()](#BaseHook-NotPoolManager--) +#### IHooks [!toc] +
+
+ + + +
+
+

constructor(int24 _maxAbsTickDelta)

+
+

internal

+# +
+
+
+ +Initializes a Uniswap V4 pool with this hook, stores baseline observation state, and optionally performs a cardinality increase. + +
+
+ + + +
+
+

_afterInitialize(address, struct PoolKey key, uint160, int24 tick) → bytes4

+
+

internal

+# +
+
+
+ +The hook called after the state of a pool is initialized + +
+
+ + + +
+
+

standardAdapter() → mapping(PoolId => address)

+
+

public

+# +
+
+
+ +Maps pool IDs to their standard V3 oracle adapters + +
+
+ + + +
+
+

truncatedAdapter() → mapping(PoolId => address)

+
+

public

+# +
+
+
+ +Maps pool IDs to their truncated V3 oracle adapters + +
+
+ + + +
+
+

AdaptersDeployed(PoolId indexed poolId, address standardAdapter, address truncatedAdapter)

+
+

event

+# +
+
+ +
+ +Emitted when adapter contracts are deployed for a pool. + +
+
+ + + +
+ +## `V3OracleAdapter` + + + + + +
+ +```solidity +import "@openzeppelin/src/oracles/panoptic/adapters/V3OracleAdapter.sol"; +``` + +This adapter exposes the normal tickCumulative values from BaseOracleHook. + +
+

Functions

+
+- [constructor(_manager, _baseOracleHook, _poolId)](#V3OracleAdapter-constructor-contract-IPoolManager-contract-BaseOracleHook-PoolId-) +- [slot0()](#V3OracleAdapter-slot0--) +- [observations(index)](#V3OracleAdapter-observations-uint256-) +- [observe(secondsAgos)](#V3OracleAdapter-observe-uint32---) +- [increaseObservationCardinalityNext(observationCardinalityNext)](#V3OracleAdapter-increaseObservationCardinalityNext-uint16-) +- [baseOracleHook()](#V3OracleAdapter-baseOracleHook-contract-BaseOracleHook) +- [manager()](#V3OracleAdapter-manager-contract-IPoolManager) +- [poolId()](#V3OracleAdapter-poolId-PoolId) +
+
+ + + +
+
+

constructor(contract IPoolManager _manager, contract BaseOracleHook _baseOracleHook, PoolId _poolId)

+
+

public

+# +
+
+
+ +
+
+ + + +
+
+

slot0() → uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked

+
+

external

+# +
+
+
+ +
+
+ + + +
+
+

observations(uint256 index) → uint32 blockTimestamp, int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128, bool initialized

+
+

external

+# +
+
+
+ +
+
+ + + +
+
+

observe(uint32[] secondsAgos) → int56[] tickCumulatives, uint160[] secondsPerLiquidityCumulativeX128s

+
+

external

+# +
+
+
+ +
+
+ + + +
+
+

increaseObservationCardinalityNext(uint16 observationCardinalityNext)

+
+

external

+# +
+
+
+ +
+
+ + + +
+
+

baseOracleHook() → contract BaseOracleHook

+
+

public

+# +
+
+
+ +
+
+ + + +
+
+

manager() → contract IPoolManager

+
+

public

+# +
+
+
+ +
+
+ + + +
+
+

poolId() → PoolId

+
+

public

+# +
+
+
+ +
+
+ + + +
+ +## `V3TruncatedOracleAdapter` + + + + + +
+ +```solidity +import "@openzeppelin/src/oracles/panoptic/adapters/V3TruncatedOracleAdapter.sol"; +``` + +This adapter exposes the truncated tickCumulative values from BaseOracleHook. + +
+

Functions

+
+- [constructor(_manager, _baseOracleHook, _poolId)](#V3TruncatedOracleAdapter-constructor-contract-IPoolManager-contract-BaseOracleHook-PoolId-) +- [slot0()](#V3TruncatedOracleAdapter-slot0--) +- [observations(index)](#V3TruncatedOracleAdapter-observations-uint256-) +- [observe(secondsAgos)](#V3TruncatedOracleAdapter-observe-uint32---) +- [increaseObservationCardinalityNext(observationCardinalityNext)](#V3TruncatedOracleAdapter-increaseObservationCardinalityNext-uint16-) +- [baseOracleHook()](#V3TruncatedOracleAdapter-baseOracleHook-contract-BaseOracleHook) +- [manager()](#V3TruncatedOracleAdapter-manager-contract-IPoolManager) +- [poolId()](#V3TruncatedOracleAdapter-poolId-PoolId) +
+
+ + + +
+
+

constructor(contract IPoolManager _manager, contract BaseOracleHook _baseOracleHook, PoolId _poolId)

+
+

public

+# +
+
+
+ +
+
+ + + +
+
+

slot0() → uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked

+
+

external

+# +
+
+
+ +
+
+ + + +
+
+

observations(uint256 index) → uint32 blockTimestamp, int56 tickCumulativeTruncated, uint160 secondsPerLiquidityCumulativeX128, bool initialized

+
+

external

+# +
+
+
+ +
+
+ + + +
+
+

observe(uint32[] secondsAgos) → int56[] tickCumulativesTruncated, uint160[] secondsPerLiquidityCumulativeX128s

+
+

external

+# +
+
+
+ +
+
+ + + +
+
+

increaseObservationCardinalityNext(uint16 observationCardinalityNext)

+
+

external

+# +
+
+
+ +
+
+ + + +
+
+

baseOracleHook() → contract BaseOracleHook

+
+

public

+# +
+
+
+ +
+
+ + + +
+
+

manager() → contract IPoolManager

+
+

public

+# +
+
+
+ +
+
+ + + +
+
+

poolId() → PoolId

+
+

public

+# +
+
+
+ +
+
+ + + +
+ +## `Oracle` + + + + + +
+ +```solidity +import "@openzeppelin/src/oracles/panoptic/libraries/Oracle.sol"; +``` + +Instances of stored oracle data, "observations", are collected in the oracle array +Every pool is initialized with an oracle array length of 1. Anyone can pay the SSTOREs to increase the +maximum length of the oracle array. New slots will be added when the array is fully populated. +Observations are overwritten when the full length of the oracle array is populated. +The most recent observation is available, independent of the length of the oracle array, by passing 0 to observe() + +
+

Functions

+
+- [transform(last, blockTimestamp, tick, maxAbsTickDelta)](#Oracle-transform-struct-Oracle-Observation-uint32-int24-int24-) +- [initialize(self, time, tick)](#Oracle-initialize-struct-Oracle-Observation-65535--uint32-int24-) +- [write(self, index, blockTimestamp, tick, cardinality, cardinalityNext, maxAbsTickDelta)](#Oracle-write-struct-Oracle-Observation-65535--uint16-uint32-int24-uint16-uint16-int24-) +- [grow(self, current, next)](#Oracle-grow-struct-Oracle-Observation-65535--uint16-uint16-) +- [lte(time, a, b)](#Oracle-lte-uint32-uint32-uint32-) +- [binarySearch(self, time, target, index, cardinality)](#Oracle-binarySearch-struct-Oracle-Observation-65535--uint32-uint32-uint16-uint16-) +- [getSurroundingObservations(self, time, target, tick, index, cardinality, maxAbsTickDelta)](#Oracle-getSurroundingObservations-struct-Oracle-Observation-65535--uint32-uint32-int24-uint16-uint16-int24-) +- [observeSingle(self, time, secondsAgo, tick, index, cardinality, maxAbsTickDelta)](#Oracle-observeSingle-struct-Oracle-Observation-65535--uint32-uint32-int24-uint16-uint16-int24-) +- [observe(self, time, secondsAgos, tick, index, cardinality, maxAbsTickDelta)](#Oracle-observe-struct-Oracle-Observation-65535--uint32-uint32---int24-uint16-uint16-int24-) +
+
+ +
+

Errors

+
+- [TargetPredatesOldestObservation(oldestTimestamp, targetTimestamp)](#Oracle-TargetPredatesOldestObservation-uint32-uint32-) +
+
+ + + +
+
+

transform(struct Oracle.Observation last, uint32 blockTimestamp, int24 tick, int24 maxAbsTickDelta) → struct Oracle.Observation

+
+

internal

+# +
+
+
+ +blockTimestamp _must_ be chronologically equal to or greater than last.blockTimestamp, safe for 0 or 1 overflows. + +
+
+ + + +
+
+

initialize(struct Oracle.Observation[65535] self, uint32 time, int24 tick) → uint16, uint16

+
+

internal

+# +
+
+
+ +
+
+ + + +
+
+

write(struct Oracle.Observation[65535] self, uint16 index, uint32 blockTimestamp, int24 tick, uint16 cardinality, uint16 cardinalityNext, int24 maxAbsTickDelta) → uint16 indexUpdated, uint16 cardinalityUpdated

+
+

internal

+# +
+
+
+ +Writable at most once per block. Index represents the most recently written element. cardinality and index must be tracked externally. +If the index is at the end of the allowable array length (according to cardinality), and the next cardinality +is greater than the current one, cardinality may be increased. This restriction is created to preserve ordering. + +
+
+ + + +
+
+

grow(struct Oracle.Observation[65535] self, uint16 current, uint16 next) → uint16

+
+

internal

+# +
+
+
+ +
+
+ + + +
+
+

lte(uint32 time, uint32 a, uint32 b) → bool

+
+

internal

+# +
+
+
+ +safe for 0 or 1 overflows, a and b _must_ be chronologically before or equal to time + +
+
+ + + +
+
+

binarySearch(struct Oracle.Observation[65535] self, uint32 time, uint32 target, uint16 index, uint16 cardinality) → struct Oracle.Observation beforeOrAt, struct Oracle.Observation atOrAfter

+
+

internal

+# +
+
+
+ +The answer must be contained in the array, used when the target is located within the stored observation +boundaries: older than the most recent observation and younger, or the same age as, the oldest observation. + +
+
+ + + +
+
+

getSurroundingObservations(struct Oracle.Observation[65535] self, uint32 time, uint32 target, int24 tick, uint16 index, uint16 cardinality, int24 maxAbsTickDelta) → struct Oracle.Observation beforeOrAt, struct Oracle.Observation atOrAfter

+
+

internal

+# +
+
+
+ +Assumes there is at least 1 initialized observation. +Used by observeSingle() to compute the counterfactual accumulator values as of a given block timestamp. + +
+
+ + + +
+
+

observeSingle(struct Oracle.Observation[65535] self, uint32 time, uint32 secondsAgo, int24 tick, uint16 index, uint16 cardinality, int24 maxAbsTickDelta) → int56, int56

+
+

internal

+# +
+
+
+ +Reverts if an observation at or before the desired observation timestamp does not exist. +0 may be passed as `secondsAgo' to return the current cumulative values. +If called with a timestamp falling between two observations, returns the counterfactual accumulator values +at exactly the timestamp between the two observations. + +
+
+ + + +
+
+

observe(struct Oracle.Observation[65535] self, uint32 time, uint32[] secondsAgos, int24 tick, uint16 index, uint16 cardinality, int24 maxAbsTickDelta) → int56[] tickCumulatives, int56[] tickCumulativeTruncated

+
+

internal

+# +
+
+
+ +Reverts if `secondsAgos` > oldest observation. + +
+
+ + + +
+
+

TargetPredatesOldestObservation(uint32 oldestTimestamp, uint32 targetTimestamp)

+
+

error

+# +
+
+
+ +
+
+ diff --git a/content/uniswap-hooks/api/utils.mdx b/content/uniswap-hooks/api/utils.mdx index 2e991cff..a312b803 100644 --- a/content/uniswap-hooks/api/utils.mdx +++ b/content/uniswap-hooks/api/utils.mdx @@ -7,16 +7,16 @@ description: "Smart contract utils utilities and implementations"
-## `CurrencySettler` +## `CurrencySettler` - +
```solidity -import "uniswap-hooks/src/utils/CurrencySettler.sol"; +import "@openzeppelin/src/utils/CurrencySettler.sol"; ``` Library used to interact with the `PoolManager` to settle any open deltas. @@ -66,3 +66,4 @@ Deltas are synced before any ERC-20 transfers in [`CurrencySettler.settle`](#Cur + diff --git a/content/uniswap-hooks/changelog.mdx b/content/uniswap-hooks/changelog.mdx index 3c2c3ff1..f4740497 100644 --- a/content/uniswap-hooks/changelog.mdx +++ b/content/uniswap-hooks/changelog.mdx @@ -1,12 +1,82 @@ --- title: Changelog --- +
+ +# [v1.2.1](https://github.com/OpenZeppelin/uniswap-hooks/releases/tag/v1.2.1) - 2025-11-27 + +## Hardhat support +* Add npm dependencies for hardhat support + +[Changes][v1.2.1] + + + +# [v1.2.0](https://github.com/OpenZeppelin/uniswap-hooks/releases/tag/v1.2.0) - 2025-11-27 + +## Base + +**BaseHook**: Deprecate `onlySelf` and `onlyValidPools` modifiers to improve extensibility and simplify hook implementation patterns. ([#105](https://github.com/OpenZeppelin/uniswap-hooks/issues/105)) + +## Fee + +**BaseFeeHook**: Add fee hook implementation to enable custom fee logic in derived contracts. ([#65](https://github.com/OpenZeppelin/uniswap-hooks/issues/65)) + +**BaseDynamicFee**: Refactor dynamic fee calculation to support more flexible fee structures and improve gas efficiency. ([#105](https://github.com/OpenZeppelin/uniswap-hooks/issues/105)) + +## General + +**RehypothecationHook**: Implementation of a rehypothecation mechanism allowing collateral reuse within liquidity pools. Hook enables efficient capital utilization while maintaining proper accounting. ([#84](https://github.com/OpenZeppelin/uniswap-hooks/issues/84)) + +## Oracles + +**PanopticOracle**: Add Panoptic-style oracle implementations for improved price data aggregation and manipulation resistance in hook contexts. ([#99](https://github.com/OpenZeppelin/uniswap-hooks/issues/99)) + +## Development +- Add balance delta assertions to improve test coverage and validation of state changes during hook execution. ([#100](https://github.com/OpenZeppelin/uniswap-hooks/issues/100)) +- Refactor magic values across test suite for better maintainability and readability. ([#106](https://github.com/OpenZeppelin/uniswap-hooks/issues/106)) +- Add Solhint linting with pre-commit hooks for code quality enforcement. ([#69](https://github.com/OpenZeppelin/uniswap-hooks/issues/69)) +- Apply Solhint rule fixes across codebase. ([#95](https://github.com/OpenZeppelin/uniswap-hooks/issues/95)) +- Update Solhint configuration and disable no-unused-vars for function parameters. ([#102](https://github.com/OpenZeppelin/uniswap-hooks/issues/102)) +- Update CI/CD workflows and dependency versions. ([#94](https://github.com/OpenZeppelin/uniswap-hooks/issues/94)) +- Update remappings and bump Solidity pragma to 0.8.26. ([#98](https://github.com/OpenZeppelin/uniswap-hooks/issues/98)) +- Address Slither static analysis detections. ([#103](https://github.com/OpenZeppelin/uniswap-hooks/issues/103)) +- Update vulnerable dependencies (cookie, tmp). ([#107](https://github.com/OpenZeppelin/uniswap-hooks/issues/107)) +- Fix documentation publishing workflow to avoid errors with no changes. ([#108](https://github.com/OpenZeppelin/uniswap-hooks/issues/108)) +- Update git submodules to latest versions. ([#109](https://github.com/OpenZeppelin/uniswap-hooks/issues/109)) +- Bump library version to 1.2.0. ([#104](https://github.com/OpenZeppelin/uniswap-hooks/issues/104)) + +[Changes][v1.2.0] + + + +# [v1.1.1](https://github.com/OpenZeppelin/uniswap-hooks/releases/tag/v1.1.1) - 2025-11-27 + +## Hardhat support +* Add npm dependencies for hardhat support + +[Changes][v1.1.1] + + + +# [v1.2.0-rc.1](https://github.com/OpenZeppelin/uniswap-hooks/releases/tag/v1.2.0-rc.1) - 2025-10-27 + + + +[Changes][v1.2.0-rc.1] + + + +# [v1.2.0-rc.0](https://github.com/OpenZeppelin/uniswap-hooks/releases/tag/v1.2.0-rc.0) - 2025-10-23 + + + +[Changes][v1.2.0-rc.0] + # [v1.1.0](https://github.com/OpenZeppelin/uniswap-hooks/releases/tag/v1.1.0) - 2025-07-11 -### Changes by Category - ## Base * `BaseAsyncSwap`: Add interface `IHookEvents` to the contract in order to standardize event emissions in hooks. Add `_calculateSwapFee` function to calculate the swap fee amount in an asynchronous swap. ([#47](https://github.com/OpenZeppelin/uniswap-hooks/issues/47)) @@ -35,6 +105,30 @@ title: Changelog [Changes][v1.1.0] + +# [v1.1.0-rc.2](https://github.com/OpenZeppelin/uniswap-hooks/releases/tag/v1.1.0-rc.2) - 2025-06-17 + + + +[Changes][v1.1.0-rc.2] + + + +# [v1.1.0-rc.1](https://github.com/OpenZeppelin/uniswap-hooks/releases/tag/v1.1.0-rc.1) - 2025-05-13 + + + +[Changes][v1.1.0-rc.1] + + + +# [v1.1.0-rc.0](https://github.com/OpenZeppelin/uniswap-hooks/releases/tag/v1.1.0-rc.0) - 2025-04-28 + + + +[Changes][v1.1.0-rc.0] + + # [v1.0.0](https://github.com/OpenZeppelin/uniswap-hooks/releases/tag/v1.0.0) - 2025-02-24 @@ -64,5 +158,22 @@ Libraries and general purpose utilities to help develop hooks. [Changes][v1.0.0] -[v1.1.0]: https://github.com/OpenZeppelin/uniswap-hooks/compare/v1.0.0...v1.1.0 -[v1.0.0]: https://github.com/OpenZeppelin/uniswap-hooks/tree/v1.0.0 + +# [v1.0.0-rc.0](https://github.com/OpenZeppelin/uniswap-hooks/releases/tag/v1.0.0-rc.0) - 2025-01-06 + + + +[Changes][v1.0.0-rc.0] + + +[v1.2.1]: https://github.com/OpenZeppelin/uniswap-hooks/compare/v1.2.0...v1.2.1 +[v1.2.0]: https://github.com/OpenZeppelin/uniswap-hooks/compare/v1.1.1...v1.2.0 +[v1.1.1]: https://github.com/OpenZeppelin/uniswap-hooks/compare/v1.2.0-rc.1...v1.1.1 +[v1.2.0-rc.1]: https://github.com/OpenZeppelin/uniswap-hooks/compare/v1.2.0-rc.0...v1.2.0-rc.1 +[v1.2.0-rc.0]: https://github.com/OpenZeppelin/uniswap-hooks/compare/v1.1.0...v1.2.0-rc.0 +[v1.1.0]: https://github.com/OpenZeppelin/uniswap-hooks/compare/v1.1.0-rc.2...v1.1.0 +[v1.1.0-rc.2]: https://github.com/OpenZeppelin/uniswap-hooks/compare/v1.1.0-rc.1...v1.1.0-rc.2 +[v1.1.0-rc.1]: https://github.com/OpenZeppelin/uniswap-hooks/compare/v1.1.0-rc.0...v1.1.0-rc.1 +[v1.1.0-rc.0]: https://github.com/OpenZeppelin/uniswap-hooks/compare/v1.0.0...v1.1.0-rc.0 +[v1.0.0]: https://github.com/OpenZeppelin/uniswap-hooks/compare/v1.0.0-rc.0...v1.0.0 +[v1.0.0-rc.0]: https://github.com/OpenZeppelin/uniswap-hooks/tree/v1.0.0-rc.0 diff --git a/content/uniswap-hooks/index.mdx b/content/uniswap-hooks/index.mdx index 1aeab87f..4fa3a03b 100644 --- a/content/uniswap-hooks/index.mdx +++ b/content/uniswap-hooks/index.mdx @@ -4,19 +4,31 @@ title: Uniswap Hooks A [Solidity library](https://github.com/OpenZeppelin/uniswap-hooks) for secure and modular hooks for [Uniswap v4](https://docs.uniswap.org/contracts/v4/overview). This library includes: -* Base implementations for custom accounting, asynchronous swaps, and custom curves -* Fee-related implementations for management and enforcement -* Ready-to-use hooks for general use cases, like sandwich protection -* Utilities and libraries for hook development +* Utilities and libraries for advanced hooks development +* Primitives for implementing features such as custom accounting, asynchronous swaps, and custom curves. +* Different fee-related implementations, such as dynamic fees, target-or-penalty fees, and hook fees. +* Ready-to-use hooks for general use cases, like sandwich protection, just in time liquidity protection, limit orders, and rehypothecated liquidity. ## Overview ### Installation -The library can only be installed with Foundry using gitmodules for now. Support for Hardhat is coming soon. +#### Hardhat (npm) + +```console +$ npm install OpenZeppelin/uniswap-hooks +``` #### Foundry (git) + +When installing via git, it is a common error to use the `master` branch. This is a development branch that should be avoided in favor of tagged releases. The release process involves security measures that the `master` branch does not guarantee. + + + +Foundry installs the latest version initially, but subsequent `forge update` commands will use the `master` branch. + + ```console $ forge install OpenZeppelin/uniswap-hooks ``` @@ -25,6 +37,7 @@ $ forge install OpenZeppelin/uniswap-hooks Make sure to add `@openzeppelin/uniswap-hooks/=lib/uniswap-hooks/src/` in `remappings.txt`. + ### Usage Once installed, you can use the contracts in the library by importing them: @@ -33,13 +46,13 @@ Once installed, you can use the contracts in the library by importing them: // SPDX-License-Identifier: MIT pragma solidity ^0.8.26; -import {BaseDynamicFee, IPoolManager, PoolKey} from "src/fee/BaseDynamicFee.sol"; +import {BaseDynamicFee, IPoolManager, PoolKey} from "@openzeppelin/uniswap-hooks/fee/BaseDynamicFee.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; /** * @dev A hook that allows the owner to dynamically update the LP fee. */ -contract DynamicLPFeeHook is BaseDynamicFee, Ownable { +contract DynamicOwnedLPFeeHook is BaseDynamicFee, Ownable { uint24 public fee; constructor(IPoolManager _poolManager) BaseDynamicFee(_poolManager) Ownable(msg.sender) { @@ -61,12 +74,25 @@ contract DynamicLPFeeHook is BaseDynamicFee, Ownable { } ``` -To keep your system secure, you should ***always*** use the installed code as-is, and neither copy-paste it from online sources, nor modify it yourself. The library is designed so that only the contracts and functions you use are deployed, so you don’t need to worry about it needlessly increasing gas costs. + +If you’re new to uniswap v4 hooks development, head to [Uniswap Hooks Quickstart](https://docs.uniswap.org/contracts/v4/quickstart/hooks/setup) to learn to configure your environment for creating and compililing your first hook. + + + +To keep your system secure, you should ***always*** use the installed code as-is, and neither copy-paste it from online sources, nor modify it yourself. The library is designed so that only the contracts and functions you use are included, so you don’t need to worry about it needlessly increasing gas costs. + +## API Reference + +The [full API](/uniswap-hooks/api/) is also thoroughly documented, and serves as a great reference when developing your smart contract application. You can also ask for help or follow Contracts' development in the [community forum](https://forum.openzeppelin.com) or [telegram channel](https://t.me/openzeppelin_tg). + +## Hooks Wizard 🪄 + +Head to the [Hooks Wizard](https://wizard.openzeppelin.com/uniswap-hooks) to construct feature-rich hooks by selecting the options that fit your needs, generating the code automatically for you. -### Videos +## Videos In order to facilitate understanding of Uniswap Hooks and help start building with them, we’ve released this playlist of guidelines on our YouTube channel. - + ## Security diff --git a/package.json b/package.json index 12514344..0ee48c4f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "docs", "version": "0.0.0", "private": true, - "type": "module", + "type": "module", "scripts": { "build": "next build --turbo", "dev": "next dev --turbo", @@ -43,6 +43,7 @@ "next": "^15.5.7", "next-themes": "^0.4.6", "next-validate-link": "^1.6.3", + "prettier": "^3.7.4", "react": "^19.2.1", "react-dom": "^19.2.1", "rehype-katex": "^7.0.1", @@ -69,5 +70,5 @@ "tw-animate-css": "^1.3.8", "typescript": "^5.9.2" }, - "packageManager": "pnpm@10.17.1" + "packageManager": "pnpm@10.24.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 90575e4f..4672ed97 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -83,6 +83,9 @@ importers: next-validate-link: specifier: ^1.6.3 version: 1.6.3 + prettier: + specifier: ^3.7.4 + version: 3.7.4 react: specifier: ^19.2.1 version: 19.2.1 @@ -2608,8 +2611,8 @@ packages: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} - prettier@3.6.2: - resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + prettier@3.7.4: + resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==} engines: {node: '>=14'} hasBin: true @@ -3325,7 +3328,7 @@ snapshots: dependencies: '@apidevtools/json-schema-ref-parser': 11.9.3 js-yaml: 4.1.1 - prettier: 3.6.2 + prettier: 3.7.4 '@iconify/types@2.0.0': {} @@ -5904,7 +5907,7 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - prettier@3.6.2: {} + prettier@3.7.4: {} property-information@7.1.0: {} diff --git a/scripts/generate-changelog.js b/scripts/generate-changelog.js index 8f232575..091da850 100755 --- a/scripts/generate-changelog.js +++ b/scripts/generate-changelog.js @@ -1,18 +1,20 @@ #!/usr/bin/env node -const fs = require("node:fs").promises; -const path = require("node:path"); -const { execSync } = require("node:child_process"); +import { promises as fs } from "node:fs"; +import path from "node:path"; +import { execSync } from "node:child_process"; -// Check if two arguments are provided -if (process.argv.length !== 4) { - console.error("Usage: node generate-changelog.js "); +// Check if at least two arguments are provided +if (process.argv.length < 4) { + console.error("Usage: node generate-changelog.js [-p]"); + console.error(" -p: Include pre-releases"); process.exit(1); } // Assign arguments to variables const url = process.argv[2]; const filePath = process.argv[3]; +const includePrereleases = process.argv.includes("-p"); // Check if changelog-from-release is installed function checkChangelogFromRelease() { @@ -34,14 +36,18 @@ async function generateChangelog() { const frontmatter = `--- title: Changelog --- - +
`; // Run changelog-from-release and get output - const changelogOutput = execSync(`changelog-from-release -r "${url}"`, { - encoding: "utf8", - stdio: "pipe", - }); + const flags = includePrereleases ? " -p" : ""; + const changelogOutput = execSync( + `changelog-from-release -r "${url}"${flags}`, + { + encoding: "utf8", + stdio: "pipe", + }, + ); // Remove the generated tag at the end const cleanOutput = changelogOutput