### Quote Exact Input Parameters and Function (Solidity) Source: https://docs.flap.sh/flap/developers/trade-tokens Defines the parameters and function signature for `quoteExactInput` in Solidity. This function is used to get a quote for a token swap without sending a transaction. It takes `QuoteExactInputParams` as input and returns the estimated `outputAmount`. ```solidity /// @notice Parameters for quoting the output amount for a given input struct QuoteExactInputParams { /// @notice The address of the input token (use address(0) for native asset) address inputToken; /// @notice The address of the output token (use address(0) for native asset) address outputToken; /// @notice The amount of input token to swap (in input token decimals) uint256 inputAmount; } /// @notice Quote the output amount for a given input /// @param params The quote parameters /// @return outputAmount The quoted output amount /// @dev refer to the swapExactInput method for the scenarios function quoteExactInput(QuoteExactInputParams calldata params) external returns (uint256 outputAmount); ``` -------------------------------- ### Solidity: Get Token State with Bonding Curve Parameters Source: https://docs.flap.sh/flap/developers/bonding-curve-in-developers-perspective This Solidity code defines the `getTokenV5` function, which retrieves the state of a token from the on-chain contract. It returns a `TokenStateV5` struct containing the token's status, reserve, circulating supply, price, version, bonding curve parameters (r, h, k), DEX threshold, quote token address, swap enablement, and extension ID. This function is crucial for understanding a token's financial metrics directly from the blockchain. ```solidity /// @notice Get token state (V5) /// @param token The address of the token /// @return state The state of the token (V5) with all curve parameters (r, h, k) function getTokenV5(address token) external view returns (TokenStateV5 memory state); /// @dev Token version /// Which token implementation is used enum TokenVersion { TOKEN_LEGACY_MINT_NO_PERMIT, TOKEN_LEGACY_MINT_NO_PERMIT_DUPLICATE, // for historical reasons, both 0 and 1 are the same: TOKEN_LEGACY_MINT_NO_PERMIT TOKEN_V2_PERMIT, TOKEN_GOPLUS } /// @notice the status of a token /// The token has 4 statuses: // - Tradable: The token can be traded(buy/sell) // - InDuel: (obsolete) The token is in a battle, it can only be bought but not sold. // - Killed: (obsolete) The token is killed, it can not be traded anymore. Can only be redeemed for another token. // - DEX: The token has been added to the DEX enum TokenStatus { Invalid, // The token does not exist Tradable, InDuel, // obsolete Killed, // obsolete DEX } /// @notice the state of a token (with all V4 fields plus all curve parameters) struct TokenStateV5 { /// The status of the token (see TokenStatus enum) TokenStatus status; /// The reserve amount of the quote token held by the bonding curve uint256 reserve; /// The circulating supply of the token uint256 circulatingSupply; /// The current price of the token (in quote token units, 18 decimals) uint256 price; /// The version of the token implementation (see TokenVersion enum) TokenVersion tokenVersion; /// The curve parameter 'r' used for the bonding curve uint256 r; /// The curve parameter 'h' - virtual token reserve uint256 h; /// The curve parameter 'k' - square of virtual liquidity uint256 k; /// The circulating supply threshold for adding the token to the DEX uint256 dexSupplyThresh; /// The address of the quote token (address(0) if native gas token) address quoteTokenAddress; /// Whether native-to-quote swap is enabled for this token bool nativeToQuoteSwapEnabled; /// The extension ID used by the token (bytes32(0) if no extension) bytes32 extensionID; } ``` -------------------------------- ### Calculate Bonding Curve Metrics with TypeScript CDPV2 Class Source: https://docs.flap.sh/flap/developers/bonding-curve-in-developers-perspective This TypeScript class, CDPV2, calculates price, FDV, and reserve based on a token's circulating supply and bonding curve parameters (r, h, k). It uses the `decimal.js` library for precise calculations and includes methods for estimating supply and reserve, as well as calculating market cap and FDV. ```typescript import { Decimal } from "decimal.js"; const BILLION: Decimal = new Decimal("1000000000"); // The latest curve is CDPV2 export class CDPV2 { // the initial virtual reserve private r: number; private h: number; private k: number; static defaultDexSupplyThreshold() { return new Decimal(8e8); } static getCurve(r: number, h?: number, k?: number): CDPV2 { if (h == null) { return new CDPV2(r, 0, 1e9 * r); } return new CDPV2(r, h, k); } constructor(r: number, h: number = 0, k: number = 0) { this.r = r; this.h = h; this.k = k; } estimateSupply(reserve: string): Decimal { // s = 1e9 + h - k/(r + eth) if (!reserve) return new Decimal(0); return new Decimal(BILLION).add(this.h).sub( new Decimal(this.k).div(new Decimal(reserve).add(this.r)) ); } estimateReserve(amount: string): Decimal { // eth = k/(h + 1e9 - s) - r if (!amount) return new Decimal(0); return new Decimal(this.k) .div(new Decimal(BILLION).add(this.h).sub(new Decimal(amount))) .sub(this.r); } mc(reserve: string): Decimal { return this.fdv(this.totalSupply(reserve).toString()); } price(supply: string): Decimal { // Price: k/(h + 1e9 - s)^2 const denominator = new Decimal(BILLION).add(this.h).sub(new Decimal(supply || 0)); return new Decimal(this.k).div(denominator.pow(2)); } fdv(supply: string): Decimal { return this.price(supply).mul(new Decimal(BILLION)); } } ``` -------------------------------- ### Track Token Supply Changes with Solidity Event Source: https://docs.flap.sh/flap/developers/bonding-curve-in-developers-perspective This Solidity event is emitted whenever the circulating supply of a token changes on the Flap protocol. It logs the token's address and its new supply, allowing for easy indexing to retrieve the latest supply figures. ```solidity /// @notice emitted when the circulating supply of a token changes /// @param token The address of the token /// @param newSupply The new circulating supply event FlapTokenCirculatingSupplyChanged(address token, uint256 newSupply); ``` -------------------------------- ### Calculate Token Migration Progress in TypeScript Source: https://docs.flap.sh/flap/developers/bonding-curve-in-developers-perspective This TypeScript snippet demonstrates how to calculate the migration progress of a token. It assumes you have obtained the circulating supply, curve parameters (r, h, k), and dex threshold. The code uses `formatEther` to convert bigint values to strings representing Ether, and then to numbers for calculations. It initializes a `Curve` object, estimates the reserve required at the dex threshold, estimates the current reserve based on the circulating supply, and finally calculates the progress as the ratio of current reserve to required reserve. Note that all input parameters are assumed to be in 18 decimals. ```typescript import { formatEther } from "viem"; // Assume CDPV2 and its methods are available globally or imported // declare const CDPV2: any; // declare class Curve { // estimateReserve(supply: string): number; // } // CDPV2.getCurve = (r: number, h: number, k: number): Curve => { /* ... */ return new Curve(); }; // assume we have all the following parameters from getTokenV5 // Note: all parameters are in 18 decimals // curve parameters let r: bigint; let h: bigint; let k: bigint; // circulating supply let circulatingSupply: bigint; // dex threshold let dexThreshold: bigint; // Example values (replace with actual data) r = BigInt("1000000000000000000"); // Example: 1e18 h = BigInt("2000000000000000000"); // Example: 2e18 k = BigInt("3000000000000000000"); // Example: 3e18 circulatingSupply = BigInt("1500000000000000000"); // Example: 1.5e18 dexThreshold = BigInt("2000000000000000000"); // Example: 2e18 const curve = CDPV2.getCurve( Number( formatEther(r) ), Number( formatEther(h) ), Number( formatEther(k) ) ); // The reserve required at the dex threshold const reserveRequired = curve.estimateReserve( formatEther(dexThreshold) ); // The current reserve at the current circulating supply const currentReserve = curve.estimateReserve( formatEther(circulatingSupply) ); // The progress can be calculated as: const progress = currentReserve / reserveRequired; console.log(`The migration progress is: ${progress}`); ``` -------------------------------- ### Create New Token (Solidity) Source: https://docs.flap.sh/flap/developers/launch-a-token This function creates a new standard token. It takes the token's name, symbol, and metadata URI as parameters. If msg.value is non-zero, the caller is considered the initial buyer. ```solidity /// @notice Create a new meme token /// @param name The name of the token /// @param symbol The symbol of the token /// @param meta The metadata ipfs cid of the token /// @dev if msg.value is not zero, the caller would be the initial buyer of the token function newToken(string calldata name, string calldata symbol, string calldata meta) external payable returns (address token); ``` -------------------------------- ### Create New Vanity Token (Solidity) Source: https://docs.flap.sh/flap/developers/launch-a-token This function creates a new vanity token with revenue sharing enabled. It requires name, symbol, metadata URI, a salt for deterministic deployment, and the beneficiary's address. The function is payable, and returns the address of the created token. ```solidity /// @notice Create a new vanity token /// @param name The name of the token /// @param symbol The symbol of the token /// @param meta The metadata URI of the token /// @param salt The salt for deterministic deployment /// @param beneficiary The address of the beneficiary /// @return token The address of the created token function newVanityToken( string calldata name, string calldata symbol, string calldata meta, bytes32 salt, address beneficiary ) external payable returns (address token); ``` -------------------------------- ### Solidity previewSell Method Source: https://docs.flap.sh/flap/developers/trade-tokens Previews the amount of ETH a user will receive for selling a specified amount of tokens. This is a view function that takes the token address and the amount of tokens to sell as input. ```solidity /// @notice preview the amount of ETH to receive for selling tokens /// @param token The address of the token to sell /// @param amount The amount of tokens to sell /// @return eth The amount of ETH to receive function previewSell(address token, uint256 amount) external view returns (uint256 eth); ``` -------------------------------- ### Solidity buy Method Source: https://docs.flap.sh/flap/developers/trade-tokens Executes the purchase of tokens with ETH. Users specify the token to buy, the recipient address, and the minimum amount of tokens they are willing to receive. This function is payable. ```solidity /// @notice Buy token with ETH /// @param token The address of the token to buy /// @param recipient The address to send the token to /// @param minAmount The minimum amount of tokens to buy function buy(address token, address recipient, uint256 minAmount) external payable returns (uint256 amount); ``` -------------------------------- ### Solidity previewBuy Method Source: https://docs.flap.sh/flap/developers/trade-tokens Previews the amount of tokens a user can buy with a given amount of ETH. This is a view function and does not modify the contract state. It takes the token address and ETH amount as input. ```solidity /// @notice Preview the amount of tokens to buy with ETH /// @param token The address of the token to buy /// @param eth The amount of ETH to spend /// @return amount The amount of tokens to buy function previewBuy(address token, uint256 eth) external view returns (uint256 amount); ``` -------------------------------- ### Swap Exact Input Parameters and Function (Solidity) Source: https://docs.flap.sh/flap/developers/trade-tokens Defines the parameters and function signature for `swapExactInput` in Solidity. This function is used to execute a token swap. It takes `ExactInputParams` which include input/output tokens, amounts, and optional permit data, returning the `outputAmount` received. Note: This method currently supports tokens in the bonding curve state. ```solidity /// @notice Parameters for swapping exact input amount for output token struct ExactInputParams { /// @notice The address of the input token (use address(0) for native asset) address inputToken; /// @notice The address of the output token (use address(0) for native asset) address outputToken; /// @notice The amount of input token to swap (in input token decimals) uint256 inputAmount; /// @notice The minimum amount of output token to receive uint256 minOutputAmount; /// @notice Optional permit data for the input token (can be empty) bytes permitData; } /// @notice Swap exact input amount for output token /// @param params The swap parameters /// @return outputAmount The amount of output token received /// @dev Here are some possible scenarios: /// If the token's reserve is BNB or ETH (i.e: the quote token is the native gas token): /// - BUY: input token is address(0), output token is the token address /// - SELL: input token is the token address, output token is address(0) /// If the token's reserve is another ERC20 token (eg. USD*, i.e, the quote token is an ERC20 token): /// - BUY with USD*: input token is the USD* address, output token is the token address /// - SELL for USD*: input token is the token address, output token is the USD* address /// - BUY with BNB or ETH: input token is address(0), output token is the token address. /// (Note: this requires an internal swap to convert BNB/ETH to USD*, nativeToQuoteSwap must be anabled for this quote token) /// Note: Currently, this method only supports trading tokens that are still in the bonding curve state. /// However, in the future, we may also support trading tokens that are already in DEX state. function swapExactInput(ExactInputParams calldata params) external payable returns (uint256 outputAmount); ``` -------------------------------- ### Token Created Event (Solidity) Source: https://docs.flap.sh/flap/developers/launch-a-token This event is emitted from the Portal contract whenever a new token is created. It logs details such as the creation timestamp, creator's address, nonce, the new token's address, and its name, symbol, and meta URI. ```solidity /// @notice emitted when a new token is created /// /// @param ts The timestamp of the event /// @param creator The address of the creator /// @param nonce The nonce of the token /// @param token The address of the token /// @param name The name of the token /// @param symbol The symbol of the token /// @param meta The meta URI of the token event TokenCreated( uint256 ts, address creator, uint256 nonce, address token, string name, string symbol, string meta ); ``` -------------------------------- ### TypeScript Permit-on-Sell Functionality Source: https://docs.flap.sh/flap/developers/trade-tokens Demonstrates how to implement the permit-on-sell functionality using TypeScript and viem. This involves constructing permit data, signing it, and appending it to the sell transaction calldata for tokens with `TOKEN_V2_PERMIT` or higher versions. ```typescript // you can get the abi from bscscan. import portalABI from '../../abi/portal.json'; import tokenABI from '../../abi/tokenv2.json'; import { bsc } from 'viem/chains' import { createPublicClient, createWalletClient, encodeAbiParameters, encodeFunctionData, formatEther, getContract, hashDomain, parseEther, parseSignature, signatureToCompactSignature } from 'viem'; const test_account = privateKeyToAccount("your private key here"); async function main() { // for coin with coin.version > 1, // we should append "permit" data after the calldata for selling // public client const pubClient = createPublicClient({ chain: bsc, transport: http('https://rpc.ankr.com/bsc/'), batch: { multicall: { batchSize: 1024 * 200, }, }, }); // wallet client const walletClient = createWalletClient({ chain: bsc, transport: http('https://rpc.ankr.com/bsc/'), account: test_account, }); const portal = getContract({ address: "0xe2cE6ab80874Fa9Fa2aAE65D277Dd6B8e65C9De0", abi: portalABI.abi, client: { public: pubClient, wallet: walletClient } }); // The token that uses the new TokenV2 implementation const token = "token address here"; const tokenInst = getContract({ address: token, abi: tokenABI.abi, client: { public: pubClient, wallet: walletClient } }); const balance = (await tokenInst.read.balanceOf([test_account.address])) as bigint; // // Let's sell all our token // // // step1: construct the permit data // // 1.1 fetch nonce & name from the token contract const nonce = (await tokenInst.read.nonces([test_account.address])) as bigint; const name = (await tokenInst.read.name()) as string; // you may cache the name to reduce rpc calls const deadline = BigInt(Date.now() + 10 * 60 * 1000); // 10 minutes ttl // 1.2 sign the permit data , get the signature const sig = await test_account.signTypedData({ domain: { name, version: "1", chainId: bsc.id, verifyingContract: token }, types: { Permit: [ { name: "owner", type: "address" }, ``` -------------------------------- ### Solidity: Define newTokenV2 Method and Parameters Source: https://docs.flap.sh/flap/developers/launch-a-token Defines the `newTokenV2` function in Solidity for creating a new token with flexible parameters. It includes the `NewTokenV2Params` struct and relevant enums like `MigratorType` and `DexThreshType` to specify token configurations. ```solidity // solidity interface /// @notice Create a new token (V2) with flexible parameters /// @param params The parameters for the new token /// @return token The address of the created token function newTokenV2(NewTokenV2Params calldata params) external payable returns (address token); /// @notice Parameters for creating a new token (V2) struct NewTokenV2Params { /// The name of the token string name; /// The symbol of the token string symbol; /// The ipfs cid of the metadata string meta; /// The DEX supply threshold type DexThreshType dexThresh; /// The salt for deterministic deployment bytes32 salt; /// The tax rate in basis points (if non-zero, this is a tax token) uint16 taxRate; /// The migrator type (see MigratorType enum) MigratorType migratorType; /// The quote token address (native gas token if zero address) address quoteToken; /// The initial quote token amount to spend for buying uint256 quoteAmt; /// The beneficiary address for the token /// For rev share tokens, this is the address that can claim the LP fees /// For tax tokens, this is the address that receives the tax fees address beneficiary; /// The optional permit data for the quote token bytes permitData; } /// @notice the migrator type /// @dev the migrator type determines how the liquidity is added to the DEX. /// Note: To mitigate the risk of DOS, if a V3 migrator is used but the liquidity cannot /// be added to v3 pools, the migrator will fallback to a V2 migrator. enum MigratorType { V3_MIGRATOR, // Migrate the liquidity to a Uniswap V3 like pool V2_MIGRATOR // Migrate the liquidity to a Uniswap V2 like pool } /// @dev dex threshold types enum DexThreshType { TWO_THIRDS, // 66.67% supply FOUR_FIFTHS, // 80% supply HALF, // 50% supply _95_PERCENT, // 95% supply _81_PERCENT, // 81% supply _1_PERCENT // 1% supply => mainly for testing } ``` -------------------------------- ### Swap Exact Input Source: https://docs.flap.sh/flap/developers/trade-tokens Executes a token swap by providing an exact input amount and receiving the corresponding output amount. Requires `minOutputAmount` to prevent slippage. ```APIDOC ## POST /swapExactInput ### Description Executes a token swap for an exact input amount, returning the output amount received. This method requires `minOutputAmount` to define the minimum acceptable output. ### Method `POST` ### Endpoint `/swapExactInput` ### Parameters #### Request Body - **inputToken** (address) - Required - The address of the input token (use address(0) for native asset). - **outputToken** (address) - Required - The address of the output token (use address(0) for native asset). - **inputAmount** (uint256) - Required - The amount of input token to swap (in input token decimals). - **minOutputAmount** (uint256) - Required - The minimum amount of output token to receive. - **permitData** (bytes) - Optional - Optional permit data for the input token (can be empty). ### Request Example ```json { "inputToken": "0x...", "outputToken": "0x...", "inputAmount": "1000000000000000000", "minOutputAmount": "900000000000000000", "permitData": "0x..." } ``` ### Response #### Success Response (200) - **outputAmount** (uint256) - The amount of output token received. #### Response Example ```json { "outputAmount": "950000000000000000" } ``` ``` -------------------------------- ### Solidity TokenStateV2 and TokenStateV3 Structs Source: https://docs.flap.sh/flap/developers/inspect-a-token Defines the data structures for TokenStateV2 and the enhanced TokenStateV3. TokenStateV3 includes quoteTokenAddress and nativeToQuoteSwapEnabled for detailed token information, essential for understanding trading and payment mechanisms. ```solidity /// @notice the state of a token (with dex related fields) struct TokenStateV2 { TokenStatus status; // the status of the token uint256 reserve; // the reserve of the token uint256 circulatingSupply; // the circulatingSupply of the token uint256 price; // the price of the token TokenVersion tokenVersion; // the version of the token implementation this token is using uint256 r; // the r of the curve of the token uint256 dexSupplyThresh; // the cirtulating supply threshold for adding the token to the DEX } /// @notice the state of a token (with all V2 fields plus quoteTokenAddress and nativeToQuoteSwapEnabled) struct TokenStateV3 { /// The status of the token (see TokenStatus enum) TokenStatus status; /// The reserve amount of the quote token held by the bonding curve uint256 reserve; /// The circulating supply of the token uint256 circulatingSupply; /// The current price of the token (in quote token units, 18 decimals) uint256 price; /// The version of the token implementation (see TokenVersion enum) TokenVersion tokenVersion; /// The curve parameter 'r' used for the bonding curve uint256 r; /// The circulating supply threshold for adding the token to the DEX uint256 dexSupplyThresh; /// The address of the quote token (address(0) if native gas token) address quoteTokenAddress; /// Whether native-to-quote swap is enabled for this token bool nativeToQuoteSwapEnabled; } ``` -------------------------------- ### Emitting LaunchedToDEX Event for DEX Liquidity Source: https://docs.flap.sh/flap/developers/token-migration This Solidity event is emitted when liquidity is added to a Decentralized Exchange (DEX). It records the token address, the newly created pool address, the amount of the token added as liquidity, and the amount of the quote token (e.g., ETH) added. ```Solidity /// @notice emitted when adding liquidity to DEX /// @param token The address of the token /// @param pool The address of the pool /// @param amount The amount of token added /// @param eth The amount of quote Token added event LaunchedToDEX(address token, address pool, uint256 amount, uint256 eth); ``` -------------------------------- ### Solidity sell Method Source: https://docs.flap.sh/flap/developers/trade-tokens Executes the sale of tokens for ETH. Users specify the token to sell, the amount, and the minimum amount of ETH they expect to receive. This function returns the amount of ETH received. ```solidity /// @param token The address of the token to sell /// @param amount The amount of tokens to sell /// @param minEth The minimum amount of ETH to receive function sell(address token, uint256 amount, uint256 minEth) external returns (uint256 eth); ``` -------------------------------- ### Token Buying API Source: https://docs.flap.sh/flap/developers/trade-tokens This section details the API endpoints for buying tokens on the Flap.sh portal. It includes methods to preview the amount of tokens one can buy with a given amount of ETH and to execute the actual token purchase. ```APIDOC ## Preview Token Buy ### Description Preview the amount of tokens that can be bought with a specified amount of ETH. ### Method GET ### Endpoint `/previewBuy` ### Parameters #### Query Parameters - **token** (address) - Required - The address of the token to buy. - **eth** (uint256) - Required - The amount of ETH to spend. ### Response #### Success Response (200) - **amount** (uint256) - The amount of tokens that can be bought. #### Response Example ```json { "amount": "1000000000000000000" } ``` ## Buy Tokens ### Description Buy a specified amount of a token using ETH. The transaction is sent with payable functionality. ### Method POST ### Endpoint `/buy` ### Parameters #### Query Parameters - **token** (address) - Required - The address of the token to buy. - **recipient** (address) - Required - The address to send the purchased tokens to. - **minAmount** (uint256) - Required - The minimum amount of tokens expected to receive. ### Request Body This endpoint is `payable`, meaning ETH should be sent with the request. The amount of ETH to send is determined by the transaction context. ### Response #### Success Response (200) - **amount** (uint256) - The amount of tokens actually bought. #### Response Example ```json { "amount": "950000000000000000" } ``` ## TokenBought Event ### Description Emitted when a token is successfully bought through the portal. ### Parameters - **ts** (uint256) - Timestamp of the event. - **token** (address) - Address of the token bought. - **buyer** (address) - Address of the buyer. - **amount** (uint256) - Amount of tokens bought. - **eth** (uint256) - Amount of ETH spent. - **fee** (uint256) - Amount of ETH spent on fees. - **postPrice** (uint256) - Price of the token after this trade. ### Event Example ```json { "event": "TokenBought", "ts": 1678886400, "token": "0x123...abc", "buyer": "0x456...def", "amount": "950000000000000000", "eth": "1000000000000000000", "fee": "50000000000000000", "postPrice": "95000000000000000" } ``` ``` -------------------------------- ### TypeScript Inspect Token Function using Viem Source: https://docs.flap.sh/flap/developers/inspect-a-token Demonstrates how to use the Viem library in TypeScript to call the getTokenV3 function on a smart contract. It connects to the BSC chain, reads the token state, and logs detailed information, including the new fields. ```typescript import { createPublicClient, http, formatEther, Address, zeroAddress } from "viem"; import { bsc as targetChain } from "viem/chains"; import { PORTAL_ABI } from "./abi"; import { Curve } from "./curve"; import Decimal from "decimal.js"; import {FlapConfig} from "./flap-config"; // TokenStatus and TokenVersion enums for display enum TokenStatus { Invalid = 0, Tradable = 1, InDuel = 2, Killed = 3, DEX = 4 } enum TokenVersion { TOKEN_LEGACY_MINT_NO_PERMIT = 0, TOKEN_LEGACY_MINT_NO_PERMIT_DUPLICATE = 1, TOKEN_V2_PERMIT = 2, TOKEN_GOPLUS = 3 } async function inspectToken(tokenAddress: Address) { const client = createPublicClient({ chain: targetChain, transport: http(), }); const state = await client.readContract({ address: FlapConfig.portal, abi: PORTAL_ABI, functionName: "getTokenV3", args: [tokenAddress], }) as { status: number; reserve: bigint; circulatingSupply: bigint; price: bigint; tokenVersion: number; r: bigint; dexSupplyThresh: bigint; quoteTokenAddress: Address; nativeToQuoteSwapEnabled: boolean; }; console.log(`\n=== Token: ${tokenAddress} ===`); console.log("TokenStateV3:"); console.log(` status: ${TokenStatus[state.status] ?? state.status}`); console.log(` reserve: ${formatEther(state.reserve)} QUOTE TOKEN`); console.log(` circulatingSupply: ${formatEther(state.circulatingSupply)}`); console.log(` price: ${formatEther(state.price)}`); console.log(` tokenVersion: ${TokenVersion[state.tokenVersion] ?? state.tokenVersion}`); console.log(` r: ${formatEther(state.r)}`); console.log(` dexSupplyThresh: ${formatEther(state.dexSupplyThresh)}`); console.log(` quoteTokenAddress: ${state.quoteTokenAddress == zeroAddress ? "BNB" : state.quoteTokenAddress}`); } ``` -------------------------------- ### Solidity Event Definitions for Flap Token Lifecycle Source: https://docs.flap.sh/flap/developers/launch-a-token This snippet defines several Solidity events used to track the lifecycle of a Flap token. These events cover token creation, curve and tax settings, version updates, quote token configuration, and migrator type designation. They are crucial for monitoring and reacting to changes in token properties on the blockchain. ```solidity /// @notice emitted when a new token is created /// /// @param ts The timestamp of the event /// @param creator The address of the creator /// @param nonce The nonce of the token /// @param token The address of the token /// @param name The name of the token /// @param symbol The symbol of the token /// @param meta The meta URI of the token event TokenCreated( uint256 ts, address creator, uint256 nonce, address token, string name, string symbol, string meta ); /// emitted when a token's curve is set /// @param token The address of the token /// @param curve The address of the curve /// @param curveParameter The parameter of the curve event TokenCurveSet(address token, address curve, uint256 curveParameter); /// emitted when a token's dexSupplyThresh is set /// @param token The address of the token /// @param dexSupplyThresh The new dexSupplyThresh of the token event TokenDexSupplyThreshSet(address token, uint256 dexSupplyThresh); /// emitted when a token's implementation is set /// @param token The address of the token /// @param version The version of the token event TokenVersionSet(address token, TokenVersion version); /// @notice emitted when a token's curve parameters are set (V2) /// @param token The address of the token /// @param r The virtual ETH reserve parameter /// @param h The virtual token reserve parameter /// @param k The square of the virtual Liquidity parameter event TokenCurveSetV2(address token, uint256 r, uint256 h, uint256 k); /// @notice emitted when a token's quote token is set /// @param token The address of the token /// @param quoteToken The address of the quote token event TokenQuoteSet(address token, address quoteToken); /// @notice emitted when a token's migrator is set /// @param token The address of the token /// @param migratorType The migrator type event TokenMigratorSet(address token, MigratorType migratorType); /// @notice emitted when a new tax is set for a token /// @param token The address of the token /// @param tax The tax value set for the token event FlapTokenTaxSet(address token, uint256 tax); ``` -------------------------------- ### Solidity getTokenV2 and getTokenV3 Functions Source: https://docs.flap.sh/flap/developers/inspect-a-token Provides the function signatures for retrieving token states. getTokenV2 returns TokenStateV2, while the newer getTokenV3 returns the enhanced TokenStateV3, including quote token and swap enablement details. ```solidity /// @notice Get token state /// @param token The address of the token /// @return state The state of the token function getTokenV2(address token) external view returns (TokenStateV2 memory state); /// @notice Get token state (V3) /// @param token The address of the token /// @return state The state of the token (V3) function getTokenV3(address token) external view returns (TokenStateV3 memory state); ``` -------------------------------- ### Token Selling API Source: https://docs.flap.sh/flap/developers/trade-tokens This section details the API endpoints for selling tokens on the Flap.sh portal. It includes methods to preview the amount of ETH one can receive for selling tokens and to execute the actual token sale. ```APIDOC ## Preview Token Sell ### Description Preview the amount of ETH that will be received for selling a specified amount of tokens. ### Method GET ### Endpoint `/previewSell` ### Parameters #### Query Parameters - **token** (address) - Required - The address of the token to sell. - **amount** (uint256) - Required - The amount of tokens to sell. ### Response #### Success Response (200) - **eth** (uint256) - The amount of ETH to receive. #### Response Example ```json { "eth": "950000000000000000" } ``` ## Sell Tokens ### Description Sell a specified amount of tokens in exchange for ETH. Includes a minimum ETH amount expected. ### Method POST ### Endpoint `/sell` ### Parameters #### Query Parameters - **token** (address) - Required - The address of the token to sell. - **amount** (uint256) - Required - The amount of tokens to sell. - **minEth** (uint256) - Required - The minimum amount of ETH expected to receive. ### Response #### Success Response (200) - **eth** (uint256) - The amount of ETH received. #### Response Example ```json { "eth": "950000000000000000" } ``` ## TokenSold Event ### Description Emitted when a user successfully sells tokens through the Portal. ### Parameters - **ts** (uint256) - Timestamp of the trade. - **token** (address) - Address of the token sold. - **seller** (address) - Address of the seller. - **amount** (uint256) - Amount of tokens sold. - **eth** (uint256) - Amount of ETH (or quote token) received. - **fee** (uint256) - Amount of ETH (or quote token) deducted as a fee. - **postPrice** (uint256) - Price of the token after this trade. ### Event Example ```json { "event": "TokenSold", "ts": 1678886400, "token": "0x123...abc", "seller": "0x789...ghi", "amount": "1000000000000000000", "eth": "950000000000000000", "fee": "50000000000000000", "postPrice": "95000000000000000" } ``` ``` -------------------------------- ### Constructing and Sending a Sell Transaction with Permit Data (TypeScript) Source: https://docs.flap.sh/flap/developers/trade-tokens This snippet demonstrates how to construct a sell transaction on the Flap.sh platform. It involves generating a permit signature using EIP-712, encoding the necessary data, and appending it to the sell calldata before sending the transaction. It relies on external libraries for ABI encoding and transaction handling. ```typescript import { encodeFunctionData, encodeAbiParameters, parseSignature } from "viem"; import { portalABI } from "./abi"; async function main() { // ... (previous code for setup and obtaining values like balance, nonce, deadline) // 1. construct the permit data const permit = JSON.stringify({ types: { EIP712Domain: [ { name: "name", type: "string" }, { name: "version", type: "string" }, { name: "chainId", type: "uint256" }, { name: "verifyingContract", type: "address" }, ], Permit: [ { name: "owner", type: "address" }, { name: "spender", type: "address" }, { name: "value", type: "uint256" }, { name: "nonce", type: "uint256" }, { name: "deadline", type: "uint256" }, ], }, primaryType: "Permit", message: { owner: test_account.address, spender: portal.address, value: balance, nonce, deadline, } }); const sig = await walletClient.signTypedData({ domain: JSON.parse(permit).types.EIP712Domain as any, types: JSON.parse(permit).types as any, primaryType: JSON.parse(permit).primaryType as any, message: JSON.parse(permit).message as any, }); console.log(`permit sig: ${sig}`); // we want r,s,v separately, let's parse the signature const { r, s, v } = parseSignature(sig) as { r: `0x${string}`, s: `0x${string}`, v: bigint, yParity: number }; console.log(`\tr: ${r}`); console.log(`\ts: ${s}`); console.log(`\tv: ${v}`); // 3. construct the piggback data to be appended to the calldata const piggyback = encodeAbiParameters([ { name: "owner", type: "address" }, { name: "spender", type: "address" }, { name: "value", type: "uint256" }, { name: "deadline", type: "uint256" }, { name: "v", type: "uint8" }, { name: "r", type: "bytes32" }, { name: "s", type: "bytes32" } ], [test_account.address, portal.address, balance, deadline, Number(v), r, s]); console.log(`piggyback data: ${piggyback}`); // // step2: construct the sell calldata // const selldata = encodeFunctionData({ abi: portalABI.abi, functionName: "sell", args: [ token, balance, 0, // min receive eth amount ] }); // // Step3: append the permit data to the sell calldata & send the tx // const data = selldata + piggyback.slice(2); // remove the 0x prefix in piggyback data { const hash = await walletClient.sendTransaction({ to: portal.address, data: data as `0x${string}`, }); console.log(`sell hash: ${hash}`); // wait for the transaction to be mined await pubClient.waitForTransactionReceipt({ hash, confirmations: 2, }); } } main().catch(console.error).then(() => process.exit(0)); ``` -------------------------------- ### Generate Vanity Token Salt and Address (TypeScript) Source: https://docs.flap.sh/flap/developers/launch-a-token This script generates a vanity token address and its corresponding salt using the CREATE2 opcode. It takes a desired suffix (e.g., '8888' or '7777'), the token implementation address, and the portal address as inputs. The function iteratively hashes a random seed until the predicted token address ends with the specified suffix. It also tracks and logs the number of iterations required. ```typescript /// get vanity token address and salt async function findVanityTokenSalt(suffix: string, token_impl: Address, portal: Address) { if (suffix.length !== 4) { throw new Error("Suffix must be exactly 4 characters"); } // predict the vanity token address based on the saltå const predictVanityTokenAddress = (salt: Hex): Address => { const bytecode = '0x3d602d80600a3d3981f3363d3d373d3d3d363d73' + token_impl.slice(2).toLowerCase() // remove 0x prefix + '5af43d82803e903d91602b57fd5bf3' as Hex; return getContractAddress({ from: portal, salt: toBytes(salt), bytecode, opcode: "CREATE2", }); } // Note: you don't have to use a private key as the starting seed, you can use // any pseudo-random string as the starting seed. // // Here, we use a random private key as the starting seed // Then repeatedly hash the seed until we get the vanity address const seed = generatePrivateKey(); let salt = keccak256(toHex(seed)); let iterations = 0; // Track the number of iterations while (!predictVanityTokenAddress(salt).endsWith(suffix)) { salt = keccak256(salt); iterations++; // Increment the iteration count } console.log(`Iterations: ${iterations}`); // Print the number of iterations return { salt, address: predictVanityTokenAddress(salt), } } ```