# factories

The factory is the launchpad's single entry point. Owns:

* Token + curve creation
* Deploy fee collection
* The mandatory initial buy (atomic with deploy)
* The graduated-curve → Uni V2 migration

## Two versions live in production

| Factory       | Token deployed                                 | Use                                                       |
| ------------- | ---------------------------------------------- | --------------------------------------------------------- |
| **FactoryV2** | `BasefunToken` (V1, 0/0 transfer fees forever) | Legacy. \~6 historical tokens. Not used for new launches. |
| **FactoryV3** | `BasefunTokenV2` (V2, 1% FOT post-grad)        | **Current**. All new launches.                            |

The Web UI's `/create` posts to FactoryV3. FactoryV2 is kept in the indexer + UI list so the legacy tokens still render and trade normally.

## Shared constants

```solidity
DEPLOY_FEE_USDC         = 1e6       // $1 USDC, paid by creator on createToken
INITIAL_BUY_FLOOR_USDC  = 20e6      // $20 USDC minimum, atomic with deploy
```

## createToken signature

```solidity
function createToken(
  string  name,
  string  symbol,
  string  imageURI,
  string  description,
  string  socials,
  uint256 pairIndex,
  uint256 leverage,
  bool    buyLong,
  address creatorFeeRecipient,   // defaults to msg.sender if zero
  uint256 initialBuyUSDC         // must be >= INITIAL_BUY_FLOOR_USDC
) external returns (address tokenAddr, address curveAddr)
```

Executes, in order:

1. Pull `$1 USDC` from creator → `protocolFeeRecipient`.
2. Look up the LT for `(pair, lev, dir)`. Revert if it doesn't exist (creator must call `LTFactory.getOrCreateLT` first).
3. Deploy a fresh `BondingCurveV2` parameterized for this token.
4. Deploy a fresh `BasefunToken` (V1) or `BasefunTokenV2` (V2) with `TOTAL_SUPPLY` minted to the curve.
5. `curve.bindToken(token)` so the curve knows which token to transfer in `buy`.
6. Require `initialBuyUSDC >= INITIAL_BUY_FLOOR_USDC`, pull the USDC, call `curve.initialBuy(creator, initialBuyUSDC, 0)`.
7. Emit `TokenCreated`.

The initial buy is atomic with deploy so Avantis's perp can be opened immediately on the first LT mint (Avantis requires notional >= $101, which 5× $20 = $100 satisfies for 5× leverage — and the keeper aggregates small mints below $101 until they cross the threshold).

## Migration (V2/V3 both)

```solidity
function migrateToUniV2(address curveAddr) external
```

Restricted to `owner()` + whitelisted `migrators`. The keeper EOA is whitelisted.

1. Pull `(remaining tokens, remaining USDC)` from the graduated curve via `curve.withdrawForGraduation(address(this))`.
2. Cap the LP seed at `(LP_SUPPLY, GRADUATION_LP_USDC)` = `(242.5M, $9,700)`. Anything above goes to treasury / burn.
3. Look up the Uni V2 pair address; create it if missing.
4. **(V3 only)** `token.setPair(pair, true)` — activates the 1% FOT hook on the pair.
5. `addLiquidity(token, USDC, lpTokens, lpUsdc, 95% min, 95% min, to=0xdEaD, deadline=+600s)`.
6. Sweep any leftover USDC dust to treasury; burn any leftover tokens at `0xdead`.
7. Emit `Migrated(token, pair, tokensIn, usdcIn)`.

## Migrator whitelist

```solidity
function setMigrator(address who, bool allowed) external onlyOwner
mapping(address => bool) public migrators;
```

The keeper EOA is set `migrators[keeper] = true` post-deploy. This guards against an attacker pre-creating the Uni V2 pair with hostile dust reserves and bricking `addLiquidity`.

## Ownership and admin powers

| Power                           | Held by                                                                                                                                                                        |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `setProtocolFeeRecipient(addr)` | Factory owner. Changes the destination for all future swap fees and graduation cuts. Existing per-token settings are unaffected (curve's `protocolFeeRecipient` is immutable). |
| `setMigrator(addr, bool)`       | Factory owner. Whitelist for migration callers.                                                                                                                                |
| `transferOwnership(addr)`       | Factory owner. Standard OZ Ownable.                                                                                                                                            |

There is **no** function on the factory or curve to mint more tokens, change the swap fee, drain reserves, or modify graduation thresholds. Those are all hard-coded.


---

# Agent Instructions: 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:

```
GET https://basefun.gitbook.io/basefun-docs/factories.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
