@@ -4,10 +4,6 @@ use cw_utils::{Expiration, Threshold};
4
4
5
5
use crate :: { DepositInfo , Status , Vote } ;
6
6
7
- // we multiply by this when calculating needed_votes in order to round up properly
8
- // Note: `10u128.pow(9)` fails as "u128::pow` is not yet stable as a const fn"
9
- const PRECISION_FACTOR : u128 = 1_000_000_000 ;
10
-
11
7
#[ cw_serde]
12
8
pub struct Proposal {
13
9
pub title : String ,
@@ -155,12 +151,13 @@ impl Votes {
155
151
}
156
152
}
157
153
158
- // this is a helper function so Decimal works with u64 rather than Uint128
159
- // also, we must *round up* here, as we need 8, not 7 votes to reach 50% of 15 total
154
+ // This is a helper function so Decimal works with u64 rather than Uint128.
155
+ // Also, we must *round up* here, as we need 8, not 7 votes to reach 50% of 15 total.
156
+ // `percentage` must not exceed 1.0.
160
157
fn votes_needed ( weight : u64 , percentage : Decimal ) -> u64 {
161
- let applied = Uint128 :: new ( PRECISION_FACTOR * weight as u128 ) . mul_floor ( percentage ) ;
162
- // Divide by PRECISION_FACTOR, rounding up to the nearest integer
163
- ( ( applied . u128 ( ) + PRECISION_FACTOR - 1 ) / PRECISION_FACTOR ) as u64
158
+ assert ! ( percentage <= Decimal :: one ( ) ) ;
159
+ let out = Uint128 :: from ( weight ) . mul_ceil ( percentage ) ;
160
+ out . u128 ( ) as u64 // cast is safe because percentage is <= 1.
164
161
}
165
162
166
163
// we cast a ballot with our chosen vote and a given weight
@@ -199,6 +196,8 @@ mod test {
199
196
// round up right over 1
200
197
assert_eq ! ( 2 , votes_needed( 3 , Decimal :: permille( 334 ) ) ) ;
201
198
assert_eq ! ( 11 , votes_needed( 30 , Decimal :: permille( 334 ) ) ) ;
199
+ // round up to full number of votes
200
+ assert_eq ! ( 420 , votes_needed( 420 , Decimal :: permille( 999 ) ) ) ;
202
201
203
202
// exact matches don't round
204
203
assert_eq ! ( 17 , votes_needed( 34 , Decimal :: percent( 50 ) ) ) ;
0 commit comments