Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

The mul operation of Perbill doesn't work properly #2441

@shaunxw

Description

@shaunxw

I was trying to calculate multiplying a balance value by a ratio via Perbill, like Perbill::from_percent(90) * my_balance. But the mul operation of Perbill won't work for large values like when balance is u128 and 1 coin is 10^18.

As in the Mul impl of Perbill, rhs is converted to u64, and the output would be saturated to u64::MAX/1_000_000_000, which around 1.84 * 10^10. This make it impossible to multiply by a typical balance value.

fn mul(self, b: N) -> Self::Output {
<N as traits::As<u64>>::sa(b.as_().saturating_mul(self.0 as u64) / 1_000_000_000)
}
}

Due to Currency::Balance :As<u64>, this implicit saturating is error prune for balances calculation, such as offline slash calculation in staking module if I don't misunderstand:

let slash_exposure = Self::stakers(&stash).total;
let offline_slash_base = Self::offline_slash() * slash_exposure;

Expected behavior: Perbill should be capable of u64 and u128 multiplying, and saturate the output to be Output::max_value().

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions