Morpho PAXG/USDC Market Oracle Decimal Misconfiguration (2024-10-13)
- Name: Morpho PAXG/USDC market oracle decimal misconfiguration
- Date: 2024-10-13
- Protocol: Morpho Blue ecosystem market deployed by LeadBlock
- Chain: Ethereum
- Category: oracle configuration failure / decimal mismatch / permissionless-market misconfiguration
- Loss: about
$230,000borrowed against roughly$350of PAXG at exploit time - Summary: A newly created PAXG/USDC market on Morpho Blue was launched with a misconfigured oracle that overvalued PAXG by
10^12. The mistake was not in Morpho Blue’s immutable core contracts, but in the market-specific oracle setup used for the new market. Because the configuredSCALE_FACTORfailed to reconcile PAXG’s18decimals with USDC’s6decimals, the market treated tokenized gold as if it were worth about$2.6Tper unit. An opportunistic user supplied about$350of PAXG, borrowed about$230,000USDC, and left the market with a visibly broken balance sheet until the curator handled repayment and remediation outside the market itself. - Trigger / entry point:
- The affected market was LeadBlock’s new PAXG/USDC AdaptiveCurve market with LLTV
91.5%, oracle0xDd1778F71a4a1C6A0eFebd8AE9f8848634CE1101, and market ID0x8eaf7b29f02ba8d8c1d7aeb587403dcb16e2e943e4e2f5f94b0963c2386406c9. - Morpho Blue oracle contracts expect
price()to return the price of1unit of collateral quoted in the loan asset and scaled by1e36. MorphoChainlinkOracleV2explicitly assumes the deployer passes correct token decimals into the constructor when computingSCALE_FACTOR.- In this market, the decimal configuration was wrong, so the final onchain oracle output drastically overstated PAXG collateral value relative to USDC.
- The affected market was LeadBlock’s new PAXG/USDC AdaptiveCurve market with LLTV
- Root cause:
- This was a unit / decimal integration failure. The market-specific oracle setup did not correctly account for the
18decimals of PAXG against the6decimals of USDC. - Security writeups describe the bug as a miscalculated
SCALE_FACTORthat inflated collateral value by10^12. - Morpho Blue itself behaved as designed: permissionless markets can choose custom oracle configurations, and this market chose a bad one.
- The meaningful failure was therefore at the deployment and review layer: incorrect oracle parameters were accepted into a live lending market with high LLTV and no additional sanity check that the final quoted PAXG/USDC price was dimensionally plausible.
- This was a unit / decimal integration failure. The market-specific oracle setup did not correctly account for the
Three oracle-authority promotions this incident collapsed
-
A configurable market-local oracle path already existed
MorphoChainlinkOracleV2was a legitimate oracle adapter, and the market had a syntactically valid deployed price path forPAXG / USDC.- The weak first fact was only
this market now has some reachable local oracle object with constructor-supplied decimal assumptions.
-
That locally valid adapter instance was over-promoted into canonical solvency truth for this market
- The bad
SCALE_FACTORmeant the deployedprice()answer no longer described the economically correct1 PAXG in USDCobject, but the market still accepted it as if asset identity, quote direction, and decimal normalization were all already resolved. - The stronger promotion was therefore not just
the oracle contract deployed successfully, butthis exact deployed parameter tuple deserves to define borrow power for the live PAXG/USDC market.
- The bad
-
That accepted local truth inherited immediate live borrowing authority with real liquidity behind it
- A fresh curator-deployed market with high LLTV and available USDC liquidity let the wrong price object become spendable debt authority immediately, instead of first passing through a quarantine or canary stage.
- Once that happened, the cash-out path was trivial: supply a tiny amount of PAXG, let the misconfigured oracle mark it at fantasy size, then borrow real USDC through the ordinary market flow.
- Exploit path:
- A new PAXG/USDC Morpho market went live with a misconfigured oracle.
- The faulty oracle made PAXG appear worth roughly
10^12times more than intended, with public writeups summarizing the result as gold priced around$2.6T. - The attacker identified the bad price and supplied only about
$350of PAXG as collateral. - Using the fake collateral value, the attacker borrowed about
$230,000USDC from the market in attack tx0x256979ae169abb7fbbbbc14188742f4b9debf48b48ad5b5207cadcc99ccb493b. - The borrowed USDC left the market while the residual PAXG collateral was economically meaningless.
- The market curator later stated that repayments and lender protection were handled outside Morpho to prevent further opportunistic extraction, which is why the market UI did not cleanly reflect the remediation path.
- What the attacker needed to be true:
- The market’s final oracle output had to be accepted as authoritative borrow power without a reasonableness bound.
- The market needed available USDC liquidity and a high enough LLTV for the fake PAXG valuation to monetize into a large real borrow.
- The attacker only needed to notice the bad price before the market was paused or socially quarantined; no flash loan or external market manipulation was required.
- Curator-side remediation had to be slower than the initial borrow, because the profitable step was a single ordinary collateralized loan against a wildly wrong price.
- Technical anatomy worth remembering:
- This is a clean example of the difference between
oracle manipulationandoracle configuration failure: nobody had to move the gold market or distort Chainlink itself; the deployer simply instantiated the quoting logic with bad decimal assumptions. - Morpho’s oracle code is unusually explicit about the danger. The constructor comments for
MorphoChainlinkOracleV2literally listDecimals passed as argument are correctas an assumption, andSCALE_FACTORis derived directly from token and feed decimals. - That makes the preserved lesson sharper than
someone typed the wrong number. The oracle abstraction was flexible enough to support many feed compositions, but that flexibility pushed dimensional correctness onto the market deployer. - It is also a useful permissionless-market case study: the immutable base protocol can remain technically correct while a curator-deployed market still goes live with self-destructive pricing.
- This is a clean example of the difference between
- Representative transactions and artifacts:
- Attack transaction:
0x256979ae169abb7fbbbbc14188742f4b9debf48b48ad5b5207cadcc99ccb493b - Attacker EOA:
0x02DBE46169fDf6555F2A125eEe3dce49703b13f5 - Reported attack contract:
0x4095F064B8d3c3548A3bebfd0Bbfd04750E30077 - Misconfigured oracle:
0xDd1778F71a4a1C6A0eFebd8AE9f8848634CE1101 - Market ID:
0x8eaf7b29f02ba8d8c1d7aeb587403dcb16e2e943e4e2f5f94b0963c2386406c9 - Morpho Blue core contract used by the market:
0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb
- Attack transaction:
- Response / mitigation:
- LeadBlock published a retrospective on 2024-10-15 stating that the affected PAXG/USDC market was its smallest vault allocation at about
4%, that no user funds were ultimately lost, and that the market should not be used going forward. - That same retrospective emphasized the issue was in the market’s oracle setup, not in Morpho Blue’s immutable smart contracts, and said the bad borrow had been repaid to the vault and the lender.
- A follow-up governance-forum reply then pointed out that the public market UI still appeared to show residual undercollateralized debt and direct-lender exposure; LeadBlock answered that some repayments had been handled outside Morpho specifically to avoid malicious players exploiting the cleanup flow, which is why the onchain market state and the full remediation path did not line up cleanly in the UI.
- The operator-side takeaway was to add stronger market-creation and testing procedures before launch, especially around final oracle parameter review and live-price sanity checks for curator-deployed markets.
- LeadBlock published a retrospective on 2024-10-15 stating that the affected PAXG/USDC market was its smallest vault allocation at about
Pattern tags
- oracle-configuration-failure
- unit-normalization-failure
- The preserved failure shape is not
Chainlink brokeorMorpho core bug: a curator-deployed market instantiated a mathematically general oracle contract with the wrong decimal assumptions, and that constructor-time choice became finished solvency truth for a live PAXG/USDC market. - This is also a useful
permissionless market launch published nonsense balance-sheet truthexemplar. Morpho Blue’s immutable core kept its contract-level promises, but the market still failed because the deployer-controlled finalprice()object was dimensionally wrong and immediately honored as borrow power.
Why the exploit worked
- Morpho’s own oracle contract is unusually explicit about the trust boundary.
MorphoChainlinkOracleV2says outright thatDecimals passed as argument are correctis an assumption, and its constructor computes one sharedSCALE_FACTOR = 10 ** (36 + quoteTokenDecimals + quoteFeedDecimals - baseTokenDecimals - baseFeedDecimals) ...so thatprice()returns the quantity of loan asset per unit of collateral, scaled by1e36. - That means the dangerous object was not the raw Chainlink feed. The dangerous object was the deployer’s final dimensional statement about the market: what exactly
1 PAXGshould mean inUSDCterms after the oracle multiplied feed answers and applied the constructor-time exponent. - The attacker succeeded because the market launched with that final dimensional statement already wrong by
10^12. Once the misconfigured oracle published a huge but syntactically validprice()answer, Morpho Blue’s immutable lending core had no basis to reject it as economically absurd; it simply converted the fake collateral mark into real USDC borrowing capacity. - The exploit path was therefore the clean permissionless-market version of
deposit tiny collateral -> borrow real assets. No external price manipulation, flash-loan distortion, or governance race was needed. The protocol itself exposed the borrow path after the misconfigured market treated about$350of PAXG like protocol-scale collateral. - The preserved lesson is broader than
double-check decimals. In a permissionless or curator-deployed system, constructor arguments, deployment manifests, and market-listing review are part of the balance sheet whenever they decide the final oracle object the core will honor.
Detection and audit pivots
- Reconstruct the final market price as dimensional algebra before launch:
collateral / loan, final scale1e36, raw feed decimals, and the exact exponent encoded intoSCALE_FACTOR. If reviewers cannot write that object down plainly, the market is not ready for live borrowing. - Treat constructor arguments and deployment calldata as security-critical oracle artifacts, not harmless wiring. Morpho’s oracle code was transparent about its assumptions; the missing control was independent review of the concrete decimals and resulting live answer.
- Compare the deployed market’s final
price()against at least one external reference before enabling meaningful debt. If PAXG appears able to support six-figure USDC borrows from a few hundred dollars of collateral, the system should fail closed before anyone can call the ordinary borrow path. - Permissionless-market safety needs a second boundary after immutable-core correctness. Curator factories, front-end listing flows, and market-launch playbooks should quarantine fresh markets with tight caps or isolated exposure until the live price path is reconciled.
- Cleanup design matters too. LeadBlock’s retrospective and the follow-up forum question preserve a secondary operations lesson: when remediation occurs partly outside the lending core, public onchain state may no longer cleanly express who is economically made whole, so incident notes should preserve both the protocol-state view and the operator-side settlement narrative.
Failure-prevention checklist
- Treat the final deployed oracle object as the review target, not the upstream feeds in isolation. Reviewers should sign off on
what 1 unit of collateral means in loan-token terms, the exact1e36scaling, and the constructor-time exponent that produces that answer. - Require an independent decimals worksheet before launch.
baseTokenDecimals,quoteTokenDecimals, feed decimals, vault-conversion samples, and the impliedSCALE_FACTORshould be recomputed outside the deployment script and matched against the onchain constructor arguments. - Use deterministic deployment helpers and typed manifests, then still review the manifest. Morpho’s own README recommends the factory, but factory use is not enough if the underlying decimal inputs are wrong.
- Gate new markets behind low caps, isolated lender exposure, borrow-side throttles, or observation-only windows until the live
price()output is reconciled against at least one trusted external quote and one unit test that exercises the exact deployed parameters. - Add hard sanity bounds at market activation time: if the final price implies obviously impossible borrow power for a dust collateral deposit, the market should pause or fail closed before debt opens.
- Separate immutable-core confidence from curator-market confidence. Permissionless or semi-permissionless listing flows still need explicit launch review because the published oracle object is itself a balance-sheet authority surface.
- Preserve a remediation lane that can make lenders whole without silently leaving ambiguous residual onchain state. If repairs happen partly outside the market, publish that split clearly so later reviewers do not mistake UI residue for unresolved protocol exposure or vice versa.
- Keep deployment artifacts, oracle manifests, and reviewed constructor arguments together. The dangerous diff is often not contract code changing after audit, but a market going live with one bad parameter tuple.
Audit prompts
- What exact quantity does this market’s deployed
price()claim to return, in plain units, before anyone borrows against it? - Where did reviewers independently recompute
SCALE_FACTOR, and did they use the collateral token decimals, loan token decimals, feed decimals, and any vault-underlying decimals rather than guessing from UI labels? - If I deposit one minimal but nonzero unit of collateral, what borrow power does the market grant, and is that output economically plausible relative to external spot references?
- Are factory defaults, deployment scripts, or copied manifests carrying hidden decimal assumptions from a prior market with a different quote token or vault shape?
- What launch-stage controls keep a brand-new market from receiving full borrow authority the moment its oracle is deployed?
- If the market is permissionless or curator-run, who owns the last
this price object is fit for live debtdecision, and where is that approval recorded? - Can front ends, monitoring, or keepers surface absurd live prices quickly enough to stop opportunistic first-borrow extraction, or is the first meaningful alert still the bad debt itself?
- If remediation must occur outside the core market, how will operators distinguish
economic losses are coveredfromonchain state still looks broken, and how will lenders verify which view is authoritative?
Lessons that should already be standard
- Immutable core correctness does not rescue a market whose published price object is nonsense. In lending, the final oracle configuration is part of the balance sheet.
- Decimal parameters are not clerical metadata. They are solvency logic whenever they decide the exponent on live collateral values.
- Factory deployment and audited oracle code reduce risk, but neither substitutes for reviewing the exact constructor tuple that the market will honor as debt authority.
- Fresh markets deserve quarantine. A brand-new collateral path with a new oracle should not inherit full borrow power just because the contracts are standard.
The protocol worked as designedandthe market was safeare different claims. Permissionless-market systems need explicit controls for the gap between them.- Operator remediation can hide or repair economic damage without cleaning up the protocol’s visible state. Incident writeups should preserve that distinction because it affects how later readers interpret residual debt, lender exposure, and UI artifacts.
Why this incident matters
- It is a compact, high-signal unit-mismatch exemplar for oracle-configuration-failure notes.
- It preserves a recurring permissionless-protocol lesson: immutable core safety does not save lenders if market deployers can publish nonsense collateral prices.
- It also shows why dimensional sanity checks belong on the final market price, not just on upstream feed freshness or on faith that a permissionless market deployer passed the constructor arguments correctly.
Internal linkages
- Core recurring pattern: oracle-configuration-failure.
- Narrower recurring lens: unit-normalization-failure.
- Positive-design companion: price-domain-and-reciprocal-range-discipline — the sharper review failure was that the market never published a trustworthy domain sheet for the final
PAXG / USDCsolvency object before launch. - Positive-design companion: collateral-admission-lag-and-borrow-side-quarantine — the rollout failure was that a fresh curator-deployed market with a new oracle path received immediate borrow authority instead of a tighter quarantine window.
- Adjacent but attacker-driven family: oracle-manipulation.
- Useful comparison incidents: moonwell-cbeth-usd-oracle-misconfiguration-bad-debt-liquidations-2026-02-15 and aave-wsteth-capo-snapshot-misalignment-liquidations-2026-03-10.
Control surface
-
The decisive leverage sat with the market deployer and oracle provider who chose the decimal parameters and published the final PAXG/USDC price path, not with Morpho Blue’s immutable core contracts.
-
Once that market-specific configuration turned
price()into fiction, the rest of the lending stack did exactly what lending protocols always do: honor the fake collateral and release real liquidity. -
Sources:
- https://forum.morpho.org/t/retrospective-paxg-usdc-market-oracle-configuration/891.json
- https://blog.verichains.io/p/morpho-protocol-market-oracle-price
- https://blog.solidityscan.com/morphoblue-hack-analysis-638b685f8bf2/
- https://medium.com/coinmonks/decoding-morphoblues-230k-exploit-6296565ced40
- https://raw.githubusercontent.com/morpho-org/morpho-blue-oracles/main/src/morpho-chainlink/MorphoChainlinkOracleV2.sol
- https://raw.githubusercontent.com/morpho-org/morpho-blue-oracles/main/README.md
-
Last reviewed: 2026-08-05 UTC