FlowFactoryC
0x7fd56360a20c3ebc8537a6b3aef2a6b827c2ffc8
Verification
Verified
v0.8.26+commit.8a97fa7a
Type
Contract
4,126 bytes
ABI entries
22
19 read · 1 write
License
none
Contract information
- Address
- 0x7fd56360a20c3ebc8537a6b3aef2a6b827c2ffc8
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.26+commit.8a97fa7a
- Optimization
- Enabled
- Creator
- 0xEDC32d6257…3F35DfC9d0
- Creation tx
- 0x3458ea2bc2…618e6d00a8
Token
Not a token
This contract does not expose ERC-20 metadata.
Read contract (19)
LP_FEE() → uint24
TICK_SPACING() → int24
curveOf(address) → address
curveSupplyWhole() → uint256
graduationTarget() → uint256
graduationTick() → int24
hook() → address
launcherDeployer() → address
platformVault() → address
poolManager() → address
positionManager() → address
supplyWhole() → uint256
tickLower() → int24
tickUpper() → int24
tokenDeployer() → address
tokens(uint256) → address
tokensCount() → uint256
universalRouter() → address
usdg() → address
Events (1)
Launched
ABI
[
{
"inputs": [
{
"internalType": "address",
"name": "usdg_",
"type": "address"
},
{
"internalType": "address",
"name": "poolManager_",
"type": "address"
},
{
"internalType": "address",
"name": "hook_",
"type": "address"
},
{
"internalType": "address",
"name": "positionManager_",
"type": "address"
},
{
"internalType": "address",
"name": "universalRouter_",
"type": "address"
},
{
"internalType": "address",
"name": "tokenDeployer_",
"type": "address"
},
{
"internalType": "address",
"name": "launcherDeployer_",
"type": "address"
},
{
"internalType": "address",
"name": "platformVault_",
"type": "address"
},
{
"internalType": "uint256",
"name": "supplyWhole_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "curveSupplyWhole_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "graduationTarget_",
"type": "uint256"
},
{
"internalType": "int24",
"name": "tickLower_",
"type": "int24"
},
{
"internalType": "int24",
"name": "tickUpper_",
"type": "int24"
},
{
"internalType": "int24",
"name": "graduationTick_",
"type": "int24"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "curve",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "creator",
"type": "address"
},
{
"indexed": false,
"internalType": "string",
"name": "name",
"type": "string"
},
{
"indexed": false,
"internalType": "string",
"name": "symbol",
"type": "string"
},
{
"indexed": false,
"internalType": "uint16",
"name": "feeBps",
"type": "uint16"
},
{
"indexed": false,
"internalType": "uint16[5]",
"name": "split",
"type": "uint16[5]"
},
{
"indexed": false,
"internalType": "string",
"name": "image",
"type": "string"
}
],
"name": "Launched",
"type": "event"
},
{
"inputs": [],
"name": "LP_FEE",
"outputs": [
{
"internalType": "uint24",
"name": "",
"type": "uint24"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "TICK_SPACING",
"outputs": [
{
"internalType": "int24",
"name": "",
"type": "int24"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "curveOf",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "curveSupplyWhole",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "graduationTarget",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "graduationTick",
"outputs": [
{
"internalType": "int24",
"name": "",
"type": "int24"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "hook",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "symbol",
"type": "string"
},
{
"internalType": "uint16",
"name": "feeBps",
"type": "uint16"
},
{
"internalType": "uint16[5]",
"name": "split",
"type": "uint16[5]"
},
{
"internalType": "string",
"name": "image",
"type": "string"
}
],
"name": "launch",
"outputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "address",
"name": "launcher",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "launcherDeployer",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "platformVault",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "poolManager",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "positionManager",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "supplyWhole",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "tickLower",
"outputs": [
{
"internalType": "int24",
"name": "",
"type": "int24"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "tickUpper",
"outputs": [
{
"internalType": "int24",
"name": "",
"type": "int24"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "tokenDeployer",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "tokens",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "tokensCount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "universalRouter",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "usdg",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
]Source code
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
FLOW — FlowFactoryC (v3 launchpad) ⚠️ WIP, NOT AUDITED
USDG-quoted launches on the v3 stack (FlowTokenV3 + FlowHookV3 + LaunchPoolV4c). The creator picks
their tax (feeBps, 0.5–10%) AND how the LAUNCHER portion of every trade splits across 5 buckets:
split = [holder, lp, treasury, buyback, ref] (bps, sum 10000, holder ≥ 50%)
The platform cut is taken by the hook at the platform tier (min(tax/2, cap)); ~20% of it funds the FLOW
burn pot, the rest the platform wallet. The token address is mined ABOVE USDG so USDG is currency0.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol";
import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
import {Currency} from "@uniswap/v4-core/src/types/Currency.sol";
interface IFlowHookV3Register {
function register(PoolKey calldata key, address token, uint16 feeBps, address initializer, address treasury, uint16[5] calldata split) external;
}
interface ITokenDeployerV3 {
function deploy(string calldata name, string calldata symbol, address treasury, uint256 supplyWhole,
address poolManager, address positionManager, address universalRouter, address to, uint256 saltSeed) external returns (address);
}
interface ILauncherDeployerC {
function deploy(address token, address usdg, address poolManager, address hook,
uint256 curveSupplyWei, uint256 gradReserveWei, uint256 graduationTarget,
int24 tickLower, int24 tickUpper, int24 graduationTick,
uint256 feeBps, address platformVault, address to) external returns (address);
}
interface ITokenAdmin {
function setCurve(address) external;
function setHook(address) external;
function transfer(address, uint256) external returns (bool);
function transferOwnership(address) external;
}
interface ILauncherAdmin {
function open() external;
function transferOwnership(address) external;
}
contract FlowFactoryC {
uint24 public constant LP_FEE = 3000;
int24 public constant TICK_SPACING = 60;
// No per-bucket minimum: a launcher is free to send 0% to holders (not every token is a reward token —
// some are plain "buy what you see" coins that route the tax to lp/treasury/buyback instead). The split
// is fully the creator's choice; it's transparent on-chain and shown on the launch UI. Only the sum is fixed.
address public immutable usdg;
address public immutable poolManager;
address public immutable hook; // FlowHookV3
address public immutable positionManager;
address public immutable universalRouter;
address public immutable tokenDeployer;
address public immutable launcherDeployer;
address public immutable platformVault; // 0 in v3 (no supply cut; platform earns via the hook)
uint256 public immutable supplyWhole;
uint256 public immutable curveSupplyWhole;
uint256 public immutable graduationTarget; // USDG (informational)
int24 public immutable tickLower;
int24 public immutable tickUpper;
int24 public immutable graduationTick;
address[] public tokens;
mapping(address => address) public curveOf;
event Launched(
address indexed token, address indexed curve, address indexed creator,
string name, string symbol, uint16 feeBps, uint16[5] split, string image
);
constructor(
address usdg_, address poolManager_, address hook_,
address positionManager_, address universalRouter_,
address tokenDeployer_, address launcherDeployer_, address platformVault_,
uint256 supplyWhole_, uint256 curveSupplyWhole_, uint256 graduationTarget_,
int24 tickLower_, int24 tickUpper_, int24 graduationTick_
) {
require(usdg_ != address(0) && poolManager_ != address(0) && hook_ != address(0), "zero");
require(tokenDeployer_ != address(0) && launcherDeployer_ != address(0), "zero");
require(supplyWhole_ > 0 && curveSupplyWhole_ > 0 && curveSupplyWhole_ < supplyWhole_, "supply");
require(graduationTarget_ > 0, "params");
require(tickLower_ < graduationTick_ && graduationTick_ < tickUpper_, "ticks");
require(tickLower_ % TICK_SPACING == 0 && tickUpper_ % TICK_SPACING == 0 && graduationTick_ % TICK_SPACING == 0, "align");
usdg = usdg_; poolManager = poolManager_; hook = hook_;
positionManager = positionManager_; universalRouter = universalRouter_;
tokenDeployer = tokenDeployer_; launcherDeployer = launcherDeployer_; platformVault = platformVault_;
supplyWhole = supplyWhole_; curveSupplyWhole = curveSupplyWhole_; graduationTarget = graduationTarget_;
tickLower = tickLower_; tickUpper = tickUpper_; graduationTick = graduationTick_;
}
/// Launch a v3 basket-token. `split` = [holder, lp, treasury, buyback, ref] bps (sum 10000, holder ≥ 5000).
/// The caller is the treasury + final owner of both the token and the launcher.
function launch(string calldata name, string calldata symbol, uint16 feeBps, uint16[5] calldata split, string calldata image)
external
returns (address token, address launcher)
{
require(feeBps >= 50 && feeBps <= 1_000, "fee 0.5-10%");
require(uint256(split[0]) + split[1] + split[2] + split[3] + split[4] == 10_000, "split sum");
uint256 supplyWei = supplyWhole * 1e18;
uint256 curveSupplyWei = curveSupplyWhole * 1e18;
uint256 gradReserveWei = supplyWei - curveSupplyWei;
token = ITokenDeployerV3(tokenDeployer).deploy(
name, symbol, msg.sender, supplyWhole, poolManager, positionManager, universalRouter, address(this), tokens.length
);
launcher = ILauncherDeployerC(launcherDeployer).deploy(
token, usdg, poolManager, hook, curveSupplyWei, gradReserveWei, graduationTarget,
tickLower, tickUpper, graduationTick, uint256(feeBps), platformVault, address(this)
);
IFlowHookV3Register(hook).register(_poolKey(token), token, feeBps, launcher, msg.sender, split);
ITokenAdmin(token).setCurve(launcher);
ITokenAdmin(token).setHook(hook);
ITokenAdmin(token).transfer(launcher, supplyWei);
ILauncherAdmin(launcher).open();
ITokenAdmin(token).transferOwnership(msg.sender);
ILauncherAdmin(launcher).transferOwnership(msg.sender);
tokens.push(token);
curveOf[token] = launcher;
emit Launched(token, launcher, msg.sender, name, symbol, feeBps, split, image);
}
function tokensCount() external view returns (uint256) { return tokens.length; }
function _poolKey(address token_) internal view returns (PoolKey memory) {
return PoolKey({
currency0: Currency.wrap(usdg),
currency1: Currency.wrap(token_),
fee: LP_FEE,
tickSpacing: TICK_SPACING,
hooks: IHooks(hook)
});
}
}
Chain explorer3446msChain node76ms