How to Test
The repository includes a comprehensive Rust test suite. From the root of the contracts workspace:46 unit tests passing plus doctests. A full workspace run may require Windows Application Control to allow generated Rust test binaries on some machines.
Current Testnet Deployment
The current XLM-only Testnet IDs are published in/contracts.json and the associated deployment report. Mainnet is not deployed.
The current workspace contains these contracts:
protection_enginereserve_vaultprotected_balance_vaultoracle_adapterquorum_oracle_sourceusername_registryreceipt_registryzk_verifierpayment_lock_enginefloor_shield_engine
Historical instructions later in this document reference the former CFTUSD, six-contract Testnet deployment. Do not use those values or commands for the current XLM deployment or Mainnet. UseIf the app shows Protect as unavailable on Testnet, verify the configured IDs before changing frontend quote logic or position amounts:/contracts.json, this page, and any current deployment runbook incoverfi-contracts.
engine.quote_positionfails withMissingValue, meaning the deployed engine does not expose the V2 quote ABI.reserve.get_pool,reserve.get_projected_utilization_bps, andreserve.get_projected_concentration_bpsfail withMissingValue, meaning the deployed reserve does not expose the V2 reserve ABI.engine.create_positionfails before wallet signing, so this is not a user wallet, amount, Freighter, or frontend bug.
/api/status/reserve should return ok: false with status: "legacy_mismatch" instead of HTTP 502. The only protocol fix is a fresh V2 deploy, initialization, reserve funding, and smoke test.
Do not promote a contract ID from a legacy or experimental section into the active Testnet section until the deployment workflow has:
- built and hashed every required WASM,
- deployed and initialized the contracts,
- configured engine, vault, oracle, asset, partner, proof-status, and keeper references where relevant,
- seeded the selected Testnet reserve and automation balances,
- executed smoke lifecycles for username payment, receipt anchoring, quote, protection creation, settlement, payout claim, and withdrawal,
- written a deployment report with transaction IDs and WASM hashes.
- XLM reserve seed: re-check live state after each redeploy before publishing a demo script.
- Oracle price:
100000000. - Source protection engine fee logic: duration-based schedule (
30,100,150,250bps for 1, 7, 14, and 30 day terms). Verify or redeploy the listed contract IDs before treating a deployment as enforcing the latest source. - Max payout:
1000bps. - Max oracle age:
3600seconds. - Reserve accounting: position-specific maximum payout locks, reserved claims, matured underwriting premium, safety balance, automation balance, provider shares, and withdrawal requests.
How to Deploy
Repairing the Current Testnet Protect Flow
The current legacy Testnet IDs cannot be made V2-compatible by changing.env labels or lowering the protected amount. The engine and reserve must be redeployed together because they store each other’s contract IDs and the current public reserve does not expose the methods used by the V2 UI.
Required local inputs:
Build from a trusted/developer path or CI runner:
os error 4551. That is a host policy block. Move the repo to a developer-trusted path, allow generated build artifacts, or build in CI/WSL.
Deploy the launch-critical WASMs with Stellar CLI. Add optional product contracts only when they are in scope for the deployment:
reserve_vault.initialize(admin, treasury).oracle_adapter.initialize(admin, source, source_asset, source_decimals, max_age_seconds, max_deviation_bps).oracle_adapter.configure_publishers(admin, publisher1, publisher2, publisher3, true)if using fallback publisher quorum.protected_balance_vault.initialize(admin, protection_engine).protection_engine.initialize(admin, protected_balance_vault, reserve_vault, oracle_adapter, protected_asset, payout_asset, 1000, 3600).reserve_vault.configure_protocol(admin, protection_engine, oracle_adapter).- Initialize
username_registry,receipt_registry, andzk_verifierwith their current source-defined arguments. - Initialize and configure
quorum_oracle_sourceif it is part of the deployment. - Fund the payout reserve with
reserve_vault.deposit_reserve(provider, payout_asset, amount, min_shares). - Fund automation with
reserve_vault.fund_automation(provider, payout_asset, amount). - Publish a fresh oracle observation for the protected XLM asset.
contracts.json, run node scripts/sync-contract-registry.js --write, copy the new active IDs into the frontend/backend env, restart both apps, and run:
Production admin account policy
Do not use a personal Freighter wallet, demo wallet, backend hot wallet, or reserve funder wallet as the production admin. Recommended account split:
For testnet, a single dedicated testnet admin is acceptable for speed. For mainnet, set the admin public key only after the team has chosen the multisig/admin-controller policy and documented signer custody. Publish the admin public key, deployment source, and contract IDs in the deployment record after verification.
To deploy the contracts to the Stellar network, clone the coverfi-contracts repository and use the Stellar CLI.
- Build the WASM contracts:
- Deploy to Testnet:
Security Notes
[!WARNING]
Audit Status: These contracts are currently in beta and have not undergone a formal security audit. Use at your own risk.
- Oracle Dependency: The engine rejects stale oracle data, but the system still relies on updater quality and monitoring.
- Reserve Payouts: Claims use position-specific reserved payout accounting. The owner can claim the settled amount once, and withdrawals cannot consume active collateral or restricted balances.
- Deployment Drift: Source changes do not affect existing contract IDs until rebuilt, redeployed, initialized, and verified.
- Reentrancy: State changes occur before external cross-contract token transfers to prevent reentrancy attacks.
- Access Control: Critical functions like price updates and contract upgrades must be protected by admin authentication, preferably multisig in production.