Utilities
Libraries and general purpose utilities are included in the library to help develop hooks. For technical details, refer to the API Reference.
Currency Settler
Uniswap v4 introduces a specialized Currency
type to handle both native ETH and ERC-20 tokens through a unified interface. This abstraction streamlines logic for transfers and balance checks, especially when combined with ephemeral “deltas” for each liquidity event or swap. A delta is simply the net difference that a position or user must either pay in or receive from the Uniswap PoolManager
once all operations have completed.
When tokens remain in the PoolManager
, Uniswap v4 can seamlessly represent them as ERC-6909 tokens, enabling internal accounting without external transfers. Positive deltas (credits) can be redeemed by “taking” or minting ERC-6909 tokens, and negative deltas (debts) can be settled by “paying” or burning those tokens.
The CurrencySettler
library provides easy-to-use utilities for modifying and closing these deltas. Based on the inputs, the functions determine whether to sync, transfer, or settle native assets, ERC-20 tokens, or ERC-6909 tokens. This removes the need to manually reconcile token balances or worry about the correct sequence of operations:
...
/**
* @dev 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.
*/
function _beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata params, bytes calldata)
internal
virtual
override
returns (bytes4, BeforeSwapDelta, uint24)
{
// Async swaps are only possible on exact-input swaps, so exact-output swaps are executed by the `PoolManager` as normal
if (params.amountSpecified < 0) {
// Determine which currency is specified
Currency specified = params.zeroForOne ? key.currency0 : key.currency1;
// Get the positive specified amount
uint256 specifiedAmount = uint256(-params.amountSpecified);
// Mint ERC-6909 claim token for the specified currency and amount
specified.take(poolManager, address(this), specifiedAmount, true);
// Return delta that nets out specified amount to 0.
return (this.beforeSwap.selector, toBeforeSwapDelta(specifiedAmount.toInt128(), 0), 0);
} else {
return (this.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0);
}
}
...