> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bags.fm/llms.txt
> Use this file to discover all available pages before exploring further.

# Contracts Reference

> Reference for the Bags smart contracts on Robinhood Chain: roles, addresses, key functions and events, custom errors, and ABI downloads.

This page is the reference for the Bags contracts on Robinhood Chain. For step-by-step usage, see the [Launch](/robinhood/launch-token), [Trade](/robinhood/trade-tokens), [Read State](/robinhood/read-state), and [Claim Fees](/robinhood/claim-fees) guides.

## Addresses

Protocol singletons and shared infrastructure on Robinhood Chain mainnet (chain ID `4663`):

| Contract                   | Address                                      |
| -------------------------- | -------------------------------------------- |
| `BagsFactory`              | `0x46aD6f53A3C26C8027826e2104cF0595b7b24D40` |
| `BagsLens`                 | `0xcF8DA63Dd1cb58daDd2c1B350ac756ffA43EF2d4` |
| `BagsV4Hook`               | `0x208378dDc05eD5De1833624a30EB9C1d26f86EcC` |
| `BagsVault`                | `0x26e421917aeA64B615A3127A2BA3AC3051C3ab80` |
| UniversalRouter (modified) | `0x8876789976dEcBfCbBbe364623C63652db8C0904` |
| V4Quoter                   | `0x8Dc178eFB8111BB0973Dd9d722ebeFF267c98F94` |
| StateView                  | `0xF3334192D15450CdD385c8B70e03f9A6bD9E673b` |
| PoolManager                | `0x8366a39CC670B4001A1121B8F6A443A643e40951` |
| Permit2                    | `0x000000000022D473030F116dDEE9F6B43aC78BA3` |
| WETH (aeWETH proxy)        | `0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73` |
| Multicall3                 | `0xcA11bde05977b3631167028862bE2a173976CA11` |

`BagsToken`, `BagsBondingCurve`, and `BagsFeeShare` are per-token EIP-1167 clones — resolve them via the `TokenCreated` event, `factory.curveForToken` / `factory.feeShareForToken`, or `BagsLens.getTokenState`.

## ABI Downloads

