# Security posture Holdfast holds real money in an **immutable** contract — once deployed, a bug can never be patched. This page is an honest account of what has been done to reduce that risk, **and what has not.** Read it before you deposit. ## ⚠️ Not professionally audited Holdfast has **not** had a third-party security audit. Automated tools and an automated test suite are **not a substitute** for a human audit. This is a small, personal-scale project. **Only lock funds you would be comfortable losing.** ## What has been done | Check | Status | |---|---| | Built on OpenZeppelin (`SafeERC20`, `ReentrancyGuard`) | ✅ | | Automated tests (33), incl. fuzzing + a reentrancy-attack test | ✅ | | Full lifecycle proven on Base Sepolia (lock → fee → matured → release) | ✅ | | Static analysis — Slither 0.11.5 (Trail of Bits) | ✅ 0 high, 0 medium | | Static analysis — Aderyn 0.6.8 (Cyfrin) | ✅ 0 high, 0 medium | | Source verified on Basescan | ✅ | | Ownerless, no admin key, no upgrade path | ✅ by design | Raw tool output is published alongside the app so you don't have to take our word: - [`security/slither.txt`](security/slither.txt) — also at `/security/slither.txt` on the live site - [`security/aderyn.txt`](security/aderyn.txt) — also at `/security/aderyn.txt` on the live site ## The findings, in full Between them the two tools reported **6 low-severity findings and zero high or medium.** Every one is a known false-positive for a time-lock or a cosmetic nit: **Slither** 1. *Dangerous strict equality* (`unlockTime == 0` in `timeRemaining`) — intentional sentinel for a non-existent/withdrawn deposit. Correct as written. 2. & 3. *Uses `block.timestamp` for comparisons* (`withdraw`, `timeRemaining`) — the generic "validators can nudge the timestamp a few seconds" warning. Irrelevant for day-scale locks; comparing `block.timestamp` to an unlock time is the standard, correct way to build a time-lock. **Aderyn** 1. *Large numeric literal* (`10_000` in the fee math) — style suggestion (`1e4`). `10_000` is clearer for basis points. 2. *PUSH0 opcode* — warns some exotic chains lack `PUSH0`. **Base supports it** (`evm_version = "cancun"`), so this does not apply here. 3. *Unspecific pragma* (`^0.8.24`) — best practice is an exact pin, but `foundry.toml` already pins `solc_version = "0.8.24"`, so the compiled bytecode is fixed regardless. None of these are exploitable and none were changed, because doing so would only alter style while forcing the already-deployed, verified vaults out of sync with their source. ## Reproduce it yourself You don't need this repo — pull the verified source straight from Basescan, or use the copy served at `/TimeLockVault.sol`, then: ```bash # Slither (pip install slither-analyzer) slither . --filter-paths "lib/|test/|script/" # Aderyn (https://github.com/Cyfrin/aderyn) aderyn --src contracts/ . # The test suite make install && make test ``` ## Reporting a vulnerability Found something? Please report it privately to **kp@kpledger.xyz** before disclosing publicly. The contract is immutable, so a real finding means a redeploy and a warning to existing depositors — responsible disclosure genuinely matters here.