@@ -4,10 +4,6 @@ use cw_utils::{Expiration, Threshold};
44
55use crate :: { DepositInfo , Status , Vote } ;
66
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-
117#[ cw_serde]
128pub struct Proposal {
139 pub title : String ,
@@ -155,12 +151,13 @@ impl Votes {
155151 }
156152}
157153
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.
160157fn 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.
164161}
165162
166163// we cast a ballot with our chosen vote and a given weight
@@ -199,6 +196,8 @@ mod test {
199196 // round up right over 1
200197 assert_eq ! ( 2 , votes_needed( 3 , Decimal :: permille( 334 ) ) ) ;
201198 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 ) ) ) ;
202201
203202 // exact matches don't round
204203 assert_eq ! ( 17 , votes_needed( 34 , Decimal :: percent( 50 ) ) ) ;
0 commit comments