Skip to content

feat: enforce runtime solvency invariant with locked-collateral accounting - #165

Open
Emmazlee wants to merge 5 commits into
OracleDesk:developfrom
Emmazlee:security/issue-4-enforce-the-solvency-invariant-at-runtime-with
Open

Emmazlee wants to merge 5 commits into
OracleDesk:developfrom
Emmazlee:security/issue-4-enforce-the-solvency-invariant-at-runtime-with

Conversation

@Emmazlee

Copy link
Copy Markdown

Overview

This PR hardens market-core by enforcing the solvency invariant at runtime. It adds a global TotalLocked counter and a per-market locked figure, wraps every collateral transfer in a balance-delta check, adds a global solvency guard after outflows, and exposes solvency_report / global_solvency views. Silent insolvency (fee-on-transfer, clawback, buggy collateral) now reverts loudly at the first offending transfer instead of surfacing as a failed last redeemer.

Related Issue

Changes

🔒 Runtime Solvency Accounting

  • [MODIFY] oracledesk-stellar/contracts/market-core/src/lib.rs

    • Added DataKey::TotalLocked (instance, i128, initialised to 0 in __constructor) and DataKey::Locked(u64) (persistent, i128), with a save_locked helper using the same TTL policy as Market.
    • Added transfer_in / transfer_out helpers that measure the contract's actual balance delta and revert with Error::CollateralMismatch on any mismatch; transfer_out decrements TotalLocked before running the global guard balance >= TotalLocked (reverts with Error::Insolvent).
    • Replaced all six transfer sites (create_market, buy, sell, redeem, claim_pool_remainder, sweep_fees) with the checked helpers and applied the documented accounting deltas to locked and TotalLocked.
    • Added Error::CollateralMismatch = 19 and Error::Insolvent = 20.
    • Added SolvencyReport contracttype and solvency_report(market_id) / global_solvency() views.
    • set_treasury now rejects the market-core address itself (self-transfer would be a zero-delta sweep).
    • Added #[cfg(test)] mod skim_token mock SEP-41 token that skims a fee, plus a setup_market_with_token fixture and tests covering lifecycle tracking, skim-token reverts on create_market and buy, donations, void dust, and set_treasury self-rejection.
  • [MODIFY] oracledesk-stellar/packages/bindings/market-core/src/index.ts

    • Regenerated bindings to pick up the new SolvencyReport type, solvency_report / global_solvency methods, and the CollateralMismatch / Insolvent error entries.
  • [MODIFY] oracledesk-stellar/docs/architecture.md

    • Documented the enforced invariant, the per-site accounting rules, the balance-delta checks, the global guard, the new-deployment-only migration note, and the clawback fail-safe behaviour (payouts freeze globally on detected shortfall).

Verification Results

cd oracledesk-stellar
make build
cargo test -p market-core
cargo test --workspace
make lint
make bindings && git diff --stat packages/bindings/market-core
Acceptance Criteria Status
DataKey::TotalLocked and DataKey::Locked(u64) exist and are updated at all six transfer sites ✅
Every transfer goes through transfer_in / transfer_out with balance-delta verification ✅
Error::CollateralMismatch and Error::Insolvent added, each triggered by a test ✅
Skimming mock token proves create_market and buy revert with CollateralMismatch ✅
solvency_report and global_solvency views exist and are covered by tests ✅
set_treasury rejects the market-core address itself ✅
CPU cost delta for buy and redeem documented in the PR ⏳ to be recorded from env.cost_estimate() before/after
All treasury and resolver tests pass against the refreshed vendored market_core.wasm ✅
cargo test --workspace and make lint pass, bindings regenerated ✅
docs/architecture.md describes the enforced invariant, accounting rules and clawback behaviour ✅

Closes #4

@drips-wave

drips-wave Bot commented Oct 18, 2026

Copy link
Copy Markdown

@Emmazlee Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Emmazlee

Copy link
Copy Markdown
Author

this PR is ready for another review. I resolved the merge conflicts with the develop branch (pushed 5f964e3).
Files changed: oracledesk-stellar/docs/architecture.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enforce the solvency invariant at runtime with per-market locked-collateral accounting

1 participant