# Blend protocol: complete integration context > Blend is a fixed-unit token basket protocol deployed on Robinhood Chain. This document is the complete machine-readable companion to the developer documentation at https://blend.theindex.finance/docs. ## Authoritative resources - Developer documentation: https://blend.theindex.finance/docs - ABI manifest: https://blend.theindex.finance/abis - Block explorer: https://robinhoodchain.blockscout.com - Compact LLM index: https://blend.theindex.finance/llms.txt ## Network configuration - Network: Robinhood Chain mainnet - Chain ID: 4663 - Native asset: ETH, 18 decimals - Public RPC: https://rpc.mainnet.chain.robinhood.com - Explorer: https://robinhoodchain.blockscout.com - Factory indexing start block: 55989258 - Basket share decimals: 18 - Canonical quote currencies: USDG, 6 decimals; native ETH, 18 decimals ## Deployed contracts - BasketFactory: 0x40bd43B7ff1D673e03B129dCE371761a6E81E305 - Deploys vaults and records canonical baskets. - Primary methods: deploy, predict, deployed, deployedCount, isBasket. - ABI: https://blend.theindex.finance/abis/basket-factory.json - BasketVault implementation: discover individual vault addresses from BasketFactory.BasketDeployed.vault. - Holds constituents, issues ERC-20 basket shares, processes redemption, and records fees, throttles, and recovery balances. - Primary methods: previewMint, mint, redeem, redeemExcluding, treasury, protocolFees, accrete, resync, sweepProtocolFees. - ABI: https://blend.theindex.finance/abis/basket-vault.json - BlendHook: 0x219B93D7c067f3cCc9E25aecDbecf1279D1Fc888 - Registers basket pools and constituent routes and settles routed basket trades. - Primary methods: register, poolKeyFor, routesFor, capacity, quoteLegs, replaceRoute. - ABI: https://blend.theindex.finance/abis/blend-hook.json - BlendRouter: 0x70DDEa1f1C509cE6554de3E12370Bf8A29bA4604 - Provides exact-input buy, exact-output buy, and sell transactions. - Primary methods: buy, buyExact, sell. - ABI: https://blend.theindex.finance/abis/blend-router.json - BlendLens: 0xbB95752f5F1464e2Bb4f17652daF68c7f75f6c05 - Provides read-only previews and quotes without requiring a funded or approved caller. - Primary methods: previewBuy, previewRedeem, quoteBuy, quoteBuyExactOut, quoteSell. - ABI: https://blend.theindex.finance/abis/blend-lens.json ## Shared infrastructure - Uniswap v4 PoolManager: 0x8366a39CC670B4001A1121B8F6A443A643e40951 - USDG: 0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168 - Native ETH currency sentinel: 0x0000000000000000000000000000000000000000 - Multicall3: 0xcA11bde05977b3631167028862bE2a173976CA11 ## Protocol architecture Each basket is an ERC-20 token backed by a vault. One full basket share maps to a fixed quantity of every active constituent. Market prices change the value and percentage composition of a basket but do not modify the token quantities assigned to a share. The backing requirement is that each active asset covers its units across all outstanding shares. Holder backing, basket-owner fees, Blend protocol fees, and recovery value are recorded in separate accounting buckets. The contracts have the following responsibilities: - BasketFactory deploys baskets and lists canonical vault addresses. Constituent custody is delegated to each vault. - BasketVault holds constituents, issues shares, and processes redemption. Holder backing is unavailable for administrative withdrawal. - BlendHook stores routes and settles multi-asset routed trades. Basket registration is restricted to approved factories. - BlendRouter converts between one quote currency and complete basket shares. The caller supplies slippage limits and deadlines. - BlendLens returns previews and quotes through eth_call and does not transfer assets. ## Basket accounting units(token) is the amount of a constituent assigned to one full basket share. backing(token) is the amount reserved for outstanding holders. Market price changes do not modify either value. Accounting values can change through explicit maintenance methods: - accrete moves eligible surplus into holder backing and increases units. - resync reconciles internal accounting with the actual ERC-20 balance. - Recovery methods write down failed constituents or restore recovered assets. A basket contains between 1 and 16 constituents. Deployment configures units per share, owner fee settings, issuance and redemption limits, and the basket owner. Routes are registered separately for USDG or native ETH. Routes are required for router trades but not for direct minting or redemption. ## Transaction methods - Direct mint: BasketVault.mint. The caller provides every active constituent and supplies maxIn[] and deadline. - Direct redemption: BasketVault.redeem. The caller provides basket shares and supplies minOut[] and deadline. - Exact-input routed buy: BlendRouter.buy. The caller provides USDG or native ETH and supplies minShares and deadline. - Exact-output routed buy: BlendRouter.buyExact. The caller provides USDG or native ETH and supplies maxIn and deadline. - Routed sell: BlendRouter.sell. The caller provides basket shares and supplies minOut, deadline, and an optional skip list. - Atomic composition: flashMint or flashRedeem. Settlement and complete repayment occur in the callback within the same transaction. For a direct mint, approve every active ERC-20 constituent for the vault. For a routed token buy, approve the quote token for the router. For a sell, approve basket shares. A native ETH buy uses msg.value and requires no ERC-20 approval. ## Fee calculation Fees are calculated independently for each active constituent. Direct vault operations include the separately configured basket-owner fee and the fixed Blend protocol fee. Routed operations can also incur the Uniswap v4 pool fee and price impact for every constituent route. The Blend hook pool uses fee 0 and adds no separate basket-level trading fee. Mint calculations for one constituent: - base backing = ceil(shares * units / 1e18) - basket-owner fee = ceil(base * mintFeeBps / 10,000) - Blend protocol fee = ceil(base * 35 / 10,000), equivalent to 35 basis points - total input = base backing + basket-owner fee + Blend protocol fee, plus any applicable recovery contribution Redemption calculations for one constituent: - gross output = floor(shares * units / 1e18) - basket-owner fee = floor(gross * redeemFeeBps / 10,000) - Blend protocol fee = floor(gross * 20 / 10,000), equivalent to 20 basis points - recipient output = gross output - basket-owner fee - Blend protocol fee Each basket configures mintFeeBps and redeemFeeBps independently. Each basket-owner fee is capped at 100 basis points. Integrations should read the current values and use previewMint and BlendLens.previewRedeem for exact integer amounts. Mint arithmetic rounds up and redemption arithmetic rounds down. ## Onchain accounting buckets - backing[token]: constituent assets reserved for basket holders. - treasury[token]: basket-owner fee revenue. The current basket owner may withdraw it. Before withdrawal, permissionless accretion may move eligible value into holder backing. - protocolFees[token]: fixed Blend protocol fee revenue. Anyone may sweep the complete bucket to protocolFeeRecipient(). Accretion never spends this bucket. If the vault excludes the constituent before a sweep, the unswept balance moves to forfeited together with the leg's backing and basket-owner treasury. - forfeited[token]: recovery value reserved for holders: skipped legs, excluded legs (including any unswept fee buckets on them), and the recovery share new mints pay in. Accretion consumes this value before basket-owner treasury value. - Route execution costs: pool fees and price impact incurred by routed buys and sells. These costs follow Uniswap pool accounting and are not allocated by BasketVault. Example without integer rounding, recovery contributions, or route execution costs: if one share requires 100 units of a constituent and the basket-owner fee is 10 basis points, minting transfers 100 + 0.10 + 0.35 = 100.45 units. Redeeming a gross 100 units returns 100 - 0.10 - 0.20 = 99.70 units. ## Recovery accounting and accretion A mint may include a proportional contribution to existing forfeited plus writtenDown recovery value. This prevents new entrants from receiving value reserved for prior holders. The contribution is not basket-owner or protocol fee revenue. The keeper attempts accretion every ten minutes. Vault growth is limited to 0.50% per fully refilled 9.125-day step and 20% per year, with at least one share of supply. When redeemExcluding skips a constituent, that leg charges no basket-owner or protocol fee. Its complete gross amount moves from backing into forfeited recovery value. ## NAV history in the app The app's NAV chart shows total return per basket share at each market close (4-hour bars on the 7D range; the latest point can be a bar still trading): the sum over constituents of units per share at that close times the constituent's close, times the stock token's ERC-8056 uiMultiplier in force at that close. Units are replayed from Accreted and UnitsWrittenDown events, so fee growth counts from the first close after it; multipliers come from UIMultiplierUpdated events, so each reinvested dividend counts from its effectiveAt. When the units history is unavailable, the chart reads today's units at every close and says fee growth is missing. When a range starts before the basket was deployed, the line has one more point: the basket's value at the moment of deployment, each constituent at the close of its last full hourly bar before then (a stock outside trading hours at its last extended-hours price), with its units and multiplier at that moment. The headline change counts from that point, the same on every range, and the line before it is drawn dashed as a backtest: of the starting holdings, or of today's holdings when the units history is unavailable. If a constituent's price at deployment is not yet available, no change is shown until it is. A portfolio's chart counts from the latest launch among the baskets held. Neither returns nor future dividends are guaranteed. ## Execution limits - Route cost: each constituent route can charge a pool fee and incur price impact. This applies to router trades rather than direct vault operations. - Minimum issuance: 0.001 basket shares, which bounds rounding error for small mints. - Throttles: issuance and redemption capacity refill continuously over one hour and can constrain transactions even when route liquidity is available. - Redemption floor: configuration must allow at least 10% of supply to be redeemed per hour. - Route capacity: calculated for a selected slippage budget. The shallowest weighted constituent route determines basket capacity. BlendLens.previewBuy returns estimated cost per share and conservative route capacity. It excludes current vault throttle headroom, which must be read or indexed separately. ## Failure recovery - Issuance pause: mint, routed buy, and flash entry methods stop. Ordinary redemption remains available. - Failed token transfer: redeemExcluding can return transferable constituents while recording the skipped portion as forfeited recovery value. - Constituent exclusion: the operator may exclude immediately. A permissionless caller can prove failure and repeat the operation after one day. Integrations should index ConstituentExcluded and remove the leg from new issuance. - Balance mismatch: resync reconciles accounting with the actual token balance. Integrations should check isReconciled before presenting state as current. - Empty route: any caller may report the condition. The owner may replace the route after one day. Direct minting and redemption remain available. Deficits consume accounting buckets in the following order: protocol fees, basket-owner treasury, recovery value from earlier write-offs, and holder backing. Later recovery repays holder claims first. Treasury withdrawals and protocol fee sweeps reconcile before moving assets. ## Integration workflow 1. Index BasketFactory.BasketDeployed from block 55989258, or read deployedCount() and deployed(i). 2. Validate candidate vaults with BasketFactory.isBasket(vault). 3. Read constituents(), then multicall units(token), backing(token), and excluded(token) for every constituent. 4. Read mintFeeBps(), redeemFeeBps(), fixed protocol fee constants, and protocolFeeRecipient(). 5. Read treasury(token), protocolFees(token), and forfeited(token) when fee or recovery balances are required. 6. Preview direct operations with previewMint(shares) and BlendLens.previewRedeem(vault, shares). 7. Resolve a basket pool through BlendHook.poolKeyFor(vault, quote). 8. Read constituent routes with BlendHook.routesFor(key). 9. Simulate BlendLens.quoteBuy, quoteBuyExactOut, or quoteSell. 10. Submit the corresponding BlendRouter transaction with the same pool key and basket address, plus an explicit limit and deadline. A basket pool key contains the basket and quote currencies sorted by address, fee 0, tick spacing 60, and the BlendHook address. Any field mismatch derives a different pool identifier. Integrations should call poolKeyFor instead of reconstructing the key locally. ## Indexed API The following cached endpoints support product interfaces. Responses include x-indexed-block. Contract calls and event logs remain the authoritative source when the exact chain head is required. - GET /api/blend/baskets - GET /api/blend/basket/:address - GET /api/blend/assets - GET /api/blend/holdings/:address - GET /api/blend/activity/:address - GET /api/blend/units - GET /api/blend/leaderboard - GET /api/blend/eth Every basket row (in baskets, basket and holdings) carries deployedAt, the unix time of its BasketDeployed event, and deployedBlock, both as decimal strings. Each of its legs carries the vault's buckets for that token as raw decimal strings: treasury, protocolFees, forfeited and writtenDown. activity/:address is the basket's event history, newest first: its latest 150 events of every kind except Accreted, merged with its latest 50 Accreted events. units is the units-per-share history of every vault whose units have changed, in 4-hour UTC buckets: { block, bucketSeconds, vaults }, where each vault has exact and, per token, a start level and steps, pairs of bucket end and units after it, oldest first. exact is false when the replayed history does not end on the units the vault holds now. ## Events and indexing Begin factory log indexing at block 55989258 and backfill in bounded ranges. - BasketFactory.BasketDeployed: canonical vault address, creator, symbol, and deployment order. - BasketVault.Minted, Redeemed, Transfer: share activity and holder balances. - BasketVault.FeesSet, ThrottlesSet, PausedSet, OperatorLockSet: current configuration and availability. - BasketVault.ConstituentAdded, ConstituentExcluded, UnitsWrittenDown, Accreted: constituent composition and unit changes. - BasketVault.TreasuryWithdrawn, ProtocolFeesSwept: basket-owner withdrawals and protocol fee settlement by constituent. - BlendHook.Registered, RoutesExtended, RouteDeadObserved, RouteReplaced: basket pool and route topology. - BlendHook.Bought, Sold: routed volume in share and quote units. Events provide historical state transitions. Current prices, pool depth, reconciliation status, and refilled throttle headroom require live contract reads. ## Permissions - Basket owner: while configuration is unlocked, may set fees and throttles, pause issuance, and add constituents. At any time, locked or not, the owner may register the basket, append routes for added constituents, replace a route a day after it is observed empty, unpause issuance, and withdraw basket-owner treasury. The owner cannot exclude constituents, bypass fee caps, withdraw holder backing, or block ordinary redemption. - Operator: may lock configuration, pause issuance, exclude a failed constituent, and reduce basket-owner fees to zero. The operator cannot raise fees, move holder backing, block ordinary redemption, or change the fixed operator. - Hook governance: may approve factories and transfer hook governance. It cannot deregister baskets, modify a basket's routes, or move vault funds. - Permissionless callers: may accrete, resync, sweep protocol fees, prove asset failure, restore recovered constituents, and report dead routes. They cannot redirect proceeds or bypass contract checks. New baskets begin with operator-locked configuration. A creator may also select immutable parameters at deployment, which permanently prevents later parameter changes. ## Risk considerations - Tokenized stocks provide economic price exposure rather than direct stock ownership, voting rights, or guaranteed dividends. Availability can vary by jurisdiction. - Asset issuers can upgrade contracts, pause transfers, freeze accounts, rebase balances, or discontinue an asset. - A shallow or empty constituent route can prevent a routed basket trade while direct redemption remains available. - Fee-on-transfer tokens are rejected during minting. Other nonstandard token behavior can pause issuance or require constituent exclusion. - Quotes are estimates. Transactions should always include deadlines and minimum-output or maximum-input limits. - Interfaces, indexers, RPC providers, wallets, and automation can be delayed or unavailable. Critical state should be verified onchain. ## ABI downloads - [BasketFactory ABI](https://blend.theindex.finance/abis/basket-factory.json): Machine-readable contract interface. - [BasketVault ABI](https://blend.theindex.finance/abis/basket-vault.json): Machine-readable contract interface. - [BlendHook ABI](https://blend.theindex.finance/abis/blend-hook.json): Machine-readable contract interface. - [BlendRouter ABI](https://blend.theindex.finance/abis/blend-router.json): Machine-readable contract interface. - [BlendLens ABI](https://blend.theindex.finance/abis/blend-lens.json): Machine-readable contract interface.