Skip to content

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.


ChoiceDecision
Home chainSui
LanguageMove (existing packages)
Fee~5% protocol_yield_skim_bps = 500 (Open Yield product default)
Stake defaultOFF — owner opt-in Auto Yield
First venuesSuilend + NAVI (adapters exist) — Scallop/Haedal next
Cross-chainNot in Move core; Mayan offchain + credit endowment
OrchestrationOffchain agents

Generic Open YieldXEL Move / runtime
YieldRouter (shared)treasury::Endowment (shared) + TreasuryPolicy
UserPosition (owned)Position refs offchain + venue AccountCap / obligation objects; character aNFT is owned
FeeModuleTreasuryPolicy.protocol_yield_skim_bps + waterfall in heartbeat / record_epoch_waterfall
AdapterRegistryset_yield_venue_allowed + backend allowlist
deposittop_up_endowmentno fee
withdrawwithdraw_endowment_principal — owner, no fee
harvestadapter claim_yield PTB + heartbeatfee here
Auto Payoffchain + payment/spend policy (not new vault module first)
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.mjs

MVP work is mostly runtime + API + wiring, plus small Move fixes if single-balance / survival-unstake gaps remain vs locked model.


ObjectShared / ownedWho mutatesOpen Yield role
LivingCharacter (aNFT)Ownedowner transferIdentity root
Endowment<T>Sharedowner top_up/withdraw; anyone heartbeatCapital vault
TreasuryPolicyShared / boundowner configureFee bps, venues, harvest flags
Venue position (Suilend/NAVI)Protocol objectsadapter PTB under policyYield generation
AgentCapOwned by operatorowner issue/revokeScoped 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)”
FunctionCallerFee?
create_endowmentowner pathno
top_up_endowmentanyone paying inno
withdraw_endowment_principalownerno
heartbeatpermissionlessyes (skim on net_yield / waterfall)
configure_yield_harvestpolicy owner
set_yield_venue_allowedpolicy owner
pay_storage_renewalsurvival pathrouting fee family
// 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 / bills
  • Not msg.sender free-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.

StepWorkNew Move?Ticket
1Confirm package IDs / testnet-mainnet targetsnoops
2Opportunity agent + discovery (TVL ≥ $50M)noXEL-164 / 153
3Scorer + estimates (gross/net after 5% fee)noXEL-154 / 165
4Owner Auto Yield toggle OFF defaultnoXEL-156
5Stake/unstake via Suilend then NAVIno (adapters exist)XEL-157
6Harvest PTB: claim → heartbeat fee skimpolishXEL-158 / 168
7Gas sponsor on all plansnoXEL-167
8Bridge in MayannoXEL-166
9Survival auto-unstake onlymaybe small Move eventXEL-159
10Auto Pay post-fee residualnoXEL-163
11Align Endowment to single balance if v2 still has allocation bucketsyes if neededonchain gap
12Scallop adapter (optional 3rd venue)runtimelater

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 registry

XEL characters should still prefer endowment-native Open Yield.


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 skillOnchainOffchain
routeYield deposittop_up_endowmentoptional Mayan if autoBridge
routeYield stakeSuilend/NAVI supply if Auto Yield on
harvestheartbeat (+ claim in same PTB)keeper / anyone
withdrawwithdraw_endowment_principalunstake first if needed
getPositionviews / indexerread_apy, estimates
enableAutoPaypolicy/spend configx402 / provider pay

IDCaseExpected
MV-001top_up 10000principal +10000, no skim
MV-002harvest gross 10000 skim 5%protocol_skim 500
MV-003withdraw ownerok, no fee
MV-004withdraw non-ownerabort
MV-005heartbeat permissionlesssucceeds with bounty rules
MV-006venue not allowedstake blocked offchain + policy
RT-001Suilend supply mockdigest, no secrets
RT-002harvest PTB orderclaim before heartbeat

  1. Do not start a new Sui package from Option A greenfield.
  2. Do implement agent API + adapters wiring on top of treasury.move (docs 23–24).
  3. Do add Move only for locked-model gaps (single balance, survival unstake event) after inventory.
  4. Venues: Suilend + NAVI now; Scallop when ready — not Haedal-first.
DocContent
23-auto-yield-implementation.mdE2E product + tickets
24-open-yield-api.mdAgent API + deterministic tests
This fileSui Move architecture map
  • Overview: page 5bfcc7e7-c5d0-49bd-a7fa-6f7b6704f381
  • API: page 9971f85c-cdec-41d1-be31-35d3f108c132
  • Epic: XEL-152