Severity: High
The contract casts between integer types (e.g. u64 as i64 or i128 as u64) without range validation. A value that is valid in the source type may be negative or truncated in the target type, silently corrupting balances or reward calculations.
- A balance of
u64::MAXis cast toi64, producing-1. - Subsequent arithmetic treats the balance as negative.
- Attacker exploits the corrupted value to withdraw more than they deposited.
let signed_amount = raw_amount as i64; // ❌ wraps if raw_amount > i64::MAXlet signed_amount = i64::try_from(raw_amount)
.expect("amount exceeds i64::MAX"); // ✅No separate secure crate — the fix is using try_from / try_into with explicit error handling.