Q3 2026 Security & Compliance$1.18B stolen across 107 incidents. Main drivers: supply chain, smart contracts, keys.
Get the report →

Audit name:

[SCA] ZetaChain | Zeta Migration | Oct2026

Date:

Nov 6, 2026

Table of Content

→Introduction
→Audit Summary
→System Overview
→Potential Risks
→Findings
→Appendix 1. Definitions
→Appendix 2. Scope
→Appendix 3. Additional Valuables
→Disclaimer

Want a comprehensive audit report like this?

Introduction

We express our gratitude to the ZetaChain team for the collaborative engagement that enabled the execution of this Smart Contract Security Assessment.

zeta-migration is a Solana migration program that pays ZETA holders a new SPL token in place of the token they hold, according to an off chain snapshot. The program only enforces that no entry is paid twice and that total payouts stay within fixed caps, while an off chain Go service decides who is paid. The audit covered the zeta_migration Anchor program.

Document

NameSmart Contract Code Review and Security Analysis Report for ZetaChain
Audited ByKerem Solmaz
Approved ByHamza Sajid
Websitehttps://www.zetachain.com/→
Changelog23/10/2026 - Preliminary Report
30/10/2026 - Final Report
PlatformSolana
LanguageRust (Anchor 0.31.1)
TagsClaims, Airdrop, Centralization, Fungible Token
Methodologyhttps://docs.hacken.io/methodologies/smart-contracts→

Review Scope

Repositoryhttps://github.com/zeta-chain/zeta-migration→
Initial Commitffe0064
Final Commitdfe7a2d

Audit Summary

11Total Findings
9Resolved
0Accepted
2Mitigated

The system users should acknowledge all the risks summed up in the risks section of the report

Documentation quality

  • The README describes the launch sequence, the cold key operations, the incident flow, key rotation, and the pinned toolchain versions in detail.

  • A formal specification or whitepaper is not present.

  • Rustdoc and inline comments cover every instruction handler and the state types.

  • The README matches the implemented instruction set and role model. Some safety properties rely on off chain procedures that are documented only as operator guidance.

  • A small number of code comments diverge from the implemented behavior.

Code quality

  • The code follows Anchor practice: account constraints, has_one checks, stored PDA bumps, and typed program accounts are used consistently.

  • The program is small and split into one module per instruction, with named custom errors and checked arithmetic on all value fields.

  • Dependency versions are pinned with = and the lockfile is committed.

  • Issues in business logic, input validation, and code hygiene were identified and reported.

Test coverage

The code coverage of the project cannot be measured, because neither cargo llvm-cov nor cargo tarpaulin is available in the audit environment, however:

  • The tests live in a separate harness workspace and run the built program in litesvm.

  • Test files exist for initialization, claim creation, manual claims, claiming, amount updates, entry closing, pausing, authority rotation, and guard conditions.

  • A mutation score was not produced.

System Overview

The zeta-migration system moves the holdings of ZETA holders onto Solana as a new SPL token. It has two parts: an off chain Go service that reads the ZetaChain snapshot, verifies holder signatures, and submits transactions, and the on chain zeta_migration program, which is the only component in the audit scope. The program verifies no identity and mints nothing. Its two jobs are that no entry is paid twice and that total payouts never exceed the configured caps.

The program keeps three kinds of state. A single Config account at a fixed PDA stores the token mint, the vault address, the two authorities with their pending nominees, the pause flag, and two populations of counters, each with an immutable cap and running committed and claimed totals. One Entry account per source key, derived from the chain id and a 32 byte source key, records the recipient, the destination token account, the amount, a claimed flag, and a manual flag. A vault is an SPL token account PDA owned by a vault authority PDA, and it is funded by an external mint, since the program has no funding instruction. The token is a classic SPL Token mint with 9 decimals, no freeze authority, and a mint authority held outside the program. Amounts are u64 base units, and the supply is set by the snapshot total, with no fixed value in the code.

