Sui Move
Version: 1.0
Date: 2026-07-11
Parent: docs/23-auto-yield-implementation.md, docs/24-open-yield-api.md
Authority: docs/LOCKED-MODEL-2026-07-10.md
Plane: XEL-152
Do not greenfield a new YieldRouter package for MVP.
Open Yield on Sui = extend / complete existing XEL Move modules + offchain adapters/agents.
1. Strategy
Section titled “1. Strategy”| Choice | Decision |
|---|---|
| Home chain | Sui |
| Language | Move (existing packages) |
| Fee | ~5% protocol_yield_skim_bps = 500 (Open Yield product default) |
| Stake default | OFF — owner opt-in Auto Yield |
| First venues | Suilend + NAVI (adapters exist) — Scallop/Haedal next |
| Cross-chain | Not in Move core; Mayan offchain + credit endowment |
| Orchestration | Offchain agents |
2. Name map (generic → XEL Move)
Section titled “2. Name map (generic → XEL Move)”| Generic Open Yield | XEL Move / runtime |
|---|---|
| YieldRouter (shared) | treasury::Endowment (shared) + TreasuryPolicy |
| UserPosition (owned) | Position refs offchain + venue AccountCap / obligation objects; character aNFT is owned |
| FeeModule | TreasuryPolicy.protocol_yield_skim_bps + waterfall in heartbeat / record_epoch_waterfall |
| AdapterRegistry | set_yield_venue_allowed + backend allowlist |
| deposit | top_up_endowment — no fee |
| withdraw | withdraw_endowment_principal — owner, no fee |
| harvest | adapter claim_yield PTB + heartbeat — fee here |
| Auto Pay | offchain + payment/spend policy (not new vault module first) |
Package layout (existing)
Section titled “Package layout (existing)”contracts/v2/ Move.toml # package XelV2 sources/ treasury.move # Endowment, policy, harvest waterfall, fee skim identity.move # aNFT / LivingCharacter authority.move # AgentCap wallets.move payment.move storage_policy.move ...runtime/treasury/ suilend-adapter.mjs navi-adapter.mjs gas-sponsor.mjs mayan-executor.mjsMVP work is mostly runtime + API + wiring, plus small Move fixes if single-balance / survival-unstake gaps remain vs locked model.
3. Object model
Section titled “3. Object model”| Object | Shared / owned | Who mutates | Open Yield role |
|---|---|---|---|
LivingCharacter (aNFT) | Owned | owner transfer | Identity root |
Endowment<T> | Shared | owner top_up/withdraw; anyone heartbeat | Capital vault |
TreasuryPolicy | Shared / bound | owner configure | Fee bps, venues, harvest flags |
| Venue position (Suilend/NAVI) | Protocol objects | adapter PTB under policy | Yield generation |
AgentCap | Owned by operator | owner issue/revoke | Scoped automation |
Why Endowment is shared: permissionless harvest/keeper without holding the aNFT.
4. Core entrypoints (already in treasury.move)
Section titled “4. Core entrypoints (already in treasury.move)”| Function | Caller | Fee? |
|---|---|---|
create_endowment | owner path | no |
top_up_endowment | anyone paying in | no |
withdraw_endowment_principal | owner | no |
heartbeat | permissionless | yes (skim on net_yield / waterfall) |
configure_yield_harvest | policy owner | — |
set_yield_venue_allowed | policy owner | — |
pay_storage_renewal | survival path | routing fee family |
Fee at harvest (conceptual)
Section titled “Fee at harvest (conceptual)”// already: DEFAULT_PROTOCOL_YIELD_SKIM_BPS = 500 // 5%// waterfall:// protocol_skim = mul_bps(gross_yield, protocol_yield_skim_bps)// net = gross - protocol_skim// residual compounds / billsAgent authorization
Section titled “Agent authorization”- Not
msg.senderfree-for-all on withdraw. - Owner = root on aNFT.
- Agent =
AgentCap+ spend policy: may trigger stake/harvest/Auto Pay within caps; cannot withdraw principal or transfer character.
5. MVP build order (Sui) — realistic
Section titled “5. MVP build order (Sui) — realistic”| Step | Work | New Move? | Ticket |
|---|---|---|---|
| 1 | Confirm package IDs / testnet-mainnet targets | no | ops |
| 2 | Opportunity agent + discovery (TVL ≥ $50M) | no | XEL-164 / 153 |
| 3 | Scorer + estimates (gross/net after 5% fee) | no | XEL-154 / 165 |
| 4 | Owner Auto Yield toggle OFF default | no | XEL-156 |
| 5 | Stake/unstake via Suilend then NAVI | no (adapters exist) | XEL-157 |
| 6 | Harvest PTB: claim → heartbeat fee skim | polish | XEL-158 / 168 |
| 7 | Gas sponsor on all plans | no | XEL-167 |
| 8 | Bridge in Mayan | no | XEL-166 |
| 9 | Survival auto-unstake only | maybe small Move event | XEL-159 |
| 10 | Auto Pay post-fee residual | no | XEL-163 |
| 11 | Align Endowment to single balance if v2 still has allocation buckets | yes if needed | onchain gap |
| 12 | Scallop adapter (optional 3rd venue) | runtime | later |
Not step 1: new package OpenYieldRouter + Scallop+Haedal from zero.
6. If you add Move modules later (Phase B)
Section titled “6. If you add Move modules later (Phase B)”Only if product needs a standalone multi-user Open Yield vault separate from character endowments:
open_yield/ sources/ router.move # optional shared router position.move # optional owned position receipt fee.move # if split from treasury registry.move # venue registryXEL characters should still prefer endowment-native Open Yield.
7. Move.toml note
Section titled “7. Move.toml note”Existing:
[package]name = "XelV2"edition = "2024.beta"
[addresses]xel = "0x0"Open Yield does not need a second package for MVP; ship under current XEL package lineage / v3 upgrade path per deploy discipline.
8. Example: how agent calls map to Move + adapters
Section titled “8. Example: how agent calls map to Move + adapters”| Agent skill | Onchain | Offchain |
|---|---|---|
routeYield deposit | top_up_endowment | optional Mayan if autoBridge |
routeYield stake | — | Suilend/NAVI supply if Auto Yield on |
harvest | heartbeat (+ claim in same PTB) | keeper / anyone |
withdraw | withdraw_endowment_principal | unstake first if needed |
getPosition | views / indexer | read_apy, estimates |
enableAutoPay | policy/spend config | x402 / provider pay |
9. Sui-specific tests (Move + runtime)
Section titled “9. Sui-specific tests (Move + runtime)”| ID | Case | Expected |
|---|---|---|
| MV-001 | top_up 10000 | principal +10000, no skim |
| MV-002 | harvest gross 10000 skim 5% | protocol_skim 500 |
| MV-003 | withdraw owner | ok, no fee |
| MV-004 | withdraw non-owner | abort |
| MV-005 | heartbeat permissionless | succeeds with bounty rules |
| MV-006 | venue not allowed | stake blocked offchain + policy |
| RT-001 | Suilend supply mock | digest, no secrets |
| RT-002 | harvest PTB order | claim before heartbeat |
10. Immediate recommendation
Section titled “10. Immediate recommendation”- Do not start a new Sui package from Option A greenfield.
- Do implement agent API + adapters wiring on top of
treasury.move(docs 23–24). - Do add Move only for locked-model gaps (single balance, survival unstake event) after inventory.
- Venues: Suilend + NAVI now; Scallop when ready — not Haedal-first.
Deliverables already available
Section titled “Deliverables already available”| Doc | Content |
|---|---|
23-auto-yield-implementation.md | E2E product + tickets |
24-open-yield-api.md | Agent API + deterministic tests |
| This file | Sui Move architecture map |
- Overview: page
5bfcc7e7-c5d0-49bd-a7fa-6f7b6704f381 - API: page
9971f85c-cdec-41d1-be31-35d3f108c132 - Epic: XEL-152