Description
The fee module is disciplined about checked arithmetic, but the betting/payout math is not. In contracts/predictify-hybrid/src/bets.rs, calculate_bet_payout performs raw i128 multiplication and division when computing the distributable pool and per-winner share, and place_bet mutates market.total_staked with a raw +=. While [profile.release] sets overflow-checks = true (workspace Cargo.toml), relying on panics for fund math is fragile and yields opaque failures instead of typed errors. This issue audits and converts the hot paths to checked arithmetic with explicit errors.
Requirements and context
- Raw arithmetic to address in
bets.rs: the payout block in calculate_bet_payout (bets.rs:636), e.g. summary.total_pool * fee_percentage / 10_000, total_pool - fee, distributable_pool / num_winners, and the final / total_bets_on_outcome (the checked_mul there is followed by an unchecked divide).
place_bet (bets.rs:240) uses market.total_staked += amount; (raw); note place_bets (bets.rs:329) already uses checked_add, so align place_bet with it.
- Helper functions
calculate_implied_probability and calculate_payout_multiplier in bets.rs also use raw * 100 / ....
- Follow the established pattern in
fees.rs (checked_fee_add, checked_mul_div_floor -> Error::FeeArithmeticOverflow); reuse or mirror it and guard divide-by-zero (num_winners/total_bets_on_outcome == 0).
- Non-functional: behavior for normal values must be unchanged; only overflow/zero-divisor cases change from panic to typed
Error.
Acceptance criteria
Suggested execution
1. Fork the repo and create a branch — git checkout -b feature/checked-bet-arithmetic.
2. Implement changes — contracts/predictify-hybrid/src/bets.rs (payout/stake math); optionally factor a shared checked-math helper.
3. Write/extend tests — extend contracts/predictify-hybrid/src/property_based_tests.rs (proptest is a dev-dependency) and bet_tests.rs.
4. Test and commit
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test -p predictify-hybrid
stellar contract build --verbose
Example commit message
security: convert bet payout/stake math to checked arithmetic with typed errors
Guidelines
≥90% coverage on the arithmetic branches, including overflow/zero-divisor paths. Add doc-comments describing failure modes and update docs/contracts/FEES.md/docs/security/SECURITY_CONSIDERATIONS.md where payout math is described. Timeframe: 96 hours.
Description
The fee module is disciplined about checked arithmetic, but the betting/payout math is not. In
contracts/predictify-hybrid/src/bets.rs,calculate_bet_payoutperforms rawi128multiplication and division when computing the distributable pool and per-winner share, andplace_betmutatesmarket.total_stakedwith a raw+=. While[profile.release]setsoverflow-checks = true(workspaceCargo.toml), relying on panics for fund math is fragile and yields opaque failures instead of typed errors. This issue audits and converts the hot paths to checked arithmetic with explicit errors.Requirements and context
bets.rs: the payout block incalculate_bet_payout(bets.rs:636), e.g.summary.total_pool * fee_percentage / 10_000,total_pool - fee,distributable_pool / num_winners, and the final/ total_bets_on_outcome(thechecked_multhere is followed by an unchecked divide).place_bet(bets.rs:240) usesmarket.total_staked += amount;(raw); noteplace_bets(bets.rs:329) already useschecked_add, so alignplace_betwith it.calculate_implied_probabilityandcalculate_payout_multiplierinbets.rsalso use raw* 100 / ....fees.rs(checked_fee_add,checked_mul_div_floor->Error::FeeArithmeticOverflow); reuse or mirror it and guard divide-by-zero (num_winners/total_bets_on_outcome== 0).Error.Acceptance criteria
i128arithmetic incalculate_bet_payoutis replaced with checked operations returning a typed error.place_betuses checked addition fortotal_staked, matchingplace_bets.cargo fmt,cargo clippy, andcargo testpass.Suggested execution
1. Fork the repo and create a branch —
git checkout -b feature/checked-bet-arithmetic.2. Implement changes —
contracts/predictify-hybrid/src/bets.rs(payout/stake math); optionally factor a shared checked-math helper.3. Write/extend tests — extend
contracts/predictify-hybrid/src/property_based_tests.rs(proptest is a dev-dependency) andbet_tests.rs.4. Test and commit
cargo fmt --all -- --check cargo clippy --all-targets --all-features -- -D warnings cargo test -p predictify-hybrid stellar contract build --verboseExample commit message
Guidelines
≥90% coverage on the arithmetic branches, including overflow/zero-divisor paths. Add doc-comments describing failure modes and update
docs/contracts/FEES.md/docs/security/SECURITY_CONSIDERATIONS.mdwhere payout math is described. Timeframe: 96 hours.