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.

Last updated

Was this helpful?