3

I know with rust you need to be sure you do not cause buffer overflows/underflows when performing math operations.

What are the best practices for doing common math safely within programs? Adding, subtracting, and calculating the remainder, range checks, etc

If I have a u8 and want to add 1 to it, what is the best way to perform this without eventually causing a buffer overflow?

  • does this method change based on the number type (i.e u8 vs u32)?
  • does this change for different types of math? (addition vs subtraction)

Ideally, I would be able to make my anchor program return enum based error to the client if the math operation was bad, as opposed to causing a panic.

1 Answer 1

3

Here is a minimal example on Solana playground:

You can create a custom Anchor errors and then use checked_add(1).ok_or(MyErrors::CustomError)

use anchor_lang::prelude::*;

// This is your program's public key and it will update
// automatically when you build the project.
declare_id!("8Drnj5xTde66bZc79bvC7DFTM1SrR12NLx4fz5LrRNdV");

#[program]
mod hello_anchor {
    use super::*;
    pub fn initialize(ctx: Context<Initialize>, count: u8) -> Result<()> {
        ctx.accounts.counter.count = count;
        msg!("Count is: {}!", count); // Message will show up in the tx logs
        Ok(())
    }

    pub fn increment(ctx: Context<Increment>) -> Result<()> {
        let counter = &mut ctx.accounts.counter;
        counter.count = counter.count.checked_add(1).ok_or(MyErrors::CustomError)?;
        msg!("Count is: {}!", counter.count); // Message will show up in the tx logs
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(init, payer = signer, space = 8 + 1)]
    pub counter: Account<'info, Counter>,
    #[account(mut)]
    pub signer: Signer<'info>,
    pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct Increment<'info> {
    #[account(mut)]
    pub counter: Account<'info, Counter>,
}

#[account]
pub struct Counter {
    count: u8,
}

#[error_code]
pub enum MyErrors {
    #[msg("My Custom Error Message")]
    CustomError,
}

If the counter in the example was 255 and you tried to invoke the increment instruction, you would get the custom Anchor error message in the program logs and the value on the account would be unchanged.

'Program log: AnchorError occurred. Error Code: CustomError. Error Number: 6000. Error Message: My Custom Error Message.'
1
  • thank you very much john!
    – nickfrosty
    Commented Jan 2 at 14:16

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.