Skip to content

State and Trackers

The Zink Bridge is stateful. Every transfer is recorded as entries inside tracker accounts on both chains, with per-entry status fields, authority vote maps, and finalization cursors that make the full protocol lifecycle queryable over standard RPC.

Primary on-chain accounts

Bridge

The Bridge account is the per-chain-pair configuration root, derived with seeds ["bridge", chain_id].

FieldTypePurpose
bumpu8PDA bump seed
other_chain_idChainId (u16)Identifies the paired chain
native_vault_addressPubkeyVault for native token operations
update_nonceUpdateNonce (u64)Monotonic nonce for AuthProposal sequencing
thresholdU0F64Fixed-point 0.0–1.0 voting threshold; required weight = ceil(total_weight × threshold)
total_authority_weightWeightVal (u64)Sum of all registered authority weights
fee_definitionFeeDefinitionflat_fee + other_chain_token_account_rent
fee_targetPubkeyDestination for collected fees
other_chain_nameUnsizedStringHuman-readable name of the paired chain
authoritiesMap<Pubkey, BridgeAuthority>Each authority has a weight (u64) and index (u16)
other_chain_mintsMap<OtherChainMint, ThisChainMint>Reverse lookup from other-chain mint to this-chain mint
token_pairsMap<ThisChainMint, TokenPair>Forward lookup keyed by this-chain mint

TokenPair fields

FieldTypePurpose
other_chain_mintKeyFor<OtherChainMint>Mint address on the paired chain
token_vaultKeyFor<TokenAccount>Vault holding escrowed tokens (for Vault mode)
pending_entriesu64Count of in-flight entries for this pair
own_mint_typeOwnMintTypeVault (lock/release) or MintBurn (burn/mint)
import_limitTokenBridgeLimitRate limit for tokens bridged to this chain
export_limitTokenBridgeLimitRate limit for tokens bridged from this chain
limit_authorityOptionalPubkeyKey that can adjust limits without a full proposal
frozenboolWhen true, all operations on this pair are blocked
freeze_authorityOptionalPubkeyKey that can toggle the frozen flag

TokenBridgeLimit fields

FieldTypePurpose
limitSubTokensValMaximum token volume per period
period_durationSecondsValLength of each rate-limit window in seconds
period_startSecondsValUnix timestamp when the current period began
total_for_periodSubTokensValVolume consumed in the current period

Available capacity is limit − total_for_period. The period resets automatically when period_duration elapses.

Fee model

The total fee charged to a depositor is:

flat_fee + other_chain_token_account_rent + rent_for(DepositEntry + TokenAccountData)

At cleanup, a partial refund is returned. The refund depends on whether the destination-chain token account was actually created and whether the source-chain ATA was created during the deposit. If neither was created, the corresponding rent portions are refunded.

DepositTracker

The DepositTracker lives on the source chain, derived with seeds ["deposit", bridge].

FieldTypePurpose
bridgeKeyFor<Bridge>Back-reference to the parent bridge
other_chain_idChainIdPaired chain identifier
entry_countEntryIdVal (u64)Total entries ever appended
next_finalized_entryEntryIdValCursor: entries before this index are finalized
auth_votesAuthVoteMapPer-authority vote tracking
entriesList<DepositEntry>Append-only list of deposit entries

DepositEntry fields

FieldTypePurpose
refund_toPubkeyAddress that receives fee/token refunds at cleanup
destinationPubkeyAddress on the destination chain to receive tokens
mintKeyFor<ThisChainMint>Token mint on this (source) chain
other_chain_mintKeyFor<OtherChainMint>Token mint on the destination chain
amountSubTokensValAmount deposited
min_amountSubTokensValMinimum acceptable amount at destination
cleanup_completedboolSet to true after cleanup_deposit runs
statusDepositStatusCurrent lifecycle status

WithdrawTracker

The WithdrawTracker lives on the destination chain, derived with seeds ["withdraw", bridge].

FieldTypePurpose
bridgeKeyFor<Bridge>Back-reference to the parent bridge
other_chain_idChainIdPaired chain identifier
entry_countEntryIdValTotal entries ever appended
next_finalized_entryEntryIdValCursor: entries before this index are finalized
auth_votesAuthVoteMapPer-authority vote tracking
cleanup_trackerWithdrawCleanupTrackerPer-authority rent accounting for cleanup
entriesList<WithdrawEntry>Append-only list of withdraw entries

