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);
}
}
...