Skip to Content
OTF token economics

OTF token economics

OTF is the protocol token, used for rewards and fee buybacks. Each fund issues its own shares, which represent a claim on that fund’s basket.

The active deployment runs on Robinhood Chain Testnet with the 15/135 ETH launch curve. See Deployment addresses for the current contracts.

Supply and allocation

OTFToken is an 18-decimal ERC-20 named Onchain Traded Funds with symbol OTF. Its constructor mints one billion OTF using ProtocolConstants.OTF_INITIAL_SUPPLY. It has no later mint, tax, blacklist, seizure, or upgrade function. Holders can burn their own OTF; burnFrom requires allowance.

The shared constant records the original issuance; the token exposes only totalSupply() for live supply after burns. The frontend’s issuance constant is generated from the same Solidity definition. The deployment script allocates every token and leaves the deployer with none:

DestinationOTFUse
Team market-cap vesting100,000,000Ten live-FDV milestones
V4 launch manager200,000,000Bootstrap and permanent liquidity
Cumulative rewards distributor700,000,000650 million for depositors and 50 million for fund creators, published by multisig

Canonical V4 launch

The launch manager creates one OTF/WETH Uniswap V4 pool with a fixed 0% LP fee and tick spacing 1. The pool starts at 0.000000015 WETH per OTF, a 15 ETH reference fully diluted valuation (FDV) against the original one-billion-token supply. At the price boundary just below 135 ETH reference FDV, the launch can graduate to permanent liquidity.

Anyone can initialize the launch by approving the manager to spend 200 million OTF and calling initializeLaunch() from the same wallet. The call pulls the full amount from the caller, initializes the pool, and creates bootstrap liquidity in one transaction. If any step fails, the transfer also reverts. OTF already held by the manager does not reduce the caller’s funding requirement. The deployment script approves exactly REQUIRED_OTF_BALANCE before calling initialization.

The launch has four phases:

PhaseWhat happens
NotInitializedThe bootstrap position has not been created.
BootstrapActiveUsers can buy and sell OTF within the launch price boundaries.
GraduationReadyThe pool has reached the exact final price. Further swaps revert until finalization.
GraduatedThe manager has replaced bootstrap liquidity with a permanently locked full-range position. Normal Uniswap trading resumes.

Graduation depends on price, with no schedule or countdown. Launch reference FDV uses ProtocolConstants.OTF_INITIAL_SUPPLY, so burns do not change the launch targets and no token supply read is required for this calculation.

OTFLaunchRouter is the supported bootstrap route. It partially fills buys or sells at the boundaries, takes only the input used, and refunds unused native ETH. A purchase that reaches the final boundary also finalizes graduation after PoolManager returns control. Both steps succeed or the entire transaction reverts. Anyone can also call finalization separately once the pool is ready.

Ordinary Uniswap UI trades can succeed within the launch boundaries. Orders that cross a boundary revert because the standard router cannot supply the required price limit.

Finalization removes the bootstrap position and funds a permanent full-range position with the derived principal. Extra WETH stays locked in the manager and cannot enlarge the position. After the permanent mint succeeds, the manager burns its entire remaining OTF balance, normally about 2,582.6037 OTF plus any unsolicited OTF. The manager owns the permanent NFT and has no withdrawal or replacement function.

The exact prices and liquidity amounts account for V4 rounding. The pool price is exact at initialization, while each liquidity boundary comes from V4 TickMath:

OTF/WETH orderingExact initialization sqrtPriceX96Bootstrap start tick and boundaryFinal tick and boundary
OTF is currency09703428570912459262669889-180161 / 9703508046175219238931631-158188 / 29110022932210076965716350
OTF is currency1646895238060830617511325894307352180161 / 646889939753375374376401562675059158188 / 215633692560272871859121182412411

The initial price sits just outside the starting position boundary. The final boundary is the closest tick-derived OTF price below the 135 ETH target, at approximately 134.997562702653186573 ETH reference FDV.

Permanent liquidity is fixed at 18371007233046122951295. It pairs just under 50 million OTF with 6.749878135132658333 WETH. This is the greatest integer liquidity that stays within the 50 million OTF cap after V4 rounding.

Bootstrap liquidity is fixed at 27556748080852150400017 and uses approximately 149,997,417.3963 OTF from its 150 million cap. It is the smallest integer liquidity that returns the permanent position’s full WETH principal at graduation. Swap rounding adds 44 or 45 wei of WETH to a purchase that reaches the final boundary, depending on currency order. The security specification defines the rounding requirements.

The launch hook uses beforeInitialize, beforeAddLiquidity, and afterSwap. The afterSwap hook enforces the bootstrap price boundaries and marks GraduationReady only at the exact final sqrt price; tick equality alone is insufficient.

Team market-cap vesting

The team’s 100 million OTF allocation unlocks in ten steps. Each completed $1 million of live USD FDV unlocks 10 million OTF, up to the full allocation at $10 million. Values between milestones round down, and unlocked tokens cannot relock after a price or supply decline.

Only the current beneficiary can record a milestone by calling checkpoint() on TeamMarketCapVesting. The contract calculates live USD FDV from:

canonical OTF/WETH V4 spot price × current ETH/USD oracle price × OTF.totalSupply()

The calculation handles either currency order with full-precision integer arithmetic. It uses the current spot price, which can be manipulated. Beneficiary-only checkpoints do not remove that risk. The ETH/USD answer must be positive, no older than maxOracleAge, and not from the future. Testnet uses a fixed $2,000 fake oracle; production requires an explicit oracle address.

Team allocation unlocks

10 million OTF per completed $1 million live-FDV milestone

100M OTF · 10% of supply
Team OTF unlocks by live FDV milestoneA step chart with ten milestones. Each completed one million dollar live FDV milestone unlocks ten million OTF, reaching the complete 100 million OTF team allocation at ten million dollars.0M25M50M75M100M$0M$2M$4M$6M$8M$10MCumulative unlocked OTFCompleted live FDV checkpoint
A checkpoint rounds live FDV down to the last completed $1 million milestone. Once recorded, an unlocked tranche cannot relock.
View team milestone data
Completed live FDVCumulative unlockedShare of supply
$1M10M OTF1%
$2M20M OTF2%
$3M30M OTF3%
$4M40M OTF4%
$5M50M OTF5%
$6M60M OTF6%
$7M70M OTF7%
$8M80M OTF8%
$9M90M OTF9%
$10M100M OTF10%

The beneficiary can claim unlocked tokens minus prior claims and nominate a successor. They can replace or cancel the nomination. Authority transfers only when the nominee accepts, preserving unlocked and claimed amounts.

The beneficiary is the contract’s OpenZeppelin owner(). Call transferOwnership(newOwner) to nominate a successor, transferOwnership(address(0)) to cancel, and acceptOwnership() from the nominee to complete the transfer. Ownership renunciation is disabled so unclaimed tokens cannot be stranded by abandoning the role.

Immutable fund fees

Each vault creator selects three rates at creation:

FeeDefault in the applicationContract maximum
Annual creator expense0%10% / 1,000 bps
Mint0%2% / 200 bps
Redeem0%1% / 100 bps

The rates and expense beneficiary cannot change. A mint fee increases the deposit needed for a requested share amount. A redeem fee reduces the basket returned. Annual expense increases share supply over time, reducing the backing per share.

The vault collects all three fees by issuing vault shares and records accrued annual expense at checkpoints. Redemptions by the configured collector and redemptions after shutdown have no redeem fee. Redemption previews take the share owner as an argument and use the same arithmetic as execution.

Holding OTF as an accounted vault constituent changes the division of fee shares, not the fee charged to the investor:

creator share = 50% + 40% × sqrt(min(accounted OTF, 10m OTF) / 10m OTF) buyback share = 100% - creator share
Accounted OTFCreatorBuyback and burn
050%50%
1 million62.64%37.36%
2.5 million70%30%
5 million78.28%21.72%
10 million or more90%10%

The contract rounds the creator’s percentage down to whole basis points. Mint and redeem creator portions also round down, leaving the remainder for buyback. Annual expense carries fractional split remainders between checkpoints so their frequency does not change the cumulative split.

The vault records accrued expense before accounted OTF changes. Direct donations do not affect the split. OTF held in the fund remains a constituent and is not burned merely because the fund holds it.

BuybackCollector receives both portions and records their exact share counts in a separate account for each factory-recognized vault. At settlement, it reads the vault’s immutable beneficiary.

Fee settlement and burn

Fee settlement converts the collected fund shares into WETH, pays the creator’s portion to the expense beneficiary, and uses the remainder to buy and burn OTF.

Only the expense beneficiary can start settlement. The collector first records accrued annual fees, then converts all pending creator and buyback shares through one of two routes:

  1. Sell the combined vault shares through approved adapters to canonical WETH.
  2. Redeem the shares and convert the returned constituents to canonical WETH.

The share-sale route may use intermediate tokens but must consume the exact pending balance and leave only WETH as transient output. The beneficiary supplies routes, minimum WETH and OTF outputs, and a deadline. The collector does not price assets or choose slippage limits.

The collector divides the WETH using the share counts recorded when fees accrued and rounds the beneficiary’s payment down.

Settlement, beneficiary payment, OTF purchase, and burn all succeed or all revert. Selling shares leaves them outstanding with buyers; redeeming burns them and removes their proportional backing.

The final swap uses only the canonical OTF/WETH V4 pool, enforces the deadline and minimum output, and burns every OTF purchased. Buybacks can execute during bootstrap or after graduation. The collector has no arbitrary-call, withdrawal, or rescue function.

Cumulative rewards and incentive emissions

MerkleRewardsDistributor receives 700 million OTF: 650 million for depositors and 50 million for fund creators, or 65% and 5% of the original supply. The publisher’s policy sets weekly budgets over 208 weeks (four years), then ends emissions. Actual allocations can be lower than these budgets.

The schedule, allocation split, eligibility rules, weight cap, and 10,000% depositor rewards APY cap below are publisher policy. The distributor enforces proof validity and cumulative claims. Its owner can publish an immediately active reward root with no delay or per-period limit, including one that allocates the entire remaining balance ahead of schedule. The owner has no function to withdraw reward principal.

The weekly target starts at 14 million OTF and declines by approximately 1.968% every week:

weeklyEmission(n) = 14,000,000 × 0.9803203^(n - 1)

Each week uses the same 65-to-5 split:

depositorEmission(n) = weeklyEmission(n) × 13 / 14 creatorEmission(n) = weeklyEmission(n) - depositorEmission(n)

Week 1 budgets 13 million OTF for depositors and 1 million OTF for creators.

n starts at 1. The rounded decay factor leaves a shortfall of about 425.05 OTF over 208 weeks. The shared schedule rounds each weekly decay down to 18-decimal OTF units for weeks 1–207 and budgets the remainder in week 208, approximately 229,144.55 OTF. Its budgets sum to exactly 650 million depositor OTF and 50 million creator OTF; this does not require allocating unused rewards.

CheckpointApproximate weekly emission
Week 114.000 million OTF
Week 213.724 million OTF
Week 313.454 million OTF
Week 413.190 million OTF
Week 512.930 million OTF
Week 612.676 million OTF
Week 712.426 million OTF
Week 812.182 million OTF
3 months, week 1311.03 million OTF
6 months, week 268.52 million OTF
1 year, week 525.08 million OTF
2 years, week 1041.81 million OTF
3 years, week 156643,000 OTF
Week 208229,000 OTF

Cumulative incentive budgets

Scheduled depositor and fund creator budgets across 208 weeks

Depositors · 650MFund creators · 50M
Cumulative scheduled OTF incentive budgetsA stacked area chart rising from zero to a 700 million OTF budget over four years: 650 million for depositors and 50 million for fund creators. Actual allocations can be lower.0M175M350M525M700MStartYear 1Year 2Year 3Year 4Cumulative OTF700M total
The chart shows scheduled budgets. Excess above the depositor APY cap stays unallocated. Tokens become claimable only after the publisher includes the cumulative entitlement in an active Merkle root.
View cumulative checkpoint data
CheckpointDepositorsFund creatorsTotal
Start0 OTF0 OTF0 OTF
Week 13150.42M OTF11.57M OTF161.99M OTF
Week 26266.58M OTF20.51M OTF287.09M OTF
Week 52425.58M OTF32.74M OTF458.32M OTF
Week 104576.98M OTF44.38M OTF621.36M OTF
Week 156630.84M OTF48.53M OTF679.37M OTF
Week 208650M OTF50M OTF700M OTF

Both buckets calculate each fund’s initial allowance using capped pro-rata weights:

cappedWeight(fund) = min(accounted OTF balance(fund), 10,000,000 OTF) proportionalAllowance(fund) = bucketEmission × cappedWeight(fund) / sum(cappedWeight)

Only funds with an accounted protocol OTF balance receive an allowance. Balances above 10 million OTF receive no extra weight. Direct OTF transfers that do not enter accounted balances add no weight. If the total weight is zero, no fund receives an allocation.

Each fund’s depositor rewards have a 10,000% APY maximum, calculated by compounding the weekly return over 52 weeks:

weeklyDepositorAllowance = min( proportionalDepositorAllowance, snapshot NAV USD × (101^(1/52) − 1) ÷ chosen OTF price USD )

