Reference

Contracts

Addresses and the functions you will call or read.

Current deployment#

New launches use these contracts. The app also publishes them at /deployments/4663.json.

ContractAddress
Factory0x09A8a315eDFC896F23966464C6094e0C5B913F60
Hook (curve)0xfA81233b14Cf452E9FB207DCe2980Dac18976888
MediaStore0xF349bE8F144305dBD6c9aEfc2BCe61c16F0D92F0
Links registry0xA4b353d8D4Fc2c037828Bb802930215c01772cd4
Treasury0xe36A1419b03Fbc389D615857596258F2C39fDEce
Uniswap v4 PoolManager0x8366a39cc670b4001a1121b8f6a443a643e40951

Deployed at block 64591055. The factory owner, which approves pairs, is the treasury address.

What each contract does#

Factory
Deploys tokens, opens their pools, and routes every buy and sell. Keeps the list of tokens and each token's pair.
Hook
The Uniswap v4 hook that runs each token's curve. Holds reserves, accrues tax, and pays claims.
Token
One ERC-20 per launch. Stores the media index and the holder reward pool.
MediaStore
Writes and reads media chunks.
Links registry
Stores website, X, and Telegram links per token. Only the token's creator can set them.

Previous factories#

Older tokens keep trading on their own factory and hook. The app reads all of these.

FactoryHookFeatures
0x91BaE7fEd59320947C50421647C86177f67aCEc80x3F44F6F1579b6D929C9F7ee377e669371C5368881% to 10% tax, holder payouts on trade. No launch protection.
0x56831D2521f6b4E2d5596F16a3413aEaD53CA1eb0xd4a7543935f976997f1b9331955Ab4d91EeEa888Stock and USDG pairs. Fixed 1% fee.
0x6aE2fd40414D47F025C8DeA736B62Ebd6bdf31D80x93225BB3DA3e9ACB00dE26a303eb96f9628FA888ETH pairs only. Fixed 1% fee. Early holder routing.
0x6B2e96b8d8683281309f74B6ED4668c281267fF80x064d02b8BEf6A8cBbd6B998fE692781d0214A888ETH pairs only. Fixed 1% fee.
0x5168025a7b36ac77bB0a79823A721e72174EDBfb0xB14401fa9e87145F5B73E8c7a1fC696338c32888ETH pairs only. Fixed 1% fee. Home of FIST, the first inscription.
0x7ca994edf6b718a7413F3E0044587f6331d61CeF0xb316C847284cA47aa72Db8006AD9bFCA2868e888ETH pairs only. Fixed 1% fee.
0xE8d02290F7ba43656338D5AE2ad72f5A5f54785cn/aFirst deployment. Reads revert; the app skips it.

Older hooks use an older interface. For example, curves(token) returns three fields (tokens, raised, exists) instead of five.

Pool keys#

Every Scrible pool uses:

  • fee: 0
  • tickSpacing: 1
  • hooks: the factory's hook
  • currencies sorted by address, with native ETH as address(0)

Call factory.poolKey(token) to get it. Adding liquidity always reverts.

Factory functions#

FunctionWhat it does
tokenCount()Number of tokens this factory launched.
tokens(uint256 i)Token address at index i. Oldest first.
isToken(address)true if this factory launched the token.
quoteOf(address token)The token's pair. address(0) means ETH.
approvedQuote(address)Whether a pair is open for new launches.
virtualQuoteFor(address)Virtual reserve for new launches on that pair.
buy(token, minTokens, deadline, amount)Exact-input buy. Send amount as value for ETH pairs. Approve the pair token first for others.
sell(token, amount, minQuote, deadline)Exact-input sell. Approve the token for the factory first.
launch(...)Creates a token and pool. Use the app for this.

minTokens and minQuote must be above 0. deadline is a Unix timestamp in seconds.

Hook functions#

FunctionWhat it does
quote(token, buy, input)Output for an exact input, after tax.
curves(token)tokens, raised, exists, quote, virtualQuote.
totalTaxBps(token)Tax in basis points, 100 to 1000.
fees(token), taxes(token)Unclaimed base share and extra tax.
totalFees(token), totalTaxes(token)Lifetime totals.
taxRecipient(token)Who can claim, outside holder mode.
holderMode(token)Whether tax goes to holders.
lastDistribution(token)Timestamp of the last holder payout.
treasuryOwed(quote)Treasury share waiting for claimTreasury.
claimFees(token), claimTaxes(token)Pay the recipient, or sweep to holders in holder mode.
pokeDistribution(token)Sweep to holders once 15 minutes have passed.
claimTreasury(quote)Send the treasury share. Anyone can call it.

Token functions#

FunctionWhat it does
creator(), description()Launch details.
mediaCount()Number of inscribed files.
mediaInfo(i)mime, digest, size, chunks.
readMedia(i)The full file bytes.
contractURI()ERC-7572 metadata link. May be empty.
claimableRewards(account)Holder rewards ready to claim.
claimRewards()Pays your holder rewards.
rewardToken()Reward asset. address(0) means ETH.
eligibleSupply()Tokens held outside the curve.

Read a token with ethers#

import { Contract, JsonRpcProvider, formatEther } from "ethers";

const provider = new JsonRpcProvider("https://rpc.mainnet.chain.robinhood.com", 4663);
const hook = new Contract("0xfA81233b14Cf452E9FB207DCe2980Dac18976888", [
  "function curves(address) view returns (uint256 tokens, uint256 raised, bool exists, address quote, uint256 virtualQuote)",
  "function quote(address token, bool buy, uint256 input) view returns (uint256)",
], provider);

const token = "0x36D3e02eae31F7F3846ba8893d8EB25f0a7dE515";
const c = await hook.curves(token);
console.log("tokens left", formatEther(c.tokens));

// Tokens out for a buy of 0.01 in the pair asset (18 decimals here)
const out = await hook.quote(token, true, 10n ** 16n);
console.log("buy quote", formatEther(out));

Use the hook that matches the token's factory. The example token trades against NVDA, which has 18 decimals. USDG has 6.

esc