Contracts
Four contracts, two on Robinhood Chain and two on BNB Chain, written in Solidity 0.8.26, no proxy upgrade. They are the on-chain half of Pivot. The Solana half has no custom program: it uses pump.fun's own program and fee sharing. Source in contracts/src/.
| Contract | Role |
|---|---|
PivotLauncher | The keeper calls launch to launch the coin on Pons with a dedicated vault as creator fee recipient. Keeps the list of coins. |
PivotFlapLauncher | BNB Chain. The keeper calls launch to launch the coin on Flap as a Tax Token V3 with a dedicated splitter as tax beneficiary. Keeps the list of coins. |
PivotFlapSplit | BNB Chain. One per coin, a minimal proxy. Receives the Flap tax in BNB and splits it between the creator's address and Pivot. Nothing else can leave it. |
PivotVault | Robinhood Chain. One per coin, a minimal proxy. Receives the Pons creator fees and splits them between the creator's address and Pivot. It also has keeper-only buy and sell functions on the Pons curve, which Pivot does not use: the vault starts with no cash. |
Launcher
struct LaunchParams {
string name;
string symbol;
string logoIpfs; // ipfs:// URI
string description;
string twitter;
string website;
uint16 creatorFeeBps; // Pons creator tax, 0..1000
address creatorEvm; // optional Robinhood payout address
uint16 creatorShareBps; // share of Pons creator fees for creatorEvm
bytes32 salt;
uint256 devBuyWei; // optional first buy on the curve, paid by the creator
}
function launch(LaunchParams calldata p) external payable
returns (address token, address curve, address vault); // only the keeper
msg.value is the Pons launch fee plus devBuyWei. The dev buy is made on the curve in the same transaction and its tokens go straight to creatorEvm, which is required when devBuyWei > 0 (NoRecipient); the creator is exempted from the snipe tax like the launcher, because Pons checks the recipient of the tokens (found on a fork: without it the buy lost 99 %). The vault starts with no cash. The launcher exempts itself and the vault from the 99 % snipe tax so the first buys are not taxed.
Vault
// keeper only
function buy(uint256 ethIn, uint256 minTokensOut) external returns (uint256);
function sell(uint256 tokensIn, uint256 minEthOut) external returns (uint256);
// keeper or pool
function sweep(uint256 ethAmount, uint256 tokenAmount) external; // to the pool address only
function retire() external; // after Pons graduation, to the pool
// public
function collect() external; // pull the Pons creator fees into the vault
function split() external; // creatorShareBps to creatorEvm, the rest to the pool
function price() external view returns (uint256);
function cash() external view returns (uint256);
function inventory() external view returns (uint256);
buycannot spend more thancash: the subtraction reverts on underflow.sweepandretiresend funds only to the pool address fixed at deployment. The pool address can call them too, so the funds can be pulled out even if the keeper key is lost. The pool cannot trade.- A reentrancy lock covers
buy,sell,sweep,retireandsplit. initializecan only be called once, by the launcher.
In the contract, pool is simply the Pivot address: it receives Pivot's share of the Pons creator fees. It is not a pool of money used to prop up a price.
Flap launcher
struct LaunchParams {
string name;
string symbol;
string meta; // CID of the metadata pinned on Flap's gateway
bytes32 salt; // mined off chain: the token address must end in 7777
uint16 taxBps; // buy tax = sell tax = the creator fee, 100..1000
address creatorEvm; // optional payout address of the creator on BNB Chain
uint16 creatorShareBps; // share of the tax for creatorEvm, at most 5000
}
function launch(LaunchParams calldata a) external payable
returns (address token, address split); // only the keeper
The launcher calls Portal.newTokenV6 with TOKEN_TAXED_V3, the V2 migrator (required for tax tokens), mktBps = 10000 so the whole tax after Flap's own share goes to the splitter, a tax duration of 99 years, and the Pivot address as commission receiver. A tax below 1 % is refused by Flap itself, so the launcher refuses it first (BadTax). msg.value is the creator's dev buy, made through the Portal in the same transaction. Its tokens go straight to creatorEvm, which is required when there is a dev buy (NoRecipient). If the dev buy is larger than what the curve takes before graduating, the Portal gives the rest back and the launcher forwards it to creatorEvm: it is the creator's money, never the pool's.
Flap splitter
function harvest() external returns (uint256); // public: dispatch the tax Flap holds, then split the balance
function split() external returns (uint256); // public: split the current balance
// creatorShareBps to creatorEvm (if set), the rest to the pool. Fixed at launch.
- The splitter only ever sends BNB to
creatorEvmand to the pool address. There is no other function that moves funds. - A reentrancy lock covers both functions,
initializeruns once and only for the launcher, and the implementation contract cannot be initialised. - The call to Flap's dispatch is wrapped so that a Flap-side revert never blocks the split. The keeper and wallets must send enough gas: estimate it, do not hard-code it.
Deployment
script/Deploy.s.sol deploys the Robinhood Chain launcher, which deploys the vault implementation, and script/DeployBnb.s.sol deploys the BNB Chain launcher, which deploys the splitter implementation (Flap Portal 0xe2cE6ab80874Fa9Fa2aAE65D277Dd6B8e65C9De0). It needs two addresses: KEEPER, the only address that can launch and trade, and POOL, which receives swept funds and the pad's share of fees. Both are immutable afterwards.
Deployment status
PivotLauncher and PivotFlapLauncher are not deployed yet. The contracts are written, tested on forks and ready: each script takes the two addresses it needs and deploys the launcher and its implementation in one transaction. The addresses will be published here, on the token page and in site.js the day it is deployed. The cost of a deployment is a few cents of gas.
What is not on-chain
The pump.fun creation and the order of the launch are run by the keeper from its own wallets. See the keeper and the operator and the trust model.