Wallets & Indexers

Self-contained integration guide for wallets and indexers surfacing Arcadia positions across Base, Optimism, and Unichain. Covers Account discovery via the Factory, distinguishing Margin (V3) and Spot

Arcadia Finance is a DeFi yield-earning platform that lets users run leveraged automated-market-maker liquidity strategies on major DEXes (Uniswap, Aerodrome, Velodrome). Under the hood, the Arcadia Protocol provides user-owned, non-custodial smart-contract Accounts that come in two flavours: Margin Accounts (can borrow against deposited collateral) and Spot Accounts (pure asset holders for non-leveraged strategies). Arcadia supports both virtual and concentrated-liquidity positions and is live on Base, Optimism, and Unichain.

This page describes how to surface Arcadia positions in a wallet UI or indexer. End-users do not hold assets directly in their EOA; they hold them in Arcadia Accounts, which are proxy smart contracts owned by the EOA.

All Arcadia contracts are deployed with CREATE2, so the core and periphery addresses are identical on Base, Optimism, and Unichain. The chain-specific differences are:

  • Lending pools available (Base: USDC, WETH, cbBTC; Optimism: USDC, WETH; Unichain: USDC, WETH but margin is not yet enabled; no Account versions are currently allowlisted to borrow on Unichain).

  • Slipstream V3 Asset Module and wrapper addresses (different on Optimism, which has a separate Velodrome v3 deployment; not deployed on Unichain).

  • Underlying DEX deployments (Uniswap V3/V4 position managers, Slipstream / Velodrome position managers).

Chain Deployments

Chain
Chain ID
Block Explorer

1. The Factory

The Factory mints a non-transferable-by-itself ERC-721 (ArcadiaAccount) whose tokenId == accountIndex. Each token wraps an Account proxy.

Factory       0xDa14Fdd72345c4d2511357214c5B89A919768e59    (Base + Optimism + Unichain)

The Account NFT IS the right to control the underlying Account proxy. Transferring the NFT transfers the Account.

Key Factory ABI

Key Factory events

The simplest way to index "Accounts owned by an EOA" is to subscribe to Transfer on the Factory.

2. Two Account Types: Margin (V3) and Spot (V4)

Each Account is a proxy. Its implementation determines its type. Because of CREATE2, the same implementation addresses are used across chains:

Version
Type
Implementation address

1

Margin (legacy)

0xbea2B6d45ACaF62385877D835970a0788719cAe1

2

Spot (legacy)

0xd8AF1F1dEe6EA38f9c08b5cfa31e01ad2Bfbef28

3

Margin

0x78Db6a136EdD0F70bEd7a6eb5ca2fDF6eE16E8D6

4

Spot

0xe976BFb44f9322164ca6fdA6C5B84fBb6163D442

Per-chain availability:

Version
Base
Optimism
Unichain

1 (Margin, legacy)

available

not used (placeholder)

not used (placeholder)

2 (Spot, legacy)

available

not used (placeholder)

not used (placeholder)

3 (Margin)

available

available

available (no borrow allowlist yet)

4 (Spot)

available

available

available

Legacy caveat. V1 (margin) and V2 (spot) Accounts only exist on Base and are considered legacy. The storage layout and most of the ABI (creditor(), numeraire(), generateAssetData(), getUsedMargin(), balance mappings, Transfers events) are the same as V3/V4, so the same indexing logic works. Newly-created Accounts on Base default to V3/V4; you may still encounter V1/V2 Accounts that were never upgraded.

To determine the type of an Account at runtime, call:

  • ACCOUNT_VERSION() ∈ {1, 3}Margin Account (can have debt).

  • ACCOUNT_VERSION() ∈ {2, 4}Spot Account (no debt; pure asset holder).

Common state on every Account (from AccountStorageV1)

3. Margin Account (V3): Assets and Debt

A Margin Account is linked to exactly one Creditor (a LendingPool). Read it with:

Possible creditors (LendingPools)

LendingPool addresses are identical on all three chains (CREATE2). The debt-asset address depends on the chain.

Pool
LendingPool address
Underlying (Base)
Underlying (Optimism)
Underlying (Unichain)

USDC

0x3ec4a293Fb906DD2Cd440c20dECB250DeF141dF1

0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913

0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85

0x078D782b760474a361dDA0AF3839290b0EF57AD6

WETH

0x803ea69c7e87D1d6C86adeB40CB636cC0E6B98E2

0x4200000000000000000000000000000000000006