WithdrawEntry fields

FieldTypePurpose
source_chain_mintKeyFor<OtherChainMint>Mint on the source chain
destination_chain_mintKeyFor<ThisChainMint>Mint on this (destination) chain
destinationPubkeyAddress to receive withdrawn tokens
amountSubTokensValAmount to withdraw
statusWithdrawStatusCurrent lifecycle status

WithdrawCleanupTracker

Tracks per-authority cleanup state within the WithdrawTracker:

FieldTypePurpose
authoritiesMap<Pubkey, WithdrawCleanupInfo>Per-authority tracking

Each WithdrawCleanupInfo contains next_finalized_entry (the authority's cleanup cursor) and owed_rent (accumulated rent owed to the authority for accounts created during ack_deposit).

AuthProposal

AuthProposal is the governance mechanism for bridge configuration changes.

FieldTypePurpose
rent_toPubkeyReceives rent refund when proposal is closed
chain_idChainIdWhich bridge this proposal targets
proposerPubkeyAuthority that created the proposal
update_nonceUpdateNonceMust match the bridge's current nonce (prevents stale proposals)
statusProposalStatusBuilding, Voting, Accepted, or Canceled
vote_weightWeightValAccumulated vote weight
vote_resultVoteResultCurrent vote tally
proposal_itemsUnsizedList<AuthProposalItem>List of configuration changes

AuthProposalItem variants

VariantPurpose
ChangeThresholdSet a new voting threshold (U0F64)
AddAuthorityRegister a new authority with a given weight
RemoveAuthorityRemove an existing authority
ModifyAuthorityChange an authority's weight
AddTokenPairRegister a new bridgeable token pair
ModifyTokenPairUpdate parameters on an existing pair (cannot change mints)
RemoveTokenPairRemove a token pair (requires pending_entries == 0)

A proposal moves through BuildingVotingAccepted (or Canceled). During Building, the proposer can add items. During Voting, authorities cast weighted votes. Once threshold is met, the proposal is applied atomically to the Bridge account and the update_nonce increments.

Status enums

DepositStatus

VariantFieldsMeaning
InitializedDeposit created, awaiting authority acknowledgement
Votingproposed: DepositResult, yes: WeightVal, no: WeightValAuthorities are voting on the result (during ack_withdraw)
Finalizedresult: DepositResultThreshold reached; result is locked

WithdrawStatus

VariantFieldsMeaning
Votingyes: WeightVal, no: WeightValAuthorities are voting (during ack_deposit)
Finalizedresult: DepositResultThreshold reached; withdraw is executable if result is Confirmed

DepositResult

VariantFieldsMeaning
Confirmedamount: SubTokensVal, created_token_account: CreatedTokenAccountTransfer approved; specified amount will be released/minted
Rejectedreason: DepositRejectionReasonTransfer denied; tokens will be refunded at cleanup

CreatedTokenAccount is an enum with variants Pending, True, and False, tracking whether a destination token account was created as part of the bridge operation. This affects fee refund calculations at cleanup.

DepositRejectionReason

VariantMeaning
InternalErrorAn unexpected error occurred during processing
InsufficientFundsThe vault or mint lacks sufficient balance
LimitExceededThe token pair's rate limit would be exceeded
TokenPairFrozenThe token pair is currently frozen
TokenPairNotFoundNo matching token pair exists on the destination chain

Why the tracker model matters

The tracker model gives operators and integrators concrete on-chain state to answer operational questions:

QuestionWhere to look
Has the deposit been created?DepositTracker.entries[id].status == Initialized
Has authority threshold been reached on the destination?WithdrawTracker.entries[id].status == Finalized
Was the deposit confirmed or rejected?WithdrawTracker.entries[id].status.result
Is withdraw executable?Finalized + DepositResult::Confirmed
Has the source-side been finalized?DepositTracker.entries[id].status == Finalized
Is cleanup safe to run?DepositTracker.entries[id].status == Finalized && !cleanup_completed

Upstream-compatible

These are ordinary Solana accounts queried over standard RPC with getAccountInfo and deserialized with the bridge program's layout. The bridge-specific aspect is the voting lifecycle and status model, not the underlying account mechanics.

Zink is a general-purpose SVM network for programs, operators, and bridge integrations.