Zebec - Rust

CertiKCode version: not recorded (see the report)

CertiK reviewed Zebec (Zebec - Rust) on 30 Mar 2024: 9 findings, 0 critical; 7 marked fixed, 1 acknowledged, 1 open.

No open critical findings
Open the reportOpen Zebec’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings9

Statuses are the security firm’s own, from its report.

SeverityOpenAcknowledgedFixed
Critical000
High010
Medium001
Low106
MediumMissing `ZBC` and `ZBCN` Token Decimal ConversionFixed

Based on the code logic below, it's clear that the value of the `amount` argument provided is used for both burning `ZBC` and minting `ZBCN`. Notably, there is no code logic for decimal conversion. Consequently, the minted amount of `ZBCN` does not match the expected value. **[migrate_token.rs#L97](https://github.com/Zebec-protocol/migration-program/blob/938b8d6e58860f210ac1110ce6850399329e68ba/programs/migration-program/src/instructions/migrate_token.rs#L97)** ```rust=97 // Burn ZBC tokens. burn(burn_ctx, amount)?; ``` **[migrate_token.rs#L114](https://github.com/Zebec-protocol/migration-program/blob/938b8d6e58860f210ac1110ce6850399329e68ba/programs/migration-program/src/instructions/migrate_token.rs#L114)** ```rust=114 // Mint equivalent ZBCN tokens that were burned. mint_to(mint_ctx, amount)?; ```

Low`ZBC` and `ZBCN` Token PriceFixed

