Bonding.sol is the core smart contract responsible for bootstrapping the Taikodrome economy. Its primary function is to facilitate the one-way conversion of the native $TAIKO token into max-locked veTD governance positions.
The contract is designed to create a powerful incentive for early, large-scale participation by offering significant, competitive discounts. It also serves as the primary mechanism for accumulating Protocol-Owned Liquidity (POL), which will be used to establish deep liquidity for the foundational $TAIKO/$TD pair on the Taikodrome DEX.
The contract's logic is built around three primary functions: the user-facing bonding process, a dynamic pricing engine, and administrative treasury management.
The user experience is designed to be seamless. A user approves the Bonding.sol contract to spend their $TAIKO and calls a single function, bond(). The contract then handles the entire process atomically:
- It calculates the amount of
$TDthe user is entitled to based on the dynamic pricing engine. - It pulls the required
$TAIKOfrom the user. - It mints the corresponding amount of
$TD. - It automatically deposits this new
$TDinto theVotingEscrow.solcontract on behalf of the user, creating a max-lockedveTDNFT. - The
veTDNFT is minted directly to the user's wallet.
The amount of $TD minted for a given amount of $TAIKO is determined by a multi-factor pricing formula. This ensures both security and powerful incentives.
The base conversion rate between $TAIKO and $TD is determined by one of two phases:
- Bootstrap Phase: At launch, a 1:1 exchange rate is used. This is necessary because no on-chain market exists yet. This phase is controlled by a boolean flag,
isBootstrapPhase. - Market Phase: Once the bootstrap phase is manually concluded by the admin, the contract switches to using the on-chain price from the Taikodrome
$TAIKO/$TDAMM pool. Crucially, this must be a Time-Weighted Average Price (TWAP) to prevent flash loan manipulation.
Two discounts are applied to the base price to incentivize participation:
- Illiquidity Discount: This is a fixed (but potentially adjustable) percentage discount that compensates all users for locking their assets for the max lock. It acknowledges the premium of liquid assets over illiquid ones.
- Early Adopter Discount: This is a competitive, dynamic discount that creates a race to bond. The discount is an inverse function of the
tokenIdfromVotingEscrow.sol. The first bonder (tokenId #1) receives the highest possible bonus discount, which then decays with each subsequent bond until a predefined cap (MAX_EARLY_BIRD_BONDS) is reached. This creates maximum urgency and rewards the earliest and most committed participants.
All $TAIKO tokens accepted by the contract are stored in its own balance, effectively removing them from circulating supply. These funds are designated to become POL.
- Discretionary Control: An
adminorDAOaddress has the exclusive right to call adeployPol()function. - Supply Management: This function allows the admin to specify both the amount of
$TAIKOto use and the amount of$TDto mint for pairing. This provides the DAO with discretionary control over the$TDmonetary supply, which is a critical safety lever in the early stages of the economy.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @title IBonding
* @notice Interface for the Taikodrome bonding contract, which handles the conversion
* of TAIKO into max-locked veTD positions.
*/
interface IBonding {
// --- Events ---
/**
* @notice Emitted when a user successfully bonds TAIKO for veTD.
* @param user The address of the user who initiated the bond.
* @param taikoAmount The amount of TAIKO bonded.
* @param tdAmount The amount of TD minted and locked.
* @param tokenId The ID of the resulting veTD NFT.
*/
event Bonded(
address indexed user,
uint256 taikoAmount,
uint256 tdAmount,
uint256 indexed tokenId
);
/**
* @notice Emitted when the treasury deploys Protocol-Owned Liquidity.
* @param admin The address that initiated the deployment.
* @param taikoAmount The amount of TAIKO used from the treasury.
* @param tdAmount The amount of TD minted and paired.
*/
event PolDeployed(
address indexed admin,
uint256 taikoAmount,
uint256 tdAmount
);
// --- User-facing Functions ---
/**
* @notice Bonds a specified amount of TAIKO tokens in exchange for a new,
* 1-year max-locked veTD NFT.
* @dev User must first approve this contract to spend their TAIKO.
* @param _taikoAmount The amount of TAIKO to bond.
* @return tokenId The ID of the newly created veTD NFT.
*/
function bond(uint256 _taikoAmount) external returns (uint256 tokenId);
/**
* @notice A view function to quote the expected amount of TD to be minted for a
* given amount of TAIKO, based on the current state.
* @dev This is an estimate, as the early adopter discount can change based on transaction ordering.
* @param _taikoAmount The amount of TAIKO to quote for.
* @return tdAmount The estimated amount of TD that will be minted and locked.
*/
function quoteBond(
uint256 _taikoAmount
) external view returns (uint256 tdAmount);
// --- Admin Functions ---
/**
* @notice Deploys a specified amount of the contract's TAIKO balance and newly minted
* TD as Protocol-Owned Liquidity on the Taikodrome DEX.
* @dev Can only be called by the contract owner/admin.
* @param _taikoAmountToUse The amount of TAIKO from the treasury to use for liquidity.
* @param _tdAmountToMint The amount of new TD to mint for pairing.
*/
function deployPol(
uint256 _taikoAmountToUse,
uint256 _tdAmountToMint
) external;
/**
* @notice Sets the bootstrap phase state. When true, a 1:1 price is used.
* When false, the AMM TWAP price is used.
* @dev Can only be called by the contract owner/admin. Should only be called once.
* @param _isBootstrap The new state of the bootstrap phase.
*/
function setBootstrapPhase(bool _isBootstrap) external;
/**
* @notice Updates the illiquidity discount percentage.
* @dev Can only be called by the contract owner/admin.
* @param _newDiscountBps The new discount in basis points (e.g., 500 for 5%).
*/
function setIlliquidityDiscount(uint256 _newDiscountBps) external;
}The following pseudocode illustrates the core logic within the bond() function for determining the final $TD mint quantity.
// This is PSEUDOCODE to illustrate the pricing logic.
function getTdMintQty(uint256 _taikoAmount) internal returns (uint256) {
// 1. Determine Base Price in TAIKO per TD
uint256 basePriceTaikoPerTd;
if (isBootstrapPhase) {
basePriceTaikoPerTd = 1e18; // 1:1
} else {
basePriceTaikoPerTd = taikodromeOracle.fetchTwapPrice(TAIKO, TD);
}
// 2. Calculate Total Discount
// Start with the fixed illiquidity discount
uint256 totalDiscountBps = illiquidityDiscountBps;
// Add the competitive early adopter bonus
uint256 nextTokenId = IVotingEscrow(escrow).tokenId() + 1;
if (nextTokenId <= MAX_EARLY_BIRD_BONDS) {
totalDiscountBps += getEarlyBirdDiscount(nextTokenId);
}
// 3. Apply Discount to Price
// Note: To apply a discount, we reduce the TAIKO cost per TD
uint256 finalPriceTaikoPerTd = (basePriceTaikoPerTd *
(10000 - totalDiscountBps)) / 10000;
// 4. Calculate Final TD Amount
// The amount of TD the user gets is their TAIKO divided by the final price
uint256 tdAmount = (_taikoAmount * 1e18) / finalPriceTaikoPerTd;
return tdAmount;
}