pub fn swap_exact_in(… zero_for_one: bool ) -> Result<()> {
    …
    if zero_for_one {
        
        let numerator: u128   = (reserve_b as u128)
            .checked_mul(amount_in as u128)
            .ok_or(AmmError::Overflow)?;
        let denominator: u128 = (reserve_a as u128)
            .checked_add(amount_in as u128)
            .ok_or(AmmError::Overflow)?;
        if denominator == 0 {
            return err!(AmmError::DivisionByZero);
        }
        let mut amount_out: u64 = numerator.div_floor(&denominator) as u64;
        
        let lp_fees = (amount_out as u128 * 3).div_floor(&1000) as u64;
        amount_out = amount_out - lp_fees;
        …
    } else {
        
    }
}
pub fn swap_exact_out(… zero_for_one: bool ) -> Result<()> {
    …
    if zero_for_one {
        
        let numerator: u128   = (reserve_a as u128)
            .checked_mul(amount_out as u128)
            .ok_or(AmmError::Overflow)?;
        let denominator: u128 = (reserve_b as u128)
            .checked_sub(amount_out as u128)
            .ok_or(AmmError::Underflow)?;
        require!(denominator > 0, AmmError::DivisionByZero);
        let amount_in_no_fee: u64 = numerator.div_floor(&denominator) as u64;
        
        let fee_numerator_u128 = (amount_in_no_fee as u128)
            .checked_mul(3)
            .ok_or(AmmError::Overflow)?;
        let lp_fees: u64 = fee_numerator_u128.div_floor(&1000) as u64;
        let amount_in_final = (amount_in_no_fee as u128)
            .checked_add(lp_fees as u128)
            .ok_or(AmmError::Overflow)? as u64;
        …
    } else {
        
    }
}
fn simulate_swap_exact_in() {
    
    let reserve_a: u128   = 10_000;
    let reserve_b: u128   = 20_000;
    let amount_in: u128   = 1_000;
    
    
    
    
    
    let amount_in_with_fee = amount_in * 997;
    let numerator_correct  = amount_in_with_fee * reserve_b;
    let denominator_correct = (reserve_a * 1_000) + amount_in_with_fee;
    let amount_out_correct = (numerator_correct / denominator_correct) as u64;
    assert_eq!(amount_out_correct, 1_812);
    
    
    
    
    
    
    let numerator_impl     = reserve_b * amount_in;
    let denominator_impl   = reserve_a + amount_in;
    let gross_out_impl     = (numerator_impl / denominator_impl) as u64; 
    let lp_fees_impl       = ((gross_out_impl as u128 * 3) / 1000) as u64; 
    let amount_out_impl    = gross_out_impl - lp_fees_impl;                
    
    
    
    
    
    
    println!("Uniswap V2 gives {} vs impl gives {}", amount_out_correct, amount_out_impl);
    
}