Based on the code logic below, it's evident that the provided `amount` argument value is used for both burning `ZBC` and minting `ZBCN`. This implies that the conversion rate between `ZBC` and `ZBCN` tokens is 1:1 when they have the same decimal precision. **[migrate_token.rs#L97](https://github.com/Zebec-protocol/migration-program/blob/938b8d6e58860f210ac1110ce6850399329e68ba/programs/migration-program/src/instructions/migrate_token.rs#L97)** ```rust=97 // Burn ZBC tokens. burn(burn_ctx, amount)?; ``` **[migrate_token.rs#L114](https://github.com/Zebec-protocol/migration-program/blob/938b8d6e58860f210ac1110ce6850399329e68ba/programs/migration-program/src/instructions/migrate_token.rs#L114)** ```rust=114 // Mint equivalent ZBCN tokens that were burned. mint_to(mint_ctx, amount)?; ``` The holders of `ZBC` token assets accesses the `migrate_token()` function to convert a specified amount, rather than their entire holding, of `ZBC` to `ZBCN`. Therefore, the duration of the token migration is not predetermined. Throughout the migration process, the prices of `ZBC` and `ZBCN` may differ. In such instances, a 1:1 amount conversion could potentially reduce the value of the holder's assets if the price of `ZBCN` is lower than that of `ZBC`. **[lib.rs#L21](https://github.com/Zebec-protocol/migration-program/blob/938b8d6e58860f210ac1110ce6850399329e68ba/programs/migration-program/src/lib.rs#L21)** ```rust=21 pub fn migrate_token(ctx: Context<MigrateToken>, amount: u64) -> Result<()> { migrate_token::handler(ctx, amount) } ```

Low`ZBCN` Max Minted AmountFixed

According to the logic outlined in the following code, it is evident that only 10 billion `ZBCN` tokens are minted via the `migration-program`, implying that only 10 billion `ZBC` tokens undergo migration. **[migrate_token.rs#L84](https://github.com/Zebec-protocol/migration-program/blob/938b8d6e58860f210ac1110ce6850399329e68ba/programs/migration-program/src/instructions/migrate_token.rs#L84)** ```rust=84 // The migration program is one way ZBC -> ZBCN. The migration program will stop once 10,000,000,000 ZBCN tokens are minted. require!( migrate_pda.total_migrated + amount <= 10_000_000_000 * 10u64.pow(zbcn_decimals as u32), MigrationError::MaxMigrationReached ); ```

LowAssignee and Assigning Time for `zbcn_mint` MintFixed

According to the comment at L27, the `mint_authority` account has been designated the mint authority role for the `ZBCN` token. However, the current codebase lacks the necessary logic to assign the mint authority role for the `ZBCN` token to the `mint_authority` account. ```rust=19 #[account( init, payer = admin, space = 8, seeds = [b"zbcn_mint"], bump )] /// CHECK: seeds has been checked /// This account has mint authority for ZBCN tokens. pub mint_authority: AccountInfo<'info>, /// ZBC (new) mint account. pub zbc_mint: Account<'info, Mint>, /// ZBCN (old) mint account. pub zbcn_mint: Account<'info, Mint>, ```

LowMeaningless Variable NameFixed

The following `CPI` is utilized for minting `ZBCN`, however, the variable name `mint_zbc` fails to accurately convey the meaning of `MintTo` struct instance. ```rust=103 let mint_zbc = MintTo { mint: zbcn_mint.to_account_info(), to: sender_zbcn_ata.to_account_info(), authority: mint_authority.to_account_info(), }; let mint_ctx = CpiContext::new_with_signer( token_program.to_account_info(), mint_zbc, mint_authority_seed, ); ```

LowMissing Mint Authority ValidationFixed

Based on the comment at L27, the `mint_authority` account has been assigned the role of mint authority for the `ZBCN` token. However, a current flaw in the code is the lack of a check to verify whether the `zbcn_mint` mint authority truly corresponds to the `mint_authority` PDA. And after executing `init_config()` instruction, `migrate_pda.zbcn_mint` and `migrate_pda.mint_authority` cannot be updated. **[init_config.rs#L19](https://github.com/Zebec-protocol/migration-program/blob/938b8d6e58860f210ac1110ce6850399329e68ba/programs/migration-program/src/instructions/init_config.rs#L19)** ```rust=19 #[account( init, payer = admin, space = 8, seeds = [b"zbcn_mint"], bump )] /// CHECK: seeds has been checked /// This account has mint authority for ZBCN tokens. pub mint_authority: AccountInfo<'info>, /// ZBC (new) mint account. pub zbc_mint: Account<'info, Mint>, /// ZBCN (old) mint account. pub zbcn_mint: Account<'info, Mint>, ``` A similar issue also exists in `migrate_token.rs`. **[migrate_token.rs#L39](https://github.com/Zebec-protocol/migration-program/blob/938b8d6e58860f210ac1110ce6850399329e68ba/programs/migration-program/src/instructions/migrate_token.rs#L39)** ```rust=39 /// ZBCN (new) mint account. pub zbcn_mint: Account<'info, Mint>, #[account( mut, seeds = [b"zbcn_mint"], bump )] /// CHECK: seeds has been checked /// This account has mint authority for ZBCN tokens. pub mint_authority: AccountInfo<'info>, ```

LowMore `migrate_pda` Account Storage Space is AllocFixed

The space constraint at L13 serves to restrict the on-chain storage size of `migrate_pad`. In general, the `#[derive(InitSpace)]` macro is used to record `Migrate` storage size through adding an `INIT_SPACE` constant. This constant's value equals the sum of the sizes of the struct's fields with fixed byte sizes. However, the usage of the `std::mem::size_of::<Migrate>()` function will get the size for the `Migrate` struct, including padding, exceeds the value of the `INIT_SPACE` constant. Consequently, the on-chain storage size of `migrate_pad` becomes larger than necessary, and will pay more rent lamports than actually needed. **[init_config.rs#L10](https://github.com/Zebec-protocol/migration-program/blob/938b8d6e58860f210ac1110ce6850399329e68ba/programs/migration-program/src/instructions/init_config.rs#L10)** ```rust=10 #[account( init, payer = admin, space = 8 + std::mem::size_of::<Migrate>(), seeds = [b"migrate"], bump )] /// PDA that stores the migration state and authority. pub migrate_pda: Box<Account<'info, Migrate>>, ```

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Part of Zebec’s security record

Zebec
Audits1 audit by 1 firmLast audit Mar 2024, by CertiK.
Critical findingsNo open critical findingsIn 1 report.
Open Zebec’s security record

Security firm

CertiK

1,044 projects reviewed · 1,375 reports · latest May 2025

See CertiK’s audits

Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.

Tell us