zk-token-sdk: calculate transfer fee without conditional branch (#27356)

This commit is contained in:
samkim-crypto 2022-08-24 17:29:23 +09:00 committed by GitHub
parent 19fc4fcbf8
commit 0ea984ae20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 11 additions and 9 deletions

View File

@ -697,18 +697,20 @@ impl FeeParameters {
#[cfg(not(target_os = "solana"))]
fn calculate_fee(transfer_amount: u64, fee_rate_basis_points: u16) -> Option<(u64, u64)> {
let numerator = (transfer_amount as u128).checked_mul(fee_rate_basis_points as u128)?;
let mut fee = numerator.checked_div(ONE_IN_BASIS_POINTS)?;
let mut delta_fee = 0_u128;
let remainder = numerator.checked_rem(ONE_IN_BASIS_POINTS)?;
if remainder > 0 {
fee = fee.checked_add(1)?;
// Warning: Division may involve CPU opcodes that have variable execution times. This
// non-constant-time execution of the fee calculation can theoretically reveal information
// about the transfer amount. For transfers that invole extremely sensitive data, additional
// care should be put into how the fees are calculated.
let fee = numerator
.checked_add(ONE_IN_BASIS_POINTS)?
.checked_sub(1)?
.checked_div(ONE_IN_BASIS_POINTS)?;
let scaled_fee = fee.checked_mul(ONE_IN_BASIS_POINTS)?;
delta_fee = scaled_fee.checked_sub(numerator)?;
}
let delta_fee = fee
.checked_mul(ONE_IN_BASIS_POINTS)?
.checked_sub(numerator)?;
let fee = u64::try_from(fee).ok()?;
Some((fee as u64, delta_fee as u64))
}