Create
Documentation
Reference

Contracts

Every deployed contract: functions, events and errors.

FociV2LaunchFactory#

0xa93f9CeFD92A77e1EAffa3246B6F4DB91a5c5659

Functions an application calls#

canLaunch(address)#

0x58373f04 · view · view

Whether launcher may launch right now: true while the public gate is open, and true for whitelisted addresses while it is closed. The same predicate launchToken enforces on its caller, exposed so routers like FociV2LaunchAndBuy can hold their own callers to this single list instead of maintaining a second one.

launchEnabled is left FALSE by deployment. Always check this before showing a launch form.

Parameters

NameTypeDescription
launcheraddress

Returns

NameTypeDescription
arg0bool

createGraduatedPool(address)#

0x2f53ef2f · nonpayable · Permissionless and retryable.

Initializes the V4 pool with the swept reserves, mints a full-range position directly to the locker, and registers the pool with the meme hook. The curve already holds the pool's quote asset, so this seeds with exactly what it swept and needs no slippage bound. Permissionless and retryable: a launch stays in Swept until a seed succeeds, so a transient failure can never strand reserves.

Seeds the V4 pool and locks the position. Like graduate this normally runs inside the crossing buy — but it costs roughly 900k gas on its own, and under EIP-150's 63/64 rule a buy sized by a naive estimateGas starves it. When that happens the curve emits AutoSeedFailed and the launch sits in phase 1 with no tradeable venue until someone calls this. Run a keeper on that event. Send an explicit gas limit; estimation is reliable here because there is no try/catch to hide the cost.

Parameters

NameTypeDescription
tokenaddress

Returns

NameTypeDescription
positionIduint256

Reverts

  • WrongGraduationPhase — not in the Swept phase
  • GraduationSeedNotViable

getLaunchConfig(uint256)#

0x1cad862d · view · view

Returns one token launch configuration.

Parameters

NameTypeDescription
iduint256

Returns

NameTypeDescription
arg0(uint256,uint256,uint256,uint256,uint24,int24,bool)

getLaunchedToken(address)#

0x3cf28b5a · view · view

Returns the immutable record for a token created by this factory.

Returns a ZEROED struct for an unknown token rather than reverting — check .exists. This is also where you get the per-launch curve address, since curves have no fixed deployment.

Parameters

NameTypeDescription
tokenaddress

Returns

NameTypeDescription
arg0(address,address,address,address,address,uint256,uint24,int24,uint16,uint8,uint256,uint256,uint256,bool)

graduate(address)#

0xff6d8d05 · nonpayable · Permissionless — anyone may call it.

Sweeps the curve's remaining quote and token reserves into this factory and halts curve trading. Purely internal to the curve's own balances, so it is safe for the curve to call this automatically the instant a buy crosses the graduation threshold.

Normally runs automatically inside the buy that crosses the threshold. Call it manually only when that inner attempt failed, which the curve reports by emitting AutoGraduationFailed.

Parameters

NameTypeDescription
tokenaddress

Reverts

  • WrongGraduationPhase — already swept
  • NotReadyToGraduate — the curve is not finished

launchFee()#

0xcf3cf573 · view · view

Returns

NameTypeDescription
arg0uint256

launchFeeToken()#

0xbd03b5fc · view · view

A flat charge on creating a launch, in launchFeeToken. Spam friction rather than revenue. Zero disables it outright: the payment path is skipped entirely, so nothing is pulled and no approval is needed while it is off. ERC-20 rather than native even where a chain's native asset is the same asset: the atomic launch router funds itself through transferFrom, and a native fee would make one call carry both an approval and attached value for what is economically one token.

Returns

NameTypeDescription
arg0address

launchToken((string,string,string,string,(string,string,string,string,string),address,uint16,bytes32,bytes32),uint256,address)#

0xbc9bc035 · nonpayable · Permissionless, but gated by canLaunch(msg.sender) — check it before offering a launch UI.

Deploys a bonding curve and its launch token, wires them together, and records the launch. Trading starts immediately on the curve; the graduation pool's pairToken is fixed here, chosen by the caller.

Approve first: factory for launchFee() of launchFeeToken() (USDC).

Use this when there is NO opening buy. The atomic router reverts on a zero quoteIn, so it cannot be used as a plain deployer. Note the approval target differs from the router path: the factory pulls the fee from msg.sender itself. If launchFee() is zero, no approval is needed at all. A token launched this way starts with the creator holding none of its supply.

Parameters

NameTypeDescription
params(string,string,string,string,(string,string,string,string,string),address,uint16,bytes32,bytes32)
launchConfigIduint256
pairTokenaddress

Returns

NameTypeDescription
tokenaddress
curveaddress

Reverts

  • NotWhitelistedlaunchEnabled is false and you are not a whitelisted launcher
  • InvalidLaunchConfigId — no such config
  • InvalidTokenParams — empty name or symbol
  • CreatorTaxTooHighcreatorTaxBps above maxCreatorTaxBps()
  • PairTokenNotApproved — quote asset not approved by the owner
  • LaunchEconomicsMismatch(expected,actual) — terms moved since you read previewLaunchEconomics
  • FailedDeployment — you already used this salt; salts are namespaced per account
  • ERC-20 revert on the fee transfer — insufficient allowance to the factory

pairTokenEconomics(address)#

0x31082134 · view · view

Phantom reserve and graduation threshold in the QUOTE ASSET'S OWN DECIMALS (6 for USDC).

Parameters

NameTypeDescription
pairTokenaddress

Returns

NameTypeDescription
phantomQuoteuint256
graduationThresholduint256
decimalsuint8

previewLaunchEconomics(uint256,address)#

0xf718b78c · view · view

Returns the economics digest a launch of launchConfigId in pairToken would produce right now, for a creator to pass back as TokenParams.expectedEconomics.

Reading the digest and launching in separate transactions still leaves the terms free to move in between; the pin is what makes that movement revert instead of silently repricing the launch.

Returns the digest to put in TokenParams.expectedEconomics. Fetch it in the same flow as the submit — it covers the launch fee, so an owner changing setLaunchFee between your quote and your signature invalidates it. Passing bytes32(0) waives the check entirely, which means accepting whatever terms are live when the transaction lands.

Parameters

NameTypeDescription
launchConfigIduint256
pairTokenaddress

Returns

NameTypeDescription
arg0bytes32

Other functions#

SignatureSelectorMutability
acceptOwnership()0x79ba5097nonpayable
addLaunchConfig((uint256,uint256,uint256,uint256,uint24,int24,bool))0x0e5b0aaenonpayable
approvedPairTokens(address)0x9831705eview
cancelCreatorFeeRecipientChange(address)0x6e47a188nonpayable
CREATOR_FEE_RECIPIENT_EXECUTION_WINDOW()0x02d4753dview
CREATOR_FEE_RECIPIENT_TIMELOCK()0x5a83b00aview
executeCreatorFeeRecipientChange(address)0x3d3d2d58nonpayable
feeEscrow()0xc4b7de97view
forceSweptGraduation(address)0x7aed273enonpayable
getLaunchFeePolicy(address)0x470ef5fcview
GRADUATION_RESCUE_DELAY()0x2d1250b8view
graduationExecutor()0xcc6d7a39view
graduationGuard()0x496aa100view
launchConfigCount()0xae72d871view
launchDeployer()0x858f5964view
launchEnabled()0x236a4afbview
launchForwarder()0x9b924452view
launchTokenFor((string,string,string,string,(string,string,string,string,string),address,uint16,bytes32,bytes32),uint256,address,address)0x266101cbnonpayable
locker()0xd7b96d4eview
maxCreatorTaxBps()0xf325a5fbview
memeHook()0x6651812cview
owner()0x8da5cb5bview
pendingCreatorFeeRecipient(address)0x9beacf4aview
pendingOwner()0xe30c3978view
permit2()0x12261ee7view
poolManager()0xdc4c90d3view
positionManager()0x791b98bcview
renounceOwnership()0x715018a6pure
rescueCurveFees(address)0x189eb0f5nonpayable
rescueSweptGraduation(address,address)0xdbcb9c76nonpayable
setCreatorFeeRecipient(address,address)0xe102c9aanonpayable
setGraduationExecutor(address)0xfbec2d8bnonpayable
setLaunchDeployer(address)0x3a9391e8nonpayable
setLaunchEnabled(bool)0xf56f05b2nonpayable
setLaunchFee(address,uint256)0x6e51833fnonpayable
setLaunchForwarder(address)0x767b7c16nonpayable
setMaxCreatorTaxBps(uint256)0x2260aeadnonpayable
setPairTokenApproved(address,bool)0x8763e3dcnonpayable
setPairTokenEconomics(address,uint256,uint256,uint8)0x092c08bdnonpayable
setWhitelistedLauncher(address,bool)0x366f0f3enonpayable
transferCreatorFeeRecipient(address,address)0x2931861bnonpayable
transferOwnership(address)0xf2fde38bnonpayable
updateLaunchConfig(uint256,(uint256,uint256,uint256,uint256,uint24,int24,bool))0xe73e334anonpayable
whitelistedLaunchers(address)0xda3eda65view

Events#

Eventtopic0
CreatorFeeRecipientChangeCancelled(address,address)0xbe2de91c1cbef653c760573fff8355c0c851d35ed2a898342b4db556301cccf4
CreatorFeeRecipientChangeProposed(address,address,address,uint256,uint256)0x7f119e44c84a715429bee60d30ad2e14afdef6c60bb1a7eaa01290ecf6d1b2e5
CreatorFeeRecipientUpdated(address,address,address)0x308c390ed1ab5873392818e036cabdf408bc8ad042fbaead3108954ff75ba980
GraduationExecutorSet(address)0xac04674474e93058fae25e6df5dd94f57cdcacfe560a182a2eefc8c6006fbf6f
GraduationTokensPermanentlyLocked(address,uint256)0xa0a18f5bf205becee8b268d7cf69addab8548ae8ef361791464cf0e0e17c1361
LaunchConfigAdded(uint256)0xedd96c570c6e5ef9add0378e59df53579a283889dc5dab6440ef6eca2ee6c8ce
LaunchConfigUpdated(uint256)0x2f8ba78ae68cfd0c82c7756c540eaf4eead3341aef9ccebcb91d546bff10d62b
LaunchDeployerSet(address)0xd5ea7aa3e328a0594dcf6914cd9e5369779efaa194ee4dd4c5afcad4f4ebbb0c
LaunchEnabledUpdated(bool)0x4f1ea5016c51c2f82324e00e9b8a4a95ee5aeaa10c653dabaec5f1bc9047ba0b
LaunchFeeUpdated(address,uint256)0xd0766d3f1431146228fe8edef25f27842a1669c91d46e4af1b73405b354489a5
LaunchForceSwept(address)0x52c1a28345695afc7f6b7629133124dec5d61ee745affd65e4fd2a776bc05840
LaunchForwarderSet(address)0x56b32d3633fed72f97c4df44a78b5fa04f1d662d4bddebcd8a9b216d26d093ad
LaunchGraduationRescued(address,address,uint256,uint256)0x7017304fdd491394686dce984eac721f0be1a22228346210f16694772bde44ca
LaunchSwept(address,uint256,uint256)0xcdb72f157fd3666758a6ce201387ffb52038c7562e4fff352828da1096c4b6b4
MaxCreatorTaxUpdated(uint256)0x3e99ceb3e222d2214d53dacca902810db845f156f78152fdc076be628c4e9a40
OwnershipTransferred(address,address)0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0
OwnershipTransferStarted(address,address)0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700
PairTokenApprovalUpdated(address,bool)0x060d1992d069dc524985f328329aae36102a017c59733c5c91fc0691ee0703b6
PairTokenEconomicsUpdated(address,uint256,uint256,uint8)0x67d517ee0e305d608b8410ddef27bbd2ed964d843d9b936e84ea2ad1bd65e5d1
PoolGraduated(address,uint256,uint256,uint256)0x0a44ef75df69c534f43cd6c1aa3ef8983065fe5fe79ef9e79f6494e6f258c259
TokenLaunched(address,address,address,address,uint256,uint256)0x8d4aad4953d0ca700d468f3753aa14432d1b35b43ec6409f051fb6aa43a89607
WhitelistedLauncherUpdated(address,bool)0xef2b562a67f01ed4b7c4265ec09b539039c6d5dd7e752191d3940508c3dc0068

