Fortress Protocol FTS Collateral-Listing Governance Capture / Public submit() Oracle Manipulation Drain (2022-05-08)
- Name: Fortress Protocol FTS collateral-listing governance capture / public
submit()oracle manipulation drain - Date: 2022-05-08
- Protocol: Fortress Loans / Fortress Protocol (JetFuel Finance lending arm)
- Chain: BNB Chain
- Category: governance capture / oracle manipulation / protocol-native collateral fragility / lending-market drain
- Loss: about
1,048.1 ETHplus400,000 DAI, or roughly$2.98Mto$3M - Summary: Fortress did not fall to one isolated oracle bug. The attacker first pushed governance proposal
11throughFortressGovernorAlphato make the thinly traded house tokenFTSaccepted collateral at a0.7collateral factor, then abused the oracle path behindFortressPriceOraclebecause the upstreamChain.submit()authentication checks had effectively been disabled. Once Fortress was willing to treat protocol-nativeFTSas borrowable collateral and also willing to believe an attacker-submitted price for that same token, roughly100 FTScould be marked at fantasy value and used to borrow out the rest of the market. - Trigger / entry point:
- Fortress governance was cheap enough that contemporary reporting and CertiK both describe the attacker acquiring just over
400,000 FTSand using it to create and carry malicious proposal11. - Proposal
11changed Fortress risk parameters soFTSitself became acceptable collateral with collateral factor700000000000000000(70%). - The oracle path
FortressPriceOracle -> Chain.submit()accepted attacker-shaped price submissions because the relevant signature / power validation inChain.submit()had been commented out or disabled in deployment. - Fortress then let the same thin governance token sit in the solvency core of the lending market at an attacker-chosen price.
- Fortress governance was cheap enough that contemporary reporting and CertiK both describe the attacker acquiring just over
- Root cause:
- Fortress governance could directly change live lending collateral parameters even though the effective cost to control that vote was tiny relative to protocol TVL.
- Fortress admitted its own low-depth governance token
FTSas collateral, turning a thin local market into solvency truth for stronger reserve assets. - The oracle implementation delegated trust to a
Chaincontract whosesubmit()path no longer enforced the authentication assumptions the rest of the protocol relied on. - There was no operational backstop strong enough to stop an obviously dangerous governance proposal even though REKT reported it sat active for about three days.
- Exploit path:
- The attacker funded BNB Chain activity from Ethereum-side funds that reporting traced back to Tornado Cash, then staged BNB Chain address
0xA6AF2872176320015f8ddB2ba013B38Cb35d22Adand attack contract0xcd337b920678cf35143322ab31ab8977c3463a45. - The attacker accumulated enough
FTSto control the sleepy governance surface and used helper wallet0x0dB3B68c482b04c49cD64728AD5D6d9a7B8E43e6to submit malicious proposal11throughFortressGovernorAlpha0xe79ecdb7fedd413e697f083982bac29e93d86b2e. - Proposal
11passed and was executed, changing Fortress soFTScould be posted as collateral with a70%collateral factor. - The attacker then abused
Chaincontract0xc11b687cd6061a6516e23769e4657b6efa25d78e, whosesubmit()function no longer enforced the expected signer / power checks, and fed a maliciousFTSprice intoFortressPriceOracle0x00fcF33BFa9e3fF791b2b819Ab2446861a318285. - With
FTSboth governance-approved and oracle-inflated, the attacker posted about100 FTSthrough attack contract0xcd337...as collateral and borrowed large quantities of stronger assets across Fortress’s lending markets in exploit transaction0x13d19809b19ac512da6d110764caee75e2157ea62cb70937c8d9471afcb061bf. - The borrowed assets were swapped into
ETHandDAI, then moved off BNB Chain via Celer / Multichain routes and ultimately sent into Tornado Cash.
- The attacker funded BNB Chain activity from Ethereum-side funds that reporting traced back to Tornado Cash, then staged BNB Chain address
- What the attacker needed to be true:
FTSgovernance participation had to be so weak that buying a few hundred thousand tokens on market was enough to carry a malicious proposal.- Governance had to retain direct authority over collateral listing / collateral-factor changes for the live lending system.
FTShad to remain thin enough that its local quoted price could not support the borrowing power the protocol was prepared to assign to it.FortressPriceOraclehad to trustChain.submit()results without an independent sanity layer that would reject unauthenticated or absurdFTSprices.- The market had to hold deeper-liquidity borrow assets than the true executable value of the posted
FTScollateral.
- Technical anatomy worth remembering:
- This is a clean composed failure where governance capture was not the final payout rail by itself. Governance first rewired risk parameters, and the oracle bug then monetized that new risk surface.
- The dangerous asset was Fortress’s own governance token. That makes this more specific than generic oracle manipulation: the protocol let a house asset become balance-sheet truth.
- The oracle weakness was not subtle market microstructure. CertiK’s writeup says the critical validation inside
Chain.submit()had effectively been removed, so the protocol’s trusted price source had collapsed into a public write surface. - The incident is also a useful governance-monitoring lesson. REKT noted the malicious proposal sat active for roughly three days, so Fortress’s constitutional defense failed well before the exploit transaction.
- Representative transactions and addresses:
- Exploit transaction:
0x13d19809b19ac512da6d110764caee75e2157ea62cb70937c8d9471afcb061bf - Proposal-creation transaction for proposal
11:0x12bea43496f35e7d92fb91bf2807b1c95fcc6fedb062d66678c0b5cfe07cc002 - Vote transaction highlighted by CertiK:
0x83a4f8f52b8f9e6ff1dd76546a772475824d9aa5b953808dbc34d1f39250f29d - Attacker EOA:
0xA6AF2872176320015f8ddB2ba013B38Cb35d22Ad - Helper / proposal wallet:
0x0dB3B68c482b04c49cD64728AD5D6d9a7B8E43e6 - Attack contract:
0xcd337b920678cf35143322ab31ab8977c3463a45 - FortressGovernorAlpha:
0xe79ecdb7fedd413e697f083982bac29e93d86b2e - FortressPriceOracle:
0x00fcF33BFa9e3fF791b2b819Ab2446861a318285 - Upstream
Chaincontract:0xc11b687cd6061a6516e23769e4657b6efa25d78e
- Exploit transaction:
- Response / mitigation:
- Fortress / JetFuel publicly acknowledged the incident, paused the UI, and pointed users to a follow-up governance proposal intended to repair the damage.
- The immediate lesson was broader than
patch the oracle: Fortress had to treat governance control over collateral admission and the oracle-authentication path as the same security surface. - Even after the exploit, the case remained an uncomfortable reminder that a lending market should not wait for social monitoring to catch obviously malicious risk-parameter proposals.
Pattern tags
- governance-capture
- oracle-manipulation
- protocol-native-collateral-fragility
- Governance-authored collateral admission for a thin house token
- Oracle-authentication collapse turning protocol-native collateral into attacker-priced borrow power
Why the exploit worked
- Fortress let a weakly defended governance surface write directly into live lending risk. Proposal
11was not cosmetic policy; it changed what the protocol would accept as collateral and therefore what counted as solvency truth. - The newly admitted collateral was Fortress’s own thinly traded governance token. That meant the attacker did not need to buy or sustain real market depth large enough to justify the borrow power they were about to extract; they only needed the protocol to treat
FTSas money-good collateral in the first place. - The oracle path then removed the last remaining restraint. Once
FortressPriceOracletrusted aChain.submit()surface whose signature / voting-power checks were effectively disabled, the attacker did not have to manipulate an honest market — they could simply publish the fantasy price the lending engine would trust. - These were not two separate bugs with independent blast radii. Cheap governance first created the dangerous collateral lane, and the broken oracle then monetized that exact lane. The exploit worked because collateral admission, house-token market quality, and oracle authentication were all part of one joined borrow-authority object.
- Fortress also lacked a real constitutional backstop. A proposal that turned a low-float governance token into 70%-factor collateral reportedly sat live for days, which means the protocol’s practical defense model had already failed before the final borrow transaction.
Detection and audit pivots
- Treat governance-controlled collateral listings and collateral-factor changes as treasury-grade actions. Ask what token float, borrowable voting power, quorum profile, and emergency-veto latency would be required for a malicious listing to pass right now.
- For every protocol-native or low-depth asset that governance could admit as collateral, ask whether the protocol is about to let its own local token narrative become solvency truth for deeper reserve assets. Thin house tokens deserve extra skepticism even before any oracle review begins.
- Trace the exact oracle-authentication path all the way down to the write surface. If the protocol believes a
submit()call is backed by signatures, voting power, reporters, or validator weights, verify where that check actually happens onchain and whether deployment drift commented it out or bypassed it. - Review composition, not components in isolation. A governance system that can list collateral and an oracle that can publish its price may each look survivable alone, but together they can create an instant
list thin thing, price thin thing, borrow everything elsepath. - Monitor queued and active governance proposals for parameter combinations, not only for admin-target changes.
New collateral + high collateral factor + weak market depth + same-token oracle dependencyshould already look like an emergency condition. - Ask what bounded-loss controls survive if governance or pricing truth fails anyway: listing caps, borrow caps, per-asset debt ceilings, collateral quarantine windows, or delays before newly admitted collateral can support large borrowing.
Failure-prevention checklist
- Do not let low-float governance tokens become normal lending collateral just because governance can vote it through. Protocol-native assets need stricter admission rules, lower or zero borrow power by default, and explicit market-depth / unwind tests before they ever reach solvency-critical status.
- Treat collateral listing, collateral-factor changes, and oracle-source changes as treasury-grade actions with stronger quorum, longer delay, narrower proposer sets, or an emergency veto. If one sleepy vote can rewrite borrow truth, governance is already acting like an admin key.
- Keep newly listed or newly reconfigured collateral in borrow-side quarantine. A passed proposal should not immediately let the same asset support deep borrowing before caps, canaries, and independent review confirm the market and oracle assumptions are real.
- Require hard oracle authentication at the final write surface. If
FortressPriceOracletrustsChain.submit(), thensubmit()must itself prove reporter identity, voting power, signature set, and freshness rather than hoping an upstream assumption survived deployment. - Bound losses even if governance or price publication fails: per-asset debt ceilings, borrow caps, collateral caps, isolated listings, and fast pause paths should stop one bad listing from draining the whole market.
- Monitor governance for economic nonsense, not only code-change proposals.
Thin house token + high collateral factor + same-token oracle dependencyshould already page humans before execution. - Make proposal-review and emergency-response ownership explicit. A three-day malicious proposal window means the protocol lacked a credible constitutional backstop even before the exploit transaction.
Audit prompts
- Exactly which governance actions can change live borrow authority here: listing a market, changing collateral factor, swapping oracle sources, or editing reporter / submitter sets?
- How expensive is malicious control in practice, not in theory? What float is liquid, what fraction is borrowable, how concentrated is turnout, and how quickly could an attacker buy or rent quorum?
- If the protocol listed its own token as collateral tomorrow, what independent market-depth, liquidity, and exit assumptions would justify that decision? Are any of those assumptions actually enforced onchain?
- Where does oracle authentication really happen? Trace the path through every adapter and helper until you reach the final state write, then verify that signature, power, reporter-set, and freshness checks still exist in deployed code.
- If governance successfully lists dangerous collateral, what stops immediate full-size borrowing before humans react: caps, quarantine delays, isolated markets, utilization throttles, or nothing?
- Does the same organizational surface control both collateral admission and collateral pricing? If so, the review target is not
governanceplusoracle; it is one combined borrow-authority object. - What alerts fire for active proposals that would make protocol-native or low-depth assets systemically important, and who is actually empowered to block them?
- If the oracle path becomes publicly writable or governance gets captured, what is the maximum extractable value before pauses, caps, or market isolation take effect?
Lessons that should already be standard
- Governance is already a hot wallet when it can list collateral or rewrite collateral factors for a lending market. Calling it a DAO does not reduce the need for treasury-grade controls.
- Protocol-native tokens are not neutral collateral candidates. If the protocol is the main source of narrative, liquidity, and incentive demand for an asset, the bar for making that asset borrow-power truth should be extremely high.
- An oracle is only as strong as its last authenticated write surface. If the final
submit()lane is public, then every elegant upstream trust story is already dead. - Cheap governance and weak oracle auth are multiplicative, not additive, risk. One creates a dangerous lane; the other makes that lane immediately cash-outable.
- Watching proposals in Discord or Telegram is not a security model. If a malicious listing can sit live for days and still execute, the constitutional defense is already broken.
- Deep-liquidity reserves should never fully trust a newly admitted, low-depth, or protocol-native collateral asset without tight caps and time to prove that its price path is adversarially robust.
Why this incident matters
- It is a strong preserved example of how two medium-strength failures can compose into a total drain: cheap governance plus a public oracle write surface.
- It sharpens the
protocol-native collateral fragilitypattern because the attacker did not need deep external market support forFTS; they only needed Fortress to believe Fortress’s own token was money-good collateral. - It also broadens governance-capture notes beyond treasury sweeps and admin seizures. Here, governance capture mattered because it changed what the lending engine was willing to believe about collateral.
Internal linkages
- Parent governance family: governance-capture.
- Parent oracle family: oracle-manipulation.
- Sharper house-asset framing: protocol-native-collateral-fragility.
Control surface
-
The leverage sat in governance proposal thresholds, collateral-admission authority,
FTSmarket depth, oracle-source authentication, and the lack of a real veto / monitoring backstop for risk-parameter changes. -
The quiet mistake was not merely
bad oracle code. It was letting a sleepy DAO vote a thin house token into the solvency core and then trusting an unauthenticated price for that same token. -
Sources:
- https://rekt.news/fortress-rekt
- https://www.certik.com/blog/fortress-loans-exploit
- https://beosin.com/resources/beosin-detailed-analysis-of-fortresss-oracle-attack
- https://bscscan.com/tx/0x13d19809b19ac512da6d110764caee75e2157ea62cb70937c8d9471afcb061bf
- https://bscscan.com/tx/0x12bea43496f35e7d92fb91bf2807b1c95fcc6fedb062d66678c0b5cfe07cc002
- https://bscscan.com/tx/0x83a4f8f52b8f9e6ff1dd76546a772475824d9aa5b953808dbc34d1f39250f29d
- https://bscscan.com/address/0xe79ecdb7fedd413e697f083982bac29e93d86b2e#code
- https://bscscan.com/address/0x00fcf33bfa9e3ff791b2b819ab2446861a318285#code
- https://bscscan.com/address/0xc11b687cd6061a6516e23769e4657b6efa25d78e#code
-
Last reviewed: 2026-07-22 UTC