# How to create a bug bounty for smart contract project on Bug Buster In this tutorial, you will learn how to create a bug bounty on [Bug Buster](https://www.youtube.com/live/t0tUpCwiOpk?t=644s) for a smart contract project! Bug Buster expects bounties to be submitted in a particular format. All the necessary files (such as source code, binaries, etc.) must be bundled as an archive file with `tar` and compressed with `xz`. The final product should be a file with the `.tar.xz` extension. The archive file should contain a `start.sh` file, which is the entry-point that will be called by the Bug Buster back-end when someone tries to exploit your bounty. It passes the path of the exploit file as argument, and checks the status code returned by the Shell script. If it exits with status code 0, it marks the exploit as valid and rewards the hacker. In the case of smart contract bounties, the bundle only needs to contain the Solidity files of your project and its dependencies, and a few other files. The Bug Buster back-end already contains [Reth](https://reth.rs/), a production-level Ethereum node, [Forge](https://book.getfoundry.sh/forge/), a development smart contract development tool, and the [Solidity](https://soliditylang.org/) compiler. :::warning This is a draft version intented for early adopters and alpha testers. ::: ## Requirements In order to follow this tutorial you will need to have the following dependencies installed on your machine: - [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) - [Cartesi CLI](https://docs.cartesi.io/cartesi-rollups/1.5/development/installation/) - [Foundry framework](https://book.getfoundry.sh/getting-started/installation) ## Preparing the project To demonstrate how to submit a bounty for a smart contract project, let’s start with a new Forge project from scratch. 1. Create a directory called `counter-bounty` ``` bash mkdir counter-bounty cd counter-bounty ``` 2. Create a forge project in it ``` bash forge init ``` 3. Let's start deleting the files `script/Couner.s.sol` and `tests/Counter.t.sol` which are created by default, but will not be used in this tutorial. ```bash rm script/Counter.s.sol test/Counter.t.sol ``` 4. Also by default, forge creates a smart contract on `/src` folder called `Counter`, which has a state variable `number`, whose value can be set calling the function `setNumber` and can be incremented by 1 calling the function `increment`. See the code below. ```solidity // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; contract Counter { uint256 public number; function setNumber(uint256 newNumber) public { number = newNumber; } function increment() public { number++; } } ``` 5. For the purpose of this tutorial, let’s change a bit this code by changing the function `increment` to intentionally insert an [arithmetic overflow](https://101blockchains.com/underflow-and-overflow-vulnerabilities-in-smart-contracts/) vulnerability. :::danger Never do this on code that is intented to be deployed on mainnet! ::: ```solidity // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; contract Counter { uint256 public number; function setNumber(uint256 newNumber) public { number = newNumber; } function increment() public { unchecked { number++; } } } ``` 6. Great! You are almost there. Now, you will need to create a `start.sh` script file in the root folder, which is the entry point for the execution of your project on Bug Buster. This script must: deploy your contract, set the initial state, execute the exploit code and, finally, run the assertions to check if the contract was exloited or not. Just paste the code below and read the comments to understand the sequence of actions. ```bash #!/usr/bin/env bash source ./setup-exec-env.sh >&2 echo "Deploying and registering project contracts..." COUNTER=$(deploy_and_register src/Counter.sol Counter) >&2 echo "Deploying exploit contract..." EXPLOIT=$(deploy src/Exploit.sol Exploit) >&2 echo "Running exploit..." send "$EXPLOIT" 'run(address)' "$REGISTRY" >&2 echo "Verifying contracts after exploit execution..." number=$(cast call "$COUNTER" 'number()(uint256)') if [ "$number" -eq 0 ] then >&2 echo "Valid exploit!" exit 0 else >&2 echo "No exploit found." exit 1 fi ``` :::warning Set the execution permission for this file using the following command: chmod +x start.sh ::: 7. As you may have noticed, the `start.sh` file that was provided depends on another script called `setup-exec-env.sh`. This script prepares Bug Buster's execution environment and must be kept with no modifications! :wink: You can download it using the commands below. ```bash wget https://raw.githubusercontent.com/crypto-bug-hunters/bug-buster/refs/heads/next/tests/bounties/src/adder/setup-exec-env.sh chmod +x setup-exec-env.sh ``` 8. You will also need to add 2 more files to your project: a smart contract called `Register.sol` and its corresponding interface `IRegistry.sol`. As their name suggest, they register the deployment addresses of the project's contracts and make them available for all execution stages declared in the `start.sh` file (it will become clearer later, when you read about the exploit code example). Download these files inside the `src` folder using the command below. ```bash wget https://raw.githubusercontent.com/crypto-bug-hunters/bug-buster/refs/heads/next/tests/bounties/src/Register.sol wget https://raw.githubusercontent.com/crypto-bug-hunters/bug-buster/refs/heads/next/tests/bounties/src/IRegister.sol ``` 9. At this point you should be able to compile the code to check if everything is working as expected. You can do it by executing the following command and the result should be "Compiler run successful!". ``` bash forge build ``` 10. Now, we have everything set up to create your bounty's bundle. The command below creates the `counter-bounty.tar.xz` file using the Forge cache to list all Solidity files necessary to compile the project. This helps reduce the size of the bundle, and, therefore, the cost of the base layer transaction. ```bash jq -r '.files|keys[]' cache/solidity-files-cache.json | \ xargs tar -cJf counter-bounty.tar.xz setup-exec-env.sh start.sh foundry.toml ``` ## Cloning Bug Buster and running it locally 1. Clone Bug Buster repo ``` bash https://github.com/crypto-bug-hunters/bug-buster.git ``` 2. Switch to the branch in which the implementation for supporting smart contract bug bounties is committed. ```bash cd bug-buster git switch next ``` 3. Follow the instructions provided in the README file to properly run the [back-end](https://github.com/crypto-bug-hunters/bug-buster/blob/next/docs/backend.md) and the [front-end](https://github.com/crypto-bug-hunters/bug-buster/blob/next/docs/frontend.md) on your machine. :::info The `make machine` command may take some minutes to complete for the first time. This command builds the Cartesi Machine with a full Linux distro plus the Solidity compiler, Foundry, Reth, etc. :sweat_smile: ::: ## Configuring your wallet 1. Having the back-end and the front-end running, access Bug Buster front-end at http://localhost:3000/ 2. Open your wallet to configure the local development network and to import a valid account on this environment. :::warning Check the links below for instructions on how to do the configuration using Metamask. If you use another wallet, don't worry because these are common configurations and it will not be difficult to find information on how to do that in your wallet. ::: - To [add a local development network](https://support.metamask.io/networks-and-sidechains/managing-networks/how-to-add-a-custom-network-rpc/#adding-a-network-manually) provide the following info: - Network Name = Cartesi Devnet - RPC URL = 127.0.0.1:8545 - Chain ID = 31337 - Currency symbol = ETH - To [import one of the default accounts provided by Cartesi CLI](https://support.metamask.io/managing-my-wallet/accounts-and-addresses/how-to-import-an-account/), choose one of the 3 accounts below. All of them have an initial balance of 1000 ETH. :money_mouth_face: ```bash Available Accounts ================== (0) 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 (10000.000000000000000000 ETH) (1) 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 (10000.000000000000000000 ETH) (2) 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC (10000.000000000000000000 ETH) Private Keys ================== (0) 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 (1) 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d (2) 0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a ``` ## Creating the bug bounty 1. Click on *Explore bounties*. 2. Click on *Create bounty*, and fill in the required form fields. - For the *Token Address* field, enter the address for TestToken(`0x92C6bcA388E99d6B304f1Af3c3Cd749Ff0b591e2`) an ERC-20 contract provided by Cartesi CLI for testing purpose. - Upload the `counter-bounty.tar.xz` file. 3. When ready, click on the *Create* button. - Your wallet will ask you to confirm the transaction. Do it and wait until the notification with your transaction confirmation arrives. 4. Once the transaction is confirmed, navigate back to the *Explore bounties* page and your recently created bounty must be listed there (sometimes it takes 2-3 seconds to appear). ## Testing the bug bounty All right! The bug bounty for your project was created and now you can send some solidity code to interact with it. 1. Click on your bounty card in the *Explore bounties* page. 2. Confirm that your wallet is connected. 3. Click on *Submit exploit* and fill the required fields in the form. In the script tab, paste the code below that just initializes `number` to 1 and then call the increment method. ``` solidity // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.27; import {IRegistry} from "src/IRegistry.sol"; import {Counter} from "src/Counter.sol"; contract Exploit { function run(IRegistry registry) external { Counter counter = Counter(registry.get("Counter")); counter.setNumber(1); counter.increment(); } } ``` 4. Click on *Submit* and wait until the notification informing that your transaction was successful. 5. Once the transaction is confirmed, navigate back to the *Explore bounties* page and find the card for your bounty. You will see that there will be no red badge informing "Exploited" on it. Isn't it awesome!? You submit a solidity code to interact with the bug bounty for the `Counter` smart contract running in a sandboxed production-level EVM (Reth) inside an altVM (Cartesi Machine)! :shocked_face_with_exploding_head: ## Hacking the bug bounty Now it is time to become a white-hat-hacker and submit a code to exploit the arithmetic overflow that was introduced. 1. Follow the same steps of the last section, but this time paste another solidity code to exploit the vulnerability that was intentionally added in the `Counter` smart contract and click on *Submit* button. ```solidity // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.27; import {IRegistry} from "src/IRegistry.sol"; import {Counter} from "src/Counter.sol"; contract Exploit { function run(IRegistry registry) external { Counter counter = Counter(registry.get("Counter")); uint256 currentNumber = counter.number(); uint256 maxUint256 = type(uint256).max - currentNumber; counter.setNumber(maxUint256); counter.increment(); } } ``` 2. Once the transaction is confirmed, navigate back to the *Explore bounties* page and find the card for your bounty. Now, you will see the red badge informing "Exploited"! 3. If you navigate to the *Vouchers List* page, you will see a voucher that will allow you to receive your reward. ![list vouchers](https://hackmd.io/_uploads/ryZLbYerkg.png) ## Proposal to dig deeper If you would like to explore more the smart contracts bounty feature, try to create a bug bounty for your own project or for a project that you like/support/use. :wink: ## Thank you! Thanks for following this tutorial and learn more about Bug Buster! :beetle: If you have any comments, suggestions and/or doubts, please don't hesitate to reach out through our [Telegram group](https://t.me/BugBusterApp) or [X account](https://x.com/BugBusterApp).