Introduction
One of the key skills that separates advanced hackers from beginners is the ability to write a proof of concept (PoC). A PoC is essentially runnable code that demonstrates a smart contract vulnerability without actually exploiting it in a live environment.
But writing a PoC can be challenging, especially if you’re not familiar with the specific details of setting up a test environment or underlying protocols which are needed to support a PoC.
That’s why we’re introducing PoC templates to revolutionize the bug report submission process.
With this PoC template repository, you can use pre-written code blocks to easily and quickly build PoCs for any bugs that you find–without having to start from scratch.
Why is this repo needed?
Building a PoC is challenging, even for elite hackers. Sometimes, it can be boring.
Additionally, many PoCs use similar design patterns, which are commonly repeated across different protocols, but because most PoCs in successful bug reports stay private, no one else can benefit from them. This means that whitehats have to write a lot of code from scratch for no good reason.
The templates we’ve designed are an open-source collaborative repository aimed at making PoC creation easier, more efficient, and even enjoyable. Making PoC creation easier will make creating bug reports easier, and more bug reports mean more security for projects and more bounty rewards for whitehats.
The repository provides pre-built templates for common vulnerability types like reentrancy, token manipulation, flash loans, and oracle price manipulation. These templates integrate design patterns commonly repeated across different protocols.
These PoC templates are designed to be approachable by all skill levels, with clear instructions on how to use the templates and customize them to your specific attack. By using templates, whitehats can save time and collaborate more effectively, ultimately leading to more secure and resilient blockchain ecosystems.
What are the difficulties of writing a PoC?
PoCs are required by almost all bug bounty programs on Immunefi. Even though PoCs are the de facto standard for showing concrete evidence a vulnerability exists in a web3 project, there aren’t many resources for reusable components. This leads to whitehats performing duplicate work for vulnerabilities with similar attack vectors.
For example, let’s say you’re testing a smart contract for reentrancy vulnerabilities. By using our reentrancy PoC template, you can quickly spin up a local fork of mainnet and test your code in a controlled environment. The Reentrancy contract defines a list of common callback functions which all call a standard method, _executeAttack
.
https://github.com/immunefi-team/forge-poc-templates/blob/main/src/reentrancy/Reentrancy.sol
https://github.com/immunefi-team/forge-poc-templates/blob/main/src/ReentrancyTemplate.sol
Extending the Reentrancy contract allows you to construct your attack in a standard way, making it easier for you to create a PoC that illustrates a specific class of vulnerability.
What PoC templates are available?
The following vulnerability templates are currently available:
- Reentrancy
- Token Balance Manipulation
- Flash Loan
- Curve Price Manipulation (Oracle Manipulation)
Using a reentrancy PoC template
To get a better idea of how these templates can be used, we’ll be recreating the Hundred Finance PoC, since it demonstrates a reentrancy attack and uses flash loans.
First, we’ll extend the flash loan and reentrancy modules, since we’ll be using a flash loan to get the initial capital required, and are exploiting a reentrancy vulnerability in Hundred Finance contracts. Additionally, we’ll import the Tokens module to reference the USDC address on Gnosis Chain more easily.
Next, we’ll override the fallback function and default to the Flash Loan module handler, as this pays back our flash loan after executing the attack.
To initiate our attack, we’ll call takeFlashLoan
, which takes a flash loan from the specified provider. The flash loan module automatically changes the contract addresses for the flash loan providers depending on which chain the local fork is running on by referencing block.chainid
. The default flash loan handler will also handle repayment, so all we need to implement is _executeAttack
, which is invoked by the default flash loan handler.
Now that we have our flash loaned funds, we can execute the attack on Hundred Finance’s markets by depositing our borrowed USDC as collateral and borrowing multiple tokens against it. Since the Reentrancy module also calls _executeAttack
, we can determine the invoker of the fallback by checking the function signature, msg.sig
, that was used to call our attack contract.
Finally, the function _completeAttack
is called before flash loan repayment, so we can swap the stolen xDAI to USDC be able to repay our USDC flash loan.
The full PoC can be seen here.
Summary
Writing a PoC can be a challenging task, but our PoC templates are here to help.
By providing pre-built templates and extendable contracts, the repository makes it easier for whitehats to secure smart contracts and test for vulnerabilities. Whether you’re a beginner or an advanced hacker, these templates can help you save time and effort.
If you’d like to know more about PoCs and our guidelines, you can check out the following links: