Docs
Open app
REARCTOR / PROTOCOL13 min read

Smart contracts

Source-aligned guide · Updated 16 September 2026

On this pageContract architectureValues and transaction conventionsFactory APIPool APIFee vault APIHook and canonical identityProtocol treasury API and permissionsEvents and indexing semanticsPermission summary

Rearctor creates a separate token, pool and fee vault for each reaction. A shared factory registers the launches; a shared hook enforces their canonical V4 pool settings. An optional dedicated protocol treasury accounts for the protocol’s fee receipts and manual spending.

Deployment status: Arc Testnet is connected to live Rearctor deployments; Mainnet remains a preview. The network selector separates the optimized Testnet deployment from the previous immutable deployment. See Network and deployment status for exact identities. Existing Arc or Uniswap infrastructure addresses are not Rearctor factory, hook, vault or treasury addresses.

Contract architecture#

Contract Responsibility Custody or authority
RearctorLaunchpad Validate launches, create and initialize clones, register the hook configuration, collect seed and optional dev-buy input Owner sets up the hook, updates the minimum seed for future launches and may graduate eligible pools early; no per-launch fee or principal control
RearctorToken Standard 18-decimal ERC-20; initial one-billion-token mint; holder burning Initial supply goes to its pool; no public additional mint or transfer tax
RearctorPool Curve trading, automatic or owner-directed migration, canonical V4 routing, block-opening price guard and locked liquidity Holds curve assets, then owns the native V4 position; no principal withdrawal
RearctorFeeVault Account for and distribute that project’s fees Fixed beneficiaries; separate buyback and liquidity budgets
RearctorHook Bind each canonical key and apply directional V4 fees Initialization and LP additions restricted to its registered pool
RearctorPriceGuard Block-opening execution reference and shared budget interval Abstract implementation inherited by the pool; not a separate asset custodian
RearctorTreasury Account for protocol receipts, operations, conversions and manual Rearc burns Separate owner controls treasury spending
RearctorHookDeployer Deploy a hook at a CREATE2 address with the required permission bits Deployment helper; no later administrative control

Token, pool and vault implementations are disabled for direct initialization. The factory creates minimal clones and initializes them within the launch transaction. Their implementation target is fixed; these are not upgradeable proxy deployments. The factory’s implementation, manager, quote and treasury addresses are fixed at construction; the hook is bound once before launches can proceed.

The older legacy implementation is not the architecture documented here. A production deployment must explicitly use the reviewed Rearctor contract family.

Values and transaction conventions#

Token amounts use 18 decimals; USDC quote amounts use 6. deadline is a Unix timestamp in seconds. Fee rates and creator-selected allocation shares are basis points, with 10,000 representing 100%. See Tokenomics for the distinction between a trading fee and a share of collected fees.

Successful trades require a nonzero output minimum. Approve the correct input ERC-20 to the canonical pool before direct trading. A launch requires approval to the factory for seed plus any optional dev-buy input. Expired transactions revert, and a quote does not reserve the price or guarantee inclusion.

Factory API#

Creation inputs#

createLaunch(LaunchParams p, FeeConfig fees) returns (token, pool, vault).

LaunchParams contains:

Field Meaning
name, symbol Nonempty token name and symbol; maximum 64 and 12 UTF-8 bytes
description Up to 1,024 bytes
image Up to 512 bytes
website, socialX, telegram Up to 256 bytes each
seed At least the current owner-set minimum (1 USDC initially), strictly below 5,042 USDC
devBuy Optional USDC purchase input; zero disables the purchase
devBuyMinOut Minimum token output for a nonzero dev buy
deadline Latest allowed block timestamp for creation and its purchase

Contract metadata checks enforce byte lengths, not verified ownership of a name, website or social account. Names and symbols can be duplicated. The application may apply stricter formatting than the contract.

FeeConfig contains buyBps, sellBps, creatorBps, buybackBps, liquidityBps and creatorWallet. Each directional fee is 100–1,000 bps. The three allocation fields total 10,000 bps and apply to the 70% remaining after the protocol allocation. The creator wallet must not be a rejected system address.

Reads and setup#

Method Semantics
launchCount() Number of registered launches
getLaunches(offset, limit) Returns metadata and immutable fee settings; limit is capped at 100
isPool(pool) Canonical factory registration check
isSystemAddress(account) Addresses rejected as creator beneficiaries
previewLaunchBuy(seed, amount, buyBps) Hypothetical curve purchase at initialization; returns output, fee and actual spend
previewDevBuy(seed, amount, buyBps) Same preview, additionally enforcing the 20% token cap and the requirement to leave the curve open
initializeHook(hook) Owner-only, one-time binding; validates the factory and manager relationship
quoteToken(), treasury(), manager(), hook() Deployment identity and routing configuration
minimumSeed(), graduationThreshold(), minimumFeeBps(), maximumFeeBps(), maximumDevBuyTokens() Current minimum seed and fixed economic limits exposed on-chain

An owner can transfer the factory owner role through the inherited two-step ownership flow. Renouncing ownership is disabled. After hook setup, that owner cannot change a launch’s fees, replace its hook or withdraw its principal. On updated pools it can request early graduation, subject to the pool’s eligibility, deposit and dead-transfer limits.

Pool API#

Trading and quoting#

Method Semantics
buy(amount, minOut, deadline) Buy with USDC; uses the curve before graduation and the stored canonical V4 key afterward
sell(amount, minOut, deadline) Sell project tokens through the corresponding current stage
quoteBuy(amount) Curve-only output and USDC fee
previewBuy(amount) Curve-only output, fee and capped actual USDC spend
maxCurveBuy() Gross USDC input required to reach the curve target
quoteSell(amount) Curve-only USDC output and fee; returns zero if real USDC backing is insufficient
quoteBuyback(amount) Curve-stage fee-free project buyback preview; does not establish price-guard eligibility
getPoolKey(), poolId() The registered V4 key and its ID
sqrtPriceX96() V4 square-root price in currency1/currency0 base-unit orientation

quoteBuy, previewBuy, maxCurveBuy, quoteSell and quoteBuyback return zero once graduated. This is not a trading shutdown. Use the matching V4 Quoter and getPoolKey() after graduation.

For a V4 exact-input quote, use quoteExactInputSingle with the canonical key, input direction determined by its currency ordering, the amount in input base units and empty hook data. Verify that the Quoter’s poolManager() matches the pool’s manager. The application uses amounts below 2^127 for the signed V4 input-delta path.

Do not choose a quote path solely from an indexed graduated value. The application reads fresh canonical state at a pinned block, validates the pair, vault, manager and hook, and requotes after approvals. It never lowers the originally accepted absolute minimum. The contract makes the final routing decision using its state at execution.

Fees, budgets and guard reads#

Method Caller and effect
collectV4Fees() Anyone, after graduation; realizes earned LP fees into the project vault without removing principal
claimFees() Claims the caller’s vault entitlements; does not withdraw pool reserves
executionPriceState() Returns opening tick and current spot tick; historical TWAP storage is absent in the latest revision
maxBudgetInput(buySide) Maximum input for a guarded swap: 0.5% of the relevant real or locked-position input reserve
guardedMinimum(buySide, amount, feeFree) Calculates the guard floor for valid, bounded input after the block-opening deviation checks
buyWithPriceGuard(...), sellWithPriceGuard(...) Treasury-only guarded variants; the caller’s minimum can only tighten the guard floor
previewFeeLiquidity(tokenAmount, quoteAmount) Estimates the quantities a V4 LP addition can use; not an execution guarantee
previewLiquidityRebalance(tokenAmount, quoteAmount) Computes direction and a bounded excess-side amount at the guarded block-opening price

executeBuyback, rebalanceFeeLiquidity and addFeeLiquidity are vault-only execution paths. buyFromFactory is factory-only. recordPrice is hook-only. unlockCallback is PoolManager-only and interprets the pool’s internally generated actions; it is not an arbitrary public router.

The graduated flag is permanent. After migration, tokenReserve and quoteReserve are cleared because custody has moved to V4. They are not a measure of V4 liquidity. Read the canonical V4 state alongside lockedLiquidity, migratedToken, migratedQuote, the locked remainder counters and deadTokenRemainder. The last field records the manual-graduation transfer; it is not a reduction in token totalSupply.

Manual graduation interface#

Function Meaning
manualGraduationEnabled() Manual-graduation capability marker; older versions may lack the dead-transfer extension
DEAD_ADDRESS() Fixed destination for the manual-graduation token remainder
deadTokenRemainder() Accounted tokens sent to dead at manual graduation; excludes other transfers to dead
previewGraduation() (usedToken, usedQuote, remainderToken, remainderQuote, eligible); on the manual path the token remainder is sent to dead and the quote remainder stays locked
manualGraduate(minToken, minQuote, maxDeadTokens, deadline) Current factory owner only; next-block restriction; early reserves only; at least 200 million tokens and 99% of accounted USDC deposited; token transfer to dead must not exceed the caller maximum

The caller cannot redirect assets or change fees. Only the accounted token remainder is transferred to 0x000000000000000000000000000000000000dEaD; donations, fee budgets and V4 deposits are excluded. This transfer does not invoke burn or reduce totalSupply. Any quote remainder stays locked. Automatic migration retains its small remainders in the pool.

Minimum deposits must be positive; maxDeadTokens may be zero to forbid any nonzero remainder transfer. Deposit shortfalls, a remainder above this cap or an expired deadline revert the whole migration. Accepted factory ownership transfers change this authority. Old immutable clones require a new deployment to support this method and its getters; manualGraduationEnabled() alone does not identify the extension.

Fee vault API#

Method or read Semantics
claimFor(recipient) Anyone can trigger both-asset claims; funds go only to the specified beneficiary’s accrued entitlement
processBuyback(minOut, deadline) Anyone can process the available project budget, with the pool clipping USDC purchases to its guard/curve limits; acquired and already budgeted project tokens are burned
processLiquidity(minToken, minQuote, deadline) Anyone, after graduation; reinvest available paired budgets into the same locked position
rebalanceLiquidity(minOut, deadline) Anyone, after graduation; swap a calculated portion of the excess liquidity asset through the canonical pool
totalAccrued(asset) Cumulative fees recognized for this asset
allocated(asset, bucket) Cumulative entitlement; bucket 0 protocol, 1 creator, 2 buyback, 3 liquidity
claimable(asset, beneficiary) Beneficiary’s currently unclaimed fee balance
protocolClaimed(asset) Cumulative protocol-only receipts used by the treasury
buybackBudget(asset), liquidityBudget(asset) Unspent balances of the separate project budgets
totalBuybackQuoteSpent(), totalBuybackTokensBurned(), buybackExecutions() This vault’s cumulative buyback counters
distributionHash() Binding of the project addresses, beneficiaries and allocation configuration

Only the registered pool can call accrue, and only for the configured quote or token asset. Direct transfers to the vault are not automatically recognized as fees or spendable budgets. There is no general vault rescue function that turns unaccounted donations into withdrawable revenue.

No administrator is needed to call the three project-budget processing methods. Permissionless callers cannot choose their own destination or take the output. Processing can still fail because of an uninitialized price reference, the price guard, unbalanced amounts, output minima or token transfer restrictions.

Hook and canonical identity#

The hook’s required address flags are 0x2880: beforeInitialize, beforeAddLiquidity and beforeSwap. Its key uses the sorted token/quote addresses, dynamic-fee flag 0x800000, tick spacing 200 and the hook itself.

Only the factory can register a configuration, and an existing pool ID cannot be overwritten. Registration cross-checks the pool, vault and distribution hash. Only PoolManager can invoke the hook callbacks. Initialization and LP additions additionally require the registered RearctorPool as sender. Swaps through this key may come through other routers, but they still invoke the hook and its directional fee logic.

Canonical validation should start from a verified factory deployment and confirm isPool, the pool’s factory, token, quote, vault, manager, hook, full getPoolKey() and poolId(). A familiar symbol or a token pair alone is not sufficient.

Protocol treasury API and permissions#

The protocol treasury has its own two-step owner role, separate from the factory’s setup role. Renouncing that role is disabled.

Method Permission and meaning
bindFactory(factory) Owner, once; validates the quote, treasury destination and compatible vault implementation
bindRearctorPool(pool) Owner, once; selects a canonical pool belonging to the bound factory as the permanent buyback target
collectProtocolFees(vaults) Anyone; validates and collects 1–50 canonical sources into the treasury
convertProtocolTokens(pool, amount, minUSDC, deadline) Owner; sell accounted protocol token receipts through their own canonical guarded pool
executeRearctorBuyback(amount, minTokens, deadline) Owner; spend up to the supplied USDC amount through the fixed target, then burn only the newly acquired tokens
withdrawOperations(amount, recipient) Owner; withdraw accounted protocol USDC for operations
withdrawProtocolTokens(asset, recipient, amount) Owner; withdraw accounted protocol token receipts without relying on a working conversion market
recoverSurplus(asset, recipient, amount) Owner; recover balance above the recorded protocol liabilities, such as donations
onProtocolFeesReceived(asset) Authenticated canonical-vault accounting callback; not an open income-crediting function

