> For the complete documentation index, see [llms.txt](https://wiki.orbofi.com/learn/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.orbofi.com/learn/systems/bonding-curve-liquidity-management.md).

# Bonding curve, liquidity management

(To be updated and include periphery contracts)

#### AgentToken

`AgentToken` is the main contract for tokens launched on the platform.

It is an upgradeable ERC20 token with permit functionality, inheriting from `ERC20Upgradeable` and `ERC20PermitUpgradeable` for built-in initialization.

The contract holds the following metadata:

* Creator address
* Creation timestamp
* Curve contract address
* Uniswap V2 pair address
* AgentToken image URL
* AgentToken description
* AgentToken wallet address

During initialization, it mints the total supply to the curve contract, which currently is set to 1B tokens in `AgentFactory`.

The contract implements a migration mechanism:

* The `migrated` value is updated by `saveMigration` function, which can only be called by the curve contract.
* Before migration, the `_update` function prevents any liquidity addition to the Uniswap V2 Pair except from the curve contract.
* After migration, normal trading and liquidity operations are allowed on the Uniswap V2 Pair.

#### Curve

`Curve` is the contract that manages the initial bonding curve before migrating liquidity to Uniswap V2.

It initially receives AgentToken tokens and sells them for OBI tokens.

Migration can be triggered by any of these conditions:

* All the agent tokens allocated to the curve have been sold.
* OBI accumulated in the curve (real balance without considering virtual reserves) is above a certain threshold of USD value.

When migrating, it checks current AGENT/OBI price and the `CURVE_MIGRATION_PRICE_CHANGE_BPS` parameter. Based on the desired migration price, it takes the OBI balance and calculates how many AGENT tokens it needs to match the desired price. It sends some portion of OBI to the creator as a reward and burn all remaining tokens (OBI, AGENT, Uniswap V2 pair LP tokens).

It has three big parts:

**`CurveReserves`**

`CurveReserves` is the contract that manages the reserves for the curve.

It receives from the factory some variables that are used to handle reserves.

`agentCurveAllocation` is the amount of agent tokens that are allocated to the curve. Currently set to 600M tokens (60% of the total supply).

`CURVE_AGENT_VIRTUAL_RESERVE` and `OBI_VIRTUAL_RESERVE` are used together with real balances to calculate prices.

* `CURVE_AGENT_VIRTUAL_RESERVE` is a `AgentFactory` variable, currently set to 90M tokens.
* `OBI_VIRTUAL_RESERVE` is variable, calculated on `AgentFactory` based on current OBIUSD price.

It features `_safeSendAgent`, `_safeReceiveAgent`, `_safeSendObi` and `_safeReceiveObi` functions used in external trading functions to handle transfers of agent and obi tokens, keeping track of balances in `_agentBalance` and `_obiBalance` variables.

**`CurvePrices`**

`CurvePrices` is the contract that calculates prices for the curve.

`getAgentTokensOut`, `getObiTokensOut`, `getAgentTokensIn` and `getObiTokensIn` functions are used to calculate amounts of agent and obi tokens for a given amount of agent or obi tokens.

They follow standard `x * y = k` bonding curve formula but with virtual reserves for adapting prices.

So real + virtual reserves are used to calculate prices, but real balances are used for checking liquidity.

**`Curve` Trading**

`Curve` features trading functions `buyExactIn`, `buyExactOut`, `sellExactIn` and `sellExactOut`.

These functions can only be called by periphery contracts `AgentCreator` for initial creator purchase and `Trading` for before migration trades.

All these functions use reentrancy guard (transient storage version), checks for zero amounts and addresses, checks for already migrated and that `msg.sender` is one of the allowed contracts. There are no deadline or slippage checks as they are handled by the periphery contracts.

It emits `Price` event with current AGENT/OBI price, AGENT/USD price and OBIUSD price, that is used to index trades for the UI prices chart.

After each trade, it checks if migration should be triggered, doing it if needed.

**`Curve` Migration**

Liquidity migration can be triggered from two different places: internal checks at the end of each trade or the `migrate` external function.

Migration is triggered when one of these conditions is met:

* `agentBalance == 0` (real reserves that represent the agent curve allocation, exluding tokens reserved for migration)
* `obiAccumulatedInUsd >= CURVE_OBI_MIGRATION_THRESHOLD_IN_USD`

When migrating:

* It checks current AGENT/OBI price
* It calculates migration target price based on current price and `CURVE_MIGRATION_PRICE_CHANGE_BPS` parameter, being 12000 120% of current price and 20% price increase.
* It calculates how many OBI tokens will be used for liquidity, calculated based on `CURVE_OBI_MIGRATION_LP_BPS` parameter
* It calculates how many AGENT tokens are needed to match the migration target price.
* Adds liquidity to Uniswap V2 Pair by transfering tokens to the pair and minting LP tokens with `mint` function.
* It sends creator reward to the creator, calculated based on `CURVE_OBI_MIGRATION_CREATOR_REWARD_BPS` parameter
* Burns remaining tokens (OBI, AGENT, Uniswap V2 pair LP tokens)

#### AgentFactory

`AgentFactory` is the contract that manages the creation of new agents.

It has a set of upgradeable variables used for creating new agents, but don't affect previously deployed ones. BPS meaning basis points, 1 = 0.01%, 10000 = 100%.

* `agentTotalSupply` used when minting AGENT total supply.
* `agentVirtualReserve` used for calculating prices in the bonding curve before migration.
* `migrationThreshold` obi accumulated value in USD in the curve for triggering migration.
* `migrationPriceChangeBps` used when calculating migration target price. 12000 means 120% of current price, 20% increase.
* `obiLPBps` used when calculating how many OBI tokens will be used for liquidity. 8000 means 80% of accrued OBI will be used for liquidity.
* `obiAgentCreatorRewardBps` used when calculating how many OBI tokens will be sent to the creator as a reward. 1000 means 10% of accrued OBI will be sent to the creator as a reward.
* `curveAllocation` 60M tokens means 60% of the total supply will be allocated to the curve.
* `obiVirtualReserveFactor` used when calculating OBI virtual reserve at the time of deployment based on `OBIBUSD` price. The goal is that at that current price, both migration conditions would be met at the same time. Selling 60M OBI == accumulating 15k USD in OBI (without considering OBI price variation).
* `tradingContract` address of the `Trading` contract that will be able to call trading functions in every curve.
* `agentCreator` address of the `AgentCreator` contract that will be able to call `createAgent` function in `AgentFactory` and trading functions in `Curve` for initial creator purchase.
* `obiOracle` address of the `OBIBUSD` oracle.

`createAgent` function is used to create a new agent from the `AgentCreator` contract. It creates the `Curve`, `AgentToken` and Uniswap V2 pair, and saves the agent address in the `agents` enumerable set.

Creation is pausable, enabling pausing creation of new agents if a new version of the factory is deployed.

Initialization is already implementd in `AgentToken` and `Curve` contracts. Clones implementation as minimal proxies still to be added.

#### Oracle

`UniswapV2TWAPOracle` is the contract that provides the TWAP price for the `OBIBUSD`, with a period set at deployment (currently 15 minutes for prod, 2 minutes for tenderly fork).

It returns spot price until the first TWAP update, and returns standard TWAP price in 1e18 after that.

It has various functions to consult last price, consult and update, update if necessary (without reverting), update (reverting if necessary) and simulate update and consult.


---

# 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://wiki.orbofi.com/learn/systems/bonding-curve-liquidity-management.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.
