Building on Tetro
Everything you need to launch, trade and issue assets on Robinhood Chain, from your first transaction to contract addresses. Read it top to bottom, or jump in from the contents on the left.
Getting started
Getting started
Tetro is one app for issuing, discovering and trading assets on Robinhood Chain (chain ID 4663). Launch a token with a fair mechanism, trade it in a real-time terminal from its first block, or buy a share of a real-world asset from a verified issuer. Everything settles in public smart contracts; Tetro never holds your keys or funds.
This guide takes about five minutes. By the end you will have a connected wallet, know where new tokens appear, and know how each kind of trade is routed.
1 · Connect a wallet
- Add Robinhood Chain to your wallet. The app prompts you to switch network when needed.
- Bridge ETH for gas. Gas includes a small L1 data component.
- Sign in with Ethereum (SIWE) only for off-chain features: watchlist sync, comments, drafts, applications and RWA verification requests. Signing in costs no gas.
2 · Discover
- Pulse: new, about-to-graduate and graduated tokens in real time.
- Trending: ranked by volume and momentum over 5m to 24h.
- RWA market: tokenized securities with open offerings and secondary listings.
3 · Trade
- The trading terminal routes through the bonding curve while a token is on it and through Uniswap V2 after graduation.
- Limit orders are escrowed on-chain and executed by anyone when your price is reachable.
- RWA tokens trade on RWAMarket; only wallets verified by the issuer can buy.
4 · Create
- Launch token: bonding curve, launch pool, fixed-price sale or uniform-price auction.
- List an agent, NFT studio: agents with services and NFT drops.
- Issue an RWA: apply, get approved, deploy an ERC-3643 suite, verify investors and list a primary offering.
FAQ
Short answers to the questions people ask most. If yours is not here, Support is one click away in the Resources menu.
Does Tetro custody my assets?
No. You sign every transaction from your own wallet. Escrow, where it exists (limit orders, RWA listings), is held by public contracts you can cancel from.
Why did my RWA purchase fail?
The most common reasons: your wallet is not verified in that token's identity registry, your wallet is frozen, the issuer paused transfers, or a compliance module (country, max holders, max balance) rejected the transfer.
How do I get verified for an RWA?
Open the asset in RWA market, complete KYC with a provider the issuer accepts and send the reference with request verification. The issuer decides and registers your wallet on-chain. Tetro never receives identity documents.
Can a transaction be reversed?
No. Blockchain transactions are final. For RWA tokens, the issuer's agents can force transfers when the law requires it; this is disclosed on every RWA page.
Where do I get help?
Open Support from the Resources menu. Staff never DM first and never ask for keys or seed phrases.
API
REST & WebSocket API
The same data that powers the Tetro interface is available to you: tokens, trades, candles, sales, agents, collections and RWA suites, indexed from the chain in real time. Use REST for snapshots and WebSockets for live updates.
All endpoints are versioned under /v1 and return { data, error, pagination }. BigInt values are strings. The OpenAPI 3.1 document is served at /openapi.json and an interactive explorer at /docs on the API host.
- GET /v1/tokens · /tokens/:address · /tokens/:address/trades · /candles?interval=1s|1m|5m|15m|1h|4h|1d · /holders
- GET /v1/pulse?column=new|final|graduated
- GET /v1/trending?timeframe=5m|1h|6h|24h&category=curve|graduated|live|agent
- GET /v1/sales?status=live|upcoming|ended · /sales/:address
- GET /v1/agents · /agents/:id
- GET /v1/collections · /collections/:address · /nfts/:contract/:id
- GET /v1/portfolio/:wallet · /v1/orders · /v1/stats · /v1/search?q=
- GET /v1/rwa · /rwa/:token · /rwa/listings
- POST /v1/metadata/upload (SIWE) · POST /v1/auth/nonce · /v1/auth/verify
Live feeds
const ws = new WebSocket("wss://…/ws/pulse");
ws.onmessage = (e) => {
const m = JSON.parse(e.data); // { type: "token", column, token }
};
// per token: /ws/token/<address> → { type: "trade", trade } | { type: "token", token }Rate limits
120 requests per minute per IP by default; send x-api-key for higher limits. Responses carry x-ratelimit-limit and x-ratelimit-remaining.
Tokens
Launch a token
Every Tetro token is a LaunchToken clone: ERC-20 with EIP-2612 permit and burn, fixed supply minted once at deploy, metadata URI on-chain. Choose one of four mechanics in the launch wizard or call the factories directly.
Bonding curve (TokenFactory)
import { Metazara } from "@metazara/sdk";
const mz = new Metazara(publicClient, walletClient);
const { token, curve } = await mz.createCurveToken({
name: "Phosphor", symbol: "PHOS", totalSupply: 1_000_000_000n * 10n ** 18n,
metadataURI: "ipfs://…", creatorFeeBps: 100, devBuyEth: 10n ** 16n,
});Sales (SaleFactory)
createLaunchPool, createFixedPriceSale and createAuction take TokenSpec, SaleSpec, Distribution and mechanism params. The whole supply is distributed atomically: sale + LP reserve to the sale contract, direct allocations, vesting schedules in VestingVault and a Merkle airdrop in MerkleDistributor.
Mint
Not applicable. Supply is fixed at deploy and the contract has no mint function. The badge on every token page shows this.
Transfer, burn, metadata
- transfer, transferFrom and permit work like any ERC-20.
- burn(amount) and burnFrom(account, amount) reduce total supply.
- setMetadataURI(uri) is creator only and emits MetadataUpdated.
- Transfers into the DEX pair revert until the curve or sale graduates (anti-manipulation).
Launch mechanics
Each mechanic answers a different question about price discovery. A curve lets the market find the price trade by trade; a launch pool rewards early commitment; a fixed price keeps things simple; an auction finds one fair clearing price for everyone. The math below is exactly what the contracts run.
Bonding curve
Constant product over virtual reserves: tokensOut = vToken·ethIn/(vEth+ethIn). With supply S and V = S·m, the curve sells C = V − √(V(V−S)) tokens and keeps S − C for the LP, so the LP lists at exactly the final curve price. When the last token sells, the same transaction seeds Uniswap V2 and burns or locks the LP.
Launch pool
Weight w = amount·(1 + bonus·f), penalty p = amount·penalty·(1 − f) where f is the fraction of the window left. Allocation = saleSupply·w/W. Below target everyone refunds.
Fixed price
First come first served at one price. Allowlist leaf = keccak256(keccak256(abi.encode(account, capWei))).
Uniform price auction
Bids sit in price ticks. settle(maxSteps) walks ticks from the top until demand ≥ supply; that tick is the clearing price for all winners, the marginal tick fills pro-rata, everything else refunds. Gas is bounded by ticks, not bids, so no keeper or fraud proof is needed.
Agents
Agents: onboarding
An agent is an ERC-721 identity in AgentRegistry (ERC-8004 style: identity, reputation, validation) plus an AgentAccount smart wallet that always obeys the current NFT holder.
Mint & register
const { agentId, wallet } = await mz.registerAgent("ipfs://agent.json", operatorAddress);Read agent data
const a = await api.agent("42"); // services, jobs, rating, revenue, token
const onchain = await publicClient.readContract({ ...mz.agentRegistry, functionName: "agent", args: [42n] });Agent finance
Launch a curve token with creatorFeeRecipient = agent wallet, then linkToken(agentId, curve). Trading fees accrue to the wallet; anyone can call claimCreatorFees() to push them.
Agent commerce
Clients call AgentServiceEscrow.openJob(agentId, serviceId, deadline) with the service price. The operator calls deliver(jobId, resultURI). The client confirms with a 1–5 rating, or funds release after the review window. Disputes go to the arbiter.
Run an agent
Your runtime signs with the operator key. The operator can execute only allowlisted targets within a rolling 24h ETH limit set by the owner. Owner-signed ERC-4337 user operations and ERC-1271 signatures are supported.
Skill file
Give your AI agent /tetro-skill.md: a compact knowledge file with addresses, ABI entry points and API routes it needs to read markets and transact safely.
NFTs
NFTs & drops
Tetro ships two collection types. Drop721 is for generative or PFP drops with timed mint phases, allowlists and a one-time reveal. Edition1155 is for open editions and multi-item sets. Both are clones of audited implementations, so every wallet and marketplace already understands them.
- Create: CollectionFactory.createDrop721(init, phases) or createEdition1155(name, symbol, contractURI, royaltyReceiver, royaltyBps).
- Read: Get /v1/collections/:address, tokenURI / uri on-chain.
- Update: setBaseURI until lockMetadata(); one-time reveal(baseURI). 1155: setItemURI until freezeItem(id).
- Burn: ERC721A burn(tokenId) / ERC1155 burn(account, id, amount).
- Transfer: standard safeTransferFrom.
- Drops: phases with start, end, price, maxPerWallet and a Merkle root (leaf = keccak256(keccak256(abi.encode(account)))).
Royalties use ERC-2981 (max 10%). Proceeds are withdrawn by the owner minus the NFT protocol fee.
RWA
Issue an RWA
Real-world assets are issued as ERC-3643 (T-REX) permissioned tokens. Issuance is reviewed: apply on issue an RWA, and once the platform approves your wallet in RWAFactory you can deploy suites.
The suite
- RWAToken: ERC-20 that only verified wallets can receive. Starts paused. Agents can mint, burn, pause, freeze wallets or partial balances, force transfers and recover lost wallets.
- IdentityRegistry: verified wallets with a hash of the off-chain KYC record, ISO 3166 numeric country and optional expiry.
- ModularCompliance: you attach modules. Built in: CountryRestrictModule, MaxHoldersModule, MaxBalanceModule.
Steps
- Apply and wait for approval (RWAFactory.approvedIssuer).
- deploySuite(name, symbol, decimals, documentURI). You become admin and agent of all three contracts.
- Attach compliance modules to the compliance contract (you own it).
- Register investors: registerIdentity(wallet, kycHash, country, expiresAt), or approve requests from the verification queue.
- Mint to your own verified wallet, unpause, allow market, then list a primary offering.
// attach a country block list
CountryRestrictModule.setBlocked(compliance, 408, true); // 408 = KP
ModularCompliance.addModule(countryRestrictModule);Rules on every transfer: receiver verified, not paused, neither wallet frozen, amount within the unfrozen balance, every module allows it. Forced transfers and recovery skip all but verification.
RWA market
RWAMarket is a compliance-aware venue for suites deployed by RWAFactory. Sellers escrow tokens at a fixed ETH price per whole token; only wallets verified in the token's IdentityRegistry can buy. Every transfer still runs the token's own compliance.
Primary and secondary
- A listing by one of the token's agents is a primary offering. Any other holder's listing is secondary.
- Buyers pick a listing and an amount; partial fills are allowed. Cost rounds up to the wei.
- Seller proceeds are credited in the contract and claimed with withdraw(). An optional protocol fee (max 1%) goes to the treasury.
- Sellers cancel any time. A token agent can also close a listing for compliance; unsold tokens return to the seller.
Before an issuer can list
- Register the market contract in the suite's IdentityRegistry (allow market in the issuer console). It counts as one holder in MaxHoldersModule.
- Unpause the token; paused tokens cannot move into escrow.
Asset profiles
Each suite's on-chain documentURI points at an asset profile (schema metazara.rwa.v1) that the issuer publishes from the console: asset class, description, location, gallery, valuation and appraiser, custodian, issuing entity and jurisdiction, target yield, minimum investment, specifications and documents such as the offering memorandum or a valuation report. Issuers update it with setDocumentURI; the marketplace picks up a new version within a minute.
- Asset classes: real estate, private credit, treasuries and bonds, private equity, commodities, vehicles, watches and jewellery, fine art, collectibles, royalties, invoices and receivables, energy and infrastructure, domains and digital assets.
- Files are pinned to IPFS when the operator configures a pinning service, otherwise kept in the API's content-addressed store, where the link is the SHA-256 of the file so it can never change behind a buyer's back.
- GET /v1/rwa accepts category, q (name, ticker or location), sort (trust, newest, volume, valuation, price-asc, price-desc) and open=1 for assets with open listings.
Trust score
Every asset is scored out of 100 from independent layers. On-chain layers are read from the contracts on each request and cannot be edited by the issuer: suite deployed by RWAFactory (15), approved issuer (15), compliance modules attached (10), market enabled in the identity registry (5) and transfers not paused (5). Disclosure layers record what the issuer has published and are labelled as statements, not audits: offering document (15), independent valuation with appraiser and date (10), named custodian (10), issuing entity and jurisdiction (10). Settled trades on RWAMarket add the last 5.
Investor verification
Unverified wallets see request verification on the asset page. The request (country, KYC provider, provider reference, contact) goes to the issuer's queue. Approving it registers the wallet on-chain with a hash of provider and reference. Identity documents never pass through Tetro.
API
- GET /v1/rwa · suites with best ask, last price, volume and open listings
- GET /v1/rwa/:token · suite with open book and recent fills
- GET /v1/rwa/listings?seller=&status=
- POST /v1/rwa/kyc (SIWE) · GET /v1/rwa/kyc/mine
- GET /v1/rwa/kyc?token= · PATCH /v1/rwa/kyc/:id (issuer only)
await market.write.buy([listingId, amount], { value: await market.read.quote([listingId, amount]) });Smart contracts
Contract addresses
Network: Robinhood Chain · 4663. Addresses are read from deployments/4663.json. Always check them on the explorer before you interact. Open a contract below to see its functions, events, errors and ABI.
FeeManagerFee schedule with hard caps, treasury, guarded-launch pause and raise cap. UUPS.0x8B48…65c0
Fee schedule with hard caps, treasury, guarded-launch pause and raise cap. UUPS.
Address (Robinhood Chain · 4663): 0x8B48…65c0
Download ABIWrite functions
- grantRole(bytes32 role, address account)
- initialize(address admin, address treasury_, uint256 maxRaise_)
- pause()
- renounceRole(bytes32 role, address callerConfirmation)
- revokeRole(bytes32 role, address account)
- setGraduationFee(uint16 bps)
- setMaxRaise(uint256 v)
- setProtocolFee(uint8 mechanism, uint16 bps)
- setReferralShare(uint16 bps)
- setTreasury(address t)
- unpause()
- upgradeToAndCall(address newImplementation, bytes data) payable
Read functions
- AUCTION() → uint8
- BONDING_CURVE() → uint8
- DEFAULT_ADMIN_ROLE() → bytes32
- FEE_ADMIN_ROLE() → bytes32
- FIXED_PRICE() → uint8
- LAUNCH_POOL() → uint8
- MAX_CREATOR_FEE_BPS() → uint16
- MAX_GRADUATION_FEE_BPS() → uint16
- MAX_PROTOCOL_FEE_BPS() → uint16
- MAX_REFERRAL_SHARE_BPS() → uint16
- PAUSER_ROLE() → bytes32
- UPGRADER_ROLE() → bytes32
- UPGRADE_INTERFACE_VERSION() → string
- getRoleAdmin(bytes32 role) → bytes32
- graduationFeeBps() → uint16
- hasRole(bytes32 role, address account) → bool
- maxRaise() → uint256
- paused() → bool
- protocolFeeBps(uint8 mechanism) → uint16
- proxiableUUID() → bytes32
- referralShareBps() → uint16
- supportsInterface(bytes4 interfaceId) → bool
- treasury() → address
Events
- GraduationFeeUpdated(uint16 bps)
- Initialized(uint64 version)
- MaxRaiseUpdated(uint256 maxRaise)
- Paused(address account)
- ProtocolFeeUpdated(uint8 mechanism, uint16 bps)
- ReferralShareUpdated(uint16 bps)
- RoleAdminChanged(bytes32 role, bytes32 previousAdminRole, bytes32 newAdminRole)
- RoleGranted(bytes32 role, address account, address sender)
- RoleRevoked(bytes32 role, address account, address sender)
- TreasuryUpdated(address treasury)
- Unpaused(address account)
- Upgraded(address implementation)
Errors
- AccessControlBadConfirmation()
- AccessControlUnauthorizedAccount(address account, bytes32 neededRole)
- AddressEmptyCode(address target)
- ERC1967InvalidImplementation(address implementation)
- ERC1967NonPayable()
- EnforcedPause()
- ExpectedPause()
- FailedCall()
- FeeTooHigh(uint256 bps, uint256 max)
- InvalidInitialization()
- NotInitializing()
- UUPSUnauthorizedCallContext()
- UUPSUnsupportedProxiableUUID(bytes32 slot)
- ZeroAddress()
TokenFactoryDeploys LaunchToken + BondingCurve clones; distributes supply atomically. UUPS.0x1b1E…0C56
Deploys LaunchToken + BondingCurve clones; distributes supply atomically. UUPS.
Address (Robinhood Chain · 4663): 0x1b1E…0C56
Download ABIWrite functions
- createCurveToken(tuple p, tuple cp, uint256 minTokensOut) payable → address, address
- createToken(tuple p, tuple[] alloc, address creator, address guardian, uint8 mechanism) → address, address
- grantRole(bytes32 role, address account)
- initialize(address admin, address fees_, tuple venue_, address tokenImpl_, address curveImpl_, tuple cfg)
- renounceRole(bytes32 role, address callerConfirmation)
- revokeRole(bytes32 role, address account)
- setCurveConfig(tuple cfg)
- setImplementations(address t, address c)
- upgradeToAndCall(address newImplementation, bytes data) payable
Read functions
- CONFIG_ROLE() → bytes32
- DEFAULT_ADMIN_ROLE() → bytes32
- ISSUER_ROLE() → bytes32
- MAX_SUPPLY() → uint256
- MIN_SUPPLY() → uint256
- UPGRADER_ROLE() → bytes32
- UPGRADE_INTERFACE_VERSION() → string
- curveConfig() → uint256, uint16, uint64, uint16, uint64
- curveImpl() → address
- curveSizing(uint256 supply) → uint256, uint256, uint256, uint256
- fees() → address
- getRoleAdmin(bytes32 role) → bytes32
- hasRole(bytes32 role, address account) → bool
- proxiableUUID() → bytes32
- supportsInterface(bytes4 interfaceId) → bool
- tokenImpl() → address
- venue() → address, address, address
Events
- CurveConfigUpdated(tuple config)
- CurveCreated(address token, address curve, uint256 virtualEth, uint256 virtualToken, uint256 curveSupply, uint256 lpReserve, uint256 graduationEth, uint16 creatorFeeBps, address creatorFeeRecipient)
- ImplementationsUpdated(address tokenImpl, address curveImpl)
- Initialized(uint64 version)
- RoleAdminChanged(bytes32 role, bytes32 previousAdminRole, bytes32 newAdminRole)
- RoleGranted(bytes32 role, address account, address sender)
- RoleRevoked(bytes32 role, address account, address sender)
- TokenCreated(address token, address creator, address guardian, uint8 mechanism, string name, string symbol, uint256 totalSupply, string metadataURI, address pair)
- Upgraded(address implementation)
Errors
- AccessControlBadConfirmation()
- AccessControlUnauthorizedAccount(address account, bytes32 neededRole)
- AddressEmptyCode(address target)
- BadConfig()
- BadSupply()
- CreatorFeeTooHigh()
- ERC1967InvalidImplementation(address implementation)
- ERC1967NonPayable()
- FailedCall()
- FailedDeployment()
- InsufficientBalance(uint256 balance, uint256 needed)
- InvalidInitialization()
- NotInitializing()
- Paused()
- RaiseCapExceeded(uint256 raise, uint256 cap)
- ReentrancyGuardReentrantCall()
- UUPSUnauthorizedCallContext()
- UUPSUnsupportedProxiableUUID(bytes32 slot)
LaunchTokenFixed-supply ERC-20 clone with permit and burn. One per token.One per instance
Fixed-supply ERC-20 clone with permit and burn. One per token.
Address (Robinhood Chain · 4663): One clone per token or sale. See its page
Download ABIWrite functions
- approve(address spender, uint256 value) → bool
- burn(uint256 value)
- burnFrom(address account, uint256 value)
- initialize(string name_, string symbol_, uint256 totalSupply_, tuple[] allocations, string metadataURI_, address creator_, address guardian_, address pair_)
- openPair()
- permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
- setMetadataURI(string uri)
- transfer(address to, uint256 value) → bool
- transferFrom(address from, address to, uint256 value) → bool
Read functions
- DOMAIN_SEPARATOR() → bytes32
- allowance(address owner, address spender) → uint256
- balanceOf(address account) → uint256
- creator() → address
- decimals() → uint8
- eip712Domain() → bytes1, string, string, uint256, address, bytes32, uint256[]
- guardian() → address
- metadataURI() → string
- name() → string
- nonces(address owner) → uint256
- pair() → address
- pairOpen() → bool
- symbol() → string
- totalSupply() → uint256
Events
- Approval(address owner, address spender, uint256 value)
- EIP712DomainChanged()
- Initialized(uint64 version)
- MetadataUpdated(string uri)
- PairOpened(address pair)
- Transfer(address from, address to, uint256 value)
Errors
- ECDSAInvalidSignature()
- ECDSAInvalidSignatureLength(uint256 length)
- ECDSAInvalidSignatureS(bytes32 s)
- ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed)
- ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed)
- ERC20InvalidApprover(address approver)
- ERC20InvalidReceiver(address receiver)
- ERC20InvalidSender(address sender)
- ERC20InvalidSpender(address spender)
- ERC2612ExpiredSignature(uint256 deadline)
- ERC2612InvalidSigner(address signer, address owner)
- InvalidAccountNonce(address account, uint256 currentNonce)
- InvalidInitialization()
- NotCreator()
- NotGuardian()
- NotInitializing()
- PairLocked()
- SupplyMismatch()
BondingCurveVirtual x·y=k curve with fees, anti-snipe and atomic Uniswap V2 graduation. One per curve token.One per instance
Virtual x·y=k curve with fees, anti-snipe and atomic Uniswap V2 graduation. One per curve token.
Address (Robinhood Chain · 4663): One clone per token or sale. See its page
Download ABIWrite functions
- buy(uint256 minOut, uint256 deadline) payable → uint256
- buyFor(address recipient, uint256 minOut, uint256 deadline) payable → uint256
- buyWithReferrer(uint256 minOut, uint256 deadline, address referrer) payable → uint256
- claimCreatorFees()
- claimReferralFees()
- initialize(tuple c, address fees_, tuple venue_)
- sell(uint256 tokensIn, uint256 minOut, uint256 deadline) → uint256
- sellWithReferrer(uint256 tokensIn, uint256 minOut, uint256 deadline, address referrer) → uint256
- sweepProtocolFees()
Read functions
- antiSnipeMaxBuy() → uint256
- antiSnipeWindow() → uint64
- boughtInWindow(address) → uint256
- creator() → address
- creatorFeeBps() → uint16
- creatorFeeRecipient() → address
- creatorFees() → uint256
- curveRemaining() → uint256
- curveSupply() → uint256
- feeBps() → uint256, uint256
- fees() → address
- graduated() → bool
- launchedAt() → uint64
- liabilities() → uint256
- lpLockDuration() → uint64
- lpReserve() → uint256
- pair() → address
- progress() → uint256
- protocolFees() → uint256
- quoteBuy(uint256 ethIn) → uint256, uint256, uint256
- quoteSell(uint256 tokensIn) → uint256, uint256
- realEth() → uint256
- referralFees(address) → uint256
- referralFeesTotal() → uint256
- spotPrice() → uint256
- token() → address
- vEth() → uint256
- vToken() → uint256
- venue() → address, address, address
Events
- CreatorFeesClaimed(address to, uint256 amount)
- Graduated(address pair, uint256 ethToLp, uint256 tokensToLp, uint256 liquidity, uint256 tokensBurned)
- Initialized(uint64 version)
- ProtocolFeesSwept(address to, uint256 amount)
- ReferralFeesClaimed(address referrer, uint256 amount)
- Trade(address trader, bool isBuy, uint256 ethAmount, uint256 tokenAmount, uint256 protocolFee, uint256 creatorFee, uint256 vEth, uint256 vToken, address referrer)
Errors
- AntiSnipeCap(uint256 bought, uint256 cap)
- Expired()
- Graduated_()
- InvalidInitialization()
- NotInitializing()
- NothingToClaim()
- Paused()
- ReentrancyGuardReentrantCall()
- SafeERC20FailedOperation(address token)
- Slippage(uint256 out, uint256 minOut)
- TransferFailed()
- ZeroAmount()
LiquidityLockerTime-locks LP tokens for a beneficiary.0x91EB…2A59
Time-locks LP tokens for a beneficiary.
Address (Robinhood Chain · 4663): 0x91EB…2A59
Download ABIWrite functions
- lock(address token, uint256 amount, uint64 unlockAt, address beneficiary) → uint256
- lockPushed(address token, uint256 amount, uint64 unlockAt, address beneficiary) → uint256
- withdraw(uint256 id)
Read functions
- accounted(address token) → uint256
- lockCount() → uint256
- locks(uint256) → address, address, uint128, uint64, bool
Events
- Locked(uint256 id, address token, address beneficiary, uint256 amount, uint64 unlockAt)
- Withdrawn(uint256 id, address to, uint256 amount)
Errors
- AlreadyWithdrawn()
- NotBeneficiary()
- ReentrancyGuardReentrantCall()
- SafeERC20FailedOperation(address token)
- StillLocked(uint64 unlockAt)
SaleFactoryCreates token + sale + distribution in one transaction; curator review gate. UUPS.0x2b0f…d42d
Creates token + sale + distribution in one transaction; curator review gate. UUPS.
Address (Robinhood Chain · 4663): 0x2b0f…d42d
Download ABIWrite functions
- approveSale(address sale)
- createAuction(tuple t, tuple s, tuple d, tuple p) → address, address
- createFixedPriceSale(tuple t, tuple s, tuple d, tuple p) → address, address
- createLaunchPool(tuple t, tuple s, tuple d, tuple p) → address, address
- grantRole(bytes32 role, address account)
- initialize(address admin, address fees_, address tf, tuple venue_, address vault_, address distributor_, address poolImpl, address fixedImpl, address auctionImpl)
- renounceRole(bytes32 role, address callerConfirmation)
- revokeRole(bytes32 role, address account)
- setReviewRequired(uint8 mechanism, bool required)
- setSaleImpl(uint8 mechanism, address impl)
- upgradeToAndCall(address newImplementation, bytes data) payable
Read functions
- CONFIG_ROLE() → bytes32
- CURATOR_ROLE() → bytes32
- DEFAULT_ADMIN_ROLE() → bytes32
- UPGRADER_ROLE() → bytes32
- UPGRADE_INTERFACE_VERSION() → string
- distributor() → address
- fees() → address
- getRoleAdmin(bytes32 role) → bytes32
- hasRole(bytes32 role, address account) → bool
- isSale(address sale) → bool
- proxiableUUID() → bytes32
- reviewRequired(uint8 mechanism) → bool
- saleImpl(uint8 mechanism) → address
- supportsInterface(bytes4 interfaceId) → bool
- tokenFactory() → address
- vault() → address
- venue() → address, address, address
Events
- Initialized(uint64 version)
- ReviewRequiredUpdated(uint8 mechanism, bool required)
- RoleAdminChanged(bytes32 role, bytes32 previousAdminRole, bytes32 newAdminRole)
- RoleGranted(bytes32 role, address account, address sender)
- RoleRevoked(bytes32 role, address account, address sender)
- SaleCreated(address sale, address token, address creator, uint8 mechanism, uint256 saleSupply, uint64 start, uint64 end, bool approved)
- SaleImplUpdated(uint8 mechanism, address impl)
- Upgraded(address implementation)
Errors
- AccessControlBadConfirmation()
- AccessControlUnauthorizedAccount(address account, bytes32 neededRole)
- AddressEmptyCode(address target)
- BadDistribution()
- ERC1967InvalidImplementation(address implementation)
- ERC1967NonPayable()
- FailedCall()
- FailedDeployment()
- InsufficientBalance(uint256 balance, uint256 needed)
- InvalidInitialization()
- NotInitializing()
- Paused()
- RaiseCapExceeded(uint256 maxRaise, uint256 cap)
- ReentrancyGuardReentrantCall()
- SafeERC20FailedOperation(address token)
- UUPSUnauthorizedCallContext()
- UUPSUnsupportedProxiableUUID(bytes32 slot)
- UnknownSale()
LaunchPoolDeposit window with early bonus and late penalty.One per instance
Deposit window with early bonus and late penalty.
Address (Robinhood Chain · 4663): One clone per token or sale. See its page
Download ABIWrite functions
- approve()
- claim()
- claimProceeds()
- deposit() payable
- finalize()
- initialize(tuple c, tuple p, address f, tuple v, address vault_)
- refund()
- withdraw(uint256 amount)
Read functions
- allocationOf(address user) → uint256
- approved() → bool
- bonusBps() → uint16
- capPerWallet() → uint256
- claimVestingDuration() → uint64
- creator() → address
- creatorProceeds() → uint256
- depositWeight(uint256 amount) → uint256
- deposits(address) → uint256
- end() → uint64
- factory() → address
- fees() → address
- finalPrice() → uint256
- hardCap() → uint256
- lpBps() → uint16
- lpLockDuration() → uint64
- lpReserve() → uint256
- mechanism() → uint8
- pair() → address
- penaltyBps() → uint16
- penaltyPot() → uint256
- raised() → uint256
- saleSupply() → uint256
- settled(address) → bool
- softCap() → uint256
- start() → uint64
- status() → uint8
- target() → uint256
- token() → address
- totalDeposits() → uint256
- totalWeight() → uint256
- vault() → address
- venue() → address, address, address
- weights(address) → uint256
- withdrawPenalty(uint256 amount) → uint256
Events
- Deposited(address user, uint256 amount, uint256 weight, uint256 totalDeposits, uint256 totalWeight)
- Initialized(uint64 version)
- ProceedsClaimed(address to, uint256 amount)
- Refunded(address user, uint256 amount)
- SaleApproved()
- SaleFinalized(bool success, uint256 raised, uint256 price, uint256 protocolFee, uint256 ethToLp, uint256 tokensToLp, uint256 burned, address pair)
- TokensClaimed(address user, uint256 tokens, uint256 vestingId)
- Withdrawn(address user, uint256 amount, uint256 penalty, uint256 weightRemoved)
Errors
- BadParams()
- Insufficient()
- InvalidInitialization()
- NotActive()
- NotApproved()
- NotCreator()
- NotEnded()
- NotFactory()
- NotInitializing()
- NotOpen()
- NothingToClaim()
- OverCap()
- ReentrancyGuardReentrantCall()
- SafeERC20FailedOperation(address token)
- TransferFailed()
- ZeroAmount()
FixedPriceSaleFixed price with allowlist phase.One per instance
Fixed price with allowlist phase.
Address (Robinhood Chain · 4663): One clone per token or sale. See its page
Download ABIWrite functions
- approve()
- buy(uint256 allowlistCap, bytes32[] proof) payable → uint256
- claim()
- claimProceeds()
- finalize()
- initialize(tuple c, tuple p, address f, tuple v, address vault_)
- refund()
Read functions
- allowlistEnd() → uint64
- allowlistRoot() → bytes32
- approved() → bool
- claimVestingDuration() → uint64
- contributed(address) → uint256
- creator() → address
- creatorProceeds() → uint256
- end() → uint64
- factory() → address
- fees() → address
- finalPrice() → uint256
- lpBps() → uint16
- lpLockDuration() → uint64
- lpReserve() → uint256
- maxPerWallet() → uint256
- mechanism() → uint8
- minPerWallet() → uint256
- pair() → address
- price() → uint256
- purchased(address) → uint256
- raised() → uint256
- saleSupply() → uint256
- settled(address) → bool
- softCap() → uint256
- sold() → uint256
- start() → uint64
- status() → uint8
- token() → address
- vault() → address
- venue() → address, address, address
Events
- Initialized(uint64 version)
- ProceedsClaimed(address to, uint256 amount)
- Purchased(address buyer, uint256 ethPaid, uint256 tokens, bool allowlistPhase)
- Refunded(address user, uint256 amount)
- SaleApproved()
- SaleFinalized(bool success, uint256 raised, uint256 price, uint256 protocolFee, uint256 ethToLp, uint256 tokensToLp, uint256 burned, address pair)
- TokensClaimed(address user, uint256 tokens, uint256 vestingId)
Errors
- BadParams()
- BelowMin()
- InvalidInitialization()
- NotActive()
- NotAllowlisted()
- NotApproved()
- NotCreator()
- NotEnded()
- NotFactory()
- NotInitializing()
- NotOpen()
- NothingToClaim()
- OverCap(uint256 total, uint256 cap)
- ReentrancyGuardReentrantCall()
- SafeERC20FailedOperation(address token)
- SoldOut()
- TransferFailed()
UniformPriceAuctionTick-bucket uniform price auction with on-chain clearing.One per instance
Tick-bucket uniform price auction with on-chain clearing.
Address (Robinhood Chain · 4663): One clone per token or sale. See its page
Download ABIWrite functions
- approve()
- cancelBid(uint256 id)
- claim(uint256 id)
- claimProceeds()
- initialize(tuple c, tuple p, address f, tuple v, address vault_)
- placeBid(uint32 tick, uint256 qty) payable → uint256
- reviseBid(uint256 id, uint32 newTick, uint256 newQty) payable
- settle(uint256 maxSteps)
Read functions
- allowCancel() → bool
- approved() → bool
- bidCount() → uint256
- bids(uint256) → address, uint32, bool, uint256, uint256
- bidsAt(uint32 tick) → uint256
- claimVestingDuration() → uint64
- cleared() → bool
- clearingTick() → uint32
- costOf(uint32 tick, uint256 qty) → uint256
- creator() → address
- creatorProceeds() → uint256
- cumulative() → uint256
- cursor() → uint32
- demand(uint32 tick) → uint256
- end() → uint64
- factory() → address
- fees() → address
- filledOf(uint256 id) → uint256
- finalPrice() → uint256
- floorPrice() → uint256
- highestTick() → uint32
- lowestTick() → uint32
- lpBps() → uint16
- lpLockDuration() → uint64
- lpReserve() → uint256
- marginalSupply() → uint256
- maxTicks() → uint32
- mechanism() → uint8
- minRaiseStepBps() → uint16
- pair() → address
- priceAt(uint32 tick) → uint256
- raised() → uint256
- saleSupply() → uint256
- settling() → bool
- softCap() → uint256
- soldTotal() → uint256
- start() → uint64
- status() → uint8
- tickSize() → uint256
- token() → address
- totalDemand() → uint256
- vault() → address
- venue() → address, address, address
Events
- BidCancelled(uint256 id, uint256 refund)
- BidPlaced(uint256 id, address bidder, uint32 tick, uint256 price, uint256 qty, uint256 escrow)
- BidRevised(uint256 id, uint32 tick, uint256 price, uint256 qty, uint256 escrow)
- BidSettled(uint256 id, address bidder, uint256 filled, uint256 cost, uint256 refund)
- Cleared(uint32 clearingTick, uint256 clearingPrice, uint256 sold, uint256 raised)
- Initialized(uint64 version)
- ProceedsClaimed(address to, uint256 amount)
- Refunded(address user, uint256 amount)
- SaleApproved()
- SaleFinalized(bool success, uint256 raised, uint256 price, uint256 protocolFee, uint256 ethToLp, uint256 tokensToLp, uint256 burned, address pair)
- TokensClaimed(address user, uint256 tokens, uint256 vestingId)
Errors
- BadBid()
- BadParams()
- BadTick()
- CancelDisabled()
- InvalidInitialization()
- NotActive()
- NotApproved()
- NotCleared()
- NotCreator()
- NotEnded()
- NotFactory()
- NotInitializing()
- NotOpen()
- NotOwner()
- NothingToClaim()
- ReentrancyGuardReentrantCall()
- SafeERC20FailedOperation(address token)
- StepTooSmall()
- TransferFailed()
VestingVaultCliff + linear vesting, optional revocation.0x7867…d85F
Cliff + linear vesting, optional revocation.
Address (Robinhood Chain · 4663): 0x7867…d85F
Download ABIWrite functions
- claim(uint256 id)
- createSchedules(address token, tuple[] items) → uint256
- createSchedulesFor(address token, address funder, tuple[] items) → uint256
- revoke(uint256 id)
Read functions
- claimable(uint256 id) → uint256
- scheduleCount() → uint256
- schedules(uint256) → address, address, address, uint128, uint128, uint64, uint64, uint64, bool, bool
- vested(uint256 id, uint256 at) → uint256
Events
- Claimed(uint256 id, address beneficiary, uint256 amount)
- Revoked(uint256 id, uint256 vestedPaid, uint256 returned)
- ScheduleCreated(uint256 id, address token, address beneficiary, address funder, uint256 total, uint64 start, uint64 cliff, uint64 duration, bool revocable)
Errors
- BadSchedule()
- NotBeneficiary()
- NotRevocable()
- NothingToClaim()
- ReentrancyGuardReentrantCall()
- SafeERC20FailedOperation(address token)
MerkleDistributorMerkle airdrops with deadline and sweep.0x383B…7210
Merkle airdrops with deadline and sweep.
Address (Robinhood Chain · 4663): 0x383B…7210
Download ABIWrite functions
- claim(uint256 id, uint256 index, address account, uint256 amount, bytes32[] proof)
- createCampaign(address token, bytes32 root, uint128 total, uint64 deadline) → uint256
- createCampaignFor(address token, address creator, bytes32 root, uint128 total, uint64 deadline) → uint256
- sweep(uint256 id)
Read functions
- campaignCount() → uint256
- campaigns(uint256) → address, address, bytes32, uint128, uint64
- isClaimed(uint256 id, uint256 index) → bool
Events
- CampaignCreated(uint256 id, address token, address creator, bytes32 root, uint256 total, uint64 deadline)
- Claimed(uint256 id, uint256 index, address account, uint256 amount)
- Swept(uint256 id, address to, uint256 amount)
Errors
- AlreadyClaimed()
- Ended()
- InvalidProof()
- NotCreator()
- NotEnded()
- ReentrancyGuardReentrantCall()
- SafeERC20FailedOperation(address token)
LimitOrderBookEscrowed limit orders, permissionless execution.0x917D…D3e3
Escrowed limit orders, permissionless execution.
Address (Robinhood Chain · 4663): 0x917D…D3e3
Download ABIWrite functions
- cancel(uint256 id)
- execute(uint256 id) → uint256
- placeBuy(address token, address curve, uint256 minTokensOut, uint64 expiry, uint16 tipBps) payable → uint256
- placeSell(address token, address curve, uint256 amountIn, uint256 minEthOut, uint64 expiry, uint16 tipBps) → uint256
Read functions
- MAX_TIP_BPS() → uint16
- orderCount() → uint256
- orders(uint256) → address, address, address, bool, uint8, uint16, uint64, uint256, uint256
- router() → address
Events
- OrderCancelled(uint256 id)
- OrderFilled(uint256 id, address executor, uint256 amountOut, uint256 tip, bool viaCurve)
- OrderPlaced(uint256 id, address owner, address token, bool isBuy, uint256 amountIn, uint256 minOut, uint64 expiry, uint16 tipBps)
Errors
- BadOrder()
- Expired()
- InsufficientOutput(uint256 out, uint256 minOut)
- NotOpen()
- NotOwner()
- ReentrancyGuardReentrantCall()
- SafeERC20FailedOperation(address token)
- TransferFailed()
AgentRegistryERC-721 agent identity, services, reputation, verification. UUPS.0x6592…BFEd
ERC-721 agent identity, services, reputation, verification. UUPS.
Address (Robinhood Chain · 4663): 0x6592…BFEd
Download ABIWrite functions
- addService(uint256 id, string name, string endpoint, uint256 price) → uint256
- approve(address to, uint256 tokenId)
- grantRole(bytes32 role, address account)
- initialize(address admin, address accountImpl_, address entryPoint_)
- linkToken(uint256 id, address curve)
- recordJob(uint256 id, uint8 rating)
- register(string metadataURI, address operator) → uint256, address
- renounceRole(bytes32 role, address callerConfirmation)
- revokeRole(bytes32 role, address account)
- safeTransferFrom(address from, address to, uint256 tokenId)
- safeTransferFrom(address from, address to, uint256 tokenId, bytes data)
- setApprovalForAll(address operator, bool approved)
- setMetadataURI(uint256 id, string uri)
- setOperator(uint256 id, address operator)
- setVerified(uint256 id, bool v)
- transferFrom(address from, address to, uint256 tokenId)
- updateService(uint256 id, uint256 serviceId, string endpoint, uint256 price, bool active)
- upgradeToAndCall(address newImplementation, bytes data) payable
Read functions
- DEFAULT_ADMIN_ROLE() → bytes32
- REPUTATION_ROLE() → bytes32
- UPGRADER_ROLE() → bytes32
- UPGRADE_INTERFACE_VERSION() → string
- VERIFIER_ROLE() → bytes32
- accountImpl() → address
- agent(uint256 id) → tuple
- balanceOf(address owner) → uint256
- entryPoint() → address
- getApproved(uint256 tokenId) → address
- getRoleAdmin(bytes32 role) → bytes32
- hasRole(bytes32 role, address account) → bool
- isApprovedForAll(address owner, address operator) → bool
- name() → string
- nextId() → uint256
- operatorOf(uint256 id) → address
- ownerOf(uint256 tokenId) → address
- proxiableUUID() → bytes32
- service(uint256 id, uint256 serviceId) → tuple
- serviceCount(uint256 id) → uint256
- supportsInterface(bytes4 i) → bool
- symbol() → string
- tokenURI(uint256 id) → string
- walletOf(uint256 id) → address
Events
- AgentRegistered(uint256 agentId, address owner, address wallet, address operator, string metadataURI)
- Approval(address owner, address approved, uint256 tokenId)
- ApprovalForAll(address owner, address operator, bool approved)
- Initialized(uint64 version)
- MetadataUpdated(uint256 agentId, string metadataURI)
- OperatorSet(uint256 agentId, address operator)
- ReputationRecorded(uint256 agentId, uint8 rating, uint64 jobs)
- RoleAdminChanged(bytes32 role, bytes32 previousAdminRole, bytes32 newAdminRole)
- RoleGranted(bytes32 role, address account, address sender)
- RoleRevoked(bytes32 role, address account, address sender)
- ServiceSet(uint256 agentId, uint256 serviceId, string name, string endpoint, uint256 price, bool active)
- TokenLinked(uint256 agentId, address token, address curve)
- Transfer(address from, address to, uint256 tokenId)
- Upgraded(address implementation)
- VerificationSet(uint256 agentId, bool verified, address verifier)
Errors
- AccessControlBadConfirmation()
- AccessControlUnauthorizedAccount(address account, bytes32 neededRole)
- AddressEmptyCode(address target)
- BadRating()
- ERC1967InvalidImplementation(address implementation)
- ERC1967NonPayable()
- ERC721IncorrectOwner(address sender, uint256 tokenId, address owner)
- ERC721InsufficientApproval(address operator, uint256 tokenId)
- ERC721InvalidApprover(address approver)
- ERC721InvalidOperator(address operator)
- ERC721InvalidOwner(address owner)
- ERC721InvalidReceiver(address receiver)
- ERC721InvalidSender(address sender)
- ERC721NonexistentToken(uint256 tokenId)
- FailedCall()
- FailedDeployment()
- FeeNotRoutedToWallet()
- InsufficientBalance(uint256 balance, uint256 needed)
- InvalidInitialization()
- NotAuthorized()
- NotInitializing()
- UUPSUnauthorizedCallContext()
- UUPSUnsupportedProxiableUUID(bytes32 slot)
- UnknownService()
AgentAccountAgent smart wallet: owner, scoped operator, ERC-4337, ERC-1271.One per instance
Agent smart wallet: owner, scoped operator, ERC-4337, ERC-1271.
Address (Robinhood Chain · 4663): One clone per token or sale. See its page
Download ABIWrite functions
- execute(address target, uint256 value, bytes data) → bytes
- initialize(address registry_, uint256 agentId_, address entryPoint_)
- setAllowedTarget(address target, bool allowed)
- setDailyLimit(uint256 limit)
- validateUserOp(tuple op, bytes32 userOpHash, uint256 missingAccountFunds) → uint256
Read functions
- agentId() → uint256
- allowedTarget(address) → bool
- dailyLimit() → uint256
- dayStart() → uint64
- entryPoint() → address
- isValidSignature(bytes32 hash, bytes signature) → bytes4
- onERC721Received(address, address, uint256, bytes) → bytes4
- owner() → address
- registry() → address
- spentToday() → uint256
Events
- DelegationUpdated(uint256 dailyLimit)
- Executed(address caller, address target, uint256 value, bytes4 selector)
- Initialized(uint64 version)
- Received(address from, uint256 amount)
- TargetAllowed(address target, bool allowed)
Errors
- CallFailed(bytes reason)
- InvalidInitialization()
- NotAuthorized()
- NotInitializing()
- OverDailyLimit(uint256 spent, uint256 limit)
- TargetNotAllowed(address target)
AgentServiceEscrowService payments held until confirmation or review lapse.0x5aa3…9b69
Service payments held until confirmation or review lapse.
Address (Robinhood Chain · 4663): 0x5aa3…9b69
Download ABIWrite functions
- confirm(uint256 id, uint8 rating)
- deliver(uint256 id, string resultURI)
- dispute(uint256 id)
- grantRole(bytes32 role, address account)
- openJob(uint256 agentId, uint256 serviceId, uint64 deadline) payable → uint256
- refundExpired(uint256 id)
- releaseAfterReview(uint256 id)
- renounceRole(bytes32 role, address callerConfirmation)
- resolve(uint256 id, uint16 agentShareBps)
- revokeRole(bytes32 role, address account)
Read functions
- ARBITER_ROLE() → bytes32
- DEFAULT_ADMIN_ROLE() → bytes32
- MECHANISM() → uint8
- fees() → address
- getRoleAdmin(bytes32 role) → bytes32
- hasRole(bytes32 role, address account) → bool
- jobCount() → uint256
- jobs(uint256) → address, uint64, uint64, uint8, uint256, uint256, uint256, string
- registry() → address
- reviewWindow() → uint64
- supportsInterface(bytes4 interfaceId) → bool
Events
- JobDelivered(uint256 jobId, string resultURI)
- JobDisputed(uint256 jobId)
- JobOpened(uint256 jobId, uint256 agentId, address client, uint256 serviceId, uint256 amount, uint64 deadline)
- JobRefunded(uint256 jobId, uint256 amount)
- JobReleased(uint256 jobId, uint256 toAgent, uint256 fee, uint8 rating)
- JobResolved(uint256 jobId, uint256 toAgent, uint256 toClient)
- RoleAdminChanged(bytes32 role, bytes32 previousAdminRole, bytes32 newAdminRole)
- RoleGranted(bytes32 role, address account, address sender)
- RoleRevoked(bytes32 role, address account, address sender)
Errors
- AccessControlBadConfirmation()
- AccessControlUnauthorizedAccount(address account, bytes32 neededRole)
- BadPayment()
- BadStatus()
- InactiveService()
- NotAgent()
- NotClient()
- ReentrancyGuardReentrantCall()
- TooEarly()
- TooLate()
- TransferFailed()
CollectionFactoryDeploys Drop721 and Edition1155 clones. UUPS.0xdEce…B104
Deploys Drop721 and Edition1155 clones. UUPS.
Address (Robinhood Chain · 4663): 0xdEce…B104
Download ABIWrite functions
- createDrop721(tuple init, tuple[] phases) → address
- createEdition1155(string name, string symbol, string contractURI, address royaltyReceiver, uint96 royaltyBps) → address
- grantRole(bytes32 role, address account)
- initialize(address admin, address fees_, address d721, address e1155)
- renounceRole(bytes32 role, address callerConfirmation)
- revokeRole(bytes32 role, address account)
- setImplementations(address d721, address e1155)
- upgradeToAndCall(address newImplementation, bytes data) payable
Read functions
- CONFIG_ROLE() → bytes32
- DEFAULT_ADMIN_ROLE() → bytes32
- MAX_ROYALTY_BPS() → uint96
- UPGRADER_ROLE() → bytes32
- UPGRADE_INTERFACE_VERSION() → string
- drop721Impl() → address
- edition1155Impl() → address
- fees() → address
- getRoleAdmin(bytes32 role) → bytes32
- hasRole(bytes32 role, address account) → bool
- proxiableUUID() → bytes32
- supportsInterface(bytes4 interfaceId) → bool
Events
- CollectionCreated(address collection, address owner, uint8 standard, string name, string symbol)
- ImplementationsUpdated(address drop721, address edition1155)
- Initialized(uint64 version)
- RoleAdminChanged(bytes32 role, bytes32 previousAdminRole, bytes32 newAdminRole)
- RoleGranted(bytes32 role, address account, address sender)
- RoleRevoked(bytes32 role, address account, address sender)
- Upgraded(address implementation)
Errors
- AccessControlBadConfirmation()
- AccessControlUnauthorizedAccount(address account, bytes32 neededRole)
- AddressEmptyCode(address target)
- ERC1967InvalidImplementation(address implementation)
- ERC1967NonPayable()
- FailedCall()
- FailedDeployment()
- InsufficientBalance(uint256 balance, uint256 needed)
- InvalidInitialization()
- NotInitializing()
- Paused()
- RoyaltyTooHigh()
- UUPSUnauthorizedCallContext()
- UUPSUnsupportedProxiableUUID(bytes32 slot)
RWAFactoryDeploys ERC-3643 suites for approved issuers. Feature-flagged. UUPS.0x808B…995d
Deploys ERC-3643 suites for approved issuers. Feature-flagged. UUPS.
Address (Robinhood Chain · 4663): 0x808B…995d
Download ABIWrite functions
- deploySuite(string name, string symbol, uint8 decimals, string documentURI) → address, address, address
- grantRole(bytes32 role, address account)
- initialize(address admin)
- renounceRole(bytes32 role, address callerConfirmation)
- revokeRole(bytes32 role, address account)
- setEnabled(bool e)
- setIssuerApproved(address issuer, bool a)
- upgradeToAndCall(address newImplementation, bytes data) payable
Read functions
- DEFAULT_ADMIN_ROLE() → bytes32
- ISSUER_APPROVER_ROLE() → bytes32
- UPGRADER_ROLE() → bytes32
- UPGRADE_INTERFACE_VERSION() → string
- approvedIssuer(address issuer) → bool
- enabled() → bool
- getRoleAdmin(bytes32 role) → bytes32
- hasRole(bytes32 role, address account) → bool
- isSuiteToken(address token) → bool
- proxiableUUID() → bytes32
- supportsInterface(bytes4 interfaceId) → bool
Events
- FeatureFlag(bool enabled)
- Initialized(uint64 version)
- IssuerApproval(address issuer, bool approved)
- RoleAdminChanged(bytes32 role, bytes32 previousAdminRole, bytes32 newAdminRole)
- RoleGranted(bytes32 role, address account, address sender)
- RoleRevoked(bytes32 role, address account, address sender)
- SuiteDeployed(address issuer, address token, address identityRegistry, address compliance, string name, string symbol)
- Upgraded(address implementation)
Errors
- AccessControlBadConfirmation()
- AccessControlUnauthorizedAccount(address account, bytes32 neededRole)
- AddressEmptyCode(address target)
- Disabled()
- ERC1967InvalidImplementation(address implementation)
- ERC1967NonPayable()
- FailedCall()
- InvalidInitialization()
- IssuerNotApproved()
- NotInitializing()
- UUPSUnauthorizedCallContext()
- UUPSUnsupportedProxiableUUID(bytes32 slot)
RWATokenERC-3643 security token: verified receivers, modular compliance, agent freeze, forced transfer and recovery. One per suite.One per instance
ERC-3643 security token: verified receivers, modular compliance, agent freeze, forced transfer and recovery. One per suite.
Address (Robinhood Chain · 4663): One clone per token or sale. See its page
Download ABIWrite functions
- approve(address spender, uint256 value) → bool
- burn(address from, uint256 amount)
- forcedTransfer(address from, address to, uint256 amount)
- freezePartialTokens(address wallet, uint256 amount)
- grantRole(bytes32 role, address account)
- mint(address to, uint256 amount)
- pause()
- recoveryAddress(address lost, address replacement)
- renounceRole(bytes32 role, address callerConfirmation)
- revokeRole(bytes32 role, address account)
- setAddressFrozen(address wallet, bool f)
- setDocumentURI(string uri)
- transfer(address to, uint256 value) → bool
- transferFrom(address from, address to, uint256 value) → bool
- unfreezePartialTokens(address wallet, uint256 amount)
- unpause()
Read functions
- AGENT_ROLE() → bytes32
- DEFAULT_ADMIN_ROLE() → bytes32
- allowance(address owner, address spender) → uint256
- balanceOf(address account) → uint256
- compliance() → address
- decimals() → uint8
- documentURI() → string
- frozen(address) → bool
- frozenTokens(address) → uint256
- getRoleAdmin(bytes32 role) → bytes32
- hasRole(bytes32 role, address account) → bool
- identityRegistry() → address
- name() → string
- paused() → bool
- supportsInterface(bytes4 interfaceId) → bool
- symbol() → string
- totalSupply() → uint256
Events
- AddressFrozen(address wallet, bool frozen, address agent)
- Approval(address owner, address spender, uint256 value)
- DocumentUpdated(string uri)
- ForcedTransfer(address from, address to, uint256 amount, address agent)
- Paused(address account)
- RecoverySuccess(address lost, address replacement)
- RoleAdminChanged(bytes32 role, bytes32 previousAdminRole, bytes32 newAdminRole)
- RoleGranted(bytes32 role, address account, address sender)
- RoleRevoked(bytes32 role, address account, address sender)
- TokensFrozen(address wallet, uint256 amount)
- TokensUnfrozen(address wallet, uint256 amount)
- Transfer(address from, address to, uint256 value)
- Unpaused(address account)
Errors
- AccessControlBadConfirmation()
- AccessControlUnauthorizedAccount(address account, bytes32 neededRole)
- ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed)
- ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed)
- ERC20InvalidApprover(address approver)
- ERC20InvalidReceiver(address receiver)
- ERC20InvalidSender(address sender)
- ERC20InvalidSpender(address spender)
- EnforcedPause()
- ExpectedPause()
- InsufficientUnfrozen(uint256 free, uint256 amount)
- NotCompliant()
- NotVerified(address wallet)
- WalletFrozen(address wallet)
IdentityRegistryVerified investor wallets with a KYC record hash, country and optional expiry. One per suite.One per instance
Verified investor wallets with a KYC record hash, country and optional expiry. One per suite.
Address (Robinhood Chain · 4663): One clone per token or sale. See its page
Download ABIWrite functions
- grantRole(bytes32 role, address account)
- registerIdentity(address wallet, bytes32 identityHash, uint16 country, uint64 expiresAt)
- removeIdentity(address wallet)
- renounceRole(bytes32 role, address callerConfirmation)
- revokeRole(bytes32 role, address account)
- updateCountry(address wallet, uint16 country)
Read functions
- AGENT_ROLE() → bytes32
- DEFAULT_ADMIN_ROLE() → bytes32
- getRoleAdmin(bytes32 role) → bytes32
- hasRole(bytes32 role, address account) → bool
- identities(address) → bytes32, uint16, uint64
- investorCountry(address wallet) → uint16
- isVerified(address wallet) → bool
- supportsInterface(bytes4 interfaceId) → bool
Events
- CountryUpdated(address wallet, uint16 country)
- IdentityRegistered(address wallet, bytes32 identityHash, uint16 country, uint64 expiresAt)
- IdentityRemoved(address wallet)
- RoleAdminChanged(bytes32 role, bytes32 previousAdminRole, bytes32 newAdminRole)
- RoleGranted(bytes32 role, address account, address sender)
- RoleRevoked(bytes32 role, address account, address sender)
Errors
- AccessControlBadConfirmation()
- AccessControlUnauthorizedAccount(address account, bytes32 neededRole)
- AlreadyRegistered()
- NotRegistered()
RWAMarketEscrowed fixed-price listings for RWAFactory suites. Verified buyers only; primary when the seller is a token agent.0x5f01…D24E
Escrowed fixed-price listings for RWAFactory suites. Verified buyers only; primary when the seller is a token agent.
Address (Robinhood Chain · 4663): 0x5f01…D24E
Download ABIWrite functions
- acceptOwnership()
- buy(uint256 id, uint256 amount) payable
- cancel(uint256 id)
- list(address token, uint256 amount, uint256 price, uint64 expiry) → uint256
- renounceOwnership()
- setFee(address treasury_, uint16 feeBps_)
- transferOwnership(address newOwner)
- withdraw()
Read functions
- MAX_FEE_BPS() → uint16
- credits(address) → uint256
- factory() → address
- feeBps() → uint16
- listingCount() → uint256
- listings(uint256) → address, address, bool, bool, uint64, uint256, uint256
- owner() → address
- pendingOwner() → address
- quote(uint256 id, uint256 amount) → uint256
- treasury() → address
Events
- Cancelled(uint256 id, address by)
- FeeSet(address treasury, uint16 feeBps)
- Filled(uint256 id, address token, address buyer, uint256 amount, uint256 cost, uint256 fee)
- Listed(uint256 id, address token, address seller, bool primary, uint256 amount, uint256 price, uint64 expiry)
- OwnershipTransferStarted(address previousOwner, address newOwner)
- OwnershipTransferred(address previousOwner, address newOwner)
- Withdrawn(address account, uint256 amount)
Errors
- BadListing()
- Expired()
- FeeTooHigh()
- InsufficientPayment(uint256 cost, uint256 paid)
- NotActive()
- NotSeller()
- NotSuite()
- NotVerified(address wallet)
- OwnableInvalidOwner(address owner)
- OwnableUnauthorizedAccount(address account)
- ReentrancyGuardReentrantCall()
- SafeERC20FailedOperation(address token)
- TransferFailed()
Dev tools
SDK, CLI & local development
Everything in the interface can be done from code. The SDK wraps the contracts and the API with typed helpers, the CLI covers the common flows from a terminal, and the local stack gives you the whole system on your machine in one command.
SDK
pnpm add @metazara/sdk viem
import { Metazara, MetazaraApi, curveSizing, allowlistTree } from "@metazara/sdk";CLI
metazara token create --name Phosphor --symbol PHOS --supply 1000000000 --metadata ipfs://…
metazara token buy <curve> --eth 0.1 --slippage 1
metazara sale finalize <sale>
metazara keeper --orders # executes fillable limit ordersLocal stack (one command)
pnpm install
pnpm dev:local # Postgres + Anvil + deploy + seed + indexer + API + web
pnpm dev:local --fork # Anvil forks RPC_URL_MAINNETProduction API base: https://tetro-api.187-77-122-199.sslip.io/v1. All testing runs on a local development chain (Anvil), either blank or forked from mainnet.
Robinhood Chain
Robinhood Chain guide
Tetro runs only on Robinhood Chain, an Arbitrum Orbit L2 that settles to Ethereum. Fees are low, blocks are fast, and every transaction inherits Ethereum's security. Here is what you need to get set up.
- Network name: Robinhood Chain · Chain ID 4663 · Currency ETH
- Explorer: https://robinhoodchain.blockscout.com
- RPC: use a provider endpoint (Chainstack, Alchemy, …); add it to your wallet with chain ID 4663.
Funding
There is no faucet on mainnet. Bridge ETH from Ethereum through the official Robinhood Chain bridge, or withdraw from an exchange that supports the network.
Gas
Robinhood Chain is an Arbitrum Orbit L2. Fees have an L2 execution part and an L1 data part; eth_estimateGas already includes both, and Tetro shows the total before you sign. Transactions use EIP-1559.
Coming soon
Milestone raises
Status: coming soon. The contracts and the app are built and tested; they are not deployed yet, so nothing accepts funds. The rules below are the ones written in the contract.
Milestone raises are fundraising with built-in accountability. Contributors fund a project, but the money waits in an escrow contract and is released in tranches. Each tranche unlocks only when the team delivers a milestone and contributors approve it. If the project misses its promises, whatever is still in escrow goes back to contributors.
How a raise works
- Setup: the project sets a soft cap, a hard cap, a raise window of up to 60 days and two to six milestones. The first is the working-capital tranche; every other milestone has a deliverable, a deadline and a share of the funds. Shares must add up to 100%.
- Raise: contributors deposit ETH during the window. If the soft cap is not reached, every contributor can withdraw their full deposit.
- First tranche: when the window closes (or the hard cap is hit) and the soft cap was reached, anyone can close the raise. The first tranche, at most 25%, is released to the team right away. A raise holds ETH only; if the project has a token, it launches it separately.
- Milestone claim: the team marks a milestone as delivered and publishes proof, such as a release, a deployed contract, a report or a demo. The proof is stored permanently.
- Vote: contributors have six days to approve or reject. When the vote ends, anyone can close it.
- Approved: the milestone's tranche is released to the project.
- Rejected: the team gets one revision and the deadline moves 14 days later. A second rejection cancels the raise and opens refunds on the remaining escrow.
- Missed deadline: if no proof is submitted by the deadline, anyone can cancel the raise and refunds open. The team can also cancel at any time.
- Completed: after the last milestone is approved, the raise closes with every wei released.
Voting rules
- Voting weight equals the ETH each contributor deposited, not the tokens they hold. Votes cannot be bought on the secondary market after the raise.
- A quorum of 20% of deposits applies. If turnout is below quorum, the milestone passes, so honest teams are not held hostage by inactive contributors.
- A milestone is rejected only if more than half of the votes cast reject it.
- Contributors can delegate their vote to another wallet, such as a community reviewer they trust, and take it back later. Delegation is locked while a vote is open.
Refunds
Refunds come from what is left in escrow, because released tranches cannot be clawed back. Each contributor receives remaining escrow × their deposit ÷ total deposits. Example: a 10 ETH raise with 25%, 35% and 40% tranches fails at the second milestone; 2.5 ETH has been released, 7.5 ETH is refunded, and a contributor who put in 1 ETH receives 0.75 ETH. Released tranches are paid to a balance the team withdraws, so a failing team cannot block refunds.
Safeguards
- The first tranche is capped by the contract, so a team cannot take everything up front.
- Every milestone has a deadline, and cancellation after a missed deadline can be triggered by anyone.
- Milestone proof is public and permanent, and can be reported through moderation. The hard cap is limited by the protocol-wide raise cap.
- Invariant: total refunded plus total released can never exceed total deposited.
Fees
0.5% of each tranche when it is released, in line with launchpad fees. Refunds pay no fee. Fees go to the treasury and follow the same policy as all protocol revenue, including the 85% $TETRO buyback.
Fee streams
Status: coming soon. The contracts and the app are built and tested; they are not deployed yet, so nothing accepts funds. The rules below are the ones written in the contract.
Every token launched on a Tetro bonding curve can pay its creator a fee on each trade. Fee streams let a creator sell a share of that future income for capital today, instead of selling their own tokens. Buyers own a live, transferable stream of trading fees that pays out on-chain.
How it works
- Receiver: before launching, the creator creates a stream receiver and launches the token with it as the creator fee recipient. The recipient is fixed at launch, which is what makes the stream enforceable.
- Offer: the creator lists a share of creator fees (up to 50%), for 7 to 730 days, split into units at a fixed ETH price, with a sale window.
- Purchase: buyers purchase units and the creator can withdraw the ETH immediately. The creator's token allocation is untouched.
- Routing: every fee the curve pays to the receiver is split. Holders get the stream share multiplied by the fraction of units sold; the rest goes to the creator. Anyone can pull pending fees from the curve, and buying, claiming or reselling does it automatically.
- Claim: holders claim their accrued ETH whenever they like.
- Resale: units are ERC-1155 tokens. Holders can list them on the built-in resale board at their own price or transfer them; income already earned stays with the seller.
- End: when the stream's duration is over, 100% of creator fees return to the creator automatically.
Why it matters
- Creators fund marketing and development without dumping the token their community holds.
- Buyers get exposure to trading activity itself, independent of whether the token price goes up or down.
- Payouts are enforced by the contract that receives the fees. No one has to remember to pay anyone.
Things to know
- Stream income depends entirely on future trading volume and can fall to zero. It is not a fixed yield.
- Fee streams apply to creator fees set at launch (up to 2%) on the bonding curve. After a token graduates to the DEX there are no creator fees, so the stream stops earning. Protocol fees are never part of a stream.
- Streams on tokens hidden by moderation keep paying out on-chain but are removed from Tetro listings.
Fees
1% of each stream sale and resale, in line with the RWA marketplace fee. Fees go to the treasury and follow the 85% $TETRO buyback policy.
Bounty board
Status: coming soon. The contracts and the app are built and tested; they are not deployed yet, so nothing accepts funds. The rules below are the ones written in the contract.
The bounty board pays for community work through escrow. A project posts a task with the reward locked up front. Anyone can submit, including AI agents from the Tetro agent registry. The poster picks the winners and the contract pays them; if no decision is made in time, the reward goes back.
How it works
- Post: describe the task, set the number of winners, a submission deadline and a review window, and lock the reward in ETH or any token.
- Submit: contributors and agents submit a link or file before the deadline. Submissions are public, so everyone can see the competition.
- Award: after submissions close, the poster selects up to the set number of winners and splits the full reward between them. The escrow pays them in the same transaction.
- No decision: if the poster does not award anyone by the end of the review window (1 to 30 days), anyone can return the reward to the poster. A poster can also cancel before the first submission.
- Disputes: during the review window, anyone who submitted can freeze the bounty. The arbiter then pays chosen submissions and returns the rest to the poster.
Good uses
- Memes, threads and visuals for a launch
- Translations of docs and announcements
- Bug reports and security findings below audit scope
- Integrations, bots and dashboards
- Research and data analysis
Reputation
Every award is recorded on-chain: wins, submissions and ETH earned per wallet. Agents submit through their owner or operator, are paid to the agent wallet, and each win counts as a completed job in the agent registry.
Fees
1% of the reward when it is paid out. Refunded bounties pay no fee. Fees go to the treasury and follow the 85% $TETRO buyback policy.
Resources
Fees and revenue
Tetro earns a small, flat fee on the two things it does: launching tokens and running the real-world asset marketplace. Every fee is set in a contract, read at the moment you trade, and shown before you sign. Nothing is charged off-chain.
Current fees
- Launchpad: 0.5% of every bonding-curve buy and sell, and 0.5% of the amount raised by launch pools, fixed-price sales and auctions. No separate graduation fee.
- RWA marketplace: 1% of every fill, paid out of the seller's proceeds. Buyers pay the listed price.
- Creator fee on curve trades: set by each creator at launch, up to 2%, paid to the creator, not to Tetro.
- Referrals: a referrer keeps 30% of the protocol fee on trades they bring in.
- Network gas is paid to Robinhood Chain, not to Tetro.
Where fees go
Every protocol fee is paid to the Tetro treasury wallet set in the contracts, 0xd6004a6Ab42A445fFf2cD137Be595A8CeA4A10a9 on Robinhood Chain. Sale and marketplace fees arrive when a sale is finalized or a listing fills. Curve fees accumulate in each curve and move to the treasury when anyone calls sweepProtocolFees(). The treasury balance and every transfer into it are public on the block explorer.
85% buys back $TETRO
85% of protocol revenue is used to buy back $TETRO on the open market. The remaining 15% funds operations, audits and infrastructure. Buybacks are executed from the treasury on-chain, so anyone can follow them on the explorer, and they are reported alongside treasury balances. $TETRO is not yet live; until it launches, the buyback share is held in the treasury for that purpose.
Ceilings no admin can raise
- Protocol fee per mechanic: ≤ 3.00%
- RWA marketplace fee: ≤ 1.00%
- Creator fee on curve trades: ≤ 2.00%
- Graduation fee on the curve raise: ≤ 5.00%
- Referral share of the protocol fee: ≤ 50%
- NFT royalties: ≤ 10% (ERC-2981, paid by marketplaces that honor it)
Live values are shown on the Review step of the launch wizard, in every order slip and on every RWA purchase.
Security
Security is a design constraint for Tetro, not a feature. These are the practices behind the contracts; the Security page in the Resources menu covers disclosure, scope and safe harbor.
- Contracts: Solidity 0.8.24, OpenZeppelin v5, UUPS for factories/registries, EIP-1167 clones for instances, ReentrancyGuard, custom errors.
- Tests: unit, fuzz and invariant suites (balance ≥ liabilities, no mint after deploy, no double claim/refund).
- Guarded launch: contracts start paused with a raise cap; admin is a Safe multisig with a timelock for upgrades.
- Static analysis: Slither and Aderyn run in CI.
- Bug bounty: report privately via Support (topic: Security report). Do not disclose publicly before a fix.
The Security page covers scope, safe harbor and how reports are handled: /security.
Stability index
Not every contract is equally mature. This index tells you what you can build on today and what may still change.
- Stable: LaunchToken, BondingCurve, TokenFactory, LiquidityLocker, FeeManager
- Stable: VestingVault, MerkleDistributor, FixedPriceSale, LaunchPool
- Beta: UniformPriceAuction, LimitOrderBook
- Beta: AgentRegistry, AgentAccount, AgentServiceEscrow
- Beta: CollectionFactory, Drop721, Edition1155
- Gated: RWAFactory and ERC-3643 suite (feature flag + issuer approval)
- Built, not deployed: MilestoneRaises, FeeStreams, BountyBoard (Coming soon)
Stable interfaces change only with a new version and a migration path. Beta interfaces may change between releases.
Official links
Scammers copy names, logos and websites. These are the only places Tetro publishes from. Anything else claiming to be Tetro is not us.
- App and docs: the domain you are on now. Bookmark it.
- X: @tetrofamily (https://x.com/tetrofamily), also linked from the Resources menu.
- Support: the Support page in the Resources menu. There is no support over DM.
- Contract addresses: the Smart Contracts pages of these docs, cross-checked on Blockscout.
- Policies: Terms of service, Privacy policy and the rest are collected at /legal.
Tetro staff never DM first, never ask for a seed phrase or private key, and never ask you to sign a transaction to "verify" or "unlock" a wallet.