pyth2wormhole - Governance

CertiKCode version: not recorded (see the report)

CertiK reviewed Wormhole (pyth2wormhole - Governance) on 13 Dec 2022: 13 findings, 0 critical; 4 marked fixed, 9 open.

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

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings13

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

SeverityOpenAcknowledgedFixed
Critical000
High101
Medium000
Low803
HighCentralization Related RisksOpen

In the program `staking`, the role `governance_authority` has authority over the following functions: - `update_governance_authority()` will change the `governance_authority` role of the `config_account`. - `update_freeze()` will change the `freeze` status of the `config_account`. - `create_target()` will create a voting target `target_account`. Any compromise to the `governance_authority` account may allow the hacker to take advantage of this and result in unexpected loss. Additionally, the Solana program could be upgradeable, and the upgrade authority is the deployer by default. Therefore, if the program is upgradable, and the upgrade authority account is compromised, it could lead to a malicious program upgrade, thus introducing centralization risk.

LowChecked Math Not UsedOpen

The above linked locations are places where checked math is not used and integer overflow is possible.

LowInapproiate Program IDOpen

In L43, the program is using a default program ID provided by the Anchor framework: ```rust=43 declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); ```

LowMissing Emit EventsOpen

In the program `staking`, the functions that affect the status of sensitive variables should be able to emit events. - `init_config` affects the `GlobalConfig` account - `update_governance_authority` affects `governance_authority` of the `GlobalConfig` account - `update_freeze` affects `freeze` of the `GlobalConfig` account - `create_stake_account` affects `StakeAccountMetadataV2` account and `VoterWeightRecord` account - `create_position` affects `PositionData` account - `close_position` affects `PositionData` account - `update_voter_weight` affects `VoterWeightRecord` account

LowMissing Error Messages For Account CheckOpen

The **#[account(address = <expr>)]** in Anchor supports throwing an exception if the address does not match. It is better to use **#[account(address = <expr> @ custom_error)]** instead of **#[account(address = <expr>)]** to provide a customized error message and pass it back to the caller. Reference:[Accounts in anchor_lang](https://docs.rs/anchor-lang/latest/anchor_lang/derive.Accounts.html)

LowMissing Mint CheckOpen

When withdrawing the staked token, a `destination` TokenAccount is given but missing the mint check against `config.pyth_token_mint`.

LowRedundant CheckOpen

The following two risk validations at L322 to L332 and L345 to L355 in the `withdraw_stake` instruction are redundant. ```rust=318 let remaining_balance = stake_account_custody .amount .checked_sub(amount) .ok_or_else(|| error!(ErrorCode::InsufficientWithdrawableBalance))?; if utils::risk::validate( stake_account_positions, remaining_balance, unvested_balance, current_epoch, config.unlocking_duration, ) .is_err() { return Err(error!(ErrorCode::InsufficientWithdrawableBalance)); } transfer( CpiContext::from(&*ctx.accounts).with_signer(&[&[ AUTHORITY_SEED.as_bytes(), ctx.accounts.stake_account_positions.key().as_ref(), &[stake_account_metadata.authority_bump], ]]), amount, )?; ctx.accounts.stake_account_custody.reload()?; if utils::risk::validate( stake_account_positions, ctx.accounts.stake_account_custody.amount, unvested_balance, current_epoch, config.unlocking_duration, ) .is_err() { return Err(error!(ErrorCode::InsufficientWithdrawableBalance)); } ```

LowValidations for ProposalOpen

When updating a voter's weight with the `CastVote` action, a proposal account is deserialized, but not sufficiently checked. For example, since the `governance` and `governing_token_mint` fields are not checked, it is possible for the proposal account to belong to different governance. Furthermore, the `state` field is not checked, meaning the proposal may have already succeeded or failed.

LowValidity Checks on Vesting ScheduleOpen

When creating a stake account, the user provides the vesting schedule. If `PeriodVesting` is chosen, four parameters need to be provided: - `initial_balance` - `start_date` - `period_duration` - `num_periods` Since there are operations that involve dividing by `period_duration` or `num_periods`, there should be checks to ensure that these parameters are positive, especially since they cannot be changed after the stake account is created.

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 Wormhole’s security record

Wormhole
Audits11 audits by 4 firmsLast audit Oct 2024, by Cyfrin.
Critical findingsNo open critical findingsAcross 11 reports.
Open Wormhole’s security record

Security firm

CertiK

1,044 projects reviewed · 1,393 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