Assessment reports>Penumbra>Threat Model>Action: SwapClaim

Action: SwapClaim

A SwapClaim action redeems the assets that were swapped by a Swap action in an earlier block as notes (which can be spent with a Spend action in a subsequent block).

A SwapClaim action contains a nullifier, a transparent fee, two commitments to note ciphertexts, a BatchSwapOutputData struct, a zero-knowledge proof, and an epoch duration. A BatchSwapOutputData struct contains a trading pair that mentions which assets were swapped, input amounts , aggregated amounts swapped from the corresponding Swap's block , and aggregated unfilled amounts from the corresponding Swap's block , a block height, and an epoch height.

SwapClaim::check_stateless verifies the zero-knowledge proof, which enforces that

  • the swap plaintext provided as a witness matches the swap commitment provided as another witness.

  • the swap commitment is present in the state commitment tree.

  • the nullifier was computed correctly.

  • the transparent fee matches the one in the swap plaintext.

  • the output data's block height is equal to the sum of the output data's epoch height and the epoch-relative block height (from the SCT proof).

  • the output data's trading pair matches the one in the swap plaintext.

  • the amounts attempting to be claimed are equal to the fraction of the aggregated swaps corresponding to this swap plaintext's amounts.

  • the note commitments are correctly computed for notes with the current claimed values, with blinding factors provided as witnesses.

SwapClaim::check_stateful checks that

  • the epoch duration provided in the SwapClaim matches the state's epoch duration parameter (although the SwapClaim's epoch duration appears otherwise unused).

  • the provided BatchSwapOutputData matches the state's records for the corresponding block height.

  • the nullifier is unspent.

SwapClaim::execute records

  • the note commitments to the SCT

  • the note positions and commitments to the compact block

  • the nullifier to the spent nullifier set

To avoid the potential TOCTOU issue () regarding duplicate nullifier spends in the same transaction, Transaction::check_stateless's no_duplicate_spends checks that all nullifiers are unique within a transaction.

Zellic © 2025Back to top ↑