Skip to content

fix(edge-cases): fail closed instead of returning Ok from placeholders - #1469

Merged
greatest0fallt1me merged 1 commit into
Predictify-org:masterfrom
baling-1:fix/edge-case-placeholders
Oct 19, 2026
Merged

greatest0fallt1me merged 1 commit into
Predictify-org:masterfrom
baling-1:fix/edge-case-placeholders

Conversation

@baling-1

Copy link
Copy Markdown
Contributor

Summary

Closes #1461.

The full build exported several "edge case" entry points whose internals were
placeholders returning Ok(()) without acting, and one (handle_zero_stake_scenario)
that trapped on unchecked timestamp arithmetic once a market's end_time was in the
past. Callers (operators, scripts, dashboards) were told a market was resolved,
cancelled or extended when nothing happened.

This PR stops exporting those placeholders, makes the remaining helpers fail closed
with typed errors, and removes the dead surface that would otherwise be carried into
the split-out contracts.

Entry point disposition

Entry point Action Why
handle_zero_stake_scenario Removed (option b) Duplicated cancel_event / extend_market; computed market_age with unchecked arithmetic that traps when end_time < now; its extend_for_participation / cancel_zero_stake_market / emergency_extension_for_stakes helpers were empty Ok(()) placeholders.
handle_partial_resolution Removed Duplicated the real resolution path; resolve_with_partial_data / attempt_alternative_resolution were empty Ok(()) placeholders. No admin auth, no state change.
test_edge_case_scenarios Removed from #[contractimpl] A test helper that was exported by mistake; its helpers were empty. Real coverage lives under #[cfg(test)].
implement_tie_breaking_mechanism Implemented (reduced to one rule) Now returns Error::InvalidInput on empty input instead of panicking. One honest, documented rule: the lexicographically smallest outcome wins. The previous "strategies" all returned the first element.
detect_orphaned_markets Fail closed The contract has no global market index, so it cannot enumerate markets. Returns Error::InvalidState instead of a misleading empty list.
validate_edge_case_handling Kept Pure validation entry point.
get_edge_case_statistics Kept Read-only baseline; docs now state no aggregation is persisted yet.
PartialData + private placeholders Removed PartialData, is_market_orphaned, get_all_market_ids, and the tie_break_by_* shims were only reachable from the removed entry points.

No state-changing entry point was added; the remaining surface is read-only, so no new
auth is required.

Fail-closed / no silent success

  • No exported function returns Ok without a state change or an explicit read-only purpose.
  • grep -n 'Ok(())' contracts/predictify-hybrid/src/edge_cases.rs now only matches the two
    return sites inside validate_edge_case_handling and validate_edge_case_config. Both are
    pure validators whose documented contract is Ok(()) on valid input and Err(_) otherwise.

Acceptance criteria

  • grep -n 'Ok(())' contracts/predictify-hybrid/src/edge_cases.rs shows no placeholder bodies
    on reachable paths (remaining lines justified above).
  • Removed entry points are absent from PredictifyHybridClient (asserted by
    edge_case_surface_tests.rs through the generated ContractFunctionSet registry).
  • implement_tie_breaking_mechanism(vec![]) returns InvalidInput with no panic.
  • Zero-stake on a market with past end_time can no longer trap (entry point removed).
  • Slim build unaffected: edge_cases is full-only and this change only deletes dead
    code / entry points (-457 / +195 across edge_cases.rs, lib.rs and the new test).

Test plan

New contracts/predictify-hybrid/src/edge_case_surface_tests.rs:

# Scenario Test
1 handle_zero_stake_scenario absent from the client surface handle_zero_stake_scenario_absent_from_client_surface
2 handle_partial_resolution absent from the client surface handle_partial_resolution_absent_from_client_surface
3 test_edge_case_scenarios absent from the client surface test_edge_case_scenarios_absent_from_client_surface
4 Surface probe is meaningful (finds a still-exported entry point) surface_probe_finds_exported_entry_point
5 implement_tie_breaking_mechanism(vec![]) → InvalidInput, no panic implement_tie_breaking_mechanism_empty_returns_invalid_input
6 Tie-breaking is deterministic / documented implement_tie_breaking_mechanism_picks_lexicographically_smallest
7 Remaining helper fails closed detect_orphaned_markets_fails_closed

Verification

cargo test  -p predictify-hybrid --lib
cargo check -p predictify-hybrid --no-default-features

The full build exported several edge-case entry points whose internals were
placeholders returning Ok(()) without acting, and one that trapped on
unchecked timestamp arithmetic when a market's end_time was in the past.

- Remove handle_zero_stake_scenario, handle_partial_resolution and
  test_edge_case_scenarios from the contract surface (and their dead private
  helpers + the now-unused PartialData type). Zero-stake and partial
  resolution are already covered by cancel_event / extend_market and the
  real resolution path; test_edge_case_scenarios was a test helper exported
  by mistake.
- implement_tie_breaking_mechanism now returns Error::InvalidInput on empty
  input (never panics) and applies one honest, documented rule: the
  lexicographically smallest outcome wins. The previous "strategies" all
  returned the first element.
- detect_orphaned_markets and the remaining private placeholders fail closed
  with Error::InvalidState instead of succeeding silently.

Refs Predictify-org#1461
@baling-1
baling-1 force-pushed the fix/edge-case-placeholders branch from bf1d93d to a677a35 Compare October 19, 2026 17:06
@drips-wave

drips-wave Bot commented Oct 19, 2026

Copy link
Copy Markdown

@baling-1 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

@greatest0fallt1me
greatest0fallt1me merged commit a7e9c79 into Predictify-org:master Oct 19, 2026
1 check passed
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.

Stop exporting edge_cases placeholders that return Ok without acting (handle_partial_resolution, handle_zero_stake_scenario)

2 participants