Dr. Fraudsworth's Finance Factory
Executive Summary
Dr. Fraudsworth's Finance Factory is a tax-driven DeFi protocol on Solana built around a novel economic loop: every token swap incurs a configurable tax (1-14%, set by VRF randomness each epoch) that is split between stakers (71%), a Carnage buyback-and-burn fund (24%), and treasury (5%). The protocol deploys 6 active Anchor programs totaling 19,447 lines of Rust, plus a Next.js frontend with ~26K lines of TypeScript, all open source.
The on-chain security architecture is well above average. All programs passed the 16-point Solana vulnerability checklist. Core arithmetic is formally verified via Kani model checker with 18 mathematically proven properties. The protocol employs sophisticated defenses: VRF anti-reroll protection, dead stake attack prevention, flash loan resistance via cooldowns, reentrancy guards, and protocol-enforced 50% slippage floors. Cross-program invocations are validated through seeds::program constraints, and the transfer hook's whitelist-based tax interception operates at the Token-2022 level.
Three medium findings prevent a clean PASS. First, the source code on GitHub hardcodes a devnet treasury address for mainnet builds — the correct address is injected at build time via a patching script that is not included in the verified build CI pipeline, creating a source-binary gap that undermines independent reproducibility. Second, the transfer hook's whitelist authority has not been burned, meaning the team's Squads multisig can add addresses to bypass trading taxes. Third, the CSP requires unsafe-inline for scripts due to Next.js framework limitations, though this is mitigated by React's automatic escaping and the absence of dangerous rendering patterns. Two low-severity findings cover a webhook auth bypass in non-production environments and a deployment generator bug that always reads devnet config regardless of the target cluster.
The project is transparent about its security posture: all internal audits (SOS, Bulwark, VulnHunter) are explicitly disclaimed as AI-generated analysis, and the SECURITY_AUDIT_SUMMARY.md clearly states no professional third-party audit has been conducted. OtterSec badges on 6 programs are build verification (binary reproducibility), not security audits. The BOK formal verification framework using Kani is legitimate and provides real mathematical guarantees for the protocol's core math. No rug pull indicators were detected: all mint and freeze authorities are permanently revoked, the deployer has a clean history with no prior rugs, and no coordinated buying was detected at launch.
Rug Risk Assessment
Audit Scope
| Scope Item | Status | Notes |
|---|---|---|
| Source code review (Rust on-chain programs) | complete | All 7 programs reviewed: AMM, Transfer Hook, Tax Program, Epoch Program, Staking, Conversion Vault, Bonding Curve (historical). 19,447 LOC analyzed. |
| Frontend source code review (Next.js) | complete | Full review of app/ directory: API routes, components, hooks, providers, middleware, config. ~26K LOC. |
| 16-point Solana vulnerability checklist | complete | Signer, owner, overflow, PDA, reinit, cosplay, CPI, close, arithmetic, rent, duplicates, unauthorized PDA, flash loan, oracle, timestamp, frontrunning — all passing. |
| Frontend security (unauthenticated) | complete | Playwright mock wallet injection, security header analysis, drainer/phishing scan, network request interception. All clean. |
| Frontend security (authenticated) | limited | Mock wallet not detected by Wallet Adapter Standard (expected). Unauthenticated analysis confirmed no drainers. Operator-provided Twitter screenshots analyzed. |
| On-chain authority checks | complete | Mint/freeze/upgrade authority verified via getAccountInfo. Upgrade authority confirmed as Squads v4 vault via PDA derivation. Whitelist authority confirmed active (not burned). |
| Holder analysis (paginated) | complete | Full pagination via Helius getTokenAccounts for all 3 tokens. 28/40/15 holders. Top holder owners identified against mainnet.json PDA manifest. |
| Deployer identification and history | complete | Deployer 23g7x... identified via first FRAUD mint transaction. 100 recent transactions analyzed — clean history, primarily Squads governance. |
| Bundle detection | complete | First 50 transactions on FRAUD mint analyzed. Zero multi-tx slots. No coordinated buying patterns. |
| Team and social legitimacy | complete | @fraudsworth: Joined Feb 2026, 309 followers, 8 following, 54 posts, parody label. Domain fraudsworth.fun registered Feb 2026. Low engagement but organic-looking for project size. |
| Dependency audit | complete | Cargo.lock reviewed. @coral-xyz/anchor 0.32.1, @solana/web3.js 1.98.4, Token-2022. No suspicious or vulnerable packages detected. |
| Build verification | limited | Static analysis of build pipeline (CI, verified-build.yml, patch scripts, deployment configs). Identified source-binary gap: patch-mint-addresses.ts not included in CI verified build. OtterSec build verification = binary reproducibility only, not security audit. |
| Audit claim verification | complete | SOS/Bulwark/VulnHunter = AI-generated (Claude), explicitly disclaimed. BOK = legitimate Kani formal verification. OtterSec = build verification only. No professional third-party security audit exists. |
| Cross-layer analysis (frontend-to-contract) | complete | 3 critical flows traced (buy, stake, claim). Slippage enforced on-chain. Program IDs hardcoded at build time. Transaction contents verified — no hidden instructions. |
| Trust boundary analysis | complete | RPC proxy method-allowlisted (17 methods). SSE data from Helius webhooks with bounds validation. On-chain data is authoritative — frontend display issues cannot cause fund loss. |
| Infrastructure security | complete | Excellent headers (CSP, HSTS, X-Frame-Options, nosniff, Permissions-Policy). Rate limiting on all endpoints. Constant-time webhook auth. Per-IP connection caps on SSE. |
| Domain analysis | complete | fraudsworth.fun — .fun TLD via Radix/Cloudflare. Domain registered Feb 2026. Hosted on Railway (europe-west4) behind Cloudflare CDN. |
Findings (12)
| ID | Severity | Title |
|---|---|---|
| TG-001 | medium | Source-binary treasury mismatch — patch-based build flow not in CI |
| TG-002 | medium | Transfer hook whitelist authority remains mutable |
| TG-003 | medium | CSP allows unsafe-inline for scripts and styles |
| TG-004 | low | Webhook auth skipped in non-production environments |
| TG-005 | low | Deployment generator reads devnet config for all clusters |
| TG-006 | info | Programs upgradeable via Squads v4 multisig |
| TG-007 | info | CPI depth at Solana maximum (4/4) |
| TG-008 | info | All security audits are AI-generated (explicitly disclaimed) |
| TG-009 | info | 16-point Solana vulnerability checklist — all clear |
| TG-010 | info | Formal verification of core arithmetic (Kani proofs) |
| TG-011 | info | Clean frontend — no drainers, hidden approvals, or malicious scripts |
| TG-012 | info | Comprehensive API rate limiting and security hardening |
The mainnet cfg block in tax-program constants.rs hardcodes the devnet treasury address (8kPzh...) for mainnet builds. The actual mainnet treasury (3ihhw...) is injected at build time by patch-mint-addresses.ts reading TREASURY_PUBKEY from env. However, the verified-build.yml CI pipeline does NOT include the patching step — meaning CI-produced verified binaries would contain the wrong treasury address. On-chain evidence confirms the deployed binary uses the correct treasury (3ihhw... has 1.78 SOL; 8kPzh... has 0 SOL), so no funds are misdirected today. But the build process that produced the deployed binary is not fully captured in the public repository, undermining independent reproducibility of OtterSec verified builds.
programs/tax-program/src/constants.rs:146-148, scripts/deploy/patch-mint-addresses.ts:201, .github/workflows/verified-build.yml, deployments/mainnet.json:72
// constants.rs line 146-148 (mainnet cfg):
#[cfg(not(any(feature = "devnet", feature = "localnet")))]
pub fn treasury_pubkey() -> Pubkey {
Pubkey::from_str("8kPzhQoUPx7LYM18f9TzskW4ZgvGyq4jMPYZikqmHMH4").unwrap()
}
// patch-mint-addresses.ts line 201 (mainnet fallback):
treasuryAddress = process.env.TREASURY_PUBKEY || "8kPzhQoUPx7LYM18f9TzskW4ZgvGyq4jMPYZikqmHMH4";
// mainnet.json line 72 (actual treasury):
"treasury": "3ihhwLnEJ2duwPSLYxhLbFrdhhxXLcvcrV9rAHqMgzCv"
Add patch-mint-addresses.ts to verified-build.yml before the anchor build step. Or commit the mainnet treasury address directly into the mainnet cfg block in constants.rs so the source code matches the deployed binary without build-time patching.
The WhitelistAuthority PDA (J3cjg...YpJe) has authority = Some(4SMcP...NAvXJ), the Squads v4 vault. The burn_authority() instruction exists but has not been called — the whitelist remains mutable. The multisig can add new WhitelistEntry PDAs, allowing any address to send/receive tokens without triggering the transfer hook's tax validation. Currently all 8 whitelisted addresses are legitimate protocol PDAs (AMM vaults, carnage vaults, staking vault, conversion vault). However, the capability to whitelist arbitrary addresses persists. Since all operations go through the Squads multisig (confirmed: SQDS4ep65T...), exploitation requires multi-party collusion.
programs/transfer-hook/src/instructions/burn_authority.rs:21-48, programs/transfer-hook/src/instructions/add_whitelist_entry.rs, deployments/mainnet.json:27
// On-chain WhitelistAuthority account data:
// Byte 8 (Option tag): 0x01 = Some (ACTIVE, not burned)
// Authority: 4SMcPtixKvjgj3U5N7C4kcnHYcySudLZfFWc523NAvXJ (Squads vault)
// burn_authority.rs — exists but not called:
pub fn handler(ctx: Context<BurnAuthority>) -> Result<()> {
// ... burns authority, making whitelist immutable
auth.authority = None;
}
Consider burning the whitelist authority once all protocol PDAs are whitelisted and the protocol is stable. If future whitelist modifications are needed (e.g., new pool deployments), document a timeline for when burn_authority will be called. At minimum, add a governance commitment (e.g., in README or docs) stating when immutability is planned.
The Content Security Policy in next.config.ts sets script-src and style-src to 'self' 'unsafe-inline'. This is a known Next.js limitation — the framework's style-jsx runtime and Turbopack CSS injection require inline scripts/styles. While React's automatic JSX escaping and the absence of dangerouslySetInnerHTML significantly reduce XSS risk, unsafe-inline weakens the CSP's ability to block injected scripts. All other CSP directives are properly restrictive (connect-src allowlisted, frame-ancestors 'none', object-src 'none').
app/next.config.ts:34-35
// next.config.ts CSP header: script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';
Migrate to nonce-based CSP using runtime middleware (e.g., next-csp library) to replace 'unsafe-inline' with per-request nonces. This is a framework-level change and may require coordination with Next.js updates.
The Helius webhook handler at /api/webhooks/helius/route.ts skips HMAC authentication when HELIUS_WEBHOOK_SECRET is not set and the environment is not production. While intentional for local development, staging/CI deployments without the secret accept unauthenticated webhook payloads, allowing injected protocol state data into the SSE pipeline.
app/app/api/webhooks/helius/route.ts:281-295
if (!webhookSecret && isProduction) {
return NextResponse.json({ error: "Webhook secret not configured" }, { status: 500 });
}
// Non-production: webhook secret not required — auth bypassed
Require HELIUS_WEBHOOK_SECRET in all environments. Use a test secret for local development.
generate-deployment-json.ts line 189 contains a conditional that always evaluates to 'devnet': cluster === 'mainnet' ? 'devnet' : 'devnet'. The Anchor.toml has no [programs.mainnet] section, so both clusters read from [programs.devnet]. This works by coincidence — devnet and mainnet use the same program IDs from the same keypairs. If they ever diverged (e.g., mainnet redeploy to new address), the generator would silently produce incorrect mainnet deployment configs.
scripts/deploy/generate-deployment-json.ts:189, Anchor.toml
// generate-deployment-json.ts line 189: const anchorCluster = cluster === "mainnet" ? "devnet" : "devnet"; // TODO: Add [programs.mainnet] to Anchor.toml for mainnet // Anchor.toml — no [programs.mainnet] section exists: // [programs.devnet] <-- used for both devnet and mainnet // [programs.localnet] <-- localnet only
Add [programs.mainnet] section to Anchor.toml with explicit mainnet program IDs. Fix the conditional to correctly select the cluster.
All 6 active programs share upgrade authority 4SMcPtixKvjgj3U5N7C4kcnHYcySudLZfFWc523NAvXJ, confirmed on-chain as a Squads v4 vault PDA (seeds=[multisig, F7axB..., vault, 0], bump=255, program=SQDS4ep65T...). The multisig account F7axBNUgWQQ33ZYLdenCk5SV3wBrKyYz9R7MscdPJi1A is owned by the Squads v4 program. Program upgrades require multi-party approval through the Squads governance flow. This is a centralization consideration, not a vulnerability.
deployments/mainnet.json:73-79
The Carnage atomic execution path reaches the Solana CPI depth limit: execute_carnage_atomic -> Tax::swap_exempt -> AMM::swap_sol_pool -> Token-2022::transfer_checked -> Transfer Hook. A fallback execution path (execute_carnage) exists with more lenient slippage (75% vs 85%) and executes after the lock window expires. The protocol handles this correctly with the two-path design.
programs/epoch-program/src/instructions/execute_carnage_atomic.rs
The project has 4 internal audit frameworks: SOS, Bulwark, VulnHunter (all Claude/AI-generated), and BOK (legitimate Kani formal verification). SECURITY_AUDIT_SUMMARY.md explicitly states: 'This document summarizes AI-assisted internal security analysis, not a traditional paid external audit.' OtterSec badges on 6 programs are build verification (binary reproducibility), NOT security audits. No professional third-party security audit from a recognized firm exists. The README's mention of '3 comprehensive security audits' could be misread as professional audits.
SECURITY_AUDIT_SUMMARY.md, .audit/FINAL_REPORT.md, .bulwark/FINAL_REPORT.md, .bok/reports/2026-03-12-report.md
Comprehensive review of all 6 active programs against the standard 16-point Solana security checklist. All checks pass: (1) Signer checks enforced via Anchor Signer type, (2) Owner checks via seeds::program constraints, (3) Overflow protection via checked arithmetic throughout, (4) PDA validation via Anchor account constraints, (5) No reinitialization vectors (initialized flags + has_one constraints), (6) Account cosplay prevented by Anchor discriminators, (7) CPI validated via seeds::program, (8) Close account handling correct (Bonding Curve rent reclaim), (9) Arithmetic safe (u128 intermediates, checked_mul/div), (10) Rent exemption handled, (11) Duplicate accounts validated, (12) PDA access controlled, (13) Flash loan resistant (dead stake + cooldown), (14) Oracle (VRF) properly validated with anti-reroll, (15) Timing uses slot-based checks (not clock), (16) Frontrunning mitigated by 50% slippage floor.
All programs in programs/
18 properties mathematically proven via Kani model checker (v0.67.0, CBMC 6.8.0): tax floor division bounds, no u128 overflow in tax/AMM/staking calculations, AMM fee never exceeds principal, zero input produces zero output, staking cumulative monotonically increasing, bonding curve price monotonicity, no panics in reward functions. Additionally 116 properties stress-tested via Proptest (10,000+ iterations each) and LiteSVM integration tests.
.bok/reports/2026-03-12-report.md, .bok/confirmed-invariants/
Playwright automated testing confirmed: zero intercepted transaction signing attempts, zero sign message attempts, zero drainer patterns detected, zero hidden iframes, zero suspicious external requests. Only external resource: Cloudflare beacon (analytics). Security headers excellent: HSTS (63M seconds, preload), X-Frame-Options DENY, X-Content-Type-Options nosniff, Permissions-Policy (camera/mic/geo disabled), restrictive CSP, Referrer-Policy strict-origin-when-cross-origin.
reports/playwright-results.json, app/next.config.ts
RPC proxy: 17-method allowlist with inline documentation, per-method rate limits (sendTransaction 10/min, simulateTransaction 20/min, general 300/min), 64KB body limit, batch rejection, 20 concurrent request cap per IP. Webhook: constant-time HMAC comparison via timingSafeEqual, 1MB payload limit, 5-minute transaction age rejection, slot-monotonic freshness checks. SSE: per-IP connection caps, 30-minute idle timeout, 15-second heartbeat. Settings: field-by-field validation with bounds checking, corrupted JSON handling.
app/app/api/rpc/route.ts, app/app/api/webhooks/helius/route.ts, app/lib/rate-limit.ts
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