Assessment reports>MultiGov>Threat Model>Crate: wormhole-staking-program

Crate: wormhole-staking-program

The wormhole-staking-program program is a Solana program built using the Anchor framework. It handles multiple aspects of protocol state including governance configuration, stake account creation and management, delegation and vote-casting, vesting operations, and cross-chain message execution (via Wormhole). The contract maintains various on-chain states:

Global Configuration: Stored in a configuration account, this includes:

  • bump: Seed bump for proper PDA derivation.

    • governance_authority: The address authorized to make governance-level changes.

    • voting_token_mint: The mint address for the token used in voting.

    • vesting_admin: The administrator permitted to perform vesting operations.

    • max_checkpoints_account_limit: A bound on checkpoint entries to mitigate potential account bloat/DoS.

Stake Account State: For each user, stake account metadata and checkpoint data track:

  • Ownership, delegated addresses, and recorded balances.

    • Historical checkpoints for stake and delegation amounts, which are critical for calculating voting power over time.

Vesting State: Multiple vesting-related accounts and configuration parameters are maintained to control token vesting, claims, transfers, and cancellations.

Spoke Message Execution State: This includes executor, airlock, and metadata collector accounts used to securely process cross-chain messages.

Below is a function-by-function walkthrough with key safety and threat-mitigation considerations.

Function: init_config

Description:

  • Initializes the global configuration.

  • Stores the governance authority, voting token mint, vesting admin, and a checkpoint limit.

  • Enforces that the max_checkpoints_account_limit does not exceed 655,000 (to prevent account bloat and DoS).

Safety Considerations:

  • DoS Mitigation: Limiting checkpoint size prevents an attacker from filling the account.

Function: update_governance_authority

Description:

  • Updates the governance authority stored in the configuration.

  • Critical for transferring administrative control.

Safety Considerations:

  • Authorization: Must be callable only by the current governance authority.

Function: update_vesting_admin

Description:

  • Updates the vesting administrator.

  • Allows transfer of vesting operational control.

Safety Considerations:

  • Authorization: Access is restricted to authorized parties.

Function: create_stake_account

Description:

  • Creates a new stake account for a user.

  • Initializes stake account metadata and checkpoint data.

Safety Considerations:

  • State Initialization: Correctly sets up user stake and checkpoint state for later operations.

Function: create_checkpoints

Description:

  • Creates and appends a checkpoint entry reflecting the current stake balance.

  • Loads the existing checkpoint data and pushes a new checkpoint.

Safety Considerations:

  • Checkpoint Limits: Verifies that the number of checkpoints does not exceed the configured limit.

  • Account Safety: Uses safe account initialization via anchor's init annotation to avoid state corruption.

Function: delegate

Description:

  • Updates a staker’s delegation to a delegatee.

  • Adjusts checkpoint data for both the previous delegate and the new delegatee.

  • Emits events (DelegateChanged) to signal delegation updates.

Safety Considerations:

  • Checkpoint Boundaries: Enforces limits to prevent account bloat.

  • Balance Validation: Updates both stake and recorded vesting balances carefully to avoid miscounting.

Function: withdraw_tokens

Description:

  • Allows users to withdraw tokens from their stake custody.

  • Updates checkpoint data to reflect a changed balance.

  • Verifies that the withdrawal amount is non-zero and that the destination is controlled by the signer.

Safety Considerations:

  • SPL Token Transfer: Uses the SPL token program with invoke_signed and proper signer seeds.

  • Account Ownership: Checks that the destination account is owned by the signer to prevent unauthorized transfers.

Function: cast_vote

Description:

  • Enables users to cast votes on proposals.

  • Determines voting weight by traversing historical checkpoints within a defined time window.

  • Validates that the vote does not exceed the available weight and updates proposal totals.

Safety Considerations:

  • Historical Integrity: Uses checkpoint history to secure against vote manipulation.

  • Bounds Checking: Thorough arithmetic and bounds checks prevent overflows and replay of stale checkpoints.

  • Data Consistency: Handles transitions between checkpoint accounts safely.

Function: initialize_vesting_config

Description:

  • Initializes vesting configuration (mint, vault, admin, etc.).

Safety Considerations:

  • Access Control: Only authorized (vesting-admin) accounts should perform this operation.

Function: create_vesting_balance

Description:

  • Creates a vesting balance account for a user.

  • Intended to be used when the vesting configuration is not yet finalized.

Safety Considerations:

  • Account Initialization: Ensures that vesting balance accounts are correctly associated and initialized.

Function: finalize_vesting_config

Description:

  • Finalizes the vesting configuration, preventing further vesting account creation or cancellation.

  • Restricted to the vesting admin.

Safety Considerations:

  • Locking Critical State: Once finalized, no further vesting changes are allowed. This is strictly enforced.

  • Privilege Control: Ensures only the vesting admin can finalize to prevent accidental or malicious configuration changes.

Function: create_vesting

Description:

  • Opens a new vesting account and deposits tokens into the vesting vault.

  • Accepts parameters for maturation time and vesting amount.

Safety Considerations:

  • Parameter Validation: Ensures maturation and amount parameters are valid and won’t cause overflow.

  • State Consistency: Must integrate correctly with vesting configuration state (especially in non-finalized mode).

Function: claim_vesting

Description:

  • Allows a user to claim tokens from a vesting account and close it.

  • Emits events to signal vesting balance and delegated vote adjustments.

Safety Considerations:

  • Atomic Claims: Updates vesting state and transfers tokens atomically to prevent double-claims.

  • State Cleanup: Correctly removes vesting accounts to free storage and avoid dangling state.

Function: transfer_vesting

Description:

  • Transfers vesting tokens from one account to another.

  • Updates the stake account metadata and emits events for vesting balance changes.

Safety Considerations:

  • State Synchronization: Both source and destination vesting accounts are updated to avoid fund loss.

  • Arithmetic Safety: Uses safe math and validated state updates.

Function: cancel_vesting

Description:

  • Cancels and closes a vesting account for configurations that are not finalized.

  • Restricted to the vesting admin.

Safety Considerations:

  • Conditional Access: Ensures vesting cancellation is only permitted when configuration is not finalized.

  • Fund Recovery: Must correctly refund any remaining tokens and update state.

Function: withdraw_surplus

Description:

  • Enables the vesting admin to withdraw surplus tokens beyond the total vested amount.

  • Intended to recover tokens that are not allocated to vesting obligations.

Safety Considerations:

  • Privilege Restriction: Only callable by the vesting admin.

  • Amount Validation: Must ensure that withdrawal amounts are correctly computed to avoid draining user funds.

Function: initialize_spoke_message_executor

Description:

  • Sets up the executor for processing cross-chain messages (using Wormhole).

  • Initializes key state variables such as the hub chain ID, spoke chain ID, and Wormhole core program ID.

Safety Considerations:

  • Proper Initialization: Uses bump seeds and strict account derivation to prevent misrouting of messages.

  • Access Control: Only authorized accounts should set up the executor.

Function: receive_message

Description:

  • Processes an incoming Wormhole message.

  • Validates that the message comes from the expected Wormhole (spoke) chain.

  • Iterates over embedded instructions and calls them via invoke_signed with the correct signer seeds.

  • Ensures that lamport usage remains within the allowed maximum and that the payer’s ownership is unchanged after execution.

Safety Considerations:

  • Cost Limitation: Verifies lamport differences to prevent draining the payer’s account.

  • Payload Validation: Checks that the Wormhole chain ID and message payload are as expected to block spoofing.

Function: initialize_spoke_airlock

Description:

  • Initializes the airlock and its self-call counterpart used in cross-chain message execution.

Function: initialize_spoke_metadata_collector

Description:

  • Sets up a metadata collector to receive proposal metadata from the hub chain.

  • Stores details such as the hub chain ID, hub proposal metadata, and Wormhole core program ID.

Safety Considerations:

  • Data Authenticity: Ensures that only messages from legitimate hub sources are recorded.

Function: update_hub_proposal_metadata

Description:

  • Updates the hub proposal metadata stored in the metadata collector.

  • Enforces that either governance or an authorized airlock self-call account may perform the update, based on a configuration flag.

Safety Considerations:

  • Access Verification: Validates the caller’s authority (either governance or via a valid self-call).

  • Data Integrity: Prevents unauthorized modifications that could misdirect proposal data.

Function: relinquish_admin_control_over_hub_proposal_metadata

Description:

  • Permanently disables governance control over updating hub proposal metadata.

  • Shifts control solely to the airlock self-call mechanism.

Function: initialize_vote_weight_window_lengths

Description:

  • Initializes the vote weight window lengths, which are used to determine historical vote weight based on checkpoint data.

  • Sets an initial window length in a dedicated account.

Safety Considerations:

  • State Integrity: Correctly initializes historical data needed for secure vote weight calculations.

  • Boundary Enforcement: Uses safe initialization methods to avoid overflow or misconfiguration.

Function: update_vote_weight_window_lengths

Description:

  • Updates (by appending) the window lengths used in vote weight calculations.

  • Records the new window length along with a timestamp.

Safety Considerations:

  • Bounds Checking: Ensures that new window lengths do not cause account bloat or exceed limits.

Function: post_signatures

Description:

  • Appends guardian signatures to a GuardianSignatures account.

  • Supports multiple invocations if the number of required signatures exceeds what can fit in a single transaction.

Safety Considerations:

  • Authorization: Verifies that the caller (the refund recipient) is authorized to append signatures.

Function: close_signatures

Description:

  • Allows the initial payer to close the GuardianSignatures account if the associated query was invalid.

  • Returns the funds by refunding the payer.

Safety Considerations:

  • Access Restriction: Only callable by the initial payer.

Function: add_proposal

Description:

  • Adds a new proposal after verifying external proposal metadata obtained via a Wormhole query response.

  • Parses the query response, validates the Ethereum call data (including the expected function signature and proposal ID), and updates the proposal state.

  • Emits events (ProposalCreated) on successful addition.

Safety Considerations:

  • Strict Validation: Checks chain IDs, function signatures, and proposal IDs to prevent spoofing.

Zellic © 2025Back to top ↑