Operations
Role-based workflows, entity onboarding, withdrawal management, and audit with receipts.
Role Matrix
RegVault uses a role-based access control system with four distinct roles. Each role has specific permissions for different operations.
| Action | Admin | Compliance | Operator | Emergency |
|---|---|---|---|---|
| Initialize Vault | ✓ | — | — | — |
| Set Roles / Policy | ✓ | — | — | — |
| Pause Operations | ✓ | — | — | ✓ |
| Unpause Operations | ✓ | — | — | * |
| Create Entity | — | ✓ | — | — |
| Set Entity Status | — | ✓ | — | — |
| Link/Unlink Wallets | ✓ | ✓ | — | — |
| Approve Withdraw | — | ✓ | ✓ | — |
| Execute Withdraw | — | ✓ | ✓ | — |
* Emergency admin can unpause only if allow_emergency_unpause is set to true.
Entity Onboarding Flow
Before a wallet can deposit or receive shares, it must complete the onboarding flow:
Create Entity
Compliance creates an Entity PDA with a unique entity_id, tier, jurisdiction, and metadata hash. Entity status is initially Active.
create_entity(entity_id, tier, jurisdiction_code, metadata_hash)Wallet Claims Entity
The wallet owner signs a transaction to claim their wallet for the entity. This creates an EntityWallet PDA linking the wallet to the entity.
claim_wallet(entity)Issuer Signs Attestation
An allowed issuer (typically the primary issuer) creates an attestation certifying the entity meets compliance requirements. This includes tier, jurisdiction, expiry, and a claim hash.
upsert_entity_attestation(entity, tier, jurisdiction, expires_at, claim_hash)Success
Venue Wallet Linking
For approved venues (e.g., custody providers, exchanges), compliance can directly link wallets without requiring the venue to claim:
link_venue_wallet(entity, wallet_pubkey)Venue wallets bypass attestation requirements in the Transfer Hook. This enables shares to be transferred to approved custody venues even if the venue itself doesn't have an entity attestation.
Withdrawal Workflow
Phase 1: Request
An eligible user initiates a withdrawal by requesting to redeem shares for underlying USDC:
- User specifies shares to redeem and expected USDC amount
- Shares are transferred to vault escrow (Transfer Hook validates)
- WithdrawRequest PDA is created with unique request_id
- Timelock is set based on vault configuration
- Required approvals determined by amount threshold
Phase 2: Approval
Operator and/or Compliance review and approve the request:
- Approvals tracked via bitmap in the WithdrawRequest
- Operator approval sets bit 0b01
- Compliance approval sets bit 0b10
- Duplicate approvals from same role rejected
- Small withdrawals may only need 1 approval; larger need 2
Note
Phase 3: Execution
After sufficient approvals and timelock expiry, the withdrawal is executed:
- Operator or Compliance calls execute_withdraw
- Program verifies timelock has expired
- Shares burned from escrow
- USDC transferred to destination token account
- Immutable Receipt PDA created
- Request status updated to Executed
Immutable Receipts
Every executed withdrawal creates a Receipt PDA that serves as permanent audit evidence:
Receipt Schema
| request_id | Unique withdrawal identifier |
| entity | Entity that initiated the withdrawal |
| wallet | Requester wallet address |
| amount | USDC amount transferred |
| timestamp | Unix timestamp of execution |
| policy_version | Policy version at time of execution |
| attestation_issuer | Expected issuer at time of execution |
| destination | USDC destination token account |
Policy Version Snapshots
The WithdrawRequest captures a snapshot of policy_version and attestation_issuer at the time of request creation. The Receipt preserves these values at execution. This ensures audit trails remain accurate even if policies change later.