Protocol

Transfer Hook Enforcement

How RegVault enforces compliance at the token layer using Solana's Token-2022 Transfer Hook extension.

Token-Layer Enforcement

Traditional DeFi protocols enforce compliance in the UI or in program instructions. Users can bypass these checks by interacting directly with the chain or using third-party tools.

RegVault takes a different approach: compliance is enforced by the token itself. The rvUSDC share token is a Token-2022 mint with the Transfer Hook extension. Every transfer—regardless of origin—triggers the hook program which validates compliance rules.

Cannot be bypassed

Even if a user constructs a transaction manually, uses a different UI, or calls the token program directly, the Transfer Hook still runs and will reject non-compliant transfers.

How It Works

Extension Setup

When the share mint is created during initialization, it includes the Transfer Hook extension pointing to the share_hook program:

Transfer Hook Extension:
  Program ID: EduibecVcDB9oMp1uUy1WLnYJMGCMHXHwRwi7eSdg9GK
  ExtraAccountMetaList: PDA derived from ["extra-account-metas", mint]

ExtraAccountMetaList

The ExtraAccountMetaList is a PDA that describes additional accounts required for hook execution. RegVault uses the official SPL TLV (Type-Length-Value) account resolution to define these accounts:

Fixed Accounts

  • regvault_program - For account validation
  • vault_config - Policy and roles
  • primary_issuer - Expected attestation signer

Dynamic Accounts (Source Side)

  • source_entity_wallet - PDA derived from token account owner
  • source_attestation - PDA derived from entity and primary issuer

Dynamic Accounts (Destination Side)

  • destination_entity_wallet - Only if not approved venue
  • destination_attestation - Only if not approved venue

Tip

Using SPL TLV account resolution means the Token-2022 program can automatically resolve these PDAs at execution time. No client-side computation is required for standard transfers.

Validation Logic

When a transfer is initiated, the share_hook program executes the following validation:

  1. Load Source Entity Wallet

    Verify the source token account owner has a linked EntityWallet PDA that is active.

  2. Load Source Attestation

    Verify the entity has a valid attestation from the primary issuer that has not expired.

  3. Check Destination

    If destination is an approved venue (e.g., vault escrow), skip entity checks.

  4. Validate Destination Entity (if needed)

    For non-venue destinations, repeat entity wallet and attestation validation.

Blocked Transfer Examples

The following transfer attempts will fail at the token layer with clear error messages:

Unknown Wallet

Attempting to transfer to a wallet that is not linked to any entity:

Transfer blocked: wallet is not allowlisted

Expired Attestation

Source entity has an attestation, but it has expired:

Transfer blocked: attestation expired

Inactive Entity

Entity exists but has been suspended or revoked:

Transfer blocked: attestation inactive

Invalid Issuer

Attestation was signed by an issuer not in the allowed list:

Transfer blocked: invalid attestation issuer

Remaining Accounts in CPI

For instructions that CPI into the Token-2022 program (like request_withdraw and cancel_withdraw), the regvault program forwards remaining accounts to satisfy the hook requirements:

request_withdraw CPI flow:
  1. User calls regvault.request_withdraw
  2. Program builds TransferChecked instruction
  3. Program appends hook accounts (EntityWallet, Attestation PDAs)
  4. CPI invokes Token-2022 with extended account list
  5. Token-2022 calls share_hook.execute with all accounts
  6. Hook validates and returns, transfer completes

Warning

If the remaining accounts are not provided, the transfer will fail with MissingHookAccounts. The SDK automatically handles this for standard operations.

Debugging Hook Failures

The dashboard provides real-time Transfer Hook health status. If wiring is broken:

  • Verify share mint has Transfer Hook extension: spl-token display <mint>
  • Check ExtraAccountMetaList exists: solana account <pda>
  • Confirm hook program ID matches configuration
  • Use the Operator Demo panel to test failure scenarios