This is work in progress code for an upcoming bug bounty challenge for Fe. It uses an early version of the Fe support for hardhat provided by the hardhat-fe
plugin. It also requires Fe version 0.17.0
to be build.
Bountiful is a registry for contracts that should uphold certain conditions. If the contract can be brought into a state where such condition no longer holds it means that either a bug in the Fe language or in the contract was found and exploited. In that case, the exploiter can claim prize money in ETH without having to obtain any further permission.
- Different implementations of the 15 puzzle game which start from an unsolvable game state
npx hardhat deploy --network mainnet
- After the deployment went through, send the prize money to the registry contract manually.
- Run
git clone https://github.com/cburgdorf/bountiful.git
- Run
npx hardhat test
Unless the system is in locked
state, the admin can withdraw the prize money at any time. This would be used to migrate
to a newer version of the system.
Run: npx hardhat withdraw <address-of-registry>--network mainnet
Ethereum is a dark forest which is why we need a front running prevention mechanism. In short, if it is possible to send a transaction that will make the sender richer (in our case by exploiting a Fe bug and claiming ETH prize money) we can be sure that somewhere there's a bot noticing it who will perform the same transaction faster leaving the honest claimer empty handed.
To avoid this we've come up with a very simple front-running prevention mechanism. Here is how it works:
-
As a bounty hunter we first try to find an exploit by attacking the contracts locally on our own development machine
-
Let's suppose we have found a way to bring the code challenge into its
solved
state on our own local machine -
To replicate our success on the actual bug bounty registry and claim the prize we first have to aquire an exclusive lock via
registry.lock()
-
Now that we have acquired an exclusive lock we have a window of
1000
blocks (roughly 3 hours) to bring any of the challenges into the solved state. Cautious as we are we will wait a few more blocks before we present the solution. -
Now it's time to solve one of the challenges, which means we exploit the contract in the same way that we have successfully done before on our local development machine. It is important to point out that no other party can interfere with any of the code challenges because we have obtained an exclusive lock.
-
Next we call
registry.claim(address_of_challenge)
to claim the prize money. -
Profit! 💸