Skip to content
NoetherDocs

Contracts and events

Addresses for the testnet deployment and the guarded mainnet deployment, how to verify what the gateway serves, and every event the contracts emit.

This page is the on-chain reference for Noether: every deployed contract address on the live stack, how to confirm what a running gateway is pointed at, and the complete list of events each contract emits with exact field order, so indexers and integrations can decode them without guesswork.

Deployed contracts (Stellar testnet)

The production stack, which testnet.noether.exchange and the gateway at https://noether-api.proudmeadow-533cf0d8.germanywestcentral.azurecontainerapps.io serve:

ContractRoleAddress
MarketTrading engine: positions, orders, liquidation, fundingCBHHWFAYLB3SXJCE232DC6WNSK74IBEOROAGCI2AFBA2H5NQOH2KYKNN
VaultLP pool and counterparty; holds USDC, issues NOECBSWA5P75NGV2LP5KOY7A7LOAX2CENI5OYBSJ5IVLHENKQJF2I3ZBSYE
Noeracle shimSEP-40 price reader the market callsCDRQJDCZ2EKIVAM6D6U2YFTE7VNMN3TFUUJGZ5SKAFB5TCLMSHSSWU6N
Noether RouterRelays a signed price and trades in one transactionCBDVQKYEN6QMRGQZC77DFYEQXQHDMCVJ3TPBJKNERJVMIESA6GQT44LG
USDCTest USDC token (Stellar Asset Contract)CA63EPM4EEXUVUANF6FQUJEJ37RWRYIXCARWFXYUMPP7RLZWFNLTVNR4
NOEVault share token (Stellar Asset Contract)CADEAZ3TT5SIGJVBIWMMWC4TFZKPKGPGGJ6O4JGAAZTLR6MIBDRBQ4H5
Vault FactoryUser-created trader vaultsCAG5E6IM32GFEXGZOXWLFHNVRMDOYGPRZKZSBFXXHVJ5Q5MNJUSNQKT7
ReferralCodes, bindings, fee share and claimsCB4A2OHP6BKKF2RC532PPRE7K4X3UOZEVASEQTTTWMRSZGUN2AV2REND
NoeracleSigned price source (pull oracle)CBTO5K2NLG2KYHQDL5ME4SWFQ5GRR7GVU4DFATOXGVS3OUJJDFF2YYNS

Snapshot from the gateway on 2026-09-18, stack deployed 2026-07-21. Live values: the gateway's /v1/health response.

Notes:

  • NOE is a classic Stellar asset, code NOE, issued by GA7PCANKNREYVUMU6CCOPJHVE5XCRUCFLZ6CGS3GX4BNDBR63QAVLVUZ, wrapped as a Stellar Asset Contract (the NOE address above). It is pre-minted to the liquidity vault and moved by transfer; there is no runtime minting.
  • USDC is a test asset issued for Noether, also wrapped as a Stellar Asset Contract. It has no real-world value.
  • Noeracle is the external signed-price source. The market reads prices through the shim, and the router relays signed attestations into Noeracle at trade time. See Oracle and price feeds.
  • Addresses change whenever contracts are redeployed or the Stellar testnet resets. Do not hardcode them; read them from GET /v1/health at startup.
  • All amounts and prices on-chain use 7-decimal fixed point: raw 10_000_000 = 1.0.

Deployed contracts (Stellar mainnet, guarded mode)

Deployed on 2026-10-03. The stack is live but dark: the market is paused (mode 1: no new positions; closes, cancels and withdrawals stay possible), the liquidity vault holds no funds, and every admin operation needs two of three keys. Since 2026-10-05 the vault's deposit cap is set to zero and creating a trader vault is limited to the admin, so no funds can enter before the opening. Trading opens after the independent audit; see Security and audits. The settlement asset on mainnet is Circle's USDC.

ContractAddress
MarketCBC2XPFPI2DI7CVGRHDLVIHENIPFJJOGSUPAHLWZ43UTHK5TFJVIHJTC
Liquidity vaultCCKLYRVPC7V3N46C22MOPGLPWFLMCBTEZXLFH6USLMOUI34M2TIGBJZG
Noeracle shimCCMIT3N6MFNMRI4DALO2IYWJUX3KCAISBLQMXVYLGMQNCIEALNG6BNCS
Noether routerCDQ3IIOHD3ROBIJGMAQY7XNXOOJMJVUNVJKISZKRL2HDXS2OVRRK3FJZ
NoeracleCBX4S2UPV5RHPPRUDK6GHIETWFUIEI446FPU7RWGEZ3V3MU5GK4JRUHC
Vault factoryCBVO5EYFMQ3MJRNWWMFTPK25PCC32HUZR3A657ULGIWMCR2JRP6GEWSD
Referral registryCCNE2BCYJMOULKOEJL5OXCYL6FY3LSZPPBR2GRRMQXTWMBOET6KNEFV4
USDC (Circle, SAC)CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75
NOE token (SAC; issuer GBZUHPF62VNZZ4FGUG2GIOFSNTLLFQ3EPV7RIHLAJFID3Q2NLT7LZPKD, supply locked)CD2MFZILCJA4DSM2JA4YQ535YIBVLX5C5ANZOMDLUMO3B2NGPDLBWL3I
Admin account (2-of-3)GCAINIWHPUKBDNSWNHQM5AZUZ27DNIFK7RR7V6Q4X55SKTGQG4XZKHO7

