Skip to content

fix: pool interest cast from i128 to u128 without negative value check #372

@thewealthyplace

Description

@thewealthyplace

Bug

contracts/pool/src/lib.rs — in the interest calculation path:

let interest = calculate_interest(...) as u128;

calculate_interest() returns i128. If it somehow returns a negative value (due to a bug in the calculation or storage corruption where yield_bps reads as very large), casting i128 to u128 produces an astronomically large positive number due to Rust's wrapping cast behaviour.

A negative interest value cast to u128 = 2^128 + negative_value, which would then cause either an overflow or an extraordinarily large repayment demand from the SME.

Fix

Use a checked cast:

let interest = calculate_interest(...);
if interest < 0 {
    return Err(PoolError::NegativeInterest);
}
let interest_u128 = interest as u128;

Or use u128::try_from(interest).map_err(|_| PoolError::NegativeInterest)?.

Also add a debug_assert!(result >= 0) inside calculate_interest() to catch this in test builds.

Acceptance Criteria

  • Negative interest caught before u128 cast
  • NegativeInterest error variant added to PoolError
  • Unit test: artificially trigger negative interest → error returned, no wrapping
  • calculate_interest() has debug assertion that result >= 0

References

  • contracts/pool/src/lib.rs — interest cast, ~line 856

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions