Earn Contracts
Use Flex shares, Term shares and withdrawal tickets through the Earn vault and Pool adapter.
Flex, Term and tickets#
FuyuEarnVault invests through one configured ERC-4626 venue and tracks Flex shares, Term shares and withdrawal tickets. The vault is the Flex token. term() returns the Term token, and ticket(series) returns an asset-denominated ticket. These public ERC-20 positions can also be held in private Pool notes when the tokens and routes are admitted.
Flex accepts deposits and redeems shares for underlying. Term uses supplyTerm, then requestWithdrawal to issue a series ticket, and claim when its window opens. A withdrawal request gives you tickets while you wait for underlying. Read the series and window before telling a user they can claim.
Deposit and redeem Flex#
Use totalAssets, previewDeposit, previewRedeem, maxDeposit and maxRedeem for amounts and limits. deposit must receive exactly the underlying amount before minting shares to the receiver. redeem consumes authorized shares and pays measured underlying. Shares and underlying have separate units; their conversion follows the venue and current vault accounting.
The vault supports only part of the ERC-4626 API. mint and withdraw are unsupported, their max functions return zero, and previewMint/previewWithdraw revert. Use deposit and redeem for exact-input flows. A generic ERC-4626 helper must not assume that the other methods work.
function deposit(uint256 _assets, address _receiver)
external returns (uint256 shares);
function redeem(uint256 _shares, address _receiver, address _owner)
external returns (uint256 assets);
function supplyTerm(uint256 _assets, address _receiver)
external returns (uint256 shares);
function requestWithdrawal(uint256 _shares, address _receiver)
external returns (uint256 tickets, uint256 series);
function claim(uint256 _series, uint256 _tickets_, address _receiver)
external returns (uint256 assets);Request and claim Term withdrawals#
Term has its own asset bucket and share conversion. previewSupplyTerm estimates shares, previewRequest estimates tickets, and requestWithdrawal returns the issued ticket amount and series. Scheduling uses a one-week period, three-day offset and four-period notice rule, with eight rotating series. Read currentSeries, requestClaimWindow and claimWindow for the applicable dates.
claimOpen tells you whether a series is claimable, and previewClaim estimates its payout. claim burns eligible caller-owned tickets and pays the asset to the receiver. For ClaimClosed, InvalidSeries or ExceedsLimit, check the window, series and amount. A preview does not reserve the venue's liquidity.
Store the ticket token address with the position. Different series are different assets even if the UI uses the same label. The private action's output asset must match the series selected at execution, so check it at review and again before broadcasting.
Earn adapter operations#
FuyuEarnAdapter fixes Pool, vault, underlying, Term token, deployment chain and runtime hashes. route(operation) returns the input/output pair. Only the Pool can call execute. It requires a positive input and minimum, actionData zero, a valid deadline and unchanged contract identities.
The adapter consumes the input, calls the vault operation and returns one measured output to the Pool. Queued or immediate finalization then creates the private settlement note. Targets and calldata come from the adapter's code, not the user.
| Operation | Input | Output |
|---|---|---|
| 0: SUPPLY_FLEX | Underlying asset | Vault/Flex shares |
| 1: REDEEM_FLEX | Vault/Flex shares | Underlying asset |
| 2: SUPPLY_TERM | Underlying asset | Term shares |
| 3: REQUEST | Term shares | Ticket for the current series |
| 8 + s: CLAIM | Ticket for series s, 0 ≤ s < 8 | Underlying asset |
Fees and administration#
FEE_BPS is 1,000, a 10% fee on Flex yield. The current protocol-share basis points divide that fee between Term boost and treasury. MAX_PROTOCOL_BPS is 5,000, and protocol-share changes take effect after the 30-day delay. Boost cycles last seven days. Yield estimates follow venue performance and current accounting; they are not promised returns.
adminProposeProtocolShare schedules a change, and currentProtocolShareBps reads the effective value. An admin transfer requires nomination and acceptance. sync updates accounting, collectTreasury pays accrued treasury value, and claimVenueRewards handles the reviewed venue rewards. The admin has no permission through these functions to change private note ownership.
Follow FlexFeeAccrued, BoostCycleStarted, ProtocolShareProposed/Applied and TreasuryCollected when explaining share-value changes. Display underlying, Flex, Term and ticket values separately. If a ticket valuation is unavailable, show that status instead of counting it as zero in a total.
Build the Earn flow#
Check asset, venue, treasury, admin and share-token addresses and route admission at a known block. Simulate the full Pool transaction as well as reading vault previews. Deposits, redemptions and venue calls reveal public asset amounts even when the input was a private note.
After supply, check the measured shares and recover their note. After a Term request, show the ticket series and notice/claim state. After claim, confirm the finalized output and change. A queued receipt still needs finalization before the private balance is spendable.
Test same-block window changes, minimum-output failures, inexact transfers, wrong series, revoked supply and remaining exit routes. Query capacity instead of assuming it from a deployed vault address. If maxDeposit is zero on a network, supply needs another usable reviewed venue.
Handle a failed Earn action#
OnlyPrivacyPool means a caller tried to execute the adapter outside its Pool. VenueChanged means the chain or code differs. InexactInput and InexactConsumption mean measured balances failed their checks. InsufficientOutput means the output missed the proof's minimum. For Insolvent or ClaimClosed, inspect the vault accounting, venue and claim window.
If submission times out, check the original nullifier, ActionQueued/ActionFinalized events and ticket/share position. The transaction may already have spent the input, so check before making another action.