Errors#

ErrorSelector
AlreadySet()0xa741a045
CombinedFeeTooHigh()0x49e55bcb
CoreLpFeeMustBeZero()0x85258712
CreatorTaxTooHigh()0x9ad465dc
CurveFeeTooHigh()0x4e222a24
CurveNotQuotable()0x95e32dab
FeeTransferFailed()0x4033e4e3
GraduationExecutorNotSet()0xd43cabc3
GraduationRescueTooEarly(uint256)0xbdcd75af
GraduationSeedNotViable()0x2c37d0eb
GraduationStillViable()0x6d3bcfe5
InexactTransfer(address,uint256,uint256)0x495a9962
InvalidBasisPoints()0x800c7e91
InvalidGraduationThreshold()0x2bb8bdd6
InvalidLaunchConfigId()0x68b42c59
InvalidPhantomQuote()0x2b7ad4f8
InvalidTickSpacing()0x270815a0
InvalidTokenParams()0x374852ca
LaunchConfigDisabled()0xa8b63076
LaunchDependenciesNotWired()0x1de25df3
LaunchDeployerNotSet()0x57332dcf
LaunchEconomicsMismatch(bytes32,bytes32)0xecb27319
LaunchFeeTokenNotSet()0x52660db0
NoPendingChange()0xa3fef2f8
NotCreatorFeeRecipient()0xb9f93944
NothingToGraduate()0xc2074c46
NotLaunchForwarder()0xea9eaa96
NotReadyToGraduate()0xffa32558
NotWhitelisted()0x584a7938
OwnableInvalidOwner(address)0x1e4fbdf7
OwnableUnauthorizedAccount(address)0x118cdaa7
OwnershipCannotBeRenounced()0x2fab92ca
PairTokenDecimalsMismatch(uint8,uint8)0x4e3de34f
PairTokenDecimalsUnavailable()0xe43c14ca
PairTokenEconomicsInvalid()0x764c63c8
PairTokenNotApproved()0x49285dfb
PairTokenValidationFailed()0x26fbfa60
ReentrancyGuardReentrantCall()0x3ee5aeb5
SafeERC20FailedOperation(address)0x5274afe7
SqrtPriceOutOfBounds()0x582157bb
SupplyTooHigh()0xacb9fa2b
SupplyTooLow()0xc0b4e373
TimelockExpired(uint256)0xb79d40e8
TimelockNotElapsed(uint256)0x810c4f2a
TokenNotFound()0xcbdb7b30
UnsupportedPrice()0xdd737e7c
WrongGraduationPhase()0x9465dbd4
ZeroAddress()0xd92e233d
ZeroAmount()0x1f2a2005

FociV2BondingCurve#

Deployed once per launch — no fixed address. Read it from factory.getLaunchedToken(token).

Functions an application calls#

buy(uint256,uint256,address)#

0x59a87bc1 · payable · Permissionless. Reverts once the launch has graduated.

Buys the launch token with this launch's quote asset. The fee is always taken from the quote leg, so this curve never holds a memecoin-denominated fee.

quoteIn must equal msg.value for a native launch, and must be accompanied by no value at all for an ERC-20 launch. The credited amount for an ERC-20 is the observed balance delta rather than the requested amount, so a fee-on-transfer quote asset cannot make the curve promise reserves it never received. A buy that would take the curve past its reserved allocation is filled only up to that allocation, charged for what it actually received, and refunded the difference. It is deliberately not rejected: the last buy of a launch is the one most likely to be sized against a state someone else has already moved, and reverting would let anyone grief it by slipping a small buy in ahead. Partial fills reinterpret minTokensOut as a bound on price rather than on quantity, since a caller who spends less than they offered cannot expect the whole quantity they asked for. The requirement is that the price paid is no worse than the price implied by the caller's own arguments, and when nothing is clamped it reduces exactly to tokensOut >= minTokensOut.

Approve first: curve for quoteIn of the quote asset (USDC).

minTokensOut is a PRICE bound, not a quantity bound. A buy that would exceed the remaining allocation is clamped rather than reverted, and the remainder is refunded to msg.sender in the same transaction — so you can safely overshoot the graduation threshold.

Parameters

NameTypeDescription
quoteInuint256
minTokensOutuint256
recipientaddress

Returns

NameTypeDescription
tokensOutuint256

Reverts

  • CurveGraduated — the curve is closed; trade the V4 pool instead
  • SlippageExceeded(tokensOut,minTokensOut) — the effective price broke your bound
  • UnexpectedNativeValue — sent ETH on an ERC-20-quoted launch; msg.value must be 0
  • ZeroAmount — the transfer delivered nothing

buy(uint256,uint256,address,address)#

0x82b2a559 · payable · Permissionless. Reverts once the launch has graduated.

Buys with a referrer attached.

The referrer is only consulted the first time recipient trades with one; after that the binding in the registry stands and this argument is ignored, so passing a fresh referrer cannot poach an existing relationship. An unusable referrer (the recipient themselves, or someone the recipient already refers) reverts rather than being dropped, because it is an argument the caller chose to supply and silently charging them the undiscounted fee would be worse.

Approve first: curve for quoteIn of the quote asset (USDC).

As above, with a referrer bound to recipient (not to msg.sender). The binding is written only on that address's first referred trade and is permanent thereafter. An unusable referrer REVERTS THE WHOLE BUY — SelfReferral and ReciprocalReferral are not swallowed — so resolve and validate a referrer before putting it in the call.

Parameters

NameTypeDescription
quoteInuint256
minTokensOutuint256
recipientaddress
referreraddressThe account to credit for this recipient's trades, or the zero address to trade under whatever binding already exists.

Returns

NameTypeDescription
tokensOutuint256

