3

I have a function like this:

pub fn initialize_pool(ctx: Context<InitializePool>, rate: u64) -> Result<()> {
    require!(rate.gt(&0), SwapPoolError::SwapRateError);

    // {...more logic}

    Ok(())
}

I want to check if rate is equal or less than zero, throw an error here, however the function still passed with negative values (for example "new anchor.BN(-10)")

Besides above code I tried:

require!(rate > 0, SwapPoolError::SwapRateError);

and

if rate <= 0 
{
    return err!(SwapPoolError::SwapRateError);
}

What am I doing wrong here?

1 Answer 1

2

rate is defined as u64, an unsigned 64-bit integer, meaning that the 8 bytes that make up the number will always be interpreted as unsigned, greater than or equal to 0.

When you pass -10, that creates 8 bytes that are encoded as a signed integer. Your program doesn't know that, so it will interpret those 8 bytes as unsigned, and give an unexpected answer.

Here's some rust code that shows the issue:

fn main() {
    let i: i64 = -10;
    let u: u64 = i as u64;
    println!("{u}");
}

Which outputs:

18446744073709551606

which is the same as u64::MAX - 9. You can output what you're receiving in your program using the msg! macro.

2
  • I see, so what is the solution for this problem? Maybe change rate type to i64 so it can check for negative numbers, but do we have more elegant solution?
    – agentp
    Commented Apr 16, 2023 at 15:35
  • The easiest solution is to just pass in a u64 every time. If someone passes in an improper input, then that's a user error
    – Jon C
    Commented Apr 16, 2023 at 17:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.