0x4200000000000000000000000000000000000006

0x4200000000000000000000000000000000000006

cbBTC

0xa37E9b4369dc20940009030BfbC2088F09645e3B

0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf

not deployed

not deployed

On Unichain, the USDC and WETH LendingPools exist but no Account versions are currently allowlisted to borrow against them. In practice, Unichain Accounts today are all Spot (V4).

(The numeraire of the Account equals the underlying asset of the Creditor.)

The LendingPool itself is an ERC-4626 with the debt token as the underlying. Each pool has a Tranche (an interest-bearing share) and a Wrapped Tranche (ERC-4626 wrapper of the Tranche).

Reading assets in a Margin Account

generateAssetData() returns three parallel arrays of every asset held in the Account, including ERC-721 LP NFTs and ERC-1155 positions, with no off-chain indexing required.

Reading debt and open liabilities

Note. usedMargin = openDebt + minimumMargin (the latter is a small fixed gas buffer). The bare open liability is:

Alternative: the user's "debt token" balance is also visible directly through the LendingPool's ERC-4626-like accounting:

Health metrics (for UI display)

Margin Accounts expose everything needed to render health, borrow capacity, and liquidation risk in the wallet UI. All values are denominated in the Account's numeraire (with that asset's native decimals).

Suggested derived metrics for a wallet UI:

  • Total value: getAccountValue(numeraire) (raw mark-to-market, ignoring haircuts).

  • Net equity: getAccountValue(numeraire) - getOpenPosition(account).

  • Borrow capacity remaining: getFreeMargin().

  • Health factor (collateral-side): getCollateralValue() / getUsedMargin(). Below 1.0 the Account is unhealthy (cannot borrow more, owner must repay or add collateral).

  • Health factor (liquidation-side): getLiquidationValue() / getUsedMargin(). Below 1.0 the Account is liquidatable and may be put up for Dutch auction.

If the Account has no debt (creditor() == 0x0 or getOpenPosition(account) == 0), usedMargin collapses to just minimumMargin and health checks are trivially satisfied.

4. Spot Account (V4): Assets

Spot Accounts have no creditor, no debt, and no generateAssetData(). They are pure asset holders.

Spot Account holdings must be indexed via the token contracts, not the Account itself. V4 does not store any per-asset bookkeeping: _deposit() and _withdraw() only execute the token transfer and emit Transfers. They do not update erc20Balances / erc1155Balances. Those mappings are inherited from AccountStorageV1 but are never written on V4, so they are permanently zero on Spot Accounts (any pre-existing values are cleared by upgradeHook when an Account is upgraded from V1/V2). Combined with the fact that anyone can send tokens directly to the Account proxy with a plain ERC-20 / ERC-721 / ERC-1155 transfer that bypasses the Account entirely, this means neither the Account's Transfers event nor its storage mappings are authoritative.

Index ERC-20 / ERC-721 / ERC-1155 Transfer events on the underlying token contracts, filtered by to == accountProxy (inflows) and from == accountProxy (outflows). For the current balance, call balanceOf(accountProxy) or ownerOf(tokenId) directly on the token contract.

5. Arcadia Asset Addresses (LP positions, staked, wrapped)

These are the assets that Margin and Spot Accounts will most commonly hold (on top of plain ERC-20s).

5.1 CL position managers (the assets themselves)

Protocol
Position Manager (Base)
Position Manager (Optimism)
Position Manager (Unichain)

Uniswap V3

0x03a520b32C04BF3bEEf7BEb72E919cf822Ed34f1

0xC36442b4a4522E871399CD717aBDD847Ab11FE88

0x943e6e07a7E8E791dAFC44083e54041D743C46E9

Uniswap V4

0x7C5f5A4bBd8fD63184577525326123B519429bDc

0x3C3Ea4B57a46241e54610e5f022E5c45859A1017

0x4529A01c7A0410167c5740C487A8DE60232617bf

Slipstream V1 (Aero v1 CL / Velo v1 CL)

0x827922686190790b37229fd06084350E74485b72

0x416b433906b1B72FA758e166e239c43d68dC6F29

0x991d5546C4B442B4c5fdc4c8B8b8d131DEB24702

Slipstream V2 (Aero v2 CL)

0xa990C6a764b73BF43cee5Bb40339c3322FB9D55F

(not deployed)

(not deployed)

Slipstream V3 (Aero v3 CL / Velo v3 CL)

0xe1f8cd9AC4e4A65F54f38a5CdAfCA44f6dD68b53