Reverts

  • SelfReferral — referrer is the recipient
  • ReciprocalReferral — the recipient already refers that address
  • everything the 3-argument overload throws

getReserves()#

0x0902f1ac · view · view

Returns the curve's current tradeable reserves, excluding fees pending sweep.

Returns the VIRTUAL reserves — quoteReserve includes the phantom reserve. For the amount actually raised use realQuoteReserve().

Returns

NameTypeDescription
quoteReserve_uint256
tokenReserve_uint256

graduated()#

0xe7c2b772 · view · view

Returns

NameTypeDescription
arg0bool

quoteReserve()#

0x9da771f4 · view · view

Tradeable quote reserve only, matching IFociV2BondingCurve.

Returns

NameTypeDescription
quoteReserve_uint256

readyToGraduate()#

0xc68360a5 · view · view

True once the curve's sellable allocation has been bought out.

Equivalent to the real quote reserve reaching graduationThreshold, since the reserved balance is derived from that same point. Expressed against the token side because that is the one a buy cannot overshoot: the quote side is a floor that a large trade could sail past, while the token side is a hard stop the curve refuses to cross.

True when the sellable allocation reaches zero, which is by construction the same point as the real quote reserve reaching the graduation threshold.

Returns

NameTypeDescription
arg0bool

realQuoteReserve()#

0x4f1f58fd · view · view

Returns physically held tradeable quote asset, excluding virtual liquidity and balances already earmarked as fees or creator tax.

Returns

NameTypeDescription
arg0uint256

sell(uint256,uint256,address)#

0xd04c6983 · nonpayable · Permissionless. Closes the instant readyToGraduate() is true.

Sells the launch token back to the curve for the quote asset. The fee is taken from the quote output, so it is always quote-denominated here too.

Closed once the sellable allocation is exhausted, not merely once graduated is set. _tryAutoGraduate swallows a failed graduation so a problem there cannot take the crossing buy down with it, which leaves a window where the curve is ready but the flag is still false. buy already refuses that state through its own sellable == 0 check, and sell has to match: graduate hands the pool whatever trackedTokens holds, so a sell landing in the window would put tokens back on the curve and take quote off it, and the pool would then be seeded deeper and cheaper than the reserved allocation fixes it at. The deterministic graduation price only holds if the window is closed on both sides. This cannot strand a holder. graduate is permissionless, so anyone blocked here can settle the launch themselves in the same transaction and trade the V4 pool instead.

Approve first: curve for tokensIn of the MEMECOIN (18 decimals).

Unlike buy, minQuoteOut is a strict QUANTITY bound. The sell side shuts the moment the allocation is exhausted — before the graduated flag is even set — so a sell can start reverting with CurveGraduated while the UI still shows a live curve. Approve the CURVE for the memecoin, not the factory.

Parameters

NameTypeDescription
tokensInuint256
minQuoteOutuint256
recipientaddress

Returns

NameTypeDescription
quoteOutuint256

Reverts

  • CurveGraduated — the allocation is exhausted or the curve has graduated
  • SlippageExceeded(quoteOut,minQuoteOut)
  • ZeroAmount

sellableTokens()#

0x808bcddc · view · view

Tokens still available to buy before the curve graduates.

Returns

NameTypeDescription
arg0uint256

Other functions#

SignatureSelectorMutability
creatorTaxBalance()0xdb2bd533view
creatorTaxBps()0xc1bb8901view
deployer()0xd5f39488view
factory()0xc45a0155view
feeBps()0x24a9d853view
feeEscrow()0xc4b7de97view
feePolicy()0x82589038view
graduate(address)0xff6d8d05nonpayable
graduationThreshold()0x8b0bc501view
initialize(address)0xc4d66de8nonpayable
isNativeQuote()0xdc08e094view
launchedAt()0xbf56b371view
launchSupply()0x3f7ed6b7view
maxInternalPriceImpactBps()0x90addc1eview
pairToken()0x3de35b79view
phantomQuote()0xc57eadfcview
protocolFeeRecipient()0x64df049eview
protocolFeeShareBps()0x9040f866view
quoteFeeBalance()0xed479c47view
referralDiscountBps()0x30ab6943view
referralRegistry()0x4e627e62view
referralShareBps()0x47c9bc2dview
rescueFees()0x52920587nonpayable
reservedTokens()0x15a55347view
setCreatorFeeRecipient(address)0x7b04ea62nonpayable
sweepFees()0xd113b95cnonpayable
token()0xfc0c546aview
tokenReserve()0xcbcb3171view
trackedQuote()0xca52b0b7view
trackedTokens()0x4c37ef23view

Events#

Eventtopic0
AutoGraduationFailed(address,uint256)0xe2cd2f31ebc05ec28640102987f4c8fc5f20e269e1b3aa82577f3f2f0e35c7c6
AutoSeedFailed(address,uint256)0x2cbe77dadc7f8418071409bebfd71778263eecb998af52aa5c9e27b995a71676
CreatorFeeRecipientUpdated(address,address)0x2cc664e1ac1e2d05c0d4637bb63ec8189113b6ac39276be8977e26216a8cdd19
CurveBuy(address,address,uint256,uint256,uint256,uint256)0xec36bf571f136799e8dc0b0b8bea4b04d8bd3d43de838aab0d5fc21d4cbfc455
CurveBuyRefunded(address,uint256)0xa69e8258ccc7b9bbb70ab953fc2d1062b4ee28b8ca827534097e1732e87b0262
CurveCompleted(address,uint256,uint256)0xf8d37a90738ae063b8b8058b66f5880cf3cf7ab0c5d4fa78219696591dfbfb67
CurveSell(address,address,uint256,uint256,uint256,uint256)0x8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df
FeesRescued(address,address,uint256,uint256)0x6460dc5c867a0678a8bcc5e64f629fae539901c53a4a8b42fe21d7a6c5e6437d
FeesSwept(uint256,uint256)0xaf739f46ca7a23c9f259838ec2c5249acf4e1cf9fe68a46f77c3dfa452eda605
Initialized(address)0x908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e6
ReferralFeePaid(address,address,uint256)0xde9bddf476dde28b26de9d0b38bb9811ebb9d4945cd0c7feadd215c28fe09717

