Base
This document is better viewed on the docs page. |
Base contracts for building secure and modular Uniswap hooks, providing core functionality and common patterns for hook development.
-
BaseCustomAccounting
: Base hook implementation for custom accounting, including support for swaps and liquidity management. -
BaseCustomCurve
: Base hook implementation for custom curves. -
BaseHook
: Base implementation for hooks. -
BaseAsyncSwap
: Base hook implementation for asynchronous swaps.
Hooks
BaseCustomAccounting
import "uniswap-hooks/src/base/BaseCustomAccounting.sol";
Base implementation for custom accounting and hook-owned liquidity.
To enable hook-owned liquidity, tokens must be deposited via the hook to allow control and flexibility over the liquidity. The implementation inheriting this hook must implement the respective functions to calculate the liquidity modification parameters and the amount of liquidity shares to mint or burn.
Additionally, the implementer must consider that the hook is the sole owner of the liquidity and manage fees over liquidity shares accordingly.
This base hook is designed to work with a single pool key. If you want to use the same custom
accounting hook for multiple pools, you must have multiple storage instances of this contract and
initialize them via the PoolManager with their respective pool keys.
|
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
ensure(uint256 deadline)
modifier
Ensure the deadline of a liquidity modification request is not expired.
addLiquidity(struct BaseCustomAccounting.AddLiquidityParams params) → BalanceDelta delta
external
To cover all possible scenarios, msg.sender
should have already given the hook an allowance
of at least amount0Desired/amount1Desired on token0/token1. Always adds assets at the ideal ratio,
according to the price when the transaction is executed.
The amount0Min and amount1Min parameters are relative to the principal delta, which excludes
fees accrued from the liquidity modification delta.
|
removeLiquidity(struct BaseCustomAccounting.RemoveLiquidityParams params) → BalanceDelta delta
external
_modifyLiquidity(bytes params) → BalanceDelta callerDelta, BalanceDelta feesAccrued
internal
Calls the PoolManager
to unlock and call back the hook’s unlockCallback
function.
unlockCallback(bytes rawData) → bytes returnData
external
Callback from the PoolManager
when liquidity is modified, either adding or removing.
_handleAccruedFees(struct BaseCustomAccounting.CallbackData data, BalanceDelta callerDelta, BalanceDelta feesAccrued)
internal
Handle any fees accrued in a liquidity position. By default, this function transfers the tokens to the owner of the liquidity position. However, this function can be overriden to take fees accrued in the position, or any other desired logic.
_beforeInitialize(address, struct PoolKey key, uint160) → bytes4
internal
Initialize the hook’s pool key. The stored key should act immutably so that it can safely be used across the hook’s functions.
_beforeAddLiquidity(address, struct PoolKey, struct IPoolManager.ModifyLiquidityParams, bytes) → bytes4
internal
Revert when liquidity is attempted to be added via the PoolManager
.
_beforeRemoveLiquidity(address, struct PoolKey, struct IPoolManager.ModifyLiquidityParams, bytes) → bytes4
internal
Revert when liquidity is attempted to be removed via the PoolManager
.
_getAddLiquidity(uint160 sqrtPriceX96, struct BaseCustomAccounting.AddLiquidityParams params) → bytes modify, uint256 shares
internal
Get the liquidity modification to apply for a given liquidity addition, and the amount of liquidity shares would be minted to the sender.
_getRemoveLiquidity(struct BaseCustomAccounting.RemoveLiquidityParams params) → bytes modify, uint256 shares
internal
Get the liquidity modification to apply for a given liquidity removal, and the amount of liquidity shares would be burned from the sender.
_mint(struct BaseCustomAccounting.AddLiquidityParams params, BalanceDelta callerDelta, BalanceDelta feesAccrued, uint256 shares)
internal
Mint liquidity shares to the sender.
_burn(struct BaseCustomAccounting.RemoveLiquidityParams params, BalanceDelta callerDelta, BalanceDelta feesAccrued, uint256 shares)
internal
Burn liquidity shares from the sender.
getHookPermissions() → struct Hooks.Permissions permissions
public
Set the hook permissions, specifically beforeInitialize
, beforeAddLiquidity
and beforeRemoveLiquidity
.
ExpiredPastDeadline()
error
A liquidity modification order was attempted to be executed after the deadline.
BaseCustomCurve
import "uniswap-hooks/src/base/BaseCustomCurve.sol";
Base implementation for custom curves, inheriting from BaseCustomAccounting
.
This hook allows to implement a custom curve (or any logic) for swaps, which overrides the default v3-like
concentrated liquidity implementation of the PoolManager
. During a swap, the hook calls the
_getUnspecifiedAmount
function to get the amount of tokens to be sent to the receiver. The return delta
created from this calculation is then consumed and applied by the PoolManager
.
This hook by default does not include fee or salt mechanisms, which can be implemented by inheriting contracts if needed. |
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
_getAddLiquidity(uint160, struct BaseCustomAccounting.AddLiquidityParams params) → bytes, uint256
internal
Defines how the liquidity modification data is encoded and returned for an add liquidity request.
_getRemoveLiquidity(struct BaseCustomAccounting.RemoveLiquidityParams params) → bytes, uint256
internal
Defines how the liquidity modification data is encoded and returned for a remove liquidity request.
_beforeSwap(address sender, struct PoolKey key, struct IPoolManager.SwapParams params, bytes) → bytes4, BeforeSwapDelta, uint24
internal
Overides the default swap logic of the PoolManager
and calls the _getUnspecifiedAmount
to get the amount of tokens to be sent to the receiver.
In order to take and settle tokens from the pool, the hook must hold the liquidity added
via the addLiquidity function.
|
_modifyLiquidity(bytes params) → BalanceDelta callerDelta, BalanceDelta feesAccrued
internal
Overides the custom accounting logic to support the custom curve integer amounts.
unlockCallback(bytes rawData) → bytes returnData
external
Decodes the callback data and applies the liquidity modifications, overriding the custom accounting logic to mint and burn ERC-6909 claim tokens which are used in swaps.
_getUnspecifiedAmount(struct IPoolManager.SwapParams params) → uint256 unspecifiedAmount
internal
Calculate the amount of the unspecified currency to be taken or settled from the swapper, depending on the swap direction and the fee amount to be paid to LPs.
_getSwapFeeAmount(struct IPoolManager.SwapParams params, uint256 unspecifiedAmount) → uint256 swapFeeAmount
internal
Calculate the amount of fees to be paid to LPs in a swap.
_getAmountOut(struct BaseCustomAccounting.RemoveLiquidityParams params) → uint256 amount0, uint256 amount1, uint256 shares
internal
Calculate the amount of tokens to use and liquidity shares to burn for a remove liquidity request.
BaseHook
import "uniswap-hooks/src/base/BaseHook.sol";
Base hook implementation.
This contract defines all hook entry points, as well as security and permission helpers. Based on the Uniswap v4 periphery implementation.
Hook entry points must be overiden and implemented by the inheriting hook to be used. Their respective
flags must be set to true in the getHookPermissions function as well.
|
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
onlyValidPools(contract IHooks hooks)
modifier
Restrict the function to only be called for a valid pool.
constructor(contract IPoolManager _poolManager)
internal
Set the pool manager and check that the hook address matches the expected permissions and flags.
getHookPermissions() → struct Hooks.Permissions 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.
validateHookAddress(contract BaseHook hook)
internal
Validate the hook address against the expected permissions.
_beforeInitialize(address, struct PoolKey, uint160) → bytes4
internal
Hook implementation for beforeInitialize
, to be overriden by the inheriting hook. The
flag must be set to true in the getHookPermissions
function.
afterInitialize(address sender, struct PoolKey key, uint160 sqrtPriceX96, int24 tick) → bytes4
external
_afterInitialize(address, struct PoolKey, uint160, int24) → bytes4
internal
Hook implementation for afterInitialize
, to be overriden by the inheriting hook. The
flag must be set to true in the getHookPermissions
function.
beforeAddLiquidity(address sender, struct PoolKey key, struct IPoolManager.ModifyLiquidityParams params, bytes hookData) → bytes4
external
_beforeAddLiquidity(address, struct PoolKey, struct IPoolManager.ModifyLiquidityParams, bytes) → bytes4
internal
Hook implementation for beforeAddLiquidity
, to be overriden by the inheriting hook. The
flag must be set to true in the getHookPermissions
function.
beforeRemoveLiquidity(address sender, struct PoolKey key, struct IPoolManager.ModifyLiquidityParams params, bytes hookData) → bytes4
external
_beforeRemoveLiquidity(address, struct PoolKey, struct IPoolManager.ModifyLiquidityParams, bytes) → bytes4
internal
Hook implementation for beforeRemoveLiquidity
, to be overriden by the inheriting hook. The
flag must be set to true in the getHookPermissions
function.
afterAddLiquidity(address sender, struct PoolKey key, struct IPoolManager.ModifyLiquidityParams params, BalanceDelta delta0, BalanceDelta delta1, bytes hookData) → bytes4, BalanceDelta
external
_afterAddLiquidity(address, struct PoolKey, struct IPoolManager.ModifyLiquidityParams, BalanceDelta, BalanceDelta, bytes) → bytes4, BalanceDelta
internal
Hook implementation for afterAddLiquidity
, to be overriden by the inheriting hook. The
flag must be set to true in the getHookPermissions
function.
afterRemoveLiquidity(address sender, struct PoolKey key, struct IPoolManager.ModifyLiquidityParams params, BalanceDelta delta0, BalanceDelta delta1, bytes hookData) → bytes4, BalanceDelta
external
_afterRemoveLiquidity(address, struct PoolKey, struct IPoolManager.ModifyLiquidityParams, BalanceDelta, BalanceDelta, bytes) → bytes4, BalanceDelta
internal
Hook implementation for afterRemoveLiquidity
, to be overriden by the inheriting hook. The
flag must be set to true in the getHookPermissions
function.
beforeSwap(address sender, struct PoolKey key, struct IPoolManager.SwapParams params, bytes hookData) → bytes4, BeforeSwapDelta, uint24
external
_beforeSwap(address, struct PoolKey, struct IPoolManager.SwapParams, bytes) → bytes4, BeforeSwapDelta, uint24
internal
Hook implementation for beforeSwap
, to be overriden by the inheriting hook. The
flag must be set to true in the getHookPermissions
function.
afterSwap(address sender, struct PoolKey key, struct IPoolManager.SwapParams params, BalanceDelta delta, bytes hookData) → bytes4, int128
external
_afterSwap(address, struct PoolKey, struct IPoolManager.SwapParams, BalanceDelta, bytes) → bytes4, int128
internal
Hook implementation for afterSwap
, to be overriden by the inheriting hook. The
flag must be set to true in the getHookPermissions
function.
beforeDonate(address sender, struct PoolKey key, uint256 amount0, uint256 amount1, bytes hookData) → bytes4
external
_beforeDonate(address, struct PoolKey, uint256, uint256, bytes) → bytes4
internal
Hook implementation for beforeDonate
, to be overriden by the inheriting hook. The
flag must be set to true in the getHookPermissions
function.
afterDonate(address sender, struct PoolKey key, uint256 amount0, uint256 amount1, bytes hookData) → bytes4
external
BaseAsyncSwap
import "uniswap-hooks/src/base/BaseAsyncSwap.sol";
Base implementation for async swaps, which skip the v3-like swap implementation of the PoolManager
by taking the full swap input amount and returning a delta that nets out the specified amount to 0.
This base hook allows developers to implement arbitrary logic to handle swaps, including use-cases like
asynchronous swaps and custom swap-ordering. However, given this flexibility, developers should ensure
that any logic implemented interacts safely with the PoolManager
and works correctly.
In order to handle async swaps, the hook mints ERC-6909 claim tokens for the specified currency and amount.
Inheriting contracts are free to handle these claim tokens as necessary, which can be redeemed for the
underlying currency by using the settle
function from the CurrencySettler
library.
If the hook is used for multiple pools, the ERC-6909 tokens must be separated and managed independently for each pool in order to prevent draining of ERC-6909 tokens from one pool to another. |
The hook only supports async exact-input swaps. Exact-output swaps will be processed normally
by the PoolManager .
|
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
_beforeSwap(address sender, struct PoolKey key, struct IPoolManager.SwapParams params, bytes) → bytes4, BeforeSwapDelta, uint24
internal
Skip the v3-like swap implementation of the PoolManager
by returning a delta that nets out the
specified amount to 0 to enable asynchronous swaps.