One ticker. The whole basket.
MemeETF is a permissionless issuer of exchange-traded memecoin baskets on BNB Chain. Each ETF is a single BEP-20 token fully collateralized, in kind, by the components it holds. This page documents the protocol precisely enough to integrate against it: contract roles, transaction flows, fee mathematics, enforced constraints and the security model.
Overview
An ETF is an ERC-20 unit token whose supply is always backed by a vault of 2–10 component tokens. Units are minted only when the exact pro-rata slice of every component is deposited, and burned only when that slice is withdrawn. Nothing is minted against a price feed; the vault is the source of truth.
- Permissionless. Anyone can issue an ETF over any tokens that have a funded WBNB pool on PancakeSwap V2 or V3. No listing process by default.
- In kind. Redemption pays out the underlying coins, never a synthetic claim. Selling for BNB is a convenience layer on top of redemption.
- Non-custodial. No admin key can move vault assets, pause redemptions or change an ETF's basket after issuance.
- Manager economics. The issuer of an ETF — its manager — earns 70% of a 1% desk fee (paid instantly in BNB) and 70% of a streaming expense ratio (paid in units) for as long as the ETF holds assets.
Architecture
Four contracts, one of which is deployed per ETF:
| Contract | Instances | Role |
|---|---|---|
| EtfIssuer | 1 | Registry and deployer. Validates the basket against the issuance rules, deploys a MemeEtf, records it. Owned by the treasury for parameter updates only. |
| MemeEtf | 1 per ETF | ERC-20 unit token + vault. Holds components, mints/burns pro rata, streams the expense ratio, exposes AUM and unit-price views. |
| EtfDesk | 1 | BNB in / BNB out. Splits BNB across the basket via PancakeSwap and subscribes; redeems in kind and unwinds to BNB. Collects the desk fee. |
| PancakeQuoter | 1 (replaceable) | Discovers the deepest WBNB venue per token (V2 pair or V3 fee tier) and quotes spot prices. Used for display and the desk's BNB split only. |
user ──BNB──▶ EtfDesk ──issueFor / isEtf──▶ EtfIssuer ──new──▶ MemeEtf (vault + ERC-20)
│ ▲ ▲
│ └── venue / quote ── PancakeQuoter ───────────────┘ (aum / unitPrice views)
└── swaps ──▶ PancakeSwap V2 Router / V3 SwapRouter ──▶ tokens ──subscribe──▶ MemeEtfThe quoter is the only upgradeable pointer (EtfIssuer.setQuoter). Swapping it changes how AUM is displayed and how the desk splits BNB; it cannot change what a unit is redeemable for.
Lifecycle
1 · Issue and seed
EtfDesk.issueAndSeed(name, symbol, components, allocations, expenseRatioBps, minUnits) with msg.value as the opening subscription. In one transaction the desk asks the issuer to deploy the ETF with manager = msg.sender, takes the desk fee, splits the remaining BNB by target allocation, buys each component on its deepest venue and calls MemeEtf.subscribe. Because issuance and seed settle atomically, an ETF is never listed empty and its opening basket cannot be front-run.
The first subscription prices units at ISSUE_PRICE = 0.01 BNB of value per unit, valued on the tokens that actually landed in the vault (so fee-on-transfer tokens cannot over-mint).
2 · Buy
EtfDesk.enter(etf, minUnits). After the desk fee, BNB is split by current value weights (reserves × quote) so every leg purchases the same unit fraction. The desk mints the largest units that every purchased leg can cover, pulls exactly quoteSubscribe(units) into the vault and refunds any rounding surplus in kind to the buyer. Direct in-kind subscription via MemeEtf.subscribe(units, maxIn) is also supported.
3 · Sell
EtfDesk.exit(etf, units, minBnbOut). Units are pulled, redeemed in kind to the desk, each leg is swapped to BNB on its deepest venue, the desk fee is taken from gross proceeds and the remainder is paid to the seller. Requires a prior approve of units to the desk.
4 · Redeem
MemeEtf.redeemInKind(units, minOut). Burns units and transfers reserves[i] × units / totalSupply of each component to the caller. No fee, no permission, no lock-up. This path never touches an AMM or a price and is therefore the protocol's safety exit.
Unit price & quotes
aum = Σ reserves[i] × quote(token[i]) / 1e18 and unitPrice = aum × 1e18 / totalSupply. Quotes are decimals-agnostic: the quoter returns BNB wei per 1e18 raw token units, so the same formula works for 8-, 9- and 18-decimal tokens.
Venue selection. For each token the quoter inspects the PancakeSwap V2 WBNB pair and the four V3 fee tiers (0.01%, 0.05%, 0.25%, 1%) and picks the pool holding the most WBNB. The desk trades on that same pool. V2 quote is reserveWBNB / reserveToken; V3 quote is derived from slot0.sqrtPriceX96.
Quotes are informational. They drive the board and account figures and the BNB split inside the desk. They never determine how many units a deposit mints after the seed, nor what a unit redeems for.
Fees
| Fee | Rate | Paid in | Timing | Split |
|---|---|---|---|---|
| Desk fee | 1.00% (owner-adjustable, hard cap 3%) | BNB | Instantly on every desk buy and sell | 70% manager / 30% treasury |
| Expense ratio | 0–3.00% p.a., fixed by the manager at issuance | Newly minted units | Streams continuously; collected on any subscribe/redeem or via collectExpense() | 70% manager / 30% treasury |
| Redeem in kind | 0 | — | — | — |
Expense accrual is linear: units = totalSupply × expenseRatioBps × Δt / (10 000 × 365 days). Minting these units dilutes holders by exactly the expense ratio — standard ETF mechanics — while vault reserves are untouched. quoteSubscribe and quoteRedeem already include accrued expense units, so quotes match execution within the same block.
If a manager address cannot receive BNB (e.g. a contract without a payable fallback), its desk-fee cut falls through to the treasury rather than blocking the trade.
Issuance rules
Enforced by EtfIssuer at issuance; an ETF that violates any rule cannot be deployed.
| Rule | Default | Rationale |
|---|---|---|
| Component count | 2 – 10 | Enough to be a basket, small enough to stay legible and gas-bounded. |
| Max allocation per component | 60% | No basket is one token in a trench coat. |
| Allocations | Sum to exactly 100%, each > 0 | Deterministic opening split. |
| Duplicates | Not allowed | One vault slot per token. |
| Liquidity | Funded WBNB pool on PancakeSwap V2 or V3 | AUM is real and the desk can always trade the leg. |
| Expense ratio | ≤ 3% p.a. | Manager incentive without predatory expense ratios. |
| Listing requirement | Off (treasury may enable) | Emergency lever for regulatory or safety reasons; never retroactive. |
Composition, allocations and the expense ratio are immutable after issuance. Allocations are targets for the opening subscription only; they drift with price afterwards. This is a passive ETF, not a rebalancer.
Security model
- No oracle on the safety path. Subscription (after seed) and redemption are pure functions of vault balances and unit supply. Manipulating a PancakeSwap pool can distort displayed AUM or make a desk trade unattractive, but cannot extract more coins than a unit is backed by.
- Slippage is user-controlled.
minUnits/minBnbOutguard the whole basket trade;maxIn/minOutguard direct in-kind flows per token. - Reentrancy. ETF and desk entry points are
nonReentrant; token transfers use SafeERC20 with balance-delta accounting for fee-on-transfer tokens. - Atomic seed. Issuance and opening subscription are one transaction, eliminating empty-ETF and opening-basket front-running windows.
- Desk holds nothing. Every desk call ends with zero BNB and zero token balance; surplus is refunded to the caller within the same transaction.
- Admin surface. The treasury owner can update the quoter, desk, treasury address, desk fee (≤ 3%), issuance limits and listing requirement. It cannot touch any ETF's assets, supply or basket.
- Residual risks. Component token risk (malicious or upgradeable tokens, transfer taxes, blacklists) is inherited by the basket. Thin pools mean higher price impact on desk trades; redemption in kind is always available as the exit.
Contract reference
| Contract | Address |
|---|---|
| $METF (protocol token) | 0xbec631fdbed606339bd6431048e148c469fa7777 |
| EtfIssuer | 0xeb607647d5CFd07F59373608f29d6DD8F814f8Bc |
| EtfDesk | 0x46B34f7C2C1023a7B4e797bE359ed1A9B66Ad26f |
| PancakeQuoter | 0xCCd20E6e7eFacA4d3bfBd82B4d7e6Cd1a91AF297 |
| WBNB | 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c |
| BNB/USD (Chainlink) | 0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE |
EtfIssuer
issue(string name, string symbol, address[] components, uint16[] allocations, uint16 expenseRatioBps) → address etfs(uint256) → address · etfCount() → uint256 · isEtf(address) → bool quoter() · desk() · treasury() · treasuryShareBps() minComponents() · maxComponents() · maxAllocationBps() · maxExpenseRatioBps() · listingRequired() · listed(address) event EtfIssued(address etf, address manager, string name, string symbol, address[] components, uint16[] allocations, uint16 expenseRatioBps)
MemeEtf (ERC-20)
components() → address[] · allocations() → uint16[] · reserves() → uint256[] aum() · unitPrice() · accruedExpenseUnits() · lastExpenseAt() manager() · treasury() · expenseRatioBps() · treasuryShareBps() quoteSubscribe(uint256 units) → uint256[] · quoteRedeem(uint256 units) → uint256[] subscribe(uint256 units, uint256[] maxIn) → uint256[] · redeemInKind(uint256 units, uint256[] minOut) → uint256[] collectExpense()
EtfDesk
enter(address etf, uint256 minUnits) payable → uint256 units exit(address etf, uint256 units, uint256 minBnbOut) → uint256 bnbOut issueAndSeed(string name, string symbol, address[] components, uint16[] allocations, uint16 expenseRatioBps, uint256 minUnits) payable → (address etf, uint256 units) deskFeeBps() → uint16
PancakeQuoter
quote(address token) → uint256 (BNB wei per 1e18 raw units) venue(address token) → (address pool, uint8 kind, uint24 fee) kind: 0 none · 1 V2 · 2 V3
FAQ
One position gives you a whole narrative — AI coins, blue-chip memes, a manager's picks — without buying and tracking ten tokens. You are always one redeemInKind away from the underlying, so you are never locked in.
No. Composition, allocations and expense ratio are immutable, and no address — manager or treasury — has any withdrawal path other than burning units.
The desk buys every leg with the same unit fraction in mind; swap fees and price impact differ per pool, so the excess on the better-executed legs is refunded to you in kind rather than kept.
AUM shows that leg at zero and desk trades may fail slippage checks, but in-kind redemption keeps working: you receive your slice of every token regardless of pool state.
Read etfCount/etfs(i) on the issuer to enumerate listings, then the ERC-20 and pricing views on each ETF. Trades go through the desk; all ABIs are listed above. Issue an ETF to try it end to end.