Errors#

ErrorSelector
AlreadyGraduated()0xe6a0d45f
AlreadyInitialized()0x0dc149f0
CurveGraduated()0x025ac17e
InsufficientInputAmount()0x098fb561
InsufficientLiquidity()0xbb55fd27
InsufficientOutputAmount()0x42301c23
InvalidFeePolicy()0x7a34030f
InvalidLaunchEconomics()0xbc0ecfe3
NativeValueMismatch(uint256,uint256)0xbc760cfe
NotFactory()0x32cc7236
NotFeeSweepOperator()0x8d42130c
NotInitialized()0x87138d5c
NotReadyToGraduate()0xffa32558
ReentrancyGuardReentrantCall()0x3ee5aeb5
SafeERC20FailedOperation(address)0x5274afe7
SlippageExceeded(uint256,uint256)0x71c4efed
TransferFailed()0x90b8ec18
UnexpectedNativeValue()0xe0aeda7d
ZeroAddress()0xd92e233d
ZeroAmount()0x1f2a2005

FociV2LauncherToken#

Deployed once per launch — no fixed address. Read it from factory.getLaunchedToken(token).

Other functions#

SignatureSelectorMutability
allowance(address,address)0xdd62ed3eview
approve(address,uint256)0x095ea7b3nonpayable
balanceOf(address)0x70a08231view
burn(uint256)0x42966c68nonpayable
burnFrom(address,uint256)0x79cc6790nonpayable
curve()0x7165485dview
decimals()0x313ce567view
deployer()0xd5f39488view
description()0x7284e416view
getTokenInfo()0xabb1dc44view
launchFactory()0x536dac9bview
logo()0xfb7f21ebview
name()0x06fdde03view
socials()0x53cd512aview
symbol()0x95d89b41view
totalSupply()0x18160dddview
transfer(address,uint256)0xa9059cbbnonpayable
transferFrom(address,address,uint256)0x23b872ddnonpayable

Events#

Eventtopic0
Approval(address,address,uint256)0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925
Transfer(address,address,uint256)0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef

Errors#

ErrorSelector
ERC20InsufficientAllowance(address,uint256,uint256)0xfb8f41b2
ERC20InsufficientBalance(address,uint256,uint256)0xe450d38c
ERC20InvalidApprover(address)0xe602df05
ERC20InvalidReceiver(address)0xec442f05
ERC20InvalidSender(address)0x96c6fd1e
ERC20InvalidSpender(address)0x94280d62
ZeroAddress()0xd92e233d

FociV2LaunchAndBuy#

0xE4A165a52A6033ee0C1b3B6dA83f72AbA1707349

Functions an application calls#

launchAndBuy((string,string,string,string,(string,string,string,string,string),address,uint16,bytes32,bytes32),uint256,address,uint256,uint256,address)#

0x32b6091a · payable · Permissionless, but factory.canLaunch(msg.sender) must hold — routing through the router does not widen the gate.

Launches a token and immediately buys quoteIn of its curve for recipient, both in this transaction.

A native launch carries the opening buy as msg.value. An ERC-20 launch carries no value at all and the buy is pulled from the caller, who must have approved this contract for quoteIn first.

Approve first: launchAndBuy for launchFee() + quoteIn — ONE approval covers both of launchFeeToken() (USDC).

Deploys the token and performs the creator's opening buy in one transaction. Two things differ from the direct path: creatorFeeRecipient may NOT be zero here (the direct path defaults it to the caller), and quoteIn may not be zero — the router exists to buy. GAS: if the opening buy crosses the graduation threshold the curve tries to seed the V4 pool inside this same transaction, and eth_estimateGas cannot size that — the seed is a best-effort try/catch, so a simulation in which it fails still succeeds overall and returns a limit too small for it to work. Send an explicit generous gas limit.

Parameters

NameTypeDescription
params(string,string,string,string,(string,string,string,string,string),address,uint16,bytes32,bytes32)Launch parameters, forwarded to the factory untouched. Set creatorFeeRecipient to the wallet that should earn the launch's fees, and expectedEconomics to the value previewLaunchEconomics returned, which still pins the terms as it would on a direct launch.
launchConfigIduint256Factory launch config to launch against.
pairTokenaddressQuote asset, or the zero address for a native launch.
quoteInuint256Amount of the quote asset to spend on the opening buy. An amount past what the curve can sell is clamped by the curve and the remainder comes back to the caller.
minTokensOutuint256Slippage bound on the opening buy. The curve prices a clamped fill against this too, so a buy sized to take the whole allocation can still set a meaningful floor.
recipientaddressReceives the purchased tokens.

Returns

NameTypeDescription
tokenaddress
curveaddress
tokensOutuint256

Reverts

  • NotApprovedLauncher — the factory's launch gate is closed for you
  • ZeroAddressrecipient or params.creatorFeeRecipient is zero
  • ZeroAmountquoteIn is zero; use factory.launchToken instead
  • everything launchToken throws, plus an allowance failure against the router

Other functions#

SignatureSelectorMutability
acceptOwnership()0x79ba5097nonpayable
factory()0xc45a0155view
owner()0x8da5cb5bview
pendingOwner()0xe30c3978view
renounceOwnership()0x715018a6nonpayable
rescue(address,address)0x4fdf5d1dnonpayable
transferOwnership(address)0xf2fde38bnonpayable

Events#

Eventtopic0
Launched(address,address,address,address,uint256,uint256)0xdcacba5e347ae7abd91cb519eb877af8fa7774e347b85dd3ddcd24a2ba8cdf37
OwnershipTransferred(address,address)0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0
OwnershipTransferStarted(address,address)0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700
Rescued(address,address,uint256)0x3af790fafda720819b2fc6e15090606e81154e0ac9a92d38ecad006d99d20ecc

Errors#