The initialize instruction runs once and is gated on the program upgrade authority. It creates Config and the vault, and takes the mint, both caps, and both authorities as arguments. The entry authority, a hot key held by the relay, calls create_claim, which writes an Entry paying the recipient associated token account and commits the amount against the cap. The cold authority, a Squads multisig vault, calls create_manual_claim to write an Entry with a named destination token account, update_entry_amount to correct an amount, close_unclaimed_entry to release a commitment and free the address, pause and unpause, and set_authorities to nominate new keys. A nominee confirms a role change through accept_authority. Any signer may call claim, which checks the entry, the destination, the mint, and the recipient, creates the associated token account if needed, records the claim against the cap, transfers tokens from the vault with transfer_checked signed by the vault authority PDA, and marks the entry claimed. The program depends on the SPL Token, Associated Token, System, and BPF upgradeable loader programs. Token-2022 is not supported.

Privileged roles

  • Upgrade authority (zeta_migration): The BPF loader upgrade authority is handed to a Squads multisig after deployment. It is the only signer able to call initialize, which sets the mint, both caps, and the initial authorities with no on chain validation of those values. It can also upgrade the program, which is the only way to change the caps or any immutable configuration. A compromised or misused upgrade authority can replace the program logic and redirect vault funds. The role is protected by a multisig, and no timelock is described.

  • Entry authority (zeta_migration): A hot key held in a key file by the relay service. It can call create_claim to write an entry for any recipient and any amount up to the remaining cap, while the program is not paused. It cannot update or close entries. Compromise of this key allows false entries that any caller can then claim, bounded by the cap. Pausing, voiding, and rotation are the available mitigations, and all of them depend on the cold authority. The key is a single key file with no multisig or timelock.

  • Cold authority (zeta_migration): A Squads multisig vault. It can call create_manual_claim with an arbitrary destination token account and amount, update_entry_amount, close_unclaimed_entry with an arbitrary rent receiver, pause, unpause, and set_authorities. Update, close, and rotation calls remain available while the program is paused. Misuse could redirect payouts through manual entries, void entries, or take over both roles through nominations. The role sits behind the Squads multisig threshold, with no timelock. The program does not prevent the entry and cold authorities from being the same key.

  • Nominee (zeta_migration): Any key named as a pending entry or cold authority by set_authorities. The nominee calls accept_authority to take the role, which clears the pending nomination. Accepting the cold role also clears a pending entry nomination. The role grants no power until the cold authority nominates the key.

  • Mint authority holder (external to zeta_migration): The mint authority is an SPL token multisig with threshold 1, whose signers are the issuer bridge and the migration minter. It is not part of the program, but it controls the vault funding and can mint further tokens after launch. The program never compares the vault balance with the caps.

Potential Risks

Scope Definition and Security Guarantees: The audit covers only the zeta_migration Anchor program. The off chain Go service that reads the snapshot, verifies holder signatures, builds transactions, and runs the funding step is outside the scope, as are the Squads multisig configuration, the key handling of the relay, and the launch procedures described in the README. The program trusts the service completely for recipient identity and amount, so the correctness of every payout depends on code and operations that were not assessed.

Dependency on External Logic for Implemented Logic: The zeta_migration program does not fund its own vault and has no instruction that deposits tokens. The vault is filled by an external mint step performed by the migration minter, and the program never compares the vault balance with the two caps. If the vault is funded below the snapshot total, claims past the funded amount fail at the token transfer until the vault is topped up. The match between the caps and the funded amount relies on the off chain funding step and its operator checks.

Centralized Control of Minting Process: The mint authority of the migrated token is an SPL token multisig with threshold 1, whose signers are the issuer bridge and the migration minter. Either signer alone can mint further tokens after launch, and the supply has no fixed value in the code, because it follows the snapshot total. The program has no control over this authority, so holders depend on the operational discipline of these two signers.

Administrative Key Control Risks: The entry authority is a single hot key stored in a key file on the relay. It can write entries for any recipient and amount up to the remaining cap, and any caller can claim them. If the key is stolen, the only containment is a pause by the cold authority, and entries created and claimed in the same transaction can be paid before a pause takes effect. The loss is bounded by the cap but cannot be recovered once tokens leave the vault.

Single Entity Upgrade Authority: The upgrade authority of zeta_migration is held by one Squads multisig after deployment. It alone can call the initialization instruction that sets the mint, both caps, and both authorities without on chain validation, and it can replace the program code. The caps are immutable except through an upgrade, so a mistaken initialization or a malicious upgrade directly affects the vault funds.

Absence of Time-lock Mechanisms for Critical Operations: No timelock protects program upgrades, authority nominations, manual claims, entry amount changes, or entry closing. The cold authority can write a manual entry with an arbitrary destination token account and amount and can rotate both authorities, and holders have no review window before such changes take effect. Update, close, and rotation operations also stay available while the program is paused.

Insufficient Multi-signature Controls for Critical Functions: The cold authority is a multisig, while the entry authority is a single key, and the program does not prevent both roles from being set to the same key at initialization. If the same key fills both roles, the pause and void protections that depend on the cold authority are available to an attacker who holds the hot key.

Findings

F-2026-2002Missing requirewallet Recipient Validation In createclaim
Status
fixed
Severity

Low
F-2026-2002Missing Destination Owner Revalidation In claim Allows Third Parties To Redirect Manual Payout
Status
fixed
Severity

Low
F-2026-2006claim Re-Derives The Retail ATA Address That create_claim Already Stored
Status
fixed
Severity

Observation
F-2026-2006Missing Canonical Anchor IDL Initialisation In Launch Flow
Status
fixed
Severity

Observation
F-2026-2005Doc Comments Diverge From Implemented Behaviour In claim And pause
Status
fixed
Severity

Observation
F-2026-2005Missing Event Emission In initialize
Status
fixed
Severity

Observation
F-2026-2005Missing Zero Address Validation For entryauthority And coldauthority In initialize
Status
fixed
Severity

Observation
F-2026-2005Missing Decimals Check On mint In initialize
Status
fixed
Severity

Observation
F-2026-2005Unused rent Sysvar Account In Initialize
Status
fixed
Severity

Observation
F-2026-2003Error Messages Disagreeing With Guarded Conditions In RecipientNotAWallet And EntryClaimed
Status
mitigated
Severity

Observation
Code
―
Title
Status
Severity
F-2026-2002Missing requirewallet Recipient Validation In createclaim
fixed

Low
F-2026-2002Missing Destination Owner Revalidation In claim Allows Third Parties To Redirect Manual Payout
fixed

Low
F-2026-2006claim Re-Derives The Retail ATA Address That create_claim Already Stored
fixed

Observation
F-2026-2006Missing Canonical Anchor IDL Initialisation In Launch Flow
fixed

Observation
F-2026-2005Doc Comments Diverge From Implemented Behaviour In claim And pause
fixed

Observation
F-2026-2005Missing Event Emission In initialize
fixed

Observation
F-2026-2005Missing Zero Address Validation For entryauthority And coldauthority In initialize
fixed

Observation
F-2026-2005Missing Decimals Check On mint In initialize
fixed

Observation
F-2026-2005Unused rent Sysvar Account In Initialize
fixed

Observation
F-2026-2003Error Messages Disagreeing With Guarded Conditions In RecipientNotAWallet And EntryClaimed
mitigated

Observation
1-10 of 11 findings

Identify vulnerabilities in your smart contracts.

Appendix 1. Definitions

Severities

When auditing smart contracts, Hacken is using a risk-based approach that considers Likelihood, Impact, Exploitability and Complexity metrics to evaluate findings and score severities.

Reference on how risk scoring is done is available through the repository in our Github organization:

Severity

Description

Critical
Critical vulnerabilities are usually straightforward to exploit and can lead to the loss of user funds or contract state manipulation.

High
High vulnerabilities are usually harder to exploit, requiring specific conditions, or have a more limited scope, but can still lead to the loss of user funds or contract state manipulation.

Medium
Medium vulnerabilities are usually limited to state manipulations and, in most cases, cannot lead to asset loss. Contradictions and requirements violations. Major deviations from best practices are also in this category.

