---
name: tartarus
description: Build applications against the Tartarus launchpad on Elysium: launching tokens, trading Uniswap V4 pools, fees, holder rewards and the API. Use when writing code that calls Tartarus contracts, or when debugging a revert from one.
---

# Tartarus

Tartarus is a permissionless token launchpad on Elysium (elysium-mainnet, chain 99901). A launch
is one transaction: a fixed 1,000,000,000-token supply goes entirely into a single-sided Uniswap V4
position that is locked forever, and the token trades from that block. There is **no bonding curve and
no graduation**. If code you are reading mentions either, it is about another launchpad.

## Getting the full reference

The complete documentation, with every address, function signature, selector, event topic and error,
is one document:

    https://tartarus.world/llms-full.txt

9 contracts · 188 functions · 60 events · 124 errors.
Fetch it before writing code. Individual pages are at `https://tartarus.world/documentation/<page>.md`. ABIs are at
`https://tartarus.world/abi/<Contract>.json`. Live addresses and terms are at
`https://api.tartarus.world/v1/protocol`.

## The things that are counter-intuitive

Most integration failures are one of these.

### 1. Native HYPE needs no approval, and an ERC-20 swap needs two

| Doing | Approve | `msg.value` |
|---|---|---|
| `factory.launchToken` | nothing | exactly `launchFee()` |
| `launchAndBuy`, HYPE config | nothing | `launchFee() + quoteIn` |
| `launchAndBuy`, ERC-20 config | the quote, to `TartarusLaunchAndBuy` | `launchFee()` |
| buy with HYPE | nothing | the amount in |
| sell, or buy with an ERC-20 | **`token.approve(PERMIT2)` and `permit2.approve(token, router, amount, expiry)`** | 0 |

Skipping the Permit2 grant reverts `AllowanceExpired` (`0xd81b2f2e`), a name that suggests a grant
lapsed when none was made. A grant that is too small, or already used up, reverts
`InsufficientAllowance` (`0xf96fb071`). The launch fee is always native HYPE, and a wrong `msg.value` reverts.

### 2. All trading is one path: UniversalRouter V4_SWAP

Command `0x10`, actions `0x060c0f` (`SWAP_EXACT_IN_SINGLE`, `SETTLE_ALL`, `TAKE_ALL`). This router
build's `ExactInputSingleParams` has an extra `uint256 minHopPriceX36` before `hookData`: the tuple is
`((address,address,uint24,int24,address),bool,uint128,uint128,uint256,bytes)`. Pass `0` and empty
`hookData`. Read the key from `factory.poolKeyFor(token)`. A buy is `zeroForOne` exactly when the quote
is `currency0`, which is always true for HYPE (`address(0)`).

### 3. Elysium's RPC situation decides whether a transaction lands

Use `https://api.tartarus.world/v1/rpc`. Community RPCs mostly refuse or silently drop
third-party transactions. A transaction with `maxFeePerGas` below the base fee (floor about 0.1 gwei) is
dropped with no error. A transaction may take 15 to 30 seconds through the delayed-inbox fallback, so
wait for the receipt rather than assuming failure. The fallback only carries Tartarus-related targets.

### 4. Fees take several steps to arrive

The hook takes 1% to 10% from each swap's unspecified leg, so exact-in buys collect in the token and
sells collect in the quote. Fees sit in the hook until a sweep, then in `TartarusFeeEscrow` until
claimed. Only the operator can convert memecoin fees (`sweepPoolFees`). The creator recipient can call
`sweepPoolQuoteFees`. `claim` and `claimToken` are overloaded, so pass `args` explicitly.

### 5. The price cannot fall below the launch tick

Tartarus's liquidity ends at the floor. Selling there returns `fillsNothing: true` from the API, while
V4Quoter reverts `UnexpectedRevertBytes` wrapping `NotEnoughLiquidity`. That is a normal state, not an error.

### 6. Per-launch contracts have no fixed address

`TartarusRewardsDistributor` comes from `rewardsFactory.distributorOf(token)`, which is zero if the
launch did not choose holder rewards. `factory.getLaunchedToken(token)` returns a **zeroed struct** for
an unknown token rather than reverting, so check `.exists`.

### 7. Holder rewards use a sentinel

Set `creatorFeeRecipient` to `factory.HOLDER_REWARDS()` and the factory resolves the distributor. Use a
fresh salt per launch, or it reverts `HolderRewardsDistributorTaken`. It is a one-way choice.

### 8. HyperCore is not live yet

`factory.bridgeWalletFor` and `expectedMirrorFor` revert `BridgeFactoryNotSet` on mainnet today.

## Quoting

`GET https://api.tartarus.world/v1/tokens/:address/quote?side=buy&amount=1&slippageBps=100`.
`amount` is in **whole units**. Use `minOutRaw`, not `outRaw`, as the swap's minimum. On chain, use
V4Quoter through `simulateContract`, since it is not a view function.

## Amounts

Tokens and HYPE are 18 decimals. An ERC-20 quote has its own. Fields ending in `Raw` are strings for
transactions, and the rest are floats for display. Never round-trip an amount through a JavaScript number.

## When a transaction reverts

Look the selector up at `https://tartarus.world/documentation/errors.md`. Every custom error across every contract is
listed by selector. Decoding beats guessing.
