# Create a bug bounty for a project that uses OpenZeppelin contracts
In a [previous tutorial](https://hackmd.io/@claudioantonio/smartcontract-on-bugbuster-testnet) you learned how to create a bug bounty for a simple smart contract project on [Bug Buster](https://preview.bugbuster.app/) from scratch. For the sake of simplicity, a project with no external dependencies was chosen, but real projects commonly depend on one or more external dependencies.
As you may remember, 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.
Therefore, you may conclude that for projects with external dependencies you should have only to include the dependencies' source code to the bundle. This logic is right, but there is a limit to the size of bundles that can be sent on-chain, which is around 95KiB, according to tests on Optimism Sepolia and Mainnet.
## Built-ins: OpenZeppelin
In order to avoid bundles from surpassing the size limit, Bug Buster already includes commonly used artifacts in its execution environment. For smart contract projects, Bug Buster provides the [OpenZeppelin](https://www.openzeppelin.com/solidity-contracts) smart contract library out-of-the-box. The library contains ERC interfaces and implementations, as well as other utility libraries and contracts.
In this new tutorial you will learn how to prepare a project that depends on OpenZeppelin to be submitted as a bug bounty on Bug Buster.
## Creating the project
As we did in the first tutorial, let's create the project from scratch.
1. Create a directory called `counter`
```bash
mkdir counter
cd counter
```
2. Create a forge project in it
```bash
forge init
```
3. Let's delete the files `script/Counter.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. By default, forge creates a smart contract on the `src` folder called Counter, which has a state variable called `number`, whose value can be set by 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. Install OpenZeppelin executing the command below.
```bash
forge install OpenZeppelin/openzeppelin-contracts --no-commit
```
6. Let's now use the `Ownable` contract from OpenZeppelin to restrict the `setNumber` and `increment` functions to the contract owner. For the sake of simplicity, we will assign the contract deployer as the initial owner. Substitute the contract's code for the one below.
```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
contract Counter is Ownable {
uint256 public number;
constructor() Ownable(msg.sender) {}
function setNumber(uint256 newNumber) public onlyOwner {
number = newNumber;
}
function increment() public onlyOwner {
number++;
}
}
```
7. Edit the `foundry.toml` file to add the remappings config.
```toml
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
remappings = [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
]
```
8. it's time to create the assertions script (`start.sh`) file. This script will deploy the `Counter` contract and define the conditions to unlock the reward.
```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" 'increment()(uint256)')
if [ "$number" -eq 0 ]
then
>&2 echo "No exploit found."
exit 1
else
>&2 echo "Valid exploit!"
exit 0
fi
```
:::warning
Set the execution permission for this file using the following command:
chmod +x start.sh
:::
9. Download `setup-exec-env.sh`, which is the script that prepares Bug Buster's execution environment. Keep it with no modifications! :wink:
```bash
wget https://gist.githubusercontent.com/claudioantonio/9cfcbec91de8aef1376c56d34432386f/raw/a8bffe442b94190ad46fe5ff53b2911ea0afa8ee/setup-exec-env.sh
chmod +x setup-exec-env.sh
```
10. Also download the `Register` contract and its interface which will allow easy access the `Counter` contract address.
```bash
cd src
wget https://raw.githubusercontent.com/crypto-bug-hunters/bug-buster/refs/tags/v0.10.0-alpha.1/tests/bounties/src/adder/src/Registry.sol
wget https://raw.githubusercontent.com/crypto-bug-hunters/bug-buster/refs/tags/v0.10.0-alpha.1/tests/bounties/src/adder/src/IRegistry.sol
```
11. At this point, it is important to build the project to check if everything is working as expected.
```bash
forge build
```
## Configuring remappings and creating the bundle
1. Considering the project is compiling successfully locally, let's edit the `foundry.toml` file to change the remapping configuration in order to make the project to use Bug Buster's built-in installation for OpenZeppelin.
```toml
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
remappings = [
"@openzeppelin/contracts/=/usr/share/forge-lib/openzeppelin-contracts/contracts",
]
```
2. Now, you have everything set up to create your bounty's bundle. Just run the command below from the root folder to create the `tar.xz` file.
```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
```
## Submitting the bug bounty
1. Access Bug Buster in Testnet: https://preview.bugbuster.app/
2. Click on *Explore bounties*.
3. Click on *Create bounty*, and fill in the required form fields.
- For the *Token Address* field, enter the address for any existing ERC-20 contract on Optimism Sepolia. For example, USDC address on Optimism Sepolia is `0x5fd84259d66Cd46123540766Be93DFE6D43130D7`.
- Upload the `counter-bounty.tar.xz` file.
4. 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.
5. 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
Now it's time to test if your bug bounty is running properly inside Bug Buster's execution environment!
1. Click on your bounty card in the *Explore bounties* page.
2. Confirm that your wallet is connected.
3. Click on *Submit exploit* and, in the script tab, paste the code below that just calls the `increment` function.
``` 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.increment();
}
}
```
4. Click on *Test* and wait until the execution ends. The expected result is a transaction reverted because the `increment` function was called by an account which is not the `Counter` contract owner.
```bash
server returned an error response: error code 3: execution reverted, data:
"0x118cdaa7000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc9"
```
## Thank you!
Thanks for following this tutorial and learn more about Bug Buster!
If you have any comments, suggestions and/or doubts, please don't hesitate to reach out through our [Telegram development community](https://t.me/BugBusterApp) or our [X account](https://x.com/BugBusterApp).