The contract’s target binding validates a canonical pool; it does not enforce the name “Rearc,” the symbol, or launch index zero. The application’s official-token verification additionally checks the first registered launch and its treasury binding. Verify both layers before treating a token as official.

A curve-stage treasury purchase can spend less than requested when it completes graduation. The current treasury records actual USDC spent, preserves the refund and burns only the newly purchased tokens. It also verifies the corresponding supply reduction. The requested maximum must still fit the treasury’s available recorded USDC and applicable pool guard checks.

Useful accounting reads include availableProtocolUSDC, totalProtocolUSDCReceived, totalUSDCFromConversions, totalOperationsUSDCWithdrawn, totalBuybackUSDCSpent, totalRearctorBurned, buybackExecutions and the per-token received, available, converted and withdrawn counters.

Events and indexing semantics#

Emitter / event What it establishes
Factory LaunchCreated(id, token, pool, creator, vault) Canonical launch identities and directory ID
Factory DevBuy(token, creator, tokensBought) The optional creation-time purchase
Pool Trade(trader, buy, amountIn, amountOut, fee) Router-level execution; curve fees are USDC, V4 fee is a configured estimate in the input asset
Pool Graduated(id, tokenAmount, quoteAmount, manual) Canonical V4 migration; automatic migration emits manual = false; owner-directed early migration emits manual = true
Pool GraduationRemainderSentToDead(address indexed recipient, uint256 amount) Accounted token remainder transferred to the fixed dead address during manual graduation; total supply unchanged; separate from fee burns
Pool V4FeesCollected(tokenAmount, quoteAmount) LP fees transferred to the vault for allocation
Hook PoolRegistered(...) Pool ID, related contracts, immutable directional rates and distribution binding
Vault FeesAccrued, Claimed, ProtocolClaimed Fee recognition, beneficiary payment and protocol-only receipt accounting
Vault Buyback(quoteSpent, tokensBurned) Project-budget execution; distinct from protocol-funded Rearc burns
Vault LiquidityRebalanced, LiquidityReinvested Budget conversion and locked-position additions
Treasury FactoryBound, RearctorPoolBound One-time source and target bindings
Treasury ProtocolFeesReceived, ProtocolTokensConverted Recorded protocol receipts and conversions
Treasury OperationsWithdrawn, ProtocolTokensWithdrawn, SurplusRecovered Owner-directed treasury outflows
Treasury ProtocolBuyback(quoteSpent, tokensBurned) The treasury’s manual Rearc purchase and burn

Use PoolManager’s Swap events filtered by the full canonical pool ID for complete V4 trade history and actual V4 fee fields. A pool’s post-graduation Trade event duplicates the corresponding swap when the pool acts as router; counting both doubles volume. External-router swaps can produce a canonical V4 Swap without a Rearctor Trade.

Similarly, the pool’s volume counter tracks its buy/sell routing paths and is not a complete count of all external-router V4 activity. Indexers need a clear graduation boundary, transaction/log identity, confirmed block coverage and reorganization handling. An external-router Swap.sender can be a router contract, not the ultimate wallet. Holder burns emit the ERC-20 burn transfer but do not increase a vault’s or treasury’s buyback counters.

Permission summary#

Users control their own trades and token burns. Anyone can create a valid launch, claim for a fixed beneficiary, collect V4 fees, execute eligible project budgets and collect protocol receipts. The factory owner establishes the initial hook, can transfer its role and can execute eligible early migration through manualGraduate. The treasury owner retains spending authority over treasury assets. No role can withdraw a project pool’s committed principal, rewrite its fee split, replace its canonical hook, mint extra project supply.

See Permissions and liquidity for contract roles and asset controls.

Adjustable minimum initial liquidity#

minimumSeed() starts at 1 USDC (1_000_000 base units). Only the current factory owner may call setMinimumSeed(uint256). The amount must be at least minimumSeedFloor() (1 USDC in the next deployment; the existing Testnet revision permits one base unit, 0.000001 USDC) and strictly below 5,042 USDC. MinimumSeedUpdated(previousMinimum,newMinimum) records each update. The deposit remains pool principal; this setting is not a protocol fee. Existing pools, fees, reserves and graduation thresholds are unaffected. Both launch previews use the current setting.

Download Markdown ↓