Role Definitions
| Role | How identified |
|---|---|
| Sender | hash160(pubkey) == senderHash compiled into bytecode |
| Authority | hash160(pubkey) == authorityHash compiled into bytecode |
| Recipient | hash160(pubkey) == recipient_hash from NFT commitment |
| Vault Signer | hash160(pubkey) matches one of the stored vault signer hashes |
| M-of-N Signers | required signer subset validated by the treasury covenant |
| All N Signers | every registered signer participates in the same transition |
| Permissionless | any caller may submit the valid transaction when contract conditions are met |
Streaming Covenants
| Function | VestingCovenant | RecurringPaymentCovenant |
|---|---|---|
claim() | Recipient | — |
pay() | — | Permissionless |
complete() | Permissionless after end | — |
pause() | Sender | Sender |
resume() | Sender | Sender |
cancel() | Sender if cancelable | Sender if cancelable |
transfer() | Recipient if transferable | — |
refill() | — | Sender |
Distribution Covenants
| Function | Airdrop | Grant | Bounty | Reward |
|---|---|---|---|---|
claim() | Permissionless submission with claim-authority co-sign | — | Authority co-sign | — |
releaseMilestone() | — | Authority | — | — |
reward() | — | — | — | Authority |
pause() | Authority | Authority | Authority | Authority |
resume() | Authority | Authority | Authority | Authority |
cancel() | Authority if cancelable | Authority if cancelable | Authority if cancelable | Authority if cancelable |
transfer() | — | Recipient if transferable | — | — |
Treasury Covenants
| Function | VaultCovenant | ProposalCovenant |
|---|---|---|
spend() | M-of-N vault signers | — |
unlockPeriod() | any single vault signer | — |
approve() | — | registered vault signer |
execute() | — | permissionless after timelock |
cancel() | — | M-of-N vault signers |
expire() | — | permissionless after deadline |
pause() | any single vault signer | — |
resume() | M-of-N vault signers | — |
emergencyLock() | all registered signers | — |
Governance Covenants
| Function | VoteLockCovenant |
|---|---|
reclaim() | voter after unlockTimestamp |
earlyReclaim() | voter after final proposal state is known |
What the Backend Cannot Do
The backend API, indexer, and executor do not get special contract privileges. They cannot:- spend from a covenant without the right signer set
- override caps, schedules, or allowlists
- cancel non-cancelable state
- redirect payouts to unauthorized recipients

