
Finding smart contract bugs can be a highly rewarding endeavor, and it also protects the ecosystem from hackers. I recently had the pleasure of interviewing a developer who found a $7 billion bug and was paid $2.2 million for reporting it.
In this post, I'll walk through the process of finding the bug this developer found, how it had the potential to damage $7 billion in value, and then offer some strategies and tools to help you find the bug.
let's start.
Polygon smart contract bug case
background
On May 31, 2020, the Matic blockchain went live (Matic was later renamed Polygon). Polygon is an EVM-compatible blockchain known for its low gas fees and short block times. The chain recently started exploring zk- Rollup technology.
If you look at Polygon 's "genesis" block, the first block of the blockchain, you'll see 10 transactions. One of these transactions creates a contract called MRC20.

Polygon Genesis Block
What is this smart contract?
When we send native blockchain tokens, we have to spend gas. So the Polygon team deployed a contract that allows you to sign a transaction to send someone ETH, and someone else can pay the gas fee for that transaction. Known as “meta transactions,” this functionality became popularized with the introduction of EIP-712.
You can see that the contract was awarded nearly 10 billion Matic tokens to help facilitate these gas-free transactions. However, this neatly designed contract contains a bug that could be exploited to steal the entire balance!
On December 3, 2021, the protagonist of the story, pseudo-anonymous developer Leon Spacewalker, submitted a report to the Immunefi bug bounty program detailing the problem with this function. A second hero, whom we'll call Whitehat2, also reported the bug a day later.
Approximately 800,000 Matic were stolen before the chain was finally forked, rolled back, and fixed on December 5, 2021.
This incident raised many questions for us: What is a bug? How did it go undiscovered for so long? How was it discovered?
bug exploit
Below is the function to send a gasless transaction

At first glance, it seems harmless: it requires the user's signature, how many tokens they have, who they want to send the tokens to, further data, and an expiration date for the transaction.
It also has some restrictions, get the data hash to send the meta transaction, make sure the data hash is not used, and execute this ecrecovery function.
This function is essentially a Wrapper for the Solidity ecrecover function.

A wrapper for the Solidity ecrecover function
Here's the actual code: Our function verifies the origin of signed transactions. You'll notice that even in the Solidity docs, it says it will "return zero for errors". The same goes for the ecrecovery function, which returns 0 if there is a problem. As many developers know, this can be risky. If it returns zero on error, that means we should check to make sure the returned address is not zero, right?
Here's the actual code:

Here's the ideal code:

We don't actually perform a check on the address to make sure it doesn't cause an error, okay. The last line of code in the transferWithSig function does the actual transfer, surely we have to perform some kind of check there, right?

