This document defines the architectural decisions, storage layouts, and contract responsibility matrix for the SO4 Markets protocol on Stellar/Soroban.
All request types (Deposits, Withdrawals, Orders) and Positions live in handler-local persistent storage within their respective contracts rather than in the shared data_store.
- Deposits are stored in the persistent storage of
deposit_handler. - Withdrawals are stored in the persistent storage of
withdrawal_handler. - Orders are stored in the persistent storage of
order_handler. - Positions are stored in the persistent storage of
order_handler.
-
Storage Rent (TTL) Isolation Soroban requires contracts to pay rent (TTL) for persistent storage. Placing user-specific transient requests (deposits, withdrawals, orders) and long-lived positions in their local handler contracts isolates their TTL management. It prevents a single global
data_storefrom becoming a bottleneck or a source of shared rent eviction risk. -
Access Control & Encapsulation Positions and orders represent critical financial states. Storing them inside
order_handlerenforces that only the authorizedorder_handlerlogic (viacreate_order,execute_order, etc.) can mutate position records. If stored in a shareddata_store, any contract granted theCONTROLLERrole would have raw write access to position states, increasing the attack surface. -
Avoid Serialization Overhead Storing complex Rust structs (like
PositionPropsorOrderProps) in a centralized key-value database likedata_storerequires cross-contract serialization/deserialization into raw bytes or maps. Local storage allows direct, type-safe serialization within the contract's own storage namespace, significantly reducing CPU instruction usage and transaction size.
No core contracts store requests or positions in a way that contradicts this decision.
deposit_handlerusesLocalKey::Deposit(key)in its own persistent storage.withdrawal_handlerusesLocalKey::Withdrawal(key)in its own persistent storage.order_handlerusesOrderStorageKey::Order(key)andPositionStorageKey::Position(key)in its own persistent storage.- View and settlement contracts (e.g.
liquidation_handler,adl_handler, andreader) query theorder_handlervia cross-contract view calls (get_position) to read position details rather than querying thedata_store.
Below is the responsibility mapping of every contract under contracts/* within the protocol graph.
- Description: Access control registry mapping accounts to roles.
- State Owned:
InstanceKey::Admin,InstanceKey::Initialized, and persistent(account, role) -> bool. - Initialization Args:
admin: Address - Roles Checked: Admin authorization required for granting/revoking roles.
- Callers: All contracts validating roles (via
has_role). - Callees: None.
- Emitted Events:
RoleGranted,RoleRevoked(implied). - Upgrade Policy: Upgradeable (Admin).
- Description: Universal typed key-value database for market metadata, configs, and parameters.
- State Owned:
InstanceKey::Admin,InstanceKey::RoleStore, and arbitraryBytesN<32> -> Valuemappings. - Initialization Args:
admin: Address, role_store: Address - Roles Checked:
CONTROLLERrole required for all state-mutating (write) calls. - Callers: Handlers, factories, and utilities.
- Callees:
role_store. - Emitted Events: None.
- Upgrade Policy: Upgradeable (Admin).
- Description: Keeper-fed oracle that stores and signs token prices per ledger.
- State Owned:
InstanceKey::Admin,InstanceKey::RoleStore,InstanceKey::DataStore, and temporary price records. - Initialization Args:
admin: Address, role_store: Address, data_store: Address, passphrase: Bytes - Roles Checked:
price_keeper/order_keeperrole required to set prices. - Callers: Handlers and readers.
- Callees:
role_store,data_store. - Emitted Events:
prices_set(implied). - Upgrade Policy: Upgradeable (Admin).
- Description: Deterministically deploys LP token contracts (
market_token) and registers them. - State Owned:
InstanceKey::Admin,InstanceKey::RoleStore,InstanceKey::DataStore,InstanceKey::MarketTokenWasmHash. - Initialization Args:
admin: Address, role_store: Address, data_store: Address - Roles Checked:
MARKET_KEEPERrequired to create markets; Admin required to set WASM hash. - Callers: Keepers/Admin.
- Callees: Deploys and initializes
market_token. Writes market props todata_store. - Emitted Events:
wasm_set,mkt_new. - Upgrade Policy: Upgradeable (Admin).
- Description: SEP-41 compliant LP token representing pool ownership.
- State Owned: Decimals, name, symbol, balances, allowances.
- Initialization Args:
admin: Address, role_store: Address, decimal: u32, name: String, symbol: String - Roles Checked:
CONTROLLERrequired to mint/burn LP tokens. - Callers:
market_factory, handlers. - Callees:
role_store. - Emitted Events: Standard SEP-41
Transfer,Mint,Burn,Approval. - Upgrade Policy: Immutable.
- Description: Holds long/short tokens between deposit creation and execution/cancellation.
- State Owned:
InstanceKey::RoleStore, and persistentTokenBalance(Address)snapshots. - Initialization Args:
admin: Address, role_store: Address - Roles Checked:
CONTROLLERrequired fortransfer_out. - Callers:
deposit_handler. - Callees: SEP-41 token contracts,
role_store. - Emitted Events: None.
- Upgrade Policy: Immutable.
- Description: Holds LP tokens between withdrawal creation and execution/cancellation.
- State Owned:
InstanceKey::RoleStore, and persistentTokenBalance(Address)snapshots. - Initialization Args:
admin: Address, role_store: Address - Roles Checked:
CONTROLLERrequired fortransfer_out. - Callers:
withdrawal_handler. - Callees:
market_token,role_store. - Emitted Events: None.
- Upgrade Policy: Immutable.
- Description: Holds collateral during pending order lifecycle.
- State Owned:
InstanceKey::RoleStore, and persistentTokenBalance(Address)snapshots. - Initialization Args:
admin: Address, role_store: Address - Roles Checked:
CONTROLLERrequired fortransfer_out. - Callers:
order_handler. - Callees: SEP-41 token contracts,
role_store. - Emitted Events: None.
- Upgrade Policy: Immutable.
- Description: Manages two-step deposit lifecycle (create -> keeper execute/cancel).
- State Owned:
InstanceKey::Admin,InstanceKey::RoleStore,InstanceKey::DataStore,InstanceKey::Oracle,InstanceKey::DepositVault, and persistentLocalKey::Deposit(nonce)props. - Initialization Args:
admin: Address, role_store: Address, data_store: Address, oracle: Address, deposit_vault: Address - Roles Checked:
ORDER_KEEPERrequired to execute/cancel. - Callers:
exchange_router, keepers. - Callees:
deposit_vault,market_token,data_store,oracle,role_store. - Emitted Events:
dep_req,dep_exec,dep_fail. - Upgrade Policy: Upgradeable (Admin).
- Description: Manages two-step withdrawal lifecycle (create -> keeper execute/cancel).
- State Owned:
InstanceKey::Admin,InstanceKey::RoleStore,InstanceKey::DataStore,InstanceKey::Oracle,InstanceKey::WithdrawalVault, and persistentLocalKey::Withdrawal(nonce)props. - Initialization Args:
admin: Address, role_store: Address, data_store: Address, oracle: Address, withdrawal_vault: Address - Roles Checked:
ORDER_KEEPERrequired to execute/cancel. - Callers:
exchange_router, keepers. - Callees:
withdrawal_vault,market_token,data_store,oracle,role_store. - Emitted Events:
wd_req,wd_exec,wd_fail. - Upgrade Policy: Upgradeable (Admin).
- Description: Manages full order lifecycle, position updates, and execution routing.
- State Owned:
InstanceKey::Admin,InstanceKey::RoleStore,InstanceKey::DataStore,InstanceKey::Oracle,InstanceKey::OrderVault, persistentOrderStorageKey::Order(nonce), and persistentPositionStorageKey::Position(key). - Initialization Args:
admin: Address, role_store: Address, data_store: Address, oracle: Address, order_vault: Address - Roles Checked:
ORDER_KEEPERrequired to execute/cancel orders.LIQUIDATION_KEEPER/ADL_KEEPER/CONTROLLERrequired for liquidation and ADL. - Callers:
exchange_router, keepers,liquidation_handler,adl_handler. - Callees:
order_vault,data_store,oracle,role_store, and libraries (increase_position_utils,decrease_position_utils, etc.). - Emitted Events:
ord_req,ord_exec,ord_fail,pos_update. - Upgrade Policy: Upgradeable (Admin).
- Description: Validates position health and triggers forced closing of underwater positions.
- State Owned:
InstanceKey::Admin,InstanceKey::RoleStore,InstanceKey::DataStore,InstanceKey::Oracle,InstanceKey::OrderHandler. - Initialization Args:
admin: Address, role_store: Address, data_store: Address, oracle: Address, order_handler: Address - Roles Checked:
LIQUIDATION_KEEPERrequired to liquidate. - Callers: Keepers.
- Callees:
order_handler(for position view and liquidation execution),data_store,oracle,role_store. - Emitted Events:
liq_req. - Upgrade Policy: Upgradeable (Admin).
- Description: Deleveraging handler that closes profitable positions when the pool PnL threshold is breached.
- State Owned:
InstanceKey::Admin,InstanceKey::RoleStore,InstanceKey::DataStore,InstanceKey::Oracle,InstanceKey::OrderHandler. - Initialization Args:
admin: Address, role_store: Address, data_store: Address, oracle: Address, order_handler: Address - Roles Checked:
ADL_KEEPERrequired to execute deleveraging. - Callers: Keepers.
- Callees:
order_handler(for position view and ADL execution),data_store,oracle,role_store. - Emitted Events:
adl_req. - Upgrade Policy: Upgradeable (Admin).
- Description: Claims accumulated protocol fees and manages fee distribution.
- State Owned:
InstanceKey::Admin,InstanceKey::RoleStore,InstanceKey::DataStore. - Initialization Args:
admin: Address, role_store: Address, data_store: Address - Roles Checked:
FEE_KEEPER/ Admin required to claim fees. - Callers: Keepers/Admin.
- Callees:
data_store,role_store, SEP-41 token contracts. - Emitted Events:
fees_claimed(implied). - Upgrade Policy: Upgradeable (Admin).
- Description: Stores referral codes, trader-referrer links, and tier rebate configs.
- State Owned:
InstanceKey::Admin,ReferralKey::CodeOwner,ReferralKey::TraderCode,ReferralKey::ReferrerTier,ReferralKey::TierConfig. - Initialization Args:
admin: Address - Roles Checked: Admin auth required to configure tiers and referrer settings.
- Callers: Users (code registration), frontend/handlers (discounts).
- Callees: None.
- Emitted Events:
CodeRegistered,TraderCodeSet. - Upgrade Policy: Upgradeable (Admin).
- Description: Stateless read-only aggregate queries for UI and keepers.
- State Owned: None (Stateless).
- Initialization Args: None.
- Roles Checked: None (Public view).
- Callers: Client UI, keepers.
- Callees:
data_store,oracle(via read-only calls). - Emitted Events: None.
- Upgrade Policy: Upgradeable (Admin).
- Description: Main entry point for user interactions. Supports atomic multicall.
- State Owned:
InstanceKey::Admin,InstanceKey::RoleStore,InstanceKey::DataStore,InstanceKey::DepositHandler,InstanceKey::WithdrawalHandler,InstanceKey::OrderHandler. - Initialization Args:
admin: Address, role_store: Address, data_store: Address, deposit_handler: Address, withdrawal_handler: Address, order_handler: Address - Roles Checked: None (Public).
- Callers: Users, frontends.
- Callees:
deposit_handler,withdrawal_handler,order_handler, SEP-41 token contracts. - Emitted Events: None.
- Upgrade Policy: Upgradeable (Admin).
(Detailed launch scope definitions and Solidity-to-Soroban deviations to be finalized by the secondary contributor).