Low
Major deviations from best practices or major Gas inefficiency. These issues will not have a significant impact on code execution.
  • Severity

    Critical

    Description

    Critical vulnerabilities are usually straightforward to exploit and can lead to the loss of user funds or contract state manipulation.

    Severity

    High

    Description

    High vulnerabilities are usually harder to exploit, requiring specific conditions, or have a more limited scope, but can still lead to the loss of user funds or contract state manipulation.

    Severity

    Medium

    Description

    Medium vulnerabilities are usually limited to state manipulations and, in most cases, cannot lead to asset loss. Contradictions and requirements violations. Major deviations from best practices are also in this category.

    Severity

    Low

    Description

    Major deviations from best practices or major Gas inefficiency. These issues will not have a significant impact on code execution.

Potential Risks

The "Potential Risks" section identifies issues that are not direct security vulnerabilities but could still affect the project’s performance, reliability, or user trust. These risks arise from design choices, architectural decisions, or operational practices that, while not immediately exploitable, may lead to problems under certain conditions. Additionally, potential risks can impact the quality of the audit itself, as they may involve external factors or components beyond the scope of the audit, leading to incomplete assessments or oversight of key areas. This section aims to provide a broader perspective on factors that could affect the project's long-term security, functionality, and the comprehensiveness of the audit findings.

Appendix 2. Scope

The scope of the project includes the following smart contracts from the provided repository:

Scope Details

Repositoryhttps://github.com/zeta-chain/zeta-migration→
Initial Commitffe006474a2ad924daf10322b6dedc44b3eaa44e
Final Commitdfe7a2d3f09a9a37213bfeb41b5a0da9207fc725
Whitepaper-
RequirementsREADME.md
Technical RequirementsREADME.md
  • Scope Details

    Initial Commit
    ffe006474a2ad924daf10322b6dedc44b3eaa44e
    Final Commit
    dfe7a2d3f09a9a37213bfeb41b5a0da9207fc725
    Whitepaper
    -
    Requirements
    README.md
    Technical Requirements
    README.md

Assets in Scope

programs
zeta_migration
src
instructions
accept_authority.rs - programs › zeta_migration › src › instructions › accept_authority.rs
programs
zeta_migration
src
errors.rs - programs › zeta_migration › src › errors.rs
instructions
claim.rs - programs › zeta_migration › src › instructions › claim.rs
close_unclaimed_entry.rs - programs › zeta_migration › src › instructions › close_unclaimed_entry.rs
create_claim.rs - programs › zeta_migration › src › instructions › create_claim.rs
create_manual_claim.rs - programs › zeta_migration › src › instructions › create_manual_claim.rs
initialize.rs - programs › zeta_migration › src › instructions › initialize.rs
mod.rs - programs › zeta_migration › src › instructions › mod.rs
pause.rs - programs › zeta_migration › src › instructions › pause.rs
set_authorities.rs - programs › zeta_migration › src › instructions › set_authorities.rs
update_entry_amount.rs - programs › zeta_migration › src › instructions › update_entry_amount.rs
lib.rs - programs › zeta_migration › src › lib.rs
state.rs - programs › zeta_migration › src › state.rs

Appendix 3. Additional Valuables

Additional Recommendations

The smart contracts in the scope of this audit could benefit from the introduction of automatic emergency actions for critical activities, such as unauthorized operations like ownership changes or proxy upgrades, as well as unexpected fund manipulations, including large withdrawals or minting events. Adding such mechanisms would enable the protocol to react automatically to unusual activity, ensuring that the contract remains secure and functions as intended.

To improve functionality, these emergency actions could be designed to trigger under specific conditions, such as:

  • Detecting changes to ownership or critical permissions.

  • Monitoring large or unexpected transactions and minting events.

  • Pausing operations when irregularities are identified.

These enhancements would provide an added layer of security, making the contract more robust and better equipped to handle unexpected situations while maintaining smooth operations.

Frameworks and Methodologies

This security assessment was conducted in alignment with recognised penetration testing standards, methodologies and guidelines, including the NIST SP 800-115 – Technical Guide to Information Security Testing and Assessment →, and the Penetration Testing Execution Standard (PTES) →, These assets provide a structured foundation for planning, executing, and documenting technical evaluations such as vulnerability assessments, exploitation activities, and security code reviews. Hacken’s internal penetration testing methodology extends these principles to Web2 and Web3 environments to ensure consistency, repeatability, and verifiable outcomes.

Disclaimer