# My Personal Blog: Creating a POC ###### tags: `blogs` ![](https://i.imgur.com/U2dHTIT.png) ### Making a POC When auditing smart contracts, many programs will require the creation of a POC, or Proof of Concept, of any exploit that auditors find. This is usually done through the recreation of the exploit on a test environment. Sometimes, this can be very difficult for auditors, especially if the smart contract is large (as in requires multiple contracts working together). In the following, I provide my personal guide into creating a working POC for Smart Contracts. This requires knowledge of the language `Solidity`, which you can get by following this tutorial. ___ ### Setting up a POC when test cases are provided ![](https://i.imgur.com/7tweBkD.png) In Code4rena audits and (sometimes) Immunefi auditing challenges, ___test cases___ may be provided. In that case, making a POC usually only involves: + Downloading dependencies with `yarn`, `forge`, `npm`, or whatever program that the Smart Contract deploys their tests with (usually provided) ![](https://i.imgur.com/vhk7kki.png) + Modifying the test cases to replicate your exploit ![](https://i.imgur.com/SCYrjfd.png) + Run and check results And that's it! Submit the POC along with the required explanations of the exploit for judgement in the bug-hunting program. ___ ### Setting up a POC when test cases are not provided ![](https://i.imgur.com/gisCdDa.png) When test cases are not provided, things may get difficult. In order to realize an exploit, one may need to simulate the entire ___on-chain___ contract from an __off-chain__ environment. + The first step is the same: ___install dependencies___. In bug-hunting programs, the tool for installing dependencies is always provided. + `foundry`, `npm`(hardhat), and `yarn` are all popular package-installing tools. + The second step is to __create a `config` file__. This allows you to deploy the contract in the test space. You may need to go onto __Alchemy.api__ or similar programs in order to get a suitable test environment. ![](https://i.imgur.com/EOO1Ypy.png) + Sometimes, contracts may tell you places to change in order to deploy test environments: ![](https://i.imgur.com/zN1Vaku.png) + Othertimes, you may need to create a `config` file all by yourself and/or replace the `config` file with one of your own. The `config` file template that I use is: ```solidity= require("@nomiclabs/hardhat-waffle"); require("@nomiclabs/hardhat-web3"); require('@openzeppelin/hardhat-upgrades'); /** * @type import('hardhat/config').HardhatUserConfig */ module.exports = { solidity: { version: "0.8.4", settings: { optimizer: { enabled: true, runs: 1000, }, }, }, networks: { hardhat: { loggingEnabled: false, forking: { url: "YOUR URL HERE", chainId: 4, } } } }; ``` + The third step is to __create a `.js` or `.ts` deployment file__. This file will be used to deploy certain contracts and clone certain accounts. This is basically your setup file. Here is a template file that I use. ![](https://i.imgur.com/ogvKGj5.png) ```typescript= const { ethers } = require("hardhat"); const { solidity } = require("ethereum-waffle"); //other requirements async function main(){ //stuff } main().then(() => process.exit(0)).catch((error) => { console.error(error); process.exit(1); }); ``` + The fourth step is to start __deploying contracts__. Start with whatever main file you have found your exploit in. There can be many of these deployments, and it can get frustrating, but don't give up! You can make modifications to certain files if you are __ABSOLUTELY SURE__ that they do not interfere with normal contract function or your exploit. Such cases may include certain `locks`, or `requirements`. + You can also `clone` deployments from the blockchain, if the addresses are provided (like in Immunefi). __Always `clone` the deployment if you can --- it results in a more accurate exploit__. You can __deploy__ a `Solidity` contract with the following script in your `.js` or `.ts` file: ```typescript= //Deploy ContractName const _contractNameDeployer = await ethers.getContractFactory("ContractName"); const contractNameDeployed = await _contractNameDeployer.deploy({input parameters}); console.log("[*] Successful Deployment"); ``` You __clone__ a `Solidity` contract with the following script in your `.js` or `.ts` file. One thing you may need to do is to go onto etherscan.io in order to find the addresses of related contracts. ```typescript= clonedContract = await ethers.getContractAt("ContractName", "DeployedAddress"); ``` + The fifth step is to __impersonate any accounts that you may want/need__ to access in your exploit. This can range from certain currencies like `ERC20`, to certain actors that can `mint` or `transfer`, to certain roles like `Owner` or `Oracle`. This can be done by finding the address of the account (through programs such as etherscan.io) and using the following script: ```typescript= randomDudeAddress = "hisAddress"; await hre.network.provider.request({ method: "hardhat_impersonateAccount", params: [randomDudeAddress], }); randomDude = await ethers.getSigner(randomDudeAddress); console.log("[*] Impersonate Successful"); ``` One easy way to impersonate an account that has a certain asset is to search the asset up on etherscan.io, and then click Holders: ![](https://i.imgur.com/D69IjsA.png) Then, chose an account __without a symbol__ next to the name, and you will be able to impersonate that account. ![](https://i.imgur.com/weQDVEZ.png) Accounts with symbols next to their name are Smart Contracts, not users. + The sixth step is to __create a Smart Contract yourself in order to recreate your exploit__. Having a `Solidity` Smart Contract for your exploit ensures that everything you are doing in your exploit occurs within one transaction. ![](https://i.imgur.com/HebLndO.png) ![](https://i.imgur.com/5pgmegv.png) You should have everything you need now in order to recreate the exploit. Implement your exploit and see if it works. ___ ### Summary This is my guide on how to write a POC. ItsNio