SoraSwap is an Apache-2.0 Kotodama smart-contract repository for Sora Nexus. It uses the sibling ../iroha checkout as the canonical compiler, IVM runtime, CLI, and Torii toolchain.
The repo now also carries an SCCP bridge contract at contracts/bridge/sccp_bridge.ko. The deploy flow compiles and deploys it automatically with the rest of the contract set, and the signed Taira gate now verifies proof submit plus bridge-message relay through the real contract console backend.
Current status:
- Repo scaffold is in place.
- Initial Kotodama contracts are present for
n3x, DLMM, launchpad, referral, automation, farms, perps, options, and cover. - The derivatives stack is being rebuilt as a launch-gated multi-contract graph:
contracts/risk/risk_vault.ko,contracts/perps/perps_engine.ko,contracts/options/{manager,factory,vault,shout_option,outperformance_option}.ko, andcontracts/cover/policy_manager.ko. - The derivatives graph now depends on sibling
../irohasupport for same-transaction ABI v1 contract-to-contractcall_contract(...)execution. Product contracts store deployed contract address literals as UTF-8bytesrouting fields for nested calls, while nestedauthority()inside the callee still resolves to the caller contract subject account. - DLMM is treated as the deployable AMM surface.
- Core module config is now init-only, caller-bound, and canonical-asset based: the public
*_with_assetsand post-initconfigure_*compatibility surfaces were removed from the SoraSwap contracts. - The
n3xbasket hub now supports init-time basket targets, mint/redeem fees, redeem quoting, and mirrored fee accounting. - The DLMM pool scaffold now executes guarded multi-bin swaps, seeds multiple bins deterministically, and supports explicit
position_idLP records with per-bin fee claims. - The launchpad scaffold now tracks recorded allocations, init-time claim windows, claim inventory, refunds, explicit seed inventory, registered DLMM seed plans, and executor-backed activation results on chain.
- The risky product modules now keep executor/job ids, cadence, backlog caps, and safe-mode state on the product contracts while
contracts/automation/job_queue.koremains the generic scheduler backbone. - Derivatives now route user collateral, liability, and payout state through
risk_vaultinstead of direct product-owned custody transfers. The shared risk-vault custody account is the deployed contract subject itself, so nested product calls settle against contract-owned collateral on chain. Local acceptance and the signed Taira smoke lane both exercise active write paths for perps/options/cover. - Perps/options/cover plus
risk_vaultremain one shared rollout surface behind the combinedlint + compile + simulate + isolated local smokegate rather than independent per-module acceptance. - The current DLMM LP surface is a single-contract scaffold, not the final helper/NFT wrapper layout.
xor#universalis the canonical base asset for routing and pool pricing.docs/parity/migration_register.mdis the canonical release ledger. Modules must beported,blocked,stub, orreference-only;adaptedis treated as an intermediate non-release state only.
contracts/- Kotodama contracts grouped by module.scripts/- compile, lint, deploy, and smoke wrappers around../iroha.ui/- static browser assets for the local contract console.tests/- end-to-end local verification wrappers that keep the localnet alive for the duration of the run.config/- local, testnet, and production client templates.docs/- parity, interface, state-layout, and release notes.artifacts/- generated bytecode and manifests.deployments/- deployment evidence, canonical address records, and manifests by environment.
- Base asset:
xor#universal - Stable basket brand:
n3x - Helper aliases under this repo:
usdt#soraswap.universal,usdc#soraswap.universal,kusd#soraswap.universal,n3x#soraswap.universal
- A sibling
../irohacheckout with ABI v1 synchronous contract-to-contractcall_contractsupport wired through Kotodama codegen, IVM host/runtime dispatch, executor, Torii payload normalization, and CLI helpers. - Rust toolchain able to build
iroha,ivm, andirohad. curlandjqfor Torii smoke calls and response checks.- A client config for either local Nexus or a public environment such as Taira testnet.
make lint
make compile
make simulate-smoke
make simulate-full
make local-up
make deploy-local
make smoke-local
make test-local
make test-local-isolated
make test-local-foundation-isolated
make contract-console
make test-contract-console
make test-contract-console-ui
make test-contract-console-integration
make test-contract-console-live
make test-contract-console-testnet
make soak-contract-console
make deploy-testnet
make deploy-production
make smoke-testnet
make smoke-testnet-readonly
make smoke-production
make smoke-production-readonly
make test-contract-console-production
make testnet-nested-call-probe
make production-nested-call-probe
make test-public-env-helpers
make release-checklistmake compile and the deploy/smoke entrypoints emit stripped .to artifacts by default. Runtime deployments therefore use the same compact bytecode shape that the release evidence set records, while manifests remain under artifacts/compiled/.
The repo now includes a root Node/TypeScript/Jest workspace for derivatives simulation and cross-product stress runs.
Useful entrypoints:
npm run build
make simulate-smoke
make simulate-fullSimulation suites live under simulations/, and generated telemetry is written to artifacts/telemetry/.
For bridge operations, contract browsing, and ad hoc operator calls, start the local browser console:
make contract-consoleBy default it serves http://127.0.0.1:4173, reads the live deployments/<env>/*.deploy.json records, refresh-compatible deployments/<env>/contracts.latest.json metadata, plus the adjacent *.manifest.json files, and exposes a local proxy for:
POST /v1/contracts/viewPOST /v1/contracts/callGET /v1/sccp/capabilitiesGET /v1/sccp/manifestsGET /v1/sccp/messages/recentGET /v1/sccp/proofs/message/<message_id>GET /v1/sccp/artifacts/message/<message_id>GET /v1/sccp/jobs/message/<message_id>POST /v1/bridge/proofs/submitPOST /v1/bridge/messagesGET /v1/pipeline/transactions/status
The backend resolves Torii targets from the checked-in deployment record for the selected environment. Signer configs can contribute authority and signing material, but they do not override the deployment Torii URL. The catalog response now also surfaces signer source metadata and any mismatch warnings that were detected during signer discovery.
Mutation policy is environment-aware:
localpermits signed mutations by default.testnetpublic environments, including Taira, permit signed mutations only when the console was started withSORASWAP_ALLOW_TESTNET_MUTATIONS=1.- bridge-message submission for proof-managed bridge entrypoints rejects caller-supplied
settlement.payload; the release path must stay proof-driven.
It now also auto-discovers the standard signer configs when they exist and are not placeholder templates:
tmp/iroha-localnet/client.tomlforlocal(or$SORASWAP_LOCALNET_DIR/client.tomlwhen that env var is set)config/testnet/taira.client.tomlfortestnet
The browser UI is deployment-driven: it shows the canonical contract address, dataspace, deploy metadata, and manifest entrypoints already recorded in this repo. No frontend build step is required.
The console now also includes a bridge workspace for the deployed bridge.sccp_bridge contract. It can:
- aggregate the common bridge
viewcalls (listing_config,mirror_asset,asset_vault_account,route_config,route_provenance,mirror_outbound,inbound_consumed) into one local snapshot request - jump directly to the deployed bridge contract in the generic invocation form
- prefill the common bridge mutation payloads (
register_asset,bind_asset_vault,activate_route,activate_route_governed,pause_route,resume_route,lock_to_remote,finalize_inbound) - validate bridge action fields before loading them into the generic invocation panel
- validate
lock_to_remoterecipients against the live SCCP codec metadata for the selected counterparty lane - store browser-local bridge bookmarks for asset keys, routes, transfer ids, and inbound message ids
The operator console now also adds:
- a transaction tracker that stores recent signed actions in browser
localStorage, trackstx_hash_hex, and polls/v1/pipeline/transactions/statusuntil terminal status - best-effort remote transaction history rendering through
/v1/transactions/history; public Taira may report this as unavailable, and the UI degrades to a warning state instead of failing - an SCCP proof/status workspace that renders live capabilities, manifests, newest-first recent messages, counterparties, verifier targets, finality models, raw bundles, typed artifacts, normalized jobs, and submission-package metadata
- guided proof and bridge-message submission builders that keep the final payload as editable JSON while prebuilding common
message_bundle,finalize_inbound, andactivate_route_governedsettlement shapes
View-only sessions can be started with a default authority override:
make contract-console \
CONTRACT_CONSOLE_ARGS="--authority testnet=i105..."Local signed entrypoints stay server-side. Bind an untracked client config to an environment when you want the UI to enable call requests:
make contract-console \
CONTRACT_CONSOLE_ARGS="--signer local=$SORASWAP_LOCALNET_DIR/client.toml"For a mutation-enabled Taira session, bind the signer explicitly and enable the mutate gate before starting the console:
export SORASWAP_CLIENT_CONFIG=/absolute/path/to/taira.client.toml
export SORASWAP_ALLOW_TESTNET_MUTATIONS=1
make contract-console \
CONTRACT_CONSOLE_ARGS="--signer testnet=$SORASWAP_CLIENT_CONFIG --authority testnet=$SORASWAP_AUTHORITY"If the console port is already occupied, override it with:
make contract-console CONTRACT_CONSOLE_ARGS="--port 4273"When a signer config includes a public key and the sibling ../iroha/target/debug/iroha binary is present, the console will attempt to derive the canonical I105 authority automatically. Otherwise pass --authority ENV=I105... explicitly.
If you want a strictly manual session, disable default signer discovery with:
make contract-console CONTRACT_CONSOLE_ARGS="--no-auto-signers"The console backend has a small regression suite:
make test-contract-consoleThe browser smoke suite serves the static UI, mocks the local proxy surfaces, and verifies catalog load, bridge validation, SCCP discovery, proof lookup rendering, and browser-local persistence:
make test-contract-console-uiThere is also a real browser-to-backend integration smoke. It starts the actual Python console server against a local mock Torii node, then drives the UI through catalog load, bridge snapshot, contract call, SCCP lookup, and proof/message submission flows:
make test-contract-console-integrationIf Playwright browser binaries are not installed yet on your machine, run:
npx playwright install chromiumThe repo also carries an optional live non-mutating SCCP discovery smoke against the public contract-console surface. It defaults to Taira and stays opt-in so routine local runs do not depend on network reachability:
SORASWAP_RUN_CONTRACT_CONSOLE_LIVE_SMOKE=1 make test-contract-console-liveTo point the same smoke at the parallel production environment, set SORASWAP_PUBLIC_ENV=production and either provide an explicit Torii URL or a production client config:
SORASWAP_PUBLIC_ENV=production \
SORASWAP_CONTRACT_CONSOLE_LIVE_TORII_URL=https://production.example.invalid \
SORASWAP_RUN_CONTRACT_CONSOLE_LIVE_SMOKE=1 \
make test-contract-console-liveSigned Taira verification uses the same contract console:
export SORASWAP_CLIENT_CONFIG=/absolute/path/to/taira.client.toml
export SORASWAP_ALLOW_TESTNET_MUTATIONS=1
make test-contract-console-testnet
make soak-contract-consolemake test-contract-console-testnet self-grants CanRegisterTrigger to the configured signer when the permission is missing, because the bridge message settlement path uses an ephemeral by-call trigger in the submitted transaction.
make test-contract-console-testnet first auto-discovers the newest unconsumed SORA-targeted bridge transfer for the configured route. When live SCCP discovery is unavailable, the latest saved console evidence already points at a consumed bridge message, or recent live inventory only exposes consumed SORA-targeted transfers, it reuses the newest matching saved console report from deployments/testnet/ or deployments/testnet/archive/ and verifies the duplicate/replay rejection path instead of silently skipping the bridge gate. SORASWAP_TESTNET_BRIDGE_MESSAGE_ID remains available as an explicit debug override when you need to force a specific message id.
SORASWAP_IROHA_ROOT- defaults to../irohaSORASWAP_CLIENT_CONFIG- CLI config path; defaults per scriptSORASWAP_AUTHORITY- optional canonical I105 override; otherwise derived from the client config public keySORASWAP_BASE_ASSET_ALIAS- defaults toxor#universalSORASWAP_XOR_ASSET_DEFINITION_ID- defaults to the repo-localxorasset definition id used forxor#universalSORASWAP_USDT_ASSET_DEFINITION_ID,SORASWAP_USDC_ASSET_DEFINITION_ID,SORASWAP_KUSD_ASSET_DEFINITION_ID,SORASWAP_N3X_ASSET_DEFINITION_ID- optional public helper-asset definition overrides used bybootstrap_assets.sh; set these beforemake deploy-productionwhen the parallel public chain uses different helper asset ids than TairaSORASWAP_SMOKE_GAS_LIMIT- defaults to100000SORASWAP_SKIP_IROHA_CLI_BUILD- set to1to reuse an existing../iroha/target/debug/irohabinary even when the sibling tree is newer than the binarySORASWAP_SKIP_KOTO_TOOL_BUILD- set to1to reuse existing../iroha/target/debug/{koto_compile,koto_lint}binaries instead of rebuilding themSORASWAP_SKIP_LOCALNET_TOOL_BUILD- set to1to reuse existing../iroha/target/debug/{iroha,irohad,kagami}binaries instead of rebuilding themSORASWAP_TORII_URL- optional explicit Torii URL overrideSORASWAP_TESTNET_CHAIN_ID- defaults to809574f5-fee7-5e69-bfcf-52451e42d50f; used to override malformed borrowed public Taira client configs and to keep testnet evidence tied to the live chain idSORASWAP_TESTNET_CHAIN_DISCRIMINANT- defaults to369; used when deriving canonical public contract addresses locally for testnet deploy recoverySORASWAP_ALLOW_TESTNET_MUTATIONS- required for any signed Taira console or Taira smoke pathSORASWAP_SKIP_PUBLIC_SIGNER_READY_CHECK- optional debug bypass for public deploy/smoke signer balance checks; use only when the configured chain cannot expose the fee asset or faucet state yet and you explicitly want to skip readiness validationSORASWAP_PUBLIC_BOOTSTRAP- optional shared bootstrap toggle formake deploy-testnetandmake deploy-production; set to1to run the one-time public domain and helper-asset bootstrap before contract deploySORASWAP_PRODUCTION_BOOTSTRAP- optional production-specific bootstrap toggle that overridesSORASWAP_PUBLIC_BOOTSTRAPformake deploy-productionSORASWAP_PRODUCTION_CLIENT_CONFIG- optional default config path used bymake deploy-production,make smoke-production,make smoke-production-readonly, andmake test-contract-console-productionwhenSORASWAP_CLIENT_CONFIGis not setSORASWAP_PRODUCTION_CHAIN_ID- optional production chain-id override used when the production client config is copied from another environment or otherwise carries the wrongchainvalueSORASWAP_PRODUCTION_CHAIN_DISCRIMINANT- optional network-prefix override for the parallel production environment; falls back toSORASWAP_CHAIN_DISCRIMINANTwhen omittedSORASWAP_PRODUCTION_FEE_ASSET_DEFINITION_ID,SORASWAP_PRODUCTION_FEE_ASSET_LABEL- optional production fee-asset overrides for deploy/bootstrap/smoke preflight when the production fee asset is not query-visible throughSORASWAP_FEE_ASSET_ALIASSORASWAP_PUBLIC_RUN_SUFFIX,SORASWAP_PUBLIC_BRIDGE_ROUTE,SORASWAP_PUBLIC_BRIDGE_RECENT_LIMIT,SORASWAP_PUBLIC_BRIDGE_MESSAGE_ID- optional shared public-env overrides used by the generic public smoke and contract-console wrappers before their built-in defaultsSORASWAP_TESTNET_BRIDGE_MESSAGE_ID- optional debug override formake test-contract-console-testnetwhen you want to force a specific live SCCP message id instead of using chain-derived recent-message discoverySORASWAP_TESTNET_BRIDGE_ROUTE- optional bridge route override for testnet console smoke when the looked-up message bundle cannot derive the routeSORASWAP_TESTNET_RUN_SUFFIX- optional suffix reused by the signed Taira smoke for mutable launchpad, referral, farm, perps, options, cover, and automation identifiersSORASWAP_PRODUCTION_BRIDGE_MESSAGE_ID,SORASWAP_PRODUCTION_BRIDGE_ROUTE,SORASWAP_PRODUCTION_BRIDGE_RECENT_LIMIT,SORASWAP_PRODUCTION_RUN_SUFFIX- optional production-wrapper equivalents used by the paralleldeployments/productionevidence familySORASWAP_PUBLIC_XOR_TOPUP_MAX_ATTEMPTS,SORASWAP_PUBLIC_XOR_TOPUP_MAX_USDT_IN,SORASWAP_PUBLIC_XOR_TOPUP_BUFFER- optional shared public-env signer autofund controls used by the mutating public smoke before its built-in defaultsSORASWAP_TESTNET_XOR_TOPUP_MAX_ATTEMPTS,SORASWAP_TESTNET_XOR_TOPUP_MAX_USDT_IN,SORASWAP_TESTNET_XOR_TOPUP_BUFFER- optional testnet signer autofund controls for the mutating public smokeSORASWAP_PRODUCTION_XOR_TOPUP_MAX_ATTEMPTS,SORASWAP_PRODUCTION_XOR_TOPUP_MAX_USDT_IN,SORASWAP_PRODUCTION_XOR_TOPUP_BUFFER- optional production-wrapper equivalents used bymake smoke-productionSORASWAP_LAUNCHPAD_SALE_ASSET_ID- optional launchpad sale-asset override; local and signed Taira launchpad smoke default tousdt#soraswap.universalso the executor seeds the canonicalxor/usdtDLMM poolSORASWAP_LAUNCHPAD_POOL_QUOTE_ASSET_ID- optional launchpad executor / DLMM quote-asset override; defaults tousdt#soraswap.universalSORASWAP_RECOMMENDED_TX_GOSSIP_FRAME_CAP- defaults to1048576; deploy scripts warn when live Taira is below this frame-cap budgetSORASWAP_CONTRACT_DEPLOY_MAX_TIME_SECS- defaults to45; max request time for the public/v1/contracts/deploywrapper before deploy recovery/fallback logic takes overSORASWAP_DEPLOY_PIPELINE_WAIT_SECS,SORASWAP_DEPLOY_COMMITTED_WAIT_SECS,SORASWAP_DEPLOY_MANIFEST_WAIT_SECS- default to300,120, and180; control live deploy revalidation windows for pipeline status, committed transaction lookup, and manifest visibility during deploy recovery plus post-deploy bootstrapSORASWAP_CONTRACT_CALL_MAX_TIME_SECS- defaults to120; max request time for signed/v1/contracts/callmutations before the wrapper fails the requestSORASWAP_CONTRACT_CALL_RETRY_COUNT- defaults to1; mutating/v1/contracts/callrequests are not retried by default because a transport timeout can still submit the first transaction and make a blind retry duplicate a non-idempotent actionSORASWAP_CONTRACT_VIEW_MAX_TIME_SECS,SORASWAP_TORII_READ_MAX_TIME_SECS- optional public-node timeout controls for/v1/contracts/viewand read-only Torii queries; useful whentaira.sora.orgis intermittently resetting or stalling connectionsSORASWAP_LOCALNET_DIR- optional override for the generated localnet directorySORASWAP_LOCALNET_BASE_API_PORT- optional localnet API port root override; useful when another local Nexus already occupies8080-8082SORASWAP_LOCALNET_BASE_P2P_PORT- optional localnet P2P port root override; useful when another local Nexus already occupies1337+SORASWAP_LOCALNET_CONSENSUS_MODE- optional localnet consensus override; defaults tonposforlocal_up.shandpermissionedfortests/isolated_e2e.shSORASWAP_LOCALNET_BLOCK_TIME_MS,SORASWAP_LOCALNET_COMMIT_TIME_MS- optional Kagami timing overrides passed through bylocal_up.sh;tests/isolated_e2e.shdefaults both to5000on the isolated permissioned debug pathSORASWAP_LOCALNET_COMMIT_INFLIGHT_TIMEOUT_MS- optional override for[sumeragi.persistence].commit_inflight_timeout_msin generated local peer configs; SoraSwap defaults it to60000so cold DLMM deploy blocks do not stall behind Kagami's tighter localnet capSORASWAP_WARM_VIEW_TIMEOUT_SECS- optional per-view timeout used only by bootstrap prewarm calls; defaults to5so a cold diagnostic view cannot stall the whole isolated bootstrapSORASWAP_LOCALNET_GUEST_STACK_BYTES- optional localnet guest stack override; defaults to8388608so DLMM swap smoke has an8 MiBguest stack budgetSORASWAP_LOCALNET_GAS_TO_STACK_MULTIPLIER- optional localnet gas-to-stack multiplier override; defaults to8so the DLMM pool can use the raised guest stack budget at its currentmax_cyclesSORASWAP_LOCALNET_MEMORY_BUDGET_PROFILE- optional localnet IVM memory-budget profile name; defaults tosoraswap-dlmmSORASWAP_LOCALNET_MAX_STACK_BYTES- optional localnet compute-profile stack cap override; defaults to the same value asSORASWAP_LOCALNET_GUEST_STACK_BYTESSORASWAP_INIT_CONTRACT_STATE- defaults to1on testnet deploys; set to0only for an explicit debug bypass of post-deploy initSORASWAP_BOOTSTRAP_SCOPE- defaults tofull; set tofoundationto stop post-deploy initialization aftern3xplus DLMM setupSORASWAP_SMOKE_SCOPE- defaults tofull; set tofoundationto skip launchpad, referral, farms, perps, options, cover, and automation smoke mutationsSORASWAP_TREASURY_ACCOUNT- optional override for the treasury/vault account used during post-deploy initSORASWAP_POOL_SEED_NEXT_BASE,SORASWAP_POOL_SEED_NEXT_QUOTE,SORASWAP_POOL_SEED_FAR_BASE,SORASWAP_POOL_SEED_FAR_QUOTE- optional adjacent-bin bootstrap liquidity overridesSORASWAP_POOL_POSITION_ID,SORASWAP_POOL_POSITION_BASE,SORASWAP_POOL_POSITION_QUOTE,SORASWAP_POOL_POSITION_REMOVE_SHARES- optional local DLMM smoke position controlsSORASWAP_POOL_IMPACT_CAP_BPS,SORASWAP_POOL_MIN_RESERVE_BASE,SORASWAP_POOL_MIN_RESERVE_QUOTE,SORASWAP_POOL_MAX_BINS_PER_SWAP,SORASWAP_POOL_BIN_LIQUIDITY_CAP- optional DLMM risk guard overridesSORASWAP_POOL_SMOKE_SWAP_IN- local DLMM swap input used by smoke flowsSORASWAP_ROUTER_BIN_QUOTE_IN- routerquote_binsample amount used by smoke flowsSORASWAP_N3X_VAULT_ACCOUNT,SORASWAP_DLMM_POOL_VAULT_ACCOUNT- optional custody-account overrides for bootstrap repair and custom environments; bootstrap now targets the current deployed contract subjects by default and, on publictestnet|production, migrates seeded balances forward from previous contract-subject custody when contracts are upgradedSORASWAP_N3X_SMOKE_USDT_IN,SORASWAP_N3X_SMOKE_USDC_IN,SORASWAP_N3X_SMOKE_KUSD_IN,SORASWAP_N3X_TARGET_USDT_BPS,SORASWAP_N3X_TARGET_USDC_BPS,SORASWAP_N3X_TARGET_KUSD_BPS,SORASWAP_N3X_MINT_FEE_BPS,SORASWAP_N3X_REDEEM_FEE_BPS- optionaln3xsmoke controls for basket inputs, target weights, and fee configurationSORASWAP_SALE_NAME,SORASWAP_LAUNCHPAD_SMOKE_PAYMENT_AMOUNT,SORASWAP_LAUNCHPAD_SMOKE_ALLOCATION_ID,SORASWAP_LAUNCHPAD_CLAIM_INVENTORY_AMOUNT,SORASWAP_LAUNCHPAD_CLAIM_SLOT,SORASWAP_LAUNCHPAD_SEED_PAYMENT_AMOUNT,SORASWAP_LAUNCHPAD_SEED_SALE_AMOUNT,SORASWAP_LAUNCHPAD_SEED_BIN_ID,SORASWAP_LAUNCHPAD_SEED_POSITION_ID,SORASWAP_REFUND_SALE_NAME,SORASWAP_REFUND_ALLOCATION_ID,SORASWAP_REFUND_PAYMENT_AMOUNT,SORASWAP_REFUND_SOFT_CAP- optional launchpad smoke controls for recorded allocations, claim inventory, refunds, and the explicit DLMM seed planSORASWAP_REFERRAL_SMOKE_MEMBER,SORASWAP_REFERRAL_SMOKE_PARENT_MEMBER,SORASWAP_REFERRAL_SMOKE_CLAIM_THRESHOLD,SORASWAP_REFERRAL_SMOKE_ACCRUAL,SORASWAP_REFERRAL_SMOKE_DIRECT_SHARE_BPS,SORASWAP_REFERRAL_SMOKE_PARENT_SHARE_BPS- optional referral smoke controls for the routed child and parent member settlement pathSORASWAP_FARM_SMOKE_REWARD_FUND,SORASWAP_FARM_SMOKE_STAKE_AMOUNT,SORASWAP_FARM_SMOKE_UNSTAKE_AMOUNT,SORASWAP_FARM_SMOKE_CLAIM_SLOT,SORASWAP_FARM_SMOKE_UNSTAKE_SLOT- optional farms smoke controls for the slot-synced accrual pathSORASWAP_PERPS_SMOKE_FUNDING_BPS,SORASWAP_PERPS_SMOKE_MAX_LEVERAGE_BPS,SORASWAP_PERPS_SMOKE_MAINTENANCE_MARGIN_BPS,SORASWAP_PERPS_SMOKE_LIQUIDATION_FEE_BPS- optional perps bootstrap defaults for market funding and guard configurationSORASWAP_PERPS_MARKET_OPEN_INTEREST_CAP,SORASWAP_PERPS_MARKET_FUNDING_INTERVAL_SLOTS,SORASWAP_PERPS_MARKET_ORACLE_STALE_SLOTS,SORASWAP_PERPS_MARKET_BACKLOG_LIMIT,SORASWAP_PERPS_MARKET_UTILISATION_CLAMP_BPS,SORASWAP_PERPS_MARKET_LIQUIDATION_STRESS_LIMIT- optional perps market registration overrides for the shared derivatives stackSORASWAP_PERPS_SMOKE_POSITION,SORASWAP_PERPS_SMOKE_SIZE,SORASWAP_PERPS_SMOKE_COLLATERAL,SORASWAP_PERPS_SMOKE_ADD_COLLATERAL,SORASWAP_PERPS_SMOKE_REMOVE_COLLATERAL,SORASWAP_PERPS_SMOKE_REQUESTED_LEVERAGE_BPS,SORASWAP_PERPS_SMOKE_LIQUIDATION_REQUESTED_LEVERAGE_BPS,SORASWAP_PERPS_SMOKE_ENTRY_PRICE_BPS,SORASWAP_PERPS_SMOKE_FUNDING_MARK_PRICE_BPS,SORASWAP_PERPS_SMOKE_FUNDING_INDEX_PRICE_BPS,SORASWAP_PERPS_SMOKE_EXIT_MARK_PRICE_BPS,SORASWAP_PERPS_SMOKE_LIQUIDATION_COLLATERAL,SORASWAP_PERPS_SMOKE_LIQUIDATION_STRESS_MARK_PRICE_BPS,SORASWAP_PERPS_SMOKE_LIQUIDATION_HEALTHY_MARK_PRICE_BPS,SORASWAP_PERPS_SMOKE_LIQUIDATION_SCAN_LIMIT- optional perps smoke controls for the normal open/funding/margin/close path plus the automatic queue/recover/liquidate rehearsal; the liquidation path uses its own requested leverage so lower-margin liquidation fixtures can stay valid against the market max leverage checkSORASWAP_OPTIONS_SHOUT_TENOR_SLOTS,SORASWAP_OPTIONS_OUTPERFORMANCE_TENOR_SLOTS,SORASWAP_OPTIONS_SHOUT_STRIKE_BPS,SORASWAP_OPTIONS_OUTPERFORMANCE_STRIKE_BPS,SORASWAP_OPTIONS_COLLATERAL_MULTIPLIER_BPS,SORASWAP_OPTIONS_SHOUT_BASE_PREMIUM_BPS,SORASWAP_OPTIONS_OUTPERFORMANCE_BASE_PREMIUM_BPS,SORASWAP_OPTIONS_SHOUT_EXPIRY_SLOT,SORASWAP_OPTIONS_OUTPERFORMANCE_EXPIRY_SLOT,SORASWAP_OPTIONS_SHOUT_MAX_NOTIONAL,SORASWAP_OPTIONS_OUTPERFORMANCE_MAX_NOTIONAL- optional options template and series bootstrap overridesSORASWAP_OPTIONS_GUARD_BUMP_ACTIVATE_BPS,SORASWAP_OPTIONS_GUARD_BUMP_DEACTIVATE_BPS,SORASWAP_OPTIONS_GUARD_PAUSE_THRESHOLD_BPS,SORASWAP_OPTIONS_GUARD_BUMP_PERCENT_BPS- optional options factory utilisation-guard overridesSORASWAP_OPTIONS_SHOUT_SMOKE_NOTIONAL,SORASWAP_OPTIONS_SHOUT_SMOKE_PREMIUM_PAID,SORASWAP_OPTIONS_SHOUT_SMOKE_COLLATERAL_LOCKED,SORASWAP_OPTIONS_SHOUT_SMOKE_RECORD_MARK_BPS,SORASWAP_OPTIONS_SHOUT_SMOKE_EXERCISE_MARK_BPS,SORASWAP_OPTIONS_OUTPERFORMANCE_SMOKE_NOTIONAL,SORASWAP_OPTIONS_OUTPERFORMANCE_SMOKE_PREMIUM_PAID,SORASWAP_OPTIONS_OUTPERFORMANCE_SMOKE_COLLATERAL_LOCKED,SORASWAP_OPTIONS_OUTPERFORMANCE_FINAL_MARK_BPS,SORASWAP_OPTIONS_OUTPERFORMANCE_FINAL_QUOTE_MARK_BPS- optional local active options smoke controls for shout and outperformance buy/settle/exercise flowsSORASWAP_COVER_REQUIRED_OBSERVATIONS,SORASWAP_COVER_ORACLE_STALE_SLOTS,SORASWAP_COVER_SMOKE_NOTIONAL,SORASWAP_COVER_SMOKE_PAYOUT_AMOUNT,SORASWAP_COVER_SMOKE_PREMIUM_PAID,SORASWAP_COVER_SMOKE_LOWER_BOUND,SORASWAP_COVER_SMOKE_UPPER_BOUND,SORASWAP_COVER_SMOKE_TRIGGER_PRICE,SORASWAP_COVER_SMOKE_WINDOW_SLOTS,SORASWAP_COVER_SMOKE_POLICY_REQUIRED_OBSERVATIONS,SORASWAP_COVER_SMOKE_REGISTRATION_SLOT- optional cover bootstrap and active local smoke controls, including the stale-oracle reset drillSORASWAP_RISK_BUCKET_1_BOOTSTRAP_DEPOSIT,SORASWAP_RISK_BUCKET_2_BOOTSTRAP_DEPOSIT,SORASWAP_RISK_BUCKET_3_BOOTSTRAP_DEPOSIT- optional shared risk-vault bootstrap funding overrides for buckets1=perps,2=options,3=cover; the signed Taira flow now seeds bucket1with200by default so the live perps smoke uses the same funded baseline as the local rehearsalSORASWAP_AUTOMATION_SMOKE_JOB,SORASWAP_AUTOMATION_SMOKE_EXECUTOR,SORASWAP_AUTOMATION_SMOKE_NEXT_SLOT,SORASWAP_AUTOMATION_SMOKE_RESUME_SLOT,SORASWAP_AUTOMATION_SMOKE_RETRY_DELAY_SLOTS,SORASWAP_AUTOMATION_SMOKE_MAX_RETRIES,SORASWAP_AUTOMATION_SMOKE_CRON_INTERVAL_SLOTS- optional automation smoke scheduler overrides
scripts/local_up.sh generates and starts a fresh one-peer Kagami localnet in tmp/iroha-localnet using the sibling ../iroha checkout and the Nexus/NPoS profile. It now also injects a SoraSwap-specific IVM stack profile into the generated peer config so DLMM swap smoke runs with an 8 MiB guest stack budget by default, and raises the generated sumeragi.persistence.commit_inflight_timeout_ms to 60000 so cold large-contract deploy blocks do not flap at the default localnet cap. When another local Nexus is already running, set SORASWAP_LOCALNET_DIR, SORASWAP_LOCALNET_BASE_API_PORT, and SORASWAP_LOCALNET_BASE_P2P_PORT to spin up an isolated verification localnet instead of reusing the default one.
Default local client config:
tmp/iroha-localnet/client.tomlLocal bootstrap also acquires the soraswap SNS domain-name lease before registering the on-ledger soraswap domain, which is now required by current Nexus core. It then binds and tops up xor#universal as the base asset alongside the repo helper assets.
iroha.app.toml is the repo's canonical SoraSwap bundle manifest. make deploy-local compiles the listed contracts, then hands the full bundle to ../iroha via iroha contract app deploy --manifest iroha.app.toml so address planning, alias binding, deploy receipts, and recovery semantics live in the platform instead of repo shell logic. The wrapper still runs scripts/bootstrap_contract_state.sh after activation so the foundational contracts have usable local state before smoke calls. The bootstrap is skip-and-verify: singleton init/config writes are skipped when their typed config views already match, and the DLMM seed block is only replayed when the current bin and position snapshots are still pristine. Each deploy now writes both the platform bundle receipt to deployments/local/soraswap.bundle.deploy.json and the materialized per-contract deployments/local/<contract>.deploy.json evidence used by the smoke/bootstrap flows, plus a timestamped deployments/local/contracts.<utc>.json snapshot of the whole local deployment set.
make smoke-local now writes a machine-readable report to deployments/local/smoke.latest.json and a timestamped copy. That report separates committed mutation transaction hashes from typed /v1/contracts/view results and records decoded integer snapshots for the n3x, deployable DLMM, launchpad, referral, farms, risk vault, perps, options, cover, and automation surfaces. The n3x section includes init-time fee and target state, the launchpad section includes both sale-level claim/seed aggregates plus allocation refund state, and the referral section includes routed child-plus-parent settlement state. The derivatives section now includes committed local write-path coverage for perps open/funding/margin/close plus queue/recover/requeue/liquidate, shout buy/record/exercise, outperformance buy/series settlement/exercise, and cover register/stale-reset/claim, all routed through risk_vault.
The public testnet template lives at:
config/testnet/taira.client.toml.exampleCopy it to an untracked .toml, set the correct credentials, then point SORASWAP_CLIENT_CONFIG at that file before running make deploy-testnet.
Use a fully qualified account domain in the copied config, for example wonderland.universal.
As observed on March 25, 2026, live taira.sora.org still uses chain id 809574f5-fee7-5e69-bfcf-52451e42d50f. If Taira is redeployed with a new chain id, either update your copied client config or set SORASWAP_TESTNET_CHAIN_ID before running any deploy or smoke flow.
make deploy-testnet now treats public deployment as a permissionless universal dataspace bundle flow. Before deploying it fingerprints the live chain using chain id + block 1 hash, writes deployments/testnet/chain.latest.json, and archives stale deployments/testnet evidence under deployments/testnet/archive/<utc>-<block1-hash>/ whenever Taira has been redeployed without changing the chain id. The observed torii_url is still recorded in that snapshot as metadata, but endpoint URL is not part of chain identity. The wrapper compiles iroha.app.toml, submits it through iroha contract app deploy, persists the first-class platform receipt to deployments/testnet/soraswap.bundle.deploy.json, then materializes the per-contract *.deploy.json records that the readonly and mutable smoke flows already consume. deployments/testnet/nested_call_probe.latest.json still records both a persisted bytes state round-trip check and the minimal no-arg live call_contract(...) probe that must pass before bootstrap proceeds.
scripts/fund_testnet_signer.sh is the operator helper for public Taira funding. make deploy-testnet will auto-claim faucet funds when the signer is missing or unfunded, solve the faucet PoW puzzle, and wait for a positive xor#universal balance before deploying. Post-deploy init now runs by default there, and SORASWAP_BOOTSTRAP_SCOPE=foundation|full still narrows the init surface when needed.
Public bootstrap now targets the current n3x_hub and DLMM pool contract subjects on testnet|production and migrates seeded balances forward from previous contract-subject custody after upgrades. local still defaults n3x custody to the n3x_hub contract subject, and SORASWAP_N3X_VAULT_ACCOUNT remains the explicit override when an operator wants to force a different custody account during repair or migration drills.
make smoke-testnet is now the canonical signed Taira rehearsal for the mutable DeFi surface. It requires SORASWAP_ALLOW_TESTNET_MUTATIONS=1, reuses the readonly compatibility lane for deployment-record and manifest revalidation, rechecks the saved nested_call_probe.latest.json evidence against the current chain, then executes the same active router, launchpad, farms, automation, and derivatives write paths that the local smoke uses, including the perps queue/recover/requeue/liquidate path, before writing deployments/testnet/smoke.latest.json.
The bridge proof lane stays in the same release gate, but it runs as its own target: make test-contract-console-testnet records deployments/testnet/contract_console_smoke.latest.json separately so the bridge message is not consumed twice by a single rehearsal. A green release gate therefore requires both the signed make smoke-testnet evidence and the signed make test-contract-console-testnet evidence.
make smoke-testnet-readonly preserves the older non-destructive compatibility lane. It revalidates each saved *.deploy.json record on the current chain, rebuilds missing records from live aliases plus local manifests when possible, compares live code manifests against any saved deployment manifests, and records typed readonly view evidence under the same deployments/testnet/ directory.
The release flow no longer depends on a separate staging environment. The repo now also carries a parallel production wrapper family:
make deploy-production
make smoke-production
make smoke-production-readonly
make production-nested-call-probe
make test-contract-console-productionThose commands write the same artifact shape under deployments/production/, reuse the same signed public-env code path as Taira, and keep the same SORASWAP_ALLOW_TESTNET_MUTATIONS=1 mutation gate for the mutable smoke and console paths. Production wrappers default SORASWAP_CLIENT_CONFIG from SORASWAP_PRODUCTION_CLIENT_CONFIG or config/production/production.client.toml when present.
When the production client config is copied from another chain or the production fee asset is not query-visible by alias, set SORASWAP_PRODUCTION_CHAIN_ID, SORASWAP_PRODUCTION_CHAIN_DISCRIMINANT, and SORASWAP_PRODUCTION_FEE_ASSET_DEFINITION_ID before running the production wrappers so contract-subject derivation and fee-balance preflight stay pinned to the real production chain.
Release guidance and operator procedures live under:
docs/release/production_readiness_checklist.mddocs/release/contract_console_security_review.mddocs/release/contract_console_runbook.md
On March 28, 2026, probing the live Taira node showed:
- chain id
809574f5-fee7-5e69-bfcf-52451e42d50f /v1/accounts/onboardresponding403withUAID onboarding disabled/v1/accounts/faucet/puzzleresponding200once faucet is enabled on the public nodestatus.tx_gossip.caps.frame_cap_bytesis expected to be at least1048576for routine SoraSwap deploys without split fallback- public contract lifecycle writes were being rejected when Taira omitted an explicit
[nexus.fees]block and fell back to the canonical default fee selector instead ofxor#universal
Public SoraSwap docs and scripts now target canonical contract addresses in the universal dataspace. A Taira rollout must therefore include both the explicit nexus.fees.fee_asset_id = "xor#universal" override and the raised network.max_frame_bytes_tx_gossip = 1048576 setting from ../iroha/configs/soranexus/taira/config.toml, then a fresh make deploy-testnet run after the node comes back.
When deployments/testnet/nested_call_probe.latest.json reports state_bytes_roundtrip_supported = true but nested_call_supported = false, stop blaming SoraSwap bootstrap. That is the public Taira runtime rejecting minimal nested call_contract(...). The fix path is to roll public Taira forward from ../iroha, not to add a non-nested fallback here:
- build and stage an exact runtime bundle with
bash ../iroha/configs/soranexus/taira/build_taira_rollout_bundle.sh - install/restart the public validator(s) from that bundle
- rerun the public canary plus the SoraSwap gate with
bash ../iroha/configs/soranexus/taira/verify_soraswap_rollout.sh --public-root "<direct-public-node>" --write-config /run/secrets/taira-canary-client.toml --soraswap-client-config /absolute/path/to/taira.client.toml --run-release-checklist --allow-testnet-mutations
For a collision-free local full-stack check, use make test-local-isolated. It starts a dedicated localnet under tmp/iroha-localnet-verify, defaults to 18080 / 11337 instead of the main local ports, deploys the full contract set, runs the full smoke_local.sh mutation flow against the generated client config, asserts the exact post-smoke n3x and DLMM view snapshots, and drives the shared derivatives write path through risk_vault before tearing the node back down. The same DLMM-oriented stack overrides are applied there by default, and the isolated permissioned wrapper now raises both Kagami timing knobs to 5000 ms by default so the cold first-write dlmm_pool path stays clear of the 6 s quorum-timeout band seen on the debug localnet profile.
For a foundation-only deployability check, use make test-local-foundation-isolated. It exports both scope variables as foundation, proves the n3x plus DLMM bootstrap and smoke path on a dedicated permissioned localnet, and skips later-module initialization so unrelated launchpad/farms/perps/options scaffolds do not block DLMM verification.
- The scripts are idempotent where practical and explicitly verify alias bindings before skipping asset registration.
- Bootstrap now applies the init-only
n3x, DLMM, launchpad, referral, farms, risk-vault, perps, options, and cover config surfaces before smoke begins. The derivatives bootstrap also binds the product contracts into the sharedrisk_vaultcontroller map so all later perps/options/cover write paths route through bucket accounting instead of raw product custody transfers. - The local smoke also queries
n3xand DLMM state throughview fnsnapshots after the mutation flow and asserts the expected post-smoke multi-bin DLMM reserves, share supply, and guard config after a position add, fee collect, and partial LP withdrawal before writingdeployments/local/smoke.latest.json. - In full scope, the local smoke also drives launchpad, referral, farms, automation, perps, options, and cover through their current lifecycle surfaces. Derivatives are no longer shell-view-only: perps covers open/funding/add-remove margin/close plus automatic queue/recover/requeue/liquidate, options covers shout buy-record-exercise plus outperformance buy-series settlement-exercise, and cover covers register-policy, stale/degraded reset handling, and claim routing, with typed
view fnsnapshots still recorded after the mutations. make test-local-isolatedis the safest end-to-end verifier when another local Nexus is already running, because it avoids the defaulttmp/iroha-localnetpath and the default local ports while still proving the post-swap local contract state.make test-local-foundation-isolatedis the fastest isolated verifier for the current production target because it narrows the run ton3xplus DLMM and avoids unrelated downstream module bootstrap failures.- The canonical testnet smoke is signed and mutation-gated behind
SORASWAP_ALLOW_TESTNET_MUTATIONS=1, whilemake smoke-testnet-readonlypreserves the older readonly compatibility lane. - Mutating smoke steps require both a successful Torii submission and a committed transaction hash; read-only steps execute through
/v1/contracts/view. - The current contract set is a real Kotodama foundation, not full product parity. Use the parity register before treating a module as production-complete.