XKOVA Docs

Cap Tables and Distributions

Every issued token has a cap table: who holds it and how much. XKOVA rebuilds that cap table from the chain, so it always reflects on-chain reality rather than a hand-kept ledger. From the same cap table you can run a pro-rata distribution that pays holders out of your treasury Safe, without XKOVA ever taking custody of the funds.

The cap table is rebuilt from chain

You never write cap-table rows by hand. XKOVA rebuilds the holders and positions from the token's on-chain balance log. The rebuild is reorg-safe, so a late chain reorganization corrects the projection rather than corrupting it. What you read is a materialized snapshot of that rebuild, tagged with the block it reflects.

  • Summary: total supply, distinct holder count, and the block the snapshot reflects.
  • Holders: one position per holder, largest balance first, with each holder's fraction of total supply. For an ERC1155X share class a position is per (holder, sub-id).
  • Instances: per-instance ownership for an ERC721X or ERC1155X token, one row per (on-chain token id, holder). A fungible ERC20X token has no instance view.

These are authenticated reads, scoped to your workspace. A token outside the workspace returns 404. For the exact response shapes, see the interactive reference.

Freshness: reading as_of_block

The summary read carries as_of_block: the block height the snapshot reflects. A cap table is a read model with an explicit vantage point, not a live on-chain query. A freshly settled transfer, mint, or burn appears shortly after it confirms; until then the snapshot reflects the earlier block.

  • Treat as_of_block as the snapshot's as-of point. If it is lower than the block of a transfer you just settled, re-read after a moment.
  • Holder rows instead carry last_movement_block, the block of that holder's most recent balance change. That is a per-holder field, not the snapshot's as-of point.
  • rebuilt_at is the wall-clock time the snapshot was materialized, useful for display alongside the block height.

Distributions pay holders pro-rata

A distribution splits a single payout amount across the current cap table in proportion to each holder's balance. The payout is denominated in a stablecoin or other ERC-20, not in the asset token itself, so a dividend, interest payment, redemption proceeds, royalty, or capital return all flow as ordinary value to each holder's address.

Distributions run against any token standard. The proportion basis is the holder's balance in that standard: total token balance for a fungible ERC20X, summed balance across sub-ids for an ERC1155X share class (so each holder receives one payout, however many sub-ids they hold), and instance count for an ERC721X collection. In every case the split is pro-rata over the same chain-rebuilt cap table described above.

The flow has two steps on purpose. Creating a distribution freezes the math but moves no money; executing it moves the money out of a treasury Safe you choose.

Step one: create (freeze the math)

You supply the payout token and the total amount. XKOVA snapshots the latest cap table and splits the total across holders by balance. Floor-division dust is assigned to the largest holder so the per-holder payouts sum exactly to the total. The distribution lands in a draft state with its payout set frozen. No transfer is drafted yet.

Step two: execute (pay out of the treasury Safe)

At execute time you choose which workspace treasury Safe funds the payout. The funds are the issuer's own treasury, so the distribution is non-custodial: XKOVA never holds the money. Before any transfer is drafted, every holder is re-screened, and any sanctioned holder's leg is excluded (that payout is marked failed). The remaining clean legs are batched into one N of M treasury transfer (a multiSend), which your existing treasury signers approve and the XKOVA Relayer submits. Each payout flips to settled once the transfer confirms on-chain, and the distribution itself then lands completed.

Execute requires a step-up authenticated session, the token admin role, and that the caller is an active signer of the chosen Safe. It is resumable and idempotent: re-running after the transfer is already drafted returns the current state rather than drafting a second transfer.

End to end

flowchart TD
  A[Mint to holders] --> B[XKOVA observes balances on chain]
  B --> C[Replay rebuilds positions]
  C --> D[Create distribution draft]
  D --> E[Execute, screen and exclude]
  E --> F[Batched multiSend from Safe]
  F --> G[Treasury signers approve]
  G --> H[Relayer submits]
  H --> I[Payouts settled on chain]

Screen and exclude, not block

Sanctions screening at execute time removes a flagged holder's single leg rather than failing the whole distribution. The clean holders still get paid in the same batched transfer; the excluded leg is recorded as failed and surfaces in the payout set. This keeps one bad address from stalling a payout to everyone else.

Related

For the cap-table, distribution create, and execute operations, see the operations list or the interactive reference.