The _transferFrom function just called our _transfer function, shown above. You'll notice it doesn't check to make sure the from address has enough balance.
This means someone can send an invalid signature, which will result in a zero address being returned from ecrecovery, but the MRC20 contract will still send a certain amount of tokens to the to address. This is how 9,999,993,000 Matic was stolen, as the MRC20 contract sends tokens directly from itself!
This problem can be avoided if there is a check in the contract to ensure that the sender address has enough balance for this signed transaction.
Why smart contract bugs have not been discovered for a long time
It's odd to me that after the bug had been dormant for almost a year and a half, it was discovered within a few days by another white hat, Leon, and a hacker.
Seems tricky, but the Immunefi team told me it happens quite often. Some bug exploits may become popular as a result of an article, article, or challenge, and then people start looking for the bug, causing multiple people to find it at the same time.
But more likely, it turns out that Polygon verified the contract on Polygonscan around this time - and that's when people really started paying attention to it.
Maybe there's more to the story, but maybe not.
Anyway, let's use this bug as a teaching case to see some of the skills Leon and other bug hunters use to find bugs and help protect the Web3 ecosystem.
7 Tips for Spotting Contract Bugs
Now, we'll learn the skills Leon and other bug hunters use to find these bugs and apply for bug bounties. This list of tips assumes that you already know the basics of smart contracts, so yes, learning Solidity is a prerequisite.
Please use these techniques ethically, and remember to responsibly disclose any bugs you find.
Much of the work of finding bugs comes from looking at code and running tools like slither. For this $2.2 million harvest, Leon said that he was able to find the bug by going through the smart contract code line by line, so keep in mind that finding bugs usually requires a lot of manual work!
In addition to the following practical tips, Leon's biggest gain is to let the smart contract bug hunter "find your advantage", what does it mean? Often, that means finding what sets you apart from everyone else. As a community, we need to cover every corner of the smart contract space, so find the parts you are particularly good at and good at.
Here are seven strategies and tips to help you find an edge and become a successful smart contract bug hunter.
1. Find a project and search for bugs
The first way to find the bug is to understand how the protocol works in detail. This is one of the first skills every smart contract bug hunter needs to learn: the ability to understand the protocol end-to-end.
Go through the documentation, try to reimplement the protocol yourself, and view transactions through it on a block explorer.
Leon says this strategy works for other bug hunters, but not for him. He focuses on the next three, but it's important for every bug hunter to be able to do this.
2. Find the bug and search the project
An easier way to find bugs is to find a little-known bug and try to see which protocols implement it. This strategy requires a lot of research as there are many people working on exposing bugs to the public: https://swcregistry.io/
You first need to understand all the basic smart contract bugs, and then their advanced versions. You need to be aware of best practices and see if there are any protocols you are not following.
Once you find a smart contract bug that you think many projects may not be able to defend against, start searching for that bug. Until I get really familiar with this new bug and how to find it. Be sure to write a blog or some kind of post to help other smart contract developers who encounter this bug.
3. Be quick
Projects that want bug hunters to view their smart contracts need to sign up for a bug bounty program like Immunefi. You'll want to be one of the first developers to spot a new bounty. If you start looking at contracts before other hunters, you'll have more time to find bugs.
There are a few ways to speed things up — one of the ways Leon was able to find smart contract bugs before anyone else was through notifications on the Immunifi Discord channel. He will be notified whenever a new item comes in or an item is updated. Tools like this can help you dig into your code before everyone else does.
4. Be creative
Another way Leon got an edge was by checking out the plethora of community forums and finding out that they were considering submitting bugs. He then started looking at the smart contract even before the bounty was approved. This gives him more time to review the contract than other developers, who will wait for the project's bug bounty submission to be successful.
5. Know your tools
Bug hunters use VSCode Solidity extensions, Hardhat, Foundry, Brownie, Dune, Etherscan, and many others.
A good bug-finding strategy might be to load VSCode, use the Solidity extension to add code to VSCode, and then look for common errors or vulnerable code implementations line by line.
After finding potential vulnerabilities, set up the test environment to run tests on the contract. You can often reuse a large number of tests originally used by the protocol developers.
6. Don’t abandon audited projects
Not much to say here. Audit firms make mistakes. Many of the projects where Leon found vulnerabilities have been audited by top companies.
Using the techniques we discuss in this blog can help you find these problems!
7. Industry specific knowledge
One of your greatest strengths may be to specialize in a specific niche. If you know a domain well, you'll have the knowledge to understand how all the functions call each other. On the contrary, if you are a powerful smart contract vulnerability expert but know nothing about DeFi, it will be difficult to find vulnerabilities in DeFi contracts. For example, many developers understand code but not financial jargon.
You could be really good at understanding decentralized exchanges, lending protocols, or just NFTs!
If you can become a security expert and an expert in a certain vertical field in Web3, you will be in a good position to gain an advantage over other people who are looking for vulnerabilities.
Summarize
I hope this article helps you on your smart contract bug hunting journey. If you want to learn more about security when writing smart contracts, be sure to check out the Top 10 DeFi Security Best Practices.
And, as always, I'd love to see you build out there and keep the ecosystem safer.
Related Links:
👉 MRC20 contract:
https://polygonscan.com/address/0x0000000000000000000000000000000000001010#code
👉Immunefi writeup:
Polygon
👉Change to Polygon contracts:
https://github.com/maticnetwork/contracts/commit/55e8118ad406c9cb0e9b457ca4f275c5977809e4#diff-cc4ed03464edad9d87d48cff647eb6940dfe9a4c419f63e3994bdc91b01bfecb
👉Previous Polygon contracts:
SOL
👉Ecrecovery challenge:
https://github.com/code-423n4/2021-09-swivel-findings/issues/61