Every address is verifiable on stellar.expert: the deployed code hashes equal the testnet builds for the market, vault, router, shim and referral contracts; the vault factory carries two fixes that landed after the testnet deployment (see the changelog). market.get_pause_state returns [1, 1791048662]. There is no mainnet gateway, keeper or indexer while the stack is paused.

Verify what a deployment actually serves

The gateway echoes the contract addresses it resolved at boot from GET /v1/health. This is the ground truth for what the live API is pointed at:

curl -s https://noether-api.proudmeadow-533cf0d8.germanywestcentral.azurecontainerapps.io/v1/health
{
  "status": "ok",
  "network": "testnet",
  "contracts": {
    "market":        { "address": "CBHHWFAY...KYKNN", "source": "env" },
    "vault":         { "address": "CBSWA5P7...ZBSYE", "source": "env" },
    "noeracleShim":  { "address": "CDRQJDCZ...SWU6N", "source": "env" },
    "noetherRouter": { "address": "CBDVQKYE...T44LG", "source": "env" },
    "usdcToken":     { "address": "CA63EPM4...TVNR4", "source": "manifest" },
    "noeToken":      { "address": "CADEAZ3T...BQ4H5", "source": "env" },
    "vaultFactory":  { "address": "CAG5E6IM...NQKT7", "source": "env" },
    "referral":      { "address": "CB4A2OHP...2REND", "source": "env" }
  },
  "indexer": { "lastLedger": 4731934, "ledgerAgeSeconds": 6 },
  "market": { "pauseState": { "mode": 0 } },
  "counts": { "chainOpenPositions": 47, "indexedOpenPositions": 47, "drift": false }
}

Addresses are abbreviated here; the live response returns them in full. Each entry carries a source field telling you whether the address came from the deployment manifest or an environment override. See System endpoints for the full health response shape.

The contracts themselves agree on the wiring: the router's get_market and get_noeracle, the shim's get_noeracle, the vault's get_market_contract, the vault factory's get_market and the referral registry's get_market all return the addresses above. You can call any view function as a read-only simulation with the Stellar CLI, for example stellar contract invoke --id <MARKET> --network testnet --source-account <ANY_FUNDED_ACCOUNT> -- get_asset_risk --asset BTC; append -- --help instead of a function name to list a contract's functions and their documentation.

Network configuration

The testnet passphrase, RPC and Horizon endpoints are on Networks, together with the mainnet parameters for the guarded deployment above.

Event reference

Soroban contracts publish events as a tuple of topics plus a data payload. Below, the topic symbol is shown in quotes and the data tuple lists fields in their exact on-chain order. Conventions:

  • direction serializes as the Direction enum: Long = 0, Short = 1.
  • Amounts, sizes, prices and rates are i128 values in 7-decimal fixed point.
  • IDs (position_id, order_id) are u64; a vault factory vault_id is u32; addresses are Stellar Address values; asset is a Symbol such as BTC.

These events are what the Noether indexer consumes to build the REST projections (positions, trades, leaderboard, vaults, referrals) and the WebSocket event streams. See WebSocket.

Market contract