0xf7f8ccce99Ca2896eC75D3A399D152dB96808399

(not deployed)

These are standard Uniswap-V3-style ERC-721 position NFTs. An Arcadia Account can hold them directly (both Spot and Margin).

5.2 Staked Slipstream positions: Asset Modules (also ERC-721)

The Staked Slipstream Asset Modules are themselves the ERC-721 contracts that represent a Slipstream position that has been deposited into its gauge. The position ID is preserved: staked-position id 1000 corresponds to the underlying Slipstream position id 1000 on the relevant position manager.

Asset
Address (Base)
Address (Optimism)
Address (Unichain)

Staked Slipstream V1

0x1Dc7A0f5336F52724B650E39174cfcbbEdD67bF1

0x1Dc7A0f5336F52724B650E39174cfcbbEdD67bF1

0x1Dc7A0f5336F52724B650E39174cfcbbEdD67bF1

Staked Slipstream V2

0xBed6C3E35B9B1e044b3Bc71465769EdFDC0FDD4c

(not deployed)

(not deployed)

Staked Slipstream V3

0xE0F20BE5886F11CbcD2cb5bA9987Bcbbf1d8ca7b

0xF6a87d944204bb5Fdb9CF5534c03c46895f78eCd

(not deployed)

Staked Aerodrome (LP)

0x9f42361B7602Df1A8Ae28Bf63E6cb1883CD44C27

n/a (Aerodrome is Base-only)

n/a

Staked Stargate

0xae909e19fd13C01c28d5Ee439D403920CF7f9Eea

n/a

n/a

ABI for any Staked Slipstream Asset Module (same shape across V1/V2/V3):

5.3 Wrapped Staked Slipstream: for Spot Accounts (ERC-721 wrappers)

Margin Accounts can hold Staked Slipstream positions directly. Spot Accounts cannot (they do not price liabilities), so Arcadia exposes Wrapped Staked Slipstream wrappers; these are ERC-721s with the same position id as the underlying Slipstream NFT.

Wrapped Asset
Address (Base)
Address (Optimism)
Address (Unichain)

Wrapped Staked Slipstream V1

0xD74339e0F10fcE96894916B93E5Cc7dE89C98272

0xD74339e0F10fcE96894916B93E5Cc7dE89C98272

0xD74339e0F10fcE96894916B93E5Cc7dE89C98272

Wrapped Staked Slipstream V2

0x147a2CcbAF4521ad209A2875AE0B3c496f4B25a4

(not deployed)

(not deployed)

Wrapped Staked Slipstream V3

0x9189BC25f8faC157B4D87b0b3c14F56bA1477d53

0xC4D3d804ed64C1f78097799208D46b1db4252749

(not deployed)

Wrapped Staked Aerodrome (LP)

0x17B5826382e3a5257b829cF0546A08Bd77409270

n/a

n/a

ABI (same rewardOf semantics as the Staked AM):

Position id transparency. For every "staked" and "wrapped staked" wrapper, the tokenId equals the underlying Slipstream Position Manager tokenId. So position id 1000 on 0x9189BC25f8faC157B4D87b0b3c14F56bA1477d53 (Wrapped Staked Slipstream V1, Base) refers to the same underlying Slipstream V1 liquidity position with id 1000 on 0x827922686190790b37229fd06084350E74485b72. The user's net exposure is: the underlying LP composition + accrued LP fees + accrued gauge rewards (rewardOf(id)).

5.4 Other assets that Arcadia Accounts may hold

Asset
Address (Base)
Notes

Stargate LP (ERC-20)

factory 0xAf5191B0De278C7286d6C7CC6ab6BB8A73bA2Cd6, staking 0x06Eb48763f117c7Be887296CDcdfad2E4092739C

Base only

Aerodrome v1 pools

indexed via Aero factory 0x420DD381b31aEf6683db6B902084cB0FFECe40Da

LP tokens are plain ERC-20s

5.5 Registry and Asset Modules (for advanced lookups)

For programmatic "is this address recognized by Arcadia, and what type is it?":

6. End-to-end Indexer Pseudocode

For Slipstream / Staked Slipstream positions surfaced above:

  • Compose the LP token0/token1 underlying via the position manager's positions(id) call.

  • Add pending fees from positions(id).tokensOwed0/1 (Uniswap V3 / Slipstream).

  • Add pending gauge rewards via rewardOf(id) on the (Wrapped) Staked Slipstream contract.

Last updated