[zk-token-sdk] Fix transfer with fee edge case error (#34314)

This commit is contained in:
samkim-crypto 2023-12-07 06:46:57 +09:00 committed by GitHub
parent cf0c52c207
commit d21e7edd2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 31 additions and 7 deletions

View File

@ -41,6 +41,8 @@ use {
const MAX_FEE_BASIS_POINTS: u64 = 10_000;
#[cfg(not(target_os = "solana"))]
const ONE_IN_BASIS_POINTS: u128 = MAX_FEE_BASIS_POINTS as u128;
#[cfg(not(target_os = "solana"))]
const MAX_DELTA_RANGE: u64 = MAX_FEE_BASIS_POINTS - 1;
#[cfg(not(target_os = "solana"))]
const TRANSFER_SOURCE_AMOUNT_BITS: usize = 64;
@ -51,7 +53,7 @@ const TRANSFER_AMOUNT_LO_NEGATED_BITS: usize = 16;
#[cfg(not(target_os = "solana"))]
const TRANSFER_AMOUNT_HI_BITS: usize = 32;
#[cfg(not(target_os = "solana"))]
const TRANSFER_DELTA_BITS: usize = 48;
const TRANSFER_DELTA_BITS: usize = 16;
#[cfg(not(target_os = "solana"))]
const FEE_AMOUNT_LO_BITS: usize = 16;
#[cfg(not(target_os = "solana"))]
@ -62,6 +64,7 @@ lazy_static::lazy_static! {
pub static ref COMMITMENT_MAX: PedersenCommitment = Pedersen::encode((1_u64 <<
TRANSFER_AMOUNT_LO_NEGATED_BITS) - 1);
pub static ref COMMITMENT_MAX_FEE_BASIS_POINTS: PedersenCommitment = Pedersen::encode(MAX_FEE_BASIS_POINTS);
pub static ref COMMITMENT_MAX_DELTA_RANGE: PedersenCommitment = Pedersen::encode(MAX_DELTA_RANGE);
}
/// The instruction data that is needed for the `ProofInstruction::TransferWithFee` instruction.
@ -557,24 +560,41 @@ impl TransferWithFeeProof {
// generate the range proof
let opening_claimed_negated = &PedersenOpening::default() - &opening_claimed;
let combined_amount = combine_lo_hi_u64(
transfer_amount_lo,
transfer_amount_hi,
TRANSFER_AMOUNT_LO_BITS,
);
let amount_sub_fee = combined_amount
.checked_sub(combined_fee_amount)
.ok_or(ProofGenerationError::FeeCalculation)?;
let amount_sub_fee_opening = combined_opening - combined_fee_opening;
let delta_negated = MAX_DELTA_RANGE
.checked_sub(delta_fee)
.ok_or(ProofGenerationError::FeeCalculation)?;
let range_proof = RangeProof::new(
vec![
source_new_balance,
transfer_amount_lo,
transfer_amount_hi,
delta_fee,
MAX_FEE_BASIS_POINTS - delta_fee,
delta_negated,
fee_amount_lo,
fee_amount_hi,
amount_sub_fee,
],
vec![
TRANSFER_SOURCE_AMOUNT_BITS, // 64
TRANSFER_AMOUNT_LO_BITS, // 16
TRANSFER_AMOUNT_HI_BITS, // 32
TRANSFER_DELTA_BITS, // 48
TRANSFER_DELTA_BITS, // 48
TRANSFER_DELTA_BITS, // 16
TRANSFER_DELTA_BITS, // 16
FEE_AMOUNT_LO_BITS, // 16
FEE_AMOUNT_HI_BITS, // 32
TRANSFER_SOURCE_AMOUNT_BITS, // 64
],
vec![
&opening_source,
@ -584,6 +604,7 @@ impl TransferWithFeeProof {
&opening_claimed_negated,
opening_fee_lo,
opening_fee_hi,
&amount_sub_fee_opening,
],
transcript,
)?;
@ -708,7 +729,8 @@ impl TransferWithFeeProof {
// verify range proof
let new_source_commitment = self.new_source_commitment.try_into()?;
let claimed_commitment_negated = &(*COMMITMENT_MAX_FEE_BASIS_POINTS) - &claimed_commitment;
let claimed_commitment_negated = &(*COMMITMENT_MAX_DELTA_RANGE) - &claimed_commitment;
let amount_sub_fee_commitment = combined_commitment - combined_fee_commitment;
range_proof.verify(
vec![
@ -719,15 +741,17 @@ impl TransferWithFeeProof {
&claimed_commitment_negated,
fee_ciphertext_lo.get_commitment(),
fee_ciphertext_hi.get_commitment(),
&amount_sub_fee_commitment,
],
vec![
TRANSFER_SOURCE_AMOUNT_BITS, // 64
TRANSFER_AMOUNT_LO_BITS, // 16
TRANSFER_AMOUNT_HI_BITS, // 32
TRANSFER_DELTA_BITS, // 48
TRANSFER_DELTA_BITS, // 48
TRANSFER_DELTA_BITS, // 16
TRANSFER_DELTA_BITS, // 16
FEE_AMOUNT_LO_BITS, // 16
FEE_AMOUNT_HI_BITS, // 32
TRANSFER_SOURCE_AMOUNT_BITS, // 64
],
transcript,
)?;