> For the complete documentation index, see [llms.txt](https://trench-today.gitbook.io/trench-today/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://trench-today.gitbook.io/trench-today/for-developers/contracts.md).

# Contract Reference

{% tabs %}
{% tab title="Robinhood Mainnet" %}

## Network info

|                 |                   |
| --------------- | ----------------- |
| Chain ID        | `4663`            |
| Architecture    | Arbitrum Orbit L2 |
| Native currency | ETH (18 decimals) |

{% hint style="info" %}
Robinhood is a single-layer launchpad: users call **TrenchManager** directly, with no aggregation or vault layer in between. Tokens are quoted in native **ETH**. RPC endpoint is available from the team on request.
{% endhint %}

{% hint style="warning" %}
**V4 upgrade (2026-07-13).** New tokens now graduate to **Uniswap V4** instead of Uniswap V3. The proxy addresses below (TrenchManager, BondingCurveFactory, FeeVault) are **unchanged** — only the Manager implementation was swapped (it now exposes `migrateToV4`), and two new contracts were added (`TrenchV4FeeHook`, `TrenchPositionLocker`). Tokens that graduated **before** the upgrade stay on their Uniswap V3 pools and keep using the LPFeeSplitter — see the legacy sections below. The on-curve (pre-graduation) flow is identical for both.
{% endhint %}

## Deployments

| Contract                 | Address                                      | Description                                                                                                                          |
| ------------------------ | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| **TrenchManager**        | `0x77dC6f6361b7b99456FC3761ce5b7ddA80d83f9d` | Single entry point for all interactions and the `approve` target. Implementation now `TrenchManagerV4Migrator` (adds `migrateToV4`). |
| BondingCurveFactory      | `0x2ECFb98BCe4f3616115E4a2A7a2379AF388DFbAA` | Curve and token factory                                                                                                              |
| FeeVault                 | `0x076e3Cd13E188e3646828e7cEBB766C7Dd6aDb8A` | Protocol/dev fee collection on the curve (ETH)                                                                                       |
| **TrenchV4FeeHook**      | `0x31200554eCA1EFf6d130dbeC7975aFA1234b60CC` | Post-graduation Uniswap V4 swap-fee hook (charges 1% quote-side per swap, splits dev 60% / protocol 40% instantly)                   |
| **TrenchPositionLocker** | `0x1a3881e7013307Bc67b22b8793B93a2114aAe49E` | Holds and locks the graduation V4 LP position NFT (1-year timelock)                                                                  |
| WETH (WNative)           | `0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73` | Wrapped ETH — used internally at graduation                                                                                          |
| Owner / Deployer         | `0xbeb76A70c82B09E30B2008eAFa7F987987EC9e0b` | Contract owner                                                                                                                       |

### Uniswap V4 (graduation target for new tokens)

| Contract           | Address                                      |
| ------------------ | -------------------------------------------- |
| V4 PoolManager     | `0x8366a39CC670B4001A1121B8F6A443A643e40951` |
| V4 PositionManager | `0x58daec3116aae6D93017bAAea7749052E8a04fA7` |
| Fee hook           | `0x31200554eCA1EFf6d130dbeC7975aFA1234b60CC` |

The V4 pool's LP fee (`poolKey.fee`) is `0` — LPs charge nothing; the swap fee is taken entirely by the hook (1% on the quote side).

### Legacy — Uniswap V3 (tokens graduated before the V4 upgrade)

| Contract                         | Address                                      | Description                                                                               |
| -------------------------------- | -------------------------------------------- | ----------------------------------------------------------------------------------------- |
| LPFeeSplitter                    | `0x74a40b65320c717F0ECF74f68CcB910edCd08e22` | Post-graduation V3 swap-fee split (dev 60% / protocol 40%) — **legacy V3 graduates only** |
| UniV3 NonfungiblePositionManager | `0x73991a25C818Bf1f1128dEAaB1492D45638DE0D3` | V3 LP position NFT manager                                                                |
| UniV3 Factory                    | `0x1f7d7550B1b028f7571E69A784071F0205FD2EfA` | Uniswap V3 factory                                                                        |
| UniV3 SwapRouter                 | `0xCaf681a66D020601342297493863E78C959E5cb2` | Uniswap V3 swap router                                                                    |

Tokens that graduated before the upgrade remain in their Uniswap V3 pools (1% fee tier) and continue to split LP fees through the LPFeeSplitter. They are **not** migrated to V4.

## Quote token

Tokens are priced in native ETH.

| Quote      | Address                                      | Decimals | Buy funding           | Approve |
| ---------- | -------------------------------------------- | -------- | --------------------- | ------- |
| Native ETH | `0x0000000000000000000000000000000000000000` | 18       | `msg.value` (payable) | None    |

`virtualQuote` / `realQuoteReserves` are denominated in ETH (18 decimals). The contract's trading methods take a `quoteAddr` argument (`address(0)` = ETH) so the curve can support additional quote tokens in the future; today only ETH is enabled.

## On-chain parameters

### Trading fee

| Parameter      | Value                                                 | Description                                |
| -------------- | ----------------------------------------------------- | ------------------------------------------ |
| Trade fee      | 1% (`FEE_NUMERATOR = 100 / FEE_DENOMINATOR = 10,000`) | Applied to every buy and sell.             |
| Creator share  | 30% of trade fee                                      | ≈ 0.3% of trade size. Accrues in FeeVault. |
| Protocol share | 70% of trade fee                                      | ≈ 0.7% of trade size.                      |
| Max extra fee  | 5% (`MAX_EXTRA_FEE_RATE = 500 / 10,000`)              | Max rate for `buyWithFee` / `sellWithFee`. |

{% hint style="info" %}
Unlike MegaETH, Robinhood uses a `10,000` fee denominator (same as Ethereum). A 0.5% extra fee is `50`.
{% endhint %}

### Bonding curve config

| Parameter                            | Value                                       | Description                                             |
| ------------------------------------ | ------------------------------------------- | ------------------------------------------------------- |
| Total supply                         | `1,000,000,000` (1e27 wei, 18 decimals)     | Fixed per token.                                        |
| `virtualQuote` (initial)             | `1712328767123287671` (\~1.712 ETH)         | Starting virtual ETH reserve.                           |
| `virtualToken` (initial)             | `1073972602739726027397260274` (\~1.074e27) | Starting virtual token reserve.                         |
| Graduation threshold (`targetToken`) | `200,000,000` (2e26 wei)                    | Curve graduates when `realTokenReserves ≤ targetToken`. |
| Total user spend (inc. fee)          | \~5 ETH                                     | Gross ETH to fill the curve.                            |

Curve parameters are read via `getConfig(quote)` (pass `address(0)` for ETH).

### Listing / migration

| Parameter                   | Value                | Description                                                                         |
| --------------------------- | -------------------- | ----------------------------------------------------------------------------------- |
| Listing fee rate            | 200 / 10000 = **2%** | Deducted from the raised quote at graduation, before seeding the pool.              |
| Graduation DEX (new tokens) | Uniswap V4           | Full-range position seeded at `migrateToV4`; LP NFT locked in TrenchPositionLocker. |
| V4 pool LP fee              | `0`                  | LPs charge nothing; swap fee is taken by the hook.                                  |
| V4 hook swap fee            | **1%** quote-side    | Charged per swap by TrenchV4FeeHook, split dev 60% / protocol 40% instantly.        |
| Legacy V3 fee tier          | 10000 (= **1%**)     | Fee tier for tokens graduated before the V4 upgrade.                                |

### FeeVault claim threshold (`minClaimAmount`)

| FeeVault                 | Value                     |
| ------------------------ | ------------------------- |
| ETH FeeVault (`0x076e…`) | `1e12` wei (0.000001 ETH) |

## TrenchManager ABI

### Trading functions

#### `createCurve`

Deploy a new token and bonding curve, with an optional initial dev buy. Send `msg.value = amountIn` for the initial dev buy (pass `address(0)` as `quoteAddr` for ETH).

{% hint style="info" %}
The V4 implementation **no longer pre-builds an anchor pool** at `createCurve` (the old V3 anchor mechanism is retired). Front-running of the graduation pool is instead prevented by the hook's `beforeInitialize`, which only admits an already-authorized `poolId`.
{% endhint %}

```solidity
function createCurve(
    address quoteAddr,      // address(0) = ETH
    address creator,
    string  name,
    string  symbol,
    string  tokenURI,
    uint256 amountIn,       // initial dev buy in ETH; 0 = no dev buy
    uint256 amountOutMin,
    bytes32 salt
) external payable returns (
    address curve,
    address token,
    uint256 virtualQuote,
    uint256 virtualToken,
    uint256 amountOut
);
```

#### `buy`

Buy tokens with ETH — payable, `msg.value = amountIn`.

```solidity
function buy(
    uint256 amountIn,       // must equal msg.value
    uint256 amountOutMin,   // slippage protection
    address token,
    address to,             // token recipient
    uint256 deadline        // unix timestamp; 0 = no deadline
) external payable returns (uint256 amountOut);
```

#### `buyWithFee`

Buy with an additional third-party fee (up to 5%).

```solidity
function buyWithFee(
    uint256 amountIn,
    uint256 amountOutMin,
    address token,
    address to,
    uint256 deadline,
    uint256 extraFeeRate,     // denominator 10,000; max 500 (= 5%)
    address extraFeeReceiver  // must not be address(0) when extraFeeRate > 0
) external payable returns (uint256 amountOut);
```

Fee flow:

```
Extra fee     = amountIn × extraFeeRate / 10000  → extraFeeReceiver
Protocol fee  = (amountIn − extra fee) × 1%      → FeeVault
Curve input   = amountIn − extra fee − protocol fee
```

#### `sell`

Sell tokens for ETH. Requires prior `ERC20.approve` of the **meme token** to TrenchManager. Net ETH is transferred to `to`.

```solidity
function sell(
    uint256 amountIn,       // token wei
    uint256 amountOutMin,
    address token,
    address to,             // quote recipient
    uint256 deadline
) external returns (uint256 netQuoteOut);
```

#### `sellWithFee`

Sell with an additional third-party fee (up to 5%).

```solidity
function sellWithFee(
    uint256 amountIn,
    uint256 amountOutMin,
    address token,
    address to,
    uint256 deadline,
    uint256 extraFeeRate,
    address extraFeeReceiver
) external returns (uint256 netQuoteOut);
```

### Quote functions

#### `previewBuy`

Estimate output and protocol fee for a buy without sending a transaction.

```solidity
function previewBuy(address token, uint256 amountIn)
    external view returns (uint256 amountOut, uint256 fee);
```

#### `previewSell`

Estimate net quote out and protocol fee for a sell.

```solidity
function previewSell(address token, uint256 amountIn)
    external view returns (uint256 netQuoteOut, uint256 fee);
```

{% hint style="info" %}
`previewBuy` / `previewSell` return the **protocol** fee only. Any extra fee from `buyWithFee` / `sellWithFee` is applied on top by your own rate; compute it client-side.
{% endhint %}

### Query functions

```solidity
function tokenInfo(address token) external view returns (
    address curve,
    address creator,
    address quoteAddr,          // address(0) = ETH
    uint256 realQuoteReserves,  // ETH (18 decimals)
    uint256 realTokenReserves,
    uint256 virtualQuote,
    uint256 virtualToken,
    bool    isMigrating_,
    bool    isMigrated_
);
function curves(address token)      external view returns (address curve);
function creators(address token)    external view returns (address creator);
function tokenQuote(address token)  external view returns (address);   // the token's quote (ETH = address(0))
function allowedQuotes(address quote) external view returns (bool);
function feeVaults(address quote)   external view returns (address);   // FeeVault for a given quote
function factory()                  external view returns (address);
function wNative()                  external view returns (address);   // = WETH

// V4 infrastructure
function poolManager()              external view returns (address);   // V4 PoolManager
function v4PositionManager()        external view returns (address);   // V4 PositionManager
function v4FeeHook()                external view returns (address);   // TrenchV4FeeHook (post-graduation swap fee)
function positionLocker()           external view returns (address);   // TrenchPositionLocker (locks graduation LP NFT)
function platformTreasury()         external view returns (address);
function isMigrator(address a)      external view returns (bool);
```

{% hint style="info" %}
The old V3 accessors (`v3PositionManager`, `poolFee`, `anchorReserve`, `lpFeeSplitter`) were renamed `DEPRECATED_*` in the V4 implementation and are no longer part of the integration surface.
{% endhint %}

### Migration (V4)

```solidity
function migrateToV4(
    address token,
    uint256 amount0Min,
    uint256 amount1Min,
    uint256 deadline
) external returns (bytes32 poolId, uint256[] positionIds);
```

Only callable by a whitelisted migrator, once the curve has filled (`isMigrating`). In a single atomic transaction it authorizes the pool, initializes it, mints and **locks** the full-range LP position in TrenchPositionLocker, marks the token migrated, and enables swaps. Deducts the 2% listing fee from the quote side before seeding the pool, and sets the token to free-transfer mode. Graduation emits `V4Listing` (the pool is identified by `poolId`, a `bytes32` — not a pool address).

{% hint style="info" %}
A separate `migrateToV3(address,uint256,uint256,uint256)` exists only to rescue a small set of tokens created *before* the upgrade that pre-built a V3 anchor pool. New tokens (no anchor) always use `migrateToV4`; calling `migrateToV3` on them reverts. Both are migrator-only — integrators never call migration directly.
{% endhint %}

## IBondingCurve ABI

One `BondingCurve` contract is deployed per token. Query via `TrenchManager.tokenInfo(token)` or `curves(token)`. Write methods are TrenchManager-only.

```solidity
function getReserves()                  external view returns (uint256 realQuote, uint256 realToken);
function getVirtualReserves()           external view returns (uint256 virtualQuote, uint256 virtualToken);
function getTargetToken()               external view returns (uint256);   // 200 M tokens
function getRemainingTokenToSell()      external view returns (uint256);   // tokens left before graduation
function getQuoteTarget()               external view returns (uint256);   // quote raise target
function getRemainingQuoteToGraduate()  external view returns (uint256);
function getK()                         external view returns (uint256);
function isMigrating()                  external view returns (bool);      // curve filled, awaiting migration
function isMigrated()                   external view returns (bool);      // migrated (Uniswap V4; legacy graduates on V3)
function migrating()                    external view returns (bool);      // raw storage accessor
function migrated()                     external view returns (bool);      // raw storage accessor
function quote()                        external view returns (address);   // this curve's quote token
function token()                        external view returns (address);
function realQuoteReserves()            external view returns (uint256);
function realTokenReserves()            external view returns (uint256);
```

{% hint style="info" %}
Graduation condition: `realTokenReserves ≤ targetToken` (targetToken = 200 M = 20% of supply). Reserves are named `Quote` (not `Native`) because the curve is quote-parameterized; the live quote is ETH.
{% endhint %}

## IBondingCurveFactory ABI

```solidity
struct Config {
    uint256 listingFeeRate;     // 200 (2%)
    uint256 tokenTotalSupply;   // 1e27
    uint256 virtualQuote;       // ETH: 1712328767123287671
    uint256 virtualToken;       // ETH: 1073972602739726027397260274
    uint256 k;
    uint256 quoteTarget;        // quote raise target
    uint256 targetToken;        // 2e26
    uint256 realQuoteReserves;  // 0 at init
    uint256 realTokenReserves;  // 1e27 at init
}

function getConfig(address quote)         external view returns (Config memory);  // pass address(0) for ETH
function getListingFeeRate(address quote) external view returns (uint256);
function getK(address quote)              external view returns (uint256);
function getCore()                        external view returns (address);        // TrenchManager
function INIT_REAL_TOKEN_RESERVES()       external view returns (uint256);         // 1e27
function LISTING_FEE_DENOMINATOR()        external view returns (uint256);         // 10000
```

{% hint style="info" %}
`getConfig`, `getK`, and `getListingFeeRate` all take a quote address so the factory can hold config per quote token. Pass `address(0)` for ETH — the only enabled quote today.
{% endhint %}

## IFeeVault ABI

The FeeVault collects and pays out native ETH (`quoteToken() == address(0)`). Split is **30% creator (dev) / 70% protocol**.

```solidity
function quoteToken()                  external view returns (address);   // address(0) = ETH
function creditsDev(address creator)   external view returns (uint256);   // claimable dev balance (quote raw)
function creditsProtocol()             external view returns (uint256);   // accrued protocol fee
function minClaimAmount()              external view returns (uint256);   // decimals-aware claim floor
function feeReceiver()                 external view returns (address);
function trenchManager()               external view returns (address);
function devClaim(address creator)     external;                          // creator claims dev share
function protocolClaim(uint256 amount) external;                          // only feeReceiver
function credit(address creator, address token, uint256 amount) external payable;
function DEV_CLAIM_RATIO()             external view returns (uint256);    // 3000
function DEV_CLAIM_RATIO_DENOMINATOR() external view returns (uint256);    // 10000
```

## ITrenchV4FeeHook ABI

The post-graduation swap fee on the new **Uniswap V4** pools. The hook charges **1% on the quote side** of every swap (the V4 pool's own LP fee is `0`) and splits it by `devShareRate` — the dev share (default **60%**) is sent to the creator instantly, the remainder to the treasury. There is **no claim step**: fees settle on every swap.

```solidity
uint256 public constant OUTER_TOTAL_FEE = 100;    // numerator
uint256 public constant FEE_DENOMINATOR = 10000;  // → 1%
function devShareRate() external view returns (uint256);   // dev share in bps, default 6000 (60%), configurable
function manager()      external view returns (address);
function treasury()     external view returns (address);
function poolConfigs(bytes32 poolId) external view returns (
    address token, address dev, bool authorized, bool registered,
    bool swapEnabled, bool quoteIsCurrency0, uint256 totalFeeRate1e9
);
function poolOfToken(address token) external view returns (bytes32 poolId);
function hasPool(address token)      external view returns (bool);
```

{% hint style="info" %}
If a dev cannot receive its share (e.g. rejects ETH or is blacklisted on an ERC-20 quote), the hook falls back to sending that share to the treasury via `try/catch` — the swap is never blocked. `SwapFeeCharged.devShare` reflects the amount actually paid to the dev (0 on fallback). Only `exactInput` swaps are supported; `exactOutput` reverts.
{% endhint %}

## ITrenchPositionLocker ABI

Holds and locks the graduation V4 LP position NFT. Positions carry a **1-year timelock** (`LOCK_DURATION = 365 days`); after expiry the owner may unlock and withdraw. Neither creators nor traders can remove liquidity.

```solidity
function positionIds(address token, bytes32 poolId) external view returns (uint256[] memory);
function lockedPosition(uint256 positionId)          external view returns (bool);
function manager()                                   external view returns (address);
function positionManager()                           external view returns (address);
function unlockAndWithdrawPosition(uint256 positionId, address to) external; // onlyOwner, subject to timelock
```

## ILPFeeSplitter ABI (legacy — V3 graduates only)

{% hint style="warning" %}
This contract serves **only tokens that graduated before the 2026-07-13 V4 upgrade**. New graduates use the V4 fee hook above, which pays dev fees per swap with no claim step. This section is retained so existing V3 graduates can still claim.
{% endhint %}

For legacy V3 graduates, a token trades on a Uniswap V3 pool (1% fee tier) and its graduation LP NFT mints to the **LPFeeSplitter** rather than to a plain LP-receiver wallet. It collects the pool's swap fees and splits the **quote side** (ETH) **dev 60% / protocol 40%**; the meme side goes entirely to the protocol. The dev share ratio is configurable (`devShareBps`, currently `6000`).

{% hint style="info" %}
This is a **separate, post-graduation** fee stream from the on-curve `FeeVault` (which pays dev 30% of the 1% trade fee). A legacy-V3 dev earns from **both**: the curve `FeeVault` while the token is on the curve, and the `LPFeeSplitter` on every Uniswap V3 swap after graduation.
{% endhint %}

The splitter uses an **accounting model**: any `collect` (dev `claim` or protocol `sweep`) pulls the pool fees into the contract and books credits by ratio — funds stay in the contract until each party withdraws, so dev and protocol claims are independent and neither pays for the other's gas.

```solidity
// —— Dev (creator) claiming ——
// Collects fees across all of the creator's positions, books credits, then
// pays out the quote-side 60% to the creator (WETH auto-unwrapped to native ETH).
// One call — no approve, no ticket.
function claim(address creator) external;
// Subset variant — when a creator has so many positions that claim() runs out of gas
function claimPositions(address creator, uint256[] calldata tokenIds) external;
// Withdraw already-booked credit without re-collecting (top-up / non-quote side)
function withdrawCredit(address creator, address token) external;

// —— Read (front-end estimation) ——
function creatorPositions(address creator) external view returns (uint256[] memory); // creator's position tokenIds
function creatorCredits(address creator, address token) external view returns (uint256); // booked, claimable (dev 60%)
function protocolCredits(address token) external view returns (uint256);
function positions(uint256 tokenId) external view returns (address creator, address quoteToken);
function devShareBps() external view returns (uint256);   // dev share in bps — currently 6000 (60%), configurable
function BPS_DENOMINATOR() external view returns (uint256); // 10000
```

{% hint style="warning" %}
Claimable post-graduation fee = `creatorCredits[creator][quote]` (already collected) **plus** the uncollected pending quote fees × `devShareBps`. Estimate **both** parts — after a protocol `sweep`, the dev's share has moved into `creatorCredits` and pending resets to zero, so counting only pending under-reports. Read the ratio from `devShareBps()`; don't hard-code 60%.
{% endhint %}

## IToken (ERC-20)

Standard ERC-20 with a two-state transfer control.

| Mode         | Value | Who can transfer                             |
| ------------ | ----- | -------------------------------------------- |
| `free`       | `0`   | Anyone (post-graduation)                     |
| `restricted` | `1`   | Only via TrenchManager (default at creation) |

```solidity
function mode()          external view returns (uint8);   // 0 = free, 1 = restricted
function tokenURI()      external view returns (string memory);
function core()          external view returns (address); // TrenchManager
function setMode(uint8 mode_) external;                    // only core (TrenchManager)

// Standard ERC-20
function name()          external view returns (string memory);
function symbol()        external view returns (string memory);
function decimals()      external view returns (uint8);           // always 18
function totalSupply()   external view returns (uint256);         // always 1e27
function balanceOf(address account)                               external view returns (uint256);
function allowance(address owner, address spender)                external view returns (uint256);
function approve(address spender, uint256 value)                  external returns (bool);
function transfer(address to, uint256 value)                      external returns (bool);
function transferFrom(address from, address to, uint256 value)    external returns (bool);
```

{% hint style="warning" %}
A newly created token is `restricted` (mode 1): EOA-to-EOA transfers revert with `"Token: restricted"`, and only transfers where TrenchManager is the sender or recipient are allowed. This is why in-curve sells must approve the meme token to TrenchManager and route through `sell` — you cannot build your own pool pre-graduation. After migration completes, TrenchManager calls `setMode(0)` and the token trades freely on Uniswap V4 (legacy graduates trade on Uniswap V3).
{% endhint %}

## Events

### TrenchManager

| Event           | Key fields                                                                                        | When                                             |
| --------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
| `TokenCreate`   | `creator, curve, token, quote, name, symbol, timestamp, tokenURI`                                 | New token created                                |
| `TokenPurchase` | `token, buyer, amountOut, quoteAmountUsed, protocolFee, extraFee, extraFeeReceiver, extraFeeRate` | Token bought                                     |
| `TokenSale`     | `token, seller, amountIn, netQuoteOut, protocolFee, extraFee, extraFeeReceiver`                   | Token sold                                       |
| `Sync`          | `token, realQuoteReserves, realTokenReserves, virtualQuote, virtualToken`                         | After every trade                                |
| `LimitReach`    | `token` (indexed)                                                                                 | Graduation threshold hit — enters migrating      |
| `V4Listing`     | `token` (indexed), `poolId` (indexed), `positionIds, quoteAmount, tokenAmount, listingFee`        | Migrated to Uniswap V4                           |
| `MigrationDust` | `token, poolId, quoteDust, tokenDust, to`                                                         | Leftover dust returned after seeding the V4 pool |
| `SetV4Config`   | `poolManager, v4PositionManager, v4FeeHook, positionLocker, platformTreasury`                     | V4 infrastructure configured                     |

`TokenCreate` has `creator`, `curve`, and `token` indexed — `token` is the 3rd indexed topic, or read it from the return value. For `V4Listing`, `token` and `poolId` are indexed; the pool is identified by `poolId` (`bytes32`), not a pool address.

{% hint style="info" %}
The five on-curve events (`TokenCreate`, `TokenPurchase`, `TokenSale`, `Sync`, `LimitReach`) are byte-for-byte identical to the pre-V4 version — existing curve listeners need no changes. Only the graduation event changed (`Listing` → `V4Listing`). Legacy V3 graduates still emitted the old `Listing` event at their graduation time.
{% endhint %}

### FeeVault

| Event           | Key fields                    | When                       |
| --------------- | ----------------------------- | -------------------------- |
| `Credit`        | `token` (indexed), `amount`   | Fee deposited from a trade |
| `DevClaim`      | `creator` (indexed), `amount` | Creator claimed dev share  |
| `ProtocolClaim` | `amount`                      | Protocol fee withdrawn     |

### TrenchV4FeeHook

| Event             | Key fields                                               | When                                                                                                 |
| ----------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `SwapFeeCharged`  | `token, poolId, quoteToken, feeBase, totalFee, devShare` | Fee taken on a V4 swap; `devShare` = amount actually paid to the dev (0 if it fell back to treasury) |
| `PoolAuthorized`  | `token, poolId`                                          | Pool authorized (front-run guard)                                                                    |
| `SwapEnabled`     | `poolId`                                                 | Post-graduation trading opened                                                                       |
| `SwapPaused`      | `poolId`                                                 | Trading paused                                                                                       |
| `SetDevShareRate` | `previousRate, newRate`                                  | Dev split ratio changed                                                                              |

### TrenchPositionLocker

| Event             | Key fields                   | When                                 |
| ----------------- | ---------------------------- | ------------------------------------ |
| `PositionsLocked` | `token, poolId, positionIds` | Graduation LP position NFT(s) locked |

### LPFeeSplitter (legacy — V3 graduates only)

| Event              | Key fields                                       | When                                           |
| ------------------ | ------------------------------------------------ | ---------------------------------------------- |
| `RegisterPosition` | `tokenId, creator, quoteToken` (all indexed)     | A graduation LP NFT registered to the splitter |
| `Claim`            | `creator` (indexed), `token` (indexed), `amount` | Creator withdrew their post-graduation share   |
| `SetDevShare`      | `previous, current`                              | Dev split ratio changed                        |

## Error codes

Robinhood contracts use OpenZeppelin custom errors plus string reverts. The most common ones integrators will hit:

| Revert                                | Description                                                                        |
| ------------------------------------- | ---------------------------------------------------------------------------------- |
| `"Token: restricted"`                 | Direct transfer attempted while the token is in `restricted` mode (pre-graduation) |
| `OwnableUnauthorizedAccount(address)` | Caller lacks the required owner/migrator role                                      |
| `ReentrancyGuardReentrantCall()`      | Reentrant call blocked                                                             |
| `SafeERC20FailedOperation(address)`   | Underlying ERC-20 transfer/approve failed (e.g. missing token approval on sell)    |
| `ERC20InsufficientAllowance(...)`     | Selling without approving the meme token to TrenchManager                          |
| `ERC20InsufficientBalance(...)`       | Insufficient token or ETH balance                                                  |
| {% endtab %}                          |                                                                                    |

{% tab title="Ethereum Mainnet" %}

## Deployments

| Contract                    | Address                                      |
| --------------------------- | -------------------------------------------- |
| **TrenchManagerV2** (Proxy) | `0x974B2d86d6353c62f19110127aF1A5df4c6370f0` |
| **FeeVault**                | `0x18D9Ddd296b676d68e6658BcC6Dcdb6C23C28457` |
| **BondingCurveFactory**     | `0x02acb27BD38AB7aE4b569bA7251Ff31739Bd8E36` |

## On-chain parameters

| Parameter                            | Value                                                       | Description                                                     |
| ------------------------------------ | ----------------------------------------------------------- | --------------------------------------------------------------- |
| Trade fee                            | 1.25% (`12,500,000 / 1e9`)                                  | Applied to `amountIn` on every buy and sell.                    |
| Creator share                        | 24% of trade fee                                            | ≈ 0.3% of trade size. Accrues in FeeVault.                      |
| Protocol share                       | 76% of trade fee                                            | ≈ 0.95% of trade size.                                          |
| `virtualNative`                      | `2009158000000000000` (\~2.009 ETH)                         | Starting virtual ETH reserve.                                   |
| `virtualToken`                       | `1068000000000000000000000000` (\~1.068 × 10²⁷)             | Starting virtual token reserve.                                 |
| Total supply                         | `1000000000000000000000000000` (1 × 10²⁷, 1 billion tokens) | Fixed, minted at deploy.                                        |
| Graduation threshold (`targetToken`) | `200000000000000000000000000` (2 × 10²⁶, 200 M tokens)      | Migration triggers when real token reserves drop to this level. |
| Max platform fee                     | 5% (`500 / 10,000`)                                         | Max rate for `buyWithFee` / `sellWithFee`.                      |
| Minimum claim                        | 0.01 ETH                                                    | Below this, `devClaim` is rejected.                             |

## TrenchManagerV2 ABI

### Trading functions

#### `createCurve`

Deploy a new token and bonding curve. `msg.value` = `amountIn` (the initial dev buy, or 0).

```solidity
function createCurve(
    address creator,
    string  name,
    string  symbol,
    string  tokenURI,
    uint256 amountIn,       // ETH for initial dev buy; 0 = no dev buy
    uint256 amountOutMin,
    bytes32 salt
) external payable returns (
    address curve,
    address token,
    uint256 virtualNative,
    uint256 virtualToken,
    uint256 amountOut
);
```

#### `buy`

Buy tokens with ETH. No platform fee.

```solidity
function buy(
    uint256 amountIn,       // must equal msg.value
    uint256 amountOutMin,   // slippage protection
    address token,
    address to,             // token recipient
    uint256 deadline        // unix timestamp; 0 = no deadline
) external payable returns (uint256 amountOut);
```

#### `buyWithFee`

Buy tokens with an additional platform fee (up to 5%).

```solidity
function buyWithFee(
    uint256 amountIn,
    uint256 amountOutMin,
    address token,
    address to,
    uint256 deadline,
    uint256 buyFeeRate,       // denominator 10,000; max 500 (= 5%)
    address buyFeeReceiver    // must not be address(0)
) external payable returns (uint256 amountOut);
```

Fee flow:

```
Platform fee  = amountIn × buyFeeRate / 10000  → buyFeeReceiver
Protocol fee  = (amountIn − platform fee) × 1.25%  → FeeVault
Curve input   = amountIn − platform fee − protocol fee
```

#### `sell`

Sell tokens for ETH. No platform fee. Requires prior `ERC20.approve`.

```solidity
function sell(
    uint256 amountIn,       // token wei — must be Gwei-aligned (amountIn % 1e9 == 0)
    uint256 amountOutMin,
    address token,
    address to,             // ETH recipient
    uint256 deadline
) external returns (uint256 amountOut);
```

#### `sellWithFee`

Sell tokens with an additional platform fee (up to 5%).

```solidity
function sellWithFee(
    uint256 amountIn,
    uint256 amountOutMin,
    address token,
    address to,
    uint256 deadline,
    uint256 sellFeeRate,      // denominator 10,000; max 500 (= 5%)
    address sellFeeReceiver
) external returns (uint256 amountOut);
```

Fee flow:

```
Curve output  = calculated from bonding curve
Protocol fee  = curve output × 1.25%  → FeeVault
Platform fee  = curve output × sellFeeRate / 10000  → sellFeeReceiver
User receives = curve output − protocol fee − platform fee
```

### Quote functions

#### `quoteBuyWithFee`

Estimate output and fee breakdown for a buy without sending a transaction.

```solidity
function quoteBuyWithFee(
    uint256 amountIn,
    address token,
    uint256 buyFeeRate
) external view returns (
    uint256 amountOut,           // tokens user will receive
    uint256 protocolFee,
    uint256 buyFee,              // platform fee
    uint256 grossAmountUsed,     // ETH entering the curve
    uint256 totalAmountInUsed,   // total ETH consumed
    uint256 refundAmount         // ETH refunded if graduation hit mid-purchase
);
```

#### `quoteSellWithFee`

Estimate output and fee breakdown for a sell without sending a transaction.

```solidity
function quoteSellWithFee(
    uint256 amountIn,
    address token,
    uint256 sellFeeRate
) external view returns (
    uint256 grossAmountOut,  // total ETH from curve
    uint256 netAmountOut,    // ETH user will receive after all fees
    uint256 protocolFee,
    uint256 sellFee          // platform fee
);
```

### Mapping queries

```solidity
function curves(address token)   external view returns (address curve);    // BondingCurve for a token
function creators(address token) external view returns (address creator);  // creator wallet for a token
function factory()               external view returns (address);
function wNative()               external view returns (address);          // WETH
function vault()                 external view returns (address);          // FeeVault
```

## IBondingCurve ABI

One `BondingCurve` contract is deployed per token. Query it for reserves and graduation status.

```solidity
function realNativeReserves()    external view returns (uint256);
function realTokenReserves()     external view returns (uint256);
function getVirtualReserves()    external view returns (uint256 virtualNative, uint256 virtualToken);
function getK()                  external view returns (uint256);
function getTargetToken()        external view returns (uint256);          // 200 M tokens
function getRemainingTokenToSell() external view returns (uint256);
function migrating()             external view returns (bool);             // true = graduation threshold hit
function migrated()              external view returns (bool);             // true = listed on Uniswap V2
function token()                 external view returns (address);
function wNative()               external view returns (address);
function pair()                  external view returns (address);          // Uniswap V2 pair (post-migration)
```

## IBondingCurveFactory ABI

```solidity
struct Config {
    uint256 listingFeeRate;
    uint256 tokenTotalSupply;   // 1e27
    uint256 virtualNative;      // ~2.009 ETH
    uint256 virtualToken;       // ~1.068e27
    uint256 k;
    uint256 targetToken;        // 200 M tokens
    uint256 realNativeReserves; // initial = 0
    uint256 realTokenReserves;  // initial = 1e27
}

function getConfig()         external view returns (Config memory);
function wNative()           external view returns (address);
function getDexFactory()     external view returns (address);              // Uniswap V2 factory
function getListingFeeRate() external view returns (uint256);
```

## IToken (ERC-20)

Standard ERC-20 plus a `mode` field that controls transfer permissions before graduation.

```solidity
function mode()          external view returns (uint8);  // 0 = normal, 2 = controlled (pre-graduation)
function trenchManager() external view returns (address);

// Standard ERC-20
function name()          external view returns (string memory);
function symbol()        external view returns (string memory);
function decimals()      external view returns (uint8);           // always 18
function totalSupply()   external view returns (uint256);         // always 1e27
function balanceOf(address account)                               external view returns (uint256);
function allowance(address owner, address spender)                external view returns (uint256);
function approve(address spender, uint256 amount)                 external returns (bool);
function transfer(address to, uint256 amount)                     external returns (bool);
function transferFrom(address from, address to, uint256 amount)   external returns (bool);
```

| Mode                       | Value | Who can transfer                    |
| -------------------------- | ----- | ----------------------------------- |
| `MODE_NORMAL`              | `0`   | Anyone (post-graduation)            |
| `MODE_TRANSFER_RESTRICTED` | `1`   | No one (reserved)                   |
| `MODE_TRANSFER_CONTROLLED` | `2`   | Only TrenchManager (pre-graduation) |

## Events

| Event           | Emitted when                   | Key fields                                                                                    |
| --------------- | ------------------------------ | --------------------------------------------------------------------------------------------- |
| `TokenCreate`   | New token deployed             | `creator, curve, token, name, symbol, launchTime, tokenURI`                                   |
| `TokenPurchase` | Buy executed                   | `token, account, amountToken, amountQuote, protocolFee, buyFee, buyFeeReceiver, buyFeeRate`   |
| `TokenSale`     | Sell executed                  | `token, account, amountToken, amountQuote, protocolFee, sellFee, sellFeeReceiver`             |
| `LimitReach`    | Graduation threshold hit       | `token` (indexed)                                                                             |
| `Listing`       | Migrated to Uniswap V2         | `curve, token, pair` (all indexed), `listingWNativeAmount, listingTokenAmount, burnLiquidity` |
| `sync`          | Reserves updated (every trade) | `token, realNativeReserves, realTokenReserves, virtualNativeReserve, virtualTokenReserve`     |

## Error codes

### TrenchManagerV2

| Error                             | Description                            |
| --------------------------------- | -------------------------------------- |
| `ERR_CORE_EXPIRED`                | Transaction deadline passed            |
| `ERR_CORE_INVALID_AMOUNT_IN`      | `msg.value` doesn't match `amountIn`   |
| `ERR_CORE_INVALID_AMOUNT_OUT`     | Output below `amountOutMin` (slippage) |
| `ERR_CORE_CURVE_NOT_FOUND`        | Token has no bonding curve             |
| `ERR_CORE_CURVE_ALREADY_MIGRATED` | Token already graduated                |
| `ERR_CORE_INVALID_FEE`            | Fee rate exceeds 5% maximum            |
| `ERR_CORE_GWEI`                   | Sell `amountIn` not Gwei-aligned       |
| `ERR_BUY_FEE_RATE`                | `buyFeeRate` > 500                     |
| `ERR_BUY_FEE_RECEIVER`            | `buyFeeReceiver` is `address(0)`       |
| `ERR_SELL_FEE_RATE`               | `sellFeeRate` > 500                    |
| `ERR_SELL_FEE_RECEIVER`           | `sellFeeReceiver` is `address(0)`      |

### BondingCurve

| Error                                              | Description                                |
| -------------------------------------------------- | ------------------------------------------ |
| `ERR_BONDING_CURVE_NOT_TRADABLE`                   | Curve is migrating or migrated             |
| `ERR_BONDING_CURVE_OVERFLOW_TARGET`                | Purchase would exceed graduation threshold |
| `ERR_BONDING_CURVE_INSUFFICIENT_RESERVE`           | Insufficient reserves for sell             |
| `ERR_BONDING_CURVE_LIBRARY_INSUFFICIENT_LIQUIDITY` | Trade size exceeds available liquidity     |

### Token

| Error                           | Description                                             |
| ------------------------------- | ------------------------------------------------------- |
| `ERR_TOKEN_TRANSFER_RESTRICTED` | Direct transfer attempted in `MODE_TRANSFER_CONTROLLED` |
| `ERR_TOKEN_INVALID_TRANSFER`    | Invalid transfer parameters                             |
| {% endtab %}                    |                                                         |

{% tab title="MegaETH Mainnet" %}

## Network info

|          |                                   |
| -------- | --------------------------------- |
| Chain ID | `4326`                            |
| RPC      | `https://mainnet.megaeth.com/rpc` |
| Explorer | `https://megaexplorer.xyz`        |

## Deployments

| Contract                    | Address                                      | Description                                    |
| --------------------------- | -------------------------------------------- | ---------------------------------------------- |
| **TrenchManagerV3** (Proxy) | `0x2978E15501C792152602eC85c299083aa61b1bd4` | Main entry point for all interactions          |
| ProxyAdmin                  | `0xbB9DBc3028D2318eC7D0Ada935711042A9ea69C2` | Proxy admin contract                           |
| TrenchManagerV3 Impl        | `0x95CCeBaf5C664E18cB569386Bf38a3771a804943` | Current implementation                         |
| BondingCurveFactory         | `0xA25890Dd71eF04955baF57F93D27380d1e235f8A` | Curve and token factory                        |
| FeeVault                    | `0x6adaC2FC414032f49BC7C4B9F2C5EA7B2D4dd4AD` | Protocol fee collection and distribution       |
| WETH (WNative)              | `0x4200000000000000000000000000000000000006` | Wrapped ETH                                    |
| Kumbaya V3 Position Manager | `0x2b781C57e6358f64864Ff8EC464a03Fdaf9974bA` | V3 LP position NFT manager (graduation target) |

**Admin addresses**:

| Role                             | Address                                      |
| -------------------------------- | -------------------------------------------- |
| Owner                            | `0xbeb76A70c82B09E30B2008eAFa7F987987EC9e0b` |
| Migrator                         | `0xfB771beb315D7d6512b414496D012d3B084B17bF` |
| LP Receiver                      | `0xfB771beb315D7d6512b414496D012d3B084B17bF` |
| Listing Fee Receiver             | `0x551c19aCbEAE33C07b98120cC2992Ec70e943e79` |
| Protocol Fee Receiver (FeeVault) | `0x39d91743ee3BB4CecfD3331e84185D29898Da34C` |

## On-chain parameters

### Trading fee

| Parameter        | Value                      | Description                                |
| ---------------- | -------------------------- | ------------------------------------------ |
| Trade fee        | 1.25% (`12,500,000 / 1e9`) | Applied to every buy and sell.             |
| Creator share    | 24% of trade fee           | ≈ 0.3% of trade size. Accrues in FeeVault. |
| Protocol share   | 76% of trade fee           | ≈ 0.95% of trade size.                     |
| Max platform fee | 5% (`50,000,000 / 1e9`)    | Max rate for `buyWithFee` / `sellWithFee`. |

### Bonding curve config

| Parameter                            | Value                                       | Description                              |
| ------------------------------------ | ------------------------------------------- | ---------------------------------------- |
| Total supply                         | `1,000,000,000` (1e27 wei, 18 decimals)     | Fixed per token.                         |
| `virtualNative` (initial)            | `2026585820895522388` (\~2.027 ETH)         | Starting virtual ETH reserve.            |
| `virtualToken` (initial)             | `1098507462686567164179104478` (\~1.099e27) | Starting virtual token reserve.          |
| Graduation threshold (`targetToken`) | `200,000,000` (2e26 wei)                    | Remaining tokens in curve at graduation. |
| Expected ETH raised (net)            | \~5.43 ETH                                  | ETH in curve at graduation.              |
| Total user spend (inc. fee)          | \~5.5 ETH                                   | Gross ETH to fill curve.                 |

### Listing / migration

| Parameter            | Value                                        | Description                             |
| -------------------- | -------------------------------------------- | --------------------------------------- |
| Listing fee rate     | 800 / 10000 = **8%**                         | Deducted from raised ETH at graduation. |
| Listing fee receiver | `0x551c19aCbEAE33C07b98120cC2992Ec70e943e79` | Receives listing fee at migration.      |
| Kumbaya V3 fee tier  | 100 (= 0.01%)                                | V3 pool fee tier.                       |

### FeeVault

| Parameter          | Value     |
| ------------------ | --------- |
| Min dev claim      | 0.001 ETH |
| Min protocol claim | 0.001 ETH |

## TrenchManagerV3 ABI

### Trading functions

#### `createCurve`

Deploy a new token and bonding curve. Optionally performs an initial dev buy. The contract pre-initializes a Kumbaya V3 anchor position at the graduation price using 1e12 wei from its own balance.

```solidity
function createCurve(
    address creator,
    string  name,
    string  symbol,
    string  tokenURI,
    uint256 amountIn,       // ETH for initial dev buy; 0 = no dev buy
    uint256 amountOutMin,
    bytes32 salt
) external payable returns (
    address curve,
    address token,
    uint256 virtualNative,
    uint256 virtualToken,
    uint256 amountOut
);
```

#### `buy`

Buy tokens with ETH. No platform fee.

```solidity
function buy(
    uint256 amountIn,       // must equal msg.value
    uint256 amountOutMin,
    address token,
    address to,
    uint256 deadline
) external payable returns (uint256 amountOut);
```

#### `buyWithFee`

Buy tokens with an additional platform fee (up to 5%).

```solidity
function buyWithFee(
    uint256 amountIn,
    uint256 amountOutMin,
    address token,
    address to,
    uint256 deadline,
    uint256 buyFeeRate,       // denominator 1e9; max 50,000,000 (= 5%)
    address buyFeeReceiver
) external payable returns (uint256 amountOut);
```

Fee flow:

```
Platform fee  = amountIn × buyFeeRate / 1e9  → buyFeeReceiver
Protocol fee  = (amountIn − platform fee) × 1.25%  → FeeVault
Curve input   = amountIn − platform fee − protocol fee
```

#### `sell`

Sell tokens for ETH. Requires prior `ERC20.approve`.

```solidity
function sell(
    uint256 amountIn,       // token wei — must be Gwei-aligned (amountIn % 1e9 == 0)
    uint256 amountOutMin,
    address token,
    address to,
    uint256 deadline
) external returns (uint256 amountOut);
```

#### `sellWithFee`

Sell tokens with an additional platform fee (up to 5%).

```solidity
function sellWithFee(
    uint256 amountIn,
    uint256 amountOutMin,
    address token,
    address to,
    uint256 deadline,
    uint256 sellFeeRate,
    address sellFeeReceiver
) external returns (uint256 amountOut);
```

### Quote functions

#### `quoteBuyWithFee`

Simulate a buy. Returns estimated output and full fee breakdown.

```solidity
function quoteBuyWithFee(
    uint256 amountIn,
    address token,
    uint256 buyFeeRate
) external view returns (
    uint256 amountOut,
    uint256 protocolFee,
    uint256 buyFee,
    uint256 newVirtualNative,
    uint256 newVirtualToken,
    uint256 newRealNative
);
```

#### `quoteSellWithFee`

Simulate a sell. `amountIn` must be divisible by 1e9.

```solidity
function quoteSellWithFee(
    uint256 amountIn,
    address token,
    uint256 sellFeeRate
) external view returns (
    uint256 amountOut,
    uint256 protocolFee,
    uint256 sellFee,
    uint256 newRealNative
);
```

### Query functions

```solidity
function curves(address token)    external view returns (address curve);
function creators(address token)  external view returns (address creator);
function tokenInfo(address token) external view returns (
    address curve,
    address creator,
    uint256 realNativeReserves,
    uint256 realTokenReserves,
    uint256 virtualNativeReserve,
    uint256 virtualTokenReserve,
    bool    isMigrating,
    bool    isMigrated
);
function factory()  external view returns (address);
function vault()    external view returns (address);
function wNative()  external view returns (address);
function migrator() external view returns (address);
```

### Migration (V3)

```solidity
function migrateToV3(
    address token,
    uint256 amount0Min,
    uint256 amount1Min,
    uint256 deadline   // 0 = no deadline
) external returns (
    address pool,
    uint256 tokenId,
    uint128 liquidity,
    uint256 amount0,
    uint256 amount1
);
```

Only callable by the whitelisted migrator. Deducts listing fee (8%), seeds the Kumbaya V3 full-range position, sends the LP NFT to `LP_receiver`, and sets token mode to 0.

## IBondingCurve ABI

One `BondingCurve` contract is deployed per token. Query via `TrenchManagerV3.curves(token)`.

```solidity
function getVirtualReserves()      external view returns (uint256 virtualWNative, uint256 virtualToken);
function getReserves()             external view returns (uint256 reserveWNative, uint256 reserveToken);
function getRemainingTokenToSell() external view returns (uint256);
function getTargetToken()          external view returns (uint256);   // 200 M tokens
function getK()                    external view returns (uint256);
function isMigrating()             external view returns (bool);      // true = curve filled, awaiting migration
function isMigrated()              external view returns (bool);      // true = migrated to Kumbaya V3
function migrating()               external view returns (bool);      // raw storage accessor
function migrated()                external view returns (bool);      // raw storage accessor
function token()                   external view returns (address);
function realNativeReserves()      external view returns (uint256);
function realTokenReserves()       external view returns (uint256);
```

{% hint style="info" %}
Unlike Ethereum's BondingCurve, there is no `pair()` function — graduation goes to a Kumbaya V3 pool, not a V2 pair.
{% endhint %}

## IBondingCurveFactory ABI

```solidity
struct Config {
    uint256 listingFeeRate;     // 800 (8%)
    uint256 tokenTotalSupply;   // 1e27
    uint256 virtualNative;      // 2026585820895522388 (~2.027 ETH)
    uint256 virtualToken;       // 1098507462686567164179104478
    uint256 k;
    uint256 targetToken;        // 2e26
    uint256 realNativeReserves; // 0 at init
    uint256 realTokenReserves;  // 1e27 at init
}

function getConfig()         external view returns (Config memory);
function getK()              external view returns (uint256);
function getListingFeeRate() external view returns (uint256);
function getDexFactory()     external view returns (address);  // legacy, unused on MegaETH
function getOwner()          external view returns (address);
function getTrenchManager()  external view returns (address);
```

## IFeeVault ABI

```solidity
function credit(address creator, address token, uint256 amount) external payable;
function creditsDev(address creator)  external view returns (uint256);  // accrued dev fee
function creditsProtocol()            external view returns (uint256);  // accrued protocol fee
function devClaim(address creator)    external;                         // anyone can call; ETH goes to creator
function protocolClaim(uint256 amount) external;
function feeReceiver()                external view returns (address);
function DEV_CLAIM_RATIO()            external view returns (uint256);  // 2400
function DEV_CLAIM_RATIO_DENOMINATOR() external view returns (uint256); // 10000
```

## IToken (ERC-20)

Standard ERC-20 with transfer restriction modes:

| Mode                       | Value | Behavior                                                             |
| -------------------------- | ----- | -------------------------------------------------------------------- |
| `MODE_NORMAL`              | `0`   | Free transfer (post-graduation)                                      |
| `MODE_TRANSFER_RESTRICTED` | `1`   | All transfers blocked (emergency)                                    |
| `MODE_TRANSFER_CONTROLLED` | `2`   | Only transfers involving TrenchManager allowed (default at creation) |

```solidity
function setMode(uint256 v)      external;          // only TrenchManager; cannot leave mode 0
function trenchManager()         external view returns (address);
function _mode()                 external view returns (uint256);
function _metaUrl()              external view returns (string memory);
```

## Events

### TrenchManagerV3

| Event             | Key fields                                                                                              | When                                  |
| ----------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------- |
| `TokenCreate`     | `creator, curve, token, name, symbol, launchTime, tokenURI`                                             | New token created                     |
| `TokenPurchase`   | `token, account, amountToken, amountQuote, protocolFee, buyFee, buyFeeReceiver, buyFeeRate`             | Token bought                          |
| `TokenSale`       | `token, account, amountToken, amountQuote, protocolFee, sellFee, sellFeeReceiver`                       | Token sold                            |
| `sync`            | `token, realNativeReserves, realTokenReserves, virtualNativeReserve, virtualTokenReserve`               | After every trade                     |
| `LimitReach`      | `token` (indexed)                                                                                       | Curve filled — trading halted         |
| `TradeStop`       | `token`                                                                                                 | Trading halted                        |
| `V3AnchorListing` | `curve, token, pool, tokenId, liquidity, nativeAmount, tokenAmount, sqrtPriceX96, tickLower, tickUpper` | Anchor LP minted at `createCurve`     |
| `V3Listing`       | `curve, token, pool, tokenId, liquidity, amount0, amount1, sqrtPriceX96, tickLower, tickUpper`          | Full migration to Kumbaya V3 complete |

### FeeVault

| Event             | Key fields                    | When                     |
| ----------------- | ----------------------------- | ------------------------ |
| `Credit`          | `token` (indexed), `amount`   | Fee deposited from trade |
| `DevClaim`        | `creator` (indexed), `amount` | Creator claimed fee      |
| `TrechOwnerClaim` | `amount`                      | Protocol fee withdrawn   |

## Error codes

### TrenchManagerV3

| Error                             | Description                                    |
| --------------------------------- | ---------------------------------------------- |
| `ERR_CORE_CURVE_NOT_FOUND`        | Token not registered                           |
| `ERR_CORE_INVALID_AMOUNT_OUT`     | Output below `amountOutMin` (slippage)         |
| `ERR_CORE_EXPIRED`                | Transaction deadline passed                    |
| `ERR_CORE_INVALID_AMOUNT_IN`      | Zero or invalid input amount                   |
| `ERR_CORE_INVALID_SEND_NATIVE`    | `msg.value < amountIn`                         |
| `ERR_CORE_GWEI`                   | Sell `amountIn` not Gwei-aligned               |
| `ERR_BUY_FEE_RATE`                | `buyFeeRate` > 5%                              |
| `ERR_BUY_FEE_RECEIVER`            | `buyFeeRate > 0` but receiver is zero address  |
| `ERR_SELL_FEE_RATE`               | `sellFeeRate` > 5%                             |
| `ERR_SELL_FEE_RECEIVER`           | `sellFeeRate > 0` but receiver is zero address |
| `ERR_CORE_INVALID_ALLOWANCE`      | Insufficient ERC-20 approval for sell          |
| `ERR_CORE_CURVE_NOT_MIGRATING`    | Token not in migrating state                   |
| `ERR_CORE_CURVE_ALREADY_MIGRATED` | Token already migrated                         |
| `ERR_CORE_ONLY_MIGRATOR`          | Caller is not whitelisted migrator             |
| `ERR_CORE_V3_NOT_CONFIGURED`      | V3 position manager or fee not set             |
| `ERR_CORE_V3_ZERO_LIQUIDITY`      | Minted LP has zero liquidity                   |
| `ERR_CORE_INVALID_LP_RECEIVER`    | `LP_receiver` not set                          |

### BondingCurve

| Error                                   | Description                      |
| --------------------------------------- | -------------------------------- |
| `ERR_BONDING_CURVE_ONLY_TRENCH_MANAGER` | Only TrenchManager can call      |
| `ERR_BONDING_CURVE_FINISHED`            | Curve already graduated          |
| `ERR_BONDING_CURVE_INVALID_AMOUNT_OUT`  | Computed output too low          |
| `ERR_BONDING_CURVE_INVALID_AMOUNT_IN`   | Zero input                       |
| `ERR_BONDING_CURVE_OVERFLOW_TARGET`     | Buy exceeds remaining capacity   |
| `ERR_BONDING_CURVE_NOT_TRADABLE`        | Trading halted (migrating state) |
| `ERR_BONDING_CURVE_ALREADY_MIGRATED`    | Curve already migrated           |

### Token

| Error                           | Description                           |
| ------------------------------- | ------------------------------------- |
| `ERR_TOKEN_INVALID_TRANSFER`    | Transfer blocked by mode 2            |
| `ERR_TOKEN_TRANSFER_RESTRICTED` | Transfer blocked by mode 1            |
| `ERR_TOKEN_INVALID_OWNER`       | Only TrenchManager can call `setMode` |

### FeeVault

| Error                               | Description                            |
| ----------------------------------- | -------------------------------------- |
| `TOO_SMALL`                         | Claim amount below 0.001 ETH minimum   |
| `ERR_FEE_VAULT_ONLY_TRENCH_MANAGER` | Only TrenchManager can call `credit()` |
| {% endtab %}                        |                                        |
| {% endtabs %}                       |                                        |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://trench-today.gitbook.io/trench-today/for-developers/contracts.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
