Skip to Content
Program ReferencePrivacy (FHE)

Privacy (FHE) Instructions

Veil’s privacy layer uses Fully Homomorphic Encryption (FHE) via Encrypt . Privacy is opt-in per position. The plaintext UserPosition is never removed — it remains the authoritative source for health factor enforcement.

Implementation status: The Encrypt SDK (encrypt-pinocchio) currently targets pinocchio 0.10.x. Veil’s program uses 0.11.x. All five private instructions are fully implemented and routed. The FHE graph execution CPI (execute_graph) is stubbed and will activate when the SDK ships the version update.

Encrypt program ID (devnet): 4ebfzWdKnrnGseuQpezXdG8yCdHqwQ1SSBHD3bWArND8

EncryptedPosition Account

Discriminator: VEILENC! · Size: 144 bytes

OffsetSizeFieldDescription
08discriminatorVEILENC!
832ownerUser wallet
4032poolAssociated lending pool
7232enc_depositPubkey of the EUint64 ciphertext for deposit balance
10432enc_debtPubkey of the EUint64 ciphertext for debt balance
1361bumpPDA bump
1377_pad

PDA: seeds ["enc_pos", user, pool]

The ciphertext account pubkeys are opaque 32-byte handles. To any RPC observer the position reveals nothing about the amounts. Only the position owner (with their FHE secret key) can decrypt.


EnablePrivacy

Discriminator: 0x08 (8)

Create an EncryptedPosition for an existing UserPosition. Initialises two ciphertext accounts (enc_deposit, enc_debt) seeded with the current plaintext values.

Accounts

#NameFlagsDescription
0usersigner, writable
1user_positionreadonlyMust already exist
2encrypted_positionwritableNew PDA — seeds: ["enc_pos", user, pool]
3enc_deposit_ctwritableNew EUint64 ciphertext account (Encrypt program)
4enc_debt_ctwritableNew EUint64 ciphertext account (Encrypt program)
5poolreadonly
6encrypt_programreadonlyEncrypt program

Instruction Data

OffsetSizeField
01discriminator 0x08
11enc_position_bump

PrivateDeposit

Discriminator: 0x09 (9)

Identical to Deposit plus an FHE add_deposit computation on enc_deposit.

Accounts

#NameFlagsDescription
0usersigner, writable
1user_tokenwritableSource token account
2vaultwritablePool vault
3poolwritable
4user_positionwritablePlaintext position (updated)
5encrypted_positionwritable
6enc_deposit_ctwritableEUint64 deposit ciphertext (updated)
7amount_ctwritableFresh EUint64 holding the plaintext amount
8system_programreadonly
9token_programreadonly
10encrypt_programreadonly

Instruction Data

OffsetSizeField
01discriminator 0x09
18amount (u64 LE)
91position_bump

PrivateBorrow

Discriminator: 0x0A (10)

Borrow tokens (same checks as Borrow) plus FHE add_debt on enc_debt.

Instruction Data

OffsetSizeField
01discriminator 0x0A
18amount (u64 LE)

PrivateRepay

Discriminator: 0x0B (11)

Repay debt (same as Repay) plus FHE sub_debt on enc_debt.

Instruction Data

OffsetSizeField
01discriminator 0x0B
18amount (u64 LE)

PrivateWithdraw

Discriminator: 0x0C (12)

Withdraw deposit (same as Withdraw) plus FHE sub_deposit on enc_deposit.

Instruction Data

OffsetSizeField
01discriminator 0x0C
18shares (u64 LE)

Privacy Model

┌──────────────────────────────────────────────────────────┐ │ What is on-chain │ │ │ │ UserPosition.deposit_shares ← plaintext (authoritative)│ │ UserPosition.borrow_principal← plaintext (authoritative)│ │ │ │ EncryptedPosition.enc_deposit ← opaque 32-byte pubkey │ │ EncryptedPosition.enc_debt ← opaque 32-byte pubkey │ │ │ │ ciphertext account (Encrypt) ← FHE-encrypted amount │ └──────────────────────────────────────────────────────────┘

Health factor checks always use the plaintext UserPosition. The encrypted ciphertexts provide observer confidentiality — an RPC caller cannot infer position size from on-chain data. The protocol itself never operates on encrypted values for solvency decisions.

Last updated on