# Analytics
Source: https://docs.cashmere.exchange/api-reference/analytics
Read-only kapi endpoints for transfers, volumes, fees, points and leaderboards.
## Overview
The Monitoring API (`https://kapi.cashmere.exchange`) serves public data for dashboards, points trackers and transfer monitoring. Every payload uses snake\_case keys.
***
## Transactions
```
GET https://kapi.cashmere.exchange/transactionsmainnet?senders=0xYourAddress&limit=20
```
Every mainnet transfer made through Cashmere, newest first. `/transactions` takes the same parameters for testnet, which has no data newer than October 2025.
| Query | Type | Description |
| - | - | - |
| `senders` | string | Comma-separated sender addresses, in any letter case |
| `addr_or_tx_hash` | string | An ENS (`.eth`) or SNS (`.sol`) name, an address or a transaction hash. Lookups by address or hash can take over a minute: filter by `senders` instead |
| `source_domain` | number | Source CCTP domain |
| `destination_domain` | number | Destination CCTP domain |
| `start_time` | number | Unix seconds, lower bound on `created_at` |
| `end_time` | number | Unix seconds, upper bound on `created_at` |
| `limit` | number | Page size, default 10 |
| `cursor` | string | `next_cursor` from the previous page |
```json theme={null}
{
"transactions": [
{
"id": 882672,
"source_tx_hash": "0xSourceTxHash…",
"block": 158712232,
"source_domain": 2,
"destination_domain": 3,
"sender": "0xSenderAddress…",
"recipient": "0xrecipientaddress…",
"solana_owner": "0x0000000000000000000000000000000000000000",
"deposit_amount": 10000000,
"receive_amount": 9998700,
"max_fee": 1300,
"relayer_fee": 190000,
"is_gas_drop_in_native": false,
"gas_drop_amount": 0,
"gas_drop_status": "pending",
"gas_drop_tx_hash": null,
"message_hash": "0x0000…",
"attestation_hash": "0x…",
"nonce": "0x…",
"domain_nonce": 82732,
"version": 2,
"confirmed": true,
"destination_tx_hash": "0xDestinationTxHash…",
"destination_tx_status": "success",
"source_tx_error": null,
"attestation_error": null,
"destination_tx_error": null,
"has_source_tx_error": false,
"has_attestation_error": false,
"has_destination_tx_error": false,
"created_at": "2026-10-26T14:04:43.31283Z",
"updated_at": "2026-10-26T14:06:43.422173Z"
}
],
"next_cursor": "1793021083_882672",
"has_more": true
}
```
### Fields
| Field | Type | Description |
| - | - | - |
| `source_tx_hash`, `block` | string, number | The source transaction and its block |
| `source_domain`, `destination_domain` | number | CCTP domains |
| `sender` | string | The source wallet |
| `recipient` | string | The CCTP recipient. Into Solana, the USDC token account |
| `solana_owner` | string | Into Solana, the wallet that owns `recipient`; zero otherwise |
| `deposit_amount` | number | USDC burned on the source chain, in base units |
| `receive_amount` | number | USDC minted to the recipient, after Circle's fee |
| `max_fee` | number | Circle's fee cap, in USDC base units |
| `relayer_fee` | number | Cashmere's fee: USDC base units, or the source chain's smallest native unit when `is_gas_drop_in_native` is `true` |
| `is_gas_drop_in_native` | boolean | The transfer's `isNative` flag |
| `gas_drop_amount`, `gas_drop_status`, `gas_drop_tx_hash` | | Gas drop is not offered: always `0`, `pending` and `null` |
| `message_hash` | string | The CCTP message bytes, despite the name |
| `attestation_hash` | string | Circle's attestation |
| `nonce`, `domain_nonce` | string, number | The CCTP nonce, and Cashmere's per-domain counter |
| `version` | number | CCTP version, `1` or `2` |
| `confirmed` | boolean | The source transaction is confirmed |
| `destination_tx_hash` | string | The mint transaction. It can be all zeros even on success |
| `destination_tx_status` | string | `success` once the USDC is minted, `failed` if the mint transaction failed |
| `source_tx_error`, `attestation_error`, `destination_tx_error` | string or null | Error text for each stage |
| `has_source_tx_error`, `has_attestation_error`, `has_destination_tx_error` | boolean | Whether each error is set |
| `created_at`, `updated_at` | string | ISO 8601 timestamps |
> [!NOTE]
>
> A `relayer_fee` in wei can exceed `Number.MAX_SAFE_INTEGER`, which `JSON.parse` rounds. Treat it as approximate, or parse the body with a big-integer JSON parser.
***
## Leaderboard
```
GET https://kapi.cashmere.exchange/users/leaderboard?network=mainnet&limit=50&offset=0
```
| Query | Default | Notes |
| - | - | - |
| `network` | `devnet` | Pass `mainnet` for the production leaderboard |
| `limit` | `50` | Up to `100`; larger values fall back to `50` |
| `offset` | `0` | Pagination offset |
| `search` | *empty* | Case-insensitive username filter, up to 100 characters |
```json theme={null}
{
"leaderboard": [
{
"user_id": 42,
"username": "cashmerefan",
"ref_code": "CASHFAN",
"total_base_points": 5320.5,
"domain_multiplier": 2.5,
"domain_total_multiplied_points": 13301.25,
"referral_points": 1200,
"total_points_with_referrals": 14501.25,
"staked_op_nfts": 3,
"staked_eth_nfts": 1,
"wallet_count": 4,
"domain_rank": 128
}
],
"network": "mainnet",
"search": "",
"total_count": 4827,
"limit": 50,
"offset": 0,
"has_more": true
}
```
Entries without a rank return `null` and come after ranked users.
***
## Users
Two lookups:
1. `GET /users?domains=builder.csm`: one profile, with each bound wallet.
2. `GET /users?wallets=0xabc…_evm,So111…_solana`: points per wallet, each written as `
_` (`evm`, `solana`, `sui` or `aptos`).
An unknown profile returns `404 {"error":"user not found"}`.
### Profile query
```json theme={null}
{
"username": "builder.csm",
"ref_code": "BUILD",
"has_twitter": true,
"has_discord": false,
"binded_wallets": {
"evm": "0xabc…",
"sol": "So111…",
"apt": "",
"sui": ""
},
"domain_rank": 128,
"domain_total_multiplied_points": 13301.25,
"domain_total_multiplied_points_mainnet": 4600,
"total_points_all_chains": 13301.25,
"total_points_all_chains_mainnet": 4600,
"referral_points_earned": 1200,
"total_points_with_referrals": 14501.25,
"evm": {
"address": "0xabc…",
"chain_type": "evm",
"swap_points": 1200,
"swap_points_mainnet": 400,
"testnet_points": 800,
"nft_points": 120,
"points_multiplier": 2.5,
"total_points_multiplied": 3500,
"total_points_multiplied_mainnet": 2600,
"staked_eth_nfts": 1,
"staked_op_nfts": 3
}
}
```
`sol`, `apt` and `sui` have the same fields as `evm`.
### Wallet query
```json theme={null}
{
"users": [
{
"user_id": 42,
"username": "cashmerefan",
"ref_code": "CASHFAN",
"has_twitter": true,
"has_discord": false,
"wallets": [
{
"address": "0xabc…",
"chain_type": "evm",
"testnet_points": 800,
"nft_points": 120,
"swap_points": 1200,
"swap_points_mainnet": 400,
"staked_op_nfts": 3,
"staked_eth_nfts": 1,
"points_multiplier": 2.5,
"total_points_multiplied": 3500,
"total_points_multiplied_mainnet": 2600
}
],
"total_testnet_points": 800,
"total_nft_points": 120,
"total_swap_points": 1200,
"total_swap_points_mainnet": 400,
"total_staked_op_nfts": 3,
"total_staked_eth_nfts": 1,
"max_multiplier": 2.5,
"total_points_multiplied": 3500,
"total_points_multiplied_mainnet": 2600,
"referral_points_earned": 1200,
"total_points_with_referrals": 4700
}
]
}
```
***
## Wallet Binding
The Cashmere app binds wallets to a profile with a signed message.
### `GET /users/messages`
```
GET https://kapi.cashmere.exchange/users/messages?username=builder.csm&address=0xabc…&chain_type=evm
```
| Query | Notes |
| - | - |
| `username` | Profile name, including `.csm` |
| `address` | The wallet being bound or unbound |
| `chain_type` | `evm`, `solana`, `sui` or `aptos` |
```json theme={null}
{ "nonce": "483920" }
```
The nonce works once: request a new one for every signature.
### `POST /users/verify`
Have the wallet sign this exact text, where each `\n` is a newline:
```
Please sign this message to bind your wallet to Cashmere:\nProfile: builder.csm\nnonce: 483920
```
To unbind, sign `Please sign this message to unbind your wallet from Cashmere:\nProfile: \nnonce: ` instead. Then send:
```
POST https://kapi.cashmere.exchange/users/verify
Content-Type: application/json
```
```json theme={null}
{
"username": "builder.csm",
"address": "0xabc…",
"chain_type": "evm",
"type": "bind",
"signature": "0x…",
"public_key": "",
"message": "Please sign this message to bind your wallet to Cashmere:\nProfile: builder.csm\nnonce: 483920"
}
```
| Chain | `signature` | `public_key` |
| - | - | - |
| EVM | The `personal_sign` signature, hex | Empty |
| Solana | The Ed25519 signature, base64 | Empty |
| Sui | The `signPersonalMessage` signature, as the wallet returns it | Empty |
| Aptos | The Ed25519 signature from the wallet's `signMessage` (with the nonce), base64 | The account's public key, base64 |
A successful call returns:
```json theme={null}
{
"success": true,
"username": "builder.csm"
}
```
***
## Volumes
| Endpoint | Returns |
| - | - |
| `GET /stats/mainnet/volumes` | `{ "network": "mainnet", "total_volume": 315000000000000 }`: lifetime volume in USDC base units |
| `GET /stats/mainnet/volumes?senders=0xabc…,So111…` | `{ "network": "mainnet", "user_volume": … }` for those wallets |
| `GET /stats/mainnet/volumes/hourly?limit=24` | Hourly buckets, the last 24 by default |
| `GET /stats/mainnet/volumes/daily?limit=30` | Daily buckets, the last 30 by default |
```json theme={null}
{
"network": "mainnet",
"period": "hourly",
"limit": 24,
"offset": 0,
"volumes": [
{
"id": 51234,
"date": "2026-10-26T00:00:00Z",
"hour": 16,
"total_volume_usd": 12500.42,
"transaction_count": 38,
"unique_senders_count": 21,
"calculated_at": "2026-10-26T17:00:04Z"
}
]
}
```
Daily rows have `date`, `total_volume_usd`, `transaction_count`, `avg_unique_senders`, `period_type` and `last_updated`.
***
## Fees
```
GET https://kapi.cashmere.exchange/stats/mainnet/fees?period=daily&limit=7
```
* `period`: `hourly` (default), `daily`, `weekly` or `monthly`.
* `limit`: the number of buckets, 24 by default and up to 1000.
```json theme={null}
{
"network": "mainnet",
"period_type": "daily",
"limit": 7,
"offset": 0,
"cached": false,
"relayer_fees_usd": 33.54,
"total_fees_usd": 360.62,
"fees": [
{
"date": "2026-10-26T00:00:00Z",
"period_type": "daily",
"total_fee_usd": 6.72,
"native_fee_usd": 3.68,
"stable_fee_usd": 3.04,
"transaction_count": 38,
"native_tx_count": 22,
"stable_tx_count": 16,
"last_updated": "2026-10-26T17:00:05Z"
}
]
}
```
`relayer_fees_usd` sums the buckets, and `total_fees_usd` adds NFT royalty revenue (detailed in `nft_revenue`). The last entry of `fees` is that NFT summary and has no `date`: skip it when charting.
***
## Transaction Count
```
GET https://kapi.cashmere.exchange/stats/mainnet/transactions
```
```json theme={null}
{
"network": "mainnet",
"total_transactions": 48271
}
```
***
## Chain Shares
```
GET https://kapi.cashmere.exchange/stats/mainnet/chain-shares
```
```json theme={null}
{
"network": "mainnet",
"chain_shares": [
{
"domain": 0,
"amount": 2750000,
"total_amount": 5500000
}
]
}
```
Amounts are in USDC base units: divide `amount` by `total_amount` for each domain's share. The list also contains IDs that aren't CCTP domains, such as `30101`, so keep only the domains you chart.
***
## Unique Wallets
`GET /stats/mainnet/wallets` (mainnet) and `GET /stats/wallets` (testnet) return distinct sender counts:
```json theme={null}
{
"unique_senders_count": 18342
}
```
***
## Caching & Rate Limits
* Stats endpoints are cached for 60 seconds, and transaction, leaderboard and user lookups for 5.
* No rate limits are published and no rate-limit headers are sent. Poll no faster than the cache interval.
> [!NOTE]
>
> Apart from `POST /users/verify` for wallet binding, these endpoints only read data. Transfers happen on-chain, from the sender's wallet.
# API Reference
Source: https://docs.cashmere.exchange/api-reference/introduction
The Gas API and the kapi monitoring API: hosts, units, errors and limits.
## Welcome
Cashmere has two public REST APIs. Use them with the on-chain contracts described in the [developer guides](/developers/quickstart), or let the [Cashmere Agent SDK](/developers/sdks) call them for you.
## Base URLs
| Service | Host | Purpose |
| - | - | - |
| **Gas API** | `https://gas.cashmere.exchange` | Signed fee quotes for the Cashmere contracts, live fees and token prices |
| **Monitoring API** | `https://kapi.cashmere.exchange` | Read-only data: transfers, volumes, fees, points and leaderboards |
Each path exists on one host only: the other host answers 404.
## Authentication
Neither API needs an API key. Keep request volumes reasonable, and write to [contact@cashmere.exchange](mailto:contact@cashmere.exchange) for high-throughput access.
> [card] [Backend APIs guide](/developers/backend-apis)
>
> What an integration needs to get right: quotes, units and transfer tracking
## Core Endpoints
> [card] [Gas Quotes](/api-reference/quote)
>
> Signed fees for every source chain
> [card] [Transfer Execution](/api-reference/transfer)
>
> Send a transfer on-chain with a quote
> [card] [Analytics](/api-reference/analytics)
>
> Transfers, volumes, fees and points
## Units
| Value | Unit |
| - | - |
| `amount`, `maxFee`, `deposit_amount`, `receive_amount`, `max_fee`, `total_volume` | USDC base units (6 decimals) |
| Quote `fee` with `isNative=false` | USDC base units |
| Quote `fee` with `isNative=true` | The source chain's smallest native unit: wei on EVM chains (18 decimals), lamports on Solana (9), octas on Aptos (8), MIST on Sui (9) |
| `relayer_fee` | Like the quote `fee`: native units when `is_gas_drop_in_native` is `true` |
| WebSocket `usd` | USDC base units |
| `/tokenPrices`, `*_usd` stats | US dollars |
| `deadline`, `start_time`, `end_time` | Unix seconds |
Quotes return amounts as strings: parse them with `BigInt`. kapi returns amounts as JSON numbers, and native fees in wei can exceed `Number.MAX_SAFE_INTEGER`, which `JSON.parse` rounds.
## Rate Limits
No limits are published and no rate-limit headers are sent. kapi caches stats for 60 seconds and transaction and user lookups for 5, so polling faster returns the same data. For live fees, use the [WebSocket](/api-reference/quote#websocket-updates) instead of polling the Gas API.
## Error Handling
Successful responses are bare JSON objects, with no wrapper. Errors carry an `error` string:
| API | Status | Body | When |
| - | - | - | - |
| Gas API | 500 | `{"error":"Internal Server Error"}` | Any bad input (a missing `isNative`, an unknown domain, `TRUE` instead of `true`), or a route it can't price right now |
| kapi | 400 | `{"error":"invalid query params"}`, `{"error":"invalid ens"}`, `{"error":"invalid limit. must be a positive integer <= 1000"}` | A malformed filter, an unknown ENS or SNS name, a bad `limit` |
| kapi | 404 | `{"error":"user not found"}` | An unknown profile on `/users` |
The Gas API never answers 400: check your parameters first, then retry a 500 with backoff.
# Gas Quotes
Source: https://docs.cashmere.exchange/api-reference/quote
Get the signed fee quote that every Cashmere transfer needs, plus live fees and token prices.
## Overview
Every Cashmere transfer needs a fee quote signed by the Gas API: the contracts check the signature before they burn any USDC. A quote covers one route, fee mode and CCTP version, and expires about 100 seconds after it is issued.
| Source chain | Endpoint |
| - | - |
| EVM chains | `GET /getEcdsaSig_native` |
| Solana, Aptos, Sui | `GET /getEd25519Sig_native` |
***
## `GET /getEcdsaSig_native`
An ECDSA quote for the EVM contracts: `transferV2` and `transferV2WithPermit`, or the V1 `transfer` and `transferWithPermit`.
```
GET https://gas.cashmere.exchange/getEcdsaSig_native
```
### Query Parameters
| Name | Type | Required | Description |
| - | - | - | - |
| `localDomain` | number | Yes | Source CCTP domain (Ethereum `0`, Arbitrum `3`, Base `6`…) |
| `destinationDomain` | number | Yes | Destination CCTP domain |
| `isV2` | boolean | Yes | `true` for all new integrations (`transferV2*`). `false` signs the V1 `transfer*`, which Circle stops accepting on 1 December 2026 |
| `isNative` | boolean | Yes | `true` to pay the fee in the source chain's gas token, `false` to take it from the USDC. Without it the API answers 500 |
### Example
```bash theme={null}
curl "https://gas.cashmere.exchange/getEcdsaSig_native?localDomain=0&destinationDomain=3&isV2=true&isNative=false"
```
```json theme={null}
{
"fee": "190000",
"deadline": "1793034101",
"signature": "0x8b6a…1b",
"isNative": false,
"cctpVersion": 2
}
```
### Response Fields
| Field | Description |
| - | - |
| `fee` | Cashmere's fee, as a string: USDC base units with `isNative=false`, wei with `isNative=true`. It covers the destination mint, so it depends mostly on the destination chain |
| `deadline` | Unix seconds, about 100 seconds after the quote. The contract reverts after it |
| `signature` | 65-byte ECDSA signature over `keccak256(abi.encodePacked(uint32 localDomain, uint32 destinationDomain, uint128 fee, uint64 deadline, bool isNative, uint8 cctpVersion))`, with no `\x19Ethereum Signed Message` prefix |
| `isNative` | The fee mode the quote was signed for |
| `cctpVersion` | `2` for `transferV2*`, `1` for `transfer*` |
> [!NOTE]
>
> Gas drop is not offered: pass `gasDropAmount: 0`. With `isNative=true`, send at least `fee` as the transaction's `value` (the contract refunds any excess); otherwise the contract takes the fee out of `amount`.
***
## `GET /getEd25519Sig_native`
An Ed25519 quote for the Solana program and the Aptos and Sui modules.
```
GET https://gas.cashmere.exchange/getEd25519Sig_native
```
### Query Parameters
| Name | Type | Required | Description |
| - | - | - | - |
| `localDomain` | number | Yes | `5` Solana, `8` Sui, `9` Aptos |
| `destinationDomain` | number | Yes | Destination CCTP domain |
| `isNative` | boolean | Yes | `true` to pay in SOL, SUI or APT, `false` to take the fee from the USDC |
| `version` | number | For V2 | `2` for the V2 entry points (`transfer_v2`, `transfer_v2_outer`, `prepare_deposit_for_burn_v2`), `1` for Solana V1. Leave it out only for the V1 Aptos and Sui calls |
### Example
```bash theme={null}
curl "https://gas.cashmere.exchange/getEd25519Sig_native?localDomain=5&destinationDomain=0&isNative=false&version=2"
```
```json theme={null}
{
"signature": "0x6c80…d4",
"message": "0x020500000000000000ab981600000000007587df6a0000000000",
"publicKey": "0x93ab…af",
"destinationDomain": "0",
"fee": "1480875",
"deadline": "1793034101",
"isNative": false,
"version": 2
}
```
### Response Fields
| Field | Description |
| - | - |
| `signature` | 64-byte Ed25519 signature, hex |
| `message` | The signed bytes, hex (see Message Layout) |
| `publicKey` | The Gas API's Ed25519 key, which the contracts store |
| `destinationDomain` | The requested destination, as a string |
| `fee` | Cashmere's fee, as a string: USDC base units with `isNative=false`; lamports (Solana), octas (Aptos) or MIST (Sui) with `isNative=true` |
| `deadline` | Unix seconds, about 100 seconds after the quote |
| `isNative` | The fee mode the quote was signed for |
| `version` | The requested version; absent if you left it out |
### Message Layout
Little-endian, 26 bytes (25 without `version`):
1. `version` (`u8`), only if you passed `version`
2. `localDomain` (`u32`)
3. `destinationDomain` (`u32`)
4. `fee` (`u64`)
5. `deadline` (`u64`)
6. `isNative` (`bool`)
The Solana program reads these bytes from the `Ed25519Program` instruction placed before the transfer. The Aptos and Sui modules rebuild them as the BCS encoding of `TransferParamsV2` and verify the signature you pass. See [Signed Payloads](/developers/smart-contracts#signed-payloads).
***
## Token Pricing
```
GET https://gas.cashmere.exchange/tokenPrices
```
The USD price of each chain's gas token, as decimal strings keyed by chain name:
```json theme={null}
{
"ethereum": "2315.28",
"solana": "100.99",
"aptos": "0.692416",
"sui": "0.91108"
}
```
***
## WebSocket Updates
```
wss://gas.cashmere.exchange/subscribe
```
The socket sends the current fees and token prices as soon as you connect:
* `{ "type": "fees", "data": { : { fee: { : { native, usd } }, gas: { native, usd } } } }`
* `{ "type": "tokenPrices", "data": { : "" } }`
Keys are chain names, not domain IDs. `native` is in the source chain's smallest native unit, and `usd` in USDC base units (`"190000"` is 0.19 USDC).
```ts theme={null}
const socket = new WebSocket('wss://gas.cashmere.exchange/subscribe');
socket.onmessage = (event) => {
const { type, data } = JSON.parse(event.data);
if (type === 'fees') {
console.log('Base → Arbitrum fee:', Number(data.base.fee.arbitrum.usd) / 1e6, 'USDC');
}
};
```
Use the socket for display only: a transfer still needs a signed quote from the REST endpoints.
***
## Failure Modes
| HTTP Status | Body | Meaning |
| - | - | - |
| `500` | `{"error":"Internal Server Error"}` | Bad input (a missing `isNative`, an unknown domain, `TRUE` instead of `true`), or the route can't be priced right now |
The Gas API doesn't answer 400. Check the parameters first, then retry with backoff, and never sign with an expired quote.
# Transfer Execution
Source: https://docs.cashmere.exchange/api-reference/transfer
Send a transfer on-chain with a Gas API quote, then track it to the destination.
## Overview
Cashmere has no `/transfer` REST endpoint. Transfers happen **on-chain**, from the sender's own wallet, with a fee quote from the Gas API. The [Cashmere Agent SDK](/developers/sdks) does every step below in one call.
1. Get a quote from `/getEcdsaSig_native` (EVM) or `/getEd25519Sig_native` (Solana, Aptos, Sui).
2. Fill the contract parameters with it.
3. Call the Cashmere contract on the source chain.
4. Track the transfer with `/transactionsmainnet` until the destination mint succeeds.
***
## Step-by-Step (EVM)
Take the addresses from [Contract Addresses](/developers/contract-addresses) and the ABI from [Smart Contracts](/developers/smart-contracts#interface).
> [tab] 1. Quote
>
> ```ts theme={null}
> const localDomain = 0; // Ethereum
> const destinationDomain = 3; // Arbitrum
> const isNative = false; // take the fee from the USDC; true pays it in ETH
>
> const res = await fetch(
> 'https://gas.cashmere.exchange/getEcdsaSig_native?' +
> new URLSearchParams({
> localDomain: String(localDomain),
> destinationDomain: String(destinationDomain),
> isV2: 'true',
> isNative: String(isNative),
> })
> );
> if (!res.ok) throw new Error(`Gas API error ${res.status}`);
> const quote = await res.json(); // { fee, deadline, signature, isNative, cctpVersion }
> ```
> [tab] 2. Prepare Params
>
> ```ts theme={null}
> import { parseUnits, zeroPadValue, ZeroHash } from 'ethers';
>
> const amount = parseUnits('100', 6); // USDC has 6 decimals
>
> // Circle's fee for V2 Fast (threshold 1000), in basis points, possibly fractional such as 1.3
> const circleFees = await fetch(
> `https://iris-api.circle.com/v2/burn/USDC/fees/${localDomain}/${destinationDomain}`
> ).then(r => r.json());
> const { minimumFee } = circleFees.find((f: { finalityThreshold: number }) => f.finalityThreshold === 1000);
> const maxFee = (amount * BigInt(Math.ceil(minimumFee * 10)) + 99_999n) / 100_000n; // rounded up
>
> const params = {
> amount,
> maxFee,
> fee: BigInt(quote.fee),
> deadline: BigInt(quote.deadline),
> gasDropAmount: 0n, // gas drop is not offered
> destinationDomain,
> minFinalityThreshold: 1000, // V2 Fast; 2000 from sources without Fast
> recipient: zeroPadValue(destinationAddress, 32),
> solanaOwner: ZeroHash, // only used when sending to Solana
> isNative,
> hookData: '0x00', // Circle rejects empty hook data
> signature: quote.signature,
> };
> ```
> [tab] 3. Send Tx
>
> ```ts theme={null}
> import { Contract } from 'ethers';
>
> const usdc = new Contract(USDC_ADDRESS, ['function approve(address,uint256) returns (bool)'], signer);
> const cashmere = new Contract(CASHMERE_CCTP_ADDRESS, CASHMERE_ABI, signer);
>
> // The contract pulls exactly `amount`, and takes the fee out of it when isNative is false
> await (await usdc.approve(CASHMERE_CCTP_ADDRESS, params.amount)).wait();
>
> const tx = await cashmere.transferV2(params, { value: params.isNative ? params.fee : 0n });
> const receipt = await tx.wait();
> if (receipt?.status !== 1) throw new Error('transfer reverted');
> ```
> [!WARNING]
>
> Quotes expire about 100 seconds after they are issued. Request one right before the user signs, and send the transaction straight away.
> [!NOTE]
>
> Bridging into Solana? `recipient` must be the destination wallet's USDC associated token account, and `solanaOwner` the wallet itself, both as 32 bytes. See [Recipient Encoding](/developers/smart-contracts#recipient-encoding).
***
## Step-by-Step (Solana)
1. Request a quote with `localDomain=5` and `version=2`.
2. Encode the recipient as 32 bytes (see [Recipient Encoding](/developers/smart-contracts#recipient-encoding)).
3. Build an `Ed25519Program.createInstructionWithPublicKey` instruction from the quote's `publicKey`, `message` and `signature`, and place it right before `transfer_v2`.
4. Call `transfer_v2` with the quote's `fee` and `deadline` unchanged, `max_fee` from Circle Iris and `min_finality_threshold = 2000`.
The full transaction, with every account, is in [Smart Contracts → Solana](/developers/smart-contracts#solana-implementation). Aptos (`transfer_v2_outer`) and Sui (`prepare_deposit_for_burn_v2`) take the same quote fields: see [Aptos](/developers/smart-contracts#aptos-implementation) and [Sui](/developers/smart-contracts#sui-implementation).
***
## Permit Variants
* On EVM, `transferV2WithPermit` takes an EIP-2612 `PermitParams` struct in place of a separate `approve`. Sign the permit locally, then call the contract with the same quote.
* Solana, Aptos and Sui have no approval step: the sender signs the transaction that moves the USDC.
***
## Monitoring Settlement
| Endpoint | Description |
| - | - |
| `GET https://kapi.cashmere.exchange/transactionsmainnet` | Mainnet transfers, with cursor pagination and time filters |
| `GET https://kapi.cashmere.exchange/transactions` | Testnet transfers (no data since October 2025) |
| `wss://gas.cashmere.exchange/subscribe` | Live fees and token prices, no transfer status |
```ts theme={null}
// Poll until the USDC is minted on the destination chain
async function waitForMint(sender: string, sourceTxHash: string, timeoutMs = 45 * 60_000) {
const url = `https://kapi.cashmere.exchange/transactionsmainnet?senders=${sender}&limit=10`;
const giveUp = Date.now() + timeoutMs;
while (Date.now() < giveUp) {
const { transactions } = await fetch(url).then(r => r.json());
const tx = transactions.find((t) => t.source_tx_hash === sourceTxHash);
if (tx?.destination_tx_status === 'success') return tx;
if (tx?.destination_tx_status === 'failed') throw new Error(tx.destination_tx_error ?? 'mint failed');
await new Promise((r) => setTimeout(r, 10_000));
}
throw new Error('transfer not settled yet: check it again later');
}
```
Settlement time depends on the source chain: V2 Fast from Ethereum and its L2s takes about 15 seconds, and V2 Norm from fast-finality chains such as Solana, Aptos, Sui, Avalanche or Polygon takes under a minute. V2 Norm from Ethereum or an L2 waits about 15 minutes for finality. Each row also carries `receive_amount`, `relayer_fee` and `destination_tx_hash` for dashboards and reconciliation: see [Analytics](/api-reference/analytics#transactions).
***
## Common Pitfalls
* **Signature mismatch**: `isV2`, `isNative` and both domains must match the call you make.
* **Empty hook data**: pass `hookData: '0x00'`. Circle reverts V2 burns whose hook data is `0x`.
* **Allowance errors**: approve `amount` USDC before `transferV2`, or use the permit variant.
* **Native fee shortfall**: with `isNative=true`, send at least `fee` wei as `msg.value`.
* **Expired deadline**: request a fresh quote if the transaction isn't sent within about 100 seconds.
* **Wrong recipient format**: CCTP accepts any 32 bytes, so a mistake can't be fixed after the burn. An EVM address sent to Aptos or Sui mints to an account nobody controls, and into Solana the recipient must be the USDC token account.
# Agent Integration
Source: https://docs.cashmere.exchange/developers/agent-integration
Integrate Cashmere cross-chain USDC transfers and Goat LP liquidity into AI agents: an MCP server for Claude and Hermes Agent, agent skills for payments and for Goat LP, and tools for LangChain, OpenAI, Hermes, crewAI or any agent framework.
## Overview
The **Cashmere Agent SDK** (`@cashmerelabs/cashmere-agent-sdk`) turns cross-chain USDC transfers into a standard AI agent tool. Any framework that supports function calling or tool use can integrate Cashmere bridging in minutes.
**What agents can do:**
* **Simulate** a transfer to preview fees, duration, and route viability without executing
* **Execute** a transfer across 17 chains (EVM, Solana, Aptos, Sui)
* **Query** supported routes and CCTP versions programmatically
Destination minting is handled automatically by Cashmere relayers — the agent only needs to initiate the source-side burn.
From 0.4.0 the same MCP server also has [Goat LP tools](#goat-lp-tools): agents can read Goat LP pools and positions on Robinhood Chain, add liquidity, and turn auto-compound, auto-range and auto-exit on and off. Each write runs only after the user confirms its plan.
Claude Desktop, Claude Code and Hermes Agent can use these tools without any code, through the bundled [MCP server](#mcp-server) and the [agent skills](#agent-skill) for payments, transfers and Goat LP.
***
## MCP Server
The SDK package includes an MCP server, so Claude Desktop, Claude Code, Hermes Agent and other MCP clients can quote and send transfers as tools. It runs over stdio with `npx -y @cashmerelabs/cashmere-agent-sdk@0.4.0` and needs Node.js 22 or later. Keep the version pinned: the process holds your keys, so it should run exactly the release you chose.
| Tool | What it does |
| - | - |
| `cashmere_supported_routes` | Routes, CCTP versions, default version and durations, optionally filtered by `from` and `to`. Read-only |
| `cashmere_simulate` | Fee, version and duration of a transfer, from the live Gas API and Circle Iris. Read-only |
| `cashmere_bridge` | Sends the transfer and returns its `txHash` and `explorerUrl` |
The same server has the Goat LP tools as well; see [Goat LP tools](#goat-lp-tools).
> [tab] Claude Desktop
>
> Add the server to `claude_desktop_config.json` (Settings → Developer → Edit Config) and restart Claude Desktop. The file is in `~/Library/Application Support/Claude/` on macOS and `%APPDATA%\Claude\` on Windows.
>
> ```json theme={null}
> {
> "mcpServers": {
> "cashmere": {
> "command": "npx",
> "args": ["-y", "@cashmerelabs/cashmere-agent-sdk@0.4.0"],
> "env": {
> "CASHMERE_EVM_PRIVATE_KEY": "0x...",
> "CASHMERE_MCP_MAX_AMOUNT": "500",
> "npm_config_ignore_scripts": "true"
> }
> }
> }
> }
> ```
>
> For quotes only, replace the key with `"CASHMERE_MCP_READ_ONLY": "1"`.
> [tab] Claude Code
>
> The SDK repository is also a Claude Code plugin marketplace. The `cashmere` plugin brings the MCP server and the [agent skills](#agent-skill) together, and asks for the optional keys, which it keeps in the system keychain:
>
> ```bash theme={null}
> /plugin install cashmere --marketplace cashmere-prod/cashmere-agent-sdk
> ```
>
> On Claude Code before 2.1.275, run `/plugin marketplace add cashmere-prod/cashmere-agent-sdk`, then `/plugin install cashmere@cashmere`. To add only the server:
>
> ```bash theme={null}
> claude mcp add --env CASHMERE_MCP_READ_ONLY=1 --env npm_config_ignore_scripts=true --transport stdio cashmere -- npx -y @cashmerelabs/cashmere-agent-sdk@0.4.0
> ```
> [tab] Hermes Agent
>
> Add the server under `mcp_servers` in `~/.hermes/config.yaml`. Hermes passes a stdio server the `env` listed here plus a small fixed baseline, not your shell environment, and names the tools `mcp_cashmere_cashmere_simulate` and so on.
>
> ```yaml theme={null}
> mcp_servers:
> cashmere:
> command: "npx"
> args: ["-y", "@cashmerelabs/cashmere-agent-sdk@0.4.0"]
> env:
> CASHMERE_EVM_PRIVATE_KEY: "0x..."
> CASHMERE_MCP_MAX_AMOUNT: "500"
> npm_config_ignore_scripts: "true"
> ```
>
> Install the [agent skills](#agent-skill) as well, so the agent follows the confirmation workflow.
### Environment
The server reads its settings from the environment only, and only under `CASHMERE_` names. Claude Code passes your shell environment to MCP servers, so a key exported there for other tools, such as an `EVM_PRIVATE_KEY`, never becomes a wallet the agent can spend from.
| Variable | Effect |
| - | - |
| `CASHMERE_EVM_PRIVATE_KEY`, `CASHMERE_SOLANA_PRIVATE_KEY`, `CASHMERE_APTOS_PRIVATE_KEY`, `CASHMERE_SUI_PRIVATE_KEY` | Wallets `cashmere_bridge` sends from. The EVM one is also the wallet of the Goat LP write tools. Set only the chains you need |
| `CASHMERE_MCP_READ_ONLY=1` | Read tools only: `cashmere_bridge` and the Goat LP write tools are off, and the keys are not read |
| `CASHMERE_MCP_MAX_AMOUNT=500` | Largest USDC amount per transfer |
| `CASHMERE_MCP_MAX_TOTAL=2000` | Largest USDC total while the server runs |
| `CASHMERE_MCP_ALLOWED_RECIPIENTS=0x...,9WzD...` | The only recipients `cashmere_bridge` sends to, comma-separated |
| `CASHMERE_EVM_RPC_URL`, `CASHMERE_SOLANA_RPC_URL`, `CASHMERE_APTOS_RPC_URL`, `CASHMERE_SUI_RPC_URL` | Custom RPCs, https only (or a local node). The EVM one serves every EVM source chain, so set it only for a single-chain setup. The Sui one is a gRPC endpoint |
| `CASHMERE_GAS_API_URL` | Gas API, https only. Default `https://gas.cashmere.exchange` |
| `CASHMERE_ROBINHOOD_RPC_URL`, `CASHMERE_GOATLP_MAX_DEPOSIT_USD`, `CASHMERE_GOATLP_MAX_TOTAL_USD` | Goat LP settings; see [Goat LP tools](#goat-lp-tools) |
| `npm_config_ignore_scripts=true` | Set it in the same `env`: `npx` then installs without running dependency install scripts, which would otherwise run with your keys in their environment |
Paste each key as the wallet exports it: hex for EVM wallets such as MetaMask; base58 for Phantom or Solflare, or `solana-keygen`'s JSON array; hex or `ed25519-priv-0x...` for Aptos wallets such as Petra; `suiprivkey1...` for Slush or Sui Wallet, or hex.
> [!WARNING]
>
> `cashmere_bridge` moves real funds. Give the agent a dedicated wallet that holds only what it may spend, plus gas, and set `CASHMERE_MCP_MAX_AMOUNT` and `CASHMERE_MCP_MAX_TOTAL`.
The server guards `cashmere_bridge` in several ways:
* It is listed only when a private key is set and `CASHMERE_MCP_READ_ONLY` is not.
* Its description tells the agent to confirm the amount, the chains and the recipient with the user before calling it, and not to retry a failed call on its own.
* It is annotated as destructive. In Claude Code it always needs the user's own approval, never a one-tap one.
* Before signing, it refuses:
* a recipient that is not in the destination chain's address format. CCTP takes any 32 bytes as the recipient, so an EVM address sent to Sui or Aptos would otherwise mint to an account nobody controls;
* a Gas API quote for another destination, or with a fee or deadline out of bounds;
* an amount above `CASHMERE_MCP_MAX_AMOUNT` or past `CASHMERE_MCP_MAX_TOTAL`, or a recipient outside `CASHMERE_MCP_ALLOWED_RECIPIENTS`;
* a transfer identical to one from the last 10 minutes, unless the agent passes `allowDuplicate` after asking the user;
* a call that the client cancelled or timed out while it waited.
* It sends one transfer at a time and reports success only once the transaction is confirmed. Its errors never contain a private key.
***
## Goat LP Tools
> [!WARNING]
>
> Goat LP is experimental. Use small amounts.
From 0.4.0 the MCP server also has tools for [Goat LP](/goat-lp/overview): Uniswap v3 and v4 liquidity on Robinhood Chain
(chain 4663), with the auto-compound, auto-range and auto-exit automations. They need no extra setup: the same server and
the same `npx` command as above.
| Tool | What it does | Sends or signs |
| - | - | - |
| `goatlp_pools` | Pools with APR, fee APR, TVL, 24 h volume and fees, fee tier and venue, and which automations each pool offers | No |
| `goatlp_pool` | One pool: the price both ways, suggested ranges with their ticks, the APR breakdown, its hook, and why an automation is or is not offered | No |
| `goatlp_positions` | An owner's positions (default: the configured wallet) with value, uncollected fees, APR and PnL, and each automation's state | No |
| `goatlp_position` | One position with its cash flows, its permission and every automation rule, read on chain | No |
| `goatlp_add_liquidity` | Opens a Uniswap v3 or v4 position, or adds to one the wallet owns, with the token amounts as given and no swap | Yes |
| `goatlp_set_auto_compound`, `goatlp_set_auto_range`, `goatlp_set_auto_exit` | Turns an automation on, or changes it, for one position the wallet owns | Yes |
| `goatlp_stop_automation` | Stops an automation the way the app does, and cancels its unused signed messages | Yes |
The read tools are always on. The write tools are listed only when `CASHMERE_EVM_PRIVATE_KEY` is set and
`CASHMERE_MCP_READ_ONLY` is not. They are annotated as destructive, so Claude Code always asks for the user's own approval,
and they share `cashmere_bridge`'s queue: one write at a time from the wallet.
### Plan, then execute
Called without `execute`, a write tool sends nothing. It returns a plan and a `planId`: every transaction and signed
message in order, with contract names and addresses, amounts or settings, fees, and the result of simulating it. The agent
shows the plan to the user and waits for an explicit yes. Only then does it call the same tool with the same inputs plus
`execute: true` and the `planId`. A plan is single use and lasts 10 minutes. At execute the tool builds the plan again from
fresh chain reads and sends nothing if it has changed.
When a plan asks for an acknowledgement, for example a pool price more than 1% away from Chainlink, the agent asks the
user and plans again with `acknowledge: true`.
### What the tools check
* The chain is Robinhood Chain (4663), checked again right before anything is signed.
* Every contract the tools send to, or give a permission to, matches the code hash pinned in the SDK, and the Uniswap
position managers point at the pinned PoolManager and factory. None of the Goat LP contracts is upgradeable, and their
source is published on the explorer.
* Each transaction is decoded and simulated right before it is signed. A revert refuses it, and the amounts must match the
plan.
* A signed message for v4 auto-compound is checked before signing: only for `GoatAutoCompoundV4`, for a position the
wallet owns, at most 30 runs at a time and at most 90 days.
* Never a permission for all positions, an unlimited token or Permit2 allowance, a transfer of a position, an output to
anyone but the wallet, or an owner, guardian or keeper function. No swaps. Another app's approval on a position is left
alone.
* Automations only where the app offers them: listed pairs, reviewed hooks, and the keeper's size limit per pair. A
refusal gives the app's reason. Nothing is turned on while that list cannot be read from `api.cashmere.exchange`; a
stop still works.
* Deposits: Uniswap v3 pools and v4 pools without a hook; no token that copies an official stock ticker or takes a fee
when it moves; the pool price within 5% of Chainlink where both tokens have a feed; balances that cover the deposit.
### Fees
Auto-compound takes 10% of the fees it adds back, and Cashmere pays the gas. Auto-range takes 0.15% of the amount moved
per move, and auto-exit 0.15% once, when it closes. On Uniswap v4, auto-compound needs no permission on the position: the
wallet signs one message per run, which costs no gas. See [Fees](/goat-lp/fees).
### Settings
| Variable | Effect |
| - | - |
| `CASHMERE_EVM_PRIVATE_KEY` | The wallet the write tools sign with. Give the agent a dedicated wallet that holds only what it may deposit, plus a little ETH for gas |
| `CASHMERE_ROBINHOOD_RPC_URL` | Robinhood Chain RPC, https only (or a local node), never shown in errors. Default `https://rpc.mainnet.chain.robinhood.com` |
| `CASHMERE_GOATLP_MAX_DEPOSIT_USD` | Largest USD value of one `goatlp_add_liquidity` call. Empty means no limit |
| `CASHMERE_GOATLP_MAX_TOTAL_USD` | Largest USD value `goatlp_add_liquidity` deposits while the server runs. Empty means no limit |
Both caps value a deposit with the API's token prices and refuse it when a price is missing. The Claude Code plugin asks
for these as optional settings. The tools read `api.cashmere.exchange` the way the app does,
with the honest `User-Agent: cashmere-agent-sdk/`, within its per-minute limits.
### Not in this version
* Deposits into Uniswap v4 pools that have a hook are refused; use the app for those.
* [Allow for all positions](/goat-lp/allow-for-all-positions) is not available to agents.
***
## Agent Skill
The SDK repository ships an agent skill, [`cashmere-usdc-transfers`](https://github.com/cashmere-prod/cashmere-agent-sdk/tree/main/skills/cashmere-usdc-transfers), that teaches an agent to run USDC payments and transfers with the MCP tools. The agent collects the amount, the chains and the recipient, checks the address format, quotes the transfer and confirms it with the user. Only then does it send, and it reports the result. The skill also covers fees, speed and what to do when a transfer fails. It follows the [Agent Skills](https://agentskills.io) format.
| Agent | Install |
| - | - |
| Claude Code | The `cashmere` plugin above includes it |
| Claude Desktop | Zip the `skills/cashmere-usdc-transfers` folder and upload it with **Upload skill** under Customize → Skills (code execution must be on). The skill drives the local MCP server, so use it in Claude Desktop, not claude.ai in a browser |
| Hermes Agent | `hermes skills install cashmere-prod/cashmere-agent-sdk/skills/cashmere-usdc-transfers` |
| Others | Copy the folder into the agent's skills directory, such as `~/.claude/skills/`. It also ships in the npm package |
From 0.4.0 a second skill, [`goat-lp`](https://github.com/cashmere-prod/cashmere-agent-sdk/tree/main/skills/goat-lp), does the same for the [Goat LP tools](#goat-lp-tools): it finds pools and positions, plans a deposit or an automation, shows the plan, and executes it only after the user confirms. Install it the same way, from the `skills/goat-lp` folder; on Hermes Agent, `hermes skills install cashmere-prod/cashmere-agent-sdk/skills/goat-lp`. The Claude Code plugin includes both skills.
***
## Install
Requires Node.js 22 or later.
```bash theme={null}
npm install @cashmerelabs/cashmere-agent-sdk
```
For LangChain integration, also install:
```bash theme={null}
npm install @langchain/core @langchain/langgraph
```
***
## Quick Setup
```ts theme={null}
import { CashmereCCTP } from '@cashmerelabs/cashmere-agent-sdk';
const cctp = new CashmereCCTP({
evm: { privateKey: process.env.EVM_PRIVATE_KEY! },
solana: { privateKey: process.env.SOLANA_PRIVATE_KEY! },
aptos: { privateKey: process.env.APTOS_PRIVATE_KEY! },
sui: { privateKey: process.env.SUI_PRIVATE_KEY! },
});
```
Only configure the chains your agent needs. Keys are read from environment variables and used only for in-memory transaction signing.
***
## Simulate Before Execute
Use `simulate()` to let the agent preview costs before committing funds:
```ts theme={null}
const sim = await cctp.simulate({
from: 'ethereum',
to: 'arbitrum',
amount: '100',
});
// {
// supported: true,
// version: 'v2-fast',
// estimatedDuration: '~15 seconds',
// estimatedFee: { cashmere: '343617201738094 wei (native)', circleBurnBps: 1.3 }
// }
```
`estimatedFee.cashmere` is Cashmere's fixed fee: in the source chain's smallest native unit with the default `feeMode: 'native'`, or like `'0.19 USDC'` with `'stable'`, taken from the amount. Cashmere's contracts can also take a percentage of the amount, capped at 1%. It is 0 on every chain today, so the quote doesn't include it. On V2 Fast, Circle keeps up to `circleBurnBps` basis points when minting, so the recipient gets slightly less than `amount`.
This calls the Gas API and Circle Iris to fetch real-time fee data without submitting any transaction.
***
## Framework Integration
> [tab] OpenAI Assistants
>
> Import the JSON tool schemas and pass them directly to the OpenAI API:
>
> ```ts theme={null}
> import {
> bridgeToolSchema,
> simulateToolSchema,
> supportedRoutesToolSchema,
> getSupportedRoutes,
> } from '@cashmerelabs/cashmere-agent-sdk';
>
> const tools = [
> { type: "function", function: bridgeToolSchema },
> { type: "function", function: simulateToolSchema },
> { type: "function", function: supportedRoutesToolSchema },
> ];
>
> const response = await openai.chat.completions.create({
> model: "gpt-4",
> messages: [
> { role: "system", content: "You are a cross-chain treasury agent." },
> { role: "user", content: "Bridge 500 USDC from Ethereum to Solana" },
> ],
> tools,
> });
>
> // When the model calls a Cashmere tool, parse the arguments and call the SDK.
> // Confirm a cashmere_bridge call with the user before running it.
> const call = response.choices[0].message.tool_calls[0];
> if (call.function.name === 'cashmere_simulate') {
> const result = await cctp.simulate(JSON.parse(call.function.arguments));
> } else if (call.function.name === 'cashmere_supported_routes') {
> const result = getSupportedRoutes(JSON.parse(call.function.arguments));
> } else if (call.function.name === 'cashmere_bridge') {
> const result = await cctp.transfer(JSON.parse(call.function.arguments));
> }
> ```
>
> The schemas define three tools:
>
> | Tool | Description |
> | - | - |
> | `cashmere_simulate` | Preview fee, duration, route — no execution |
> | `cashmere_supported_routes` | List routes, CCTP versions and durations — no execution |
> | `cashmere_bridge` | Execute a cross-chain USDC transfer |
> [tab] LangChain
>
> The SDK provides ready-made LangChain `Tool` classes:
>
> ```ts theme={null}
> import { CashmereCCTP } from '@cashmerelabs/cashmere-agent-sdk';
> import {
> CashmereBridgeTool,
> CashmereSimulateTool,
> } from '@cashmerelabs/cashmere-agent-sdk/tools/langchain';
> import { createReactAgent } from '@langchain/langgraph/prebuilt';
>
> const cctp = new CashmereCCTP({
> evm: { privateKey: process.env.EVM_PRIVATE_KEY! },
> });
>
> const tools = [
> new CashmereBridgeTool(cctp),
> new CashmereSimulateTool(cctp),
> ];
>
> // Use with any LangChain chat model, e.g. new ChatAnthropic({ model: 'claude-sonnet-5-5' }) from @langchain/anthropic
> const agent = createReactAgent({ llm: chatModel, tools });
> const result = await agent.invoke({
> messages: [{ role: "user", content: "Send 200 USDC from Base to Polygon" }],
> });
> ```
>
> Both tools accept JSON string input and return JSON string output, compatible with all LangChain agent types. `CashmereBridgeTool` sends as soon as the agent calls it: its description tells the model to confirm with the user first, but also put a human approval step in front of it (LangGraph supports interrupts), or give the agent only `CashmereSimulateTool`.
> [tab] crewAI
>
> crewAI is a Python framework, so the TypeScript classes don't apply. Connect it to the [MCP server](#mcp-server) through crewAI's MCP support, or define its tools from the JSON tool schemas:
>
> ```python theme={null}
> # Copy the description from bridgeToolSchema: it tells the model to confirm with the user first
> cashmere_tool = {
> "name": "cashmere_bridge",
> "description": "Bridge USDC across chains via Cashmere CCTP...",
> "parameters": {
> "type": "object",
> "properties": {
> "from": {"type": "string", "description": "Source chain"},
> "to": {"type": "string", "description": "Destination chain"},
> "amount": {"type": "string", "description": "USDC amount"},
> "recipient": {"type": "string", "description": "Destination address"},
> },
> "required": ["from", "to", "amount", "recipient"],
> },
> }
> ```
> [tab] Hermes
>
> Hermes models (Nous Research) take tools as OpenAI-style functions inside `` in the system prompt, and answer with `` blocks that hold `name` and `arguments`. Behind an OpenAI-compatible server with a Hermes tool parser (vLLM `--enable-auto-tool-choice --tool-call-parser hermes`, SGLang, llama.cpp, Ollama), pass `hermesTools()` as `tools`, read `tool_calls` as with OpenAI, and send each result back as a `tool` message with its `tool_call_id`. Hermes Agent can use the [MCP server](#mcp-server) instead.
>
> To prompt a Hermes model directly, without a chat template:
>
> ```ts theme={null}
> import {
> CashmereCCTP,
> getSupportedRoutes,
> hermesTools,
> hermesSystemPrompt,
> parseHermesToolCalls,
> hermesToolResponse,
> } from '@cashmerelabs/cashmere-agent-sdk';
>
> const cctp = new CashmereCCTP({ evm: { privateKey: process.env.EVM_PRIVATE_KEY! } });
> const system = hermesSystemPrompt(hermesTools(), 'You move USDC between chains for the user.');
> // Hermes 2 Pro and 3 read tool results as a `tool` message, Hermes 4 as a `user` message
> const toolResultRole = 'user'; // Hermes 4
>
> // After each model reply. Tool calls inside are skipped.
> for (const call of parseHermesToolCalls(reply)) {
> const args = call.arguments as any;
> let result: unknown;
> if (call.name === 'cashmere_simulate') result = await cctp.simulate(args);
> else if (call.name === 'cashmere_supported_routes') result = getSupportedRoutes(args);
> else if (call.name === 'cashmere_bridge') result = await confirmWithUserThenTransfer(args); // your own approval step
> messages.push({ role: toolResultRole, content: hermesToolResponse(call.name, result) });
> }
> ```
>
> `hermesTools({ readOnly: true })` leaves `cashmere_bridge` out. `recipientError(to, recipient)` runs the same address check as the MCP server.
> [tab] Custom Framework
>
> For any framework that supports function calling, use the raw JSON schemas:
>
> ```ts theme={null}
> import {
> bridgeToolSchema,
> simulateToolSchema,
> supportedRoutesToolSchema,
> getSupportedRoutes,
> } from '@cashmerelabs/cashmere-agent-sdk';
>
> // bridgeToolSchema, simulateToolSchema and supportedRoutesToolSchema are plain objects:
> // {
> // name: "cashmere_bridge",
> // description: "...",
> // parameters: { type: "object", properties: {...}, required: [...] }
> // }
>
> // Register as tools in your framework, then dispatch:
> async function handleToolCall(name: string, args: any) {
> if (name === 'cashmere_bridge') {
> // Moves funds: show the user the amount, chains and recipient, and wait for their yes
> if (!(await confirmWithUser(args))) return { error: 'The user did not confirm this transfer' };
> return await cctp.transfer(args);
> } else if (name === 'cashmere_simulate') {
> return await cctp.simulate(args);
> } else if (name === 'cashmere_supported_routes') {
> return getSupportedRoutes(args);
> }
> }
> ```
***
## Tool Schemas Reference
### `cashmere_bridge`
Executes a cross-chain USDC transfer. Its description tells the agent to confirm the amount, the chains and the recipient with the user before every call.
| Parameter | Type | Required | Description |
| - | - | - | - |
| `from` | string | Yes | Source chain (e.g. `ethereum`, `arbitrum`, `solana`) |
| `to` | string | Yes | Destination chain |
| `amount` | string | Yes | USDC amount, human-readable (e.g. `"100"`) |
| `recipient` | string | Yes | Destination wallet address |
| `version` | string | No | `v2-fast` or `v2-norm` (auto-resolved if omitted; a `v1` request is sent over V2) |
| `feeMode` | string | No | `native` or `stable` (default: `native`) |
**Returns:** `{ txHash, explorerUrl, version, from, to }`
### `cashmere_simulate`
Previews a transfer without executing.
| Parameter | Type | Required | Description |
| - | - | - | - |
| `from` | string | Yes | Source chain |
| `to` | string | Yes | Destination chain |
| `amount` | string | Yes | USDC amount |
| `version` | string | No | CCTP version preference |
| `feeMode` | string | No | Fee payment mode |
**Returns:** `{ supported, version, estimatedDuration, estimatedFee: { cashmere, circleBurnBps } }`
### `cashmere_supported_routes`
Lists routes, grouped by source chain. Read-only. The JSON schema is exported as `supportedRoutesToolSchema`, and `getSupportedRoutes()` returns the same data in code.
| Parameter | Type | Required | Description |
| - | - | - | - |
| `from` | string | No | Only routes from this chain |
| `to` | string | No | Only routes to this chain |
**Returns:** `{ routes: [{ from, destinations, versions, defaultVersion, estimatedDuration }] }`, where `versions` are the CCTP versions the SDK sends those routes over and `estimatedDuration` maps each version to a duration.
***
## Supported Chains
Every chain can send to every other over CCTP V2, and the SDK sends every route over V2. The V1 column shows what the contracts still accept; Circle is retiring V1 burns.
| Chain | Domain | V1 | V2 Fast | V2 Norm |
| - | - | - | - | - |
| Ethereum | 0 | Y | Y | Y |
| Avalanche | 1 | Y | N | Y |
| Optimism | 2 | Y | Y | Y |
| Arbitrum | 3 | Y | Y | Y |
| Solana | 5 | Y | N | Y |
| Base | 6 | Y | Y | Y |
| Polygon | 7 | Y | N | Y |
| Sui | 8 | Y | N | Y |
| Aptos | 9 | Y | N | Y |
| Unichain | 10 | Y | Y | Y |
| Linea | 11 | N | Y | Y |
| Sonic | 13 | N | N | Y |
| Worldchain | 14 | N | Y | Y |
| Monad | 15 | N | N | Y |
| Sei | 16 | N | N | Y |
| HyperEVM | 19 | N | N | Y |
| Arc | 26 | N | N | Y |
***
## SKILL.md (Agent Context)
The SDK ships with a `SKILL.md` file that provides comprehensive context for AI agents. Load it to give your agent detailed knowledge about Cashmere CCTP:
```ts theme={null}
import { readFileSync } from 'node:fs';
import { createRequire } from 'node:module';
// In CommonJS, use the built-in require instead
const require = createRequire(import.meta.url);
const skillContext = readFileSync(
require.resolve('@cashmerelabs/cashmere-agent-sdk/SKILL.md'),
'utf8',
);
// Pass as system message to your LLM
const messages = [
{ role: "system", content: skillContext },
{ role: "user", content: "What's the fastest way to bridge 1000 USDC to Solana?" },
];
```
The SKILL.md covers:
* All contract addresses and program IDs (public, on-chain data)
* Fee calculation formulas and gas API integration
* Per-chain transfer patterns and ABI details
* CCTP version routing rules and estimated durations
***
## Security
> [!WARNING]
>
> Private keys never leave the process: they are not logged, written to disk or sent anywhere. Only signed transactions reach the chain's RPC, and the Gas API and Circle's Iris API receive only domain IDs, the fee mode and the CCTP version.
* Keys come from environment variables or your own secret store, and are used only for in-memory signing
* The MCP server reads keys from its environment only, removes them from its environment once read, never logs them, and redacts them from tool errors
* The library never writes to the console; the MCP server prints one status line to stderr, without keys
* Every contract address in the SDK is public on-chain data
* `.env.example` ships with empty values: never commit `.env`
***
## Next Steps
* [Smart Contracts](/developers/smart-contracts) — per-chain contract details and ABI reference
* [Backend APIs](/developers/backend-apis) — Gas API and monitoring endpoints
* [Contract Addresses](/developers/contract-addresses) — deployed addresses for all 17 chains
* [GitHub](https://github.com/cashmere-prod/cashmere-agent-sdk) — source code and issues
# Backend APIs
Source: https://docs.cashmere.exchange/developers/backend-apis
The Gas API for signed fee quotes, and the kapi endpoints for transfer status, protocol stats and points.
Cashmere runs two public HTTPS APIs. Neither needs an API key.
| Host | Use it to |
| - | - |
| `https://gas.cashmere.exchange` | Get the signed fee quote that every Cashmere transfer needs, plus live fees and token prices |
| `https://kapi.cashmere.exchange` | Track transfers, read protocol stats and query points and leaderboards |
The [API Reference](/api-reference/introduction) lists every parameter and field. This page covers what an integration needs to get right.
## Gas API (`gas.cashmere.exchange`)
### Purpose
The Gas API prices each route and signs a fee quote that the Cashmere contracts verify on-chain. A quote is valid for about 100 seconds.
### REST Endpoints
| Endpoint | Description |
| - | - |
| `GET /getEcdsaSig_native` | Signed quote for EVM source chains (`transfer`, `transferV2` and their permit variants) |
| `GET /getEd25519Sig_native` | Signed quote for Solana, Aptos and Sui source chains |
| `GET /tokenPrices` | USD price of each chain's gas token, keyed by chain name |
| `GET /health` | Readiness probe: `{ "status": "healthy", "timestamp": "…" }` |
#### `GET /getEcdsaSig_native`
| Query | Type | Notes |
| - | - | - |
| `localDomain` | number | Source chain's CCTP domain, for example `0` for Ethereum |
| `destinationDomain` | number | Destination domain |
| `isV2` | boolean | `true` for `transferV2*`. `false` signs the V1 `transfer*`, which Circle stops accepting on 1 December 2026 |
| `isNative` | boolean | Required. `true` to pay the fee in the source chain's gas token, `false` to take it from the USDC |
```http theme={null}
GET https://gas.cashmere.exchange/getEcdsaSig_native?localDomain=0&destinationDomain=3&isV2=true&isNative=false
```
```json theme={null}
{
"fee": "190000",
"deadline": "1793034101",
"signature": "0x8ab3…1b",
"isNative": false,
"cctpVersion": 2
}
```
* `fee` is in USDC base units (6 decimals) with `isNative=false`, and in wei with `isNative=true`. It pays for the mint on the destination chain, so it depends mostly on where the USDC goes: in October 2026, 0.19 USDC into most chains, 0.79 into Solana and about 1.48 into Ethereum. Request a quote for every transfer instead of hardcoding a fee.
* `deadline` is in unix seconds, about 100 seconds after the quote was issued. The contract reverts after it.
* `signature` is a 65-byte ECDSA signature. Pass `fee`, `deadline` and `signature` to the contract unchanged, and with `isNative=true` send `fee` as the transaction's `value`.
**Signature payload**
The contract recomputes this digest and checks the signature against it with `ecrecover`, without the `\x19Ethereum Signed Message` prefix:
```solidity theme={null}
keccak256(abi.encodePacked(
uint32(localDomain),
uint32(destinationDomain),
uint128(fee),
uint64(deadline),
bool(isNative),
uint8(cctpVersion) // 1 for transfer and transferWithPermit, 2 for the V2 variants
));
```
#### `GET /getEd25519Sig_native`
| Query | Type | Notes |
| - | - | - |
| `localDomain` | number | `5` Solana, `8` Sui, `9` Aptos |
| `destinationDomain` | number | Destination domain |
| `isNative` | boolean | Required. `true` to pay in SOL, SUI or APT, `false` to take the fee from the USDC |
| `version` | number | `2` for the V2 entry points, `1` for Solana V1. Without it the message has no version byte, which only the V1 Aptos and Sui calls accept |
```http theme={null}
GET https://gas.cashmere.exchange/getEd25519Sig_native?localDomain=5&destinationDomain=0&isNative=false&version=2
```
```json theme={null}
{
"signature": "0x6b8f…0c",
"message": "0x020500000000000000ab981600000000007587df6a0000000000",
"publicKey": "0x93ab…af",
"destinationDomain": "0",
"fee": "1480875",
"deadline": "1793034101",
"isNative": false,
"version": 2
}
```
`fee` is in USDC base units with `isNative=false`. With `isNative=true` it is in lamports on Solana (9 decimals), octas on Aptos (8) or MIST on Sui (9).
**Message encoding**
`message` holds exactly the bytes that were signed, little-endian: 26 bytes, or 25 without `version`.
| Bytes | Field | Type |
| - | - | - |
| 0 | `version` | `u8` (only present when you pass `version`) |
| 1–4 | `localDomain` | `u32` |
| 5–8 | `destinationDomain` | `u32` |
| 9–16 | `fee` | `u64` |
| 17–24 | `deadline` | `u64` |
| 25 | `isNative` | `bool` |
This is the Borsh layout the Solana program verifies, and the BCS layout of `TransferParamsV2` on Aptos and Sui. On Solana, put `publicKey`, `message` and `signature` in an `Ed25519Program` instruction right before the transfer instruction. Aptos and Sui take the signature as a call argument. See [Signed Payloads](/developers/smart-contracts#signed-payloads).
### WebSocket Broadcast
`wss://gas.cashmere.exchange/subscribe` sends the current fees and token prices as soon as you connect. Use it to show live fees in a UI, but request a signed quote right before each transfer: only a quote carries a signature.
```json theme={null}
{ "type": "fees", "data": { "ethereum": { "fee": { "arbitrum": { "native": "82063508517328", "usd": "190000" } }, "gas": { "native": "…", "usd": "…" } } } }
{ "type": "tokenPrices", "data": { "ethereum": "2315.28", "solana": "100.99" } }
```
* Keys are chain names (`ethereum`, `arbitrum`, `solana`…), not domain IDs.
* `fee..native` is in the source chain's smallest native unit, and `usd` is in USDC base units (`"190000"` is 0.19 USDC).
* Token prices are USD amounts as decimal strings, the same as `GET /tokenPrices`.
### Operational Notes
* Request a quote right before the user signs, and a fresh one if more than about 70 seconds have passed: the contracts revert once `block.timestamp` passes `deadline`.
* Booleans must be lowercase `true` or `false`.
* A missing `isNative`, an unknown domain or any other bad input returns HTTP 500 with `{"error":"Internal Server Error"}`, not 400. Check your parameters before retrying.
* A 5xx on a valid request means the API can't price the route right now: retry with backoff, and never sign with an expired quote.
* For live fees, use the WebSocket instead of polling the quote endpoints.
***
## Transaction APIs (`kapi.cashmere.exchange`)
### `/transactionsmainnet`
Every mainnet transfer made through Cashmere, newest first.
| Query | Description |
| - | - |
| `senders` | Comma-separated sender addresses |
| `addr_or_tx_hash` | An ENS (`.eth`) or SNS (`.sol`) name, an address or a transaction hash. An unknown name returns `400 {"error":"invalid ens"}`. Lookups by address or hash can take over a minute: filter by `senders` instead |
| `source_domain` / `destination_domain` | Filter by CCTP domain |
| `start_time` / `end_time` | Unix-second bounds on `created_at` |
| `limit` | Page size, default 10 |
| `cursor` | The previous page's `next_cursor` (`_`) |
```http theme={null}
GET https://kapi.cashmere.exchange/transactionsmainnet?senders=0xYourAddress&limit=20
```
```json theme={null}
{
"transactions": [
{
"id": 882672,
"source_tx_hash": "0xSourceTxHash…",
"block": 158712232,
"source_domain": 2,
"destination_domain": 3,
"sender": "0xSenderAddress…",
"recipient": "0xrecipientaddress…",
"solana_owner": "0x0000000000000000000000000000000000000000",
"deposit_amount": 10000000,
"receive_amount": 9998700,
"max_fee": 1300,
"relayer_fee": 190000,
"is_gas_drop_in_native": false,
"gas_drop_amount": 0,
"gas_drop_status": "pending",
"gas_drop_tx_hash": null,
"message_hash": "0x0000…",
"attestation_hash": "0x…",
"nonce": "0x…",
"domain_nonce": 82732,
"version": 2,
"confirmed": true,
"destination_tx_hash": "0xDestinationTxHash…",
"destination_tx_status": "success",
"source_tx_error": null,
"attestation_error": null,
"destination_tx_error": null,
"has_source_tx_error": false,
"has_attestation_error": false,
"has_destination_tx_error": false,
"created_at": "2026-10-26T14:04:43.31283Z",
"updated_at": "2026-10-26T14:06:43.422173Z"
}
],
"next_cursor": "1793021083_882672",
"has_more": true
}
```
| Field | Meaning |
| - | - |
| `deposit_amount` | USDC burned on the source chain, in base units (6 decimals) |
| `receive_amount` | USDC minted to the recipient, after Circle's fee (at most `max_fee`) |
| `relayer_fee` | Cashmere's fee: USDC base units when `is_gas_drop_in_native` is `false`, otherwise the source chain's smallest native unit |
| `is_gas_drop_in_native` | The transfer's `isNative` flag: `true` when the fee was paid in the gas token |
| `recipient`, `solana_owner` | The CCTP recipient. Into Solana it is the USDC token account, and `solana_owner` is the wallet; otherwise `solana_owner` is zero |
| `confirmed` | The source transaction is confirmed |
| `destination_tx_status` | `success` once the USDC is minted, `failed` if the mint transaction failed (see `destination_tx_error`) |
| `gas_drop_*` | Gas drop is not offered: always 0 and `pending` |
* Native fees in wei can exceed `Number.MAX_SAFE_INTEGER`, and `JSON.parse` then rounds them. Use them for display, or parse the body with a big-integer JSON parser.
* `destination_tx_hash` can be all zeros even when the status is `success`.
* Responses are cached for 5 seconds, so polling more often than that returns the same page.
### `/transactions`
The same query parameters and schema, for testnet transfers. It has no data newer than October 2025.
***
## Points & Leaderboard API (`kapi.cashmere.exchange`)
Public endpoints for Cashmere's points program and protocol stats. Stats responses are cached for 60 seconds, and leaderboard responses for 5. The [Analytics reference](/api-reference/analytics) shows every payload.
| Endpoint | Returns |
| - | - |
| `GET /users/leaderboard` | Points leaderboard: `network` defaults to `devnet`, so pass `network=mainnet`. `limit` defaults to 50 and goes up to 100 (larger values fall back to 50), plus `offset` and `search` |
| `GET /users?domains=.csm` | One profile's points, rank and bound wallets per chain |
| `GET /users?wallets=_evm,_solana` | Points for each wallet |
| `GET /users/messages`, `POST /users/verify` | Wallet binding for the Cashmere app (see [Wallet Binding](/api-reference/analytics#wallet-binding)) |
| `GET /stats/mainnet/volumes` | Lifetime volume `total_volume` in USDC base units, or `user_volume` with `?senders=` |
| `GET /stats/mainnet/volumes/hourly`, `/daily` | Volume buckets in USD: last 24 hours or last 30 days by default |
| `GET /stats/mainnet/fees` | Fee buckets in USD, with `period=hourly` (default), `daily`, `weekly` or `monthly` and `limit` up to 1000 |
| `GET /stats/mainnet/transactions` | `total_transactions` |
| `GET /stats/mainnet/chain-shares` | Volume per CCTP domain: `domain`, `amount`, `total_amount` |
| `GET /stats/mainnet/wallets`, `/stats/wallets` | `unique_senders_count` on mainnet or testnet |
Points and multipliers are floats; round them for display. An unknown profile returns `404 {"error":"user not found"}`.
***
## Smart Contract Integration (Quick Ref)
1. Request a quote. On EVM, call `/getEcdsaSig_native` with `isV2=true`; on Solana, Aptos and Sui, call `/getEd25519Sig_native` with `version=2`. Always pass `isNative`.
2. Fill the contract parameters:
* `fee`, `deadline` and `signature` from the quote, unchanged;
* `maxFee` from Circle's `minimumFee` at `https://iris-api.circle.com/v2/burn/USDC/fees/{source}/{destination}` (see [From Quote to Call](/developers/smart-contracts#from-quote-to-call));
* `gasDropAmount` 0, since gas drop is not offered;
* on EVM, `hookData` `0x00`: Circle rejects empty hook data.
3. Approve `amount` USDC (EVM). With `isNative=true`, send `fee` as the transaction's `value` on EVM, and on Sui pass it as a coin split from gas; the Solana and Aptos contracts take it from the sender's balance.
4. Submit before `deadline`.
5. Poll `/transactionsmainnet` until `destination_tx_status` is `success`.
> [!WARNING]
>
> Don't cache or reuse quotes. Each one is signed for a single route, fee mode and CCTP version, and expires about 100 seconds after it is issued.
# Contract Addresses
Source: https://docs.cashmere.exchange/developers/contract-addresses
Complete list of Cashmere and token contract addresses across all supported chains.
> [!NOTE]
>
> All addresses listed here are production mainnet contracts. For testnet addresses, contact the team at [contact@cashmere.exchange](mailto:contact@cashmere.exchange).
***
## Cashmere CCTP Contracts
| Chain | Cashmere Contract | Domain ID |
| - | - | - |
| **Ethereum** | `0xD156fFB54871F4562744d6Be5d6321B5BffCa3B6` | 0 |
| **Avalanche** | `0xD156fFB54871F4562744d6Be5d6321B5BffCa3B6` | 1 |
| **Optimism** | `0xD156fFB54871F4562744d6Be5d6321B5BffCa3B6` | 2 |
| **Arbitrum** | `0x3412ef459221d1581a08dcD56Ee55B8FaeBf5eEA` | 3 |
| **Base** | `0xD156fFB54871F4562744d6Be5d6321B5BffCa3B6` | 6 |
| **Polygon** | `0xD156fFB54871F4562744d6Be5d6321B5BffCa3B6` | 7 |
| **Unichain** | `0xd002a7172Ac6f90657FCb918B3f7e36372a4bA80` | 10 |
| **Linea** | `0xD156fFB54871F4562744d6Be5d6321B5BffCa3B6` | 11 |
| **Sonic** | `0xD156fFB54871F4562744d6Be5d6321B5BffCa3B6` | 13 |
| **Worldchain** | `0xD156fFB54871F4562744d6Be5d6321B5BffCa3B6` | 14 |
| **Monad** | `0xD156fFB54871F4562744d6Be5d6321B5BffCa3B6` | 15 |
| **Sei** | `0xD156fFB54871F4562744d6Be5d6321B5BffCa3B6` | 16 |
| **HyperEVM** | `0x15b2810232ec96ff083ca6d8b785cb930d241d83` | 19 |
| **Arc** | `0xD156fFB54871F4562744d6Be5d6321B5BffCa3B6` | 26 |
| **Solana** | `5RsvKL6LFq6yEFiAXEwgYHAN3aLFypeB4AaafdeDnHqM` | 5 |
| **Aptos** | `0xe49afb1896889e3e1dd7bcbb9e31d1df8221899d3d368e98588ac6b4d84b136d` | 9 |
| **Sui** | `0xdf37112aacb7d3535f7b3b754b9a7b9fa1a6b3a756288dc734522c603c6f11a4` (calls go to the V2 package `0x7eab670b…`, see [Sui](#sui)) | 8 |
***
## USDC Token Addresses
| Chain | USDC Address | Decimals |
| - | - | - |
| **Ethereum** | `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48` | 6 |
| **Avalanche** | `0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E` | 6 |
| **Polygon** | `0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359` | 6 |
| **Arbitrum** | `0xaf88d065e77c8cC2239327C5EDb3A432268e5831` | 6 |
| **Optimism** | `0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85` | 6 |
| **Base** | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` | 6 |
| **Unichain** | `0x078D782b760474a361dDA0AF3839290b0EF57AD6` | 6 |
| **Linea** | `0x176211869cA2b568f2A7D4EE941E073a821EE1ff` | 6 |
| **Worldchain** | `0x79A02482A880bCe3F13E09da970dC34dB4cD24D1` | 6 |
| **Sei** | `0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392` | 6 |
| **Sonic** | `0x29219dd400f2Bf60E5a23d13Be72B486D4038894` | 6 |
| **HyperEVM** | `0xb88339CB7199b77E23DB6E890353E22632Ba630f` | 6 |
| **Monad** | `0x754704Bc059F8C67012fEd69BC8A327a5aafb603` | 6 |
| **Arc** | `0x3600000000000000000000000000000000000000` | 6 |
| **BNB Chain** | `0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d` | 18 |
| **Solana** | `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` | 6 |
| **Aptos** | `0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b` | 6 |
| **Sui** | `0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC` | 6 |
> [!WARNING]
>
> **BNB Chain USDC uses 18 decimals** (not 6). Adjust your calculations accordingly when integrating BNB Chain.
> [!NOTE]
>
> **Arc pays gas in USDC.** Its native balance (18 decimals) and the USDC ERC-20 at `0x3600000000000000000000000000000000000000` (6 decimals) are the same funds. CCTP burns through the ERC-20, so transfer amounts use 6 decimals, while gas and a fee paid with `isNative` use 18: a native quote of `190000000000000000` is 0.19 USDC.
***
## USDT Token Addresses
| Chain | USDT Address | Decimals | Protocol |
| - | - | - | - |
| **Ethereum** | `0xdAC17F958D2ee523a2206206994597C13D831ec7` | 6 | LayerZero / NEAR Intents |
| **Polygon** | `0xc2132D05D31c914a87C6611C10748AEb04B58e8F` | 6 | LayerZero / NEAR Intents |
| **Arbitrum** | `0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9` | 6 | LayerZero / NEAR Intents |
| **Optimism** | `0x01bFF41798a0BcF287b996046Ca68b395DbC1071` | 6 | LayerZero |
| **Unichain** | `0x9151434b16b9763660705744891fA906F660EcC5` | 6 | LayerZero |
| **Sei** | `0x9151434b16b9763660705744891fA906F660EcC5` | 6 | LayerZero |
| **HyperEVM** | `0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb` | 6 | LayerZero |
| **Berachain** | `0x779Ded0c9e1022225f8E0630b35a9b54bE713736` | 6 | LayerZero |
| **BNB Chain** | `0x55d398326f99059fF775485246999027B3197955` | 18 | NEAR Intents |
| **Ink** | `0x0200C29006150606B650577BBE7B6248F58470c1` | 6 | LayerZero |
| **Corn** | `0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb` | 6 | LayerZero |
| **Flare** | `0xe7cd86e13AC4309349F30B3435a9d337750fC82D` | 6 | LayerZero |
| **Rootstock** | `0x779dED0C9e1022225F8e0630b35A9B54Be713736` | 6 | LayerZero |
| **XLayer** | `0x779Ded0c9e1022225f8E0630b35a9b54bE713736` | 6 | LayerZero |
| **Plasma** | `0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb` | 6 | LayerZero |
> [!WARNING]
>
> **BNB Chain USDT uses 18 decimals** (not 6). Adjust your calculations accordingly when integrating BNB Chain.
***
## USDT0 OFT Upgradeable Addresses
LayerZero OFT (Omnichain Fungible Token) contracts for USDT0:
| Chain | USDT0 Address | Decimals |
| - | - | - |
| **Ethereum** | `0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee` | 6 |
| **Polygon** | `0x6BA10300f0DC58B7a1e4c0e41f5daBb7D7829e13` | 6 |
| **Arbitrum** | `0x14E4A1B13bf7F943c8ff7C51fb60FA964A298D92` | 6 |
| **Optimism** | `0xF03b4d9AC1D5d1E7c4cEf54C2A313b9fe051A0aD` | 6 |
| **Unichain** | `0xc07bE8994D035631c36fb4a89C918CeFB2f03EC3` | 6 |
| **Sei** | `0x56Fe74A2e3b484b921c447357203431a3485CC60` | 6 |
| **HyperEVM** | `0x904861a24F30EC96ea7CFC3bE9EA4B476d237e98` | 6 |
| **Berachain** | `0x3Dc96399109df5ceb2C226664A086140bD0379cB` | 6 |
| **Ink** | `0x1cB6De532588fCA4a21B7209DE7C456AF8434A65` | 6 |
| **Corn** | `0x3f82943338a8a76c35BFA0c1828aA27fd43a34E4` | 6 |
| **Flare** | `0x567287d2A9829215a37e3B88843d32f9221E7588` | 6 |
| **Rootstock** | `0x1a594d5d5d1c426281C1064B07f23F57B2716B61` | 6 |
| **XLayer** | `0x94bcca6bdfd6a61817ab0e960bfede4984505554` | 6 |
| **Plasma** | `0x02ca37966753bDdDf11216B73B16C1dE756A7CF9` | 6 |
***
## Solana Program Addresses
| Program | Address | Usage |
| - | - | - |
| **Cashmere CCTP** | `5RsvKL6LFq6yEFiAXEwgYHAN3aLFypeB4AaafdeDnHqM` | Main program |
| **USDC Mint** | `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` | USDC token |
| **Message Transmitter V1** | `CCTPmbSD7gX1bxKPAmg77w8oFzNFpaQiQUWD43TKaecd` | CCTP V1 |
| **Token Messenger Minter V1** | `CCTPiPYPc6AsJuwueEnWgSgucamXDZwBd53dQ11YiKX3` | CCTP V1 |
| **Message Transmitter V2** | `CCTPV2Sm4AdWt5296sk4P66VBZ7bEhcARwFaaS9YPbeC` | CCTP V2 |
| **Token Messenger Minter V2** | `CCTPV2vPZJS2u2BBsUoscuikbYjnpFmbFsvVuJdgUMQe` | CCTP V2 |
| **Address Lookup Table** | `865YCTTsymGpBjLMTvjd3T3RCGT8yvxnAHhyKZqRFfLi` | Transaction compression |
### Solana CCTP Mint Allowance Accounts
| Version | Address | Usage |
| - | - | - |
| **V1 Allowance** | `FSxJ85FXVsXSr51SeWf9ciJWTcRnqKFSmBgRDeL3KyWw` | V1 transfer limit |
| **V2 Allowance** | `6xTBTqJMBr5m7BKqVxmW2x11DfqUwtD3TJsqpxELx72L` | V2 transfer limit |
***
## Move Module Addresses
### Aptos
| Module | Address |
| - | - |
| **Cashmere CCTP** | `0xe49afb1896889e3e1dd7bcbb9e31d1df8221899d3d368e98588ac6b4d84b136d` |
| **USDC** (fungible asset metadata) | `0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b` |
### Sui
| Object | Address |
| - | - |
| **Cashmere CCTP V2 package** (call `prepare_deposit_for_burn_v2` here) | `0x7eab670b3f3e3bb7a0451c7c6b6b627c09e282f0c78eac24966f6479c649d0d5` |
| **Cashmere CCTP original package** (type IDs such as `transfer::Auth`, V1 calls) | `0xdf37112aacb7d3535f7b3b754b9a7b9fa1a6b3a756288dc734522c603c6f11a4` |
| **Cashmere Config** (shared) | `0x5f1b2e205777713f44a99894d98e1e66e33dc11ff88e50108c94ee79b7ea3d67` |
| **Circle TokenMessengerMinter V2** | `0xeb14978abfe93a37c5d5bf86a0623b923553a5f0e794daac7724f1e2fdbfb830` |
| **TokenMessengerMinter V2 State** | `0x06fb166941cd7bc095edc019d054a753ec3f1e4c25f28f2ecc4a6cfa0a9b1167` |
| **MessageTransmitter V2 State** | `0x0c067f7d325e5b60e3179712e7783534ba1556cbb3d359d8161497e37689230c` |
| **Circle USDC Handler** | `0x185ed207c4d64fc594882ab927f9f3c6ff957aad03df8a731ba64378faeeb2bf` |
| **USDC Handler State** | `0xa32de8a6dd0178fb05f662929d55cddb69a25c26bde4b83f89e36d17ead94c41` |
| **USDC Treasury** | `0x57d6725e7a8b49a7b2a612f6bd66ab5f39fc95332ca48be421c3229d514a6de7` |
| **DenyList** | `0x403` |
| **USDC** (coin type) | `0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC` |
***
## NEAR Intents Treasury Contracts
> [!NOTE]
>
> These contracts are used for BNB Chain integration via NEAR Intents. Same addresses across all EVM chains.
| Treasury | Address | Usage |
| - | - | - |
| **Treasury 1** | `0x233c5370CCfb3cD7409d9A3fb98ab94dE94Cb4Cd` | NEAR Intents liquidity |
| **Treasury 2** | `0x2CfF890f0378a11913B6129B2E97417a2c302680` | NEAR Intents liquidity |
***
## Staking Contracts
### Ethereum Staking
| Contract | Address |
| - | - |
| **NFT Contract** | `0x3a40312a1c376aecf855ef784371d1fb1aa2d25d` |
| **Staking Contract** | `0x5078080686AC9381E18eEC8cA0e05d4eE2d52484` |
| **Points Contract** | `0xa0C69824C820F36CA32666462405eA85F414409f` |
### Optimism Staking
| Contract | Address |
| - | - |
| **NFT Contract** | `0xbeBEd7039DBCE2ef39E9048d0F92290c62b95414` |
| **Staking Contract** | `0xa4FAc350ca556be8fEdE2F359A7eb12623669F14` |
| **Points Contract** | `0xFac9a999CC71378Cfd249eD07A12124ef05027a2` |
***
## Chain IDs & Domain IDs
### EVM Chain IDs
| Chain | Chain ID |
| - | - |
| **Ethereum** | 1 |
| **BNB Chain** | 56 |
| **Avalanche** | 43114 |
| **Polygon** | 137 |
| **Arbitrum** | 42161 |
| **Optimism** | 10 |
| **Base** | 8453 |
| **Unichain** | 130 |
| **Linea** | 59144 |
| **Worldchain** | 480 |
| **Sei** | 1329 |
| **Sonic** | 146 |
| **HyperEVM** | 999 |
| **Monad** | 143 |
| **Arc** | 5042 |
| **Berachain** | 80094 |
| **Ink** | 57073 |
| **Corn** | 21000000 |
| **Flare** | 14 |
| **Rootstock** | 30 |
| **XLayer** | 196 |
| **Plasma** | 9745 |
### Circle CCTP Domain IDs
> [!NOTE]
>
> Domain IDs are **not** the same as Chain IDs. Always use Domain IDs when calling Gas API or Cashmere contracts.
| Chain | Domain ID |
| - | - |
| **Ethereum** | 0 |
| **Avalanche** | 1 |
| **Optimism** | 2 |
| **Arbitrum** | 3 |
| **Solana** | 5 |
| **Base** | 6 |
| **Polygon** | 7 |
| **Sui** | 8 |
| **Aptos** | 9 |
| **Unichain** | 10 |
| **Linea** | 11 |
| **Sonic** | 13 |
| **Worldchain** | 14 |
| **Monad** | 15 |
| **Sei** | 16 |
| **HyperEVM** | 19 |
| **Arc** | 26 |
### LayerZero Endpoint IDs (USDT0)
| Chain | Endpoint ID |
| - | - |
| **Ethereum** | 30101 |
| **Avalanche** | 30106 |
| **Polygon** | 30109 |
| **Arbitrum** | 30110 |
| **Optimism** | 30111 |
| **Base** | 30184 |
| **Linea** | 30183 |
| **Unichain** | 30320 |
| **Worldchain** | 30319 |
| **Sei** | 30280 |
| **Sonic** | 30332 |
| **HyperEVM** | 30367 |
| **Berachain** | 30362 |
| **Ink** | 30339 |
| **Corn** | 30331 |
| **Flare** | 30295 |
| **Rootstock** | 30333 |
| **XLayer** | 30274 |
| **Plasma** | 30383 |
***
## Integration Guidelines
### Using These Addresses
1. **CCTP Transfers:** Use Cashmere CCTP contracts + Domain IDs
2. **USDT0 Transfers:** Use USDT0 OFT contracts + LayerZero Endpoint IDs
3. **NEAR Intents:** Use Treasury contracts for BNB Chain routing
4. **Token Approvals:** Approve spending to Cashmere contracts before transfers
### Important Notes
* Domain IDs ≠ Chain IDs — use Domain IDs for Gas API and contracts
* BNB Chain USDC/USDT use **18 decimals** (exception to standard 6 decimals)
* Arc's gas token is USDC, with **18 decimals** natively; its USDC ERC-20 uses the standard 6
* Solana uses base58 addresses, not hex
* Move modules (Aptos/Sui) use module paths with `::` notation
### Getting Started
* See [Quickstart](/developers/quickstart) for integration examples
* See [Smart Contracts](/developers/smart-contracts) for detailed contract interfaces
* See [Backend APIs](/developers/backend-apis) for Gas API usage
> [!TIP]
>
> Need testnet addresses or have integration questions? Contact [contact@cashmere.exchange](mailto:contact@cashmere.exchange)
# Integration Examples
Source: https://docs.cashmere.exchange/developers/integration-examples
Practical patterns for the Cashmere SDK, the Gas API and the CashmereCCTP contracts.
> [!TIP]
>
> With the [Cashmere Agent SDK](/developers/sdks), each pattern below is a call to `cctp.transfer()`: it fetches the quote, checks the recipient, approves USDC and waits for confirmation. The manual versions show what it does underneath.
## Treasury Distributor (SDK)
```ts theme={null}
import { CashmereCCTP } from '@cashmerelabs/cashmere-agent-sdk';
const cctp = new CashmereCCTP({ evm: { privateKey: process.env.EVM_PRIVATE_KEY! } });
// One transfer at a time from the same wallet, and each one confirmed before the next
for (const { to, recipient, amount } of routes) {
const { txHash, explorerUrl } = await cctp.transfer({ from: 'base', to, amount, recipient });
console.log(to, txHash, explorerUrl);
}
```
## Minimal React Hook (EVM)
```tsx theme={null}
const bridge = useCallback(async ({ amount, destinationDomain, isNative }) => {
assertWalletConnected();
// A fresh quote for every transfer: it expires about 100 seconds after it is issued
const quote = await fetchEcdsaQuote({ localDomain, destinationDomain, isV2: true, isNative });
const params = buildTransferV2Params({
amount,
destinationDomain,
quote, // fee and deadline go in unchanged: they are signed
isNative,
recipient: toBytes32(destinationAddress),
});
await ensureAllowance(params.amount);
return cashmere.transferV2(params, { value: isNative ? params.fee : 0n });
}, [provider, cashmere, usdc]);
```
*Implement `fetchEcdsaQuote`, `buildTransferV2Params` and `ensureAllowance` with your network stack, following [From Quote to Call](/developers/smart-contracts#from-quote-to-call): `gasDropAmount` 0, `hookData` `0x00`, and `maxFee` from Circle Iris.*
## Node.js Treasury Distributor (Contracts)
```ts theme={null}
async function distribute({ amount, fromDomain, routes }) {
const signer = buildSigner(fromDomain);
const cashmere = loadCashmereContract(fromDomain, signer);
const usdc = loadUsdcContract(fromDomain, signer);
// The contract pulls exactly `amount` per transfer
await (await usdc.approve(cashmere.target, amount * BigInt(routes.length))).wait();
for (const route of routes) {
const quote = await fetchEcdsaQuote({
localDomain: fromDomain,
destinationDomain: route.domain,
isV2: true,
isNative: route.isNativeFee,
});
const params = buildTransferV2Params({
amount,
destinationDomain: route.domain,
quote,
isNative: route.isNativeFee,
recipient: route.recipient,
});
const tx = await cashmere.transferV2(params, { value: route.isNativeFee ? params.fee : 0n });
await tx.wait(); // one at a time, so nonces and allowances stay in order
}
}
```
> [!NOTE]
>
> Fetch Circle's `minimumFee` for the route from `https://iris-api.circle.com/v2/burn/USDC/fees/6/3` (source and destination domain): the response is an array with one entry per `finalityThreshold`. Use `1000` from Fast sources and `2000` otherwise.
## Status Dashboard Snippet
```ts theme={null}
async function fetchRecentTransfers(address: string) {
const url = new URL('https://kapi.cashmere.exchange/transactionsmainnet');
url.searchParams.set('senders', address);
url.searchParams.set('limit', '25');
const res = await fetch(url.toString());
if (!res.ok) throw new Error('Failed to fetch transactions');
const body = await res.json();
return body.transactions.map((tx) => ({
hash: tx.source_tx_hash,
route: `${tx.source_domain} → ${tx.destination_domain}`,
amount: Number(tx.deposit_amount) / 1e6, // USDC has 6 decimals
received: tx.receive_amount == null ? null : Number(tx.receive_amount) / 1e6,
// USDC base units, or the source chain's smallest native unit (wei, lamports, octas, MIST) when paid natively.
// It is a JSON number, so wei values above 2^53 arrive rounded: fine for display, not for accounting
relayerFee: tx.is_gas_drop_in_native ? { native: tx.relayer_fee } : { usdc: Number(tx.relayer_fee) / 1e6 },
status:
tx.destination_tx_status === 'success' ? 'completed'
: tx.destination_tx_status === 'failed' ? 'failed' // see tx.destination_tx_error
: tx.confirmed ? 'in progress'
: 'pending',
}));
}
```
`confirmed` means the source transaction confirmed; the transfer is complete once `destination_tx_status` is `success`, and `failed` means the destination mint transaction failed.
## Solana Transfer (Anchor)
```ts theme={null}
const quote = await fetchEd25519Quote({ localDomain: 5, destinationDomain, isNative: isNativeFee, version: 2 });
const config = await loadCashmereConfig(connection);
const signatureIx = buildEd25519Ix(quote); // the quote's publicKey, message and signature
const transferIx = await cashmereProgram.methods.transferV2(
new BN(amount.toString()),
destinationDomain,
recipientBytes, // 32 bytes, see Recipient Encoding
solanaOwnerBytes, // 32 zero bytes unless the destination is Solana
new BN(quote.fee),
new BN(quote.deadline),
new BN(0), // gas drop is currently disabled
isNativeFee,
new BN(maxFee.toString()),
new BN(2000), // Solana sends V2 Norm
).accounts(buildAccountMap({ owner, config, destinationDomain })).instruction();
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
const tx = assembleAndSign({
payer: owner,
blockhash,
ixs: [setComputeUnits(), signatureIx, transferIx],
lookupTables: [cashmereLookupTable],
additionalSigners: [messageSentEventData], // a fresh keypair per transfer
});
const signature = await connection.sendTransaction(tx);
await connection.confirmTransaction({ signature, blockhash, lastValidBlockHeight }, 'confirmed');
```
The complete transaction is in [Smart Contracts → Solana](/developers/smart-contracts#solana-implementation).
## Sui Transfer (V2)
```ts theme={null}
const quote = await fetchEd25519Quote({ localDomain: 8, destinationDomain, isNative, version: 2 });
const tx = new Transaction();
const ids = loadSuiConstants(); // the package and object IDs from Smart Contracts → Sui
const [nativeFee] = tx.splitCoins(tx.gas, [tx.pure.u64(isNative ? quote.fee : '0')]);
const [ticket] = tx.moveCall({
target: `${ids.cashmereV2}::transfer::prepare_deposit_for_burn_v2`,
arguments: buildPrepareV2Args({ tx, quote, nativeFee, amount, recipientHex, solanaOwnerHex, maxFee, ids }),
});
const [burnReceipt, burnCoin] = tx.moveCall({
target: `${ids.tmmV2}::deposit_for_burn::deposit_for_burn_with_package_auth`,
typeArguments: [ids.usdcType, `${ids.cashmereTypes}::transfer::Auth`],
arguments: [ticket, tx.object(ids.tmmV2State)],
});
const [completeBurnTicket] = tx.moveCall({
target: `${ids.usdcHandler}::handler::burn`,
arguments: [tx.object(ids.usdcHandlerState), burnReceipt, burnCoin, tx.object('0x403'), tx.object(ids.usdcTreasury)],
});
tx.moveCall({
target: `${ids.tmmV2}::deposit_for_burn::complete_burn`,
typeArguments: [ids.usdcType, `${ids.usdcHandler}::handler::Auth`],
arguments: [completeBurnTicket, tx.object(ids.tmmV2State), tx.object(ids.mtV2State)],
});
await wallet.signAndExecuteTransaction({ transaction: tx });
```
* `recipientHex` is the destination account as 32 bytes. Into Solana, it is the wallet's USDC associated token account, with `solanaOwnerHex` set to the wallet.
* With `fee_is_native`, the fee is in MIST (9 decimals) and comes from the gas coin split.
## Aptos Transfer (ts-sdk)
```ts theme={null}
const quote = await fetchEd25519Quote({ localDomain: 9, destinationDomain, isNative, version: 2 });
const tx = await aptos.transaction.build.simple({
sender,
data: {
function: '0xe49afb1896889e3e1dd7bcbb9e31d1df8221899d3d368e98588ac6b4d84b136d::transfer::transfer_v2_outer',
typeArguments: [],
functionArguments: [
amount.toString(), isNative ? quote.fee : '0', destinationDomain, recipientHex, solanaOwnerHex,
quote.fee, quote.deadline, '0', isNative, maxFee.toString(), 2000,
Array.from(Buffer.from(quote.signature.slice(2), 'hex')),
],
},
});
const submission = await signer.signAndSubmitTransaction({ transaction: tx });
await aptos.waitForTransaction({ transactionHash: submission.hash });
```
* `recipientHex` is the destination account as 32 bytes. Into Solana, it is the wallet's USDC associated token account, with `solanaOwnerHex` set to the wallet.
* Wallets such as Pontem expect the signature as a byte array; `Array.from(Buffer.from(...))` gives one.
> [!WARNING]
>
> Quotes expire about 100 seconds after they are issued. If a quote is within about 30 seconds of its `deadline`, request a fresh one before asking the user to sign.
# Developer Quickstart
Source: https://docs.cashmere.exchange/developers/quickstart
Bridge USDC with the Cashmere SDK in a few lines, or call the Gas API and the Cashmere contracts yourself.
## Which Path?
| You want to | Use |
| - | - |
| Send USDC cross-chain from a backend, bot or script | The [Cashmere Agent SDK](/developers/sdks): one call per transfer, every chain |
| Let an AI agent (Claude, Hermes, LangChain…) quote and send transfers | The SDK's [MCP server and agent tools](/developers/agent-integration) |
| Build the transactions yourself, in another language or a wallet UI | The [Gas API](/developers/backend-apis) and the [contracts](/developers/smart-contracts), as below |
## With the SDK
Requires Node.js 22 or later.
```bash theme={null}
npm install @cashmerelabs/cashmere-agent-sdk
```
```ts theme={null}
import { CashmereCCTP } from '@cashmerelabs/cashmere-agent-sdk';
const cctp = new CashmereCCTP({ evm: { privateKey: process.env.EVM_PRIVATE_KEY! } });
// Quote first: fee, CCTP version and duration, nothing is sent
const quote = await cctp.simulate({ from: 'base', to: 'arbitrum', amount: '100' });
// Then send: the SDK fetches the signed quote, approves USDC and waits for confirmation
const { txHash, explorerUrl } = await cctp.transfer({
from: 'base',
to: 'arbitrum',
amount: '100',
recipient: '0xYourArbitrumAddress',
});
```
Destination minting is automatic: Cashmere's relayers mint the USDC to the recipient once the source transaction confirms.
## Without the SDK (EVM)
You need an RPC endpoint and a wallet holding USDC and some gas on the source chain, plus the addresses from [Contract Addresses](/developers/contract-addresses). No API key is required.
> [tab] 1. Get a Quote
>
> ```ts theme={null}
> const isNative = true; // pay the Cashmere fee in the source chain's gas token; false takes it from the USDC
>
> const response = await fetch(
> 'https://gas.cashmere.exchange/getEcdsaSig_native?' +
> new URLSearchParams({
> localDomain: '6', // Base
> destinationDomain: '3', // Arbitrum
> isV2: 'true', // transferV2
> isNative: String(isNative),
> })
> );
> if (!response.ok) throw new Error(`Gas API error ${response.status}`);
> const quote = await response.json(); // { fee, deadline, signature, isNative, cctpVersion }
> ```
>
> The quote is valid for about 100 seconds. Its `fee` and `deadline` are signed: pass them unchanged.
> [tab] 2. Build Params
>
> ```ts theme={null}
> import { zeroPadValue, parseUnits, ZeroHash } from 'ethers';
>
> const amount = parseUnits('100', 6); // USDC has 6 decimals
>
> // Circle's fee for V2 Fast (threshold 1000), in basis points, possibly fractional such as 1.3
> const circleFees = await fetch('https://iris-api.circle.com/v2/burn/USDC/fees/6/3').then(r => r.json());
> const { minimumFee } = circleFees.find((f: { finalityThreshold: number }) => f.finalityThreshold === 1000);
> const maxFee = (amount * BigInt(Math.ceil(minimumFee * 10)) + 99_999n) / 100_000n; // rounded up
>
> const params = {
> amount,
> maxFee,
> fee: BigInt(quote.fee),
> deadline: BigInt(quote.deadline),
> gasDropAmount: 0n, // gas drop is disabled
> destinationDomain: 3,
> minFinalityThreshold: 1000, // V2 Fast; 2000 from chains without Fast
> recipient: zeroPadValue(recipientAddress, 32),
> solanaOwner: ZeroHash, // only used when sending to Solana
> isNative,
> hookData: '0x00', // must be non-empty: Circle rejects 0x
> signature: quote.signature,
> };
> ```
>
> > [!NOTE]
> >
> > Bridging into Solana (`destinationDomain = 5`)? Set `recipient` to the destination wallet's USDC associated token account (ATA) and `solanaOwner` to the wallet, both as 32-byte hex. Cashmere's relayers create the ATA if it doesn't exist. See [Recipient Encoding](/developers/smart-contracts#recipient-encoding).
> [tab] 3. Send
>
> ```ts theme={null}
> import { ethers } from 'ethers';
>
> const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
> const signer = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);
> const cashmere = new ethers.Contract(CASHMERE_CCTP_ADDRESS, CASHMERE_ABI, signer);
> const usdc = new ethers.Contract(USDC_ADDRESS, ['function approve(address,uint256) returns (bool)'], signer);
>
> // The contract pulls `amount` and takes its fee out of it
> await (await usdc.approve(CASHMERE_CCTP_ADDRESS, params.amount)).wait();
>
> const tx = await cashmere.transferV2(params, { value: params.isNative ? params.fee : 0n });
> const receipt = await tx.wait();
> if (receipt?.status !== 1) throw new Error('transfer reverted');
> ```
> [!NOTE]
>
> **Units**\\
>
> `amount` and `maxFee` are USDC base units (6 decimals). The quote's `fee` is USDC base units when `isNative=false`, and otherwise the source chain's smallest native unit: wei on EVM chains (18), lamports on Solana (9), MIST on Sui (9), octas on Aptos (8).
***
## Without the SDK (Solana)
1. Request the quote from `/getEd25519Sig_native` with `localDomain=5` and `version=2`. Always pass `version`: without it the signed message has no version byte and the program rejects it.
2. Encode the recipient as 32 bytes (see [Recipient Encoding](/developers/smart-contracts#recipient-encoding)).
3. Put an `Ed25519Program` instruction with the quote's `publicKey`, `message` and `signature` right before `transfer_v2`, in one `VersionedTransaction` that uses the Cashmere lookup table `865YCTTsymGpBjLMTvjd3T3RCGT8yvxnAHhyKZqRFfLi`.
4. Pass the quote's `fee` and `deadline` unchanged, `max_fee` from Circle Iris and `min_finality_threshold = 2000` (Solana sends V2 Norm).
```ts theme={null}
import { Ed25519Program } from '@solana/web3.js';
const quote = await fetch(
'https://gas.cashmere.exchange/getEd25519Sig_native?localDomain=5&destinationDomain=6&isNative=true&version=2',
).then(r => r.json());
const ed25519Ix = Ed25519Program.createInstructionWithPublicKey({
publicKey: Buffer.from(quote.publicKey.slice(2), 'hex'),
message: Buffer.from(quote.message.slice(2), 'hex'),
signature: Buffer.from(quote.signature.slice(2), 'hex'),
});
```
The full transaction is in [Smart Contracts → Solana](/developers/smart-contracts#solana-implementation).
## Without the SDK (Aptos)
1. Request the quote with `localDomain=9` and `version=2`.
2. Call `transfer_v2_outer` on `0xe49afb1896889e3e1dd7bcbb9e31d1df8221899d3d368e98588ac6b4d84b136d::transfer` with the quote's `fee` and `deadline`, `max_fee` from Circle Iris, `min_finality_threshold = 2000` and the signature as a byte array.
The full payload is in [Smart Contracts → Aptos](/developers/smart-contracts#aptos-implementation).
## Without the SDK (Sui)
1. Request the quote with `localDomain=8` and `version=2`.
2. In one transaction, call `prepare_deposit_for_burn_v2` on package `0x7eab670b…`, then Circle's `deposit_for_burn_with_package_auth`, the USDC handler's `burn` and `complete_burn`.
The full transaction, with every object ID, is in [Smart Contracts → Sui](/developers/smart-contracts#sui-implementation).
***
## Monitor the Outcome
The transactions API lists transfers with their source and destination status:
```bash theme={null}
curl "https://kapi.cashmere.exchange/transactionsmainnet?senders=0xYourAddress&limit=20"
```
A transfer is complete when its destination status is `success`. See [Backend APIs](/developers/backend-apis) for every field.
## Next Steps
* [Backend APIs](/developers/backend-apis): the Gas API and transactions API in detail.
* [Smart Contracts](/developers/smart-contracts): per-chain entry points, signed payloads and errors.
* [Agent Integration](/developers/agent-integration): the MCP server, the agent skill and framework tools.
# SDK Options
Source: https://docs.cashmere.exchange/developers/sdks
The Cashmere Agent SDK for TypeScript, and Gas API helpers for integrating from other languages.
## Cashmere Agent SDK
The official TypeScript SDK for programmatic and AI-agent-driven USDC transfers. It requires Node.js 22 or later.
```bash theme={null}
npm install @cashmerelabs/cashmere-agent-sdk
```
```ts theme={null}
import { CashmereCCTP } from '@cashmerelabs/cashmere-agent-sdk';
const cctp = new CashmereCCTP({
evm: { privateKey: process.env.EVM_PRIVATE_KEY! },
});
// Quote first: route, CCTP version, fee and duration; nothing is sent
const sim = await cctp.simulate({ from: 'ethereum', to: 'arbitrum', amount: '100' });
// Then send: the SDK fetches the signed quote, approves USDC and waits for confirmation
const { txHash, explorerUrl } = await cctp.transfer({
from: 'ethereum',
to: 'arbitrum',
amount: '100',
recipient: '0xDestinationAddress',
});
```
The SDK covers 17 chains (14 EVM chains, Solana, Aptos and Sui) and sends every route over CCTP V2. It also ships an MCP server, an agent skill for payments, and tool schemas for [OpenAI, LangChain, Hermes and other frameworks](/developers/agent-integration).
Configure only the chains you send from. Paste each key as the wallet exports it:
| Option | Source chains | Key format |
| - | - | - |
| `evm` | Every EVM chain | Hex, as MetaMask exports it |
| `solana` | Solana | Base58 (Phantom, Solflare) or the JSON byte array from `solana-keygen` |
| `aptos` | Aptos | Hex or `ed25519-priv-0x…` (Petra) |
| `sui` | Sui | `suiprivkey1…` (Slush, Sui Wallet) or hex |
Each option also takes an optional `rpcUrl`. Load keys from the environment or a secret manager, never from source code.
> [!NOTE]
>
> The [Agent Integration](/developers/agent-integration) guide covers the MCP server (Claude Desktop, Claude Code, Hermes Agent), the agent skill and framework setup (LangChain, OpenAI function calling, Hermes, crewAI).
***
## Direct Integration (No SDK)
Call the contracts yourself when the user signs in their own wallet (a dApp or wallet UI), or when your backend isn't written in TypeScript:
1. Fetch a signed fee quote from the [Gas API](/developers/backend-apis#gas-api-gas-cashmere-exchange).
2. Pass it to the [`CashmereCCTP` contracts](/developers/smart-contracts), as described in [From Quote to Call](/developers/smart-contracts#from-quote-to-call).
3. Track each transfer with the [Transaction APIs](/developers/backend-apis#transaction-apis-kapi-cashmere-exchange).
The [Developer Quickstart](/developers/quickstart#without-the-sdk-evm) walks through all three on EVM.
***
## Helper Snippets
Each helper fetches a quote for the V2 entry points. A quote is valid for about 100 seconds, and its `fee` and `deadline` are signed: pass them to the contract unchanged. Always send `isNative`: the Gas API answers HTTP 500 without it.
### TypeScript (EVM)
```ts theme={null}
/**
* Fetches a signed fee quote for CashmereCCTP.transferV2.
*/
export async function getTransferV2Quote({
localDomain,
destinationDomain,
isNative,
}: {
localDomain: number;
destinationDomain: number;
isNative: boolean;
}) {
const res = await fetch(
'https://gas.cashmere.exchange/getEcdsaSig_native?' +
new URLSearchParams({
localDomain: String(localDomain),
destinationDomain: String(destinationDomain),
isV2: 'true',
isNative: String(isNative),
}),
{ signal: AbortSignal.timeout(15_000) },
);
if (!res.ok) throw new Error(`Gas API error ${res.status}`);
return (await res.json()) as {
fee: string; // wei when isNative, otherwise USDC base units (6 decimals)
deadline: string; // unix seconds
signature: string; // 65-byte ECDSA signature, 0x-prefixed
isNative: boolean;
cctpVersion: number;
};
}
```
### Go (EVM)
```go theme={null}
package cashmere
import (
"encoding/json"
"fmt"
"net/http"
"time"
)
type EcdsaQuote struct {
Fee string `json:"fee"` // wei when IsNative, otherwise USDC base units
Deadline string `json:"deadline"` // unix seconds
Signature string `json:"signature"` // 65 bytes, 0x-prefixed
IsNative bool `json:"isNative"`
CctpVersion int `json:"cctpVersion"`
}
var client = &http.Client{Timeout: 15 * time.Second}
func GetECDSAQuote(local, dest uint32, isNative bool) (*EcdsaQuote, error) {
url := fmt.Sprintf(
"https://gas.cashmere.exchange/getEcdsaSig_native?localDomain=%d&destinationDomain=%d&isV2=true&isNative=%t",
local, dest, isNative,
)
resp, err := client.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("gas API returned status %s", resp.Status)
}
var quote EcdsaQuote
if err := json.NewDecoder(resp.Body).Decode("e); err != nil {
return nil, err
}
return "e, nil
}
```
### Rust (Solana, Aptos, Sui)
```rust theme={null}
// Cargo.toml: anyhow = "1", serde = { version = "1", features = ["derive"] },
// reqwest = { version = "0.12", features = ["json"] }
use anyhow::{bail, Result};
use serde::Deserialize;
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Ed25519Quote {
pub signature: String, // 64 bytes, 0x-prefixed
pub message: String, // the signed bytes, 0x-prefixed
pub public_key: String, // 32 bytes, 0x-prefixed
pub destination_domain: String,
pub fee: String, // the native unit when is_native, otherwise USDC base units
pub deadline: String, // unix seconds
pub is_native: bool,
pub version: u8,
}
pub async fn get_ed25519_quote(local: u32, dest: u32, is_native: bool) -> Result {
let url = format!(
"https://gas.cashmere.exchange/getEd25519Sig_native?localDomain={local}&destinationDomain={dest}&isNative={is_native}&version=2"
);
let resp = reqwest::get(&url).await?;
if !resp.status().is_success() {
bail!("gas api error: {}", resp.status());
}
Ok(resp.json::().await?)
}
```
`local` is 5 on Solana, 9 on Aptos and 8 on Sui. Keep `version=2`: without it the message has no version byte and the V2 entry points reject the signature. Native fees are lamports on Solana, octas on Aptos and MIST on Sui. [Signed Payloads](/developers/smart-contracts#signed-payloads) shows what each chain verifies.
***
## Resources
* [cashmere-agent-sdk on GitHub](https://github.com/cashmere-prod/cashmere-agent-sdk): source code, issues, README and SKILL.md
* [@cashmerelabs/cashmere-agent-sdk on npm](https://www.npmjs.com/package/@cashmerelabs/cashmere-agent-sdk): the published package
* [Agent Integration](/developers/agent-integration): the MCP server, the agent skill, and LangChain, OpenAI, Hermes and crewAI setup
* [Contract Addresses](/developers/contract-addresses): every deployed address
* [Backend APIs](/developers/backend-apis): the Gas API and the transaction APIs
# Smart Contracts
Source: https://docs.cashmere.exchange/developers/smart-contracts
Call the Cashmere CCTP contracts directly: V2 entry points, signed quotes, a working example per chain, errors and events.
## Overview
CashmereCCTP wraps Circle's CCTP on every supported chain: the contract takes Cashmere's fee, burns the USDC through Circle and emits a `CashmereTransfer` event. Cashmere's relayers then mint on the destination chain, so a transfer is a single source-chain transaction.
> [!TIP]
>
> Most integrations don't need this page. The [Cashmere Agent SDK](/developers/sdks) builds and sends every transaction below (`cctp.transfer()`), and its [MCP server](/developers/agent-integration#mcp-server) exposes them to AI agents. Read on to call the contracts yourself; the SDK's `src/chains/*.ts` is a tested reference implementation of each flow.
> [!WARNING]
>
> Use CCTP V2. Circle cuts V1 burn limits from 31 Oct 2026 and stops V1 burns on 1 Dec 2026. Every route has V2, Aptos and Sui included since 26 Oct 2026. The V1 entry points are listed for reference only.
> [!NOTE]
>
> **Contract Repository:** [GitHub - cashmere-prod/contracts-prod](https://github.com/cashmere-prod/contracts-prod). Addresses for every chain are on [Contract Addresses](/developers/contract-addresses).
```
contracts-prod/
├── evm/src/CashmereCCTP.sol # Solidity (EVM chains), with the Circle interfaces in evm/src/circle/
├── solana/programs/cashmere_cctp/ # Rust/Anchor (Solana)
├── aptos/sources/transfer.move # Move (Aptos)
└── sui/sources/transfer.move # Move (Sui)
```
## Entry Points
| Chain | V2 (use this) | V1 (legacy) |
| - | - | - |
| **EVM** | `transferV2`, `transferV2WithPermit` | `transfer`, `transferWithPermit` |
| **Solana** | `transfer_v2` | `transfer` |
| **Aptos** | `transfer_v2_outer` (entry function), `transfer_v2` (takes your own `FungibleAsset` and `Coin`) | `transfer_outer`, `transfer` |
| **Sui** | `prepare_deposit_for_burn_v2` on package `0x7eab670b…`, then Circle's package-auth calls | `prepare_deposit_for_burn_ticket`, `post_deposit_for_burn` |
## From Quote to Call
Every transfer carries a quote signed by the Cashmere Gas API. The quote's `fee` and `deadline` are part of the signed message, so pass them exactly as returned: any other value fails the signature check.
1. **Get a quote** for the route ([Backend APIs](/developers/backend-apis)):
* EVM sources: `GET https://gas.cashmere.exchange/getEcdsaSig_native?localDomain=6&destinationDomain=3&isNative=true&isV2=true`
* Solana, Aptos and Sui sources: `GET https://gas.cashmere.exchange/getEd25519Sig_native?localDomain=9&destinationDomain=6&isNative=true&version=2`
2. **Get Circle's fee** for the finality threshold: `GET https://iris-api.circle.com/v2/burn/USDC/fees/6/3` returns an array of `finalityThreshold` and `minimumFee` (basis points, possibly fractional, such as `1.3`).
3. **Call the V2 entry point** with these values:
| Parameter | Value |
| - | - |
| `fee`, `deadline` | From the quote, unchanged. Quotes expire about 100 seconds after they are issued |
| `isNative` / `fee_is_native` | The value you requested the quote with: the fee is then paid in the source chain's gas token instead of USDC |
| `gasDropAmount` | `0`: gas drop is currently disabled |
| `minFinalityThreshold` | `1000` (V2 Fast) from Ethereum, Arbitrum, Base, Optimism, Unichain, Linea and World Chain; `2000` (V2 Norm) from every other chain |
| `maxFee` | `ceil(amount × ceil(minimumFee × 10) / 100000)` for that threshold, in USDC base units: Circle keeps up to this much on mint |
| `hookData` (EVM) | `0x00`. Circle rejects empty hook data, so `0x` reverts |
| Native value | `fee` when `isNative` is true (EVM `msg.value`, Aptos `native_amount`, Sui gas coin split), otherwise `0` |
| `recipient`, `solanaOwner` | See [Recipient Encoding](#recipient-encoding) |
**What arrives.** The contract takes `amount × feeBP / 10000` from the USDC (`feeBP` is 0 today, at most 100, that is 1%), plus the quoted `fee` when `isNative` is false. On V2 Fast, Circle keeps up to `maxFee` when it mints. The recipient gets the rest.
## Signed Payloads
The Gas API signs the same fields on every chain: local domain, destination domain, fee, deadline, `isNative` and the CCTP version. A V1 signature therefore never passes a V2 entry point, and the other way round.
**EVM** checks an ECDSA signature over the raw digest (no `\x19Ethereum Signed Message` prefix):
```solidity theme={null}
bytes32 digest = keccak256(abi.encodePacked(
uint32(localDomain), // set from Circle's MessageTransmitter
uint32(destinationDomain),
uint128(fee),
uint64(deadline),
bool(isNative),
uint8(2) // 1 for transfer, 2 for transferV2
));
```
**Solana** checks an Ed25519 signature over the Borsh encoding below, through an Ed25519 program instruction placed before the transfer instruction. Always request Solana quotes with `version=1` or `version=2`: without it the message has no version byte and the program rejects it (`InvalidMessageData`).
```rust theme={null}
struct TransferMessage {
cctp_version: u8, // 2 for transfer_v2
local_domain: u32, // 5
destination_domain: u32,
fee: u64,
deadline: u64,
fee_is_native: bool,
}
```
**Aptos and Sui** check an Ed25519 signature over the BCS encoding of `TransferParamsV2` (`TransferParams` without `cctp_version` for V1). Request their quotes with `version=2`.
```move theme={null}
struct TransferParamsV2 has drop, copy {
cctp_version: u8, // 2
local_domain: u32, // 9 on Aptos, 8 on Sui
destination_domain: u32,
fee: u64,
deadline: u64,
fee_is_native: bool,
}
```
On the Ed25519 endpoint the `message` field of the quote is exactly these bytes, and `publicKey` is the signer key that the contracts store.
## Recipient Encoding
Every chain takes the recipient as 32 bytes, and CCTP mints to whatever account those bytes name. An address in the wrong format doesn't revert: the USDC arrives at an account nobody controls. The SDK's `recipientError(to, recipient)` checks a recipient before you sign.
* **To an EVM chain:** the 20-byte address, left-padded to 32 bytes (`ethers.zeroPadValue(address, 32)`).
* **To Solana (domain 5):** `recipient` is the wallet's USDC associated token account (ATA) and `solanaOwner` is the wallet itself, both as 32-byte hex. Cashmere's relayers create the ATA if it doesn't exist yet.
* **To Aptos or Sui:** the 32-byte account address (`0x` and 64 hex characters). An EVM address padded to 32 bytes is not an Aptos or Sui account.
* **`solanaOwner`** is 32 zero bytes for every destination other than Solana.
```ts theme={null}
import bs58 from 'bs58';
import { PublicKey } from '@solana/web3.js';
import { getAssociatedTokenAddressSync } from '@solana/spl-token';
const SOLANA_USDC = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');
const toHex = (key: PublicKey) => `0x${Buffer.from(key.toBytes()).toString('hex')}`;
// Into Solana: the wallet's USDC token account as recipient, the wallet as solanaOwner
export function solanaRecipient(wallet: string) {
const owner = new PublicKey(wallet);
return { recipient: toHex(getAssociatedTokenAddressSync(SOLANA_USDC, owner, true)), solanaOwner: toHex(owner) };
}
// From Solana: Anchor takes the 32-byte recipient as a number array
export const evmRecipientBytes = (address: string) =>
Array.from(Buffer.from(address.slice(2).padStart(64, '0'), 'hex'));
```
## EVM Implementation
### Interface
```solidity theme={null}
interface ICashmereCCTP {
struct TransferV2Params {
uint64 amount; // USDC, 6 decimals
uint256 maxFee; // Circle fee cap, USDC base units
uint128 fee; // from the quote: USDC base units, or wei when isNative
uint64 deadline; // from the quote
uint128 gasDropAmount; // 0
uint32 destinationDomain;
uint32 minFinalityThreshold; // 1000 Fast, 2000 Norm
bytes32 recipient;
bytes32 solanaOwner;
bool isNative;
bytes hookData; // 0x00
bytes signature; // 65-byte ECDSA signature from the quote
}
struct PermitParams {
uint256 value; // the transfer amount
uint256 deadline; // the permit's own deadline
bytes signature; // EIP-2612 permit signature
}
function transferV2(TransferV2Params memory _params) payable external;
function transferV2WithPermit(TransferV2Params memory _params, PermitParams memory _permitParams) payable external;
// V1 (legacy): transfer and transferWithPermit take TransferParams, the same fields without
// maxFee, minFinalityThreshold and hookData
function getFee(uint64 _amount, uint256 _staticFee) external view returns (uint64);
}
```
### TransferV2
```ts theme={null}
import { ethers } from 'ethers';
// Base (domain 6) to Arbitrum (domain 3), fee paid in ETH
const quote = await fetch(
'https://gas.cashmere.exchange/getEcdsaSig_native?localDomain=6&destinationDomain=3&isNative=true&isV2=true',
).then(r => r.json());
const circleFees = await fetch('https://iris-api.circle.com/v2/burn/USDC/fees/6/3').then(r => r.json());
const fast = circleFees.find((f: { finalityThreshold: number }) => f.finalityThreshold === 1000);
const amount = ethers.parseUnits('100', 6);
const params = {
amount,
maxFee: (amount * BigInt(Math.ceil(fast.minimumFee * 10)) + 99_999n) / 100_000n,
fee: BigInt(quote.fee),
deadline: BigInt(quote.deadline),
gasDropAmount: 0n,
destinationDomain: 3,
minFinalityThreshold: 1000,
recipient: ethers.zeroPadValue(recipientAddress, 32),
solanaOwner: ethers.ZeroHash,
isNative: true,
hookData: '0x00',
signature: quote.signature,
};
// The contract pulls `amount` of USDC and takes its fee out of it
await (await usdc.approve(CASHMERE_CCTP_ADDRESS, amount)).wait();
const tx = await cashmere.transferV2(params, { value: params.isNative ? params.fee : 0n });
const receipt = await tx.wait();
if (receipt?.status !== 1) throw new Error('transfer reverted');
```
### TransferV2WithPermit
Skip the approval transaction with an EIP-2612 permit for the same amount:
```ts theme={null}
const permitParams = {
value: params.amount,
deadline: BigInt(Math.floor(Date.now() / 1000) + 600),
signature: permitSignature, // 65-byte EIP-2612 signature from the user's wallet
};
const tx = await cashmere.transferV2WithPermit(params, permitParams, { value: params.isNative ? params.fee : 0n });
await tx.wait();
```
### Security Features
* **Reentrancy:** a lock flag in the contract state guards every transfer and fee withdrawal.
* **Signed quotes:** the fee, deadline, route and version are signed by the Cashmere signer and checked on chain.
* **Fee cap:** the percentage fee is at most 100 basis points (1%); it is 0 today.
* **Pause:** the admin can pause transfers.
## Solana Implementation
> [!NOTE]
>
> Program ID `5RsvKL6LFq6yEFiAXEwgYHAN3aLFypeB4AaafdeDnHqM`, domain `5`. Account addresses, the address lookup table and the CCTP program IDs are on [Contract Addresses](/developers/contract-addresses).
```rust theme={null}
pub fn transfer_v2(
ctx: Context,
usdc_amount: u64,
destination_domain: u32,
recipient: [u8; 32],
solana_owner: [u8; 32],
fee: u64,
deadline: u64,
gas_drop_amount: u64,
fee_is_native: bool,
max_fee: u64,
min_finality_threshold: u32,
) -> Result<()>
```
The transaction needs three instructions in this order: a compute budget, the Ed25519 verification of the quote, and `transfer_v2`. `transfer_v2` also needs a fresh keypair that signs as `messageSentEventData`, where Circle stores the burn message.
```ts theme={null}
import { BN, Program } from '@coral-xyz/anchor';
import { ComputeBudgetProgram, Ed25519Program, Keypair, TransactionMessage, VersionedTransaction } from '@solana/web3.js';
// Solana (5) to Base (6), fee paid in SOL; Solana sends V2 Norm
const quote = await fetch(
'https://gas.cashmere.exchange/getEd25519Sig_native?localDomain=5&destinationDomain=6&isNative=true&version=2',
).then(r => r.json());
const bytes = (hex: string) => Buffer.from(hex.slice(2), 'hex');
const program = new Program(idl, provider); // Anchor 0.30: the IDL carries the program ID
const messageSentEventData = Keypair.generate();
const transferIx = await program.methods
.transferV2(new BN(amount), 6, evmRecipientBytes(recipient), new Array(32).fill(0),
new BN(quote.fee), new BN(quote.deadline), new BN(0), true, new BN(maxFee.toString()), 2000)
.accounts({ /* the accounts in src/chains/solana.ts of the SDK */ messageSentEventData: messageSentEventData.publicKey })
.instruction();
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
const tx = new VersionedTransaction(new TransactionMessage({
payerKey: wallet.publicKey,
recentBlockhash: blockhash,
instructions: [
ComputeBudgetProgram.setComputeUnitLimit({ units: 160_000 }),
Ed25519Program.createInstructionWithPublicKey({
publicKey: bytes(quote.publicKey),
message: bytes(quote.message),
signature: bytes(quote.signature),
}),
transferIx,
],
}).compileToV0Message([lookupTable]));
tx.sign([wallet, messageSentEventData]);
const signature = await connection.sendTransaction(tx);
const { value } = await connection.confirmTransaction({ signature, blockhash, lastValidBlockHeight }, 'confirmed');
if (value.err) throw new Error(`transfer failed: ${JSON.stringify(value.err)}`);
```
## Aptos Implementation
> [!NOTE]
>
> Module `0xe49afb1896889e3e1dd7bcbb9e31d1df8221899d3d368e98588ac6b4d84b136d::transfer`, domain `9`. Aptos sends V2 Norm (`min_finality_threshold = 2000`).
```move theme={null}
public entry fun transfer_v2_outer(
sender: &signer,
usdc_amount: u64,
native_amount: u64, // the fee when fee_is_native, otherwise 0
destination_domain: u32,
recipient: address,
solana_owner: address,
fee: u64,
deadline: u64,
gas_drop_amount: u64, // 0
fee_is_native: bool,
max_fee: u64,
min_finality_threshold: u32,
signature: vector
)
```
```ts theme={null}
import { Aptos, AptosConfig, Network } from '@aptos-labs/ts-sdk';
const aptos = new Aptos(new AptosConfig({ network: Network.MAINNET }));
const quote = await fetch(
'https://gas.cashmere.exchange/getEd25519Sig_native?localDomain=9&destinationDomain=6&isNative=true&version=2',
).then(r => r.json());
const transaction = await aptos.transaction.build.simple({
sender: account.accountAddress,
data: {
function: '0xe49afb1896889e3e1dd7bcbb9e31d1df8221899d3d368e98588ac6b4d84b136d::transfer::transfer_v2_outer',
typeArguments: [],
functionArguments: [
amount.toString(), // usdc_amount
quote.fee, // native_amount (fee_is_native is true)
6, // destination_domain: Base
recipientHex, // 32-byte recipient
'0x0', // solana_owner
quote.fee,
quote.deadline,
'0', // gas_drop_amount
true, // fee_is_native
maxFee.toString(),
2000, // min_finality_threshold
Array.from(Buffer.from(quote.signature.slice(2), 'hex')),
],
},
});
const pending = await aptos.signAndSubmitTransaction({ signer: account, transaction });
const result = await aptos.waitForTransaction({ transactionHash: pending.hash });
if (!result.success) throw new Error(result.vm_status);
```
The module withdraws `usdc_amount` and burns it minus the USDC fee.
## Sui Implementation
> [!NOTE]
>
> Calls go to the upgraded package `0x7eab670b3f3e3bb7a0451c7c6b6b627c09e282f0c78eac24966f6479c649d0d5`; its types keep the original package ID `0xdf37112aacb7d3535f7b3b754b9a7b9fa1a6b3a756288dc734522c603c6f11a4`. Domain `8`. Sui sends V2 Norm (`min_finality_threshold = 2000`).
```move theme={null}
public fun prepare_deposit_for_burn_v2(
usdc_coin: Coin,
native_fee_coin: Coin, // the fee in SUI when fee_is_native, otherwise a zero coin
destination_domain: u32,
recipient: address,
solana_owner: address,
fee: u64,
deadline: u64,
gas_drop_amount: u64, // 0
fee_is_native: bool,
max_fee: u256,
min_finality_threshold: u32,
signature: vector,
config: &mut Config,
clock: &Clock,
ctx: &mut TxContext,
): DepositForBurnWithPackageAuthTicket
```
V2 runs Circle's package-auth flow in one transaction: Cashmere takes its fee and returns a ticket, TokenMessengerMinter V2 turns it into a burn receipt, the USDC handler burns the coin, and `complete_burn` sends the message. The ticket and receipts can't be stored or dropped, so the four calls must share a transaction.
```ts theme={null}
import { Transaction, coinWithBalance } from '@mysten/sui/transactions';
const CASHMERE_V2 = '0x7eab670b3f3e3bb7a0451c7c6b6b627c09e282f0c78eac24966f6479c649d0d5';
const CASHMERE_TYPES = '0xdf37112aacb7d3535f7b3b754b9a7b9fa1a6b3a756288dc734522c603c6f11a4';
const CASHMERE_CONFIG = '0x5f1b2e205777713f44a99894d98e1e66e33dc11ff88e50108c94ee79b7ea3d67';
const TMM_V2 = '0xeb14978abfe93a37c5d5bf86a0623b923553a5f0e794daac7724f1e2fdbfb830';
const TMM_V2_STATE = '0x06fb166941cd7bc095edc019d054a753ec3f1e4c25f28f2ecc4a6cfa0a9b1167';
const MT_V2_STATE = '0x0c067f7d325e5b60e3179712e7783534ba1556cbb3d359d8161497e37689230c';
const USDC_HANDLER = '0x185ed207c4d64fc594882ab927f9f3c6ff957aad03df8a731ba64378faeeb2bf';
const USDC_HANDLER_STATE = '0xa32de8a6dd0178fb05f662929d55cddb69a25c26bde4b83f89e36d17ead94c41';
const USDC_TREASURY = '0x57d6725e7a8b49a7b2a612f6bd66ab5f39fc95332ca48be421c3229d514a6de7';
const USDC_TYPE = '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC';
// Sui (8) to Base (6), fee paid in SUI
const quote = await fetch(
'https://gas.cashmere.exchange/getEd25519Sig_native?localDomain=8&destinationDomain=6&isNative=true&version=2',
).then(r => r.json());
const tx = new Transaction();
const [nativeFee] = tx.splitCoins(tx.gas, [tx.pure.u64(quote.fee)]);
const [ticket] = tx.moveCall({
target: `${CASHMERE_V2}::transfer::prepare_deposit_for_burn_v2`,
arguments: [
coinWithBalance({ type: USDC_TYPE, balance: amount }), nativeFee,
tx.pure.u32(6), tx.pure.address(recipientHex), tx.pure.address('0x0'),
tx.pure.u64(quote.fee), tx.pure.u64(quote.deadline), tx.pure.u64(0), tx.pure.bool(true),
tx.pure.u256(maxFee), tx.pure.u32(2000),
tx.pure.vector('u8', Array.from(Buffer.from(quote.signature.slice(2), 'hex'))),
tx.object(CASHMERE_CONFIG), tx.object('0x6'),
],
});
const [burnReceipt, burnCoin] = tx.moveCall({
target: `${TMM_V2}::deposit_for_burn::deposit_for_burn_with_package_auth`,
typeArguments: [USDC_TYPE, `${CASHMERE_TYPES}::transfer::Auth`],
arguments: [ticket, tx.object(TMM_V2_STATE)],
});
const [completeBurnTicket] = tx.moveCall({
target: `${USDC_HANDLER}::handler::burn`,
arguments: [tx.object(USDC_HANDLER_STATE), burnReceipt, burnCoin, tx.object('0x403'), tx.object(USDC_TREASURY)],
});
tx.moveCall({
target: `${TMM_V2}::deposit_for_burn::complete_burn`,
typeArguments: [USDC_TYPE, `${USDC_HANDLER}::handler::Auth`],
arguments: [completeBurnTicket, tx.object(TMM_V2_STATE), tx.object(MT_V2_STATE)],
});
const result = await client.signAndExecuteTransaction({ signer: keypair, transaction: tx });
if (result.$kind === 'FailedTransaction') {
throw new Error(result.FailedTransaction.status.error?.message ?? 'transfer failed');
}
```
`client` is a `SuiGrpcClient` from `@mysten/sui/grpc`: Sui fullnodes no longer serve JSON-RPC.
## Domain IDs
Circle CCTP domain IDs differ from chain IDs. Use them in every Gas API request and contract call.
| Chain | Domain | V2 Fast source |
| - | - | - |
| Ethereum | 0 | Yes |
| Avalanche | 1 | No |
| Optimism | 2 | Yes |
| Arbitrum | 3 | Yes |
| Solana | 5 | No |
| Base | 6 | Yes |
| Polygon | 7 | No |
| Sui | 8 | No |
| Aptos | 9 | No |
| Unichain | 10 | Yes |
| Linea | 11 | Yes |
| Sonic | 13 | No |
| Worldchain | 14 | Yes |
| Monad | 15 | No |
| Sei | 16 | No |
| HyperEVM | 19 | No |
| Arc | 26 | No |
Every chain can send V2 Norm to every other chain, and receive V2 Fast from the Fast sources.
## Chain IDs
| Chain | Chain ID |
| - | - |
| Ethereum | 1 |
| Avalanche | 43114 |
| Polygon | 137 |
| Arbitrum | 42161 |
| Optimism | 10 |
| Base | 8453 |
| Unichain | 130 |
| Linea | 59144 |
| Worldchain | 480 |
| Sei | 1329 |
| Sonic | 146 |
| HyperEVM | 999 |
| Monad | 143 |
| Arc | 5042 |
## Error Codes
### EVM
| Error | Meaning |
| - | - |
| `InvalidSignature()` | The quote's signature doesn't match its fields (a changed fee, deadline, route or version) |
| `InvalidSignatureLength()` | The signature is not 65 bytes |
| `DeadlineExpired()` | The quote's deadline has passed: request a new quote |
| `FeeExceedsAmount()` | The USDC fee is larger than the amount |
| `NativeAmountTooLow()` | `msg.value` is below the native fee |
| `NativeTransferFailed()` | Returning the extra native value failed |
| `GasDropLimitExceeded()` | `gasDropAmount` is above the limit (pass 0) |
| `TransferFailed()` | Pulling the USDC failed: check the balance and approval |
| `ReentrancyError()` | A re-entrant call |
| `Paused()` | Transfers are paused |
`BPTooHigh()`, `ZeroLimit()`, `WithdrawCooldownNotPassed()` and `WithdrawLimitExceeded()` come from admin functions.
### Solana
Anchor numbers each error enum from 6000, so the same code can mean different errors: identify them by name in the transaction logs.
| Error | Meaning |
| - | - |
| `NotSigVerified`, `InvalidSignatureData`, `InvalidDataFormat`, `LessDataThanExpected` | The Ed25519 instruction is missing, malformed or not directly before the transfer |
| `InvalidMessageData` | The signed message doesn't match the call (wrong fields, or a quote requested without `version`) |
| `InvalidSignature` | The quote was not signed by the program's signer key |
| `DeadlineExpired` | The quote's deadline has passed |
| `FeeExceedsAmount`, `NativeAmountTooLow` | Not enough USDC or SOL for the fee |
| `GasDropLimitExceeded` | Pass a gas drop of 0 |
| `InvalidDomain` | The destination domain is out of range |
| `Paused` | Transfers are paused |
### Aptos and Sui
| Abort code | Aptos | Sui |
| - | - | - |
| `0x1000` | Wrong signature | Wrong signature |
| `0x1001` | Deadline expired | Deadline expired |
| `0x1002` | Gas drop limit exceeded | Gas drop limit exceeded |
| `0x1003` | Fee exceeds amount | Fee exceeds amount |
| `0x1004` | Native fee too low | Native fee too low |
| `0x1005` | Paused | Duplicate nonce |
| `0x1006` | Fee basis points above the maximum | Paused |
## Events
Every chain emits a `CashmereTransfer` event with the same fields, which Cashmere's relayers and indexers read:
```solidity theme={null}
event CashmereTransfer(
uint32 destinationDomain,
uint256 indexed nonce,
bytes32 recipient,
bytes32 solanaOwner,
address indexed user,
uint64 amount,
uint256 gasDropAmount,
bool isNative
);
```
## Admin Functions
Integrators never call these: they set the fee, the signer, the gas-drop limits and the pause flag, and withdraw collected fees. On EVM they are restricted to `DEFAULT_ADMIN_ROLE` (`setFeeBP`, `setSigner`, `setMaxUSDCGasDrop`, `setMaxNativeGasDrop`, `setPaused`, `withdrawFee`); Solana, Aptos and Sui have the equivalent owner-only instructions.
## Best Practices
1. **Use V2** entry points on every route.
2. **Pass the quote's `fee` and `deadline` unchanged**, and request a new quote if the deadline is close.
3. **Check the recipient format** for the destination chain before signing.
4. **Take `maxFee` from Circle Iris** for the threshold you send.
5. **Report a transfer only once its transaction is confirmed**, and keep the transaction hash: delivery on the destination chain is automatic.
6. **Use permits** on EVM to skip the approval transaction.
> [card] [View Source Code](https://github.com/cashmere-prod/contracts-prod)
>
> Browse the contract repository
# Allow for all positions
Source: https://docs.cashmere.exchange/goat-lp/allow-for-all-positions
One wallet permission per Uniswap version and purpose: auto-range that keeps running, and auto-exit next to auto-compound.

> [!WARNING]
>
> Goat LP is experimental. Use small amounts.
Every auto-range move makes a new position, and a permission for one position does not carry over. With
**Allow for all positions** you give one permission for your whole wallet, per Uniswap version, so
auto-range keeps running after every move without a tap.
## What it covers

* It covers every Uniswap v3 (or v4) position in this wallet, now and later.
* The auto-range permission acts **only on positions where you turned auto-range on**. The contract checks this
on every move. On v4 the same engine also runs auto-exit rules saved for this permission (see
[Auto-exit for all positions](#auto-exit-for-all-positions)).
* A move closes the position and opens a new one in your wallet, centred on the current price, with the
width your rule sets on v3 and the same width on v4. Apart from Goat's fee, no tokens and no position go
to anyone else.
## Limits
| | Uniswap v3 | Uniswap v4 |
| - | - | - |
| Moves | Goat's system stops after 20 moves and asks you | The contract stops after 20 moves (you can pick fewer) |
| Time between moves | At most one an hour on pairs with a Chainlink price, every 6 hours on others. Kept by Goat's system, not by the contract | 6 hours by default, down to 1 hour. Kept by the contract |
| Which rules keep moving | Every v3 auto-range rule you confirm | Every v4 auto-range rule you save while the permission is on |
| Narrow ranges | At least ±5% on each side, on pairs without a Chainlink price | The same: below ±5% on such a pair, a rule moves once and waits |
| Brake | An independent monitor pauses v3 auto-range if Goat's system breaks these rules | The contract refuses a move outside the limits |
| To continue | **Renew**: one transaction, no new permission | **Renew**: one transaction, no new permission |
**Cost per move:** 0.15% of the amount moved goes to Goat. The swapped part (about half) pays the pool's
swap fee, and at most your price protection (0.50% by default; on v4 plus a 0.10% margin). Gas is paid by
us.
## Turn it on
Choose **Keep it running after every move** when you set up auto-range. You can also turn it on from the
Automation page:
**1. Open the consent screen**
On the **Automation** page, press **Keep it running** (or **Keep them running**). The screen lists every rule the
permission will be able to run, each with a switch. A rule you switch off is turned off on the chain
first.
**2. Tick the box and allow**
Tick that you understand it covers all your positions of that version in this wallet, then press
**Allow for all positions**.
**3. Check the address in your wallet**
Your wallet shows `setApprovalForAll` with one address: **Goat AutoRange** on v3, the **Goat auto-range
engine** on v4. It must match [Contracts](/goat-lp/contracts). Goat LP asks for `setApprovalForAll` only here
and in [Auto-exit for all positions](#auto-exit-for-all-positions). If anything else asks for it, or names
another address, stop.
The button only works while Goat can confirm that no change to Goat auto-range is scheduled. If one is
scheduled, or the check cannot be read, the site does not ask for the permission.
## How to stop
* **Stop auto-range** on the Automation page removes auto-range's permission for all positions and any
single-position permission Goat auto-range still has. Your wallet confirms each part. Then it reads them back:
"Stopped. Goat auto-range can no longer act on a position of this wallet."
* On v4, auto-exit rules saved for the permission for all positions use the same engine. The stop screen asks first:
keep them running (the engine keeps that permission for them) or stop them too. Auto-exit rules that use their own
permission for one position keep running either way, and the stop screen names them. If this site could not read
every v4 position, the engine keeps that permission unless you also stop auto-exit, and the result says that some
v4 positions could not be checked. Auto-compound is not changed.
* **Stop auto-exit for all positions**: on v3 it removes the AutoExit permission for all v3 positions first; then you
can delete the rules, one transaction each. On v4 the permission is the engine's, which auto-range rules saved for
it use too: when they do, the stop screen asks first whether they keep running. With "Also stop auto-range", an
auto-range rule that still has its own permission for one position can move once more, then it stops. On both,
auto-exit rules that use their own permission for one position keep running, and the stop screen names them.
Auto-compound is not changed.
* If the permission cannot be read again right after either of these stops, the result says so and claims nothing as
stopped; Try again reads it again.
* **Stop this position** on a position page stops only that rule; the permission stays for the others. On a position
where auto-exit and auto-compound run together, it removes that rule and its own permission; the stop screen says
the other rule on the position is not changed.
* **Without the app:** call `setApprovalForAll(goatAddress, false)` on the v3 or v4 position manager.
`isApprovedForAll(yourWallet, goatAddress)` must then return `false`. See
[Security](/goat-lp/security#leave-without-the-app).
## Auto-exit for all positions
Auto-exit can run next to auto-compound on the same position when auto-exit uses a permission for all positions.
Auto-compound keeps its own permission for that one position (on v4, its own signed messages). Auto-range still
runs alone.
* It covers every Uniswap v3 (or v4) position in this wallet, now and later.
* **v3:** the permission goes to **Goat AutoExit**. The contract can act on any position in this wallet that has
an auto-exit rule this wallet set. Goat's system runs a rule only if this wallet set or confirmed it after giving
this permission; a rule set up earlier waits until you confirm it.
* **v4:** it is the same permission that keeps auto-range running (the **Goat engine**). The engine runs only
rules saved for this permission. Goat's system pauses such a rule if its position left this wallet and came
back, until you confirm it.
* An auto-exit closes the position once, at your level. Apart from Goat's fee and, on a side that swaps, the
pool's swap fee, the tokens go to this wallet.
* Before the permission is given, the rules you leave off, rules on empty positions and rules whose level is
already reached are turned off on the chain.
| | Uniswap v3 | Uniswap v4 |
| - | - | - |
| Permission goes to | Goat AutoExit | The Goat engine, the same as auto-range |
| Rules that can run | Rules this wallet set or confirmed after giving the permission (kept by Goat's system, not by the contract) | Rules saved for this permission |
| A position that left the wallet and came back | Paused by Goat's system until you confirm it | Paused by Goat's system until you confirm it |
| Auto-compound next to it | Its own permission for that position | Its own signed messages for that position: each signed message allows one compound (wallets that cannot sign: one permission per compound) |
**Cost:** 0.15% of the amount closed goes to Goat, once. If a side swaps: the pool's swap fee, and at most your
price protection (0.50% by default). Auto-compound: 10% of the fees added back. Gas is paid by us.
**Turn it on:** on the auto-compound card of a position with an auto-exit, press **Allow auto-exit for all
positions**, choose the auto-compound settings and press Review. When the permission is off, the steps start with
the consent screen on the Automation page; it lists every auto-exit rule the permission would let run, each with
what happens to it, and brings you back to your setup. Your wallet shows `setApprovalForAll` with **Goat AutoExit**
on v3 or the **Goat engine** on v4; it must match [Contracts](/goat-lp/contracts). It is offered only while Goat's
system runs its confirmation check; otherwise the site shows "Not live yet", and the card keeps its switch.
**How to stop:** **Stop auto-exit for all positions** on the Automation page removes this permission. If your v4
auto-range rules use it too, the stop screen asks first whether they keep running; if they do, the permission stays
for them. Without the app: `setApprovalForAll(GoatAutoExit, false)` on the v3 position manager (v4: the Goat engine,
which also ends auto-range under it). Rules that use their own permission for one position keep running.
## The monitors
Independent monitors watch Goat auto-range. Each one holds a small key that can **only pause**:
auto-range moves, and the swaps of auto-range and auto-exit, on v3 and v4. They cannot pause compounding, or exits
that only withdraw (a swap pause makes exits that swap wait), cannot unpause and cannot move funds. Unpausing takes the owner Safe and waits 24 hours.
# Analytics
Source: https://docs.cashmere.exchange/goat-lp/analytics
How Goat LP counts PnL, APR and fees, where the data comes from, how fresh it is, and what each badge means.

> [!WARNING]
>
> Goat LP is experimental. Use small amounts.
Goat LP analytics are free and read-only. They cover every Uniswap v3 and v4 pool, position and wallet on
Robinhood Chain. Analytics describe the past: no figure is a promise of future returns.
## How PnL is counted
```
PnL vs HODL = value + fees − HODL − gas
Pool PnL = fees + divergence
Net APR = PnL ÷ base × 365 ÷ active days
```
| Term | Meaning |
| - | - |
| **Fees** | Swap fees collected, plus those still uncollected in the position |
| **Divergence** | Position value minus the value of the deposited tokens, held. Also called impermanent loss |
| **Pool PnL** | Fees plus divergence: what the pool itself did for you |
| **Gas** | Network fees for every transaction on the position, including keeper runs Cashmere paid for |
| **Rewards** | Incentives such as Merkl programs, counted when claimable, never mixed into fees |
| **PnL** | All of the above, against the reference you pick: **HODL**, **USD** or **ETH** |
* A position is one NFT. Its PnL runs from the mint to now, whoever holds it.
* Compounding does not move PnL by itself: re-added fees still count as fees.
* A range move closes one NFT and opens another. Goat LP links the two when both happen in one transaction
with the same owner, and sums their results.
* A closed position shows its realised PnL on its page. Net APR and fee APR show "—" once nothing is invested.
## APR and fee APR
| Figure | What it counts |
| - | - |
| **Net APR** | PnL ÷ base × 365 ÷ active days. Fees and price, after gas |
| **Fee APR** | Fees only |
| **Pool fee APR** | The pool's fees over the selected window, spread over all of its liquidity |
| **Past fee APR (last 24 h)** (create panel) | The last 24 hours of pool fees × your share × 365 ÷ your deposit. Past fees, not a forecast. Zero while out of range |
Your fee APR differs from the pool's because it counts only your own fees over your own deposit.
The **Dashboard** shows **Fees** (collected plus uncollected) and **Fee APR** at the top. **More stats** (open by default
on wider screens; tap it on a phone) lists the rest: divergence, PnL against holding before and after gas, gas, Net APR,
the 24 h change and the figures at event prices. The account APRs count open positions only, and a bigger position counts
more. Lifetime counts closed positions' fees at today's prices; a closed position's row shows its fees at the close.
## Where the data comes from
| Data | Source |
| - | - |
| Pools, positions, transactions | Goat LP's own index of Robinhood Chain |
| USD prices | Chainlink where a feed exists, otherwise pools with a confirmed price. Unconfirmed prices are marked |
| Uncollected fees on open v4 positions | Read from the chain on every load |
| Rewards | Merkl |
| Token logos | CoinGecko |
## Freshness
| Status | Index delay |
| - | - |
| **Live** | 60 seconds or less |
| **Behind** | Up to 10 minutes |
| **Stale** | More than 10 minutes; a banner says so |
Your open positions refresh every 15 seconds (every minute for an account with more than 100 open
positions), lifetime figures every 2 minutes, and straight away after you send a transaction.
## Badges
> [accordion] Pool badges
>
> | Badge | Meaning |
> | - | - |
> | **Swap tax x%** | A hook keeps this share of every swap. It is not a fee to liquidity providers |
> | **Hook** | The pool runs a hook. Neutral if Goat LP reviewed it, a warning if not |
> | **LPs get no swap fees** | The pool pays liquidity providers no swap fees |
> | **Not the original** | Same ticker as a listed token but a different contract. Check the address |
> | **Price stale** | A token could not be priced against a trusted pool right now |
> | **TVL capped to balance** | TVL was lowered to what the pool actually holds |
> [accordion] Position badges
>
> | Badge | Meaning |
> | - | - |
> | **price from pool** | A USD figure uses a pool's own price. PnL and APR are indicative |
> | **no price backing**, **price above ceiling**, **fees unavailable** | Not a measurement; the number is withheld or marked |
> | **unreviewed hook** | A v4 pool with a hook outside the reviewed set. Hidden by default |
> | **burned owner** | Owned by the burn address; its fees can never be collected |
> | **Skewed by gas costs** | Gas is 20% or more of the position's PnL |
> | **Not meaningful** | A launch deposit valued at today's price. PnL and Net APR show "—" |
> [accordion] Fee collection labels
>
> | Label | Meaning |
> | - | - |
> | **Not payable right now** | This token cannot be paid out right now. Try again later |
> | **Cannot be collected** | With the reason, for example the token refuses transfers from this pool |
> | **Not yet checked** | New token, pool or hook. Simulate before collecting or withdrawing |
> | **Withdrawal blocked** / **Locked until** | The pool's hook does not allow removing liquidity, or not before the date shown |
> | **Uncollectable fees** | Part of the fees cannot be collected; they are left out of fees and fee APR |
> [!NOTE]
>
> When Goat LP cannot stand behind a number, it shows "—" with the reason instead. The in-app **How we count
> PnL** page works through these rules on live example positions.
# Automation
Source: https://docs.cashmere.exchange/goat-lp/automation
Auto-compound, auto-range and auto-exit: what each does, what you allow, what it costs and how to stop it.

> [!WARNING]
>
> Goat LP is experimental. Use small amounts.
Let a keeper do routine work on your positions. You stay the owner, you can still deposit, withdraw and
collect, and you can stop at any time. Automation is live on Uniswap v3 and v4.
## The three automations
| | What it does | Goat LP fee | Gas |
| - | - | - | - |
| **Auto-compound** | Puts the fees your position collects back into it | 10% of the fees added back | Paid by us |
| **Auto-range** | When the price leaves your range by the distance you set, moves the position to a new range around the price | 0.15% per move | Paid by us |
| **Auto-exit** | Closes the position when the price reaches a level you set, above, below or both. Runs once, then turns itself off | 0.15% once, when it closes | Paid by us |
On Uniswap v4, auto-compound can also **send the fees to your wallet** instead of adding them back: 10% of
the fees collected, gas paid by us. The exact base of each fee is on [Fees](/goat-lp/fees).
A position runs **one automation at a time**, with one exception: auto-exit and auto-compound together when
auto-exit uses [Allow for all positions](/goat-lp/allow-for-all-positions#auto-exit-for-all-positions). Auto-range
runs alone, and it includes auto-compound: it puts your fees back in at each move. On v4, each signed message
allows one compound. To change, press **Switch to auto-range** on the auto-range card: it turns auto-compound off (and
auto-exit, if it is on) and auto-range on, in one review.
## How a run works
> [tab] Price check
>
> 
> [tab] Auto-compound
>
> 
> [tab] Auto-range
>
> 
> [tab] Auto-exit
>
> 
* The keeper only triggers the run. The contract decides what happens and where the money goes.
* Before any swap, the contract compares the pool price with an outside price, so one big trade in the pool
cannot set off a run or push its price.
* Every output goes to the position's owner. The keeper receives nothing.
## Turn it on
**1. Open the setup sheet**
Press **Automate** on the position page and pick **Auto-compound**, **Auto-range** or **Auto-exit**. The
sheet says straight away if the automation cannot run on this position, and why.
**2. Pick your settings**
Every field starts with a default. The picture shows your range and the prices where we act. The cost
line shows Goat's fee and that the gas is paid by us.
**3. Review, then two wallet steps**
**Allow this position**, then **Turn on**. On Uniswap v4, auto-compound asks for no permission:
**Sign N runs (free)**, then **Turn on**. Your wallet opens N times in a row, once per signed message, free
and with no gas; you can stop and continue later. Changing a rule later is one step, **Save changes**, and
the permission stays. Nothing is sent until you confirm in your wallet.
## What you allow
Every automation works through a permission for **one position**. The exceptions are auto-range and
auto-exit: each can use one permission for all your positions of one Uniswap version, see
[Allow for all positions](/goat-lp/allow-for-all-positions).

| Automation | Uniswap v3 | Uniswap v4 |
| - | - | - |
| Auto-compound | One position, to the auto-compound contract. Your NFT never moves | No standing permission. Free signed messages: each one allows one compound of this position until the end date you pick. Wallets that cannot sign: one permission per compound |
| Auto-range | One position, to the auto-range contract, or all positions with Allow for all positions | One position, to the Goat automation engine, or all positions with Allow for all positions |
| Auto-exit | One position, to the auto-exit contract, or all positions with Auto-exit for all positions | One position, to the Goat automation engine, or all positions with Auto-exit for all positions |
**On Uniswap v4, auto-compound uses signed messages.** Signing is free and costs no gas. Each signed message
allows one compound of this position until the end date you pick, and "A signed message can't move anything
except back into your own position." When the signed runs are used up or reach their end date, you sign again.
**Wallets that cannot sign these messages** (smart-contract wallets such as Safe, and 7702 wallets) give one
permission per compound instead: "Your wallet can't sign the messages auto-compound uses. You can allow this
position instead; each permission covers one compound." Before you allow it, you tick that you understand it
covers one compound, and the details say: "On Uniswap v4 a permission on a position also allows removing its
liquidity. The Goat contract you allow has no code that does that; it can only run the rule you set." After each
compound the card asks: "Allow again for the next compound."
> [!NOTE]
>
> **What you sign.** Each signed message for v4 auto-compound is a typed message (EIP-712) of the Uniswap v4
> position manager ("Uniswap v4 Positions NFT", chain 4663). It has four fields:
>
> * `spender`: `GoatAutoCompoundV4`, the address on [Contracts](/goat-lp/contracts#compounding)
> * `tokenId`: your position number
> * `nonce`: a number that lets the message be used only once
> * `deadline`: the end date you picked, at most 90 days away
>
> If your wallet shows another spender, another position number or an end date more than 90 days away, do not
> sign.
**After each auto-range move** the new position has a new number and needs your OK before it can move
again: **Allow #new**, one tap, a network fee under a cent, no Goat LP fee. Your settings move with it.
You can skip this tap with [Allow for all positions](/goat-lp/allow-for-all-positions).
**On Uniswap v3, a manual compound, or a withdraw or collect to one token,** moves the NFT through a
contract and back, which removes the permission you gave that position. If an automation is on, the app
says so before your wallet opens and adds **Allow again** to the same transaction (a second wallet step if
your wallet cannot batch calls).
**Moving a range yourself** makes a new position with a new number, and an automation that is on stays on
the old number. The app says so before your wallet opens, and after a one-transaction move it offers to set
it up on the new position. **On Uniswap v3, a deposit while auto-range is on** moves the fees collected so far
out of the position, so auto-range's next move sends them, and the fees collected until then, to your
wallet instead of into the new range. The deposit screen says so above its button.
> [!NOTE]
>
> On Uniswap v3 and v4, a permission on a position lets the allowed contract manage that position. What
> limits it is the contract's code: each Goat contract only runs the rule you set and sends every output to
> the owner. The contract addresses are on [Contracts](/goat-lp/contracts).
## Settings
> [accordion] Auto-compound
>
> * **At most once every:** 1 hour, 6 hours, 12 hours, 1 day or 7 days. The default is 1 hour on v3 and on
> wallets that give one permission per compound. With v4 signed runs, the default is the end date divided by
> the runs, rounded down to one of these and never under 1 hour: 30 days and 12 runs give 1 day; 90 days and
> 4 runs give 7 days.
> * **Price protection:** the most the swap may lose against the reference price (default 1%).
> * **Uniswap v4 mode:** **Add fees back** (default) or **Send fees to my wallet**.
> * **Uniswap v4 signed runs:** **Keep running for** 7, 30 (default) or 90 days; after that date the keeper
> stops by itself. **Runs to sign now** 4, 12 (default) or 30. A position under the minimum size starts at
> 4 runs over 90 days. When 3 days or 2 runs are left, the app asks you to sign again: "Auto-compound stops
> on *date*. Sign again to keep it running." with **Sign N more (free)**.
> * **Uniswap v3:** **Swap to match the range**. Off: only the matching part is added; the rest comes back
> to you without a fee.
> [accordion] Auto-range
>
> * **How far past the edge before we move:** at least the pair's closest move point. Before every move we
> check an outside price, and the pool price and the outside price may be a little apart, so the move point
> can't be closer than that. The sheet shows the exact figure for your pair.
> * **Width of each new range:** on v3, same as now or custom; on v4, the same width as now.
> * **Price protection per move:** default 0.50%.
> * **Uniswap v4 only:** wait between moves (1 hour to 30 days, default 6 hours), the highest swap fee in a
> move (default 1%, at most 10%) and 20 moves. After the last one the card says "Auto-range used all its
> moves. Renew to keep it running." and you press **Renew**.
> * **Uniswap v3:** no wait between moves.
> [accordion] Auto-exit
>
> * A level below your range, above it, or both. The sheet suggests 5% beyond each edge. A level must sit
> at least the pair's buffer outside your range; the sheet shows the closest allowed level.
> * **Keep** (withdraw only) acts as soon as the pool price reaches your level.
> * **Swap all to** one token also checks the outside price first, so in a fast move it can wait.
> * In a sudden jump the price can pass your level before we act, so you may get less than shown.
## Where it can run
* **Listed pairs with an outside price:** a Chainlink price, or a deep pool Goat checks against. Pairs
without one are not offered. Of the pairs priced without Chainlink, only v4 PONS / USDG offers auto-range
and swap exits today. On the others the sheet says "Auto-range and swap exits aren't offered on this pair
yet. Exits without a swap work."
* **Withdraw-only exits** also work on a listed pair's pools that have no price check of their own.
* **In the deep pool Goat checks a pair against,** auto-compound's price check uses that pool's own 30-minute
average.
* **Uniswap v4 hooks:** pools without a hook, or with a hook Goat reviewed. Other hook pools get no
automation ("Hook not reviewed"). Auto-compound follows its own list of reviewed hooks inside
`GoatAutoCompoundV4`, pinned by code hash, so a pool can be open for auto-range and auto-exit but not for
auto-compound, or the reverse. Some hooks change what is offered: see the table below.
* **Tokens that keep a cut when they move** (a transfer tax): no auto-range and no swap exits. Withdraw-only
exits work.
* **Size:** there is no per-position cap. Positions under about \$50 at today's gas are too small for us to
move, so auto-range is not offered for them; the app shows the current figure. On pairs without a Chainlink
price, an hourly swap limit is shared by everyone on the pair; auto-range is not offered for a position too
large for it, and larger runs wait until the pair's price check is deeper. Smaller runs still go ahead. In
both cases auto-exit still works, but a swap exit above the pair's limit gets "A swap exit this large is
above this pair's limit (about \$N). Withdraw only would act right away."
* **Stock-token pairs** run swaps only while their outside price is updating, so a move or a swap exit can
wait a day or more.
* **Pairs priced without Chainlink:** automatic swaps pause when the price moves fast. They resume by
themselves once the pair's other pools, and for a stock token its outside price, agree for an hour. The card
says "Paused for a price check. Back in about N min." or "Paused for a price check. We check again every 5
minutes." Exits without a swap never wait.
| Hook pool | What changes |
| - | - |
| Swaps in the pool need signed quotes | Auto-compound offers **Send fees to my wallet** only |
| Liquidity providers get no swap fee | Nothing to compound, so no auto-compound |
| The hook takes part of every deposit, or can change what a withdrawal returns | No automation |
| The hook blocks new positions | No auto-range. Auto-exit is available |
| The hook keeps part of each swap | Auto-compound runs, and the total cost stays within your price protection |
| The hook charges its own swap fee | Auto-compound needs a higher price protection; the sheet says how much |
| The pool charges a fixed swap tax | Automation includes the tax in its price checks |
| A reviewed hook with a fee | Its fee is capped and checked on every run |
**Positions that cannot be automated:**
* A full-range position: no auto-range or auto-exit, because it never leaves its range.
* An empty position.
* A position held by another app.
* A position linked to another app: "This position is linked to another app. Unlink it first."
* A range too narrow for auto-range. On v4 a range needs at least about 4% between min and max, more on some
pools; on v3 each new range must be at least that wide. The sheet shows the exact figure.
The **Agents** light on the Pools list shows green (available), red (not offered, with the reason) or grey.
## Status and stopping
| Status | Meaning |
| - | - |
| **On** | Set and waiting. The line says when it would act |
| **Ready to move** | v4 auto-range: the price is past the move point. We move it soon, or you can press **Move now** |
| **Ran / Moved / Exited** | It did its job, with a link to the transaction |
| **Needs you** | One step from you, such as **Allow #new** or **Allow again**. The buttons are listed below |
| **Waiting for fees** | Auto-compound waits for more fees to build up. Auto-range: the position is too small for us to move at this size |
| **Paused** | A price, capacity or timing check does not pass right now. The line says what it waits for; the keeper tries again later. When automation is paused for everyone, the line says so: "Your position is not affected; withdraw and collect still work." |
| **On hold** | The keeper stopped trying after failed runs and says when it tries again |
| **Closed** | The rule is saved but cannot run, for example "Auto-compound stopped: its signatures ran out." A rule that is off while a Goat permission is still set shows here too, for example "Auto-range is off, but a permission is still set.", with **Remove leftover permission** |
| **Stopped** | "Stopped: this position changed owner." |
| **Retired** | "This automation version is closed to new runs. Turn it off to remove the permission." |
| **Unknown** | "Couldn't read this automation on chain. It is not shown as off." Press **Retry** |
| **Not available** | Automation is not offered for this position. The line gives the reason |
| Needs-you button | When |
| - | - |
| **Allow #new**, **Allow again** | A move made a new position, or the permission was removed or replaced |
| **Sign N more (free)** | v4 auto-compound: 3 days or 2 signed runs are left |
| **Send again** | "Your signed messages did not reach the keeper. Sign them again; signing is free." |
| **Save again** | The pair's automation settings changed |
| **Renew** | Auto-range used all its moves |
| **Re-enable** | v4 auto-compound: its signed runs ran out or passed their end date (the banner's **Sign again** leads here) |
| **Confirm** | Auto-range waits for your OK on this position |
| **Remove other permission** | v4 auto-compound: another app is allowed to manage this position |
| **How to unlink** | The position is linked to another app |
| **Change highest swap fee** | v4 auto-range and auto-exit: the swap fee right now is above the highest swap fee you set |
| **Switch to Withdraw only** | Your swap exit is too large for the pool near your level |
When v4 auto-compound has no signed message the keeper can use (all used, past their end date, or never
received), a banner shows at the top of every Goat LP page: "Auto-compound stopped on one of your positions"
(or "on N of your positions"), "It needs you to sign again before it can run. Signing is free." Press
**Sign again**.
**Stop** turns the rule off (the keeper stops right away), then removes the permission:
* **v4 auto-compound:** the rule is turned off, then the unused signed messages are cancelled and the
permission, if one is set, is removed.
* **v4 auto-range and auto-exit:** the rule is cleared, then the permission is removed.
* **v3:** the rule is turned off, then the permission is removed.
Only the permission of that Goat automation is removed; another app's permission on the position is left
alone. The sheet then checks the chain and says "Checked on chain: the rule is off and no permission is
left." (v4 auto-compound: "Checked on chain: the rule is off, the unused signed messages are cancelled and no
permission is left.") Your funds stay in the position. Automation also stops when the position changes owner.
On a v4 auto-range rule whose trigger is reached, you can press **Move now** yourself: one transaction, you
pay the network fee, the 0.15% fee applies as usual. When a v4 auto-range card is paused because the pair's
hourly swap limit is in use, it can show **Run now**: your own move is not held by that limit, on the same
terms. On some hook pools only the keeper can run a move or a swap exit. There, **Move now** and **Run now** do
not show, and the keeper runs it on its own once your trigger is reached.
## Keepers

* Keepers are Goat-run bots. They pay the gas. They never hold or receive your tokens.
* A position that is too small for us to move is not moved. The card says "Too small for us to move at this
size. Your rule stays on."
* Exits run even on small positions: we cover the gas, within a daily limit. An exit can wait when Goat's
daily gas budget for exits is used up, when Goat's gas help for small exits is at its limit, or when network
gas is higher than Goat pays for an exit. The card then says when the keeper tries again (in UTC), and it
keeps trying while the exit is on.
* If a keeper is late or down, nothing happens to your position. Do not rely on automation alone.
# Contracts
Source: https://docs.cashmere.exchange/goat-lp/contracts
Every Goat LP contract address, what each one does, who controls it, and the contracts Goat LP calls.

Goat LP runs on Robinhood Chain mainnet, chain ID **4663**. Before you approve or send anything, compare the
address in your wallet with this page. Each address links to the explorer, where its source code is
published.
> [!WARNING]
>
> Goat LP is experimental. Use small amounts.
None of these contracts is upgradeable: no proxy, no delegatecall.
## Compounding
| Contract | What it does | Address |
| - | - | - |
| `GoatSelfCompoundor` | One-click compound on Uniswap v3. Takes the NFT, adds the fees back, pays 10% of what was added back, and returns the NFT in the same transaction | [`0x4D0D364EB62be5FcFdc88c56E64ff1eEbaD99DaA`](https://robin.etherscan.io/address/0x4D0D364EB62be5FcFdc88c56E64ff1eEbaD99DaA) |
| `GoatV4Compoundor` | The same on Uniswap v4 | [`0x307db4605691Ca81bAe9DD162de6F8De319224f5`](https://robin.etherscan.io/address/0x307db4605691Ca81bAe9DD162de6F8De319224f5) |
| `GoatPriceAnchor` | The outside price for compounds: Chainlink, or the average price of a deep pool Goat checks against | [`0x5799d99837d2736C6506AD5EE0727968B708A566`](https://robin.etherscan.io/address/0x5799d99837d2736C6506AD5EE0727968B708A566) |
| `GoatAutoCompoundV3` | Auto-compound on v3, through your permission for one position. Can only collect fees, swap part of them and add liquidity back; it cannot remove liquidity | [`0x4A036a2d8FD1d2C0110A9d775ae269fFE6Ea8390`](https://robin.etherscan.io/address/0x4A036a2d8FD1d2C0110A9d775ae269fFE6Ea8390) |
| `GoatAutoCompoundV4` | Auto-compound on v4. Its only power is to send your position to `GoatV4Compoundor` and check it came back | [`0xb0d066E7E9B21c3AbDCe9b26A767155F48Ed0500`](https://robin.etherscan.io/address/0xb0d066E7E9B21c3AbDCe9b26A767155F48Ed0500) |
## Auto-range and auto-exit on Uniswap v3
Revert Finance's AutoRange and AutoExit, with changes for Robinhood Chain only: price checks against an
outside price, re-centring on that price, a fixed 0.15% fee that can only be lowered, and a table of listed
pairs. Revert Finance has not reviewed these versions.
| Contract | What it does | Address |
| - | - | - |
| `AutoRange` | Moves a v3 position when its trigger is hit; the new position goes to the owner | [`0xF0436e6B378e7d4b1Fb17860673C091A32Fb19cD`](https://robin.etherscan.io/address/0xF0436e6B378e7d4b1Fb17860673C091A32Fb19cD) |
| `AutoExit` | Closes a v3 position at your level; everything goes to the owner | [`0xe337A443237a9eA7ED3b0610F70c24c040438161`](https://robin.etherscan.io/address/0xe337A443237a9eA7ED3b0610F70c24c040438161) |
| `GoatPairTable` | Which pairs and fee tiers v3 automation may use, their price sources and swap limits | [`0xbBF00DD403BFf43400ed3D32a29cF4eC580026De`](https://robin.etherscan.io/address/0xbBF00DD403BFf43400ed3D32a29cF4eC580026De) |
## Auto-range and auto-exit on Uniswap v4
| Contract | What it does | Address |
| - | - | - |
| `GoatV4Steward` | Decides: your rule, the price checks, the trigger and the new range | [`0xBb6494D891bd9cCCf11ADd32FD61Afe246164b3d`](https://robin.etherscan.io/address/0xBb6494D891bd9cCCf11ADd32FD61Afe246164b3d) |
| `GoatV4StewardEngine` | Executes. The one contract you allow for v4 auto-range and auto-exit; it takes orders only from the Steward and holds nothing between calls | [`0xD12D46c9d3B1FE463895A20daD19F3cae5584892`](https://robin.etherscan.io/address/0xD12D46c9d3B1FE463895A20daD19F3cae5584892) |
| `GoatV4PairRegistry` | Which v4 pools automation may use, their price sources, and reviewed hooks pinned by code | [`0x92f449da205552Eadbb51C05888EEDE1657B4048`](https://robin.etherscan.io/address/0x92f449da205552Eadbb51C05888EEDE1657B4048) |
| `GoatV4PokeOracle` | Average-price history for listed v4 pools that serve as a pair's price source | [`0xadeA4C7d46a2d3Fb442C4079FC236B262b4b2b50`](https://robin.etherscan.io/address/0xadeA4C7d46a2d3Fb442C4079FC236B262b4b2b50) |
| `GoatV4SourceMeter` | Checks a price source's depth and history when a pool is listed. No owner, no settings | [`0xd7dB57c254eA350215Fb07ab386AA5E909CD7205`](https://robin.etherscan.io/address/0xd7dB57c254eA350215Fb07ab386AA5E909CD7205) |
## What you allow, and to whom
| Automation | Uniswap v3 | Uniswap v4 |
| - | - | - |
| Auto-compound | One position, to `GoatAutoCompoundV3` | No standing permission: one signed message per run, for `GoatAutoCompoundV4`. Wallets that cannot sign: one permission per run, to `GoatAutoCompoundV4` |
| Auto-range | One position, to `AutoRange` | One position, to `GoatV4StewardEngine` |
| Auto-exit | One position, to `AutoExit` | One position, to `GoatV4StewardEngine` |
| [Allow for all positions](/goat-lp/allow-for-all-positions) | All v3 positions, to `AutoRange` | All v4 positions, to `GoatV4StewardEngine` |
| [Auto-exit for all positions](/goat-lp/allow-for-all-positions#auto-exit-for-all-positions) | All v3 positions, to `AutoExit` (auto-compound keeps its own permission for one position) | All v4 positions, to `GoatV4StewardEngine`, the same permission as auto-range |
## Roles

| Role | Who | What it can do |
| - | - | - |
| Owner | Cashmere-controlled Safe [`0xA1A286F270aE86D6008B79a48D15AbaC880f64AE`](https://robin.etherscan.io/address/0xA1A286F270aE86D6008B79a48D15AbaC880f64AE) | Add and remove keepers; pause, unpause and retire automation; list pairs, pools, hooks and price sources; lower fees, never raise them; change the fee address; withdraw Cashmere's accrued fees; recover an NFT sent by mistake to a compound contract. Adding a keeper, a reviewed hook, a pair or a price source waits 24 hours in public, and so does unpausing auto-range and auto-exit. Removing a keeper and pausing apply at once. It cannot take positions out of your wallet or redirect your outputs |
| Guardian | Cashmere-controlled Safe [`0x3197767EAcf0Ae281EB661Af3dBa6723B5e181b2`](https://robin.etherscan.io/address/0x3197767EAcf0Ae281EB661Af3dBa6723B5e181b2) | Only pause, remove a keeper (on the v4 auto-range engine it pauses instead), or narrow what automation may do. Cannot add or unpause |
| Keepers | Goat-run bots | Trigger runs and pass the swap details (route, pool or reference price), which the contracts check against their own price source and limits. They receive nothing; Cashmere pays their gas |
| You | The position owner | Turn your own rules on, change or stop them. On v4, `clearConfig` works even when the contract is paused |
## Contracts Goat LP calls but did not write
| Contract | Used for | Address |
| - | - | - |
| Uniswap v3 position manager | v3 positions | [`0x73991a25C818Bf1f1128dEAaB1492D45638DE0D3`](https://robin.etherscan.io/address/0x73991a25C818Bf1f1128dEAaB1492D45638DE0D3) |
| Uniswap v4 position manager | v4 positions | [`0x58daec3116aae6D93017bAAea7749052E8a04fA7`](https://robin.etherscan.io/address/0x58daec3116aae6D93017bAAea7749052E8a04fA7) |
| Uniswap v4 pool manager | v4 pools | [`0x8366a39CC670B4001A1121B8F6A443A643e40951`](https://robin.etherscan.io/address/0x8366a39CC670B4001A1121B8F6A443A643e40951) |
| Uniswap Universal Router | Every swap in the manual tools, and the 0.65% fee | [`0x8876789976dEcBfCbBbe364623C63652db8C0904`](https://robin.etherscan.io/address/0x8876789976dEcBfCbBbe364623C63652db8C0904) |
| Permit2 | Exact-amount, 30-minute token approvals on v4 | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://robin.etherscan.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) |
| Revert Finance V3Utils | One-token tools and move range on v3. Deployed and maintained by Revert Finance | [`0x98eC492942090364AC0736Ef1A741AE6C92ec790`](https://robin.etherscan.io/address/0x98eC492942090364AC0736Ef1A741AE6C92ec790) |
| WETH | Wraps the ETH you pay on WETH pairs, inside the Uniswap position manager's transaction (your wallet never calls it directly). An upgradeable bridge token, not WETH9 | [`0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73`](https://robin.etherscan.io/address/0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73) |
On Uniswap v4, every manual action except Compound goes straight to Uniswap's own contracts. Chainlink feeds are listed in
the app.
## Fee address
Every Goat LP fee goes to
[`0x2bf95e5f307FB84e19851865193a14DaB01A561F`](https://robin.etherscan.io/address/0x2bf95e5f307FB84e19851865193a14DaB01A561F).
See [Fees](/goat-lp/fees).
## Licences
Compound contracts, price anchor and v4 automation: MIT. v3 auto-range and auto-exit: derived from Revert
Finance's AutoRange and AutoExit, licence terms in each source file's header; `GoatPairTable` is
GPL-2.0-or-later.
# FAQ
Source: https://docs.cashmere.exchange/goat-lp/faq
Short answers to common questions about Goat LP.

> [!WARNING]
>
> Goat LP is experimental. Use small amounts.
## The basics
> [accordion] Is Goat LP live?
>
> Yes: analytics, every manual tool, and auto-compound, auto-range and auto-exit on Uniswap v3 and v4,
> with [Allow for all positions](/goat-lp/allow-for-all-positions) for auto-range and
> [Auto-exit for all positions](/goat-lp/allow-for-all-positions#auto-exit-for-all-positions) next to
> auto-compound. Goat LP is experimental. Use small amounts.
> [accordion] What does Goat LP charge?
>
> Analytics are free. Actions without a swap cost only gas. Manual tools that swap cost 0.65% of the
> swapped part. Compounding costs 10% of the fees added back; on Uniswap v4, **Send fees to my wallet**
> costs 10% of the fees collected. Auto-range costs 0.15% per move and auto-exit 0.15% once. Gas for
> automation runs is paid by us. Details on [Fees](/goat-lp/fees).
> [accordion] Does Goat LP hold my position or my tokens?
>
> No. Your position is a Uniswap NFT in your own wallet. A compound contract holds it only inside the one
> transaction that compounds it, and that transaction fails if the NFT does not come back.
> [accordion] Can Cashmere take my funds?
>
> The Goat LP contracts send every output to the position's owner and every fee to the fee address, and
> they cannot be upgraded. The owner Safe cannot take positions out of your wallet or redirect your outputs.
> See [Contracts](/goat-lp/contracts#roles).
> [accordion] What happens to my position if I stop using Goat LP?
>
> Nothing. You can manage or withdraw it at Uniswap or on the block explorer, unless the pool's hook or one
> of its tokens blocks it. [Security](/goat-lp/security#leave-without-the-app) shows every step.
## Positions and numbers
> [accordion] Is impermanent loss the same as divergence?
>
> Yes. Both mean how much less the position is worth than the tokens you deposited, held. It shrinks if
> the price returns to your entry and becomes final when you withdraw.
> [accordion] Do I lose money when my position goes out of range?
>
> Out of range, the position gets no fees and holds only one token, so its value follows that token.
> Nothing is sold for you: if the price comes back, it gets a share of the swap fees again.
> [accordion] Why is my APR different from the pool's APR?
>
> The pool's fee APR spreads its fees over all of its liquidity. Yours counts only your own fees over your
> own deposit: your range width, your time in range and when you entered all matter.
> [accordion] What is the difference between Collect and Compound?
>
> **Collect** sends your fees to your wallet; it costs only gas. **Compound** adds them back to the
> position; it costs 10% of the fees added back.
## Automation
> [accordion] What can an automation do with my position?
>
> Only the rules you set, within your limits: compound, move or close a position that has a rule on. The
> permission is for one position, or for all positions if you allow that for auto-range or auto-exit. The NFT
> stays in your wallet between runs, and **Stop** removes the permission.
> [accordion] Why does v4 auto-compound ask me to sign?
>
> On Uniswap v4, auto-compound gives no standing permission. You sign a batch of free messages instead (12 by
> default), and each one allows one compound of this position until the end date you pick. When 2 runs or 3
> days are left, the app offers **Sign N more (free)**. If they run out, auto-compound stops until you sign
> again (**Sign again**, or **Re-enable** on the card). Wallets that cannot sign these messages (Safe, 7702)
> allow the position once per
> compound instead.
> [accordion] Why do I have to allow my position after an auto-range move?
>
> A move closes the old position and opens a new one with a new number. Your settings move with it, but
> the permission covered only the old one. **Allow #new** is one tap, a network fee under a cent, no Goat
> LP fee. [Allow for all positions](/goat-lp/allow-for-all-positions) removes this step.
> [accordion] Which pairs can be automated?
>
> Listed pairs with an outside price: a Chainlink price, or a deep pool Goat checks against. On Uniswap v4,
> pools without a hook or with a hook Goat reviewed. The **Agents** light on the Pools list shows it.
> [accordion] What is the highest swap fee in a move?
>
> On Uniswap v4, a cap you set per position on the pool fee plus Uniswap's protocol fee that a move may
> pay when it swaps. The default is 1% and the most is 10%. Above your cap, the keeper waits.
> [accordion] Why did my automation not run?
>
> The position's **Automation** tab says why. Common reasons:
>
> * Small position: runs wait until enough fees build up, so they can be far apart.
> * Auto-range: the position is too small for us to move.
> * The time between runs has not passed.
> * A price check does not pass right now, or the pair is paused for a price check.
> * The pair's hourly swap limit is in use.
> * The swap fee right now is above the highest swap fee you set.
> * On v4 auto-compound: the signed runs are used up, past their end date or never reached the keeper, or
> another app is allowed to manage this position.
> * The position changed owner, or a permission is missing (for example after a move).
## Pools and tokens
> [accordion] What is a hook, and should I avoid hook pools?
>
> A Uniswap v4 hook is a contract that runs on swaps and liquidity changes. It can set a dynamic fee, take
> a share of swaps or make a call fail. Read the hook badge and its address before you deposit.
> [accordion] Why can a stock-token pool price jump suddenly?
>
> Stock-token pools trade around the clock, but their outside price does not always update. When it does,
> the pool can jump to it at once, across a whole range.
> [accordion] What does "Not the original" mean?
>
> The token uses the same ticker as a listed token but is a different contract. Check the address before
> you trade.
> [!NOTE]
>
> Still stuck? Write to [contact@cashmere.exchange](mailto:contact@cashmere.exchange). Cashmere will never
> message you first or ask for your keys.
# Fees
Source: https://docs.cashmere.exchange/goat-lp/fees
Every Goat LP fee, what it is charged on and where it goes.

> [!WARNING]
>
> Goat LP is experimental. Use small amounts.
Goat LP charges only when it does work for you. Analytics are free, and actions without a swap cost only
gas. Every manual fee is shown in tokens and dollars before you sign; automation fees are shown as a rate in the
setup sheet.
## All fees
| Action | Goat LP fee | Charged on | Gas |
| - | - | - | - |
| Analytics, dashboards, search | **Free** | | |
| Deposit, withdraw, collect, create or move range **without a swap** | **None** | | You pay |
| Paying the WETH side with ETH (WETH pairs) | **None** (wrapping is 1:1) | | You pay |
| Manual tools **that swap** (one-token deposit, withdraw or collect, move range with a swap) | **0.65%** | The swapped part only | You pay |
| Compound, manual or automatic | **10%** | The fees added back | Auto: paid by us |
| Auto-compound, **Send fees to my wallet** (Uniswap v4) | **10%** | The fees collected (the other 90% goes to your wallet) | Paid by us |
| Auto-range | **0.15%** per move | v4: the principal taken out. v3: everything added to the new position, collected fees included | Paid by us |
| Auto-exit | **0.15%** once, when it closes | v4: the principal taken out. v3: what comes out | Paid by us |
| Swaps inside automations | **No 0.65%** | Only the pool fee and Uniswap's protocol fee | |
| Turning an automation on, changing it, stopping it, **Allow #new** | **None** | | You pay |
| Signing v4 auto-compound runs, **Sign N runs (free)** | **None** | | None: signing costs no gas. **Turn on** after it is one transaction you pay |
Uniswap pool fees go to the pool's liquidity providers, not to Cashmere.
## Manual-tool swap fee: 0.65%
When a manual tool swaps, Uniswap's Universal Router keeps 0.65% of that swap's output for Cashmere and
passes the rest on, in the same transaction. Only the swapped part is charged.
* Before you sign, the app decodes the transaction and refuses it unless the fee goes to the fee address
at exactly 0.65%. The app's code will never build a fee above 1%.
* Today, if a swap fills better than quoted, the extra goes to you. You always get at least the minimum
shown in the review.
**Example.** You deposit 1,000 USDG as one token into an ETH / USDG range, and the tool swaps 480 USDG into
ETH. The fee is 0.65% of the ETH that swap returns, worth about 3.12 USDG. The 520 USDG that was not
swapped is not charged.
> [accordion] Step by step: pay with one token
>
> 
## Compound: 10%
**10% of the fees added back · gas paid by us** (on auto-compound runs).
* It is never charged on your principal.
* What does not fit your range comes back to your wallet, with no fee.
* The swap inside a compound pays only the pool fee. There is no 0.65% on it.
* On Uniswap v4, **Send fees to my wallet** collects the fees for you instead: 10% of the fees collected,
and the other 90% goes to your wallet. Gas paid by us.
## Auto-range and auto-exit: 0.15%
| Example | Uniswap v4 | Uniswap v3 |
| - | - | - |
| Move a position with \$10,000 of principal and \$40 of uncollected fees | \$15.00 (the \$40 of fees is not charged and goes into the new position) | About \$15.06 (0.15% of \$10,040 added to the new position) |
| Close a position with \$5,000 of principal | \$7.50 | 0.15% of what comes out |
The swap inside a move is about half of the value. It pays the pool fee and Uniswap's protocol fee only:
on v4 at most your highest swap fee (default 1%), on v3 only in the fee tiers Goat lists for the pair.
Price movement during the swap is limited by your price protection (default 0.50%).
## Where fees go
Every Goat LP fee goes to Cashmere's fee address,
[`0x2bf95e5f307FB84e19851865193a14DaB01A561F`](https://robin.etherscan.io/address/0x2bf95e5f307FB84e19851865193a14DaB01A561F).
* Compound fees and v4 automation fees are paid out in the same transaction.
* v3 auto-range and auto-exit fees stay in those contracts until Cashmere withdraws them.
* The 0.65% fee is paid by Uniswap's Universal Router straight from the swap output.
## Can fees change?
* Compound 10%: fixed in the one-click compound contracts. The automation fees (10% on v3 auto-compound,
0.15% on auto-range and auto-exit) can only be **lowered**. No one can raise them.
* The app shows each automation's fee as its contract holds it now, read on chain, so a cut shows on the next
read. For an automation that is not live yet it shows the planned fee, marked "Fee (planned)".
* The 0.65% manual-tool fee is an app setting with a hard limit of 1% in the app's code. The exact rate is
written into every transaction you sign.
* The owner Safe can change the fee address. Before any automation transaction, the app checks that the
contract's fee address is the one above.
> [!NOTE]
>
> Gas for keeper runs is paid by Cashmere. It still shows in the position's gas line in analytics, because
> the position used the service.
# Getting started
Source: https://docs.cashmere.exchange/goat-lp/getting-started
Connect, find a pool, open a position and manage it.

> [!WARNING]
>
> Goat LP is experimental. Use small amounts.
## Before you start
* **A wallet on Robinhood Chain** (chain ID 4663), with a little ETH for gas.
* **The right site.** Only `app.cashmere.exchange`. Cashmere will never message you first, or ask for your
keys or a signature anywhere else.
* **The idea.** You deposit two tokens into a price range. While the price is inside the range, the position
gets a share of the swap fees. Outside it, the position holds one token and gets no fees.

## Open a position

**1. Pick a pool**
Browse **Pools** (search and sort by TVL, volume or fee APR), **Stock pools** (pools built around
Robinhood stock tokens that pass Goat LP's filters) or **Top positions**. A listing is not a
recommendation.
**2. Pick a range**
Use a preset (±1%, ±5%, ±10%, ±20% or Full) or set your own bounds. Bounds snap to the pool's price
steps, so the review shows the exact ones. A narrow range gets a larger share of the swap fees while the price is
inside it, and leaves the range more often.
**3. Enter amounts, or one token**
Type one amount and the other follows the pool's ratio. Or deposit **one token**: part of it is swapped
to match the range. Only that swapped part pays the 0.65% Goat LP fee.
**4. Read the review, then sign**
The review lists each wallet step in order, the minimum you will get, and any fee in tokens and dollars.
Token approvals are for the exact amount. On Uniswap v4 they go through Permit2 and expire after
30 minutes. The new position NFT goes to your wallet.
On WETH pairs you can pay the WETH side with ETH. The Uniswap position manager wraps it in the same transaction
and sends unused ETH back to your wallet. No WETH approval is needed. On Uniswap v3 you can also start a
one-token deposit from ETH. When you pay with ETH on Uniswap v4, unused ETH and WETH fees come back to you
as ETH. If your wallet cannot receive ETH back, the app says so: "Pay with WETH instead." On Uniswap v3, a
withdrawal or a fee collect pays the WETH part as WETH, not ETH.
## Manage a position
Open the position from your **Dashboard**. The main buttons sit at the top.

> [accordion] Deposit
>
> Adds to the same position at the same range. With two tokens, only what fits the ratio is added; the
> rest stays in your wallet. With one token, part is swapped first (0.65% of the swapped part). On Uniswap
> v4, the position's uncollected fees are settled inside the deposit, so fewer tokens are taken from your
> wallet; any fee surplus comes back to your wallet in the same transaction. On Uniswap v3, uncollected fees
> stay in the position; a deposit does not add them.
> [accordion] Withdraw
>
> Take out part or all of the position, as both tokens (no Goat LP fee) or as one token (0.65% of the
> swapped part). The app does not swap through a pool that taxes swaps.
> [accordion] Collect fees
>
> Sends the position's fees to your wallet. In both tokens it costs only gas. As one token, the swapped part
> pays 0.65%.
> [accordion] Move range
>
> Closes the position at the current price and opens a new one in the range you choose, with a new
> position number. Uncollected fees go into the new position. If the move needs a swap, the swapped part
> pays 0.65%.
> [accordion] Compound
>
> Collects the fees, swaps part of them to the range's ratio and adds them back. The fee is **10% of the
> fees added back**. The NFT goes to the Goat compound contract and comes back in
> the same transaction, or the whole transaction fails.
> [accordion] Automate
>
> Opens the setup sheet for auto-compound, auto-range or auto-exit. See [Automation](/goat-lp/automation).
## After you sign
* Every action is simulated first. If it would fail, you see the reason instead of a wallet prompt.
* If you reject a request in your wallet, nothing is sent.
* After a transaction confirms, the position refreshes straight away.
* On Uniswap v4, some tools that swap take two transactions: adding one token to a position you already
have, withdrawing or collecting to one token, and moving a range with a swap. The review lists both.
Wallets that can batch calls confirm them once. If the second one is not sent, your funds stay in your
wallet as two tokens: nothing is lost, and you can finish later.
> [!NOTE]
>
> You do not need Goat LP to leave. Your position is a Uniswap NFT in your wallet, and you can withdraw it
> at Uniswap or on the block explorer, unless the pool's hook or one of its tokens blocks it.
> [Security](/goat-lp/security#leave-without-the-app) shows every step.
# Goat LP
Source: https://docs.cashmere.exchange/goat-lp/overview
Analytics, manual tools and automation for Uniswap v3 and v4 positions on Robinhood Chain.

> [!WARNING]
>
> Goat LP is experimental. Use small amounts.
Goat LP helps you provide liquidity on **Uniswap v3 and v4** pools on **Robinhood Chain** (chain ID 4663).
Your position stays an ordinary Uniswap NFT in your own wallet. Nothing on these pages is financial advice.

## What you get
| Part | What it does | Cost |
| - | - | - |
| **Analytics** | Every pool, position and wallet, with PnL against holding, fees, gas and rewards | Free |
| **Manual tools** | Create, deposit, withdraw, collect, move range and compound. One-token deposits and exits (zaps) | Gas only; 0.65% of the swapped part when a tool swaps; compound: 10% of the fees added back |
| **Automation** | Auto-compound, auto-range and auto-exit, run by a Goat keeper inside limits you set | 10% of the fees added back, or 0.15% per move or exit. Gas paid by us |
Every manual fee is shown in tokens and dollars before you sign; automation fees are shown as a rate in the
setup sheet. See [Fees](/goat-lp/fees).
## What is live
* Analytics, every manual tool, and auto-compound, auto-range and auto-exit on Uniswap v3 and v4.
* **Allow for all positions**: one wallet permission that keeps auto-range running after every move.
[Read more](/goat-lp/allow-for-all-positions)
Without it, auto-range moves a position once and then asks you to allow the new position: one tap.
## How the pieces fit

* **You** sign every manual action in your own wallet.
* **A keeper** is a Goat-run bot. It only triggers a run. It pays the gas and receives nothing.
* **The contract** decides what may happen, checks prices and sends every output to the position's owner.
## Principles
> [card] Your position stays yours
>
> The NFT stays in your wallet. Where a contract needs it for a moment, it comes back in the same
> transaction, or the whole transaction fails.
> [card] Checked before you sign
>
> The app decodes every transaction it builds and checks the recipient, the minimums, the contract
> and the fee before your wallet sees it.
> [card] You choose each permission
>
> Automation works through a permission for one position, or for all positions if you allow that for
> auto-range or auto-exit. Token approvals are for the exact amount.
> [card] No upgradeable contracts
>
> No proxy, no delegatecall. A Cashmere-controlled Safe owns them. Adding a keeper, a pair or a price
> source waits 24 hours in public.
## Read next
> [card] [Getting started](/goat-lp/getting-started)
>
> Connect, find a pool, open a position and manage it.
> [card] [Automation](/goat-lp/automation)
>
> What each automation does, what you allow and how to stop it.
> [card] [Fees](/goat-lp/fees)
>
> Every fee and its exact base.
> [card] [Risks](/goat-lp/risks)
>
> What can go wrong. Read this before you deposit.
# Risks
Source: https://docs.cashmere.exchange/goat-lp/risks
What can go wrong when you use Goat LP. Read this before you deposit.

> [!WARNING]
>
> Goat LP is experimental. Use small amounts.
Providing liquidity can lose money even when the pool pays fees. Nothing in these docs or in the app is
financial advice, and no figure is a promise of future returns.
## The main ones
| Risk | In one line |
| - | - |
| **Divergence** | A position is worth less than simply holding its tokens whenever the price has moved away from your entry, in either direction |
| **Out of range** | Outside your range the position holds one token and gets no fees |
| **New software** | Goat LP is new and its contracts may contain bugs that reviews missed |
| **Keepers** | Automated runs can be late, or not happen at all |
| **Fast moves** | An exit can fill past your level when the price jumps |
## Details
> [accordion] Price and divergence
>
> * Divergence (impermanent loss) is final when you withdraw. Narrow ranges get a larger share of the swap fees while in
> range, and lose to divergence faster.
> * A position can show healthy fees and still lose money against holding once divergence and gas are
> counted. The analytics show the split.
> * Stock-token pools trade around the clock, but their outside price does not always update. When it
> does, the pool can jump to it at once, across a whole range.
> * In a thin pool one trade moves the price a lot. The minimum in the review is what protects you.
> [accordion] Smart contracts
>
> * Goat contracts can contain bugs that the internal reviews missed.
> * Contracts Goat LP did not write can fail too: Uniswap, Permit2, Revert Finance's V3Utils, Chainlink
> feeds, every token and every v4 hook.
> * A token's issuer can pause it or block transfers. Part of a position or its fees can then be stuck.
> [accordion] Automation and keepers
>
> * Runs are not guaranteed at your trigger price, or at all, while a keeper is offline or behind.
> * Small position: runs wait until enough fees build up, so they can be far apart. A position under about
> \$50 is too small for us to move.
> * A withdraw-only exit acts at the pool price when the trigger is seen, which in a fast move can be past
> your level. A short spike can trigger it, and the position stays closed if the price comes back.
> * A swap exit waits until the pool price agrees with the outside price, so it can act later.
> * Every move pays 0.15% plus a swap, and locks in the price change since the last one. A choppy price
> can trigger many moves.
> * When price sources are missing, stale or disagree, swap-based runs wait. Price checks come first, so a
> run you expected may not happen.
> [accordion] Permissions
>
> * A permission on a position lets the allowed contract manage that position. Allow only the addresses on
> [Contracts](/goat-lp/contracts), and stop automation when you no longer want it.
> * [Allow for all positions](/goat-lp/allow-for-all-positions) covers every position of
> that Uniswap version in your wallet, now and later. Goat's code acts only on positions with a Goat rule.
> On v3 its move limit and time between moves are kept by Goat's system, not by the contract.
> * [Auto-exit for all positions](/goat-lp/allow-for-all-positions#auto-exit-for-all-positions) lets Goat AutoExit
> (v3) or the Goat engine (v4) close any position of that Uniswap version in your wallet that has an auto-exit
> rule, at that rule's level. On v3, Goat's system, not the contract, makes sure that only rules you set or
> confirmed after giving this permission can run.
> [accordion] Hooks, taxes and odd tokens
>
> * A Uniswap v4 hook runs its own code on swaps and liquidity changes. It can change fees, take a share
> of swaps or block withdrawals for a while. A reviewed hook can still surprise.
> * Some pools keep a share of every swap for the hook. That share is not a fee to liquidity providers.
> * Some tokens tax transfers or refuse some addresses. Collecting or withdrawing them can fail or return
> less than shown.
> * A token can copy another token's ticker. Goat LP marks these **Not the original**. Check the address.
> [accordion] Analytics and the chain
>
> * Numbers come from Goat LP's own index and price rules. The index can fall behind and a rule can be
> wrong. Check important numbers against the chain.
> * APR and estimates describe the past. They are not forecasts.
> * Robinhood Chain is a young network. It can slow down, stop or reorganise recent blocks.
> * Use only `app.cashmere.exchange`. Whatever a page shows, what your wallet displays is what you sign.
> [!NOTE]
>
> Questions or a problem to report: [contact@cashmere.exchange](mailto:contact@cashmere.exchange). For
> vulnerabilities, see [Security](/goat-lp/security#report-a-vulnerability).
# Security
Source: https://docs.cashmere.exchange/goat-lp/security
What protects your position, what to check before you sign, how to remove approvals and how to leave without the app.

> [!WARNING]
>
> Goat LP is experimental. Use small amounts.
The Goat LP contracts have been through internal security reviews. The app only sends an automation
transaction when the code at the contract's address matches the build pinned in the app.
## The short version
> [card] Your NFT stays in your wallet
>
> Automation works through a permission for one position. Where a contract needs the NFT for a moment,
> it comes back in the same transaction, or the whole transaction fails.
> [card] Smallest possible approvals
>
> Token approvals are for the exact amount. On Uniswap v4 they go through Permit2 and expire after
> 30 minutes. A token that already gives Permit2 a permanent allowance skips that approval step; the
> allowance to Uniswap is still exact and lasts 30 minutes.
> [card] Checked before you sign
>
> The app decodes the final transaction and refuses it unless the recipient, minimums, deadline, contract
> and fee are all as expected.
> [card] No upgrades, slow admin
>
> No proxy, no delegatecall. A Cashmere-controlled Safe owns the contracts. Adding a keeper, a pair or a
> price source waits 24 hours in public. See [Contracts](/goat-lp/contracts#roles).
## What the app checks before you sign

If any rule fails, your wallet never sees the request.
* **Recipient.** Every output goes to your connected wallet.
* **Paying with ETH.** On a WETH pair the deposit goes straight to Uniswap's position manager and ends with the
refund of unused ETH to your wallet in the same transaction (v3 `refundETH`, v4 `SWEEP`). The app refuses any
request that would leave ETH or WETH in a contract or send it anywhere but your wallet.
* **Minimums and deadline.** Every swap, add and remove has a minimum above zero; deadlines are minutes away.
* **Known contracts.** Contract addresses come from the app's own build, never from the analytics API, and
automation code is checked on chain against the pinned version.
* **Fee.** A Goat LP fee may go only to the fee address, at exactly the configured rate.
* **Permissions.** An automation permission must be for one position, to a Goat automation contract. The two
exceptions are the permissions for all positions of auto-range that keeps running and of auto-exit, each after its own
consent screen, to the addresses on [Contracts](/goat-lp/contracts).
* **Simulation.** Every action is simulated on chain before it is offered for signing.
## What you should check
* **The address bar:** only `app.cashmere.exchange`. Cashmere never messages you first.
* **The contract** in your wallet: a Uniswap contract, Permit2, Revert Finance's V3Utils, or a Goat contract
listed on [Contracts](/goat-lp/contracts).
* **Approvals:** a token approval names the exact amount; a position permission is `approve` for one
position number.
* **Permissions for all positions:** Goat LP asks for `setApprovalForAll` in two flows only, each after its own consent
screen: [Allow for all positions](/goat-lp/allow-for-all-positions) for auto-range that keeps running (to Goat AutoRange
on v3, the Goat engine on v4) and
[auto-exit for all positions](/goat-lp/allow-for-all-positions#auto-exit-for-all-positions) (to Goat AutoExit on
v3, the same Goat engine on v4). Auto-compound always uses a permission for one position. If anything else
asks, or names another address, stop.
* **Never** sign a message you do not understand, and never type a seed phrase anywhere.
> [!NOTE]
>
> **What you sign.** The only message Goat LP asks you to sign is for v4 auto-compound. Each one is a typed
> message (EIP-712) of the Uniswap v4 position manager ("Uniswap v4 Positions NFT", chain 4663). It has four
> fields:
>
> * `spender`: `GoatAutoCompoundV4`, the address on [Contracts](/goat-lp/contracts#compounding)
> * `tokenId`: your position number
> * `nonce`: a number that lets the message be used only once
> * `deadline`: the end date you picked, at most 90 days away
>
> If your wallet shows another spender, another position number or an end date more than 90 days away, do not
> sign.
## Remove approvals
| What | How |
| - | - |
| An automation | **Stop** in the app. It turns the rule off and removes its permission for that position, then checks the chain. On v4 auto-compound it also cancels the unused signed messages. Another app's permission on the position is left alone. A permission for all positions stays until you stop it (rows below) |
| A position permission, on the explorer | `approve(0x0000000000000000000000000000000000000000, yourPositionId)` on the v3 or v4 position manager. `getApproved(yourPositionId)` must then return the zero address |
| A token approval | Exact approvals are used up by the action. To clear a rest, `approve(spender, 0)` on the token |
| Auto-range for all positions | **Stop auto-range** in the app, or `setApprovalForAll(GoatAutoRange, false)` (v4: the Goat engine) |
| Auto-exit for all positions | **Stop auto-exit for all positions** in the app, or `setApprovalForAll(GoatAutoExit, false)` (v4: the Goat engine) |
| A permission for all positions you gave another app | `setApprovalForAll(thatAddress, false)` on the position manager |
## Leave without the app
You do not need Goat LP to get out, unless the pool's hook or one of its tokens blocks it. Each step is a
transaction you sign on the block explorer (Contract, then Write). Check every argument before signing.
**1. Remove the permission**
On the v3 or v4 position manager, call `approve(0x0000000000000000000000000000000000000000,
yourPositionId)`. Without the permission no automation can touch the position.
**2. On v4, cancel signed messages**
A signed message you gave for v4 auto-compound could set the permission again until it is used or its end
date passes. Call `revokeNonce(nonce)` on the v4 position manager for each unused one. The app's **Stop**
does this for you.
**3. Clear the rule (optional)**
Auto-compound: `configToken` with an all-off setting on the auto-compound contract. Auto-range or
auto-exit on v4: `clearConfig(yourPositionId)` on the Steward; it works even when the contract is paused.
On v3: `configToken` with an all-zero setting on the auto-range or auto-exit contract.
**4. Withdraw at Uniswap**
On v3, call `decreaseLiquidity` and then `collect` to your address. Minimums of 0 accept any price; only
use 0 if you accept that. On v4, use Uniswap's interface or the Withdraw button in Goat LP, which does
not depend on the analytics API.
If an NFT were ever stuck in a Goat compound contract, only its owner, the Cashmere-controlled Safe, can
move it out with `emergencyWithdrawNFT`. Contact us below.
## How Goat LP is watched
Keepers, sentinels (the independent monitors) and watchers raise alarms, and every alarm reaches the
Cashmere team by e-mail. The team can pause at once through the guardian Safe.
> [accordion] How an alarm reaches the team
>
> 
## Report a vulnerability
Email [contact@cashmere.exchange](mailto:contact@cashmere.exchange) with the contract, the steps to
reproduce and the impact. Please do not test against other people's positions on mainnet, and give us time
to fix an issue before sharing details publicly.
# Contracts
Source: https://docs.cashmere.exchange/goat-street/contracts
Every deployed address, and what is fixed in each of them.
Goat Street runs on Robinhood Chain mainnet, chain ID **4663**. Every contract below is verified on
the explorer — read the source there rather than taking this page's word for what they do.
Nothing here needs this site. Distributing, delivering and clearing stale positions are all open to
anyone, the ledger is on chain, and a holder who never loads this page can call all of it directly.
## Deployed
| Contract | Address | What it holds |
| - | - | - |
| `GoatSoftStake` | [`0x29A23E6b…2969`](https://robinhoodchain.blockscout.com/address/0x29A23E6bF5fF54A897cF100654dA0aE452482969) | The registry. Positions, rarity, weight, entry pricing and the tenure clock |
| `GoatDistributor` | [`0x7fa5602D…0Db3`](https://robinhoodchain.blockscout.com/address/0x7fa5602Dc38a35E00f7D6c93a90E7D6982760Db3) | The engine. Payout choices, royalty conversion, the credit ledger and delivery |
| `GoatPriceFloor` | [`0x57Fdc93c…9ec2`](https://robinhoodchain.blockscout.com/address/0x57Fdc93c7Cd0381b0E6D418570ac3fd3490e9ec2) | Derives each swap's minimum from Chainlink marks |
| `GoatSwapRouter` | [`0xa37Ff8A5…d216`](https://robinhoodchain.blockscout.com/address/0xa37Ff8A53Aa3d0fB31D25B579F6a6C0198cAd216) | Buys the chosen assets from Uniswap V3 pools, one route per asset |
| `ERC6551Registry` | [`0x211a83BE…Ef9b`](https://robinhoodchain.blockscout.com/address/0x211a83BEE2eDE8fe3004A1CfE9Ad9fbD7340Ef9b) | Derives the wallet address each NFT owns |
| `Goat6551Account` | [`0xBAD1a0Ec…E5fD`](https://robinhoodchain.blockscout.com/address/0xBAD1a0Ec18760c829b342c2F5378729B23D8E5fD) | The implementation those wallets are cloned from |
| Collection | [`0xC21159F4…C929`](https://robinhoodchain.blockscout.com/address/0xC21159F412c294ca2C38f2A9eCAAcCF9d93eC929) | GoatStreetCashmere. 6,666 NFTs |
## What is fixed and what can move
Read this next to [Administrative Powers](/goat-street/operations#administrative-powers), which
covers who holds the keys. This table is about what those keys can and cannot reach.
| | Value | Fixed how |
| - | - | - |
| Withdrawal lock | **4 hours** | Set at construction. No setter, and capped at 7 days by a constant |
| Emergency notice | **24 hours**, expiring 48 hours later | Constant |
| Entry-fee split | **50 / 50** to the reward pot and the treasury | Constant. The destination can be repointed; the ratio cannot |
| Entry-fee treasury | [`0x2bf95e5f…561F`](https://robinhoodchain.blockscout.com/address/0x2bf95e5f307FB84e19851865193a14DaB01A561F) | Repointable by the owner |
| Rarity table | **frozen** | Sealed. Both setters revert permanently |
| Level ladder | 1.00×, 1.25×, 1.50×, 2.00×, 3.00× at 0, 8.3, 22.2, 55.6 and 150 days | Constant. No setter and no owner |
| Ring floor | **0.1 ETH** | Owner |
| Ring cap | **0.5 ETH** | Owner. A pot above it is rung in several passes |
| Menu | 15 assets | Owner. Capped at 16 |
| Weight source | the registry above | Immutable on the engine |
> [!WARNING]
>
> The wallet registry and account implementation are **immutable on this engine**, so no setter on
> the live contracts can move where a delivery lands.
>
> That is not the same as saying a delivery can never be redirected. Replacing the engine is an
> owner power, and a replacement is only checked for naming this registry as its weight source — not
> for using the same wallet registry. An admin who deployed a new engine with different ones would
> send *future* deliveries to different addresses. It takes a deployment and a visible transaction,
> and the predecessor keeps paying what it already owes, but it is a thing the key can do. See
> [Operations](/goat-street/operations#if-the-engine-is-ever-replaced).
## Verifying the rarity table yourself
Rarity is not read from metadata at request time — it is a table written into the registry and then
sealed. What the seal committed to is a SHA-256 hash of the collection's metadata file.
That means the whole chain is checkable by anyone: hash the published metadata file, compare it to
the hash stored on the registry, then read any token's tier straight from the contract and check it
against the file. The registry also records that it covered all 6,666 ids rather than a prefix.
Tiers are numbered 1 to 7 in the order on [Tiers](/goat-street/tiers) — 1 is Intern Broker, 7 is
King Broker.
## Royalty
The collection advertises ERC-2981, but its on-chain royalty is **not configured** — a venue reading
the standard collects nothing. Creator earnings are configured in the marketplace's own panel
instead, split between the engine and the treasury, and enforced by the marketplace off-chain rather
than by a contract. That is a weaker guarantee than the entry-fee split above, and it is described
in full under [Rewards](/goat-street/rewards#where-the-money-comes-from).
> [!WARNING]
>
> **Check an address here against the explorer before you sign anything.** A contract with a
> matching name at a different address is not this contract, and no page — including this one — is a
> substitute for reading the chain.
# Levels & Tenure
Source: https://docs.cashmere.exchange/goat-street/levels
A level is time held, and nothing else. No token, no purchase, no approval.
## What a level is
A **level** raises how much of every distribution your NFT takes, up to **3.00×**, and it is earned
by one thing only: keeping the NFT registered to the same wallet.
There is nothing to buy. No progression token, no approval, no burn, no emission schedule, and no
pot for anyone to fund. The contract reads a clock.
```
weight = rarity multiplier × level multiplier
```
> [!NOTE]
>
> Every NFT climbs at the same rate. A King Broker and an Intern Broker reach the top level on the
> same day — rarity decides how large your slice is, never how fast you climb.
## The schedule
Five levels. Each threshold is a fixed amount of unbroken tenure.
| Level | Tenure required | Multiplier |
| -: | -: | -: |
| 0 | on registration | 1.00× |
| 1 | 8.3 days | 1.25× |
| 2 | 22.2 days | 1.50× |
| 3 | 55.6 days | 2.00× |
| 4 | **150 days** | **3.00×** |
## You press the button
Tenure is not weight until it is **banked**, and banking it is a call you make.
**1. Check what you have earned**
The app shows the level your tenure currently justifies, and how long is left until the next
one. Reading it costs nothing and needs no transaction.
**2. Bank it**
Level up. Your weight rises in the same transaction, and the engine is told immediately.
**3. Repeat at each threshold**
Nothing is lost by waiting, but nothing is gained either.
> [!WARNING]
>
> **A level is never automatic.** A position that has earned level 4 and never banked it still
> carries level 0 weight and is paid as a level 0 holder. Press it when it is due — or bank several
> NFTs at once.
Levelling up **sets** your position to what the clock has earned; it does not increment. Calling it
repeatedly cannot grant a level your tenure does not justify, and calling it early is refused rather
than granting partial credit. Anyone may do it for any NFT — it can only ever apply what that NFT
already earned, so there is nothing to gain by doing it on someone else's.
## The clock
```mermaid theme={null}
flowchart LR
A[NFT in wallet
unregistered] -->|register| B[Clock starts
level 0]
B -->|time passes| C[Level 1 · 2 · 3 · 4
banked by you]
C -->|sell or transfer| D[Position cleared]
D -->|buyer registers| B
```
> [card] Starts at registration
>
> Not at mint, not at launch. Nobody is handed tenure for time before their position existed.
> [card] Dies with the sale
>
> Clearing a position deletes the level, the clock and the entry it paid. The buyer starts at
> zero.
> [!WARNING]
>
> **Moving the NFT at all restarts the clock** — not only selling it. Sending it to a hardware
> wallet, into an escrow, or through a bundler looks identical to a sale from the contract's side,
> because the only thing it can see is that ownership changed. There is no grace period.
This is the whole point of the design: the multiplier is a reward for holding, and it cannot be
handed to somebody else. A borrowed NFT earns level 0 for the length of the loan, and the lender's
tenure is gone when it comes back.
## Levelling does not lock your rewards
Registering raises weight, and that starts the four-hour withdrawal lock. **Levelling up raises
weight and does not.**
The engine is told which kind of rise it is hearing, so an earned level is exempt — and it is safe
by construction rather than by policy, because the shortest level takes longer to reach than the
longest lock the engine can be configured with.
> [!NOTE]
>
> This is why levelling is worth doing the moment it is due. It costs a transaction, applies
> immediately, and takes nothing away.
## Why time rather than a token
An earlier design accrued a burnable point that holders spent on the same five multipliers. Time
replaces it, on the same schedule, and removes four problems at once: nothing is minted, so there is
no supply to model and no pot to fund; there is no second currency to approve and claim before it
can be spent; there is no keeper or daily funding transaction to keep alive; and capital buys
nothing — it is the same 150 days for the largest holder and the smallest.
Comparable protocols sell their multiplier for a token, which makes it transferable in substance:
whoever pays gets it. Tying it to time is what makes it mean the one thing this collection wants it
to mean — that you are still here.
# Operations
Source: https://docs.cashmere.exchange/goat-street/operations
How the pieces fit together, what the operators can and cannot do, and how the code was tested.
## Architecture
Goat Street is seven contracts with a single direction of dependency. **Nothing is upgradeable**,
and no component can be swapped without an explicit, observable transaction.
| Contract | Responsibility |
| - | - |
| `GoatSoftStake` | The registry. Positions, rarity, weight, entry pricing and the tenure clock |
| `GoatDistributor` | The engine. Payout choices, royalty conversion, the credit ledger and delivery |
| `ERC6551Registry` + `Goat6551Account` | The wallet each NFT owns. Control moves with the NFT |
| `GoatSwapRouter` | Buys the chosen assets directly from Uniswap V3 pools, each verified against the factory |
| `GoatPriceFloor` | Derives each swap's minimum from Chainlink marks rather than a hand-set number |
The registry reports weight changes to the engine as they happen, which is why a distribution never
has to walk the holder set — it costs the same at sixty holders as at six thousand.
Two components are minimal proxies: the collection itself, and every goat's wallet. A minimal proxy
points at one implementation and cannot be made to point at another, so this changes nothing about
"nothing is upgradeable".
## Custody
> [card] The protocol never holds an NFT
>
> The collection is touched through `ownerOf` and nothing else. There is no code path that could
> take possession.
> [card] No approval to grant
>
> Registration requires no allowance on the collection. A holder who registers has given the
> protocol nothing it could misuse.
> [card] Rewards are pulled, not pushed
>
> Value is credited to a ledger. A failed transfer never destroys a claim; it defers it.
> [card] Everyday recovery cannot reach holder funds
>
> The routine recovery paths are bounded by what is not already owed. Credited rewards are outside
> their reach by construction.
## Administrative powers
Deliberately narrow — but read this first.
> [!WARNING]
>
> **Every power below is currently held by a single externally-owned account**, not a multisig:
> `0xF3fcC8E2cb2b1d18932d6065fdbEc1E27483ECD7`. Handing these to a multisig or a timelock is a
> post-launch step. Until it happens, the bounds below describe what the key *may* do, not how many
> people must agree before it does.
| Power | Bound |
| - | - |
| Rarity table | Sealed permanently, and refused once any position exists |
| Level schedule | Fixed in code. No setter, no owner, identical for every NFT |
| Entry price | Base and slope fixed in code. Only the ceiling can move, and it is hard-capped at 5 ETH |
| Entry-fee split | A constant: half to the reward pot, half to the treasury, with no setter |
| Treasury address | Repointable by the owner; the ratio above is not |
| Asset menu | Capped at 16 entries, each of which must be a contract |
| Swap routes | Each pool is checked against the Uniswap V3 factory and the pair it claims to hold |
| Price floors | A manual floor cannot be set below a configured fraction of the oracle mark |
| Royalty split | **Not a contract.** Configured in the marketplace's creator-earnings panel and changeable there |
| Emergency withdrawal | Only for an announced asset, destination and amount; only 24 hours after the announcement; only within the 48 hours after that; only once |
| Rewards engine | Replaceable, and the replacement must already name this registry as its source |
Nothing here can mint an NFT or move one. Registration can be paused, which stops new weight
arriving without touching existing weight.
### The emergency hatch
There is one owner-only path that can move credited assets, and it is deliberate. It exists because
an audit found several ways for value to become permanently stuck, and a system with no way out of
the next one is more brittle rather than safer.
It is bounded by notice rather than by amount. The exact asset, destination and amount must be
announced on-chain 24 hours before it can execute, and the authority expires 48 hours after that —
so an announcement nobody executes becomes dead rather than standing indefinitely. Holders get a
full day to collect first.
> [!WARNING]
>
> **That notice is not a bound on what the owner can reach.** It is the price of the *announced*
> path only. The owner also configures the swap venue and the price floors, and those take effect
> immediately — so an owner willing to abuse the position does not need the hatch and does not have
> to wait. The real protection is who holds the key. It should be a timelock, and until it is, this
> is a trust assumption rather than a mechanism.
### If the engine is ever replaced
This is the one administrative action a holder would notice, so it is worth knowing what it looks
like from the outside.
Your **level is untouched** — levels live in the registry, which is not replaced. Your **existing
credit is not stranded** — the outgoing engine keeps whatever it already owes you and keeps paying
it. What changes is the withdrawal clock: the new engine learns your weight by being told it, which
reads as a fresh increase, so **the four-hour lock restarts for everybody at once**. Nothing is
lost.
> [!WARNING]
>
> One case is not covered by that. A position cleared before a migration and re-registered after it
> is recognised only by the **new** engine, so the predecessor's credit can never be delivered to
> it. If your position is cleared while a migration is announced, re-register **before** the switch,
> not after.
## Keeping it running
Three things need somebody to do them, and **none of them needs any privilege** — they are open to
anyone, and whoever does them holds no role on any contract and needs only gas.
| What | Why it matters |
| - | - |
| Clearing stale positions | A sale notifies no contract. Until a sold position is cleared it keeps its weight at the seller's level and keeps taking a share, diluting everyone still holding |
| [Ringing the Bell](/goat-street/the-bell) | Converts the pot and credits every position. Nobody else has a reason to pay for it |
| Delivering rewards | Moves credit into each NFT's own wallet, and deploys that wallet the first time |
> [!NOTE]
>
> Holders never have to wait for a keeper. Delivering is open to anyone, so you can push your own
> NFT's rewards into its wallet whenever you like — the app does it in one click.
## Assurance
| | |
| - | - |
| Tests | 359 local, 55 against a Robinhood mainnet fork |
| Invariants | 22 properties, each fuzzed at 256 runs × 200 depth — 51,200 calls, including cross-contract weight agreement and two-sided solvency |
| Mutation testing | Safety-critical guards deleted individually to confirm the suite fails |
| Live rehearsal | Full deployment and lifecycle on testnet: entry, registration, all four levels, payout choices, distribution, delivery into token-bound wallets, and a real sale with its clearing |
| Adversarial review | Repeated multi-agent audit rounds, each finding independently verified before it was accepted |
The audit record, including every finding and the reasoning behind each accepted risk, is maintained
alongside the source.
## Network
| | |
| - | - |
| Chain | Robinhood Chain |
| Chain ID | 4663 |
| Settlement asset | ETH, with WETH accepted and unwrapped |
| Price source | Chainlink feeds published on Robinhood Chain |
> [!WARNING]
>
> Every deployed address is listed on [Contracts](/goat-street/contracts) and verified on the block
> explorer. Check any address you are about to interact with against that page and against the
> explorer itself — never against a link somebody sent you.
# Goat Street
Source: https://docs.cashmere.exchange/goat-street/overview
A 6,666-piece NFT collection that pays its holders a share of real revenue, in the assets they choose.
## What it is
Goat Street turns a 6,666-piece NFT collection into a working claim on real revenue. Revenue arrives
on-chain, is converted into assets each holder picks, and is paid out in proportion to what that
holder owns and how long they have held it.
The engine does not care where that revenue came from — it splits whatever reaches it by weight.
Today what reaches it is **marketplace royalty** from secondary sales, plus **half of every entry
fee**. **Cashmere app revenue, and revenue from the products that follow, are intended to flow into
the same pot.**
**Half of every royalty collected goes to holders.** The other half funds the treasury.
Two things are split that way, and only one of them is a contract: the **entry-fee** split is fixed
in code with no setter, while the **royalty** split is a marketplace setting that whoever controls
that account can change. [Rewards](/goat-street/rewards#where-the-money-comes-from) states exactly
what each one guarantees.
Two things make it different from a conventional staking product.
> [card] Your NFT never leaves your wallet
>
> No deposit, no escrow, no lock. The protocol reads ownership; it never takes possession. You can
> list, transfer or sell at any moment without withdrawing anything first.
> [card] You choose what you are paid in
>
> Revenue arrives as ETH. Point your share at tokenized equities — NVDA, AAPL, TSLA and others
> trading natively on Robinhood Chain — or leave it in ETH. Each NFT chooses independently.
Your share of every distribution comes down to one number:
```
weight = rarity multiplier (1.00× – 7.20×, fixed at mint)
× level multiplier (1.00× – 3.00×, earned by holding)
```
> [!NOTE]
>
> Goat Street runs on **Robinhood Chain** (chain ID 4663). Every deployed address is listed under
> [Contracts](/goat-street/contracts).
## Where the money goes
```mermaid theme={null}
flowchart TD
S["Secondary sale
on a marketplace"] -->|royalty| SP["Creator earnings
split 50 / 50"]
SP -->|"50%"| T["Treasury"]
SP -->|"50%"| D["The reward pot"]
E["Entry fee
paid on every registration"] -->|"50%"| T
E -->|"50%"| D
X["Cashmere app revenue
and future products"] -.->|"planned"| D
D -->|"anyone may trigger"| SW["Bought into the assets
each holder chose"]
SW -->|split by weight| C["Per-NFT ledger"]
C -->|"anyone may trigger"| W["The NFT's own wallet"]
W -->|"holder withdraws"| H["Your wallet"]
```
Everything that reaches the pot is indistinguishable once it arrives, and all of it is split by the
same weight through the same ledger. Two streams feed it today — **marketplace royalty** and **half
of every entry fee**. **Cashmere app revenue and future products are intended to be routed there
too**; that is a commitment the team makes, not something a contract enforces, so treat it as
[roadmap](/goat-street/roadmap) rather than as mechanism.
Every arrow that moves value is open to anyone. There is no privileged keeper, no schedule to trust,
and no step where the team decides whether holders get paid.
What the treasury half is for is set out on [Roadmap](/goat-street/roadmap) — as an intention,
because no contract compels it and holders have no claim on what it earns.
## How it works
**1. Register**
Register your NFT and pay the entry fee it quotes in ETH. This records you as the holder, starts
your tenure clock, and puts your weight into the pool. **Your NFT never moves** — the fee is the
only thing that leaves your wallet.
**2. Choose your payout**
Optionally pick up to three assets from the menu and how to split between them. Skip this and
your share is paid in ETH.
**3. Earn**
Whatever has reached the pot is converted and credited against your weight every time
[the Bell](/goat-street/the-bell) is rung. Meanwhile your tenure clock runs.
**4. Level up**
At 8.3 days, and again at 22.2, 55.6 and 150, bank the level your tenure has earned — up to
**3.00×**, stacking on top of your rarity. Nothing is bought and nothing is burned; the contract
reads a clock.
**5. Collect**
Rewards are delivered into the wallet that belongs to your NFT, and you move them to your own.
Selling the NFT transfers that wallet with it.
## The four parts
> [card] [Rarity tiers](/goat-street/tiers)
>
> Seven tiers, from Intern Broker to King Broker, each with a fixed multiplier from 1.00× to
> 7.20×. Set at mint and sealed on-chain before the first registration.
> [card] [Levels & tenure](/goat-street/levels)
>
> Five levels, from 1.00× to 3.00×, earned purely by holding. Every NFT climbs at the same rate
> whatever its rarity, and selling resets the clock to zero.
> [card] [Rewards](/goat-street/rewards)
>
> Revenue converted into the assets you chose, credited by weight, and delivered to your NFT's
> own wallet.
> [card] [The Bell](/goat-street/the-bell)
>
> The public trigger that runs a distribution. Anyone can ring it. There is no privileged keeper
> and no schedule to trust.
## What it runs on
> [card] Robinhood Chain
>
> Chain 4663. Tokenized equities settle natively, which is what makes stock-denominated payouts
> possible without a bridge.
> [card] Chainlink price feeds
>
> Every conversion is bounded by an oracle-derived floor rather than a pool quote, so a thin
> market cannot fill a swap far from fair value.
> [card] Uniswap V3
>
> Swaps go straight to the pools through our own router. No third-party venue contract sits
> between the protocol and the liquidity.
> [card] Token-bound wallets
>
> Each NFT owns a standard ERC-6551 wallet. Rewards accumulate there, and control moves with the
> NFT on sale.
## What the protocol does not do
* **It never takes custody.** The collection is read through `ownerOf` and nothing else. There is no
approval to grant and no token to withdraw.
* **It never walks the holder set.** A distribution costs the same at sixty holders as at six
thousand.
* **It never pushes rewards to you.** Value is credited to a ledger and claimed when you choose.
Nothing depends on a bot delivering on time.
> [!WARNING]
>
> Rewards here are **promotional**, not dividends or investment income. Holding a goat gives you no
> equity, no shareholder rights, and no claim on revenue or the treasury. See
> [Terms](/goat-street/terms).
# Rewards
Source: https://docs.cashmere.exchange/goat-street/rewards
Where the revenue comes from, choosing what you are paid in, and how to collect it.
## Where the money comes from
Goat Street distributes real revenue. It arrives on-chain as ETH, is converted into whatever each
holder has chosen, and is credited in proportion to weight.
**The engine does not know where the money came from.** It splits whatever ETH reaches it, so
adding a new source is a matter of sending revenue to the same address — no contract change, no
migration, nothing for holders to opt into.
Two sources reach it today:
| Source | What it is |
| - | - |
| **Marketplace royalty** | Creator earnings on secondary sales of the collection |
| **Half of every entry fee** | Paid by each registration, split 50/50 with the treasury |
**Cashmere app revenue, and revenue from the products that come after it, are intended to be routed
into the same pot.** That is a commitment the team makes rather than something the contracts
enforce — the same kind of promise as the royalty split below, and it belongs in the same category
as everything on [Roadmap](/goat-street/roadmap).
Nothing about the payout itself is scheduled or discretionary. Revenue accumulates, and anyone can
[ring the Bell](/goat-street/the-bell) to convert and credit it.
> [!WARNING]
>
> **Be precise about what kind of promise the royalty split is.** Creator earnings are configured in
> the marketplace's own panel — half to the reward pot, half to the treasury — and enforced by the
> marketplace off-chain rather than by a contract, so whoever controls that account can change it.
>
> On-chain the collection advertises ERC-2981 but has **no royalty configured**, so a venue that
> reads the standard rather than running its own creator-earnings programme currently collects
> nothing.
>
> The **entry fee** split is different: it is a constant in the contract, half and half, with no
> setter and no admin path to change the ratio.
## What it costs to join
Registering a goat costs a fee in ETH. Half funds the reward pot, where it is distributed by weight
exactly like royalty. Half goes to the treasury.
The fee scales with rarity. A King Broker pays 7.20× what an Intern pays — and earns 7.20× the
share, so what you pay per unit of weight is identical whichever goat you hold.
Every entry adds a fixed **0.0000025 ETH** to the base price. It is a straight line applied per
entry, so nobody pays a jump for arriving a block later than someone else.
| Entry | Multiple | Intern | Junior | Senior | Executive | Whale | Giant | King |
| -: | -: | -: | -: | -: | -: | -: | -: | -: |
| 1st | 1× | 0.0050 | 0.0058 | 0.0065 | 0.0078 | 0.0120 | 0.0185 | 0.0360 |
| 2,001st | 2× | 0.0100 | 0.0115 | 0.0130 | 0.0155 | 0.0240 | 0.0370 | 0.0720 |
| 4,001st | 3× | 0.0150 | 0.0173 | 0.0195 | 0.0233 | 0.0360 | 0.0555 | 0.1080 |
| 8,001st | 5× | 0.0250 | 0.0288 | 0.0325 | 0.0388 | 0.0600 | 0.0925 | 0.1800 |
| 18,001st | 10× | 0.0500 | 0.0575 | 0.0650 | 0.0775 | 0.1200 | 0.1850 | 0.3600 |
All figures in ETH. The price doubles a third of the way through the first round of registrations.
> [!WARNING]
>
> **Selling clears your entry.** The buyer registers as a new entrant and pays the price the curve
> has reached; your payment does not carry over to them. The counter therefore tracks turnover, not
> goats — one goat changing hands ten times advances it ten steps.
> [!NOTE]
>
> The rise decelerates. The step from the first entry to the second is 0.05%; by the
> hundred-thousandth it is 0.001%. Entering early is worth the most precisely because the
> proportional climb is steepest at the start.
## What determines your return
Your share of any distribution is one fraction:
```
your share = your weight ÷ total registered weight
```
| | What moves it | Do you control it |
| - | - | - |
| Rarity multiplier | Fixed at mint, 1.00× to 7.20× | Only by which NFT you buy |
| Level multiplier | 1.00× to 3.00×, earned over 150 days | **Yes** — hold, and level up |
| Total registered weight | Rises with every registration and every level anyone banks | No |
| Size of the pot | Whatever revenue reaches it — royalty and half of every entry fee today | No |
> [!NOTE]
>
> **The level is the only lever you hold after you have bought.** It is also the largest single one
> available: 3.00× is a bigger move than every rarity step below King Broker.
### Three things worth understanding before you buy
**Entry fees are a transfer, not revenue.** They come from somebody registering and are paid to
everybody already registered — real money to receive, but it does not come from outside the system.
Counting entry fees alone and no other income at all, an entrant is ahead of that flow until roughly
the 3,300th and behind it after.
External revenue is what carries the return over any long horizon. Today that means marketplace
royalty; the intention is that Cashmere app revenue and later products add to it. If you are
entering late, expect your return to come from external revenue rather than from the entries behind
you — and weigh the intended sources as intentions, not as income already arriving.
**Every registration dilutes the ones before it.** There is no cap on how many NFTs register, and
each one enlarges the denominator. A holder who does nothing sees their share fall as the collection
registers around them. That is what makes the entry fee coherent: price rises while the value of an
entry falls, and together those stop the curve running to its ceiling on its own.
**Sold positions keep taking a share until somebody clears them.** A sale notifies no contract.
Until a stale position is cleared it keeps its weight at the seller's level and keeps taking a
share, which comes out of everybody still holding. Nothing can be extracted from it — the engine
refuses to pay a position the registry no longer recognises — but the dilution is real while it
sits there. Clearing one is open to anyone and costs only gas.
## Choosing what you are paid in
Each NFT chooses independently.
> [card] Take ETH
>
> The default. Register and do nothing else, and your share of every distribution is credited in
> ETH. No decision, no attestation, and no exposure to equity price movement.
> [card] Take equities
>
> Pick up to three assets from the menu below and split your weight between them.
A choice is a standing instruction, not a one-off order. It applies to every distribution from the
moment it is set until you change it, reset it, or move the NFT. A transfer clears it — including a
move to your own hardware wallet, since the contract only sees that ownership changed.
> [!WARNING]
>
> **An asset can be removed from the menu.** If that happens, a position still pointing at it is
> left out of the split entirely — no equity and no ETH — until you choose again. The removal is
> visible on chain, but nothing updates your choice for you. The app flags a stale choice; if you
> manage a position yourself, check it after any menu change.
## The menu
Fifteen tokenized equities and ETFs, capped at sixteen. Every address below is the canonical
Robinhood Stock Token published at
[docs.robinhood.com/chain/contracts](https://docs.robinhood.com/chain/contracts).
| Asset | Symbol | Contract |
| - | - | - |
| NVIDIA | NVDA | `0xd0601CE157Db5bdC3162BbaC2a2C8aF5320D9EEC` |
| Apple | AAPL | `0xaF3D76f1834A1d425780943C99Ea8A608f8a93f9` |
| Microsoft | MSFT | `0xe93237C50D904957Cf27E7B1133b510C669c2e74` |
| Alphabet Class A | GOOGL | `0x2e0847E8910a9732eB3fb1bb4b70a580ADAD4FE3` |
| Amazon | AMZN | `0x12f190a9F9d7D37a250758b26824B97CE941bF54` |
| Tesla | TSLA | `0x322F0929c4625eD5bAd873c95208D54E1c003b2d` |
| AMD | AMD | `0x86923f96303D656E4aa86D9d42D1e57ad2023fdC` |
| Micron Technology | MU | `0xfF080c8ce2E5feadaCa0Da81314Ae59D232d4afD` |
| SanDisk | SNDK | `0xB90A19fF0Af67f7779afF50A882A9CfF42446400` |
| Strategy | MSTR | `0xec262a75e413fAfD0dF80480274532C79D42da09` |
| Palantir | PLTR | `0x894E1EC2D74FFE5AEF8Dc8A9e84686acCB964F2A` |
| SpaceX | SPCX | `0x4a0E65A3EcceC6dBe60AE065F2e7bb85Fae35eEa` |
| GameStop | GME | `0x1b0E319c6A659F002271B69dB8A7df2F911c153E` |
| iShares Silver Trust | SLV | `0x411eFb0E7f985935DAec3D4C3ebaEa0d0AD7D89f` |
| United States Oil Fund | USO | `0xa30FA36Db767ad9eD3f7a60fC79526fB4d56D344` |
> [!WARNING]
>
> **Check the address, not the ticker.** Robinhood's own documentation states it plainly: a token
> with a matching name or ticker but a different contract address is not a Robinhood Stock Token.
An asset earns its place by having a live Chainlink feed **and** enough depth to fill against it.
Depth is measured on chain by buying at several sizes and comparing the result to the oracle. Every
asset above fills within tolerance at the sizes a distribution can actually reach, with room to
spare — a single round is capped well inside the thinnest route on the menu.
> [!WARNING]
>
> Choosing an equity means holding that equity. Tokenized NVDA can fall like NVDA can fall, and the
> protocol takes no view on that — it converts and delivers, and the position is yours from that
> moment. Leaving your choice empty means being paid in ETH. Neither is presented here as the better
> one.
## How a distribution works
**1. Royalties arrive**
ETH accumulates from secondary sales and entry fees.
**2. The pot is split by asset**
Weight is totalled per chosen asset, and each asset's slice is sized by its share of that total.
**3. Each slice converts**
One swap per asset, bounded by an oracle floor. Weight that chose nothing takes its share
directly in ETH.
**4. Credit accrues**
Nothing is pushed. Your entitlement is recorded and can be collected whenever you choose.
> [!NOTE]
>
> **A slice that cannot fill is paid in ETH, not lost.** If an asset has no route at that size, a
> stale feed, or is paused for a corporate action, its share is credited to the holders who chose it
> **as ETH, in the same round**. It does not leak to everyone else and it is not held over — only
> the denomination changes, and it is claimable immediately.
## Where rewards land
Each NFT owns a real wallet — a standard ERC-6551 token-bound account, controlled by whoever holds
the NFT. Royalty payouts land there, because the revenue belongs to the NFT and transfers with it on
sale.
> [!WARNING]
>
> **Withdraw before you sell, and check the wallet before you buy.** Rewards sitting in an NFT's
> wallet go with the NFT in the same transaction, with nothing in the transfer to warn either side.
> A seller can also empty that wallet at any moment, including immediately before a sale settles,
> and marketplaces do not show its contents. This is inherent to the standard and cannot be
> prevented from inside the wallet.
### Collecting is two steps
**1. Deliver it to the goat**
Moves what you are owed into the NFT's own wallet. **Anyone can do this for any NFT**, so you
never depend on the team to be paid — and never pay gas for someone else's delivery either.
**2. Withdraw it to yourself**
Moves it from the NFT's wallet into the wallet you connect with. **Only the current holder can
do this.**
Until the second step is done, the rewards belong to the NFT rather than to you. The app does both
from one screen.
### The first four hours
A position that registered less than four hours ago is credited normally but cannot be withdrawn
yet. It is a deferral, not a forfeit: the credit sits in the ledger and pays in full once the four
hours are up. This is what stops buying, draining and selling being an instant round trip.
**Levelling up does not restart the clock**, because the level was earned by waiting rather than
acquired. Losing weight does not restart it either — nobody is made to wait again for being worse
off.
Selling inside that window costs you nothing you had earned: royalty credit belongs to the NFT, so
it transfers to the buyer along with the wallet it would have been paid into. What you give up is
only the ability to have taken it out early.
# Roadmap
Source: https://docs.cashmere.exchange/goat-street/roadmap
Where Goat Street goes after royalty: liquidity farming strategies on Uniswap V3 and V4.
> [!WARNING]
>
> **Everything on this page is intention, not a promise.** The rest of these docs describes
> contracts that are deployed and verified. Nothing here is deployed, none of it is committed to in
> code, and no dates are given. Judge the project on what is already on chain.
## What exists today
Goat Street converts revenue into tokenized equities and credits them to holders by weight. That is
the whole live product, and it is deliberately narrow: one conversion, one ledger, and whatever
revenue has actually reached the pot.
Two sources reach it today — marketplace royalty and half of every entry fee. **Cashmere app
revenue, and revenue from the products on this page, are intended to be routed into the same pot.**
The engine splits whatever arrives, so adding a source needs no contract change; what it needs is
the team actually sending it.
Half of the royalty, and half of every entry fee, goes to the treasury instead. Today that half is
a balance. The rest of this page is what it is meant to become.
## Liquidity farming
The plan is to put the treasury half to work in the same markets the rewards are bought from, and
to route what it earns back into the pot that pays holders.
Two venues: **Uniswap V3**, where the engine already buys, and **Uniswap V4**, where the depth on
this chain is going.
> [card] Concentrated liquidity farming
>
> Narrow ranges around the current mark on the tokenized-equity pairs, rebalanced as it moves.
> More fee income per unit of capital than a full-range position, in exchange for active
> management.
> [card] Delta-neutral LP farming
>
> Providing liquidity while hedging the price exposure that comes with it, so what is earned is
> the fee and the premium rather than a bet on the stock.
> [card] Automated liquidity farming
>
> Rebalancing, range moves and hedges run on rules published in advance, rather than by hand.
> [card] Options underwriting
>
> Selling volatility against tokenized stock inventory, collecting premiums rather than taking a
> view on direction. The venue is not chosen yet.
Why these and not something else: the pools that price a distribution are the same ones a position
would earn fees in. That makes this adjacent to the live product rather than a new business.
> [!NOTE]
>
> **V3 and V4 are not the same job.** Goat Street's router buys through Uniswap **V3** today, so
> liquidity provided there deepens the pools a distribution actually fills against. V4 holds more of
> the depth on this chain, but the engine cannot reach its singleton pool manager yet — teaching it
> to is a separate step, and one the engine's own settings allow without touching the registry, the
> credit ledger or the frozen rarity table.
## Access
The liquidity tools are open to everyone, and the same fees apply to every user today. Benefits for
**Goat Street NFT holders** may be added later; none are offered now.
> [!WARNING]
>
> Access is a **product decision, not a security property**. It says who may use an interface. It is
> not a claim that any contract checks anything about you, and it does not make participation an
> investment, a share of a business, or a claim on revenue. The [Terms](/goat-street/terms) apply to
> everything on this page.
## What would come first
**1. Analytics**
Publish what the treasury holds and what it earns, before anything is automated. A strategy
nobody can audit is not ready to be automated.
**2. One manual position**
A single concentrated position in one pool the protocol already routes through. Small, visible,
reversible.
**3. Hedging it**
Delta-neutral only once the unhedged version has run long enough to know what it costs.
**4. V4 routing, then options**
Reach V4's depth from the engine, then underwrite options — volatility last, because being
wrong there is most expensive.
**5. Automation, then access**
Rules published and running for a while before anyone else's capital is invited in.
## The honest limit
Revenue funds rewards. The treasury half funds liquidity. That liquidity earns fees and premiums,
and those returns are meant to flow back into the pot that buys rewards.
Only one link in that loop is a contract. **What reaches the pot reaching holders is mechanism** —
distributing and delivering are open to anyone and the ledger is per NFT. Which revenue is sent
there in the first place is not: routing Cashmere app revenue, or anything else on this page, is a
plan the team can execute well, badly, or not at all.
> [!WARNING]
>
> **Treasury income is not a second reward stream, and holders have no claim on it.** Nothing in the
> contracts routes trading fees, option premium or LP income to holders. What holders are owed is
> whatever has actually reached the reward pot, split by weight. That is the whole of it — not what
> the treasury earns, and not what this page intends to send.
>
> If the treasury stopped tomorrow, every guarantee in these documents would still hold, because
> none of them depends on it.
# Terms
Source: https://docs.cashmere.exchange/goat-street/terms
What Goat Street rewards are, what they are not, and what you are agreeing to by using this interface.
These terms apply to the Goat Street interface and to the on-chain programme behind it. Two of the
statements below are also recorded on chain: every election commits a hash of the disclosure, and an
election that includes a restricted asset commits a hash of the eligibility statement as well. Both texts
are readable straight from the contract, and the interface shows you each one before you sign.
## What the rewards are
Distributions on Goat Street are **promotional rewards under a marketing programme**, paid to
broker NFTs that have been registered in the protocol. They are a reward for taking part.
They are **not dividends and not investment income**. Holding a broker NFT, or any token
distributed by this programme, gives you:
* no equity and no ownership stake in anything,
* no shareholder rights of any kind,
* no claim on revenue, profit, or the treasury.
What a registered NFT is entitled to is defined entirely by the reward pool and by weight — that is
the whole of it, and it is described in full under [Rewards](/goat-street/rewards). Nothing else
about this project creates an entitlement, including the treasury's own activity.
> [!WARNING]
>
> If you are reading a claim anywhere that these rewards are a yield, a return, a dividend, or a
> share of anyone's earnings, that claim is wrong and it is not ours. The text you commit on chain
> when you elect says so explicitly.
## Where you may not use this
**Swapping into tokenized stock is restricted in the United States.** Do not use those features if
you are located in, or a resident of, the United States.
More generally: by using this protocol you confirm that using this kind of financial product is
lawful where you are, and that you are permitted to receive what it distributes. That confirmation
is not decorative — it is the eligibility statement whose hash your election records on chain.
## What this site is
This site is **a user interface and nothing more**. It holds no funds, takes no custody, and has no
privileged position in anything it displays.
The contracts it talks to live entirely on chain and are permissionless. Registration, election,
ringing the bell, and delivery can all be started by anyone, directly, without this interface and
without our involvement. If this site disappeared tomorrow, every function it exposes would still
be callable and every reward already credited would still be claimable. That is a property of the
contracts, not a promise from us.
The consequence is worth stating plainly, and so is its limit. No routine path lets us stop a
distribution, redirect one, or decide who receives it: `distribute` and `deliver` are open to
anyone and the ledger is per-NFT. The exception is `emergencyWithdraw` — an owner-only hatch that
is unbounded on purpose, exists because value can otherwise become permanently stuck, and can only
move an asset, amount and destination announced on-chain 24 hours in advance. Those powers sit with
a single key today, not a multisig.
## What this is not
Nothing on this site or in this documentation is financial, investment, legal, or tax advice.
Nothing here is an offer or a solicitation to buy or sell any security.
Descriptions of how the contracts behave are engineering documentation. Where we describe something
the treasury *intends* to do — deploying its half of revenue as liquidity, for instance — it is
labelled as an intention rather than a mechanism, because no contract compels it and you have no
claim on it.
You are responsible for complying with the laws and regulations that apply to you. If you are not
sure whether that includes this, take advice before you register.
## Things that cost money to learn late
Not legal terms, but the three behaviours holders most often discover the hard way. Each is enforced
by the contracts, not by policy.
> [card] Rewards live in the NFT's wallet
>
> Delivery pays each NFT's own token-bound account, not the wallet you connect with. Sell or move
> the goat and everything inside that account goes with it.
> [card] A transfer clears the position
>
> Moving an NFT — including to your own hardware wallet — ends its registration, its election and
> its tenure. The next holder pays the entry price current at that moment.
> [card] Delivery waits four hours
>
> Credit cannot leave a position until four hours after its weight last rose without being
> earned. Levelling up is exempt.
# The Bell
Source: https://docs.cashmere.exchange/goat-street/the-bell
The public trigger that runs a distribution. Anyone can ring it.
## What it is
Royalties do not distribute themselves. Something has to convert the accumulated ETH into the assets
holders chose and credit each position. In Goat Street that something is called **the Bell**, and
**anyone can ring it**.
There is no keeper role, no privileged operator, and no schedule anyone has to trust. Ringing the
Bell is a single public function call, open to any address, and the caller is paid nothing for it.
If the team disappeared tomorrow, holders could keep the protocol paying by ringing it themselves.
## What happens when it rings
**1. The pot is measured**
Everything not already owed to a holder becomes the pot for this round.
**2. The pot is split by asset**
Weight is totalled per chosen asset, and each asset's slice is sized by its share of that total.
The weights are read once, up front, so nothing reached from inside a swap can move the split
underneath it.
**3. Each slice converts**
One swap per asset, each bounded by a floor derived from Chainlink marks. Weight that chose
nothing takes its share directly in ETH.
**4. Credit accrues**
Each position's entitlement is recorded. Nothing is pushed to anyone, and no holder list is ever
walked.
## Why it is open to everyone
> [card] No liveness dependency
>
> A protocol whose payouts depend on one bot is a protocol that stops paying when that bot does.
> Anyone being able to ring the Bell removes that failure mode entirely.
> [card] No trusted schedule
>
> Holders do not have to believe a stated cadence. They can check the pot on-chain and ring the
> Bell themselves the moment it is worth doing.
> [card] Constant cost
>
> A round costs the same at sixty holders as at six thousand.
> [card] Nothing to extract
>
> The caller sets no prices and receives no reward. Their only influence is a slippage bound they
> may set *tighter* than the protocol's own floor, never looser.
## What bounds the caller
Ringing the Bell is open, but it is not unconstrained.
| Guard | Effect |
| - | - |
| Minimum pot | A round is refused below a threshold, so the gas is never worth more than the value it moves |
| Maximum pot | A single round is capped, so a large accumulation converts across several passes instead of one oversized swap |
| Oracle floor | Every slice must clear a bound derived from Chainlink marks; a caller may tighten it, never loosen it |
| Settlement delay | Credit from a round cannot be extracted in the same block it was created |
| Matching books | The engine refuses to ring unless the registry currently names it *and* their two weight totals agree |
| A venue to swap at | If no route can reach any asset on the menu, the round stops rather than converting the whole pot to ETH |
## Rounds that do not fully fill
A slice can fail to convert for ordinary reasons — no route at that size, a feed that has gone
stale, an equity paused for a corporate action. When that happens its ETH is credited to **that
asset's own holders, as ETH, immediately and permanently**.
It is not returned to the general pot, and it is not held over for a later round. That distinction
matters: returning it to the pot would re-split it across every other asset, quietly moving value
from the holders it belonged to onto everyone else. Instead it stays with the holders it was sized
for, and only the denomination changes.
> [!NOTE]
>
> Delivery is separate and equally open: pushing a position's credited rewards into its own wallet
> can be done by anyone, for any NFT. See [Rewards](/goat-street/rewards#collecting-is-two-steps).
# Tiers & Weight
Source: https://docs.cashmere.exchange/goat-street/tiers
The seven rarity tiers, their multipliers, and how your share is calculated.
## How your share is decided
Every reward in Goat Street is split by **weight**. Weight is not a balance you top up — it is a
property of your NFT, and it comes from exactly two places:
```
weight = rarity multiplier × level multiplier
```
The rarity multiplier is fixed at mint and never changes. The [level multiplier](/goat-street/levels)
is earned by holding, and is the only part you control.
## The seven tiers
Each NFT belongs to one of seven broker tiers, assigned by the artwork's own metadata before a
single token was minted.
| Tier | Supply | Share of collection | Multiplier |
| - | -: | -: | -: |
| Intern Broker | 2,267 | 34.01% | 1.00× |
| Junior Broker | 1,733 | 26.00% | 1.15× |
| Senior Broker | 1,200 | 18.00% | 1.30× |
| Executive Broker | 800 | 12.00% | 1.55× |
| Whale Broker | 400 | 6.00% | 2.40× |
| Giant Broker | 200 | 3.00% | 3.70× |
| King Broker | 66 | 0.99% | 7.20× |
> [!NOTE]
>
> The ladder is deliberately non-linear. It was fitted to observed floor prices across tiers so that
> a holder's share of revenue tracks what the market already pays for their NFT, rather than
> imposing a curve the market disagrees with.
## The table is frozen
The tier assignment was published, committed on-chain, and then sealed. Two properties make it
verifiable rather than a promise:
> [card] Committed before registration
>
> Both setters refuse once any NFT has registered. Weights could not be chosen after anyone knew
> who held what.
> [card] Hashed against the source
>
> Sealing recorded a hash of the metadata file the table was derived from, so anyone can reproduce
> the assignment from the published source and check it matches the chain.
## Rarity and level multiply
They do not replace each other.
| | Level 0 | Level 1 (1.25×) | Level 2 (1.50×) | Level 3 (2.00×) | Level 4 (3.00×) |
| - | -: | -: | -: | -: | -: |
| Intern Broker (1.00×) | 1.00× | 1.25× | 1.50× | 2.00× | 3.00× |
| King Broker (7.20×) | 7.20× | 9.00× | 10.80× | 14.40× | **21.60×** |
21.60× is the widest spread the system can produce — a King at the top level against an Intern at
the base.
> [!NOTE]
>
> The gap between two NFTs at the *same level* is always exactly their rarity ratio. A King at level
> 4 is 7.20× an Intern at level 4, the same as at level 0. The ladder never widens the gap between
> tiers; it only widens the gap between holders who stay and holders who do not.
>
> That separation is deliberate. If the climb tracked weight, a King Broker would reach the top in
> three weeks against an Intern's five months. Rarity is meant to be an advantage bought once at
> mint, not one that compounds on its own.
## What changes your weight
| Event | Effect |
| - | - |
| Registering | Weight enters the pool immediately, at your rarity × 1.00×. Costs an entry fee in ETH, also scaled by rarity |
| Levelling up | The higher weight applies at once, and **withdrawals are not locked** — the level was earned by waiting, not acquired |
| Selling or moving the NFT | Position is cleared: weight leaves the pool and the tenure clock is destroyed |
| Buying an NFT | You register fresh at level 0 and pay entry at the price the curve has reached; the seller's level does not transfer |
> [!WARNING]
>
> **The level does not survive a sale — or any transfer.** A buyer always starts at level 0, and
> moving the NFT between your own wallets looks the same to the contract.
>
> Before transferring, **collect anything owed to you**. Royalty credit belongs to the NFT and
> transfers to the buyer along with the wallet it pays into, so anything you have not withdrawn goes
> with the goat.
# CashmereLabs Documentation
Source: https://docs.cashmere.exchange/index
Autonomous Monetary Infrastructure for stablecoin mobility, yield, privacy, and on/off ramps.
## Overview

CashmereLabs is building the **Autonomous Monetary Infrastructure**: a stablecoin platform that unifies cross-chain mobility, automated yield, privacy-preserving settlement, and seamless access between fiat and crypto. Every product is designed to operate as part of a single super-app experience for treasuries, financial institutions, and builders.
## Strategic Narrative
* **Mission** – deliver stablecoin functionality that is as reliable as core banking infrastructure and as programmable as DeFi.
* **Focus** – native, message-based rails that abstract away chain boundaries, liquidity management, and compliance overhead.
* **Differentiation** – zero-slippage transfers are live today; autonomous yield, privacy-preserving transfers, and unified ramps are in active development.
## Product Pillars
> [card] Mobility
>
> Zero-slippage omnichain transfers of native stablecoins. Built on issuers’ burn-and-mint messaging standards such as Circle CCTP and Tether USDT0.
> [card] Autonomy
>
> Agent-driven vaults that continuously allocate stablecoins to the highest risk-adjusted yields across integrated venues.
> [card] Privacy
>
> Privacy-preserving payment flows with zk proofs and optional disclosure tooling for institutions.
> [card] Access
>
> Unified fiat ↔ crypto ramps for both EVM and non-EVM networks, abstracting away regional and settlement constraints.
## Product Suite
> [card] [Cashmere Bridge](/products/bridge)
>
> **Status:** Production\\
>
> Native stablecoin transfers with zero slippage across EVM and non-EVM networks. Eliminates wrapped assets and market-maker inventories.
> [card] [Cashmere Yield Agents](/products/yield-agents)
>
> **Status:** Closed testnet\\
>
> Autonomous strategy engine that routes treasury balances toward the highest risk-adjusted APRs with programmatic guardrails.
> [card] [Cashmere Privacy](/products/privacy)
>
> **Status:** Research & prototyping\\
>
> Privacy-preserving stablecoin transfers with selective disclosure for audit and compliance workflows.
> [card] [Cashmere Gate](/products/gate)
>
> **Status:** In development\\
>
> Seamless on/off ramps that provide consistent UX across issuers, payment partners, and supported chains.
## Economics Snapshot
The CashmereLabs economic model is designed to align long-term infrastructure sustainability with user value.
* **Relayer fees** from zero-slippage transfers.
* **Autonomous yield service fees** on balances managed by Cashmere Yield Agents.
* **On/Off-ramp fees** through Cashmere Gate.
* **Cashmere App monetisation** via premium workflow features and partner revenue shares.
A detailed view of the business model lives in the [Economics](/overview/economics) section.
## System Architecture
> [card] On-Chain Layer
>
> Smart contracts deployed across EVM, Move, and Anchor environments handle burn, attestation, mint, and settlement logic.
> [card] Autonomous Relayers
>
> Multi-threaded Go services price routes, request attestations, enforce compliance rules, and finalise destination mints.
This modular design allows every product to share the same messaging, compliance, and monitoring stack while remaining independently deployable.
| Metric | CashmereLabs | Legacy Bridges |
| - | - | - |
| **Gas Usage (ETH)** | ≈150k units | 270k–300k units |
| **Execution Speed** | 8s (L2) / 20s (L1) | 30s–60s+ |
| **Slippage** | 0.00% | Up to 0.50%+ |
| **Architecture** | Native burn-and-mint | Wrapped tokens / liquidity pools |
## Roadmap Themes
* Launch autonomous yield agents with enterprise controls.
* Ship privacy layer MVP with configurable disclosure policies.
* Deliver unified ramps across strategic geographies and payment partners.
## Learn More
* [What is CashmereLabs?](/overview/what-is-cashmere)
* [Problems We Solve](/overview/problems-we-solve)
* [System Design](/overview/system-design)
* [Backend APIs](/developers/backend-apis)
* [Smart Contracts](/developers/smart-contracts)
> [!TIP]
>
> Looking for partner access or enterprise integrations? Contact [contact@cashmere.exchange](mailto:contact@cashmere.exchange).
# Manifesto
Source: https://docs.cashmere.exchange/manifesto
Our vision for an Autonomous Monetary Infrastructure
## Freedom of Ownership
Ownership is the foundation of freedom.
Crypto was never meant to replace fiat—it was built to counterbalance it. It exists to protect the value individuals create, to safeguard what's earned through life and labor. No institution, government, or corporation should ever have the power to seize what you own.
**Crypto restores that balance—through mathematics, not permission.**
## Borderless Value Exchange
When two parties wish to exchange value, nothing should stand between them.
Borders may define geography, but they should never define access. The internet made information flow freely; money must follow.
CashmereLabs envisions a world where value moves with the same freedom, speed, and neutrality as data packets—where transferring wealth is as simple as sending a message.
## Decentralized Systems
Power tends to centralize; systems tend to ossify.
We cannot wait for institutions to return ownership—they won't. Throughout history, people preserved their sovereignty through gold, land, and enterprise. Today, we do it with cryptography, zero-knowledge proofs, and digital signatures.
**Decentralized systems are not an ideology—they are the last line of defense for freedom in a networked world.**
## Building Autonomous Infrastructure
At CashmereLabs, we don't theorize—we build.
We are constructing the **Autonomous Monetary Infrastructure**: an open, composable layer for stablecoins, yield, and privacy across all chains.
* We defend ownership through code, not policy
* We automate integrity through cryptography, not trust
* We build infrastructure that works everywhere, for everyone
As fiat systems fragment and economies digitize, this infrastructure will form the backbone of 21st-century commerce—on Earth and beyond.
## The Social Contract
Freedom is not inherited; it's deployed.
For ownership to endure, it must become part of a collective will—a social contract of builders. Together, we must build and maintain systems that serve the common good.
We invite scrutiny, dialogue, and participation. We will evolve through collaboration, but not compromise our purpose.
**Because freedom of ownership is not a slogan—it's a shared responsibility.**
## Our Mission
Stablecoins are the bridge between open finance and real-world money.
Our mission is to make them flow like information—**zero-slippage, one-click, everywhere.**
We are building the Autonomous Monetary Infrastructure so that ownership, yield, and privacy remain where they belong:
**In the hands of the user.**
***
> [card] [Build with Us](/developers/quickstart)
>
> Join developers building the future of money
> [card] [Join Our Community](https://discord.gg/cashmerelabs)
>
> Connect with the Cashmere community
# Airdrop
Source: https://docs.cashmere.exchange/mountain/airdrop
How much CSM is airdropped, when, and who it goes to.
20% of the Treasury Safe's 166,500,000 CSM, which is 33,300,000 CSM (5% of the cap), will be airdropped in multiple phases. Where this CSM sits before it is sent is on [Tokenomics](/mountain/tokenomics).
## The first phase
The first phase is on TGE day. It is sent straight to wallets, or collected in the app. It goes to:
* Barn Raising participants
* Goat Street activators and holders
* Early users of Cashmere: testnet and mainnet users, donors, points holders and people on the leaderboard
* Holders of earlier NFTs on Ethereum and Optimism
* Listed NFTs for sale on any secondary market will be excluded.
Barn Raising participants and Goat Street activators get the largest shares. Then come Goat Street holders, earlier Optimism NFT holders, earlier Ethereum NFT holders and on-chain Cashmere users.
For Goat Street holders and activators, the share grows with how many Goat Street goats you hold, how many of them you have activated, and how high their tiers are.
## Later phases
Later phases are weighted by Barns and Goat Street goats.
# Barn Application
Source: https://docs.cashmere.exchange/mountain/apply
How to get on a founding sale list, and how to check one.
> [!NOTE]
>
> Where things stand today: the application is not open, and nothing is deployed. There is no date.
The founding sale's first two stages, GTD and WL FCFS (a list stage, first come, first served), sell only to wallets on a list. The Barn Application is how you ask for a place on one. The Public stage needs no list.
> [!NOTE]
>
> GTD means a guaranteed allocation in the founding sale. The Cashmere team announces GTD wallets in batches every 48 hours. If a GTD wallet does not buy its allocation within 48 hours, the spot goes to another applicant.
## Apply in seven steps
Applying is off-chain. It costs nothing and needs no gas. The only thing you sign is a message that proves your wallet is yours. Nobody will ask you for a transaction, a recovery phrase or a token approval to apply.
Open **Barn Application** and press **Start your application**. A short security check runs first.
**1. Connect X**
This step is required.
**2. Connect Discord**
This step is required too.
**3. Link wallets**
Link at least one wallet. Each wallet signs a message. For a Safe or another contract wallet, use **Sign with another app**: copy the message into the app that holds the wallet, sign it there and paste the signature back. Link every wallet that holds Goat Street goats or Early Goats on Ethereum or Optimism. Staked ones count too.
**4. The wallet for your Barn**
Pick a linked wallet or type in the address of another wallet you own, then tick the box that confirms it. Only that exact address goes on the list, and only that address can buy. Your Barn is minted to it, and a Barn cannot move while Deed transfers are off, so use a wallet you will keep.
**5. Your post**
Post about Mountain on X, mention @cashmerelabs and paste the post's link. One link is required, and you can add up to two more. The team reviews every post by hand.
**6. About you**
Choose what you are applying as: **Individual** (you use Cashmere or apps on Robinhood Chain), **Creator** (you make content or run a community) or **Project** (you represent a team or a protocol). You must choose one, and none of them asks for anything more. A letter is optional. It must be plain text, up to 1,200 characters.
**7. Review and submit**
Check your answers and tick the four consents. The form shows each one in full. You can add a referral code from a link you opened, but it is optional. A short security check runs, and then you submit. If something is missing, the form shows you which step it is in.
## After you apply
Open **Barn Application** and sign in with X or Discord to see your status.
| Status | What it means |
| - | - |
| In review | No decision is shown yet |
| GTD list, with a number | Your Barn wallet can buy up to that many Barns in the GTD window |
| WL FCFS list, with a number | Your Barn wallet can try to buy up to that many in the WL FCFS window, first come, first served. More wallets can be listed than there are Barns |
| Left out | Your GTD spot went to another applicant because you did not buy within 48 hours of listing |
| Removed | Your list place was taken away under the rules below |
| Withdrawn | You withdrew the application |
| Not selected | Shown once the final lists are out. You have no list place |
* While the form is open, you can add a new X post about Mountain each UTC day to increase your chance of a GTD spot.
* The status page gives you a referral link and an Application card you can share on X.
* While the status page allows it, you can edit, withdraw or delete your application, and export your data.
A spot works only if your wallet is on the list set on the sale contract at the time you buy. A spot does not oblige you to buy.
## How the team decides
* Sybil wallets are removed.
* Holding and activating Goat Street NFTs increases your chance. The more you hold, the higher your chance.
* Early use of Cashmere increases your chance. This covers points, the leaderboard and earlier NFTs.
* On-chain activity on Cashmere and other DeFi protocols increases your chance.
* A wallet with a good-quality activity history increases your chance.
## Check a list
The **Checker** looks up one address in the published lists, with no signature and no transaction. **The lists page** shows each published list file.
## What can go wrong
* **A wrong Barn wallet.** Only the listed address can buy. If it is wrong or lost, you may lose your spot.
* **Messages.** We never DM you first, and we never ask for your recovery phrase. Official word comes only from x.com/cashmerelabs, the Discord server and this site.
There is more on [Risks](/mountain/risks).
# Auctions
Source: https://docs.cashmere.exchange/mountain/auctions
Stall Permits, Shepherd orders and new Barns from the daily Barn lot.
## Stall Permits
### Buy Permits now
1. Open **Auctions**, then **Permit stalls**. You will see the price per stall, how many are left in this roll and when the roll ends.
2. Choose the Barn and 1 to 3 stalls. A Barn can hold at most 9 Permit stalls.
3. Press **Buy**. The app sets your highest price per stall and a deadline. The Barn's balance pays first. If you choose, your wallet pays the rest after it allows the Ledger to take it.
You can also press **Add Permit stalls** on [Your Barns](/mountain/barns). Each new stall counts toward the Barn's limit of 3 new stalls in a 24-hour window. The CSM you pay is burned out of supply.
### A Permit roll
Permits sell in 12-hour rolls, counted from one hour after the issuance start. The price falls through each roll toward a floor.
Prices are set in [days of one stall's Forage](/mountain/forage#one-stalls-day).
* **Price** = floor + (start - floor) x 2^(-t / half-life). The half-life is 2 hours at launch settings.
* **Floor** = 2 days of one stall's Forage at launch settings.
* **Start**: after a roll that sold, it is the highest of 2 x the last sold close (a roll's close is the price its last Permit sold at), the floor and the Raising price. After a roll that did not sell, it is the higher of 2 x the floor and the Raising price.
* **Raising price** = 35 days of one stall's Forage, less a sixth for each roll that has sold. It is gone once 6 rolls have sold.


The numbers are fixed when a roll opens. A new roll is due every 12 hours. The next action opens it, or anyone can press **Open the new roll**. Its price runs from the roll's set start time, so the moment it is opened does not change the price. A new roll usually starts above the last roll's end price. If it opens above your highest price, the buy fails.
### How many Permits
* The day's count is level x Season. The level starts at 10, which gives 10 a day at Season 1.00.
* Each roll offers half of what is left of the day's count after subtracting the goat weight brought In Barn and the Salt Blocks of the last day. No more than 100 are offered in a day.
* The level steps once a day, after the day's two rolls:
* A day that offered Permits and did not sell out: level x 3/4.
* Three sold-out days in a row, each closing at 40 days of one stall's Forage or more: level x 1.10. Then the count starts again.
* The level stays between 5 and the larger of 5 and 1% of all Barn weight.
* **Raising Week** is the first 14 rolls, or 7 days. It offers at least 5 Permits a day (fewer only when the day's count is under 5), a smaller [goat lane](/mountain/herding-toll#the-goat-lane) and one Bring In per Barn per roll.
## Shepherd orders
A Shepherd order buys Permits for you when the price comes down to your limit.
1. Open **Auctions**, then **Shepherd order**, and choose the Barn.
2. Enter 1 to 3 Permits and the most you will pay per stall.
3. Press **Place an order**. With your first order, the app names Mountain's filler account to fill it for you. The filler gets nothing for this.
* Each Barn can have one order, placed by the Deed holder.
* The order is paid only from the Barn's balance when it fills, never from a wallet. Keep the Barn topped up.
* It fills in full when the price reaches your limit, as long as Permits and stall room are left. Only you or the filler you named can fill it. You can name another filler or clear the filler, or press **Fill now** under **Your orders**.
* You can **Cancel the order** at any time. Cancelling is never paused.
* If the Deed changes hands, the order goes stale for good. Anyone can remove a stale order, or an order whose Barn has closed.
## Barn lots
1. Open **Auctions**, then **New Barn**. You will see the current price and the lots left today.
2. Press **Buy a Barn for** the shown price. The app sets your limit at the shown price plus 5%. Any ETH above the price comes back in the same transaction.
Anyone can buy, including contract wallets. The ETH goes to the Gatehouse. The new Barn has one stall and a Deed ID from 1,001 up, and it starts to forage at once.
### The lot price
* There is 1 lot in each 24-hour period at launch settings, starting one hour after the issuance start.
* **Price** = the larger of the reserve now and reserve + (start - reserve) x 2^(-t / half-life). The half-life is 4 hours and the reserve 0.25 ETH at launch settings. The reserve can never go lower.
* **Start** = 3 x the larger of the reference and the reserve. The first period's reference is the final Public price of the founding sale. After that, it is the last sale price if the period before sold, and the reserve if it did not.
* A sale opens the period's next lot at once, at 3 x the larger of that price and the reserve. Unsold lots lapse at the end of the period.
# The founding sale
Source: https://docs.cashmere.exchange/mountain/barn-raising
Barn Raising, with its stages, its prices and the Public curve.
> [!NOTE]
>
> Where things stand today: the sale is not open, and nothing is deployed. There is no date.
The founding sale, Barn Raising, sells up to 1,000 founding Barns, with Deed IDs 1 to 1,000. Any Barn it does not sell is never made.
## The three stages
| | GTD | WL FCFS | Public |
| - | - | - | - |
| Who can buy | Wallets on the GTD list | Wallets on the WL FCFS list | Any wallet that sends its own transaction |
| Price | 0.125 ETH per Barn | 0.25 ETH per Barn | 1.5 ETH, falling to 0.25 ETH over 30 minutes, then flat |
| Barns | Up to 700 at launch settings | Up to 900 for GTD and WL FCFS together | At least 100, plus whatever the first two stages leave |
| How many | Up to your listed number | Up to your listed number | One per transaction, and 3 per wallet at launch settings |
| Payment | Exact ETH: count x price | Exact ETH: count x price | At least the price. Anything above it comes back in the same transaction |
| Safes and other contract wallets | Yes, if listed | Yes, if listed | No |
Unsold GTD Barns roll over to WL FCFS. When GTD and WL FCFS together reach 900 (at launch settings), WL FCFS closes and Public opens in the same second. If they do not, Public opens at its set time.
## How to buy
1. Open **Barn Raising** on the island and connect the wallet on your list.
2. Pick how many Barns you want. The page shows the price and the total.
3. Confirm in your wallet. The Deed is minted to you in the same transaction.
WL FCFS and Public can sell out before your transaction lands, and bots may be faster than people. Be prepared, and be quick.
## Not an offer
Nothing here is an offer. Mountain is not open to anyone who is in, lives in or is organised under the laws of a Restricted Place. These include the United States, Canada, the EU and EEA, the UK, Russia, Belarus, mainland China, Hong Kong, Singapore and Malaysia, and every sanctioned place (Cuba, Iran, North Korea, and the Crimea, Donetsk and Luhansk regions of Ukraine). The full list is in section 3.3 of the [Terms of Use](https://terms.cashmere.exchange/). US persons may not use it wherever they are, and neither may anyone on a sanctions list. Read [Risks](/mountain/risks) and the [Terms of Use](https://terms.cashmere.exchange/) before you do anything.
## The Public curve
Public is a Dutch auction: the price starts at 1.5 ETH and falls to 0.25 ETH over 30 minutes, then stays at 0.25 ETH.
**Rebates.** Every Public buyer pays the same final price. It is the price of the last Public buy if all 1,000 Barns sell, and 0.25 ETH otherwise. If you paid more, Cashmere sends you the difference after the sale ends. Barn Raising shows **Your public rebate** once you connect.
## What you get
The Deed minted to you owns a Barn with 10 stalls, one of them open. Nothing builds up in it before the issuance start. A Deed cannot be minted to a token-bound account, such as a goat's own wallet. See [Your Barn](/mountain/barns).
A Barn is not a share, a loan, a deposit or a membership, and it gives no right to anything from the team, the sale ETH, the Treasury or the vaults.
## How the sale ends
The sale ends when the owner Safe ends it, when the 1,000th Barn sells, or, once the Public end time has passed, at the first rebate payment or at the launch. After the sale ends, nothing about it can change.
# Your Barn
Source: https://docs.cashmere.exchange/mountain/barns
Stalls, the balance, top-ups, cash-outs, closing a Barn and moving a Deed.
## What you can do on Your Barns
| Button | What it does | Cost |
| - | - | - |
| **Add Permit stalls** | Buys 1 to 3 [Permit stalls](/mountain/auctions#stall-permits) now | CSM, from the Barn's balance first, then your wallet |
| **Goats**, then **Bring in** on a goat under **Grazing, ready to bring in** | Brings a Grazing goat into an empty stall | The [herding toll](/mountain/herding-toll), or no toll on the goat's first Bring In after a paid bind |
| **Goats**, then **Bring in** on a goat under **In your wallet, not bound yet** | Binds the goat for good and brings it into an empty stall, one goat at a time | Only the Bring In toll, from the Barn's balance first, then your wallet. There is no Grazing toll, and the goat gets no later Bring In without a toll |
| **Goats**, then **Turn out** | Sends a goat back to Grazing | Gas only |
| **Check in now** | Restarts the 90-day clock for everything your wallet holds | Gas only |
| **Salt Block** | Adds weight to a full Barn. [Off today](/mountain/built-off-today#salt-lick-and-salt-block) | CSM |
Only the Deed holder can act on a Barn. Anyone can see it.
## Stalls and the 24-hour window


* A Barn has 10 stalls. Its own stall is open from the start. Each of the other 9 can become a Permit stall or hold a goat In Barn. A Barn holds at most 9 goats at launch settings.
* A Barn's own stall and each Permit stall weigh 1 and build the Barn's balance. A goat In Barn takes a stall, but its weight builds the goat's own balance.
* At most 3 new stalls can open in each fixed 24-hour window, counting Permit stalls, goats brought in and Salt Blocks together. The windows are counted from one hour after the issuance start.
## The balance and Top up
A Barn's balance is its unwithdrawn Forage plus any CSM you topped up and have not used. It belongs to the Barn, so whoever holds the Deed holds it. Spending and cash-outs use Forage first and topped-up CSM last.
### Top up
Press **Top up** and enter the amount. Your wallet first allows the Ledger to take it, and then sends it. Topped-up CSM pays for Permits and tolls once the Forage is used up. A reset never takes it. Cashing it out later still pays the Gate fee.
## Cash out part, or close
Press **Cash out** and choose how many of the Barn's own stalls to cash out (the own stall and Permit stalls count, but Salt Blocks do not). The CSM goes to your connected wallet. Through the explorer, you can name another address. The app sets a minimum net amount and a deadline, as described on [Cash-outs](/mountain/cash-outs).
Gross = balance x stalls you cash out / the Barn's own stalls. The Gate fee comes off, and the net is minted to you.
* The stalls you cash out close. A closed Permit stall is not refunded. Buying one again counts toward the window.
* **Close the Barn and cash out** cashes out every own stall. The Barn closes for good: the Deed is burned, its Permit stalls and Salt Blocks close, and its goats go back to Grazing.
## Moving a Deed
Selling the Deed sells the Barn, with its balance, stalls and Salt Blocks. Check what a Barn holds before you buy its Deed. The Barn Deed starts as a soulbound, non-transferable NFT. In the future it can become transferable, and a secondary market can open. There is no exact date for this.
* **The 1-hour lock.** The Deed cannot move for 3,600 seconds after a cash-out, a stall close, a reset or a toll paid from the Barn's balance.
* **Off at launch.** The owner Safe can announce that transfers will turn on, with 7 days' notice, or turn off, with 30 days' notice. Once a change is due, anyone can apply it within 7 days from the public jobs on The Trek page. Any two switches are at least 7 days apart. No notice can come before the issuance start.
* **Listings.** Approvals always work, so a Deed can be listed while transfers are off. Cancel any listing you no longer want before transfers open.
* **Royalty.** 10% of a marketplace sale goes to the Treasury Safe, at launch settings. The owner Safe can change the rate at once, from 0% to 10%, but not the receiver. While transfers are on, the Limit Break transfer validator enforces this.
* **What a move does.** The goats go back to Grazing and stay with their Bell holder. A Shepherd order goes stale. The new holder's 90-day clock starts when the Deed arrives.
* **Wallets.** A Deed cannot go to a token-bound account, such as a goat's own wallet.
* **Settle first.** If a Trek is due, a transfer or a marketplace fill also has to pay the gas for settling it. Settle on The Trek page first.
There is more on [Risks](/mountain/risks).
# Built, off today
Source: https://docs.cashmere.exchange/mountain/built-off-today
Salt, Hay Bales and drops: what each would do and how each one opens.
> [!NOTE]
>
> Nothing here has a date, and any of it may never open.
| Feature | State at launch | How it opens |
| - | - | - |
| Salt Lick and Salt Block | Deployed, paused | The owner Safe unpauses them |
| Hay Bales | Deployed later, paused | The owner Safe opens them with a grant of 999,000 CSM from the Hayloft |
| Drops | The two drop contracts deploy before the issuance start. No drop exists | Anyone can register a drop after the issuance start |
| The Goat Trail world and its chat | Not open | No contract |
Salt can be paused again but never replaced.
## Salt Lick and Salt Block
**Salt Lick** raises one goat's level by 0.25 per step, from 1.00 to 1.25 and then to 1.50, which is the top. A higher level means more weight. On **Grazing**, the Bell holder picks the goat and presses **Salt Lick**. The price is 1.5 x the step's weight (ladder x 0.18 x 0.25) x the toll reference, rounded up. The goat's own balance pays first, then your wallet if you choose. A step for an In Barn goat uses the [goat lane](/mountain/herding-toll#the-goat-lane) and follows its Barn's per-roll rule.
**Salt Block** adds a weight of 1 to a Barn whose 10 stalls are all in use. It takes no stall. On **Your Barns**, the Deed holder presses **Salt Block**, which shows only when the Barn is full. The price is the larger of 1.25 x (the higher of the last Permit [close](/mountain/auctions#a-permit-roll) and the toll reference) and 30 days of one stall's Forage. The Barn's balance pays first, then your wallet.
At launch settings, a Barn can have at most 2 Salt Blocks, no more than one per 24 hours, and each one takes one of the window's 3 new stalls. A Block also needs a Permit roll that sold and closed in the last 48 hours, and room in the salt lane. At launch settings, the salt lane allows a quarter of the day's Permit count per 24 hours across all Barns, shared with the goat lane. A Block stays with the Barn when the Deed moves, and it closes when the Barn closes.
Every Salt price is burned out of supply for good (counted as retired).
## Hay Bales


A Hay Bale locks CSM from your wallet for one term of 15 days. Barn and goat balances cannot go in.
1. **Lock.** On **Hay Bales**, enter an amount and press **Lock for 15 days**.
2. **At maturity**, you must act. Nothing rolls over by itself.
* **Redeem** gives back your CSM, with no fee.
* **Lock again for a new term** locks it again.
3. **Leave early** at any time, for a fee.
**The early-exit fee** is 2% + 13% x o^2 of the CSM you take out, at most 15%. Here, o is the early exits of the last 7 days measured against the open Bales, so the fee rises when many holders leave at once. Half the fee is burned. The other half is credited to the other open Bales, split by principal.
* Limits: at least 666 CSM per lock, at most 666,000 CSM open per wallet, and at most 19,980,000 CSM in all.
* **Redeem** and **Leave early** are never paused. A pause or a close stops only new locks and rolls.
* The owner Safe can change the Hay Bale settings: the term, the limits and the top early-exit fee, up to 30%. A new top fee also applies to Bales that are already locked.
## Drops (Future Ecosystem Projects)
A drop is a token payout held by one of the two drop contracts, one for Barns and one for goats. The drop contracts have no owner and cannot be paused or upgraded.
* **Registering.** Anyone can register a drop of any ERC-20 after the issuance start. The shares are frozen in that same transaction. Each drop keeps its own amount, deadline and send-back address.
* **Barn drops** cover either founding Barns only or all Barns. A drop is shared either by own stalls or as one share per Barn. Goats and Salt Blocks do not count. A share pays per stall as each frozen stall closes, or at exit once the Barn has fully closed. It goes to the Deed holder or, for a closed Barn, to whoever held the Deed when it was burned.
* **Goat drops** count goats by their place at registration: either Grazing goats only or every live bound goat. Shares are one per goat or set by tier, from Intern 100 to King 720. A goat's share pays out only after the goat's cash-out, to whoever held the goat at cash-out.
* **Collecting.** A Barn's share shows on Your Barns, and a goat's share shows on Grazing under **Cashed out**. You can collect to another address, but not to address 0, the drop's own contract, the Ledger, the escrow, the drop's own token or a goat wallet. A Barn drop also refuses the Deed and the sale contract.
* **After the deadline**, anyone can send what is left back to the drop's send-back address. A drop with a deadline of 0 never ends.
### What the Terms say
* A drop exists only once a drop contract registers it on chain. Its rules are in that contract.
* What we say about future drops is a plan, not a promise.
The full text is section 8.6 of the [Terms of Use](https://terms.cashmere.exchange/).
# Cash-outs, the Gate fee and Stay active
Source: https://docs.cashmere.exchange/mountain/cash-outs
The Gate fee, the Herd Share, staying active and the 90-day reset.
## The Gate fee
Every cash-out, whether of a [Barn](/mountain/barns#cash-out-part-or-close) or a [goat](/mountain/goats#cash-out-a-goat), pays the Gate fee. The fee rises when many players cash out at once. How long you have held does not matter. The app reads the exact fee and uses it to set a minimum net amount and a deadline. If the fee moves past these limits, the cash-out fails and only gas is spent. Cash-outs are never paused.
* **Fee rate = 2% + 58% x (P / 10%)^2**, with P capped at 10%. So the fee ranges from 2% to 60% of the gross amount.
* **P = recent cash-outs / the larger of (balances + recent cash-outs) and 6,660,000 CSM.**
* Recent cash-outs are all cash-outs and reset bounties from the last 7 days at launch settings, plus this one. A top-up you take back inside that window does not count. Balances are all live Barn and goat balances after this one leaves.
| P | Fee rate |
| - | - |
| 0% | 2% |
| 1% | 2.58% |
| 5% | 16.5% |
| 10% or more | 60% |


* **Goats** pay the higher of this rate and a goat-only rate: the same formula over goat cash-outs and goat balances.
* **After many resets**, cash-outs pay more for a while, up to about 7 days, until the Herd Share from those resets has streamed back.
## Where the fee goes
Half of the fee, rounded up, is burned out of supply for good (counted as retired). The other half goes to the **Herd Share**, along with half of each reset's remainder. What the Herd Share gathers in each Trek streams to all live weight over the next Trek.
## Stay active and resets


Press **Check in now** under **Stay active** on Your Barns at least once every 90 days. It costs only gas. Activity is per wallet: one action restarts the 90-day clock of every Barn and goat your wallet holds. A wallet that cannot check in, such as some contract wallets, can be reset.
| Counts as activity | Does not count |
| - | - |
| Check in, a top-up, a cash-out, buying a Barn lot | Settling a Trek, a repair |
| A Permit or herding toll payment, including at a bind | Trading CSM |
| A bind, Salt, a goat cash-out (holder and receiver) | Receiving a Deed |
| Resetting someone else's Barn or goat | Goat Street actions through the Bell |
| A Shepherd order fill, for the wallet that placed it | Turn Out, opening a roll |
| | Placing or cancelling a Shepherd order |
| | Collecting a drop share, Hay Bale actions |
**The reset date.** A Barn's date is 90 days after the latest of: its holder's last activity, the day the Deed arrived, the issuance start and its last reset. A goat's date is 90 days after the latest of: its Bell holder's last activity, its last reset and the issuance start.
**What a reset takes.** After that date, anyone can reset the Barn or goat. A Barn reset takes the unwithdrawn Forage above the topped-up CSM. A goat reset takes the goat's whole balance. Of that:
* 2% goes to the caller, at most 66,600 CSM at launch settings,
* half the rest goes to the Herd Share,
* the other half is burned out of supply.
**What it leaves.** Everything else: the Barn keeps its Deed, stalls, Salt Blocks and goats, and a goat keeps its place, weight and level. Both keep foraging, and the clock restarts. If you reset your own Barn or goat, you get the bounty.
**Where to see it.** Your Barns shows each reset date and warns you 30, 14 and 3 days before it, but a warning can fail to reach you. The Trek page lists dormant Barns and goats under public jobs, with their bounties, and asks you to confirm before you reset your own.
Nobody can tell you in advance what the Gate fee will be, and it is never paid back.
# Contracts
Source: https://docs.cashmere.exchange/mountain/contracts
Contract addresses on Robinhood Chain (chain ID 4663).
## Mountain
| Contract | Address |
| - | - |
| Cashmere (CSM) | TBA |
| Pool hook | TBA |
| Registry | TBA |
| Ledger | TBA |
| Ledger views | TBA |
| Gate fee math | TBA |
| Barn stalls | TBA |
| Barn Deed | TBA |
| Barn Raising | TBA |
| Stall Permits | TBA |
| Barn lot auction | TBA |
| Goat escrow and Goat Bell | TBA |
| Goat escrow views | TBA |
| Base Camp | TBA |
| Gatehouse | TBA |
| Avalanche vault | TBA |
| Base Camp buyback | TBA |
| Hayloft | TBA |
| Exit helper | TBA |
| Salt | TBA |
| Hay Bales | TBA |
| Barn drops | TBA |
| Goat drops | TBA |
## Outside Mountain
| Contract | Address |
| - | - |
| Uniswap v4 PoolManager | `0x8366a39CC670B4001A1121B8F6A443A643e40951` |
| Uniswap v4 PositionManager | `0x58daec3116aae6D93017bAAea7749052E8a04fA7` |
| Limit Break v5 transfer validator | `0x721C008fdff27BF06E7E123956E2Fe03B63342e3` |
| Goat Street collection | `0xC21159F412c294ca2C38f2A9eCAAcCF9d93eC929` |
| GoatSoftStake | `0x29A23E6bF5fF54A897cF100654dA0aE452482969` |
| ERC-6551 registry | `0x211a83BEE2eDE8fe3004A1CfE9Ad9fbD7340Ef9b` |
| WETH | `0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73` |
# Fees, the Gatehouse and buybacks
Source: https://docs.cashmere.exchange/mountain/fees
Every charge, how the Gatehouse splits its ETH, and the two buyback contracts.
## Every charge
All values are at launch settings.
| Charge | Size, paid in | Goes to |
| - | - | - |
| Trading tax | 90%, falling through the launch hour, then 2% on a buy and 3% on a sell. Paid in ETH | The Gatehouse |
| Pool fee | 1% of each trade, in the token you put in | Liquidity providers, with Base Camp's part going to the Team Safe |
| Liquidity exit tax | On principal taken out: the ETH part at the sell rate, the CSM part at the buy rate | ETH to the Gatehouse, CSM burned |
| Gate fee | 2% to 60% of every cash-out. Paid in CSM | Half burned out of supply, half to the Herd Share |
| Herding toll | Once per goat at the bind (the Grazing toll), from your wallet. After that, on each Bring In except the first after a paid bind, from the Barn's balance first. A bind straight into a Barn pays only the Bring In toll, from the Barn's balance first. Paid in CSM | Burned out of supply |
| Stall Permit | A falling price each roll. Paid in CSM, from the Barn's balance first | Burned out of supply |
| Salt Lick, Salt Block | Off today. Paid in CSM | Burned out of supply |
| New Barn lot | A falling price, at least 0.25 ETH | The Gatehouse |
| Deed royalty | 10% of a marketplace sale, in that sale's currency, while transfers are on | The Treasury Safe |
| Hay Bale early exit | 2% to 15%, off today. Paid in CSM | Half burned, half credited to the other open Bales, split by principal |
| Goat Street's soft-stake fee | Goat Street's own fee, paid through the Bell | Goat Street |
| Gas | ETH, on every transaction. A due Trek adds the settlement's gas | The chain |
The code counts most of this burned CSM as retired. See [Tokenomics](/mountain/tokenomics#how-csm-leaves-supply). A reset is not a fee. Its split is explained on [Stay active](/mountain/cash-outs#stay-active-and-resets).
**Gas only:** Check in, Turn Out, settling a Trek, opening a new roll, cancelling a Shepherd order, finishing a goat's clean-up, applying a Deed switch, a repair and collecting your pool fees all cost gas and nothing else.
## The Gatehouse split



At each Trek settlement, the Gatehouse splits the ETH it holds. That ETH is the taxes, the ETH part of the liquidity exit tax and every Barn lot price.
| Share | Goes to |
| - | - |
| 15% | The team, paid to the Team Safe by a call anyone can send |
| 15% | The Base Camp buyback |
| 70% | The Treasury Safe, if the Trek's net flow was above zero (net buying). The Avalanche vault, if it was zero or below (net selling) |
Taxes taken before issuance starts reach the Gatehouse with the first forward. The owner Safe can change the shares, but the team's share can be at most 20%. A change takes effect right after the next settlement, so the settlement after that is the first to use it. Net flow is explained on [Treks](/mountain/treks#the-trek).
**The Gatehouse** page shows the ETH waiting for the next Trek, the CSM burned so far, the Hayloft's balance, what is owed to the team, and each Trek's split marked "Net buying" or "Net selling".
## The two buyback contracts


| | Base Camp buyback | Avalanche vault |
| - | - | - |
| Gets | 15% of the Gatehouse each Trek, and a share of the sale ETH | The 70% after net-selling Treks, and a share of the sale ETH |
| A step | Buys CSM and sends all of it to the Hayloft. Nothing is burned | Buys CSM with the smaller of 10% of its ETH and 0.20% of Base Camp's depth at the current price, then burns all the CSM it holds |
| Size and spacing | At most 10 ETH per buy, with buys at least 15 minutes apart | Steps at least 15 minutes apart |
| Price check | Within about 16% of the pool's average, before and after | Within about 10% of the average |
| Refuses | During the launch schedule, and while either tax is under 1% | The same |
| Who can run it | The operator key or the owner Safe | The same. The owner Safe can open it to everyone, and that cannot be undone. Off at launch |
Buybacks are what the contracts do with ETH. Nothing has to run them, and these pages say nothing about any effect on any price.
## The Hayloft
The Hayloft holds the CSM that the Base Camp buyback buys. The owner Safe can send any amount of it, or of ETH, to anyone, at once. Its planned use is the [Hay Bale](/mountain/built-off-today#hay-bales) budget. That is a plan, not a promise.
# Forage and weight
Source: https://docs.cashmere.exchange/mountain/forage
How new CSM is shared by weight, and how the Season scales it.
## The two formulas
* **Forage a day = daily base x Season.** The daily base is 466,200 CSM at launch settings.
* **What a Barn or goat gets = Forage x its weight / all live weight.** It is shared out every second.


| What carries weight | Weight |
| - | - |
| A Barn's own stall, a Permit stall, a Salt Block (off today) | 1 each |
| A goat In Barn | ladder x level x 0.18 at launch settings |
| A goat Grazing | a third of its In Barn weight at launch settings |
A Barn's stalls build the Barn's balance. A goat's weight builds the goat's own balance, even when the goat is In Barn. Each tier's weight is on [Goats](/mountain/goats#grazing-and-in-barn).
## One stall's day
**One stall's day = daily base x Season / all live weight.** It is what one unit of weight gets in a day. Permit prices, tolls and Salt prices are set in this unit.
As a worked example, not a predicted outcome: with only the 1,000 founding Barns at one stall each and a Season of 1.00, one stall's day is 466,200 CSM / 1,000 = 466.2 CSM.
## The Season
At the launch base, Forage a day is 582,750 CSM at the top Season of 1.25, 466,200 CSM at the starting Season of 1.00 and 93,240 CSM at the floor of 0.20. How the Season moves is on [Treks and the Season](/mountain/treks#the-season).
## Fixed rules
* The daily base can only go down, and never below 1 CSM a day. A cut takes effect from the next Trek settlement. Apart from a cut and the Season, nothing changes the size of the stream.
* Forage comes from an issuance budget of 432,900,000 CSM. Once it is spent, Forage stops for good. The [Herd Share](/mountain/cash-outs#where-the-fee-goes) keeps streaming.
## From balance to tokens
Forage is a balance in the Ledger, not tokens. A Barn can spend it on Permits and tolls. It becomes tokens only at a cash-out, which pays the [Gate fee](/mountain/cash-outs#the-gate-fee) and mints the net amount to you.
Founding Barns start to forage at the issuance start, not when they are bought. A Barn bought from a Barn lot forages from the moment it is bought. While there is no live weight at all, nothing is credited.
# Future plans
Source: https://docs.cashmere.exchange/mountain/future-plans
What the team plans to build next, and what it plans to do with the Treasury Safe's share of the Gatehouse ETH.
> [!NOTE]
>
> These are plans, not promises. They are not in the contracts, and they can change or stop. Nothing here is advice.
## The Treasury Safe's 70%
At each Trek with net buying, the Gatehouse sends 70% of its ETH to the Treasury Safe (see [The Gatehouse split](/mountain/fees#the-gatehouse-split)). The plan for that ETH:
| Share | Plan |
| - | - |
| 50% | Goes to Cashmere |
| 50% | Funds automated AI agent strategies |
With the team's own 15% of the Gatehouse (see [The Gatehouse split](/mountain/fees#the-gatehouse-split)), this means the team and Cashmere get 50% of the Gatehouse in a Trek with net buying.
The first planned strategies:
* **Basis trade**, also called funding-rate arbitrage: hold an asset and an equal short position on it at the same time, so the price moves cancel out and the position collects the funding payments between traders.
* **Stock LP pools**: liquidity in pools of tokenized stocks, collecting the pools' trading fees.
Agents run these strategies by set rules, without a person placing each trade. Any strategy can lose ETH, for example when funding turns negative, a pool's prices move apart, a venue fails, or a position is closed at a bad price. This is how the Treasury Safe plans to use its own funds. It gives no Barn, goat or CSM holder a right to anything from those strategies.
## What the team plans to build
* **A URC-5 launchpad.** New tokens launched the way CSM is: one official Uniswap v4 pool each, under URC-5, paired with Cashmere stock LP pools, so trading on them pays fees.
* **A funding-rate arbitrage product.** The basis trade above, offered as its own product.
* **Goat LP extensions.** More automated LP strategies in Goat LP, on more pools. Goat LP has its own docs and its own risks; read them before you use it.
What the Treasury Safe gets and can do is on [Roles](/mountain/roles-and-settings).
# Goats
Source: https://docs.cashmere.exchange/mountain/goats
Binding a goat, the Goat Bell, Grazing and In Barn, the goat's own wallet and cashing out.
A Goat Street goat counts in Mountain only once it is bound.
## Bind your goats
On **Grazing**:
1. Open **In your wallet** and pick up to 90 goats. The app splits the bind into transactions of at most 44 goats.
2. Press **Check goats**. It shows each goat's tier, owner, wallet contents and Goat Street soft-stake state (Goat Street's own staking), and whether it can be bound.
3. Get each goat ready on Goat Street first. Binding gives up its pending Goat Street rewards, so collect them and deliver any Goat Street credit it is owed. Empty the goat's own wallet too: NFTs inside it cannot move after the bind, and any allowances it gave stay open.
4. Tick the box to confirm that you understand binding is permanent.
5. Approve. Your wallet approves each goat for the escrow one at a time and allows the Ledger to take the total toll in CSM.
6. Press **Bind**. The app sets the most you will pay in total toll, and a deadline: the end of the current Permit roll.
**The cost.** Each goat pays the [herding toll](/mountain/herding-toll) once, at the bind (the Grazing toll). It comes from your wallet only, in one payment for the whole batch. That CSM is burned out of supply.
**Who cannot bind.** A goat's own wallet cannot bind. Move a goat out of any token-bound account before you bind it.
## What binding does


* The goat moves into Mountain's escrow for good. A live goat has no way back.
* You get a **Goat Bell** with the goat's ID. It cannot be sold, moved or approved, and only its holder can act on the goat. If you bind from a Safe, the Bell goes to the Safe, and only the Safe can act on the goat.
* The goat builds its own balance for the Bell holder, not for a Barn. That balance stays with the goat through Turn Out, a Barn closing and a Deed moving.
**Bind and bring in at once.** On [Your Barns](/mountain/barns), open **Goats** and press **Bring in** on a goat listed under **In your wallet, not bound yet**. This binds that goat for good and puts it straight into a stall, one goat at a time. It pays no Grazing toll: the Bring In toll is the only payment, taken from the Barn's balance first, then from your wallet. A goat bound this way does not get a later Bring In with no toll.
## Grazing and In Barn
A bound goat is either **Grazing** (no Barn needed) or **In Barn** (it takes a stall in your own Barn and weighs 3x as much, at launch settings). A cashed-out goat weighs 0 for good.
**The Herd Ladder**
| Tier | Ladder | Grazing weight | In Barn weight |
| - | - | - | - |
| Intern | 1.00 | 0.06 | 0.18 |
| Junior | 1.15 | 0.069 | 0.207 |
| Senior | 1.30 | 0.078 | 0.234 |
| Executive | 1.55 | 0.093 | 0.279 |
| Whale | 2.40 | 0.144 | 0.432 |
| Giant | 3.70 | 0.222 | 0.666 |
| King | 7.20 | 0.432 | 1.296 |
The weights shown are at level 1.00 and launch settings: In Barn = ladder x level x 0.18, and Grazing is a third of that. A goat's tier never changes, and its level starts at 1.00.
## Bring In and Turn Out
**Bring In.** On Grazing, pick a goat, press **Bring into a Barn** and choose the Barn. The goat takes a stall and a slot in the 24-hour window. You must hold both the Deed and the goat's Bell. The other requirements are under [What Bring In needs](/mountain/herding-toll#what-bring-in-needs). A goat's first Bring In after a paid bind has no toll. Later ones pay the toll.
A goat drop that counts only Grazing goats leaves out any goat that is In Barn when the drop is registered. See [Drops](/mountain/built-off-today#drops-future-ecosystem-projects).
**Turn Out.** Either the Bell holder or the Deed holder can press **Turn out** at any time. Turn Out has no toll and is never paused. The toll and the window slot do not come back, so the next Bring In pays.
A goat also goes back to Grazing when its Barn's Deed moves, when its Barn closes or when the Deed holder no longer holds its Bell. Anyone can send the repair for a goat in this state.
## The goat's own wallet
While a goat is bound, the escrow owns its Goat Street wallet (a token-bound account) and the Bell holder controls it. Open **Goat wallet** on Grazing:
* **Sweep to my wallet** moves the ETH and tokens shown to your connected wallet. NFTs cannot move. Sweep any token tagged "lost at cash-out" yourself, because a cash-out leaves it behind.
* **A token not shown:** before the cash-out, call the goat escrow's sweep on the explorer with the token's address.
* **Goat Street rewards and credit.** A bound goat gets none until you register it again in Goat Street's soft stake through the Bell (Goat Street's fee and waiting period apply). After that, **Goat Street rewards** collects the rewards, and Goat Street's deliver call delivers the goat's credit.
* **The engine election** is the goat's payout choice on Goat Street. It can be set or reset through the Bell. Neither this nor registering is on the site yet, so use the goat escrow on the explorer.
## Cash out a goat
On Grazing, pick the goat and press **Cash out**. The CSM goes to your connected wallet (on the explorer you can name another address). The app sets a minimum net amount and a deadline, as described on [Cash-outs](/mountain/cash-outs).
* A goat cashes out only once, for its whole balance less the goat's [Gate fee](/mountain/cash-outs#the-gate-fee). Its Bell is burned and the goat stops foraging for good.
* If the goat was In Barn, its stall becomes empty. Neither the toll nor the lane room comes back. The goat's unused [Bring In with no toll](/mountain/herding-toll#what-never-comes-back), if it has one, is lost.
* Then the clean-up runs, in the same transaction if gas allows:
1. Any Goat Street credit the goat is owed is delivered. If the goat was registered again in the soft stake, its rewards are forwarded too.
2. The goat's wallet is swept to you: its ETH first, then up to 51 listed tokens.
3. The goat is burned once nothing is left.
The **Cashed out** tab shows each goat as "wallet sweep due", "waiting to burn" or "Burned". If the clean-up did not finish, anyone can press **Finish the sweep** or **Try the burn**. After the grace period (90 days from the cash-out, at launch settings), anyone can press **Burn now**.
## What can go wrong
* After 90 days without activity, anyone can reset the goat's whole balance. To stay active, press **Check in now** on Your Barns under **Stay active**, even if you hold no Barn. Each goat's reset date is on its Grazing card.
* NFTs and tokens that a cash-out does not sweep are lost at the burn. Credit not delivered before the bind can be lost too.
More on [Risks](/mountain/risks).
# The herding toll
Source: https://docs.cashmere.exchange/mountain/herding-toll
What a goat pays when it is bound and when it is brought in, and how the goat lane works.
## What you pay
1. **At the bind to Grazing**, each goat pays the toll once (the Grazing toll), in CSM from your wallet. That CSM is burned out of supply.
2. **That goat's first Bring In** has no toll.
3. **Every later Bring In** pays the toll, taken from the Barn's balance first. That CSM is burned out of supply too.
A bind straight into a Barn pays only one toll: the Bring In toll.
## How the toll is worked out
**Toll = rate x the goat's In Barn weight x reference**, rounded up, in CSM.
A bind to Grazing is also priced on the In Barn weight, at the roll currently in force. A bind of several goats pays the sum of their tolls.
**The reference** is the highest of these four:
* the Permit floor,
* the middle of the last two sold Permit [closes](/mountain/auctions#a-permit-roll),
* the Raising price,
* 10 days of one stall's Forage.
The reference is fixed when a [Permit roll](/mountain/auctions#a-permit-roll) opens, so the toll changes every 12 hours. It falls when more weight joins and when the Season drops.
**The rate** is 1. At launch settings, it drops to 0.5 when the toll is low in ETH terms:
* Take the highest of the Permit floor, the Raising price and the lower of the last two sold closes.
* Price that in ETH at the pool's time-weighted average price.
* If it stays at or below 0.25 ETH for 2 full days, the rate is 0.5. From the first roll where it is above that, the rate is 1 again.
* If there is no average price to read, the rate stays as it is.
### A worked example
On roll 1, at rate 1, the reference is 35 days of one stall's Forage. This is a worked example, not a predicted outcome:
| Goat | In Barn weight | Toll at roll 1 | Toll at the lowest reference |
| - | - | - | - |
| Intern | 0.18 | 6.3 days of one stall's Forage | 1.8 days |
| King | 1.296 | 45.36 days | 12.96 days |
## Your limit
A Bring In is paid for by the wallet that holds both the Deed and the Bell: from the Barn's balance first, then from that wallet if you choose. A bind to Grazing is paid from your wallet only, after you allow the Ledger to take the total. A bind straight into a Barn is paid like a Bring In: from the Barn's balance first, then from your wallet.
Every bind and Bring In carries the highest toll you accept and a deadline. If the toll is above that limit, or the deadline has passed, the transaction fails and only gas is spent.
The deadline of a bind is the end of the current Permit roll. The page shows it to the second, in UTC. If your bind lands after the deadline, it fails and only gas is spent. Check the new toll and send again.
If a Permit roll is due, it opens with your transaction, so the toll can differ from the one you saw. A bind pays at most the quote you approved. No bind or Bring In pays more than your highest toll.
If a Trek has ended and is not settled, the app asks you to send the settlement first, as its own transaction. Settling takes nothing from your wallet. Only gas is spent.
When a bind fails, the app says why:
* **The quote expired**: the roll ended before your bind landed.
* **The toll changed with the new roll**: a new roll opened with a new toll.
* **The toll rose before your bind landed**: a setting changed during the roll.
* **Mountain could not price this goat**: the goat was not counted as Grazing when its toll was worked out.
Each message ends with: "No goat was bound and no CSM was spent; only gas was spent."
## What never comes back
The toll is never paid back, whether at Turn Out, at a cash-out or when the goat never comes In Barn. A first Bring In that has been used never comes back through a Turn Out, a Deed move or a Barn closing. A goat that is cashed out before its first Bring In gives up that Bring In with no toll.
## What Bring In needs
* A Grazing goat and an empty stall in your own Barn. You must hold the Deed and the goat's Bell.
* Room among the Barn's 3 new stalls for the current 24-hour window.
* Room in the goat lane.
* Fewer than 9 goats in the Barn, at launch settings.
A Bring In with no toll still needs all of these.
## The goat lane
Goats and Permits share the day's count. Goat weight brought In Barn lowers the number of Permits offered, and a goat that is turned out gives room back later.
| When | The lane, over a trailing 24 hours | Per Barn, per roll |
| - | - | - |
| Raising Week, the first 14 rolls | Whichever is lower: the day's count less 5, or half of the day's count. At most half of that in one roll | One Bring In |
| After Raising Week | Half of the day's count at launch settings (5 stalls' weight a day while the level is 10 and the Season 1.00) | The first always fits. A later one fits only while the Barn's total for that roll, including the first, stays within the larger of 1.296 (one King's In Barn weight) and 10% of the roll's lane |
When the lane is full, Bring In fails with "lane full" and only gas is spent. Try again in a later roll.
The value of one stall's day of Forage changes over time, so the same number of days can mean a different amount of CSM. More on [Risks](/mountain/risks).
# How to play
Source: https://docs.cashmere.exchange/mountain/how-to-play
The whole game in eight steps.
**1. Get set**
Use a wallet on Robinhood Chain (chain ID 4663) with ETH for gas. Fake CSM tokens exist, so check every address against [Contracts](/mountain/contracts) first.
* **ETH.** You can use [app.cashmere.exchange](https://app.cashmere.exchange) to bring ETH onto the chain.
* **A goat**, if you plan to bind one, or a [Permit](/mountain/auctions) to buy. Goats are [Goat Street](/goat-street/overview) NFTs. The collection's address is on [Contracts](/mountain/contracts#outside-mountain).
* **CSM**, before your first bind or Permit. Buy it in [Base Camp](/mountain/trading#how-to-trade-not-yet). The toll for binding a goat to Grazing is paid only from your wallet, and a new Barn starts with a small balance. Grazing shows you the toll before you bind.
**2. Get a Barn**
Apply on [Barn Application](/mountain/apply), then buy in [the founding sale](/mountain/barn-raising). From one hour after the issuance start, you can buy a new Barn for ETH in [Auctions](/mountain/auctions). Once Deed transfers are on, you can also buy a Deed from its holder. Without a Barn, you can still [trade CSM](/mountain/trading) or [bind goats to Grazing](/mountain/goats).
**3. Wait for the start**
The launch opens the pool. After that, the owner Safe starts issuance, and binds and Permits open one hour later. See [what switches on, and when](/mountain/overview#what-switches-on-and-when).


**4. Grow your Barn**
Buy [Stall Permits](/mountain/auctions) with CSM, which is taken from the Barn's balance first. A Barn can have up to 10 stalls, and you can add up to 3 new ones in each 24-hour window. A Shepherd order buys Permits at your limit while you are away. [Top up](/mountain/barns#top-up) when the balance runs short.
**5. Bind goats**
On Grazing, you can bind up to 90 goats at a time. The app splits them into transactions of at most 44 goats. Each goat bound to Grazing pays the [herding toll](/mountain/herding-toll) once, in CSM from your wallet. The toll is burned, and you get a Goat Bell for the goat. Binding is for good, so before you bind, empty each goat's own wallet, collect its Goat Street rewards and deliver any credit it is owed. See [Goats](/mountain/goats).
**6. Bring goats in**
A goat's first Bring In after a paid bind has no toll. In Barn, a goat takes a stall and weighs 3x its Grazing weight, at launch settings. Later Bring Ins pay the toll. Turn Out has no toll at any time.
**7. Every Trek**
A Trek lasts 3 days at launch settings. When it ends, anyone can settle it for the cost of gas alone. Then the Season may step, the Gatehouse splits its ETH and the Herd Share streams to all weight. See [Treks](/mountain/treks).
**8. Stay active, then cash out**
Press **Check in now** at least once every 90 days, or anyone can reset your Barn's unwithdrawn Forage, or your goat's whole balance. A cash-out pays the Gate fee, which is 2% to 60%. A Barn can cash out some of its stalls, or close. A goat cashes out once and is then burned. See [Cash-outs](/mountain/cash-outs).
Every charge is listed on [Fees](/mountain/fees). You cannot undo binding a goat, a goat's cash-out, closing a Barn or anything you pay. Only a Public rebate from the founding sale comes back. Read [Risks](/mountain/risks) before you act.
# Mountain
Source: https://docs.cashmere.exchange/mountain/overview
What Mountain is, the island, the words you need, and what switches on when.



> [!TIP]
>
> **Ask Claude about Mountain.** Connect these docs to Claude once, then ask anything:
>
> * **Claude (web or desktop):** in Settings, open Connectors, choose Add custom connector, and paste `https://docs.cashmere.exchange/mcp`
> * **Claude Code or another agent:** `claude mcp add --transport http cashmere-docs https://docs.cashmere.exchange/mcp`
> * **Any other AI chat:** attach or paste [llms-full.txt](https://docs.cashmere.exchange/llms-full.txt), every page of these docs in one file, rebuilt on every update. Agents can start from [llms.txt](https://docs.cashmere.exchange/llms.txt), and any page reads as Markdown when you add .md to its address.
> [!NOTE]
>
> Where things stand today: nothing is deployed yet, so these pages list no Mountain address. None of the steps below has a date.
> [card] [How to play](/mountain/how-to-play)
>
> The game in eight steps.
> [card] [Barn Application](/mountain/apply)
>
> Get on a founding sale list.
> [card] [Risks](/mountain/risks)
>
> What you can lose, and when.
## What Mountain is
Mountain is a set of smart contracts on Robinhood Chain (chain ID 4663), plus a site for using them. It has one token, CSM, with one official pool.
New CSM enters by a rule set in code, called **Forage**: a stream shared every second among Barns and bound goats, by weight. Forage builds up a balance, which becomes tokens only when you cash out. CSM leaves the supply for good when players buy Permits or pay tolls, and with half of every Gate fee. ETH from trading taxes and Barn lot sales goes to the Gatehouse, which splits it at the end of every Trek.
## The island
The site is an island map. Each place has a page: [Barn Application](/mountain/apply), [Barn Raising](/mountain/barn-raising), [Barns](/mountain/barns), [Auctions](/mountain/auctions), [Grazing](/mountain/goats) for goats, [The Trek](/mountain/treks), [Base Camp](/mountain/trading) for trading, [The Gatehouse](/mountain/fees) for fees, and [Hay Bales](/mountain/built-off-today) (switched off today).
You can also walk the island as a villager. The walk is for display only. Each place opens the same page as on the map, and nothing you do on the walk moves tokens.
## Words you need
| Word | What it is |
| - | - |
| **CSM** | The token. It is capped at 666,000,000 CSM, and CSM that leaves the supply for good lowers that cap. It has no pause and no upgrade |
| **Barn** | Your place on the mountain. It has 10 stalls, and 1 is open from the start |
| **Deed** | The NFT that owns a Barn and its balance |
| **Stall Permit** | Opens one more stall. Permits are paid in CSM and sold in 12-hour rolls |
| **Goat, bind** | One of the 6,666 Goat Street goats. Binding moves a goat into Mountain for good |
| **Goat Bell** | The NFT you get for each goat bound into the goat escrow. It cannot be sold or moved |
| **Grazing, In Barn** | The two places a bound goat can be. A goat In Barn takes a stall and weighs 3x its Grazing weight, at launch settings. Bring In and Turn Out move a goat between them |
| **Herding toll** | CSM paid at a bind (the Grazing toll) and at later Bring Ins. It is burned |
| **Weight** | What sets your share of Forage. A stall weighs 1 |
| **Ledger** | The contract that keeps balances, streams Forage and pays cash-outs |
| **Trek, Season** | Mountain's clock. A Trek lasts 3 days at launch settings. The Season, from 0.20 to 1.25, scales Forage |
| **Gate fee, Herd Share** | A fee of 2% to 60% on every cash-out. Half of it streams back to all weight as the Herd Share |
| **Check in, reset** | Checking in keeps you active. After 90 idle days, anyone can reset your Barn or goat |
"At launch settings" means the value a setting has when the contracts start. The owner Safe (the team's Safe that owns the contracts) can change it within fixed limits. See [Roles](/mountain/roles-and-settings).
## What switches on, and when


**1. Deploy**
Genesis mints 66,600,000 CSM to Base Camp, for liquidity in the Uniswap v4 pool, and 166,500,000 CSM to the Treasury Safe.
**2. The founding sale**
Up to 1,000 Barns are sold. See [The founding sale](/mountain/barn-raising).
**3. The launch transaction**
Cashmere sends it after the sale ends. This is the TGE: trading opens, and the sale ETH is split.
**4. The launch hour**
This lasts 3,600 seconds. Both taxes start at 90% and fall to 2% on a buy and 3% on a sell. When this launch schedule ends, anyone can add liquidity. See [Trading](/mountain/trading#the-launch-hour).
**5. The issuance start**
This is a one-time step by the owner Safe. It comes after the launch hour and has no deadline. Forage, Trek 1 and Barn cash-outs start.
**6. One hour later**
Stall Permits, Barn lots, Shepherd order fills, goat binds and Bring In open. Raising Week, the first 7 days, begins.
> [!WARNING]
>
> There are two different hours. The launch hour is the pool's first hour. Binds and Permits open one hour after the issuance start, which comes later.
Still off at launch: Barn Deed transfers and the secondary market (these can be enabled at any time in the future), Salt Lick and Salt Block (deployed but paused), and Hay Bales and drops. See [Built, off today](/mountain/built-off-today).
> [!WARNING]
>
> Nothing here is an offer. Nothing here is advice. Mountain is not open in some places or to some people. The [founding sale's notice](/mountain/barn-raising#not-an-offer) names them. Read [Risks](/mountain/risks) and the [Terms of Use](https://terms.cashmere.exchange/).
## Explore the island
Every place on the map has its own page.
> [card] [Barn Application](/mountain/apply)
>
> Get on a founding sale list.
> [card] [Barn Raising](/mountain/barn-raising)
>
> The founding sale of the first Barns.
> [card] [Barns](/mountain/barns)
>
> Your place on the mountain.
> [card] [Auctions](/mountain/auctions)
>
> New Barns and Stall Permits.
> [card] [Grazing](/mountain/goats)
>
> Bind a goat and let it forage.
> [card] [The Trek](/mountain/treks)
>
> Mountain's clock and the Season.
> [card] [Base Camp](/mountain/trading)
>
> Trade CSM in the official pool.
> [card] [The Gatehouse](/mountain/fees)
>
> Where the fees go.
> [card] [Hay Bales](/mountain/built-off-today)
>
> Built, and off today.
> [card] [Start with How to play](/mountain/how-to-play)
> [card] [Read the risks](/mountain/risks)
# Risks
Source: https://docs.cashmere.exchange/mountain/risks
What you can lose in Mountain, and when.
> [!WARNING]
>
> You can lose all of the funds and assets you use with Mountain. CSM, Barns and goats can lose all of their market price, and there may be no market.
Nothing here is an offer. Mountain is not open in some places or to some people. The [founding sale's notice](/mountain/barn-raising#not-an-offer) names them. Read the [Terms of Use](https://terms.cashmere.exchange/).
Where this page and the code differ, the code decides what happens on chain.
## What you can lose, and when
| When | What you can lose |
| - | - |
| Buying a founding Barn | The price. It is paid at once to the Cashmere wallet, with no escrow |
| The key to the Cashmere wallet is lost or stolen | The ETH in that wallet and any unsent Public rebates |
| The launch is never sent | Barns get no token, and you do not get your price back |
| Issuance is never started | No Forage. The code sets no deadline |
| Paying above the final Public price | A wait for Cashmere to send the rebate after the sale ends |
| Trading in the launch hour | A tax of up to 90%, and the holding cap |
| Trading at any time | The tax on each trade, up to 10% a side and changeable at once, plus the 1% pool fee |
| Taking out liquidity | The tax on your principal, even if the position never traded |
| A Barn lot, a Permit, a toll or Salt | All of it |
| Turn Out, a Deed move or a Barn close | The toll stays spent |
| Any cash-out | 2% to 60% of the gross. Nobody can tell in advance what it will be |
| Closing a Barn, binding a goat, a goat's cash-out | The Barn and its Deed, or the goat and its Bell, for good |
| Anything left in a goat's own wallet | What is not swept is lost at the burn |
| 90 days with no activity | A Barn's unwithdrawn Forage, or a goat's whole balance, to a reset. Never the Barn, the Deed, stalls, the goats themselves or topped-up CSM |
| Selling CSM | A sale that would push the price below the floor band fails. Once net selling has used up the band (at most 25 ETH of buy orders), you may not be able to sell until new buys or other liquidity come in |
| New Barns | More Barns can be sold after launch, so existing Barn holders can be diluted |
| Wanting to sell a Barn | Transfers are off at launch and need 7 days' notice to switch on |
| Selling a Deed | The whole balance goes with it, and its goats go back to Grazing |
| Buying a Deed | Its balance can be spent right up to the sale. Check what it holds |
Apart from the Public rebates Cashmere sends, nothing you pay in Mountain comes back to you.
**What a Barn is not.** See [The founding sale](/mountain/barn-raising#what-you-get).
**The team.** The team holds real powers over Mountain, and most of them take effect at once. The team keeps 70% of the sale ETH above the first 25 ETH, and 15% of the Gatehouse each Trek at launch settings. After a Trek with net buying, the Treasury Safe gets the Gatehouse's 70%, and the plan is that half of it goes to Cashmere (see [Future plans](/mountain/future-plans)). So in those Treks, the team and Cashmere get 50% of the Gatehouse in all. No code locks the Treasury Safe's 166,500,000 CSM. Each key and what it can do is on [Roles](/mountain/roles-and-settings).
## The details
> [accordion] Trading and the pool
>
> * A swap can fail because of a price limit that would part-fill it, your slippage, or a sale that would push the price below the floor band. Once net selling has used up the band, you may not be able to sell until new buys or other liquidity come in. A failed swap costs gas only.
> * CSM can reach other venues. Mountain does not count them, and they may not follow Mountain's rules.
> * Large trades, including trades by large holders, can move the Season and change where the Gatehouse's largest share goes. Do not read them as a guide to anything.
> * Buybacks are what the contracts do with ETH. Nothing has to run them, and these pages say nothing about any effect on any price.
> * Uniswap's pool manager has a protocol-fee switch that could set a protocol fee on the pool later.
> [accordion] Barns and Forage
>
> * Forage per stall falls as Mountain grows and when the Season falls. New Barns are sold every day, so the number of Barns is not limited to 1,000.
> * When the issuance budget of 432,900,000 CSM is spent, Barns and goats get no new Forage, only the Herd Share.
> * Old listings can fill the moment transfers open. Cancel any listing you no longer want before then.
> * A Limit Break change or fault, or a new validator setting from the owner Safe, could block Deed transfers.
> * A Deed, Bell or Bale held by a smart account changes hands with the account. A buyer of such an account also takes the seller's remaining key control.
> [accordion] Goats
>
> * Move NFTs and unlisted tokens out of a goat's own wallet before you bind.
> * Binding gives up any Goat Street rewards that are still pending. A bound goat gets no Goat Street rewards or credit until its Bell holder registers it again in Goat Street's soft stake. Credit not delivered before the bind can be lost at the burn.
> * Allowances given by the goat's wallet stay open after the bind. Revoke them before you bind.
> * A goat pays the higher of two Gate fee rates, so it can pay more than a Barn at the same moment.
> * Goat Street's contracts and their admin are outside Mountain. A change there can affect bound goats.
> [accordion] Staying active
>
> * One Check in, which costs gas only, restarts the clock for everything in your wallet. Do it at least a day before your reset date. A chain halt does not move the date.
> * Trading CSM and Goat Street actions do not count as activity.
> * A warning can fail. Keeping your wallet active is your job.
> [accordion] Code, chain and site
>
> * The contracts can have bugs or design flaws, or be attacked. Security reviews and tests lower this risk but do not remove it. Many parts cannot be changed or paused, so a fault may not be fixable.
> * Robinhood Chain can halt or slow down, reorder or censor transactions, fork, or change its rules.
> * Helpers the team runs can be late or fail. Anyone can call the public ones, such as settling a Trek or a reset. Buyback and vault steps need the operator key or the owner Safe.
> * The site and the services it relies on can fail, show wrong data or be attacked. You can use the contracts without the site.
> * These docs can be wrong, incomplete or out of date.
> [accordion] Keys, scams and fake tokens
>
> Fake 'Cashmere (CSM)' tokens exist on Robinhood Chain. Mountain's token is only the address on [Contracts](/mountain/contracts).
>
> * You can lose access to your wallet through theft, phishing, malware or a wallet fault.
> * Mountain never asks for your recovery phrase. We never send you a DM first. Never sign a message or a transaction you do not understand.
> [accordion] Law and tax
>
> * Laws can change, or be applied in new ways, in any country. That could restrict Mountain or your use of it, or force parts of the site to close.
> * Tax rules for crypto-assets are uncertain and differ by place. Your taxes are your own.
> * Blocking access to the site does not change the contracts. The sale contract cannot tell where a buyer is. A buy made from a restricted place still breaks the Terms.
> * Nothing here is financial, investment, legal, tax or other professional advice, or a recommendation to buy, sell or hold anything.
## Off today
Salt Lick, Salt Block, Hay Bales and drops are built but off. None of them has a date, and any of them may never open. If one opens, it brings its own risks. See [Built, off today](/mountain/built-off-today).
# Roles
Source: https://docs.cashmere.exchange/mountain/roles-and-settings
Who holds each key and what each one can do.
## Who holds which key
| Key | What it can do |
| - | - |
| **Owner Safe**, a 2-of-3 Safe | Owns every Mountain contract that has an owner. Sets Mountain's settings. Re-points unlocked registry entries. Starts issuance, which it can do only once. Unpauses anything. Ends or pauses the founding sale. Runs buyback and vault steps. Sends CSM or ETH from the Hayloft |
| **Treasury Safe** | Spends its own funds. It gets 166,500,000 CSM at genesis, the Gatehouse's 70% after net-buying Treks, a share of the sale ETH and the Deed royalty. No Mountain contract can spend from it, and no code locks it |
| **Team Safe** | Receives the team's 15% of the Gatehouse and Base Camp's pool fees, at launch settings. The owner Safe can change both receivers at once |
| **Cashmere wallet** | Receives the ETH of every founding Barn buy. Sends the launch transaction and pays the Public rebates. The owner Safe can do both too |
| **Guardian** | Can only pause. Only the owner Safe can unpause |
| **Operator key** | Runs Base Camp buyback and Avalanche vault steps, as the owner Safe can. It can do nothing else |
| **Mountain's filler account** | Fills the Shepherd orders that name it |
# Terms & Conditions
Source: https://docs.cashmere.exchange/mountain/terms
The one set of terms for every Cashmere site and Mountain, and the main points in short.
> [!NOTE]
>
> The full text is the [Cashmere Terms of Use](https://terms.cashmere.exchange/). This page is a short summary; the full text wins wherever the two differ.
## One set of terms
The [Cashmere Terms of Use](https://terms.cashmere.exchange/) cover every Cashmere site and app (cashmere.exchange, app.cashmere.exchange, these docs and the Mountain site) and the Cashmere and Mountain contracts. "We" is Cashmere.
## In short
* **Who may use it.** You must be 18 or over and not on a sanctions list. Mountain is also closed to anyone in, resident in or organised under the laws of a Restricted Place: the United States and its territories; Canada; the EU and EEA; the UK; Russia; Belarus; Bosnia and Herzegovina; mainland China; Hong Kong; Singapore; Malaysia; Myanmar; Afghanistan; Bangladesh; Nepal; Uzbekistan; Syria; Lebanon; Yemen; Iraq; Qatar; Algeria; Egypt; Morocco; Tunisia; Libya; Sudan; South Sudan; Somalia; the Central African Republic; Mali; Burkina Faso; Namibia; Venezuela; Haiti; Jamaica; the Crimea, Donetsk, Luhansk, Kherson and Zaporizhzhia regions of Ukraine; sanctioned places (Cuba, Iran, North Korea and any other place under comprehensive sanctions); and any other place where a token sale like this one, or holding or trading crypto-assets, is banned or needs a licence we do not have. A US person is restricted wherever they are. Do not use a VPN or a proxy to get around these limits.
* **What the services are.** Interfaces to contracts. They hold none of your assets, open no account for you, and cannot move what is in your wallet. What a transaction does is decided by the contracts on chain. They are under active development and carry significant risk.
* **No offer and no advice.** Nothing in the sites, the docs, the posts or the chat is an offer, a request to buy or sell, or financial, investment, legal or tax advice. Plans are not promises.
* **Your wallet, your transactions.** You keep your keys and your devices safe, you check every transaction before you sign it, and you pay its gas, even when it fails. Use only the official CSM address published on the site.
* **A Barn.** A Barn Deed is an NFT that lets you use the Barn features as coded. It is not a share, a loan, a deposit or a membership, and not a right to anything from us. Nothing promises any amount of CSM, any price, or that you can sell.
* **What cannot be undone.** Binding a goat is final, and its Goat Bell cannot be moved. Apart from the public-auction differences, nothing you pay in Mountain comes back to you: not Barn lots, Stall Permits, herding tolls, Salt or Gate fees.
* **Points.** Points, rankings and multipliers have no money value, can change or reset, and are not a right to anything.
* **Nothing has a promised value.** CSM, Barns, Goat Street NFTs, the earlier Cashmere NFTs on Ethereum and Optimism, points, and every reward and campaign can fall to zero at any time. None of them promises anything.
* **Fees and taxes.** The sites charge no fee of their own. The contracts charge what their code sets, for example sale prices, the trading tax, the Deed royalty and the Gate fee. Your taxes are yours to work out and report.
* **Access.** We may block places, wallets or networks from the sites. That does not change what you hold on chain, and you can still use the contracts directly.
* **"As is" and liability.** Everything is provided "as is". To the fullest extent the law allows, we accept no liability, and our total liability is zero.
* **Disputes.** Contact us first at [contact@cashmere.exchange](mailto:contact@cashmere.exchange); we try to settle within 30 days. After that, disputes go to binding arbitration, and you give up the right to a class action. The terms are governed by the laws of the jurisdiction in which Cashmere is incorporated.
Read [Risks](/mountain/risks) before you act.
# Tokenomics
Source: https://docs.cashmere.exchange/mountain/tokenomics
How much CSM there is, who holds it, and how it enters and leaves.
## The cap and its three parts
| Part | CSM | Share of the cap | Minted at genesis? |
| - | - | - | - |
| Pool position, held by Base Camp | 66,600,000 | 10% | Yes |
| Treasury Safe | 166,500,000 | 25% | Yes |
| Issuance budget | 432,900,000 | 65% | No. Only Forage draws on it |
| **The cap** | **666,000,000** | **100%** | |


Right after genesis, the supply is 233,100,000 CSM.
## TGE (Token Generation Event)
* **When:** after Barn Raising, the founding sale, ends.
* **Where CSM trades:** one official Uniswap v4 pool, native ETH and CSM, with Mountain's own pool hook. It follows URC-5 (see [One pool: URC-5](#one-pool-urc-5) below).
* **The launch tax:** it starts at 90% and falls through the first hour, halving every 4 minutes, down to 2% on a buy and 3% on a sell. See [The launch hour](/mountain/trading#the-launch-hour).
* **The opening price:** the pool opens at tick 111,000, which is about 66,134 CSM per ETH (1 CSM is about 0.0000151 ETH, or about 0.035 USD with ETH at 2,300 USD). From the first trade, the price moves with trading.
* **At the opening price:** the 233,100,000 CSM minted at genesis come to about 3,525 ETH (about 8.1 million USD), and the full 666,000,000 cap (the fully diluted value, FDV) to about 10,070 ETH (about 23.2 million USD). The USD figures assume ETH at 2,300 USD; they move with ETH.
* **Buy orders under the opening price:** the first 25 ETH of the sale (about 57,500 USD; all of it, if the sale raised less) sits in Base Camp's floor band, from the opening price down to about 2% below it (tick 111,200, about 67,470 CSM per ETH). It buys the CSM people sell in that band, and it can never be removed. A sale that would take the price below the band's bottom fails, so once net selling has used up the band, you may not be able to sell until new buys or other liquidity come in. See [Base Camp's positions](/mountain/trading#base-camps-positions).
* **Buybacks after launch:** two contracts buy CSM with ETH from the Gatehouse and from the sale. The Base Camp buyback sends what it buys to the Hayloft; the Avalanche vault burns it. Neither runs during the launch schedule. See [The two buyback contracts](/mountain/fees#the-two-buyback-contracts).
## The token
* An ERC-20 named Cashmere, symbol CSM, 18 decimals, with no pause and no upgrade.
* Only the Mountain Ledger can mint, and only under the live ceiling. The Ledger creates the token itself, so the token can never be replaced.
* **The live ceiling** = the cap, less everything burned, less everything retired. It only goes down.
## Who holds what
* **Base Camp** holds the 66,600,000 CSM as liquidity in the Uniswap v4 pool, for good. No function can remove or move its positions. See [Trading](/mountain/trading#base-camps-positions).
## Airdrop
20% of the Treasury Safe's 166,500,000 CSM, which is 33,300,000 CSM (5% of the cap), will be airdropped in multiple phases.
**The first phase is on TGE day.** It is sent straight to wallets, or collected in the app. It goes to:
* Barn Raising participants
* Goat Street activators and holders
* Early users of Cashmere: testnet and mainnet users, donors, points holders and people on the leaderboard
* Holders of earlier NFTs on Ethereum and Optimism
* Listed NFTs for sale on any secondary market will be excluded.
Barn Raising participants and Goat Street activators get the largest shares. Then come Goat Street holders, earlier Optimism NFT holders, earlier Ethereum NFT holders and on-chain Cashmere users.
For Goat Street holders and activators, the share grows with how many Goat Street goats you hold, how many of them you have activated, and how high their tiers are.
**Later phases** are weighted by Barns and Goat Street goats.
All the airdrop details are also on their own page: [Airdrop](/mountain/airdrop).
## How CSM enters supply
[Forage](/mountain/forage) is credited from the issuance budget to Barn and goat balances, which are not tokens yet. New CSM is minted only when a balance is cashed out (the net amount) or a reset bounty is paid.
## How CSM leaves supply



The code keeps two counters. Both lower the ceiling for good.
| Retired | Burned |
| - | - |
| Stall Permits, all of it | All the CSM the Avalanche vault holds at each step |
| The herding toll, at a bind (the Grazing toll) or a Bring In, all of it | The CSM part of the liquidity exit tax |
| Salt Lick and Salt Block, all of it (off today) | Base Camp's CSM pool fee, only if switched on |
| Half of each Gate fee | Half of a Hay Bale early-exit fee (off today) |
| Half of a reset's remainder | Any holder's own burn |
**Retired** counts CSM that leaves without a token transfer at that moment, such as a Barn's balance spent on a Permit. CSM you pay from your wallet, as with the Grazing toll, is destroyed first and then counted as retired. Either way, it leaves supply for good.
**Neither.** A top-up turns wallet CSM into Barn credit without lowering the ceiling, so a cash-out can mint it again, less the Gate fee.
**Burn your own.** Anyone can burn their own CSM on the token contract. The site has no button for it.
## One pool: URC-5
CSM follows [URC-5](https://github.com/Uniswap/URCs/blob/main/URCs/urc-5.md), the draft Token Venue Policy standard in Uniswap's URC series. A URC-5 token states on chain where it can trade, so wallets, routers and aggregators can read the rule and route trades to the right pool.
* **One pool.** CSM's policy is *Enforced*, with one canonical pool: Base Camp's Uniswap v4 pool, ETH / CSM, 1% fee, with Mountain's pool hook. No other v4 pool can take CSM in, so CSM cannot be traded or added as liquidity there. The gate is on from deployment. The owner Safe can switch it off and on.
* **Blocked venues.** Venues outside v4, such as v2 pairs and v3 pools, can be blocked by address. Venues found before deployment are blocked then, and the owner Safe can add more. Only transfers in are refused, so holders there can still withdraw.
* **Never blocked:** the pool manager, the Ledger, address 0 and any address the registry names.
* **One clear error.** Every refusal reverts with the standard's `VenueNotAllowed` error, so a router can see why and use the canonical pool.
**Why it matters.** In a vampire attack, someone opens a second pool for a token to pull its trading and liquidity away. A second pool for CSM cannot take CSM in, so the taxes, the net-flow count and Base Camp's liquidity stay in one pool. Cashmere supports URC-5 and will keep contributing to the URC-5 ecosystem.
# Trading and liquidity
Source: https://docs.cashmere.exchange/mountain/trading
How to buy and sell CSM, how the launch hour works, how to provide liquidity and how to use the exit helper.
## How to trade (Not Yet)
1. **Check the token address** against [Contracts](/mountain/contracts), every character of it. Fake 'Cashmere (CSM)' tokens exist.
2. Open **Base Camp**, then **Swap**. Choose **Buy CSM** or **Sell CSM** and enter the amount.
3. Set your slippage, which is the least you will accept.
4. Confirm in your wallet.
You can also trade the same pool through Uniswap, and most routes work. A trade fails if it fixes the ETH amount and also sets a price limit that would stop it partway. If a trade fails there, use Base Camp.
## The official pool
The official pool pairs native ETH with CSM on Uniswap v4. It uses tick spacing 200 and Mountain's fixed pool hook. Base Camp opens it in the launch transaction.
## What a trade pays
* **The trading tax**, paid in ETH on the ETH side of every trade. After the launch hour it is 2% on a buy and 3% on a sell at launch settings. It goes to the [Gatehouse](/mountain/fees#the-gatehouse-split).
* **The pool fee** of 1%, charged on top and paid to liquidity providers.
## The launch hour


**Tax = floor + (90% - floor) x 0.5^(t / 240 s)** applies for the first 3,600 seconds after the pool opens. The floor is 2% on a buy and 3% on a sell.
| Minute | Buy tax | Sell tax |
| - | - | - |
| 0 | 90% | 90% |
| 10 | 17.6% | 18.4% |
| 20 | 4.75% | 5.72% |
| 60 and after | 2% | 3% |
While this launch schedule runs:
* **The holding cap applies.** No buy from the pool can take a wallet above 799,200 CSM, which is 1.2% of the pool's CSM. Wallet-to-wallet transfers are not capped. The Ledger, the pool hook, the Base Camp buyback, the Avalanche vault and the Treasury address are exempt.
* Only Base Camp can add liquidity.
* The Base Camp buyback, the Avalanche vault and the exit helper's position route refuse to run.
The owner Safe can set both taxes by hand at any time after the pool opens, up to 10% a side. Its first such call ends the launch schedule for good. The holding cap and the limit on outside liquidity end with it. While the launch schedule runs, the owner Safe can also switch the holding cap off, or on again, at once.
## Why a trade can fail
Your slippage, the holding cap in the launch hour or a Uniswap price limit can stop a trade. So can a very large sale. A sale that would push the price below the bottom of Base Camp's floor band fails. If part of the band is left, sell less. If net selling has used it all up, no one can sell in the pool until new buys or other liquidity come in. A failed trade costs gas only.
## One pool
Only the official pool can trade CSM on Uniswap v4. CSM moves in or out of Uniswap's v4 contract only as far as its hook allows. This check is on from deployment, and the owner Safe can switch it off and on. The token also names its one official pool on chain, under [URC-5](/mountain/tokenomics#one-pool-urc-5). The owner Safe can also block outside venues.
## Providing liquidity
On **Base Camp**, open **Liquidity**:
* **Add liquidity.** This opens to anyone when the launch schedule ends. The app adds full-range positions. A custom range may not have just one of its two ends at the edge of the price range.
* **Collect fees.** Collecting your pool fees on their own pays no tax.
* **Remove.** Taking principal out pays the live tax. The ETH part is taxed at the sell rate and goes to the Gatehouse. The CSM part is taxed at the buy rate and is burned. Here is a worked example, which is not an outcome: removing 1 ETH and 10,000 CSM at launch settings pays 0.03 ETH and 200 CSM.
A liquidity position carries no weight, so it gets no Forage. How a removed position counts in net flow is explained on [Treks](/mountain/treks#the-trek).
## Base Camp's positions
Base Camp opens the pool with two positions. The 66,600,000 genesis CSM sit in one wide position. The floor ETH, which is the first 25 ETH of the sale (or all of it, if the sale raised less), sits in a narrow band next to the launch price. No function can remove or move either position.
Their pool fees, in ETH and CSM, go to the Team Safe at launch settings. The owner Safe can change the receiver or burn the CSM part. Anyone can trigger the fee collection while the price is near its average.
## The exit helper
The exit helper is an ownerless contract for CSM stuck in another Uniswap v4 pool. It has no fee and cannot be paused or upgraded. It is not on the site yet, so call it from the explorer. A sale through the official pool pays the trading tax.
* **Position exit** is for your position in another v4 pool. You approve the helper, and it takes the position out. It then gives you the CSM, or sells it through the official pool with a minimum out. Taking the CSM out through the official pool pays the liquidity exit tax on it, at the buy rate, and that part is burned. This route is refused in the launch hour.
* **Balance exit** is for your ERC-6909 balances of CSM at the pool manager. The helper burns them and sells the CSM through the official pool. This route works in the launch hour, at the live sell tax.
# Treks and the Season
Source: https://docs.cashmere.exchange/mountain/treks
Mountain's clock, settling a Trek, the Season and the public jobs.
## Settle a Trek
Open **The Trek**. It shows the Trek number, the Season and the time to the next Trek. When the clock reaches zero, anyone can press **Settle this Trek**. It costs only gas. Settling moves no CSM of yours.
If a Trek is due, any Mountain action settles it first (up to 8 due Treks), which costs more gas. That is why the app sends the settlement first, as its own transaction. A settlement sent on its own also settles up to 8 due Treks. If more are due, send it again.
## The Trek
* A Trek is 3 days at launch settings. Trek 1 opens at the issuance start.
* Each Trek counts the pool's **net flow**: the ETH that buys put into the pool, less the ETH that sells take out, before tax. The two buyback contracts' own swaps are left out. A removed liquidity position counts according to what it converted: if your range sold CSM for ETH, it counts like a sale.
* Trading from the pool's launch onward counts toward Trek 1, so it can move the Season at the second settlement.
## What a settlement does
A settlement takes the Trek's net flow and forwards the trading taxes to the Gatehouse. Then it runs the Season step, applies any settings that were waiting for it, [splits the Gatehouse's ETH](/mountain/fees#the-gatehouse-split), and refreshes the Deed and Goat Bell pictures and data.
## The Season
The Season starts at 1.00 and stays between 0.20 and 1.25. At each settlement, the slope is this Trek's net flow plus the previous Trek's.
| Slope | Season |
| - | - |
| Below zero | Down 0.15, not below 0.20 |
| Above zero, first in a row | No change |
| Above zero, second in a row or more | Up 0.10, not above 1.25 |
| Exactly zero | No change, and the row starts again |
The first settlement never moves the Season. The steps are fixed in code.


**What it moves.** The Season scales [Forage](/mountain/forage#the-season) and the daily Permit count. Through one stall's day of Forage it also moves the Permit floor, the Raising price and the toll reference.
> [!NOTE]
>
> Large trades, including those by large holders, can move the Season and where the Gatehouse's largest share goes. Do not read either one as a guide to anything.
## Public jobs
The Trek page lists public jobs:
* **Reset** a Barn or goats that have been [left dormant for 90 days](/mountain/cash-outs#stay-active-and-resets), and collect the bounty.
* **Fill** a Shepherd order you placed, or one that names you as its filler.
* **Apply** a due Deed transfer switch.
# Economics
Source: https://docs.cashmere.exchange/overview/economics
CashmereLabs revenue model and economic alignment.
## Overview
The Autonomous Monetary Infrastructure is designed to be self-sustaining while remaining cost-efficient for users and partners. Revenue is tied directly to delivered value and risk-managed operations.
## Revenue Sources
* **Relayer Fees** – fees collected on every zero-slippage transfer executed through Cashmere Bridge. Fees reflect attestation costs, compute, and margin for operational resilience.
* **Autonomous Yield Service Fees** – performance- and management-based fees applied to balances managed by Cashmere Yield Agents, aligned with risk-adjusted returns.
* **On/Off-Ramp Fees** – spread-based or flat fees on conversions between fiat and stablecoins facilitated through Cashmere Gate’s partner network.
* **Cashmere App Revenue** – premium workflow features, analytics, and enterprise integrations offered through the Cashmere application layer, plus revenue-sharing with ecosystem partners.
## Alignment Principles
* **Usage-Based Pricing** – fees scale with actual usage and balances, eliminating hidden costs such as liquidity mining or wrapped-asset premiums.
* **Transparency** – all fees are surfaced in quotes prior to execution; no surprise markups or embedded spread.
* **Sustainability** – diversified revenue streams fund continuous relayer operations, smart contract maintenance, and compliance coverage.
* **Partner-Friendly** – economics are structured to align with issuers, liquidity venues, and payment partners so that value accrues across the ecosystem.
For detailed financial or partnership discussions, reach out to [contact@cashmere.exchange](mailto:contact@cashmere.exchange).
# The Problems We Solve
Source: https://docs.cashmere.exchange/overview/problems-we-solve
Resolving fragmentation across the stablecoin infrastructure stack.
## Fragmented Status Quo
The multi-chain ecosystem has unlocked innovation, but it has also produced severe fragmentation in stablecoin liquidity, yield, privacy, and compliance. Teams are forced to assemble a mesh of bridges, yield venues, and ramp providers—each with unique settlement rules, fees, and risk assumptions.
CashmereLabs unifies this landscape under a single Autonomous Monetary Infrastructure, eliminating structural inefficiencies across the stablecoin economy.
## 1. Fragmented Liquidity
**Challenge**\
Stablecoins live on dozens of chains without a consistent transport layer. Each bridge carries different settlement semantics and operational risk.
**Cashmere Response**\
A zero-slippage, omnichain rail covering every supported network, built on issuer-backed messaging (Circle CCTP, Tether USDT0) for native minting and deterministic finality. No wrapped assets, no synthetic liquidity pools.
## 2. Inefficient Transfers
**Challenge**\
Legacy bridges rely on market makers or prefunded liquidity, introducing spreads, slippage, and balance-sheet exposure.
**Cashmere Response**\
Direct burn-and-mint mechanics that remove intermediaries and guarantee exact outputs. Transfers execute as single on-chain transactions that are MEV-resistant, atomic, and predictable.
## 3. Manual Yield Management
**Challenge**\
Treasuries and DeFi users manually rebalance stablecoins across venues, track APRs, and manage risk—consuming time, gas, and operational bandwidth.
**Cashmere Response**\
Autonomous Yield Agents continuously route idle balances toward the highest risk-adjusted APRs across integrated protocols (Morpho, Felix, Hyperbeat) with programmable policy guardrails and transparent reporting.
## 4. Limited Privacy Controls
**Challenge**\
Cross-chain flows reveal counterparties, treasury behavior, and institutional strategy. There is no unified, compliance-friendly privacy framework for stablecoin settlement.
**Cashmere Response**\
The upcoming Cashmere Privacy layer introduces zk-based confidential settlement with optional selective disclosure, preserving privacy while maintaining audit trails for regulated participants.
## 5. Fragmented On/Off Ramps
**Challenge**\
Converting between fiat and crypto remains fragmented across providers, regions, and networks, resulting in inconsistent UX and settlement delays.
**Cashmere Response**\
Cashmere Gate connects partner payment networks and issuers through a single interface, delivering unified fiat ↔ crypto movement across both EVM and non-EVM ecosystems.
## Security & Cost Considerations
Traditional bridges expose users to custodial pools, router logic, and liquidity dependencies—contributing to more than **\$2.5B** in losses since 2021.
CashmereLabs minimizes this attack surface via:
* Native issuer infrastructure (CCTP, USDT0) instead of third-party custody.
* Deterministic outputs that remove MEV and sandwich vectors.
* Gas-efficient calldata design that lowers execution overhead.
## Economic Efficiency
| Legacy Model (Bridges & Market Makers) | Cashmere Model (Native & Autonomous) |
| - | - |
| Slippage: 1–5% on large transfers | Zero slippage, guaranteed outputs |
| Market-maker spreads: 0.1–0.5% | No spreads or external liquidity |
| Gas overhead: 270k–300k gas (Ethereum) | ≈150k gas usage (≈45% reduction) |
| Liquidity mining incentives: costly emissions | Fee-funded, emission-free operations |
| Manual treasury movement | Autonomous yield & policy automation |
> [!NOTE]
>
> Cashmere’s design replaces fragmented, high-overhead systems with a unified, composable infrastructure—enabling stablecoins to move, earn, and settle privately across the entire on-chain economy.
## Additional Resources
* [System Design](/overview/system-design)
* [Economics](/overview/economics)
* [Products](/products/bridge)
# System Design
Source: https://docs.cashmere.exchange/overview/system-design
Architecture of the CashmereLabs Autonomous Monetary Infrastructure.
## Architectural Summary
CashmereLabs operates a dual-layer architecture that combines:
* **On-chain execution** written in Solidity, Move, and Anchor to govern burn, attestation, mint, yield routing, and policy enforcement.
* **Autonomous relayers** implemented in Go that handle pricing, attestation retrieval, compliance, and settlement orchestration across EVM and non-EVM networks.
Together, these layers deliver deterministic, zero-slippage mobility for stablecoins while powering autonomous yield, privacy-preserving settlement, and fiat ↔ crypto connectivity.
## On-Chain Components
### CashmereCCTP (EVM)
* Verifies relayer-signed fee quotes (ECDSA).
* Executes burns, emits verifiable events, and enforces minimum output guarantees.
* Supports `transfer`, `transferV2`, and permit variants for gas-optimised execution.
### Move / Anchor Modules (Sui, Aptos, Solana)
* Mirror the burn → attest → mint lifecycle using Ed25519 signature schemes.
* Integrate chain-native fee handling and deterministic finality.
### Smart Account Infrastructure (ERC-4337)
Built on ERC-4337 account abstraction with specialised validator modules:
* **Smart Accounts:** Users interact via programmable, non-custodial accounts.
* **Validator Modules:** Authenticate relayer/yield-agent actions under cryptographic policies.
* **Session Keys:** Grant scoped authority for bridging, yield allocation, or ramp transfers without exposing primary keys.
* **Programmable Policies:** Enterprises define limits (e.g., max transfer size, approved protocols, scheduling windows).
This transforms static wallets into autonomous smart accounts—enabling safe delegation to agents while users retain full asset control.
## Cross-Chain Execution Model
| Layer | Description |
| - | - |
| **EVM Chains** | CashmereCCTP contracts handle native burn-and-mint execution with on-chain fee verification. |
| **Non-EVM Chains** | Move/Anchor modules and SDKs coordinate attestation-based mints with relayer support. |
| **Unified Policy Engine** | Enforces compliance, minimum output guarantees, and routing rules on every transaction. |
## Autonomous Relayers
Relayers are stateless orchestration agents. They never custody user funds; instead they validate events, quote fees, and submit destination transactions.
### Runtime Capabilities
* Subscribe to burn events across supported chains.
* Estimate fees using issuer feeds, on-chain gas data, and Cashmere policy limits.
* Sign quotes (ECDSA/Ed25519) with ≈100-second expiries.
* Retrieve and verify attestations from Circle CCTP, Tether USDT0, and future issuers.
* Submit destination mints with nonce management and retry logic.
* Enforce per-chain policy hooks (allowlist/denylist, AML checks).
* Provide observability via Prometheus metrics, structured logging, and circuit breakers.
## Execution Flow
1. **Detect Burn** – listen for `CashmereTransfer` (or equivalent) events on the origin chain.
2. **Retrieve Attestation** – fetch issuer proofs and validate signatures.
3. **Mint & Finalise** – submit the destination mint, enforcing min finality thresholds (1,000 Fast / 2,000 Normal).
4. **Record & Monitor** – persist transaction data and expose it through the Monitoring API for analytics.
## Fee Quotation Pipeline
* Clients call `GET /getEcdsaSig_native` or `GET /getEd25519Sig_native`.
* Relayers compute destination gas, issuer cost, and policy-defined overhead.
* Response includes `fee`, `deadline`, and signature.
* Users embed these values when invoking on-chain contracts.
* Quotes expire after \~100 seconds to keep pricing aligned with live network conditions.
## Yield Agent Layer
On top of the transfer infrastructure, Cashmere deploys autonomous agents that turn idle stablecoins into self-optimising capital:
* Continuous monitoring of APRs across integrated venues (Morpho, Euler, Jupiter).
* Policy-driven allocation using user-approved session keys (no custody risk).
* Cross-chain rebalancing via the same zero-slippage transfer fabric.
* Transparent reporting and withdrawal optionality at all times.
## Privacy & Compliance Layer
The forthcoming Cashmere Privacy module introduces zk-based settlement with optional selective disclosure:
* Confidential transfers for users and DAOs.
* Audit trails and disclosure hooks for regulated institutions.
* Integration with policy engines to maintain KYC/AML compatibility.
## Reliability & Security
| Mechanism | Purpose |
| - | - |
| **Trust minimisation** | Cashmere never holds user funds; all mints/burns occur via issuer contracts. |
| **Deterministic outputs** | Guaranteed minimum amounts remove MEV and sandwich risk. |
| **Infrastructure hardening** | Dockerised, load-balanced relayers with automated failover and throttling. |
| **Policy controls** | Allowlist/denylist, rate limits, and compliance hooks per chain. |
| **Non-custodial smart accounts** | Automation executes via user-controlled accounts with programmable permissions. |
For detailed contract interfaces and APIs, see [Smart Contracts](/developers/smart-contracts) and [Backend APIs](/developers/backend-apis).
# What is CashmereLabs?
Source: https://docs.cashmere.exchange/overview/what-is-cashmere
Autonomous Monetary Infrastructure for stablecoins.
## Definition
CashmereLabs delivers an **Autonomous Monetary Infrastructure** — a programmable, omnichain layer that eliminates fragmented bridges, manual treasury work, and siloed compliance tooling. It enables stablecoins to:
* Move with zero slippage across EVM and non-EVM chains.
* Earn through autonomous yield agents.
* Transact privately via privacy-preserving settlement rails.
* Bridge crypto and fiat through integrated on/off ramps.
In short, Cashmere turns stablecoins into a seamless, interoperable monetary network.
## Why It Matters
Stablecoins now underpin settlement across DeFi, fintech, and institutional finance — yet the supporting infrastructure remains fragmented:
| Legacy Approach | Limitation |
| - | - |
| Lock & Mint Bridges | Depend on wrapped assets and custodial collateral — over \$2.5B lost since 2021. |
| Market Maker Hops | Require prefunded liquidity, introduce spreads, and create slippage for large transfers. |
| Manual Message Relays | Enable native mints but still rely on multiple transactions and human intervention. |
CashmereLabs unifies these models by combining issuer-backed messaging (Circle CCTP, Tether USDT0) with automation, security, and a universal UX — delivering frictionless mobility for stablecoins.
## Operating Model
> [!NOTE]
>
> Cashmere smart contracts, relayers, and policy engines orchestrate the **burn → attestation → mint → yield → settlement** cycle. Every operation — from cross-chain transfer to yield allocation — executes as a single, deterministic transaction.
## Differentiators
> [card] Zero-Slippage Mobility
>
> Native burn-and-mint flows with guaranteed outputs. No wrapped tokens or pooled liquidity.
> [card] Omnichain Coverage
>
> Unified experience across Ethereum, Arbitrum, Base, Solana, Sui, Aptos, Cosmos, and upcoming L1/L2 integrations.
> [card] Autonomous Yield Agents
>
> Smart agents allocate idle balances toward the highest risk-adjusted APRs across venues like Morpho, Felix, and Hyperbeat.
> [card] Privacy-Preserving Transfers
>
> Upcoming zk-based settlement layer with optional disclosure for auditors and institutional workflows.
> [card] Seamless On/Off Ramps
>
> Cashmere Gate connects fiat payment networks to stablecoins through a single integration.
> [card] MEV & Compliance Controls
>
> Deterministic outputs remove frontrunning while policy engines enforce configurable compliance checks.
## Supported Networks
| Chain | Gas Cost\* | Average Time | Status |
| - | - | - | - |
| **Ethereum** | ≈150k gas (\~\$0.35) | ≈20 seconds | ✅ Live |
| **Arbitrum** | ≈150k gas (\~\$0.003) | ≈8 seconds | ✅ Live |
| **Optimism** | ≈150k gas (\~\$0.003) | ≈8 seconds | ✅ Live |
| **Base** | ≈150k gas (\~\$0.003) | ≈8 seconds | ✅ Live |
| **Polygon** | ≈150k gas (\~\$0.003) | ≈5 seconds | ✅ Live |
| **Avalanche** | ≈\$0.004 | ≈5 seconds | ✅ Live |
| **Solana** | ≈\$0.008 | ≈3 seconds | ✅ Live |
| **Sui** | ≈\$0.018 | ≈3 seconds | ✅ Live |
| **Aptos** | ≈\$0.002 | ≈3 seconds | ✅ Live |
| **Unichain** | ≈\$0.003 | ≈5 seconds | ✅ Live |
| **Linea** | ≈\$0.003 | ≈5 seconds | ✅ Live |
| **Worldchain** | ≈\$0.003 | ≈5 seconds | ✅ Live |
| **Sei** | ≈\$0.003 | ≈5 seconds | ✅ Live |
| **Sonic** | ≈\$0.0005 | ≈8 seconds | ✅ Live |
| **HyperEVM** | ≈\$0.0015 | ≈5 seconds | ✅ Live |
| **Monad** | ≈\$0.0015 | ≈8 seconds | ✅ Live |
| **Arc** | ≈\$0.004, paid in USDC | ≈1 second | ✅ Live |
\* Gas costs and timings are indicative and fluctuate with network conditions.
## What Comes Next
* Launch autonomous yield agents with configurable risk and diversification policies.
* Roll out privacy-preserving transfer flows with selective disclosure APIs.
* Deliver unified on/off ramps (Cashmere Gate) across strategic geographies.
# Cashmere Bridge
Source: https://docs.cashmere.exchange/products/bridge
Zero-slippage, native stablecoin transfers across chains.
## Summary
Cashmere Bridge delivers deterministic, issuer-backed stablecoin transfers across EVM and non-EVM networks. The bridge uses message-based burn-and-mint flows (Circle CCTP, Tether USDT0) with Cashmere relayers orchestrating attestations, fee collection, and mint execution.
> [!TIP]
>
> **Production** – Live on Ethereum, BNB Chain, Avalanche, Arbitrum, Optimism, Base, Unichain, Worldchain, Polygon, Linea, Sei, Sonic, HyperEVM, Monad, Arc, Aptos, Solana, and Sui. [Try the bridge →](https://app.cashmere.exchange)
## Core Advantages
> [card] Zero Slippage
>
> Direct burn-and-mint transfers with exact output amounts; no pooled liquidity or wrapped assets.
> [card] Single Transaction UX
>
> Users sign once with relayer quote data embedded; Cashmere relayers complete destination minting.
> [card] MEV Resilience
>
> Guaranteed outputs remove sandwich and frontrunning vectors.
> [card] Programmable Fees
>
> Real-time quotes exposed via API, signed, and verified on-chain for predictable fee management.
## Transfer Flow
**1. Quote**
Client requests a signature from the Gas API. Response includes fee, deadline, and signature (ECDSA or Ed25519).
**2. Burn**
User calls the Cashmere contract on the source chain, burning native stablecoins and emitting an event.
**3. Attest**
Relayer retrieves the issuer attestation, verifies signatures, and prepares destination calldata.
**4. Mint**
Relayer submits the mint transaction on the destination chain; recipient receives the exact amount minus relayer fee (if paid in USDC).
## Network Coverage
| Chain | Gas Cost\* | Finality Time | Messaging Standard |
| - | - | - | - |
| **Ethereum L1** | ≈150k gas (\~\$0.35) | ≈20 seconds | CCTP v1 |
| **Arbitrum / Base / Optimism** | ≈150k gas (\~\$0.003) | ≈8 seconds | CCTP v2 (Fast/Normal thresholds) |
| **Avalanche** | ≈\$0.004 | ≈5 seconds | CCTP v2 |
| **Solana** | ≈\$0.008 | ≈3 seconds | CCTP (Anchor) |
| **Sui / Aptos** | ≈$0.018 / ≈$0.002 | ≈3 seconds | CCTP (Move) |
\* Indicative values; actual costs fluctuate with network conditions.
## Integration Notes
* Use the [Gas API](/api-reference/quote) to retrieve signatures and fee amounts.
* Pass `minFinalityThreshold` values aligned with Circle guidance (1,000 Fast / 2,000 Normal).
* Monitor transfers via the [Monitoring API](/api-reference/analytics) using `/transactionsmainnet`.
# Cashmere Gate
Source: https://docs.cashmere.exchange/products/gate
Unified fiat ↔ stablecoin access across chains.
## Summary
Cashmere Gate delivers a single integration for converting between fiat and stablecoins, then distributing liquidity across any supported chain via Cashmere Bridge. The goal is to remove regional fragmentation, inconsistent UX, and multi-hop settlement for on/off-ramp flows.
> [!WARNING]
>
> **Status:** In development. Initial release targeted for 2026.
## Planned Capabilities
> [card] Unified UX
>
> Consistent flow for deposits and withdrawals across desktop, mobile, and embedded widgets.
> [card] Global Payment Coverage
>
> Support for cards, bank rails (ACH/SEPA/local), and regional payment schemes.
> [card] Omnichain Settlement
>
> Immediate delivery of stablecoins on the chain of choice using Cashmere Bridge.
> [card] Routing Intelligence
>
> Best-rate execution across multiple liquidity and FX partners with transparent fees.
> [card] Compliance Native
>
> Built-in KYC/AML workflows, sanctions screening, and reporting for regulated entities.
> [card] Developer Friendly
>
> APIs and embeddable components for wallets, fintechs, and dApps.
## Customer Journey
**1. On-Ramp**
User selects destination chain, enters amount, and chooses payment method. Cashmere routes through preferred payment partners and delivers stablecoins via the bridge.
**2. Portfolio Actions**
Funds can be deployed into Cashmere Yield Agents, used for private transfers, or consumed by any downstream DeFi application.
**3. Off-Ramp**
Stablecoins are bridged to the preferred settlement partner and delivered via bank rails or local payment networks.
## Ecosystem Synergies
* **Cashmere Bridge** – enables instant delivery across chains without slippage.
* **Cashmere Yield Agents** – optional auto-allocation into yield strategies post on-ramp.
* **Cashmere Privacy** – optional privacy-preserving flows before off-ramping.
## Economics & Compliance
* Transparent fees surfaced ahead of execution, with volume-based pricing for institutions.
* Licensed fiat partners handle custody and settlement under their respective regulatory regimes.
* Cashmere provides unified compliance toolkits (KYC, transaction screening) for developers embedding the service.
Questions or partnership enquiries: [contact@cashmere.exchange](mailto:contact@cashmere.exchange).
# Cashmere Privacy
Source: https://docs.cashmere.exchange/products/privacy
Privacy-preserving, issuer-backed stablecoin transfers.
## Summary
Cashmere Privacy extends the bridge infrastructure with zero-knowledge proofs and policy tooling so organisations can settle stablecoin flows without exposing counterparties, amounts, or routing metadata.
> [!WARNING]
>
> **Status:** Research and prototyping. Targeting public testnet in 2026.
## Design Objectives
> [card] Confidential Settlement
>
> Hide key transaction details on-chain while maintaining verifiable correctness.
> [card] Omnichain Coverage
>
> Deliver the same privacy guarantees across all Cashmere-supported networks.
> [card] Compliance Optionality
>
> Provide selective disclosure and audit trails for regulated participants.
> [card] CCTP / USDT0 Compatibility
>
> Integrate natively with issuer messaging standards for zero-slippage mobility.
## Technical Approach
**1. Proof Construction**
Users generate zk proofs attesting to valid balances and transfer intent without revealing sensitive data.
**2. Source Validation**
Proofs are verified prior to burning assets on the origin chain, ensuring compliance with Cashmere policies.
**3. Private Minting**
Destination mints occur without exposing origin addresses or amounts. Optional audit hooks capture encrypted metadata.
## Privacy Modes
* **Standard** – hides amount and recipient while retaining origin metadata for operational purposes.
* **Advanced** – shields origin, amount, and recipient; intended for treasury or enterprise flows.
* **Compliance** – allows designated auditors to decrypt transaction metadata via selective disclosure.
## Roadmap Highlights
> [card] Phase 1
>
> Cryptographic design, threat modelling, and issuer alignment (current).
> [card] Phase 2
>
> Closed testnet with limited privacy features and compliance APIs.
> [card] Phase 3
>
> Mainnet deployment with full privacy/compliance tooling.
> [card] Phase 4
>
> Ongoing enhancements, partner integrations, and open-source release cadence.
## Integration Guidance
* Privacy flows reuse the Gas API for fee/signature generation.
* Builders can choose between public and private transfer flows within the same contract suite.
* Selective disclosure keys and audit workflows will be exposed via enterprise APIs.
Interested teams can register interest at [contact@cashmere.exchange](mailto:contact@cashmere.exchange).
# Cashmere Yield Agents
Source: https://docs.cashmere.exchange/products/yield-agents
Autonomous yield routing for stablecoin treasuries.
## Summary
Cashmere Yield Agents allocate stablecoin reserves across integrated venues to maximise risk-adjusted return. The service is built on top of Cashmere Bridge, enabling omnichain rebalancing with zero slippage.
> [!WARNING]
>
> **Status:** Closed testnet. Production launch to be announced.
## Capabilities
> [card] Autonomous Allocation
>
> Agents monitor supported lenders and liquidity venues, deploying capital based on risk-adjusted yields.
> [card] Policy Controls
>
> Operators define guardrails (allowed venues, concentration limits, liquidity buffers) enforced on-chain.
> [card] Cross-Chain Execution
>
> Uses Cashmere Bridge to reposition capital across EVM and non-EVM networks without wrapped assets.
> [card] Transparent Reporting
>
> On-chain performance metrics, utilisation, and risk scores surfaced through dashboards and APIs.
## Operating Flow
**1. Opportunity Scanning**
Agents ingest yields, volatility, and protocol risk data from integrated venues.
**2. Scoring & Selection**
A scoring engine ranks venues based on risk-adjusted return, diversification rules, and liquidity requirements.
**3. Deployment**
Stablecoins are allocated across chosen venues. Reallocations use zero-slippage transfers via Cashmere Bridge.
**4. Monitoring & Alerts**
Continuous monitoring triggers rebalancing, alerts, or de-risking when thresholds are breached.
## Integrations (Initial Set)
> [card] Morpho
>
> Peer-to-peer lending with dynamic risk tranching.
> [card] Jupiter
>
> Stablecoin yields.
> [card] Euler
>
> Borrow/lend protocol supporting risk-managed stablecoin exposure.
> [card] Additional Venues
>
> Additional issuers, RWA lenders, and MM venues under evaluation.
## Benefits
* **Hands-free operations** – treasuries deposit once and let agents maintain target exposures.
* **Risk-aware returns** – allocation decisions consider protocol audits, liquidity depth, and historical volatility.
* **Unified view** – dashboards and APIs present consolidated exposure across chains and venues.
* **Instant liquidity** – withdrawals trigger automated unwinds with no fixed lockups.
## Security & Governance
* Whitelist-based venue selection with audit requirements.
* Concentration and stop-loss policies enforced in smart contracts.
* 24/7 monitoring with human-in-the-loop overrides for extraordinary events.
* End-to-end logging for compliance and reporting.
Interested in participating? Reach out at [contact@cashmere.exchange](mailto:contact@cashmere.exchange) for testnet access.