Building on Quero
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
Welcome to Quero
Quero is a marketplace for real-world assets on Robinhood Chain, built around one idea: owning a tokenized stock should not mean publishing your whole financial life. You hold every asset in your own wallet, and when you want privacy, you have tools that actually provide it.
There are no accounts and nothing to deposit with us. Quero never holds your funds or your keys. Every transaction is signed by you, from your wallet.
How the app is organised
- Quero Veil: Shield, Dark pool and Privacy Baskets. Sealed swap and ZK pass are coming soon.
- Assets: every listed asset, by category, plus Issuers and assets issued on Quero.
- Yield: Stock-backed loans, Rule vaults, Yield loop, Fee estimator and Asset pools, all coming soon.
- Exchange: Swap & move and Price calls. Perpetuals, Spread trades and Funding carry are coming soon.
- Create: Tokenize an asset, coming soon.
- More: Portfolio, Watchlist, Oracle feeds, Docs, Settings and Support.
Open today
- Assets: tokenized stocks, ETFs, gold, silver and Treasury bills with live Chainlink prices.
- Swap & move: swap on Robinhood Chain, or bring funds in from another network.
- Shield: break the link between the wallet that pays in and the wallet that takes out.
- Dark pool: sealed orders for stock tokens, crossed between traders at the Chainlink price.
- Privacy Baskets: swap USDG for one position across several assets, in one transaction.
- Price calls: yes-or-no markets on stock prices, settled by Chainlink.
- Portfolio and Oracle feeds.
Everything else in the menu is marked Soon. Those entries are visible so you know what is coming, but they can't be clicked until they open.
Your first trade
- Add Robinhood Chain to your wallet (chain ID 4663) and fund it with a little ETH for gas.
- Open Assets and pick what you want to hold. The price you see comes from Chainlink, not from Quero.
- Buy it in Swap & move. The transaction is simulated first, you approve the exact amount and nothing more, and you see the route and the minimum you will receive before you sign.
- Check Portfolio. If you want your next move to be private, read Shield before you make it.
What we hold ourselves to
- No custody, ever.
- Every number says where it comes from.
- Limits and costs are on screen before you sign, not after.
- Privacy claims are specific. We say exactly what each tool hides and what it doesn't.
Frequently asked questions
Is Quero a broker or an exchange?
Neither. Quero is an interface to markets that run on-chain. We don't hold order books, balances or keys. Swaps run through public pools and every transaction is signed from your wallet.
Do I own the real stock when I hold a stock token?
You hold a token issued by a third party. What it represents, how it is backed and what you can redeem it for are set by that issuer's terms. Quero doesn't issue these tokens or hold the underlying assets. Read the issuer's documents before you rely on a token.
What does Quero Veil actually hide?
It depends on the tool, and each page says so plainly. Shield hides which deposit a withdrawal came from. The Dark pool hides your side, size and limit until a batch settles. None of them make you anonymous: your wallet address and the transactions it sends are always public on a public chain.
Where do prices come from?
Chainlink price feeds on Robinhood Chain. A feed updates when the price moves past a threshold, or at least once a day. Stock feeds don't update while US exchanges are closed, so over a weekend you see Friday's last price, with its time.
Why is a swap blocked or showing high price impact?
Some pools are still thin. Above 3% price impact the app warns you, and above 30% it blocks the swap because the pool can't absorb the order. Try a smaller size or a deeper pair such as ETH and USDG.
Why can't I click some menu items?
They are marked Soon. The contracts exist but the feature isn't open yet, so the menu shows it without letting you in. It becomes clickable the day it opens.
Which wallet and network do I need?
Any wallet that supports custom EVM networks, on Robinhood Chain (chain ID 4663), with ETH for gas. The Robinhood Chain guide has the settings.
Are there fees?
Quero adds no fee to swaps. You pay the pool fee and network gas. The Dark pool charges 0.1% on filled orders. Every cost is listed in Fees and costs.
Can I use Quero from my country?
You are responsible for the laws that apply to you. Issuers can restrict who holds their assets, and you may not use Quero from a sanctioned region or if you are on a sanctions list. See the Terms of service.
Live now
Assets
Assets lists every tokenized real-world asset with a live market on Robinhood Chain: single stocks, ETFs, gold, silver and a Treasury bill ETF. Seventeen of them are priced by Chainlink today, and each has its own page with price, chart, supply, volume and issuer.
Reading an asset page
- Price: the latest Chainlink price in USD.
- Tokenized value: tokens in existence multiplied by the price. This is the value of the token on this chain, not the company's market capitalisation.
- 24-hour change: from prices Quero records every minute. It stays empty until a full day exists, rather than passing off a shorter window as 24 hours.
- 24-hour volume: what traded in this chain's pools, in USDG. It reflects on-chain liquidity only, so it can be small next to the listed stock.
- Issuer: who minted the token and what they have published about it.
Categories
- Stocks: Apple, Microsoft, NVIDIA, Amazon, Alphabet, Meta, Tesla, AMD, TSMC, Coinbase, Palantir and Strategy.
- Funds & indexes: SPY and QQQ.
- Gold & commodities: GLD and SLV.
- Treasuries: SGOV, a short-term Treasury bill ETF.
- Private credit: listed when an issuer publishes it.
Issuers and Quero-issued
Issuers shows who stands behind each token and what it has published. Quero-issued is coming soon.
Before you buy
- A token tracks an underlying price and is issued by a third party. Backing and redemption are set by that issuer.
- Liquidity is still building. Large orders can move the price, and the swap screen tells you by how much before you sign.
Swap & move
Swap & move does two jobs. It swaps one token for another on Robinhood Chain, and it brings funds in from another network so you can start trading without a separate bridge.
Swapping on Robinhood Chain
- Tokens: ETH, WETH, USDG and every asset listed in Assets.
- Routing: the direct pool and the routes through USDG and WETH are compared, and the one that returns the most is used.
- Approvals: you approve the exact amount of this swap, never an unlimited allowance.
- Slippage: 0.5%, 1% or 2%. The swap reverts rather than fill below the minimum shown.
- Deadline: a swap that sits in the mempool for more than 20 minutes is cancelled by the contract.
- Cost: each pool takes 0.3% for its liquidity providers, plus gas. Quero takes nothing.
Moving funds in from another network
Pay from Ethereum, Base, Arbitrum and most other EVM networks, and receive on Robinhood Chain. Routes come from LI.FI. Each route shows its expected output, time and fees before you sign, and the transfer is tracked until it arrives.
Price impact
Above 3% the app warns you. Above 30% it blocks the order, because the pool is too thin for it. Splitting a large order usually gets a better result.
A note on privacy
Swaps and bridges are public. Anyone can see which wallet traded what. If you want to separate your activity from a wallet, use Shield.
Shield
Shield is the first tool in Quero Veil. It breaks the on-chain link between the wallet that pays in and the wallet that takes out. Every deposit in a pool is the same size, and a withdrawal proves with a zero-knowledge proof that it owns one of those deposits, without revealing which one.
How it works
- Choose a pool: 0.1 ETH, 1 ETH, 100 USDG or 1,000 USDG.
- Your browser creates a private note. Save it somewhere safe. It is the only key to your deposit and it never leaves your device.
- Shield: send the pool amount from your wallet.
- Later, paste the note, choose any receiving wallet and prove. The proof is built in your browser, usually in 10 to 60 seconds.
- Receive the pool asset, or swap it on the way out into USDG or ETH at the best pool route, with a minimum you set.
What it hides, and what it doesn't
- Hidden: which deposit a withdrawal came from.
- Public: that a deposit happened, and that a withdrawal happened. Amounts are public too, because every deposit in a pool is the same.
- Privacy grows with the pool. The more deposits sit beside yours, the harder it is to guess which one is yours.
Getting the most from it
- Withdraw to a wallet that has never interacted with the one that deposited.
- Leave time between the deposit and the withdrawal.
- Lose the note and the deposit is gone. Nobody, including Quero, can recover it.
Costs
Gas for the deposit and the withdrawal. A swap on the way out pays the pool fee of its route. Shield itself charges nothing.
Shield is the fixed-amount version. Shield V2 adds any-amount balances in USDG and Ethereum and private trading in batches. See Shield V2.
Dark pool
The Dark pool lets traders cross orders for a stock token with each other at the Chainlink price, without showing their hand. Orders stay sealed until the batch closes, so nobody sees your side, size or limit while it is open, and there is no pool price to push around.
A batch, step by step
- Fund your dark pool balance with USDG or the stock token. A deposit says nothing about what you plan to do.
- Commit, 10 minutes: submit your order as a sealed hash of side, amount and limit.
- Reveal, 5 minutes: reveal it from the same browser.
- Settle: after the batch ends anyone can settle it. Revealed orders whose limit the Chainlink price satisfies cross at that price. If one side is bigger, it fills pro rata.
- Anything that didn't cross stays in your balance for the next batch or a withdrawal.
Markets
One dark pool per stock token, quoted in USDG: SPY, QQQ, GLD, SLV, SGOV, AAPL, MSFT, NVDA, AMZN, GOOGL, META, TSLA, AMD, TSM, COIN, PLTR and MSTR.
What stays private
Your order is private until the batch settles. After settlement the fills are public, as every on-chain trade is. What you avoid is being traded against while your order is open.
Fee
0.1% of what you receive on a filled order. Orders that don't cross pay nothing.
Privacy Baskets
Privacy Baskets give you exposure to several assets through one position. Swap USDG for QBasket units in one transaction and each unit is your share of every asset in the basket, at the basket's weights.
For example, 100 USDG can become units of a basket holding AAPL, NVDA and GOOGL, or GLD, SLV and SGOV. The basket's smart contract keeps the tokens; your wallet holds the units.
Buying
- Pick a basket and enter an amount of USDG.
- One transaction swaps your USDG into every asset at the best routes on Robinhood Chain, mints your units and returns anything left over. The first time, you also approve USDG once.
- You set a maximum slippage. If any route fills below it, the whole transaction reverts and you keep your USDG.
Building your own
- Choose the assets and their weights, or start from a template.
- Set what one unit is worth at launch, for example 100 USDG. Each weight becomes a fixed token amount at that day's Chainlink prices.
- The recipe can't change after creation. As prices move, the weights drift with them; there is no rebalancing.
- A basket has no owner powers. Nobody, including its creator, can change it, pause it or touch what it holds.
Getting out
- Redeem: your share of every token is sent to your wallet. Each transfer can be seen on-chain.
- Sell units on the market: the proceeds come to your wallet and the tokens stay in the contract. This needs a market for the units, which appears once someone provides liquidity for them.
- Sell through the assets: one transaction redeems your units and sells each token back to USDG. If the total comes in below your limit, nothing happens and you keep your units.
What stays private, and what doesn't
- While you hold QBasket units, your wallet shows one basket position rather than each stock.
- Selling units on the market moves the units, not the tokens inside.
- Redeeming is public: each token transfer to your wallet is visible.
- The basket's recipe and your unit balance are public, so anyone who looks can estimate your exposure to each asset.
Costs and safety
- Quero charges no fee. You pay the routes' own pool fees and gas.
- Buying and selling run through ArcaneBasketZap, which only works with baskets from Quero's factory, sends swaps to one aggregator fixed at deployment, keeps nothing between transactions and has no admin.
- Contracts: ArcaneBasketZap 0xD95d79205B6499A34D979D472687c25339c25928 and the basket factory 0x9B5B5da3748786F014EcefB3a80Aea7C70ADFc27 on Robinhood Chain.
Price calls
Price calls are yes-or-no markets on real stock prices, such as whether a stock closes above a set price on a given day. Stakes pool on each side. When the market closes, the first Chainlink price after the close decides it, and the winning side shares the pool.
- Settlement comes from Chainlink, so there is no human resolver and no dispute process.
- Staking stops shortly before the close, so nobody can bet on a price that is already known.
- A small fee, fixed in the contract, is taken from the pool before the winning side is paid. The rate is shown before you stake.
- If a market can't be settled from a valid price, every stake is refunded in full. Refunds can never be paused.
Portfolio
Portfolio shows the real-world assets a wallet holds, read straight from the chain.
- Connect a wallet to see its holdings.
- To view another address, add ?wallet=0x… to the link. It is read-only.
- Balances are as current as the latest block.
Portfolio never moves anything. Notes held in Shield don't appear here, because they belong to no wallet until you withdraw them.
Coming soon
What is coming
These features show as Soon in the menu. Each gets its full guide here on the day it opens.
- Quero Veil: Sealed swap and ZK pass
- Yield: Stock-backed loans, Rule vaults, Yield loop, Fee estimator and Asset pools
- Exchange: Perpetuals, Spread trades and Funding carry
- Create: Tokenize an asset and Quero-issued
- Assistant
Sealed swap and ZK pass
Coming soon.
This feature isn't open yet. Its full guide will be published here on the day it opens.
Yield
Coming soon.
This feature isn't open yet. Its full guide will be published here on the day it opens.
Perpetuals, Spread trades and Funding carry
Coming soon.
This feature isn't open yet. Its full guide will be published here on the day it opens.
Tokenize an asset and Quero-issued
Coming soon.
This feature isn't open yet. Its full guide will be published here on the day it opens.
Assistant
Coming soon.
This feature isn't open yet. Its full guide will be published here on the day it opens.
In development
Shield V2
Shield V2 opens in a coming update. Shield V1, the fixed-amount pools, is live and stays as it is.
What it does
- Keep a shielded balance in USDG and Ethereum, in any amount.
- Send any amount privately to another shielded address.
- Trade between USDG and Ethereum inside your shielded balance, in 10-minute batches.
- Withdraw any amount to any address, as USDG, or as Ethereum straight to the receiving wallet.
Your key
Your shielded key comes from one signature of your wallet, made in your browser. The signature sends no transaction. The same wallet rebuilds the same balance on any device from the chain, so there is no note file to keep. The first time, the app asks for the signature twice to check that your wallet signs the same way each time.
A viewing key shows your incoming notes, your orders and which notes you spent. It cannot move funds. You can export it from the Shield page and share it with someone you choose, such as an accountant.
How the balance works
Your balance is a set of notes in one pool shared by every wallet and both assets. For each note the chain stores a commitment and the note itself, encrypted to your key. Spending a note publishes a one-time tag that stops it being spent twice without pointing at the note.
Every spend carries a zero-knowledge proof, built in your browser in a few seconds. It shows that the notes are yours and that the amounts add up, and it reveals neither the notes nor your keys.
Trading in batches
- Your order joins the batch that is open when it lands. Each batch runs for 10 minutes.
- When the batch closes, buy and sell orders meet each other at the Chainlink price.
- The rest is swapped once on Uniswap v4, up to the price bound of the pair.
- Every order in the batch gets the same rate. Whatever does not fill within the bound returns to your shielded balance.
- Anyone can settle a closed batch and claim its orders, so results arrive without a step from you. Only you can open and spend the notes a claim creates.
The fee is 0.10% of each batch's output.
What stays private
- Who placed an order, which notes paid for it, and where its result goes.
- Who sent a private transfer, who received it, and the amount.
- Which deposit a later transfer, order or withdrawal came from.
On the public chain
- Deposits and withdrawals: the wallet, the asset and the amount.
- Each order's amount and direction, and each batch's totals and rate.
Built into the contracts
- The pool always holds at least what all unspent notes and open orders add up to.
- No note can be spent twice.
- A proof cannot create value: what goes out equals what came in, per asset.
- One rate per batch, and a batch never pays out more than it received.
- A proof is bound to its chain, its pool and its recipient, so it cannot be replayed or redirected.
API
API
The data behind Assets is available over a small REST API. Endpoints are versioned under /v1 and return { data, error }. Big integers are sent as strings.
- GET /v1/market/stocks: price, 24-hour change and 24-hour volume for every listed stock token, keyed by token address.
- GET /v1/market/series?token=0x…&range=1d|1w: recorded prices as [timestampMs, priceUsd] pairs.
- GET /v1/oracles: every Chainlink feed on Robinhood Chain with its latest answer.
- GET /v1/status: health of the API, database, RPC and indexer.
curl https://api.quero.family/v1/market/stocksRate limits
120 requests per minute per IP by default. Send an x-api-key header for higher limits. Responses carry x-ratelimit-limit and x-ratelimit-remaining.
A 24-hour change of null means a full day of prices doesn't exist yet. Null means unknown, never zero.
Oracle data feeds
Chainlink runs price feeds on Robinhood Chain (chain ID 4663) for stock tokens, ETFs, a Treasury bill ETF, gold, silver, oil, crypto, stablecoins and staking exchange rates. Each feed is a public contract: anyone can read it, and any contract can build on it. The Oracle data feeds page lists every one with its latest answer.
What a feed is
A feed is an aggregator contract behind a proxy. Chainlink oracle nodes publish a new answer when the price moves past the feed's deviation threshold, or when the heartbeat runs out without such a move. Always call the proxy address: Chainlink can replace the aggregator behind it without changing the address you read.
- Heartbeat: 24 hours on every Robinhood Chain feed.
- Deviation threshold: 0.5 percent for prices, 0.05 percent for exchange rates.
- Decimals: 8 for USD prices and 18 for exchange rates. Read decimals() instead of assuming it.
- latestRoundData() returns roundId, answer, startedAt, updatedAt and answeredInRound. The price is answer / 10^decimals.
Read a feed in Solidity
interface AggregatorV3Interface {
function decimals() external view returns (uint8);
function latestRoundData() external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
}
contract UsesAapl {
// Robinhood AAPL / USD, proxy on Robinhood Chain
AggregatorV3Interface constant FEED = AggregatorV3Interface(0x6B22A786bAa607d76728168703a39Ea9C99f2cD0);
// US equity feed: 90 hours covers a weekend plus one heartbeat; use heartbeat plus 10 percent for 24/7 feeds
uint256 constant MAX_AGE = 90 hours;
function aaplUsd() external view returns (uint256 price, uint8 decimals) {
(, int256 answer, , uint256 updatedAt, ) = FEED.latestRoundData();
require(answer > 0, "no price");
require(block.timestamp - updatedAt <= MAX_AGE, "stale price");
return (uint256(answer), FEED.decimals());
}
}Read a feed with viem
import { createPublicClient, formatUnits, http, parseAbi } from "viem";
const abi = parseAbi([
"function decimals() view returns (uint8)",
"function latestRoundData() view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)",
]);
const client = createPublicClient({ transport: http(process.env.RPC_URL) }); // a Robinhood Chain RPC
const feed = "0x6B22A786bAa607d76728168703a39Ea9C99f2cD0"; // Robinhood AAPL / USD
const [decimals, [, answer, , updatedAt]] = await Promise.all([
client.readContract({ address: feed, abi, functionName: "decimals" }),
client.readContract({ address: feed, abi, functionName: "latestRoundData" }),
]);
console.log(formatUnits(answer, decimals), new Date(Number(updatedAt) * 1000));When a price counts as stale
Quero marks a feed stale when its answer is zero or negative, or when its last update is older than the heartbeat plus 10 percent, which is 26.4 hours. Feeds that follow US market hours trade 24 hours a day, five days a week, and do not update over the weekend, so Quero allows them up to 90 hours before calling them stale: about 60 hours from Friday close to Monday open, plus one heartbeat. A feed that cannot be read shows no price and counts as stale.
Run the same checks in your own contracts: reject an answer that is zero or negative, and reject one older than the age your product can tolerate.
Asset classes
- Stocks: Robinhood stock tokens such as AAPL, NVDA, TSLA, MSFT and COIN.
- ETFs: SPY, QQQ and EWY.
- Treasuries: SGOV, an ETF of short-term US Treasury bills.
- Commodities: GLD for gold, SLV for silver and USO for oil.
- Crypto: ETH, BTC, LINK, ENA and wrapped or staked versions such as WBTC, CBBTC and WSTETH.
- Stablecoins: USDC, USDT, USDG, USDE, USDS and EURC.
- Rates: the exchange rate between a staking or yield token and its base asset, such as WSTETH to STETH.
Stock tokens
A stock token feed reports the price of one token, not of one share. The token's multiplier, which reinvests dividends and absorbs splits, is already applied, so a feed can sit above the headline share price. Do not apply the multiplier a second time. Stock, ETF, SGOV, SLV and USO feeds follow US market hours.
From the Quero API
GET /v1/oracles # every feed
GET /v1/oracles?class=equity # or etf, treasury, commodity, crypto, stablecoin, rate
GET /v1/oracles?q=aapl # name, Chainlink path or proxy address
GET /v1/oracles/robinhood-aapl-usd-shared-svr
{
"id": "robinhood-aapl-usd-shared-svr",
"name": "Robinhood AAPL / USD",
"assetClass": "equity",
"proxy": "0x6B22A786bAa607d76728168703a39Ea9C99f2cD0",
"decimals": 8, "heartbeat": 86400, "threshold": 0.5,
"marketHours": "us_equities_24/5",
"price": "346.49853494", "updatedAt": 1792686111,
"roundId": "18446744073709552415", "stale": false
}id is Chainlink's path for the feed, heartbeat is in seconds, threshold is in percent, price is a decimal string and updatedAt is in Unix seconds. A feed that could not be read returns price, updatedAt and roundId as null with stale true. Answers are read on chain at most once every 30 seconds, and the route shares the API's rate limit.
Robinhood Chain
Robinhood Chain guide
Quero runs on Robinhood Chain, an Arbitrum Orbit layer 2 that settles to Ethereum. Fees are low, blocks are fast, and transactions inherit Ethereum's security.
- Network name: Robinhood Chain
- Chain ID: 4663
- Currency: ETH
- Explorer: https://robinhoodchain.blockscout.com
- RPC: https://rpc.mainnet.chain.robinhood.com, or your own provider
Getting funds in
There is no faucet on mainnet. Use Swap & move to bring funds from another network, bridge ETH from Ethereum through the official Robinhood Chain bridge, or withdraw from an exchange that supports the network.
Gas
A fee has a layer 2 execution part and a layer 1 data part. Your wallet's estimate includes both, and Quero shows the total before you sign. Transactions use EIP-1559.
Smart contracts
Contract addresses
Network: Robinhood Chain · 4663. Addresses are read from contracts/deployments/<network>.json, written by the deploy script. Always check them on the explorer before you interact. Open a contract below to see its functions, events, errors and ABI.
RWAFactoryIssues an RWA token and its compliance contract for approved issuers.0xfd5a…f211
Issues an RWA token and its compliance contract for approved issuers.
Address (Robinhood Chain · 4663): 0xfd5a…f211
Download ABIWrite functions
- grantRole(bytes32 role, address account)
- issue(string name, string symbol, uint8 decimals, string documentURI, bytes32 documentHash) → address, address
- renounceRole(bytes32 role, address callerConfirmation)
- revokeRole(bytes32 role, address account)
- setIssuerApproved(address issuer, bool a)
Read functions
- DEFAULT_ADMIN_ROLE() → bytes32
- ISSUER_APPROVER_ROLE() → bytes32
- allTokens(uint256) → address
- approvedIssuer(address issuer) → bool
- assetCount() → uint256
- getRoleAdmin(bytes32 role) → bytes32
- hasRole(bytes32 role, address account) → bool
- isArcaneAsset(address token) → bool
- issuerOf(address token) → address
- registry() → address
- supportsInterface(bytes4 interfaceId) → bool
Events
- AssetIssued(address issuer, address token, address compliance, string name, string symbol, uint8 decimals, string documentURI, bytes32 documentHash)
- 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)
Errors
- AccessControlBadConfirmation()
- AccessControlUnauthorizedAccount(address account, bytes32 neededRole)
- EmptyText()
- IssuerNotApproved()
- ZeroAddress()
RWATokenERC-3643-style security token: verified receivers, modular compliance, agent freeze, forced transfer and recovery. One per asset.One per instance
ERC-3643-style security token: verified receivers, modular compliance, agent freeze, forced transfer and recovery. One per asset.
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)
- setDocument(string uri, bytes32 hash)
- 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
- documentHash() → bytes32
- 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, bytes32 hash)
- ForcedTransfer(address from, address to, uint256 amount, address agent)
- Paused(address account)
- RecoverySuccess(address lost, address replacement, address agent)
- 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)
- ZeroAddress()
ComplianceModular transfer rules for one RWA token, owned by its issuer. One per asset.One per instance
Modular transfer rules for one RWA token, owned by its issuer. One per asset.
Address (Robinhood Chain · 4663): One clone per token or sale. See its page
Download ABIWrite functions
- acceptOwnership()
- addModule(address m)
- bindToken(address t)
- removeModule(address m)
- renounceOwnership()
- transferOwnership(address newOwner)
- transferred(address from, address to, uint256 amount)
Read functions
- MAX_MODULES() → uint256
- canTransfer(address from, address to, uint256 amount) → bool
- isModule(address) → bool
- moduleCount() → uint256
- modules(uint256) → address
- owner() → address
- pendingOwner() → address
- token() → address
Events
- ModuleAdded(address module)
- ModuleRemoved(address module)
- OwnershipTransferStarted(address previousOwner, address newOwner)
- OwnershipTransferred(address previousOwner, address newOwner)
- TokenBound(address token)
Errors
- ModuleExists()
- ModuleMissing()
- NotToken()
- OwnableInvalidOwner(address owner)
- OwnableUnauthorizedAccount(address account)
- TokenAlreadyBound()
- TooManyModules()
IdentityRegistryShared registry of verified investor wallets with a KYC record hash, country and optional expiry.0x0867…0cEd
Shared registry of verified investor wallets with a KYC record hash, country and optional expiry.
Address (Robinhood Chain · 4663): 0x0867…0cEd
Download ABIWrite functions
- grantRole(bytes32 role, address account)
- register(address wallet, bytes32 recordHash, uint16 country, uint64 expiresAt)
- remove(address wallet)
- renounceRole(bytes32 role, address callerConfirmation)
- revokeRole(bytes32 role, address account)
- setSystem(address account, bool allowed)
- update(address wallet, bytes32 recordHash, uint16 country, uint64 expiresAt)
Read functions
- DEFAULT_ADMIN_ROLE() → bytes32
- SYSTEM_MANAGER_ROLE() → bytes32
- VERIFIER_ROLE() → bytes32
- getRoleAdmin(bytes32 role) → bytes32
- hasRole(bytes32 role, address account) → bool
- identities(address wallet) → bytes32, uint16, uint64, address
- investorCountry(address wallet) → uint16
- isSystem(address account) → bool
- isVerified(address wallet) → bool
- supportsInterface(bytes4 interfaceId) → bool
Events
- IdentityRegistered(address wallet, bytes32 recordHash, uint16 country, uint64 expiresAt, address verifier)
- IdentityRemoved(address wallet, address by)
- IdentityUpdated(address wallet, bytes32 recordHash, uint16 country, uint64 expiresAt, address verifier)
- RoleAdminChanged(bytes32 role, bytes32 previousAdminRole, bytes32 newAdminRole)
- RoleGranted(bytes32 role, address account, address sender)
- RoleRevoked(bytes32 role, address account, address sender)
- SystemAccount(address account, bool allowed)
Errors
- AccessControlBadConfirmation()
- AccessControlUnauthorizedAccount(address account, bytes32 neededRole)
- AlreadyRegistered()
- BadExpiry()
- EmptyRecord()
- NotRegistered()
- ZeroAddress()
PrimarySaleFixed-price RWA offerings paid in an allowed stablecoin, with a soft cap, refunds and escrowed delivery.0x5942…c8Fb
Fixed-price RWA offerings paid in an allowed stablecoin, with a soft cap, refunds and escrowed delivery.
Address (Robinhood Chain · 4663): 0x5942…c8Fb
Download ABIWrite functions
- buy(uint256 id, uint256 amount, uint256 maxCost)
- claim(uint256 id)
- createOffering(address token, address payToken, address proceedsTo, uint256 price, uint256 supply, uint256 softCap, uint256 maxPerWallet, uint64 start, uint64 end) → uint256
- grantRole(bytes32 role, address account)
- reclaimUnsold(uint256 id)
- refund(uint256 id)
- renounceRole(bytes32 role, address callerConfirmation)
- revokeRole(bytes32 role, address account)
- setPayToken(address payToken, bool allowed)
- settle(uint256 id)
- sweepFees(address payToken)
- withdrawProceeds(uint256 id)
Read functions
- DEFAULT_ADMIN_ROLE() → bytes32
- allowedPayToken(address) → bool
- bought(uint256 id, address buyer) → uint256
- factory() → address
- fees() → address
- feesOwed(address payToken) → uint256
- getRoleAdmin(bytes32 role) → bytes32
- hasRole(bytes32 role, address account) → bool
- offeringCount() → uint256
- offerings(uint256) → address, address, address, address, uint256, uint256, uint256, uint256, uint64, uint64, uint256, uint256, bool, bool
- paid(uint256 id, address buyer) → uint256
- proceedsOwed(uint256 id) → uint256
- quote(uint256 id, uint256 amount) → uint256
- reserved(address token) → uint256
- supportsInterface(bytes4 interfaceId) → bool
- unsoldOwed(uint256 id) → uint256
Events
- FeesSwept(address payToken, address to, uint256 amount)
- OfferingCreated(uint256 id, address token, address issuer, address payToken, uint256 price, uint256 supply, uint256 softCap, uint256 maxPerWallet, uint64 start, uint64 end)
- PayTokenAllowed(address payToken, bool allowed)
- ProceedsWithdrawn(uint256 id, address to, uint256 amount)
- Purchased(uint256 id, address buyer, uint256 amount, uint256 cost)
- Refunded(uint256 id, address buyer, uint256 amount)
- RoleAdminChanged(bytes32 role, bytes32 previousAdminRole, bytes32 newAdminRole)
- RoleGranted(bytes32 role, address account, address sender)
- RoleRevoked(bytes32 role, address account, address sender)
- Settled(uint256 id, bool succeeded, uint256 sold, uint256 raised, uint256 fee)
- TokensClaimed(uint256 id, address buyer, uint256 amount)
- UnsoldReturned(uint256 id, address to, uint256 amount)
Errors
- AccessControlBadConfirmation()
- AccessControlUnauthorizedAccount(address account, bytes32 neededRole)
- AlreadySettled()
- BadOffering()
- CostAboveMax(uint256 cost, uint256 maxCost)
- FeeOnTransferToken()
- NotCompliant()
- NotEnded()
- NotEnoughTokensInEscrow(uint256 available, uint256 needed)
- NotIssuer()
- NotOpen()
- NotSettled()
- NotVerified()
- NothingToClaim()
- PayTokenNotAllowed()
- ReentrancyGuardReentrantCall()
- SafeERC20FailedOperation(address token)
- SalesPaused()
- SoldOut(uint256 left)
- WalletLimit(uint256 limit)
- ZeroAddress()
CountryRestrictModuleCompliance module that blocks receivers from chosen countries.0x9B24…c61f
Compliance module that blocks receivers from chosen countries.
Address (Robinhood Chain · 4663): 0x9B24…c61f
Download ABIWrite functions
- setBlocked(address compliance, uint16[] countries, bool b)
- transferred(address, address, uint256)
Read functions
- blocked(address compliance, uint16 country) → bool
- canTransfer(address, address to, uint256) → bool
- name() → string
- registry() → address
Events
- CountryBlocked(address compliance, uint16 country, bool blocked)
Errors
- NotComplianceOwner()
MaxHoldersModuleCompliance module that caps the number of holders.0xcb2e…6165
Compliance module that caps the number of holders.
Address (Robinhood Chain · 4663): 0xcb2e…6165
Download ABIWrite functions
- setMaxHolders(address compliance, uint256 m)
- transferred(address from, address to, uint256 amount)
Read functions
- canTransfer(address, address to, uint256) → bool
- holders(address compliance) → uint256
- maxHolders(address compliance) → uint256
- name() → string
- registry() → address
Events
- MaxHoldersSet(address compliance, uint256 max)
Errors
- NotComplianceOwner()
MaxBalanceModuleCompliance module that caps a single wallet's balance.0x94E0…D20b
Compliance module that caps a single wallet's balance.
Address (Robinhood Chain · 4663): 0x94E0…D20b
Download ABIWrite functions
- setMaxBalance(address compliance, uint256 m)
- transferred(address, address, uint256)
Read functions
- canTransfer(address, address to, uint256 amount) → bool
- maxBalance(address compliance) → uint256
- name() → string
- registry() → address
Events
- MaxBalanceSet(address compliance, uint256 max)
Errors
- NotComplianceOwner()
LockupModuleCompliance module that holds new receipts for a lockup period.0x5Db0…3259
Compliance module that holds new receipts for a lockup period.
Address (Robinhood Chain · 4663): 0x5Db0…3259
Download ABIWrite functions
- setPeriod(address compliance, uint64 p)
- transferred(address, address to, uint256)
Read functions
- canTransfer(address from, address to, uint256) → bool
- lastReceived(address compliance, address wallet) → uint64
- name() → string
- period(address compliance) → uint64
- registry() → address
Events
- LockupSet(address compliance, uint64 period)
Errors
- NotComplianceOwner()
RegistryOn-chain index of the deployed Quero addresses.0xB9CF…9454
On-chain index of the deployed Quero addresses.
Address (Robinhood Chain · 4663): 0xB9CF…9454
Download ABIWrite functions
- grantRole(bytes32 role, address account)
- renounceRole(bytes32 role, address callerConfirmation)
- revokeRole(bytes32 role, address account)
- set(bytes32 key, address addr)
- setMany(bytes32[] ks, address[] addrs)
Read functions
- DEFAULT_ADMIN_ROLE() → bytes32
- addressOf(bytes32 key) → address
- getRoleAdmin(bytes32 role) → bytes32
- hasRole(bytes32 role, address account) → bool
- keyCount() → uint256
- keys(uint256) → bytes32
- supportsInterface(bytes4 interfaceId) → bool
Events
- AddressSet(bytes32 key, address addr)
- 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)
- ZeroAddress()
Resources
Fees and costs
Everything you can pay today, and nothing else.
- Pool fee: 0.3% per pool a swap passes through, paid to that pool's liquidity providers. A route through two pools pays it twice, and the route is shown before you sign.
- Network gas: paid in ETH to Robinhood Chain, not to Quero.
- Moving funds in from another network: the route's own bridge and gas fees, shown on each route.
- Dark pool: 0.1% of what you receive on a filled order. Nothing on orders that don't cross.
- Price calls: a small fee from each settled pool, fixed in the contract and shown before you stake.
- Shield and Privacy Baskets: no Quero fee.
- Quero: no fee on swaps, on browsing assets or on viewing a portfolio.
If a feature ever adds a fee, it will be written on that feature's page and shown in the summary before you sign.
Security
Quero is built so that the worst a mistake in the app can do is limited. These are the practices behind that.
- No custody: we never hold funds or keys. You sign every transaction.
- Simulate first: every transaction is simulated before your wallet asks for a signature. If it would fail, nothing is sent and nothing is spent.
- Exact approvals: you approve what you are spending, never an unlimited allowance.
- Price guards: swaps carry a minimum received and a deadline, and extreme price impact is blocked.
- Oracle safety: stale or invalid Chainlink prices are rejected, so features that depend on them stop rather than act on a bad number.
- Proofs in your browser: Shield proofs are generated on your device. Your note never reaches our servers.
- Tests: contracts are covered by unit, fuzz and invariant tests and built on OpenZeppelin components.
Check contract addresses on the explorer and never share your seed phrase. To report a vulnerability, see /security.
Feature status
What you can use today, what is built and waiting, and what is still being built.
Live
- Assets: all categories, Issuers
- Swap & move
- Quero Veil: Shield, Dark pool and Privacy Baskets
- Price calls
- Portfolio
- Oracle feeds
Soon
- Quero Veil: Sealed swap, ZK pass
- Yield: Stock-backed loans, Rule vaults, Yield loop, Fee estimator, Asset pools
- Exchange: Perpetuals, Spread trades, Funding carry
- Create: Tokenize an asset, Quero-issued
- Assistant
In development
- Shield V2: private balances and private trading inside the pool
Soon means the contracts are deployed and the feature is waiting to open. In development means the design is done and the code is not deployed. This page changes the day anything moves.
Official links
Scammers copy names, logos and websites. These are the only places Quero publishes from.
- App and docs: the domain you are on now. Bookmark it.
- X: @querofamily (https://x.com/querofamily), also linked in the footer.
- Support: the Support page under More. We don't offer support through social media DMs.
Quero staff never message you first, never ask for a seed phrase or private key, and never ask you to sign a transaction to "verify" or "unlock" a wallet.