PERK.FUND
Executive Summary
PERK is a permissionless perpetual futures protocol on Solana, enabling leveraged trading on any SPL token via a virtual AMM (vAMM) model ported from Anatoly Yakovenko's Percolator risk engine. The protocol consists of a Rust/Anchor smart contract (~5,800 LOC), a TypeScript SDK (~2,600 LOC), off-chain cranker bots for funding rates and trigger order execution, and a Next.js frontend hosted on Vercel. The $PERK token (F8Pz2mx7V8exRkBNFzvpkZAwjNPxWPGqzYJL2ckrpump) is a Token2022 pump.fun token with both mint and freeze authorities permanently revoked.
The smart contract code is technically strong. The codebase uses Kani formal verification with 10 proof suites running in CI — this is real, verifiable, and rare in DeFi. It also includes fuzz testing and maintains overflow-checks=true in release builds. All arithmetic on security-critical paths uses checked operations, with U256/I256/U512 wide math for intermediate products. The conservation invariant (vault balance >= total deposited capital + insurance + fees) is enforced at the end of most state-changing instructions. The risk engine implements defense-in-depth through warmup windows, haircut ratios, insurance fund epoch caps, oracle circuit breakers, per-update price banding, and sliding window bands.
However, a significant trust concern was identified: the project's audits/ folder contains 53 files named after recognized security firms — "pashov-review-round1.md", "apex-red-team-round1.md", etc. — but every single file is an AI-generated self-review authored by "Kai (AI Security Auditor)" and similar AI agents. No verified third-party security audit reports exist in the repository. The "OtterSec verified" claim in the README refers to Solana build verification (confirming bytecode matches source), not an OtterSec security audit engagement. This misrepresentation of audit provenance is misleading to users evaluating the project's security posture.
No critical findings were identified. One high-severity finding was identified: the project actively misrepresents its audit history by claiming OtterSec verification in the README, SECURITY.md, and on-chain security_txt, while naming 53 AI-generated self-reviews after real firms (Pashov, Apex). This is not a passive oversight — it is active deception that influences user trust and investment decisions. The three medium findings are infrastructure-level: (1) the frontend's Content-Security-Policy allows unsafe-inline and unsafe-eval, weakening XSS protection; (2) the on-chain program is upgradeable by a single EOA wallet without a timelock or multisig; and (3) the Helius RPC API key is exposed in client-side requests. The low findings — assert!() panics in the risk engine and saturating arithmetic in margin calculations — are minor inconsistencies in an otherwise rigorously defensive codebase.
On the token side (informational, not scored): the $PERK token has 1,792 holders. 30% of supply is locked in Streamflow vesting contracts created by the deployer. Bundle activity was detected at launch — approximately 18.7% of supply was captured by coordinated wallets within the first 3 minutes, with a common funding source identified across multiple clusters. The deployer currently holds 1.70% of supply. These are standard pump.fun launch dynamics and do not reflect on the security of the protocol's code or infrastructure.
Rug Risk Assessment
Audit Scope
| Scope Item | Status | Notes |
|---|---|---|
| Source code review | complete | Full review of 47 Rust files (~5,800 LOC) and 8 TypeScript SDK files (~2,600 LOC). All instructions, engine modules, state accounts, and tests analyzed. |
| Smart contract vulnerability scan | complete | 16-point Solana security checklist completed. Signer checks, owner checks, PDA validation, arithmetic safety, CPI safety, reinitialization, cosplay, overflow — all verified. |
| Business logic review | complete | vAMM mechanics, risk engine (Percolator port), funding rate, liquidation, warmup, trigger orders, fee flows — all reviewed for correctness and edge cases. |
| Dependency audit | complete | Cargo.toml reviewed. 6 dependencies — all standard Solana/Anchor ecosystem. No known vulnerabilities, no suspicious crates. overflow-checks=true in release profile. |
| Build verification | limited | Static build analysis — Anchor.toml, Cargo.toml, rust-toolchain (1.89.0), CI/CD (Kani + Sec3 X-ray). Compilation not possible without deployer keypair and environment (expected for third-party audits). |
| Existing audit review | complete | 53 audit documents in audits/ folder — ALL are AI-generated self-reviews by 'Kai (AI Security Auditor)' and similar AI agents. Files are misleadingly named after real firms (pashov-review-round1.md, apex-red-team-round1.md). No verified third-party audit PDFs exist. 'OtterSec verified' in README is build verification (bytecode match), not a security audit. |
| Frontend security testing | complete | Playwright automated testing with mock wallet injection across 20 pages. No auto-connect, no unsolicited signing, no drainer activity. 4,727 network requests analyzed. |
| Security headers analysis | complete | All standard headers present (HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy). CSP has weaknesses (unsafe-inline, unsafe-eval, broad connect-src). |
| Drainer/phishing detection | complete | No known drainer domains, no clipboard hijacking, no hidden approvals, no data exfiltration detected across all network requests. |
| On-chain authority analysis | complete | Token authorities (mint, freeze) revoked. Program upgrade authority is active single EOA. Protocol admin has emergency pause, fee config, oracle authority controls. |
| Holder analysis | complete | Full paginated holder scan via Helius. 1,792 unique holders. Top holders identified and labeled (vesting, LP, deployer). |
| Deployer analysis | complete | Deployer DgUnrBGMYXE4TwcqF4y4pt4cKauTCqF53vL3JG1EevN7 identified. Single launch, created Streamflow vesting for 30% of supply, currently holds 1.70%. |
| Bundle detection | complete | 6 bundle clusters in first 3 minutes. 18.7% of supply captured. Common funder identified. Jito tips confirmed. |
| Domain analysis | complete | perk.fund resolves to 76.76.21.21 (Vercel). WHOIS returns .fund TLD registry info only (registrant privacy). DNS is standard Vercel configuration. |
| Cross-layer analysis | complete | Frontend communicates exclusively with Helius RPC. No hidden endpoints. Program ID consistent across codebase (except SECURITY.md typo). Admin route wallet-gated. |
| Frontend-to-contract integrity | complete | All RPC calls are standard getAccountInfo/getProgramAccounts to Helius. No transaction construction observed without user action. Wallet adapter is standard Solana wallet-adapter-react. |
| Twitter/social verification | limited | X.com blocks automated access. @PERK_FUND handle confirmed via website footer. Manual verification pending operator input. |
Findings (9)
| ID | Severity | Title |
|---|---|---|
| TG-001 | high | Audit claims misrepresented — AI-generated reviews named after third-party firms |
| TG-002 | medium | CSP allows unsafe-inline and unsafe-eval |
| TG-003 | medium | Program upgradeable with single EOA authority |
| TG-004 | medium | Helius API key exposed in client-side requests |
| TG-005 | low | Risk engine uses assert!() panics instead of graceful errors |
| TG-006 | low | Program ID mismatch in SECURITY.md |
| TG-007 | low | Oracle equity calculation uses saturating arithmetic |
| TG-008 | low | Deployer keypair path disclosed in Anchor.toml |
| TG-009 | info | Formal verification with Kani proofs and defense-in-depth |
The project's audits/ folder contains 53 files named after recognized security firms (OtterSec, Pashov, Apex). However, every file is an AI-generated self-review authored by 'Kai (AI Security Auditor)', 'Kai (Pashov-style solo review)', 'Apex-style DeFi Red Team (automated)', 'Predator (adversarial smart contract auditor)', and similar AI agents. No verified third-party security audit reports (signed PDFs or on-chain attestations) exist in the repository. The 'OtterSec verified' claim in README and SECURITY.md refers to Solana build verification (confirming deployed bytecode matches source code), not an OtterSec security audit engagement. The security_txt macro in lib.rs lists auditors as 'OtterSec (on-chain verified)' which further conflates build verification with security auditing. Naming AI self-reviews after recognized audit firms implies endorsement that does not exist and is misleading to users evaluating the project's security posture. Evidence: pashov-review-round1.md ('Auditor: Kai (AI Security Auditor)'), apex-red-team-round1.md ('Auditor: Apex-style DeFi Red Team (automated)'), pashov-cranker-audit.md ('Auditor: Pashov-style solo review'), predator-final-oracle-audit.md ('Auditor: Predator (adversarial pass)').
audits/ folder — all 53 .md files; README.md ('OtterSec verified'); SECURITY.md ('Verified on-chain by OtterSec'); lib.rs security_txt
# From audits/pashov-review-round1.md: Auditor: Kai (AI Security Auditor) # From audits/apex-red-team-round1.md: Auditor: Apex-style DeFi Red Team (automated) # From audits/pashov-cranker-audit.md: Auditor: Pashov-style solo review # From README.md: OtterSec verified [checkmark] (this is build verification, not a security audit)
Either obtain real third-party audits from the claimed firms and include the signed PDF reports, or rename the existing files to accurately reflect that they are AI-assisted self-reviews (e.g., 'ai-review-round1.md' instead of 'pashov-review-round1.md'). Remove claims of being audited by OtterSec, Pashov, or Apex unless actual engagements exist. Update the security_txt macro to not list OtterSec as an auditor.
The Content-Security-Policy header includes 'unsafe-inline' and 'unsafe-eval' in the script-src directive, and allows connections to any https/wss endpoint via a broad connect-src. This significantly weakens XSS protection — if an attacker can inject HTML (via a compromised dependency, DNS hijack, or user-generated content), they can execute arbitrary JavaScript. Combined with the broad connect-src, injected scripts could construct and submit malicious Solana transactions to any RPC endpoint. The CSP also allows Access-Control-Allow-Origin: * on HTML responses.
HTTP response headers on perk.fund
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.vercel-insights.com; connect-src 'self' https: wss: access-control-allow-origin: *
Replace unsafe-inline with nonce-based CSP (Next.js supports this via experimental.nextScriptWorkers or custom _document). Replace unsafe-eval if possible (may require TradingView library adjustments). Restrict connect-src to specific domains: mainnet.helius-rpc.com, lite-api.jup.ag, api.coingecko.com, api.dexscreener.com. Remove wildcard CORS or scope to API routes only.
The on-chain program (3L72e4b8wKJ8ReMpLUeXxVNrRGpiK6m4VYxeSnecpNW2) is deployed via BPFLoaderUpgradeable with upgrade authority 86ghiskDv1HUJggeQyit4EhLs3K7ZqU4oU8tjwNYXt1g. This is a single externally-owned account — not a multisig, not behind a timelock. The authority holder can push arbitrary program updates at any time without on-chain governance or delay. While upgradeability is necessary during active development, the lack of a multisig or timelock means a compromised key could result in a malicious upgrade. The protocol also has a single admin key controlling: global pause, fee rates, oracle authority, market parameters, and SOL withdrawal from protocol PDA. The two-step admin transfer (propose/accept) mitigates key rotation risks but doesn't address single-key compromise.
On-chain: ProgramData FKtSHkEoBgTYjFvpakWigjDH1hMgBX9Era8woMzfi8Ni
Transfer upgrade authority to a multisig (e.g., Squads). Implement a timelock for program upgrades. Consider transferring protocol admin to the same multisig. Publish an immutability roadmap — when will the program be made immutable?
The Helius RPC API key is embedded in client-side JavaScript and visible in all network requests to mainnet.helius-rpc.com. While Helius keys for public RPC are designed to be client-facing, exposing the key allows any third party to abuse the project's rate limits and credits. Observed ~150 getAccountInfo calls per page navigation (3,002 POST requests across 20 pages tested), which further amplifies the impact of rate-limit abuse.
Network requests to mainnet.helius-rpc.com from perk.fund frontend
# All RPC calls contain the API key in the URL: POST https://mainnet.helius-rpc.com/?api-key=[REDACTED]
Proxy RPC calls through a backend API route (e.g., /api/rpc) that adds the Helius key server-side. This also enables request-level rate limiting and caching. Consider implementing batch RPC calls to reduce the ~150 calls per page load.
Multiple locations in the risk engine (engine/risk.rs) use assert!() which causes a BPF panic/abort rather than returning a structured Anchor error via require!(). While functionally equivalent (both abort the transaction), panics produce opaque error codes that are harder to debug. More importantly, if any assert!() is reachable through normal user operations (not just corrupt state), it could prevent users from interacting with their positions. Examples found in: set_pnl(), consume_released_pnl(), begin_full_drain_reset(), and several conservation checks.
programs/perk-protocol/src/engine/risk.rs (multiple locations)
// Current pattern (opaque error on failure): assert!(new_pnl.unsigned_abs() <= MAX_ACCOUNT_POSITIVE_PNL, "exceeds MAX_ACCOUNT_POSITIVE_PNL"); // Recommended pattern (structured error): require!(new_pnl.unsigned_abs() <= MAX_ACCOUNT_POSITIVE_PNL, PerkError::PnlExceedsMax);
Replace assert!() calls in production paths with require!() and corresponding PerkError variants. Keep assert!() only for invariant checks that should never be reachable.
SECURITY.md line 31 lists program ID 3L72e4b8wKJ8ReiNMcFViSmYHPJB81oKzPqFDdBmJvXq (ending ...vXq), while every other file in the repository — Anchor.toml, lib.rs, constants.ts, README.md, all docs — consistently uses 3L72e4b8wKJ8ReMpLUeXxVNrRGpiK6m4VYxeSnecpNW2 (ending ...NW2). This could mislead security researchers or integrators attempting to verify the deployed program.
SECURITY.md:31
# SECURITY.md (incorrect): Program ID: 3L72e4b8wKJ8ReiNMcFViSmYHPJB81oKzPqFDdBmJvXq # Everywhere else (correct): Program ID: 3L72e4b8wKJ8ReMpLUeXxVNrRGpiK6m4VYxeSnecpNW2
Update SECURITY.md to use the correct program ID.
The oracle_equity_net function in engine/risk.rs uses saturating_add and saturating_sub for margin calculations. If extreme values cause saturation, a position could appear healthier than it actually is, potentially preventing a necessary liquidation. The normative bounds on oracle price (MAX_ORACLE_PRICE) and position size (MAX_POSITION_ABS_Q) make this practically unreachable, but it diverges from the strict checked-math discipline used throughout the rest of the risk engine.
programs/perk-protocol/src/engine/risk.rs:1517-1526
Replace saturating operations with checked operations and return an error if values exceed expected bounds. This maintains consistency with the rest of the risk engine's defensive arithmetic approach.
Anchor.toml line 21 contains a Windows filesystem path to the deployer keypair: C:\Users\pomch.openclaw\workspace\perk\deployer-keypair.json. While the actual keypair is not in the repository, this reveals developer identity (username 'pomch') and workspace structure. This is an information disclosure in a public repository.
Anchor.toml:21
wallet = 'C:\Users\pomch\.openclaw\workspace\perk\deployer-keypair.json'
Replace with a generic path (e.g., ~/.config/solana/id.json) or use an environment variable reference.
The protocol has genuine formal verification: Kani formal verification with 10 proof suites covering arithmetic, engine, funding, instructions, invariants, liveness, margin, and safety — run in CI on every push to main. Additional verified security measures: (1) Sec3 X-ray static analysis available via manual dispatch. (2) Fuzz testing via fuzz_e2e.rs. (3) E2E security tests targeting oracle hardening. (4) overflow-checks=true in release profile. (5) security_txt macro for on-chain disclosure. (6) Two-step admin transfer. (7) Conservation invariant checked at end of most instructions. (8) Defense-in-depth: warmup windows, haircuts, insurance fund epoch caps, oracle circuit breakers, price banding, sliding window bands. Note: while the Kani proofs and automated testing are real and verifiable in the codebase, the 53 files in the audits/ folder are AI-generated self-reviews (see TG-009), not third-party audit reports.
.github/workflows/kani.yml, programs/perk-protocol/tests/
This audit was performed by Opcode using AI-assisted review with human oversight. No audit can guarantee the complete absence of vulnerabilities. This report is not financial or legal advice.
© 2026 Opcode — opcode.run