ErrorSelector
NativeValueMismatch(uint256,uint256)0xbc760cfe
NotApprovedLauncher()0x502ba015
OwnableInvalidOwner(address)0x1e4fbdf7
OwnableUnauthorizedAccount(address)0x118cdaa7
ReentrancyGuardReentrantCall()0x3ee5aeb5
RefundFailed()0xf0c49d44
SafeERC20FailedOperation(address)0x5274afe7
ZeroAddress()0xd92e233d
ZeroAmount()0x1f2a2005

FociV2MemeHook#

0x527129aB10Fa3163629A32c4E3Ab7a98ba28e044

Functions an application calls#

claimReferralFees(address,address)#

0xcf893acc · nonpayable · Permissionless — anyone may settle anyone's accrual into the escrow.

Pays a referrer their accrued fees for one currency into the escrow. Permissionless: the amount and destination are fixed by the ledger, so who triggers the settlement does not matter.

Deliberately not settled inside afterSwap. An escrow credit is an external call plus an approval, and putting it on the swap path would charge every trader for it. This mirrors how the pool's own fees are batched into sweepPoolFees rather than distributed per swap.

Two steps, not one: this moves the accrual into the escrow, then the referrer calls feeEscrow.claimToken to withdraw. Returns 0 and does nothing when the ledger is empty.

Parameters

NameTypeDescription
referreraddress
currencyaddress

Returns

NameTypeDescription
amountuint256

currentFeePolicy()#

0x89a69bd8 · view · view

Returns the policy terms new launches snapshot immutably.

Live policy. A launch freezes a copy of this at creation, so an existing launch is unaffected by later changes.

Returns

NameTypeDescription
arg0(address,uint16,uint16,uint16,uint16,uint16)

pendingReferral(address,address)#

0xd85b2777 · view · view

Parameters

NameTypeDescription
referreraddress
currencyaddress

Returns

NameTypeDescription
amountuint256

sweepPoolFees(bytes32,uint256)#

0xebe51768 · nonpayable · The fee-sweep operator, or the pool's creator.

Converts any pending memecoin-denominated fee into the pool's quote currency against the pool's own liquidity, then splits the combined quote-currency total between protocol and creator using the live policy, exactly mirroring the bonding curve's own sweep. The trusted sweep operator is required whenever the sweep would execute an internal conversion. The creator may still distribute already-quoted fees when no internal swap is needed.

If any memecoin-denominated fee is pending, only the operator may call and minConversionQuoteOut must be non-zero — the sweep converts inventory against the pool's own liquidity and needs a slippage bound.

Parameters

NameTypeDescription
poolIdbytes32
minConversionQuoteOutuint256

Other functions#

SignatureSelectorMutability
acceptOwnership()0x79ba5097nonpayable
afterAddLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),int256,int256,bytes)0x9f063efcnonpayable
afterDonate(address,(address,address,uint24,int24,address),uint256,uint256,bytes)0xe1b4af69nonpayable
afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)0x6fe7e6ebnonpayable
afterRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),int256,int256,bytes)0x6c2bbe7enonpayable
afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)0xb47b2fb1nonpayable
beforeAddLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)0x259982e5nonpayable
beforeDonate(address,(address,address,uint24,int24,address),uint256,uint256,bytes)0xb6a8b0fanonpayable
beforeInitialize(address,(address,address,uint24,int24,address),uint160)0xdc98354enonpayable
beforeRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)0x21d0ee70nonpayable
beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)0x575e24b4nonpayable
factory()0xc45a0155view
feeEscrow()0xc4b7de97view
feeSweepOperator()0x8a36a6bbview
getHookPermissions()0xc4e833cepure
hookFeeBps()0xea26abcfview
launches(bytes32)0xad091230view
maxInternalPriceImpactBps()0x90addc1eview
owner()0x8da5cb5bview
pendingCreatorTax(bytes32,address)0xc8eaa792view
pendingFees(bytes32,address)0x359b4f30view
pendingOwner()0xe30c3978view
poolManager()0xdc4c90d3view
protocolFeeRecipient()0x64df049eview
protocolFeeShareBps()0x9040f866view
referralDiscountBps()0x30ab6943view
referralRegistry()0x4e627e62view
referralShareBps()0x47c9bc2dview
registerPool((address,address,uint24,int24,address),address,address,uint16,(address,uint16,uint16,uint16,uint16,uint16))0x302511ddnonpayable
renounceOwnership()0x715018a6pure
rescuePoolFees(bytes32)0x5cbe8117nonpayable
setCreatorFeeRecipient(bytes32,address)0xed8ef7a3nonpayable
setFactory(address)0x5bb47808nonpayable
setFeeSweepOperator(address)0x54faf9c3nonpayable
setHookFeeBps(uint256)0xbfe7af83nonpayable
setMaxInternalPriceImpactBps(uint256)0xb89eddabnonpayable
setProtocolFeeRecipient(address)0xe521cb92nonpayable
setProtocolFeeShareBps(uint256)0xfc75e481nonpayable
setReferralDiscountBps(uint256)0x98da62d5nonpayable
setReferralRegistry(address)0x6a79115fnonpayable
setReferralShareBps(uint256)0xd07e995bnonpayable
transferOwnership(address)0xf2fde38bnonpayable
unlockCallback(bytes)0x91dd7346nonpayable

Events#

