Angstrom on Ethereum

Uniswap v4 Hook Contract 0x0000000aa232009084bd71a5797d089aa4edfad4 on Ethereum · Other · Verified contract

Volume (24h)
$27.11M
Value locked (TVL)
$5.22M
All-time volume
$3.68B
Pools using this hook
2
Swaps (24h)
11,276 (234 traders)
Total swaps
2M

What it does

Angstrom is a batch-auction style execution hook where whitelisted nodes submit signed bundles of top-of-block and user orders that settle against Uniswap v4 pools, while LPs receive reward distributions tracked inside the hook.

How it works step by step

  • Only whitelisted nodes can submit bundles, and only once per block through execute or an empty-block attestation.
  • Signed top-of-block and user orders are settled against pool pairs using internal balances or ERC-20 transfers.
  • Pool swaps are executed from within the bundle to reach the clearing price before orders settle.
  • Swaps by outside traders are blocked unless the pool is unlocked by a node in the same block.
  • LP rewards accrue through reward growth checkpoints and are paid to positions on liquidity removal.
  • Pool bundle and unlock fees are configured by the controller and capped at 0.2% and 0.4% respectively.
Swap behaviour
beforeSwap blocks ordinary swaps unless the pool is unlocked by a node attestation or node unlock data, then applies the per-pair unlocked fee as an override. afterSwap mints protocol fee claims to a fee collector and updates reward growth accumulators after tick moves. afterSwapReturnDelta lets the hook take its fee from the swap output.
Liquidity behaviour
beforeAddLiquidity and beforeRemoveLiquidity maintain per-position reward growth checkpoints (rewardGrowthOutside, globalGrowth) so that previously accrued rewards are preserved when liquidity changes. On removal, accrued rewards in token0 are paid to the owner via UNI_V4 sync/transfer/settleFor, so the hook moves tokens from its own balance.
Fee behaviour
Swaps are routed through the hook which overrides the LP fee with the per-pair unlockedFee (OVERRIDE_FEE_FLAG). Bundle fees (bundleFee, max 0.2%) are applied to order flow inside Angstrom's settlement rather than the pool LP fee. In afterSwap a protocolUnlockedFee portion is minted as ERC-6909 claims to the FEE_COLLECTOR, which the controller can withdraw.
Owner & admin controls
Controller address (set in constructor, changeable via setController) can configure pools (configurePool, batchUpdatePools, removePool), set bundle and unlocked fees (validated against MAX_FEE 0.2e6 and MAX_UNLOCK_FEE_E6 0.4e6), toggle nodes (toggleNodes), pull accrued fees (pullFee), and collect unlock swap fees (collect_unlock_swap_fees). Node set governs who can submit bundles via execute and attest empty blocks via unlockWithEmptyAttestation.

Enabled Uniswap v4 callbacks

beforeInitialize, afterInitialize, beforeAddLiquidity, beforeRemoveLiquidity, beforeSwap, afterSwap, afterDonate, afterSwapReturnDelta

beforeInitialize and afterInitialize: pool initialization with the Angstrom hook and dynamic fee flag, plus config lookup. beforeAddLiquidity: reward checkpoint maintenance for new liquidity. beforeRemoveLiquidity: pays accrued rewards and updates checkpoints. beforeSwap: blocks swaps unless the pool is unlocked by a node attestation or valid unlock data, then sets the unlocked fee. afterSwap: mints protocol fee claims, updates reward accumulators after tick moves. afterDonate: not directly used by the source shown. afterSwapReturnDelta: enabled so the hook can adjust the swap delta by the fee amount it takes.

Security & trust assessment

Risk level: medium (verified source, high confidence).

Who controls it: The controller can change pool configs and fee parameters for any pair, withdraw protocol fee balances, rotate the controller, and add or remove nodes that are the only parties allowed to submit bundles. A compromised controller can alter fees within the hard caps or redirect fee withdrawals, though it cannot directly seize user deposits held in the internal balance mapping.

Risk to user funds: Users deposit tokens into the internal _balances mapping or settle via ERC-20 transfers, and LP reward payouts are made from the hook's balance. Funds are held by the hook contract itself, so withdrawals depend on correct accounting and on the controller not draining protocol fee balances beyond accrued amounts.

Security findings

  • [info] Swaps gated by node bundle lock: beforeSwap reverts with CannotSwapWhileLocked when no node-attested unlock data is provided, so third-party swaps on Angstrom-hooked pools are blocked outside node bundles. Liquidity providers depend on nodes for execution.
  • [medium] Controller can change fees for existing pools: The controller can set bundleFee and unlockedFee per pair within caps of 0.2% and 0.4%, and can update these at any time through batchUpdatePools, changing economics for existing LPs and traders.
  • [medium] Hook custodies funds and performs transfers: The hook holds deposited user balances and pool assets and pays reward and settlement transfers, so a bug in accounting or the signature path could affect funds. The source is verified and audit status is not in the input.
  • [low] Single controller key holds privileged powers: A single controller key controls nodes, pool configs, fee withdrawals and controller succession. The contract is not behind a proxy in the shown source, so logic cannot be upgraded, but the key is a central point of trust.
  • [low] Malformed hook data edge case: Orders with hook data shorter than 20 bytes can cause an unexpected hook address to be called when signed malformed, a edge case documented in the source and relying on node behavior.

Contract details

Verified source
Yes (Angstrom)
Compiler
solc 0.8.26+commit.8a97fa7a
Bytecode size
23,569 bytes
Upgradeable proxy
No
Detected patterns
erc6909-claims, moves-currency, return-delta, self-unlock

Pools using Angstrom