Security Audit
Internal source-code review of Danny Wallet
- Scope
- Browser wallet · Desktop
- Network
- Danny Chain (EVM 5069)
- Audit type
- Internal source review
- Date
- September 10, 2026 (rev. 1.2)
- Version
- 1.2
Overall rating
🟢 Good
No critical, fund-loss vulnerabilities
0
Critical
1
High
1
Medium
2
Low / Info
Summary
Danny Wallet is non-custodial — private keys and recovery phrases are generated and stored only on the user's device, encrypted with a PIN or passphrase. The core architecture follows good practice: a memory-hard key derivation (scrypt) with AES-256-GCM, a minimum of 12 digits or 8 characters for the unlock secret, PIN brute-force protection, no secret logging, and explicit approval for every signing action. One high-severity issue (Permit phishing via typed-data signing) was found and has been fixed and deployed.
Reviewed areas
Cryptography & key management
scrypt (N=2^16, r=8, p=1 · 64 MB per guess) + AES-256-GCM, random salt/IV per blob, GCM-tag PIN check; older PBKDF2 vaults are re-encrypted at the next unlock
PIN brute-force protection
12+ digit PIN or 8+ character passphrase; exponential cooldown after 5 fails, wallet wipe after 10. The counter is stored on the device, so offline guessing is held back by scrypt and the minimum length
Transaction & message signing
PIN required for every in-app send/swap, no auto-sign; each WalletConnect request needs approval and must match the account on screen; calldata decoded & warned
dApp browser (iframe)
Cross-origin + no provider injection → dApp can't reach keys
Data storage & privacy
Only encrypted blobs stored; no plaintext key/seed; no tracking
Network & headers
HTTPS, CSP frame-ancestors, nosniff, referrer-policy
Findings
Permit / typed-data blind signing — content not shown; risk of being tricked into signing a Permit (gasless approve) to drain tokens
Wallet wipe after 10 wrong PINs — seedless imported accounts without a key backup risk permanent loss
Dependency hardening — removed @stablelib/ed25519 and patched elliptic via package overrides (npm prod criticals now 0)
DappBrowser broad sandbox — mitigated by cross-origin
HIGH-01 — Fixed
The WalletConnect confirmation screen now decodes typed-data requests and shows what is being signed. When a request is an EIP-2612 Permit (a gasless, signature-based token approval), it displays a strong warning including the spender and amount — preventing blind-signed approvals that could drain tokens.
Remediations (rev. 1.1)
Dependency overrides removed @stablelib/ed25519 and patched elliptic — npm production criticals reduced to 0.
Unlimited token approvals (approve max / Permit) now require an explicit acknowledgement checkbox before signing.
Import / create flows now warn that seedless accounts are not in the recovery phrase and must be backed up.
Remediations (rev. 1.2)
Key derivation moved from PBKDF2-SHA256 to scrypt (N=2^16, r=8, p=1), so every guess costs about 64 MB of memory. Existing vaults are re-encrypted automatically at the next unlock.
The 6-digit PIN was replaced by a minimum of 12 digits or an 8-character passphrase. Wallets that still use a short PIN must set a new one right after unlocking.
WalletConnect: the signing key is bound to the account shown on screen. Switching accounts drops it, and any request that names a different account is rejected.
Key-derivation errors (e.g. low memory) are no longer counted as wrong PIN attempts, so they cannot trigger the wallet wipe.
This is an internal source-code review, not an audit by an independent third-party firm. It covers the wallet client only — not DEX/bridge smart contracts or network infrastructure. The report reflects the state at the audit date; re-audit when significant crypto, signing, or dependency changes are made.
Found a vulnerability? See our Bug Bounty program.