Background
reputation.rs::update_participation adds points to UserReputation.participation_score with plain += on an unbounded u32:
pub fn update_participation(env: &Env, user: Address, points: u32) {
user.require_auth();
let mut reputation = get_reputation(env, &user);
reputation.participation_score += points;
...
}
The module's own doc comment flags this directly:
//! # TODO
//! - Add a `credit_score` field derived from all three components with
//! configurable weights (see `score.rs`).
//! - Consider capping `participation_score` to prevent overflow on very
//! active users (currently unbounded `u32`).
A very active/long-lived user (or repeated calls from a compromised caller with require_auth satisfied) can overflow participation_score, which in Rust release/wasm builds wraps rather than panicking — silently corrupting reputation data. Separately, score.rs exists as a scoring component but reputation has no single derived credit_score combining participation_score, completion_rate, and contribution_quality, even though downstream consumers (e.g. insurance, governance) would want one normalized figure.
Implementation Plan
- Change
participation_score accumulation to checked_add/saturating_add with an explicit cap, returning an error (or saturating) instead of silently wrapping.
- Add a
credit_score field to UserReputation (or a computed accessor) derived from participation_score, completion_rate, and contribution_quality using configurable weights, integrating with score.rs.
- Add tests: overflow attempt on
participation_score is handled gracefully, and credit_score reflects expected values across representative inputs.
Acceptance Criteria
participation_score cannot silently wrap/overflow
- A derived
credit_score is available and documented with its weighting formula
- Tests cover both the overflow guard and the credit score calculation
Background
reputation.rs::update_participationadds points toUserReputation.participation_scorewith plain+=on an unboundedu32:The module's own doc comment flags this directly:
A very active/long-lived user (or repeated calls from a compromised caller with
require_authsatisfied) can overflowparticipation_score, which in Rust release/wasm builds wraps rather than panicking — silently corrupting reputation data. Separately,score.rsexists as a scoring component but reputation has no single derivedcredit_scorecombiningparticipation_score,completion_rate, andcontribution_quality, even though downstream consumers (e.g. insurance, governance) would want one normalized figure.Implementation Plan
participation_scoreaccumulation tochecked_add/saturating_addwith an explicit cap, returning an error (or saturating) instead of silently wrapping.credit_scorefield toUserReputation(or a computed accessor) derived fromparticipation_score,completion_rate, andcontribution_qualityusing configurable weights, integrating withscore.rs.participation_scoreis handled gracefully, andcredit_scorereflects expected values across representative inputs.Acceptance Criteria
participation_scorecannot silently wrap/overflowcredit_scoreis available and documented with its weighting formula