- Sui’s object model vs EVM’s account model
- Why dynamic dispatch doesn’t work and how the Call pattern solves it
- Capabilities for authorization instead of
msg.sender - Programmable Transaction Blocks (PTBs) for atomic multi-step execution
- Gas model differences and rebate mechanism
VM Architecture
Sui uses the Move programming language and employs an object-based model rather than the account-based model used by EVM chains. This fundamental difference requires different patterns for implementing crosschain functionality.Sui Object Model
Sui organizes state into objects with different ownership types. For an introduction to Sui’s object model, see Getting Started. LayerZero uses all three ownership types:- Shared:
EndpointV2,MessagingChannel,OApp,OFT<T>(accessible by anyone, mutable by authorized) - Owned:
AdminCap,CallCap(belong to specific address, used for authorization) - Immutable: Published packages,
CoinMetadata<T>(read-only, never change)
- Unique ID (
UID): Globally unique identifier - Abilities: Define what operations are allowed (
key,store,copy,drop) - Type: Determines structure and behavior
No Dynamic Dispatch
Unlike EVM chains that support dynamic dispatch throughdelegatecall, Sui does not support dynamic dispatch. Function calls must target modules known at compile time.
Why this matters: The LayerZero Endpoint needs to call back into OApp modules whose addresses vary per deployment—not known when the Endpoint is published. This architectural constraint requires a different approach.
Call Pattern (Hot Potato)
LayerZero solves the dynamic dispatch limitation using a capability-based pattern called “hot potato.” To achieve dynamic routing, LayerZero uses the Call pattern—a capability-based hot potato implementation. TheCall<Param, Result> struct:
- Has no
droporstoreabilities (cannot be ignored or saved) - Can only be created by the caller module
- Must be consumed by the designated callee
- Enforces proper sequencing through lifecycle states
- Returns results back to the caller
Programmable Transaction Blocks (PTBs)
Sui’s execution model centers around Programmable Transaction Blocks—atomic command sequences that:- Execute multiple Move function calls
- Pass objects and results between calls
- Guarantee all-or-nothing execution
- Enable complex multi-contract workflows
- Support up to 1024 commands per block
Message Flow Overview
LayerZero messages on Sui flow through multiple modules using the Call pattern within a Programmable Transaction Block. High-Level Flow:- Call pattern: Dynamic routing through
Call<Param, Result>objects - PTB coordination: All steps happen atomically in one transaction
- Capability validation: Each module validates CallCap ownership
- Storage management: MessagingChannel tracks nonces and payload hashes
Complete Protocol Details
For detailed send/verify/receive workflows with contract code, struct definitions, and transaction analysis, see Protocol Overview.Transaction Execution Model
Sui supports two types of function calls, each serving different purposes in the LayerZero protocol.Static Calls
Used when the target module is known at compile time:- Direct function invocation within a PTB
- No intermediate
Callobject needed - Example: OApp calling Endpoint (Endpoint object ID is known)
Call Pattern (Dynamic Routing)
Used when the target module is not known at compile time:- Caller creates a
Call<Param, Result>object - PTB routes the
Callto the appropriate module - Recipient processes and completes the
Call - Caller confirms the
Callto extract results - Example: Endpoint routing to OApp (OApp object ID varies per deployment)
Atomicity Guarantees
All operations within a PTB are atomic:- If any step fails, the entire transaction reverts
- No partial state changes
- Enables complex multi-step operations with safety guarantees
- Nonce management and packet construction
- Worker assignment and fee aggregation
- DVN verification and threshold checking
- Message delivery and payload clearing
State Management Model
LayerZero on Sui uses shared and owned objects to manage configuration and message state, rather than EVM-style storage slots.LayerZero State Storage
State is organized into objects with different ownership types, each serving specific purposes:| State Type | Storage Location | Ownership Type |
|---|---|---|
| Endpoint | EndpointV2 shared object | Shared (anyone can read, admin can modify) |
| OApp Configuration | OApp shared object | Shared (owner via AdminCap) |
| OApp Peer Mappings | Peer struct within OApp | Embedded (has store ability) |
| Messaging Channels | MessagingChannel shared objects | Shared (created per OApp) |
| Library Configs | Objects within Uln302 | Shared object fields |
| Admin Authority | AdminCap owned objects | Owned (transferable to new admin) |
- Shared objects: Created with
transfer::share_object(), accessible to all transactions - Owned objects: Created with
transfer::transfer(), belong to specific addresses - Embedded structs: Fields within objects (e.g.,
Peer,EnforcedOptions) - Tables: Dynamic collections stored within objects (e.g., peer mappings by EID)
Object-Based Configuration
Configuration is stored in struct fields and Tables, not storage slots:Initialization Requirements
Before sending messages, you must:- Register the OApp: Call
endpoint::register_oapp()to create aMessagingChannel - Initialize channels: Call
endpoint::init_channel()for each remote EID - Set peer addresses: Call
oapp::set_peer()for each destination - (Optional) Set send/receive libraries (uses Endpoint defaults if not set)
- (Optional) Configure ULN parameters (uses library defaults if not set)
Security & Permission Model
Sui’s security model differs fundamentally from EVM’smsg.sender approach, using owned objects to prove authorization.
Capability-Based Authorization
Instead of checking the transaction sender, Sui functions require capability objects as parameters:| Capability | Type | Purpose |
|---|---|---|
CallCap | Owned | Authorizes creating Call objects and calling modules |
AdminCap | Owned | Grants admin rights (set peers, configure options) |
TreasuryCap<T> | Owned | Grants mint/burn authority for coin type T |
UpgradeCap | Owned | Authorizes package upgrades |
CallCap Type System
CallCap objects have two types that determine their identifier:
- Registry lookups use
callCap.id()→ package address MessagingChannel.oappfield stores package address- Peer addresses must be package IDs (not object IDs)
- Verification checks receiver against package address
- Remote chains send to package address, not object
Why This Matters for Configuration
When you deploy an OApp/OFT and configure peers: On Sui side:- Remote chain sends to your package ID
- Sui Endpoint looks up package ID in registry
- Finds your MessagingChannel
- Routes message to your OApp object
Validation Pattern
OApps validateCallCap ownership to ensure calls are authorized:
Receive Path Security
When receiving messages, the OApp validates:- Call Authorization: The
Callmust come from the authorized Endpoint - Peer Validation: Message sender must match configured peer for source EID
- Message Integrity: DVNs have verified the message before delivery
Common Security Risks
- Missing capability validation: Not checking
CallCaporAdminCap - Capability loss: Transferring or losing owned capability objects
- Incorrect peer configuration: Setting wrong peer addresses
- Bypassing validation: Skipping
assert_oapp_cap()checks
Gas Model
Sui’s gas system differs from EVM by separating storage and computation costs, with a unique rebate mechanism.Storage Gas
- Charged for storing data onchain
- Rebate mechanism: When storage is freed, gas is refunded
- This can result in negative gas utilization for transactions that free storage
Computation Gas
- Charged for execution/computation
- Base Budget: Every transaction requires a minimum of 1000 gas units
- Priority fees can be added during network congestion
Key Sui Concepts for LayerZero
Sui provides system-level objects and features that LayerZero leverages for crosschain messaging.Clock Object
The Clock is a system singleton object at address0x6:
- Library timeout validation
- Rate limiter windows
- Message expiration checks
Event System
Sui events are emitted and indexed for off-chain monitoring:Key Takeaways
- No Dynamic Dispatch: Sui doesn’t support dynamic dispatch; use Call pattern instead
- PTB-Centric: All crosschain operations happen within Programmable Transaction Blocks
- Explicit Validation: Replace EVM inheritance with explicit validation checks
- Object-Based State: Configuration stored in object fields, not EVM-style storage slots
- Atomicity: PTBs guarantee all-or-nothing execution
- Dual Gas Model: Separate charges for storage and computation, with storage rebates
Next Steps
- OApp Implementation Guide - Build custom crosschain applications
- OFT Implementation Guide - Deploy crosschain tokens
- OFT SDK - TypeScript SDK methods and patterns
- Configuration Guide - DVN and executor configuration
- Protocol Overview - Complete protocol workflows
- Sui Development Guidance - Best practices