Eventtopic0
CreatorFeeRecipientUpdated(bytes32,address,address)0xb45e6b72a7de9a2077babe9717744436f3880e114099956ca85f91a77469a532
FactorySet(address)0x1edf3afd4ac789736e00d216cd88be164ddcef26a6eedcc30cdb0cb62f3741b1
FeeSweepOperatorUpdated(address)0xae994ca926e252e299c3df7516cb609272a57bf80b0e0715297e55939f873420
HookFeeBpsUpdated(uint256)0xaea8b8d37d8110dd00c418d9c1c268f0fbadacb802c284b71a1777e411cd965a
HookFeeCollected(bytes32,address,uint256,uint256)0xc532c43b3423e14ef72748f1c8291238829ca0af8ba9b67975ad1483485a4b4d
MaxInternalPriceImpactUpdated(uint256)0x6968b68c1fb468c8b257b012290bf803a6a6d7e79468e0326050724f7573cf01
OwnershipTransferred(address,address)0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0
OwnershipTransferStarted(address,address)0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700
PoolConversionSkipped(bytes32,uint256)0xeed2d18eb96f3c2cb8c7b6993512a506c170e17d29355f2d7a0d5961f338de09
PoolFeesRescued(bytes32,address,uint256,uint256)0x0fbb28f9c335f55dcc5cc19e595ab55f9e6a0fd1b58ad77be3a98f99901daaff
PoolFeesSwept(bytes32,uint256,uint256)0x2b33b68d948eb789fd57906bde3dc24d9f748c1df9b98d7359910f6aa1c06e2f
PoolRegistered(bytes32,address,address,address)0x01bf263a1db1652580721573296e1a1fa70b3d4c87f61d02a69c4e1109d2d573
ProtocolFeeRecipientUpdated(address)0xc1b5345cce283376356748dc57f2dfa7120431d016fc7ca9ba641bc65f91411d
ProtocolFeeShareUpdated(uint256)0x4d1fc9430e27afb14db15169fd1c79e8b51773302919ac8c049f1c41995e380b
ReferralDiscountUpdated(uint256)0xe0f45d08835a6839e8d2327d73ee817a6da7276c4776e77abe76eaa524bc92ef
ReferralFeeAccrued(bytes32,address,address,uint256)0x7ca75a36687fd0a9628cbb8d737989015c0e5236d128a986b078ed14a030fe81
ReferralFeeClaimed(address,address,uint256)0x646dbd2d0dbd68fc66a49d8c448dd995f308238033d47b3c6122f637b331bfdb
ReferralRegistrySet(address)0xcf7381fd801bfc0e3e6a57a711e8165131a80c69051919ee96c9896cd87c0c11
ReferralShareUpdated(uint256)0x7c13f976b8efb8331f00ce07146b8270d065e3789f2eabeab837c72ca942ad61

Errors#

ErrorSelector
AlreadyRegistered()0x3a81d6fc
AlreadySet()0xa741a045
HookNotImplemented()0x0a85dc29
InexactQuoteTransfer(address,uint256,uint256)0x197001d6
InternalSwapRequiresOperator()0x31cdb504
InvalidBps()0xc6cc5d7f
InvalidPoolKey()0xc256622b
MinimumOutputRequired()0x3672d25f
NotFactory()0x32cc7236
NotFeeSweepOperator()0x8d42130c
NothingToRescue()0x00f6b210
NotPoolManager()0xae18210a
OwnableInvalidOwner(address)0x1e4fbdf7
OwnableUnauthorizedAccount(address)0x118cdaa7
OwnershipCannotBeRenounced()0x2fab92ca
ReentrancyGuardReentrantCall()0x3ee5aeb5
SafeCastOverflowedIntToUint(int256)0xa8ce4432
SafeCastOverflowedUintToInt(uint256)0x24775e06
SafeERC20FailedOperation(address)0x5274afe7
SlippageExceeded(uint256,uint256)0x71c4efed
UnknownPool()0xf7139e33
ZeroAddress()0xd92e233d

FociV2FeeEscrow#

0xcecCFebAcaDCd9404Ae70b160305Af07D9760A46

Functions an application calls#

balanceOf(address)#

0x70a08231 · view · view

Returns the claimable native ETH balance for recipient.

Parameters

NameTypeDescription
recipientaddress

Returns

NameTypeDescription
arg0uint256

balanceOfToken(address,address)#

0xf59e38b7 · view · view

Returns the claimable balance of token for recipient.

(account, token). Read this rather than an indexer if you want on-chain truth for a claim button.

Parameters

NameTypeDescription
recipientaddress
tokenaddress

Returns

NameTypeDescription
arg0uint256

claim()#

0x4e71d92d · nonpayable · Pull-only, msg.sender.

Pays out the caller's entire claimable native ETH balance.

Native-asset balance. Unreachable unless a launch quotes in the native asset, which no approved pair token does.

Returns

NameTypeDescription
amountuint256

claimToken(address)#

0x32f289cf · nonpayable · Pull-only — claims the balance of msg.sender. You cannot claim for someone else.

Pays out the caller's entire claimable balance of token.

The escrow holds ONE balance per (recipient, token). It does not distinguish creator fees from referral fees — that split is attribution derived off-chain from events — so this withdraws both at once. Fees on Arc are the 6-decimal USDC ERC-20, so this is the path, not the native claim().

Parameters

NameTypeDescription
tokenaddress

Returns

NameTypeDescription
amountuint256

Reverts

  • NoBalance — nothing accrued for you in that token

Other functions#

SignatureSelectorMutability
claim(uint256)0x379607f5nonpayable
claimToken(address,uint256)0x1698755fnonpayable
credit(address)0xd5d44d80payable
creditToken(address,address,uint256)0x09ad4dd9nonpayable

Events#

Eventtopic0
Claimed(address,uint256)0xd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a
ClaimedToken(address,address,uint256)0xdbc1ea3a8459e4c7e11fb385b52bbb5cc8c8ab85eec5d883ac9aa78c171f5141
Credited(address,address,uint256)0x4e45da441832cf53bdaa69235704fc0575e68210f459ee1562911024b12967d5
CreditedToken(address,address,address,uint256)0x5d104c62f50449fadfe6f4013c8f36588d32737f94b5ac9b83ddad33b3e1ffdf

Errors#

ErrorSelector
InsufficientBalance(uint256,uint256)0xcf479181
NoBalance()0xc2caa2a6
ReentrancyGuardReentrantCall()0x3ee5aeb5
SafeERC20FailedOperation(address)0x5274afe7
TransferFailed()0x90b8ec18
ZeroAddress()0xd92e233d

FociV2ReferralRegistry#

0xEB286974C35d2741B0fe9b2a1Cd41E53d06aE406

Functions an application calls#

referrerOf(address)#

0xd21cacdf · view · view

The permanent referrer of each user, or the zero address if they have never been referred. Read by every curve on every trade.

Parameters

NameTypeDescription
useraddress

Returns