The full ABIs (including custom `error` definitions used for revert decoding) are bundled with these docs and mirror the [`robinhood-abi`](https://github.com/bagsfm/bags-idl/tree/main/robinhood-abi) directory of the public [`bagsfm/bags-idl`](https://github.com/bagsfm/bags-idl) repository:

| Contract           | ABI                                                                            |
| ------------------ | ------------------------------------------------------------------------------ |
| `BagsFactory`      | [`/robinhood/abi/BagsFactory.json`](/robinhood/abi/BagsFactory.json)           |
| `BagsBondingCurve` | [`/robinhood/abi/BagsBondingCurve.json`](/robinhood/abi/BagsBondingCurve.json) |
| `BagsFeeShare`     | [`/robinhood/abi/BagsFeeShare.json`](/robinhood/abi/BagsFeeShare.json)         |
| `BagsLens`         | [`/robinhood/abi/BagsLens.json`](/robinhood/abi/BagsLens.json)                 |
| `BagsToken`        | [`/robinhood/abi/BagsToken.json`](/robinhood/abi/BagsToken.json)               |
| `BagsV4Hook`       | [`/robinhood/abi/BagsV4Hook.json`](/robinhood/abi/BagsV4Hook.json)             |
| `BagsVault`        | [`/robinhood/abi/BagsVault.json`](/robinhood/abi/BagsVault.json)               |

<Tip>
  Import the full ABIs so your EVM library can decode custom errors (e.g. `BagsBondingCurve_SlippageExceeded`) into readable messages instead of raw revert data.
</Tip>

## BagsFactory

Launch entry point and on-chain registry.

### Functions

```solidity theme={null}
// Launch (payable)
function create(string name, string symbol, string metadataURI, address partner, uint16 partnerBps, address[] claimers, uint16[] bps) payable returns (address token, address curve);
function createAndBuy(string name, string symbol, string metadataURI, address partner, uint16 partnerBps, address[] claimers, uint16[] bps) payable returns (address token, address curve);

// Registry / config (view)
function creationFee() returns (uint256);
function graduationThreshold() returns (uint256);
function curveForToken(address token) returns (address);
function feeShareForToken(address token) returns (address);
function tokenForPoolId(bytes32 poolId) returns (address);
function getTokens(uint256 offset, uint256 limit) returns (address[]);
function allTokens(uint256 index) returns (address);
function allTokensLength() returns (uint256);
```

### Events

```solidity theme={null}
event TokenCreated(address indexed token, address indexed curve, address indexed creator, address feeShare, bytes32 poolId, string name, string symbol, string metadataURI);
event CreationFeeUpdated(uint256 newFee);
event GraduationThresholdUpdated(uint256 oldThreshold, uint256 newThreshold);
```

### Key errors

`BagsFactory_InsufficientCreationFee(required, sent)`, `BagsFactory_InvalidClaimers`, `BagsFactory_NoClaimers`, `BagsFactory_InvalidPartnerBps(partnerBps)`, `BagsFactory_NoBuyValue`, `BagsFactory_BuyFailed(curve, value)`, `BagsFactory_RefundFailed(to, amount)`.

## BagsBondingCurve

Per-token pre-migration AMM (virtual `x * y = k`). Resolve its address per token.

### Functions

```solidity theme={null}
// Trade
function buy(uint256 minTokensOut) payable;
function buyFor(address recipient, uint256 minTokensOut) payable;
function sell(uint256 tokensIn, uint256 minQuoteOut);
function sellFor(address recipient, uint256 tokensIn, uint256 minQuoteOut);
function migrate(); // manual migration if the threshold is already met

// Quotes (view)
function quoteBuy(uint256 quoteIn) returns (uint256 tokensOut, uint256 feeQuote, uint256 netQuoteIn, uint256 grossUsed, uint256 refundQuote);
function quoteSell(uint256 tokensIn) returns (uint256 quoteToSeller, uint256 feeQuote, uint256 grossQuoteOut);

// State (view)
function migrated() returns (bool);
function paused() returns (bool);
function currentPrice() returns (uint256);        // ETH wei per whole token
function bondingProgress() returns (uint256);      // 0-100
function thresholdQuote() returns (uint256);
function realQuoteReserves() returns (uint256);
function realTokenReserves() returns (uint256);
function getVirtualReserves() returns (uint256 vToken, uint256 vQuote);
function creator() returns (address);
function TX_FEE_BPS() returns (uint256);           // 200 (2%)
```

### Events

```solidity theme={null}
event TokensBought(address indexed buyer, address indexed recipient, uint256 grossQuoteIn, uint256 netQuoteIn, uint256 tokensOut, uint256 feeQuote, uint256 vaultFeeQuote, uint256 creatorFeeWETH, uint256 refundQuote, uint256 price, uint256 virtualTokenReserves, uint256 virtualQuoteReserves);
event TokensSold(address indexed seller, address indexed recipient, uint256 tokensIn, uint256 grossQuoteOut, uint256 netQuoteToRecipient, uint256 feeQuote, uint256 vaultFeeQuote, uint256 creatorFeeWETH, uint256 price, uint256 virtualTokenReserves, uint256 virtualQuoteReserves);
event Migrated(address indexed creator, address indexed platformAdmin, address indexed token, uint256 lpQuote, uint256 lpTokens, bytes32 poolId, uint160 sqrtPriceX96);
event FeesSplit(address indexed payer, address indexed vault, address indexed feeShare, uint256 vaultFeeQuote, uint256 creatorFeeWETH);
```

### Key errors

`BagsBondingCurve_SlippageExceeded(minExpected, actualOut)`, `BagsBondingCurve_AlreadyMigrated`, `BagsBondingCurve_NotInitialized`, `BagsBondingCurve_ThresholdNotReached(have, need)`, `BagsBondingCurve_NoQuoteSent`, `BagsBondingCurve_ZeroInputAmount`, `EnforcedPause`.

## BagsFeeShare

Per-token creator-fee accounting (accrues in WETH). Resolve its address per token.

### Functions

```solidity theme={null}
function claim(bool unwrap);                        // unwrap = true pays native ETH
function claimable(address user) returns (uint256);
function getClaimers() returns (address[] addrs, uint16[] bps);
function claimerBps(address user) returns (uint16);
function PARTNER() returns (address);
function PARTNER_BPS() returns (uint16);
function poolId() returns (bytes32);
function hook() returns (address);
function bondingCurve() returns (address);
```

### Events

```solidity theme={null}
event Claimed(address indexed user, uint256 amount, bool unwrap);
event FeeNotified(uint256 amount, uint256 partnerShare, uint256 claimerPot);
event ClaimersUpdated(address[] claimers, uint16[] bps);
```

### Key errors

`BagsFeeShare_NothingToClaim`, `BagsFeeShare_NotAuthorized(caller)`, `BagsFeeShare_BpsSumInvalid(sum)`, `BagsFeeShare_DuplicateClaimer(claimer)`, `BagsFeeShare_TooManyClaimers(length, max)`.

## BagsLens

Stateless read aggregator. Preferred entry point for reads.

### Functions

```solidity theme={null}
function getTokenState(address token) returns (TokenState);
function getTokenStates(address[] tokens) returns (TokenState[]);
function claimableOf(address token, address user) returns (uint256);
function FACTORY() returns (address);
```

### TokenState struct

```solidity theme={null}
struct TokenState {
    bool exists;
    bool migrated;
    address curve;
    address feeShare;
    bytes32 poolId;
    uint256 thresholdQuote;
    uint256 realQuoteReserves;
    uint256 realTokenReserves;
    uint256 virtualTokenReserves;
    uint256 virtualQuoteReserves;
    uint256 priceQuotePerToken; // freezes at migration
    uint256 bondingProgressPct; // 0-99 bonding; 100 migrated
    uint256 totalRaised;
}
```

## BagsToken

Per-token ERC-20 with a fixed 1e9 supply (18 decimals). Standard ERC-20 surface (`name`, `symbol`, `decimals`, `totalSupply`, `balanceOf`, `approve`, `allowance`, `transfer`, `transferFrom`) plus:

```solidity theme={null}
function metadataURI() returns (string); // reverts on non-Bags ERC-20s
```

## BagsV4Hook

Singleton Uniswap v4 hook shared by all Bags pools. It takes the 2% fee on the WETH leg of post-migration swaps, locks liquidity, and routes creator fees to each token's fee-share.

### Functions

```solidity theme={null}
function pools(bytes32 poolId) returns (address bondingCurve, address feeShare, uint128 pendingFees, bool minted);
function sweep(bytes32 poolId);               // flush pending fees to vault + fee-share (permissionless)
function register(bytes32 poolId, address bondingCurve, address feeShare); // factory-only
function factory() returns (address);
```

### Events

```solidity theme={null}
event HookFeeTaken(bytes32 indexed poolId, uint256 amount);
event FeesSwept(bytes32 indexed poolId, uint256 bagsShare, uint256 creatorShare);
event PoolRegistered(bytes32 indexed poolId, address indexed bondingCurve, address indexed feeShare);
event PoolMinted(bytes32 indexed poolId, address indexed currency0, address indexed currency1);
```

### Key errors

`BagsV4Hook_ExactOutputWETHSpecifiedUnsupported` (exact-out WETH is rejected by design), `BagsV4Hook_LiquidityLocked`, `BagsV4Hook_PoolNotRegistered(poolId)`, `BagsV4Hook_PoolMissingWETH`.

## BagsVault

Platform treasury holding native ETH (the platform 1% of trade fees and the launch fee). Owner-controlled withdrawals; no integrator-facing calls.

```solidity theme={null}
function balance() returns (uint256 nativeBalance);
```

## Periphery ABIs

The Uniswap-style infrastructure is not part of the Bags ABI export. These are the minimal fragments used by the [Trade Tokens](/robinhood/trade-tokens) and [Read State](/robinhood/read-state) guides.

### UniversalRouter (modified fork)

Only `execute` is called directly. The v4 swap struct carries an extra `uint256 minHopPriceX36` field vs vanilla Uniswap (set it to `0`), so encode the calldata manually.

```solidity theme={null}
function execute(bytes commands, bytes[] inputs, uint256 deadline) payable;
```

The v4 swap params tuple (encoded manually for `SWAP_EXACT_IN_SINGLE`):

```solidity theme={null}
struct SwapExactInSingle {
    PoolKey poolKey;        // (currency0, currency1, fee, tickSpacing, hooks)
    bool zeroForOne;
    uint128 amountIn;
    uint128 amountOutMinimum;
    uint256 minHopPriceX36; // Robinhood-only field — always 0
    bytes hookData;         // "0x"
}
```

Command / action bytes: command `V4_SWAP = 0x10`; actions `SWAP_EXACT_IN_SINGLE = 0x06`, `SETTLE_ALL = 0x0c`, `TAKE_ALL = 0x0f`.

### Permit2

```solidity theme={null}
function approve(address token, address spender, uint160 amount, uint48 expiration);
function allowance(address owner, address token, address spender) returns (uint160 amount, uint48 expiration, uint48 nonce);
```

### V4Quoter (call via `eth_call` / simulate, not on-chain)

```solidity theme={null}
function quoteExactInputSingle((PoolKey poolKey, bool zeroForOne, uint128 exactAmount, bytes hookData) params) returns (uint256 amountOut, uint256 gasEstimate);
```

`quoteExactInputSingle` is `nonpayable`, not `view` — it must be **simulated** via `eth_call` (viem's `simulateContract`), never called as a plain read. The [Trade Tokens](/robinhood/trade-tokens) guide does this. Output already includes the 2% hook fee — apply slippage only.

### StateView

```solidity theme={null}
function getSlot0(bytes32 poolId) returns (uint160 sqrtPriceX96, int24 tick, uint24 protocolFee, uint24 lpFee);
function getLiquidity(bytes32 poolId) returns (uint128 liquidity);
```

### WETH (aeWETH proxy)

WETH9-compatible interface. Never rely on its bytecode/codehash — it's an upgradeable proxy.

```solidity theme={null}
function deposit() payable;
function withdraw(uint256 amount);
function approve(address spender, uint256 amount) returns (bool);
function balanceOf(address account) returns (uint256);
```

## Pool key parameters

Bags pools use these exact values — they must match the factory or derived pool IDs will be wrong:

| Parameter     | Value                                   |
| ------------- | --------------------------------------- |
| `fee`         | `0x800000` (dynamic fee flag)           |
| `tickSpacing` | `60`                                    |
| `hooks`       | `BagsV4Hook` address                    |
| Pair          | token / WETH, sorted by numeric address |

`poolId = keccak256(abi.encode(currency0, currency1, fee, tickSpacing, hooks))`. Prefer the on-chain `poolId` from `TokenCreated` or `BagsLens.getTokenState`.