The publisher supplies one positive weekly average OTF USD price and uses it across all funds. The chosen price values reward tokens; fund NAV stays at its recorded snapshot valuation. For example, a fund with $5,200 NAV and a chosen OTF price of $2 can receive at most 241.3058779198001168 OTF in weekly depositor rewards. A smaller proportional allowance lowers that limit further.

The tooling rounds the weekly rate down to 18 decimal places before calculating allowances, then rounds allowances and participant rewards down to 18-decimal OTF units. Zero NAV or zero OTF weight gives zero depositor rewards. Excess and rounding dust remain unallocated in the distributor, without redistribution or automatic rollover. Creator rewards keep their separate proportional allowance and are outside the depositor APY cap.

The Funds page shows the combined weekly rewards budget. Directory values, sorting, fund details, and the explanation dialog use the shared cap calculation with current prices. Missing valuation or reward data leaves an eligible fund’s estimate unavailable. These estimates do not determine claim entitlements. Published rewards use the selected weekly price, and later market movements can change realized returns.

Rewards accumulate across claims. If your published entitlement is 100 OTF and you have already claimed 40 OTF, your next valid claim pays 60 OTF.

Each standard-tree leaf binds that cumulative entitlement to a chain, distributor, and user. Anyone may submit its proof; payment goes to the named user. Invalid proofs, duplicate claims, and entitlements below the amount already claimed revert.

Prepare a weekly JSON input using this structure. The addresses, block, and price here are examples; supply the actual snapshot and choose the reward-token price for the week:

{ "week": 1, "otfPriceUsd": "2", "snapshot": { "blockNumber": "100", "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000001", "timestamp": "2026-09-11T00:00:00.000Z", "fundAddresses": ["0x00000000000000000000000000000000000000f1"] }, "funds": [{ "address": "0x00000000000000000000000000000000000000f1", "accountedOtf": "10000000", "navUsd": "5200", "depositors": [ { "address": "0x00000000000000000000000000000000000000a1", "amount": "1000" }, { "address": "0x00000000000000000000000000000000000000b2", "amount": "3000" } ], "creators": [ { "address": "0x00000000000000000000000000000000000000c3", "amount": "100" } ] }] }

snapshot.fundAddresses must contain the full factory roster at the snapshot block. Include each fund exactly once, including funds with zero weight or no proposed rewards. Amounts and USD values are unsigned decimal strings with at most 18 decimal places. Missing NAV, balances, or the chosen positive price blocks generation; the script does not fetch a replacement price.

Participant amount values are proposed weekly increments, not cumulative entitlements. The script reduces depositor increments proportionally if their total exceeds the fund’s allowance. In this example, it allocates 60.3264694799500292 OTF and 180.9794084398500876 OTF to the two depositors and preserves the creator’s 100 OTF. Creator increments above the proportional creator allowance are rejected. One account can receive rewards from multiple funds or both buckets; duplicate accounts within one fund’s bucket are rejected.

Generate an artifact with:

corepack pnpm rewards:tree -- \ --input <week.json> \ --output <artifact.json> \ --chain-id <id> \ --distributor <address>

For week two onward, add --previous <previous-artifact.json>. Supply the artifact from the immediately preceding week, including weeks with no allocation. The script validates the previous root and cumulative totals, requires advancing snapshot references, and rejects gaps or identity mismatches. It preserves past recipients and adds this week’s rewards to their cumulative entitlements.

Outputs use the otf-weekly-rewards-v2 schema and record the chosen price, snapshot, per-fund allocations, and budget, allocated, unallocated, and cumulative totals. Fields ending in Raw contain integer 18-decimal OTF units. Empty cumulative allocations use a zero root and no entries.

Cumulative-only JSON and CSV inputs are no longer accepted. The output path must be new, so a rerun cannot overwrite an existing artifact. Review the output before publishing its root. The publisher must verify the source snapshot, full roster against the factory, participant eligibility, and that the previous artifact is the latest publication. The script validates supplied data; it does not fetch onchain snapshots or submit a root transaction.

Trusted inputs

  • The reward-root publisher can allocate the distributor’s entire remaining balance through a valid root.
  • Each expense beneficiary chooses routes, minimums, and deadlines for its own vault’s complete pending fee account.
  • The ETH/USD oracle determines one input to live-FDV vesting.
  • PoolManager, StateView, PositionManager, Universal Router, Permit2, WETH, adapters, and trading venues execute or report external state used by the protocol.

Production addresses must be supplied explicitly and use official Uniswap V4 deployments. The testnet mirror is accepted only when its runtime code matches the configured hashes.

Last updated on