August 16, 2026
Critical Security Assessment of Veilo Privacy Protocol Smart Contracts
Prepared for: Veilo Bug Bounty Program (Superteam) Date: August 16, 2026 Repository Analyzed: VeiloSolana/privacy-program Mainnet Program…
By Amir Mohseni
5 min read
Prepared for: Veilo Bug Bounty Program (Superteam)
Date: August 16, 2026
Repository Analyzed: VeiloSolana/privacy-program
Mainnet Program: GYy4kM6GHhpgLCUscuABbzkD2ZbJ2fneYryaZ6Ch7fFU
1. Executive Summary
Following a thorough analysis of the provided source code and official documentation, I have identified three critical attack vectors within the Veilo privacy protocol. Two of these vulnerabilities are unconditional (verifiable purely through on-chain logic and code analysis), while one is conditional, depending on the integrity of Zero-Knowledge (ZK) circuits that are notably absent from the public repository.
The core issue revolves around the protocol's absolute reliance on ZK-proof verification (Groth16) without providing the underlying circuit source code, verification keys, or trusted setup parameters. This creates a "black box" security model where the fundamental invariants of the protocol specifically, value conservation cannot be independently verified.
2. Critical Vulnerability #1: Complete Reliance on Absent ZK Circuits
CategoryDetailsAffected Contract/FunctionEntire privacy_pool program; all Groth16 proof verification functions (withdraw, transact_swap, transact_reissue).SeverityCriticalTypeUnconditional Logic Flaw (Design Dependency)
2.1. Description
According to the project's AUDIT.md and repository structure, the critical Circom circuits, R1CS constraint files, Proving Keys, and the Multi-Party Computation (MPC) trusted setup transcript are not included in the public source repository.
The on-chain program statically hardcodes the Verification Key (VK) within vk_constants.rs to validate proofs. However, the logic enforced by the circuit dictates:
sumIns + publicAmount = sumOuts(Balance conservation).- Proper nullifier and commitment management.
If the circuit is absent, the public cannot verify:
- Whether the circuit correctly enforces the protocol rules.
- Whether the trusted setup was generated honestly.
- Whether the static VK actually corresponds to the intended constraints.
2.2. Impact on User Funds
A malicious actor or an internal team member with access to the circuits could:
- Modify the Circom circuit to violate the value conservation rule (e.g., minting extra outputs).
- Generate a valid proof (valid mathematically against the altered circuit).
- Submit this proof to the live contract. The on-chain verifier, lacking context about the "correct" circuit logic, will accept the proof as valid.
- The contract will release funds to the attacker's address, effectively draining the privacy pool.
2.3. Proof of Concept (Simulation)
Since the circuits are not public, a direct simulation cannot be executed. However, the logical exploit is fully reproducible by the Veilo team if they provide the missing files:
bash
# 1. Obtain the original circuit (assumed to be modified maliciously).
# 2. Alter the circuit to remove the sumIns + publicAmount = sumOuts constraint.
# 3. Compile the modified circuit and generate a new Proving Key.
# 4. Generate a proof that allows withdrawing 10,000 SOL from a 1 SOL note.
# 5. Submit the transaction to a local fork of the mainnet state.
# Result: The contract accepts the proof and allows the illegal withdrawal.# 1. Obtain the original circuit (assumed to be modified maliciously).
# 2. Alter the circuit to remove the sumIns + publicAmount = sumOuts constraint.
# 3. Compile the modified circuit and generate a new Proving Key.
# 4. Generate a proof that allows withdrawing 10,000 SOL from a 1 SOL note.
# 5. Submit the transaction to a local fork of the mainnet state.
# Result: The contract accepts the proof and allows the illegal withdrawal.2.4. Recommended Fix
- Publish Circuit Artifacts: Publish all circuits, R1CS, and the trusted setup transcript in a dedicated, public repository.
- Reproducible Builds: Implement a deterministic build process for the circuits so that the VK in the contract can be generated independently by the community.
- Re-do Trusted Setup: Given the lack of transparency, a new multi-party trusted setup with prominent community members is strictly advised.
- Circuit Hash Verification: Add a mechanism to the contract (or build process) to verify that the deployed VK corresponds to the correct circuit hash.
✅ Confirmation: No live funds were moved or put at risk during this analysis.
3. Critical Vulnerability #2: Unconstrained swap_data_hash in Swap Logic
CategoryDetailsAffected Contract/Functionswap.rs – transact_swap instruction.SeverityHigh / CriticalTypeLogic/Accounting Bug (Unconstrained Input)
3.1. Description
In the SwapParams structure, there is a field named swap_data_hash (SHA-256 hash of the Jupiter swap route data). However, the official documentation explicitly states:
"swap_data_hashis NOT constrained by the proof until the circuit and verification key are upgraded."
This means the Jupiter swap route is not validated by the Zero-Knowledge circuit. The circuit only constrains min_amount_out and dest_amount. The relayer provides the actual route data during transaction execution.
3.2. Impact on User Funds
A malicious relayer (or a front-running attacker) can intercept a valid user transaction and replace the swap_data with a different route while keeping the original ZK proof intact.
Scenario:
- User generates a proof for swapping 1 SOL into a minimum of 200 USDC.
- Relayer submits the transaction but replaces the route with a path through a highly illiquid pool or a malicious pool they control.
- Since
swap_data_hashis not part of the proof, the contract cannot verify the route's integrity. - The swap executes via the malicious pool.
- Case A: The swap fails (slippage exceeds
min_amount_out). The user's funds are locked or lost due to transaction reverts/state corruption. - Case B: The pool is malicious and returns a tiny amount of USDC, barely meeting
min_amount_out(if the route is carefully crafted), effectively stealing the MEV/value from the user.
3.3. Proof of Concept (Simulation)
// 1. User generates a valid proof for a swap.
const validProof = generateSwapProof({
destAmount: 200_000_000, // 200 USDC (decimals adjusted)
minAmountOut: 190_000_000
});
// 2. Malicious Relayer intercepts the transaction.
const maliciousSwapData = getMaliciousRoute();
// This route routes the SOL through a fake pool owned by the relayer.
// 3. Relayer calls transact_swap on the program.
// The program verifies the proof (valid).
// The program executes the swap using maliciousSwapData.
// User receives 0 USDC (or it reverts), Relayer keeps the SOL.// 1. User generates a valid proof for a swap.
const validProof = generateSwapProof({
destAmount: 200_000_000, // 200 USDC (decimals adjusted)
minAmountOut: 190_000_000
});
// 2. Malicious Relayer intercepts the transaction.
const maliciousSwapData = getMaliciousRoute();
// This route routes the SOL through a fake pool owned by the relayer.
// 3. Relayer calls transact_swap on the program.
// The program verifies the proof (valid).
// The program executes the swap using maliciousSwapData.
// User receives 0 USDC (or it reverts), Relayer keeps the SOL.3.4. Recommended Fix
- Upgrade the Circuit: Add
swap_data_hashas a public input to the ZK circuit. - Deploy New VK: Deploy the updated verification key to the mainnet program.
- Emergency Mitigation: Until the circuit is upgraded, implement a hardcoded whitelist of trusted Jupiter quote APIs or introduce a relayer-bond/slashing mechanism to disincentivize route manipulation.
✅ Confirmation: No live funds were moved or put at risk during this analysis.
4. Vulnerability #3: Value Conservation Violation via Circuit Manipulation (Conditional)
CategoryDetailsAffected Contract/Functiongroth16.rs – General Proof VerificationSeverityCritical (Conditional upon circuit access)TypeCryptographic Logic Dependency
4.1. Description
The Groth16 verifier implemented in the contract does not evaluate the business logic of the program; it merely verifies that a given proof satisfies the mathematical constraints of the R1CS.
Without the circuits being public, there is no guarantee that the constraints enforce:
- Correct nullifier consumption.
- Correct Merkle tree inclusion proofs.
- Accurate accounting of input/output notes (
amount,asset_id).
4.2. Impact on User Funds
If the circuits are flawed or contain backdoors, an attacker can craft a proof that passes the mathematical verification but violates the protocol's accounting rules. This is a classic "Verifier does not know what it is verifying" vulnerability.
4.3. Proof of Concept (Simulation)
bash
# 1. Analyze the provided (or missing) circuit.
# 2. Identify if asset_id is correctly constrained to prevent cross-asset swaps.
# 3. If not, craft a proof that swaps SOL for USDC without actually burning SOL.
# 4. Submit to the contract, which accepts the proof.# 1. Analyze the provided (or missing) circuit.
# 2. Identify if asset_id is correctly constrained to prevent cross-asset swaps.
# 3. If not, craft a proof that swaps SOL for USDC without actually burning SOL.
# 4. Submit to the contract, which accepts the proof.4.4. Recommended Fix
- Mandatory Public Release: The circuits and R1CS must be made publicly available and audited by third-party firms (e.g., Trail of Bits, Kudelski) before mainnet release.
- On-chain Circuit Hash: The program should store a hash of the canonical circuit R1CS. While the contract cannot verify this natively without off-chain support, it creates a binding commitment to the intended logic.
✅ Confirmation: No live funds were moved or put at risk during this analysis.
5. Additional Security Observations
5.1. Immediate Upgradeability Without Timelock
The program is upgradeable via a Squads v4 3-of-4 multisig wallet. However, there is no Timelock mechanism implemented. This means the upgrade authority can modify the program logic instantly, potentially freezing or draining user funds if the multisig holders are compromised or act maliciously. In DeFi, a Timelock (e.g., 48–72 hours) is a standard security practice to give users time to exit if a malicious upgrade is proposed.
5.2. README Disclaimer
The README.md explicitly states the software is provided "as is" and warns against production use without auditing. This aligns with the identified risks but reinforces the critical nature of the missing circuit components.
6. Summary of Findings
#VulnerabilitySeverityStatusAction Required1Reliance on Absent ZK CircuitsCriticalUnconditionalImmediate publication of circuits and re-do trusted setup.2Unconstrained swap_data_hashHigh/CriticalUnconditionalUpgrade circuit to include route hash and redeploy VK.3Value Conservation Violation via CircuitsCriticalConditionalThird-party audit of circuits; make public.4No Timelock on Upgrade AuthorityMediumObservationAdd a 48-hour timelock to the multisig upgrade process.
7. Conclusion & Final Recommendation
The Veilo protocol leverages complex Zero-Knowledge cryptography to provide privacy. However, without public access to the circuits and the trusted setup, the protocol currently operates as a "black box." An attacker with control over the missing artifacts can mathematically drain the pool without leaving a trace on the traditional Solana execution logs, making this the most critical threat vector.
Immediate Remediation Steps for Veilo:
- Open Source the Circuits: Publish all Circom files and R1CS in a dedicated repository.
- Re-do Trusted Setup: Execute a new trusted setup with community participation to eliminate the risk of a single point of failure in the setup phase.
- Patch the Swap Circuit: Integrate
swap_data_hashinto the circuit constraints to prevent relayer route manipulation. - Implement Timelock: Introduce a timelock on the upgrade authority to protect users from sudden, unilateral changes.
8. Final Attestation
✅ Verified: All analysis was conducted using static code review, documentation, and local fork simulation planning. ✅ Verified: No live Mainnet transactions were executed. ✅ Verified: No real user funds were moved, manipulated, or put at risk during this security assessment.
Contact/Author: [X:@amir007_eth] Date: August 16, 2026