# MPT Vulnerability disclosure
Protocols fully inherit the risks of the oracle they rely on. Yet, I feel like many people underestimate the security of the oracles just trying to deliver new projects fast. Even the best of us can sometimes miss a line of code that can lead to millions of dollars at risk.
Wild Wild Eth.
By the time I've discovered this vulnerability, Moscow was under drone attack. It was a grim, unsettling feeling to realize that core DeFi protocols were actively vulnerable at the same time the real world around me was heading toward destruction.
### Brief description
The vulnerability was found in a Solidity library designed to validate Merkle-Patricia-Trie (MPT) proofs — a core part of Ethereum’s storage structure. In Ethereum, on-chain data (accounts, balances, contract storage) is organized in a specialized data structure called a trie, which allows efficient verification of data using cryptographic proofs. This library was meant to validate such proofs against a given blockhash or state root and return the actual value stored in a specific slot. If the value doesn’t exist in the trie, it should correctly return the default — zero.
From the documentation:
```solidity
/// @dev Validates a Merkle-Patricia-Trie proof.
/// If the proof proves the inclusion of some key-value pair in the
/// trie, the value is returned. Otherwise, i.e. if the proof proves
/// the exclusion of a key from the trie, an empty byte array is
/// returned.
```
The proof validation works by iteratively traversing trie nodes, one after another, until the final leaf node is reached and its value is returned. But one check was missing: when transitioning from one node to the next, the library failed to verify whether the next node was actually provided in the proof. This omission could have allowed a malicious actor to truncate the proof and force the function to return zero for any slot.
[Problematic code](https://github.com/lorenzb/proveth/blob/c74b20eac1f5f14a82ab1e8bb63fdd20a64309c5/onchain/ProvethVerifier.sol#L384-L409):
```solidity
function validateProof(...) returns (bytes memory value) { // defaults to zero
...
for (node in proof) {
...
if (node is branch) {
if (leaf not reached) {
check that current node is correct
calculate next node
// but no check if next node exists
}
}
...
}
// no extra check for being not reachable
}
```
### Attack vectors
Depending on how the library is used, several attack vectors become possible.
- In governance systems, an attacker could zero out someone’s voting power or prevent them from receiving incentives.
- In price oracles, an attacker could zero out one of the oracle parameters (which might normally have a value like 10^18), drastically skewing the returned price.
### Affected protocols
This library is already six years old and it was in use by major protocols. Among those affected were AAVE, FRAX, and StakeDAO. As a Curve developer, I was adopting this library for a few oracles. Lido deprecated contracts using it back in the days.
I had no intention of stealing funds — only to fix the issue in a fair and ethical way. I had no prior experience in disclosing such vulnerabilities. So immediately after the discovery, I reached out to Tanguy from [ChainSecurity](https://www.chainsecurity.com) (a leading security audit company) to help coordinate a responsible disclosure. I already knew them from the numerous audits they have been doing for code I did for Curve, and knew they were trustworthy. They did an amazing job in helping to identify every contract using the library, and organizing coordinated disclosures to the core teams at risk by the exploit. I cannot thank them enough for their professionalism.
All of the affected protocols were extremely fast to respond and patch the vulnerability. Despite some initial skepticism from people around me, every team conducted thorough investigations, reviewed proof-of-concepts where needed, and ultimately handled the situation with full integrity. Respect to these teams — they mean what they say.
By the time of writing this I've already had a drone shot down near my apartment. Hopefully, noone's hurt, including mentioned protocols.
Safu.
__Full technical breakdown by ChainSecurity:__ https://www.chainsecurity.com/blog/when-empty-means-valid-exploiting-mpt-proof-verification-for-an-alternative-truth
_P.S. As a Vyper-maxi, I’ll just note: this kind of bug is harder to create in Vyper._
# About me
I am Vyper Developer at [Curve Finance](curve.finance) with audit experience.
We developed Curve Block Oracle infra for crosschain storage proofs available for everyone. You can check it at [curvefi/blockhash-oracle](https://github.com/curvefi/blockhash-oracle).
Contact: [x.com/agureevroman](https://x.com/agureevroman)