# Contracts

> Deployed addresses, ABIs, and the key functions and events of every contract.

Every contract an integrator calls on GIWA Sepolia (chain ID 91342), with the functions and events you are most likely to need. Signatures name struct parameters by their Solidity struct (`PoolKey`, `PermitSingle`, …); the full definitions are in each ABI.

{/* Source repository link: pending decision, add here once published. */}

## Core

The Vault holds every pool's tokens and enforces flash accounting; CLPoolManager holds the state of every CL pool and emits the events an indexer follows. You read from both, but trades and liquidity changes reach them through the periphery, never directly.

| Contract | Key | Address | ABI |
| --- | --- | --- | --- |
| Vault | `vault` | [`0xc296e1d77624bf021b6e2677b062d55e70b69ac7`](https://sepolia-explorer.giwa.io/address/0xc296e1d77624bf021b6e2677b062d55e70b69ac7) | [vault.json](/docs/abis/vault.json) |
| CLPoolManager | `clPoolManager` | [`0x1b24bde0c2b7fd77450a48c4f4b5db0ea4ad6bdc`](https://sepolia-explorer.giwa.io/address/0x1b24bde0c2b7fd77450a48c4f4b5db0ea4ad6bdc) | [clPoolManager.json](/docs/abis/clPoolManager.json) |

### Vault

Holds every pool's tokens and runs flash accounting: inside a lock, each balance change is recorded as a per-currency delta, and the lock only closes once every delta is back to zero.

Key functions:

- `lock(bytes data)` — Opens a lock and calls back lockAcquired(data) on the caller. The periphery contracts do this for you; call it directly only from your own contract.
- `sync(address currency)` — Checkpoints the Vault's balance of an ERC-20 before you transfer it in, so the following settle() can measure the payment.
- `settle()` — Credits the tokens paid since sync() (or msg.value for native ETH) against the caller's delta.
- `take(address currency, address to, uint256 amount)` — Sends tokens out of the Vault, adding the amount to the caller's debt for that currency.
- `currencyDelta(address settler, address currency)` — The open delta of one currency for one settler in the current lock. Non-zero at the end of a lock reverts the transaction.
- `balanceOf(address owner, address currency)` — Balance an account holds inside the Vault (minted claims), separate from its ERC-20 wallet balance.

Key events:

- `Transfer(address caller, address indexed from, address indexed to, address indexed currency, uint256 amount)` — Movements of Vault-held balances. Ordinary swaps and liquidity changes settle in ERC-20s and do not emit it.

### CLPoolManager

Owns the state of every concentrated-liquidity pool — price, ticks, liquidity, fee growth — and emits the events an indexer follows. Pools are addressed by id = keccak256(abi.encode(PoolKey)).

Key functions:

- `getSlot0(bytes32 id)` — Current sqrtPriceX96, tick, protocol fee and LP fee of a pool.
- `getLiquidity(bytes32 id)` — Liquidity active at the current tick.
- `getPoolTickInfo(bytes32 id, int24 tick)` — Gross and net liquidity and fee growth outside one initialized tick.
- `getFeeGrowthGlobals(bytes32 id)` — Cumulative fees per unit of liquidity for each currency, as Q128 values.
- `poolIdToPoolKey(bytes32 id)` — Recovers the PoolKey (currencies, hooks, fee, parameters) from a pool id.
- `getPosition(bytes32 id, address owner, int24 tickLower, int24 tickUpper, bytes32 salt)` — Raw position state. For a position NFT, owner is CLPositionManager and salt is the token id as bytes32.

Key events:

- `Initialize(bytes32 indexed id, address indexed currency0, address indexed currency1, address hooks, uint24 fee, bytes32 parameters, uint160 sqrtPriceX96, int24 tick)` — A pool was created. parameters packs the tick spacing (bits 16–39) and the hook permission bitmap (bits 0–15).
- `Swap(bytes32 indexed id, address indexed sender, int128 amount0, int128 amount1, uint160 sqrtPriceX96, uint128 liquidity, int24 tick, uint24 fee, uint16 protocolFee)` — One swap step in one pool, with the price and liquidity after it. sender is the contract that called the pool — the router — not the trader's wallet.
- `ModifyLiquidity(bytes32 indexed id, address indexed sender, int24 tickLower, int24 tickUpper, int256 liquidityDelta, bytes32 salt)` — Liquidity added (positive delta) or removed (negative). For position NFTs, sender is CLPositionManager and salt is the token id.
- `Donate(bytes32 indexed id, address indexed sender, uint256 amount0, uint256 amount1, int24 tick)` — Tokens donated to in-range liquidity providers.

## Periphery

The contracts you send transactions to. UniversalRouter executes swaps, CLPositionManager mints and changes liquidity positions, and CLQuoter and CLTickLens answer read-only questions about prices and ticks.

| Contract | Key | Address | ABI |
| --- | --- | --- | --- |
| CLPositionManager | `clPositionManager` | [`0xc818c063cabeb35296c05cc7b06d9ff38be2a9db`](https://sepolia-explorer.giwa.io/address/0xc818c063cabeb35296c05cc7b06d9ff38be2a9db) | [clPositionManager.json](/docs/abis/clPositionManager.json) |
| CLQuoter | `clQuoter` | [`0xf93cefbd66ab53de1c02fbec3b7a7b7a85743c0b`](https://sepolia-explorer.giwa.io/address/0xf93cefbd66ab53de1c02fbec3b7a7b7a85743c0b) | [clQuoter.json](/docs/abis/clQuoter.json) |
| CLTickLens | `clTickLens` | [`0x9d37696055675e6695de2205eedbf8886f31d708`](https://sepolia-explorer.giwa.io/address/0x9d37696055675e6695de2205eedbf8886f31d708) | [clTickLens.json](/docs/abis/clTickLens.json) |
| UniversalRouter | `universalRouter` | [`0xe958049fee2a61f1e96243239c4d76f91b9b19b5`](https://sepolia-explorer.giwa.io/address/0xe958049fee2a61f1e96243239c4d76f91b9b19b5) | [universalRouter.json](/docs/abis/universalRouter.json) |

### CLPositionManager

Mints liquidity positions as ERC-721 NFTs and changes them through batched actions. Pulls tokens through Permit2, with itself as the Permit2 spender.

Key functions:

- `modifyLiquidities(bytes payload, uint256 deadline)` — Runs an action plan: payload = abi.encode(bytes actions, bytes[] params). Mint 0x02, increase 0x00, decrease 0x01, burn 0x03, then settle/take or CLOSE_CURRENCY 0x12 per currency.
- `initializePool(PoolKey key, uint160 sqrtPriceX96)` — Creates a pool at a starting price. Batch it with the first mint through multicall.
- `permitBatch(address owner, PermitBatch _permitBatch, bytes signature)` — Submits a signed Permit2 allowance for both pool currencies, usually as the first call of a multicall.
- `multicall(bytes[] data)` — Runs several calls in one transaction, e.g. permitBatch + modifyLiquidities, or initializePool + mint.
- `positions(uint256 tokenId)` — PoolKey, tick range, liquidity and fee-growth checkpoints of a position.
- `getPoolAndPositionInfo(uint256 tokenId)` — PoolKey plus a packed info word (tick range, subscriber flag) — cheaper than positions().
- `ownerOf(uint256 id)` — Current owner of a position NFT.

Key events:

- `MintPosition(uint256 indexed tokenId)` — A new position NFT was minted.
- `ModifyLiquidity(uint256 indexed tokenId, int256 liquidityChange, int256 feesAccrued)` — A position's liquidity changed. feesAccrued is a packed BalanceDelta: amount0 in the upper 128 bits, amount1 in the lower.
- `Transfer(address indexed from, address indexed to, uint256 indexed id)` — ERC-721 transfer; from is the zero address on mint and to on burn.

### CLQuoter

Simulates swaps to price them. The quote functions are non-view — they run the swap and revert internally — so call them with eth_call, never in a transaction.

Key functions:

- `quoteExactInputSingle(QuoteExactSingleParams params)` — Output amount and gas estimate for an exact input in one pool. params = (PoolKey poolKey, bool zeroForOne, uint128 exactAmount, bytes hookData).
- `quoteExactInput(QuoteExactParams params)` — Output amount and gas estimate for an exact input along a multi-pool path. params = (address exactCurrency, PathKey[] path, uint128 exactAmount).
- `quoteExactOutputSingle(QuoteExactSingleParams params)` — Input amount required for an exact output in one pool.
- `quoteExactOutput(QuoteExactParams params)` — Input amount required for an exact output along a path; exactCurrency is the output currency and the path runs backwards.

### CLTickLens

Read-only helper that lists a pool's initialized ticks, for drawing liquidity depth or simulating swaps off-chain.

Key functions:

- `getPopulatedTicksInWord(bytes32 id, int16 tickBitmapIndex)` — Every initialized tick in one 256-tick bitmap word, with liquidityNet and liquidityGross.
- `getPopulatedTicksInWord(PoolKey key, int16 tickBitmapIndex)` — Same, addressed by PoolKey instead of pool id.

### UniversalRouter

Entry point for swaps. Executes a list of commands — Permit2 permit, wrap/unwrap, Infinity swap, sweep — in one transaction. This deployment supports Infinity CL pools only.

Key functions:

- `execute(bytes commands, bytes[] inputs, uint256 deadline)` — One command byte per input. Swaps use INFI_SWAP 0x10, whose input is an action plan like modifyLiquidities' (swap 0x07/0x09, then settle and take). Also PERMIT2_PERMIT 0x0a, WRAP_ETH 0x0b, UNWRAP_WETH 0x0c, SWEEP 0x04.
- `execute(bytes commands, bytes[] inputs)` — Same without a deadline. Prefer the deadline overload for user transactions.

## Shared

Standard contracts at their canonical addresses, the same as on other chains: Permit2 for token approvals, WETH9 at the OP Stack predeploy address, and Multicall3 for batching reads.

| Contract | Key | Address | ABI |
| --- | --- | --- | --- |
| Permit2 | `permit2` | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://sepolia-explorer.giwa.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | [permit2.json](/docs/abis/permit2.json) |
| WETH9 | `weth9` | [`0x4200000000000000000000000000000000000006`](https://sepolia-explorer.giwa.io/address/0x4200000000000000000000000000000000000006) | [weth9.json](/docs/abis/weth9.json) |
| Multicall3 | `multicall3` | [`0xcA11bde05977b3631167028862bE2a173976CA11`](https://sepolia-explorer.giwa.io/address/0xcA11bde05977b3631167028862bE2a173976CA11) | [multicall3.json](/docs/abis/multicall3.json) |

### Permit2

Token approval manager at its canonical address. Approve an ERC-20 to Permit2 once; Permit2 then grants time-limited allowances to UniversalRouter and CLPositionManager.

Key functions:

- `approve(address token, address spender, uint160 amount, uint48 expiration)` — On-chain allowance from the caller to a spender (e.g. UniversalRouter) until expiration.
- `allowance(address, address, address)` — (owner, token, spender) → amount, expiration and the next nonce for a signed permit.
- `permit(address owner, PermitSingle permitSingle, bytes signature)` — Sets an allowance from an EIP-712 signature instead of a transaction. Usually relayed by the spender (router command 0x0a).

Key events:

- `Approval(address indexed owner, address indexed token, address indexed spender, uint160 amount, uint48 expiration)` — An allowance was set with approve().
- `Permit(address indexed owner, address indexed token, address indexed spender, uint160 amount, uint48 expiration, uint48 nonce)` — An allowance was set from a signature.

### WETH9

Wrapped ETH at the OP Stack predeploy address. Pools may hold native ETH (address zero) or WETH; the router wraps and unwraps as needed.

Key functions:

- `deposit()` — Wraps the ETH sent as msg.value into WETH.
- `withdraw(uint256 wad)` — Unwraps WETH back to ETH.

Key events:

- `Deposit(address indexed dst, uint256 wad)` — ETH wrapped.
- `Withdrawal(address indexed src, uint256 wad)` — WETH unwrapped.

### Multicall3

Batches read calls into one RPC request at its canonical address. The app reads pool state and runs quotes through it.

Key functions:

- `aggregate3((address,bool,bytes)[] calls)` — Runs each (target, allowFailure, callData) and returns (success, returnData) per call.
- `getEthBalance(address addr)` — Native ETH balance, batchable with token reads.

## ABIs

The copy button in each table's ABI column copies the contract's full ABI as JSON. The same ABI is served as a static file at `/docs/abis/<key>.json`, where `<key>` is one of `vault`, `clPoolManager`, `clPositionManager`, `clQuoter`, `clTickLens`, `universalRouter`, `permit2`, `weth9` and `multicall3` — for example [`/docs/abis/clQuoter.json`](/docs/abis/clQuoter.json).

Addresses and ABIs are generated from the deployment manifest for chain 91342, so this page always matches the contracts the app itself uses. WETH9 and Multicall3 are predeploys outside that build: the WETH9 file is the standard ERC-20 ABI plus `deposit`, `withdraw` and their events, and the Multicall3 file covers the members viem uses (`aggregate3`, `getEthBalance`, `getCurrentBlockTimestamp`).

This is a testnet deployment. Contracts may be redeployed to new addresses, and pools and positions do not carry over when that happens. Keep addresses in configuration rather than scattered through code, recheck them here after a redeploy, and check the chain ID before sending transactions.