TopicData tupleEmitted when
"initialized"(admin, vault, oracle_adapter)Contract initialization; oracle_adapter is the shim address
"paused"(mode, since)Admin pauses trading; mode 1 = halt-open, 2 = full-freeze
"unpaused"() (empty)Admin resumes
"pause_degraded"(from_mode, to_mode)A full-freeze auto-degraded to halt-open after 72 hours
"asset_halt_set" (second topic: asset)(halted)Admin halts or resumes one asset
"position_opened"(position_id, trader, asset, direction, size, entry_price)Every open: isolated, cross and keeper-executed entries
"position_closed"(position_id, trader, asset, direction, size, entry_price, current_price, pnl)Manual close (isolated or cross), stop-loss, take-profit or trailing execution, reduce-only close, ADL close, and each leg closed by auto-netting
"position_reduced"(position_id, trader, asset, closed_size, remaining_size, current_price, pnl)Partial close, including a partial reduce-only fill
"collateral_added" / "collateral_removed"(position_id, trader, amount, liquidation_price)Margin edit on an isolated position; carries the recomputed liquidation price
"position_partial_liq"(position_id, trader, asset, direction, closed_size, keeper_reward, current_price)A partial-liquidation round; the position survives with reduced size
"position_liquidated"(position_id, trader, asset, direction, size, keeper_reward, current_price)Full isolated liquidation, and once per leg closed by a cross-account liquidation
"liq_refund"(trader, position_id, refund, penalty)Residual returned after a non-bankrupt liquidation; position_id 0 means the cross account
"cross_liq"(trader, total_pnl, keeper_reward)One per liquidate_cross_account call, after the per-leg events
"bad_debt_recorded"(trader, asset, amount, buffer_covered, lp_absorbed)A bankrupt liquidation left uncollectable debt; asset is CROSS for an account-level record
"funding_applied"(asset, funding_rate, hours_elapsed, cumulative_index)Hourly funding tick, one per pair
"funding_migrated"(asset, legacy_index)One-time migration from the global to the per-pair funding index
"adl_triggered" / "adl_cleared"(asset, reason, payable_upnl, coverage)ADL flag change; reason 0 = coverage ratio, 1 = a winner was paid short
"adl_executed"(position_id, trader, asset, direction, size, price, pnl, score)adl_close realized a winning position
"asset_risk_set"(asset, max_leverage, im_bps, mm_bps)Admin set a pair's risk parameters
"fee_split_set"(treasury, bps)Admin set the protocol fee share
"referral_set"(referral)Admin wired the referral registry
"admin_rotated"(old_admin, new_admin)Admin transfer
"order_placed"(order_id, trader, trigger_price)place_limit_order, place_stop_limit_order, set_stop_loss, set_take_profit and place_trailing_stop (for a trailing stop the third field is the current mark)
"order_cancelled"(order_id, reason)Any cancellation; reason is a Symbol (table below)
"order_executed"(order_id, reward)Successful keeper execution of a pending order

order_cancelled reasons:

ReasonMeaning
"user"Owner called cancel_order
"slippage"Execution price breached the order's slippage tolerance; collateral refunded, status set to CancelledSlippage
"ioc_not_filled"IOC order placed while its trigger condition was not met; collateral refunded at placement
"pos_closed"An attached stop-loss, take-profit or trailing stop was cancelled because its position closed or was liquidated
"reduce_only_no_position"Reduce-only order executed with no suitable opposing position to close
"asset_unconfigured"Entry order executed on a pair that has no risk parameters; collateral refunded
"risk_config"Entry order no longer fits the pair's leverage cap or maximum size at execution; collateral refunded

The indexer decodes the trading and solvency events above (positions, orders, liquidations, funding, ADL, pause state, asset halts and collateral edits) into GET /v1/events. Administrative events (unpaused, fee_split_set, referral_set, admin_rotated, funding_migrated, asset_risk_set) are not archived there; read them from Soroban RPC or an explorer.

Liquidity vault contract

TopicData tupleEmitted when
"initialized"(admin, market_contract, usdc_token, noe_token)Contract initialization
"deposit"(depositor, usdc_amount, noe_amount, fee)LP deposits USDC, receives NOE
"withdraw"(withdrawer, noe_amount, net_usdc, fee)LP redeems NOE for USDC
"pnl_settled"(pnl)Every settle_pnl call from the market (win, loss or zero)
"payout_shortfall"(trader, pnl, paid, short)A winner's payout exceeded buffer plus pool; the unpaid remainder is booked as that trader's claim
"loss_received"(amount)Market credited a real USDC receipt (trader losses, funding, fees)
"bounty_paid"(keeper, amount, paid)Insurance buffer topped a liquidation keeper up to the bounty floor
"protocol_fee_routed"(amount, to_buffer, overflow)Protocol fee share split between the insurance buffer and the treasury
"exposure_synced" (second topic: asset)(asset_unrealized_pnl, total_unrealized_pnl, release)Market pushed a fresh per-asset mark or released a payout reservation
"buffer_seeded" / "buffer_funded"(amount, to_reserve)Admin seeded, or the market credited, the insurance buffer
"buffer_drawn"(amount, covered)Bad debt drawn from the buffer
"buffer_paid"(to, amount, paid)Buffer paid an ADL compensation
"shortfall_repaid"(trader, paid, remaining)A trader claimed part of an outstanding payout shortfall
"market_updated"(old_market, new_market)Admin re-pointed the vault at a new market contract
"deposit_fee_updated" / "withdraw_fee_updated"(fee_bps)Admin changed a vault fee
"deposit_cap_set" / "aum_cap_set"(cap)Admin set the per-account or the global deposit cap (0 = unlimited)
"withdraw_cooldown_set"(seconds)Admin changed the post-deposit withdrawal cooldown
"buffer_target_set" / "shortfall_bps_set" / "reserve_cap_set"(bps)Admin changed the buffer target, the shortfall repayment share or the aggregate reserve cap
"asset_cap_set" / "skew_cap_set"(asset, bps)Admin changed a per-asset side cap or net-skew cap
"asset_cap_abs_set"(asset, max_notional)Admin set an absolute per-asset cap
"paused" / "unpaused"() (empty)Vault pause state changed (blocks deposits only; withdrawals are never pause-gated)
"admin_updated"(old_admin, new_admin)Admin transfer
"recovery_init" / "recovery_proposed" / "recovery_executed" / "recovery_cancelled"(recipient) / (amount, execute_after) / (paid, recipient) / ()Timelocked admin recovery flow, usable only while paused

