Fee
Smart contract fee utilities and implementations
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
for the unspecified currency of the swap
during BaseAsyncSwap._beforeSwap
, 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
.
NOTE: In order to use this hook, the inheriting contract must implement BaseDynamicAfterFee._getTargetUnspecified
to determine the target,
and BaseDynamicAfterFee._afterSwapHandler
to handle accumulated fees.
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
- _transientTargetUnspecifiedAmount()
- _transientApplyTarget()
- _setTransientTargetUnspecifiedAmount(value)
- _setTransientApplyTarget(value)
- constructor(_poolManager)
- _beforeSwap(sender, key, params, hookData)
- _afterSwap(sender, key, params, delta, )
- _getTargetUnspecified(sender, key, params, hookData)
- _afterSwapHandler(key, params, delta, targetUnspecifiedAmount, feeAmount)
- getHookPermissions()
IHookEvents
BaseHook
- _validateHookAddress(hook)
- beforeInitialize(sender, key, sqrtPriceX96)
- _beforeInitialize(, , )
- afterInitialize(sender, key, sqrtPriceX96, tick)
- _afterInitialize(, , , )
- beforeAddLiquidity(sender, key, params, hookData)
- _beforeAddLiquidity(, , , )
- beforeRemoveLiquidity(sender, key, params, hookData)
- _beforeRemoveLiquidity(, , , )
- afterAddLiquidity(sender, key, params, delta0, delta1, hookData)
- _afterAddLiquidity(, , , , , )
- afterRemoveLiquidity(sender, key, params, delta0, delta1, hookData)
- _afterRemoveLiquidity(, , , , , )
- beforeSwap(sender, key, params, hookData)
- afterSwap(sender, key, params, delta, hookData)
- beforeDonate(sender, key, amount0, amount1, hookData)
- _beforeDonate(, , , , )
- afterDonate(sender, key, amount0, amount1, hookData)
- _afterDonate(, , , , )
- poolManager()
IHooks
Events
_transientTargetUnspecifiedAmount() → uint256
internal
#The target unspecified amount to be enforced by the afterSwap
hook.
_transientApplyTarget() → bool
internal
#Whether the target unspecified amount should be enforced by the afterSwap
hook.
_setTransientTargetUnspecifiedAmount(uint256 value)
internal
#Set the target unspecified amount to be enforced by the afterSwap
hook.
_setTransientApplyTarget(bool value)
internal
#Set the apply flag to be used in the afterSwap
hook.
constructor(contract IPoolManager _poolManager)
internal
#Set the PoolManager
address.
_beforeSwap(address sender, struct PoolKey key, struct SwapParams params, bytes hookData) → bytes4, BeforeSwapDelta, uint24
internal
#Sets the target unspecified amount and apply flag to be used in the afterSwap
hook.
NOTE: The target unspecified amount and the apply flag are reset in the afterSwap
hook.
_afterSwap(address sender, struct PoolKey key, struct SwapParams params, BalanceDelta delta, bytes) → bytes4, int128
internal
#Enforce the target unspecified amount to the unspecified currency of the swap.
When the swap is exactInput
and the unspecified target is surpassed, the difference is decreased from the
output as a hook fee. Accordingly, when the swap is exactOutput
and the unspecified target is not reached, the
difference is increased to the input as a hook fee. Note that the fee is always applied to the unspecified
currency of the swap, regardless of the swap direction.
The fees are minted to this hook as ERC-6909 tokens, which can then be distributed in BaseDynamicAfterFee._afterSwapHandler
NOTE: The target unspecified amount and the apply flag are reset on purpose to avoid state overlapping across swaps.
_getTargetUnspecified(address sender, struct PoolKey key, struct SwapParams params, bytes hookData) → uint256 targetUnspecifiedAmount, bool applyTarget
internal
#Return the target unspecified amount to be enforced by the afterSwap
hook.
_afterSwapHandler(struct PoolKey key, struct SwapParams params, BalanceDelta delta, uint256 targetUnspecifiedAmount, uint256 feeAmount)
internal
#Customizable handler called after _afterSwap
to handle or distribute the fees.
getHookPermissions() → struct Hooks.Permissions permissions
public
#Set the hook permissions, specifically BaseHook.beforeSwap
, BaseHook.afterSwap
and afterSwapReturnDelta
.
import "@openzeppelin/src/fee/BaseDynamicFee.sol";
Base implementation to apply a dynamic fee via the PoolManager
's updateDynamicLPFee
function.
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
BaseHook
- _validateHookAddress(hook)
- beforeInitialize(sender, key, sqrtPriceX96)
- _beforeInitialize(, , )
- afterInitialize(sender, key, sqrtPriceX96, tick)
- beforeAddLiquidity(sender, key, params, hookData)
- _beforeAddLiquidity(, , , )
- beforeRemoveLiquidity(sender, key, params, hookData)
- _beforeRemoveLiquidity(, , , )
- afterAddLiquidity(sender, key, params, delta0, delta1, hookData)
- _afterAddLiquidity(, , , , , )
- afterRemoveLiquidity(sender, key, params, delta0, delta1, hookData)
- _afterRemoveLiquidity(, , , , , )
- beforeSwap(sender, key, params, hookData)
- _beforeSwap(, , , )
- afterSwap(sender, key, params, delta, hookData)
- _afterSwap(, , , , )
- beforeDonate(sender, key, amount0, amount1, hookData)
- _beforeDonate(, , , , )
- afterDonate(sender, key, amount0, amount1, hookData)
- _afterDonate(, , , , )
- poolManager()
IHooks
Errors
constructor(contract IPoolManager _poolManager)
internal
#Set the PoolManager
address.
_getFee(struct PoolKey key) → uint24
internal
#Returns a fee, denominated in hundredths of a bip, to be applied to the pool after it is initialized.
_afterInitialize(address, struct PoolKey key, uint160, int24) → bytes4
internal
#Set the fee after the pool is initialized.
poke(struct PoolKey key)
public
#Updates the dynamic LP fee for the given pool, which must have a key that contains this hook's address.
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:
- Manipulate the external conditions that
_getFee
depends on - Call
poke()
to update the fee to a more favorable rate - Execute trades at the manipulated fee rate
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.
getHookPermissions() → struct Hooks.Permissions permissions
public
#Set the hook permissions, specifically afterInitialize
.
NotDynamicFee()
error
#The hook was attempted to be initialized with a non-dynamic fee.
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
- constructor(_poolManager)
- _afterInitialize(, key, , )
- _getFee(sender, key, params, hookData)
- _beforeSwap(sender, key, params, hookData)
- getHookPermissions()
BaseHook
- _validateHookAddress(hook)
- beforeInitialize(sender, key, sqrtPriceX96)
- _beforeInitialize(, , )
- afterInitialize(sender, key, sqrtPriceX96, tick)
- beforeAddLiquidity(sender, key, params, hookData)
- _beforeAddLiquidity(, , , )
- beforeRemoveLiquidity(sender, key, params, hookData)
- _beforeRemoveLiquidity(, , , )
- afterAddLiquidity(sender, key, params, delta0, delta1, hookData)
- _afterAddLiquidity(, , , , , )
- afterRemoveLiquidity(sender, key, params, delta0, delta1, hookData)
- _afterRemoveLiquidity(, , , , , )
- beforeSwap(sender, key, params, hookData)
- afterSwap(sender, key, params, delta, hookData)
- _afterSwap(, , , , )
- beforeDonate(sender, key, amount0, amount1, hookData)
- _beforeDonate(, , , , )
- afterDonate(sender, key, amount0, amount1, hookData)
- _afterDonate(, , , , )
- poolManager()
IHooks
Errors
constructor(contract IPoolManager _poolManager)
internal
#Set the PoolManager
address.
_afterInitialize(address, struct PoolKey key, uint160, int24) → bytes4
internal
#Check that the pool key has a dynamic fee.
_getFee(address sender, struct PoolKey key, struct SwapParams params, bytes hookData) → uint24
internal
#Returns a fee, denominated in hundredths of a bip, to be applied to a swap.
_beforeSwap(address sender, struct PoolKey key, struct SwapParams params, bytes hookData) → bytes4, BeforeSwapDelta, uint24
internal
#Set the fee before the swap is processed using the override fee flag.
getHookPermissions() → struct Hooks.Permissions permissions
public
#Set the hook permissions, specifically afterInitialize
and beforeSwap
.
NotDynamicFee()
error
#The hook was attempted to be initialized with a non-dynamic fee.