NameTypeDescription
referreraddress

setReferrer(address)#

0xa18a7bfc · nonpayable · Self-service — binds msg.sender.

Claims a referrer for the caller before their first trade.

Reverts rather than no-ops on an existing binding: someone calling this directly asked for a specific outcome and should be told it did not happen, where a trade merely carrying a stale referrer should still settle.

Permanent and never rewritten. Bind before trading, or pass the referrer to buy instead.

Parameters

NameTypeDescription
referreraddress

Reverts

  • AlreadyReferred
  • SelfReferral
  • ReciprocalReferral
  • ZeroAddress

Other functions#

SignatureSelectorMutability
bindFor(address,address)0x620e206cnonpayable
factory()0xc45a0155view
memeHook()0x6651812cview

Events#

Eventtopic0
ReferrerBound(address,address,address)0x5b6dcb011725a9616ecced5408efb270f5e20477283b63e06c8b4eb0b4da4296

Errors#

ErrorSelector
AlreadyReferred()0x7aabdfe3
NotAuthorizedBinder()0xbe447ef2
ReciprocalReferral()0xb6ea0b01
SelfReferral()0x55e8f70e
ZeroAddress()0xd92e233d

FociV2LaunchLocker#

0xe047D0F0ce0dD600732793762B1f1929Adc5015d

Other functions#

SignatureSelectorMutability
acceptOwnership()0x79ba5097nonpayable
factory()0xc45a0155view
isLocked(address)0x4a4fbeecview
lockedPositions(address)0xfa22143dview
lockedTokenSupply(address)0x732e78e4view
lockPosition(address,uint256)0x292d5732nonpayable
lockTokenSupply(address,uint256)0xb8a0d7abnonpayable
onERC721Received(address,address,uint256,bytes)0x150b7a02view
owner()0x8da5cb5bview
pendingOwner()0xe30c3978view
positionManager()0x791b98bcview
renounceOwnership()0x715018a6pure
setFactory(address)0x5bb47808nonpayable
transferOwnership(address)0xf2fde38bnonpayable

Events#

Eventtopic0
FactorySet(address)0x1edf3afd4ac789736e00d216cd88be164ddcef26a6eedcc30cdb0cb62f3741b1
OwnershipTransferred(address,address)0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0
OwnershipTransferStarted(address,address)0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700
PositionLocked(address,uint256)0x2cabb2a2973327d5863ceb4707e9441851243897e86d587ee35943599752eb54
TokenSupplyLocked(address,uint256)0xaf33c4aba92959b3e7ddc83ab728938262da159a6c05ca836f6c46f9bcb2c740

Errors#

ErrorSelector
AlreadyInitialized()0x0dc149f0
NotFactory()0x32cc7236
NotPositionManager()0x20fdc658
OwnableInvalidOwner(address)0x1e4fbdf7
OwnableUnauthorizedAccount(address)0x118cdaa7
OwnershipCannotBeRenounced()0x2fab92ca
PositionAlreadyLocked()0xfe3099b6
PositionNotHeld()0x6b49c94a
SafeERC20FailedOperation(address)0x5274afe7
ZeroAddress()0xd92e233d

FociV2LaunchDeployer#

0x5C5c202271E1300bD5Ce43A4F5C1cEA8efd57B63

Functions an application calls#

predictLaunchAddresses((address,address,address,address,(address,uint16,uint16,uint16,uint16,uint16),address,uint256,uint256,uint256,uint256,uint256,bytes32,string,string,string,string,(string,string,string,string,string)))#

0xe6a900b5 · view · view

Returns the addresses deployLaunch would produce for params, without deploying anything.

Lets a caller confirm that a launch it has not seen confirmed yet will land where it expects, and lets the launch path be checked for a salt the creator has already used. The token is derived from the curve because the curve's address is one of the token's constructor arguments, so the pair has to be computed in deployment order.

Computes the CREATE2 token and curve addresses before you send. Use it to mine a vanity address, and to check for an existing deployment — a reused salt reverts with the unhelpful FailedDeployment.

Parameters

NameTypeDescription
params(address,address,address,address,(address,uint16,uint16,uint16,uint16,uint16),address,uint256,uint256,uint256,uint256,uint256,bytes32,string,string,string,string,(string,string,string,string,string))

Returns

NameTypeDescription
tokenaddress
curveaddress

Other functions#

SignatureSelectorMutability
deployLaunch((address,address,address,address,(address,uint16,uint16,uint16,uint16,uint16),address,uint256,uint256,uint256,uint256,uint256,bytes32,string,string,string,string,(string,string,string,string,string)))0x84b2d5c6nonpayable
factory()0xc45a0155view
referralRegistry()0x4e627e62view

Errors#

ErrorSelector
Create2EmptyBytecode()0x4ca249dc
FailedDeployment()0xb06ebf3d
InsufficientBalance(uint256,uint256)0xcf479181
MetadataTooLong()0x85b8e2f4
NotFactory()0x32cc7236
ZeroAddress()0xd92e233d

FociV2GraduationExecutor#

0x02e7d818080bf85EEB7191536A768B0CFdB38D5D

Other functions#

SignatureSelectorMutability
factory()0xc45a0155view
locker()0xd7b96d4eview
mintFullRangePosition(address,(address,address,uint24,int24,address),int24,int24,uint160,uint256,uint256,address,address,address)0xcbba1910payable
permit2()0x12261ee7view
positionManager()0x791b98bcview

Events#

Eventtopic0
GraduationDustRetained(address,address,uint256)0x667636bce2491e3f246c8b4ec1f4ca0be227dfa611d0575c59f5949283b433c1
GraduationDustSwept(address,address,uint256)0x80a5a2ff8b8c5533e5862e4e161bbcade9af6fd9d67bef56a590b062107f027f

Errors#

ErrorSelector
FeeTransferFailed()0x4033e4e3
MintAmountOverflow()0xeee66814
NotFactory()0x32cc7236
SafeERC20FailedOperation(address)0x5274afe7
SlippageExceeded(uint256,uint256)0x71c4efed
ZeroAddress()0xd92e233d