The indexer archives every topic above except aum_cap_set, shortfall_bps_set, reserve_cap_set and asset_cap_set.

Vault Factory contract (Trader Vaults)

Vault factory events carry the vault ID as a second topic, so you can filter per vault without decoding payloads.

TopicsData tupleEmitted when
"vault_created", vault_id(leader, name)New Trader Vault created
"deposit", vault_id(depositor, amount, shares)Depositor buys shares
"withdraw", vault_id(depositor, shares, usdc_out)Depositor redeems shares
"leader_open", vault_id(leader, position_id, collateral)Leader opened a market position through the vault
"leader_close", vault_id(leader, position_id)Leader closed a vault position
"leader_limit", vault_id(leader, order_id)Leader placed a limit order through the vault
"leader_stop_limit", vault_id(leader, order_id)Leader placed a stop-limit entry through the vault
"leader_cancel", vault_id(leader, order_id)Leader cancelled a vault order
"leader_sl" / "leader_tp" / "leader_trail", vault_id(leader, order_id, position_id)Leader attached a stop-loss, take-profit or trailing stop to a vault position
"order_reconciled", vault_id(order_id, position_id, credited)A keeper-resolved vault order was reconciled (executed or refunded)
"position_reconciled", vault_id(position_id, proceeds)A keeper-closed vault position was reconciled with its exact proceeds
"fees_claimed", vault_id(leader, owed, new_nav)Leader claimed profit share above the high-water mark
"paused" / "unpaused", vault_id() (empty)Leader paused or unpaused the vault
"admin_paused" / "admin_unpaused", vault_id() (empty)Factory admin paused or unpaused the vault
"allowlist_set"(leaders)Admin restricted who may create vaults (empty list = permissionless)
"max_vaults_set"(max)Admin capped the number of vaults (0 = unlimited)
"admin_rotated"(old_admin, new_admin)Admin transfer

The indexer archives every per-vault topic; allowlist_set, max_vaults_set and admin_rotated carry no vault ID and are not decoded.

Referral contract

TopicData tupleEmitted when
"initialized"(admin, market)Contract initialization
"code_created"(referrer, code)A referral code is registered
"referrer_set"(referee, referrer, code)A trader binds to a referral code (permanent, one-time)
"trade_recorded"(referee, referrer, original_fee, discount, payout, volume)The market recorded a fee-bearing open by a referred trader
"claimed"(referrer, amount)Referrer claimed accrued rewards in USDC
"code_revoked" / "code_unrevoked"(referrer, code)Admin revoked or restored a code
"unbound"referee (single value)Admin removed a referee's binding
"discount_bps_set" / "ref_share_bps_set" / "min_code_volume_set"(bps) / (bps) / (volume)Admin changed the discount, the referrer share or the code-creation volume floor
"market_rotated" / "usdc_rotated"(market) / (usdc)Admin re-pointed the registry
"admin_rotated"(old_admin, new_admin)Admin transfer

The indexer archives code_created, referrer_set, trade_recorded and claimed.

Reading events yourself

Events are available three ways:

  • Soroban RPC: getEvents against https://soroban-testnet.stellar.org, filtered by the contract addresses above.
  • Noether gateway: the indexer archives the decoded events and serves them over REST (GET /v1/events, filterable by topic, contract, from_ledger, to_ledger and before_ts) and streams them over WebSocket. See the REST API and WebSocket references.
  • Explorer: each address in the table above links to the contract's page on a Stellar block explorer, which shows recent invocations and events.

Next steps

On this page