Quests Protocol is a protocol to distribute token rewards for completing on-chain tasks.
For more information on all docs related to the Quest Protocol, see the documentation directory here.
Mainnet, Optimism, Polygon, Arbitrum, Base, Blast, Mantle and Sepolia:
Contract Name | Address |
---|---|
Quest Factory | 0x52629961F71C1C2564C5aa22372CB1b9fa9EBA3E |
RabbitHole Tickets | 0x0D380362762B0cf375227037f2217f59A4eC4b9E |
Protocol Rewards | 0x168437d131f8deF2d94B555FF34f4539458DD6F9 |
PowerPass | 0xe13fbb9590cb72ba5cc7b0decc9dff8027a7fc9d |
The main contracts are:
Quest Factory
(code)- Creates new
Quest
instances of an NFT reward Quest or ERC-20 reward Quest.
- Creates new
Quest
(code)- A Quest in which the reward is an ERC-20 token
QuestNFT
(code)- A Quest in which the reward is a NFT
Protocol Rewards
(code)- An escrow like contract in which funds are deposited into account balances.
Contracts are layed out in the following order:
- Use statements (i.e.
using SafeTransferLib for address;
) - Contract storage - we use upgradable architecture so pay special attention to preserving the order of contract storage, and only add to the end.
- Contract constructors and initialization functions
- Modifiers
- External Update functions - anything that modifies contract state
- External View Functions - self explanatory
- Internal Update functions
- Internal View functions
Interfaces should be used to hold the following:
- Events
- Errors
- Structs
For anything not covered here please refer to the Foundry Best Practices for more information.
The contracts use two main patterns.
More reading here
More reading here
More reading here
bun install
forge install
forge build
this uses a compromised private key from hardhat's test node, do not use this key for anything other than automated testing!
cp .env.example .env
sed -i '' "s/TEST_CLAIM_SIGNER_PRIVATE_KEY=/TEST_CLAIM_SIGNER_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80/" .env
forge test
Test QuestBudgetTest contracts:
forge test --match-contract QuestBudgetTest
forge coverage --report lcov
forge snapshot
If you see something like this expected error: 0xdd8133e6 != 0xce3f0005
in Forge logging, your best bet is to search for the hex string (ce3f0005
don't prepend 0x
) in Errors.json
within the build artifacts - that should have most error strings in it.
If you run into an issue where there isn't enough funds to deploy on Optimism, but the account appears to have sufficient funds, try adding the --legacy
tag to the deploy command.
- Deploy the ProxyAdmin
forge script script/ProxyAdmin.s.sol:ProxyAdminDeploy --rpc-url sepolia --broadcast --verify -vvvv
- Deploy QuestFactory (this also upgrades it to the latest version, and deployes the latest Quest and Quest1155 implementation contracts)
forge script script/QuestFactory.s.sol:QuestFactoryDeploy --rpc-url sepolia --broadcast --verify -vvvv
- Deploy RabbitHoleTickets (this also upgrades it to the latest version)
forge script script/RabbitHoleTickets.s.sol:RabbitHoleTicketsDeploy --rpc-url sepolia --broadcast --verify -vvvv
- Deploy the ProtocolRewards
forge script script/ProtocolRewards.s.sol:ProtocolRewardsDeploy --rpc-url sepolia --broadcast --verify -vvvv
- Set any storage variables manually if needed
- Deploy the QuestBudget
forge script script/QuestBudget.s.sol:QuestBudgetDeploy --rpc-url sepolia --broadcast --verify -vvvv
--legacy --verifier blockscout --verifier-url "https://explorer.mantle.xyz/api?module=contract&action=verify"
if you get (code: -32000, message: invalid transaction: nonce too low, data: None)
try rerunning with the --resume
flag
--legacy --verifier blockscout --verifier-url "https://blockscout.scroll.io/api?module=contract&action=verify"
--legacy
Note: This might not be needed, there is currently a bug in the mantle explorer that prevents it from marking create2 contracts as contracts
forge verify-contract --verifier blockscout --verifier-url "https://explorer.mantle.xyz/api?module=contract&action=verify" --num-of-optimizations 999999 --chain 5000 --compiler-version "0.8.10+commit.fc410830" 0x52629961F71C1C2564C5aa22372CB1b9fa9EBA3E lib/openzeppelin-contracts/contracts/proxy/transparent/TransparentUpgradeableProxy.sol:TransparentUpgradeableProxy
important: make sure storage layouts are compatible, by running the upgrades-core validate script on the contract you are upgrading, for example:
forge clean && forge build && bunx @openzeppelin/upgrades-core validate --contract RabbitHoleTickets
Then to upgrade a contract, run one of the following commands:
forge script script/QuestFactory.s.sol:QuestFactoryUpgrade --rpc-url sepolia --broadcast --verify -vvvv
forge script script/RabbitHoleTickets.s.sol:RabbitHoleTicketsUpgrade --rpc-url sepolia --broadcast --verify -vvvv
forge script script/Quest.s.sol:QuestDeploy --rpc-url sepolia --broadcast --verify -vvvv
forge script script/Quest.s.sol:Quest1155Deploy --rpc-url sepolia --broadcast --verify -vvvv
or use xargs to deploy on every chain in one command:
echo "sepolia mainnet arbitrum optimism polygon base blast" | xargs -n 1 -I {} forge script script/QuestFactory.s.sol:QuestFactoryUpgrade --broadcast --verify --rpc-url {}
echo "sepolia mainnet arbitrum optimism polygon base blast" | xargs -n 1 -I {} forge script script/Quest.s.sol:QuestDeploy --broadcast --verify --rpc-url {}
echo "sepolia mainnet arbitrum optimism polygon base blast" | xargs -n 1 -I {} forge script script/Quest.s.sol:Quest1155Deploy --broadcast --verify --rpc-url {}
and for our mantle:
forge script script/QuestFactory.s.sol:QuestFactoryUpgrade --broadcast --verify --rpc-url mantle --legacy --verifier blockscout --verifier-url "https://explorer.mantle.xyz/api?module=contract&action=verify"
Note the extra options to use with mantel and scroll above.
If you get a (code: -32000, message: invalid transaction: nonce too low, data: None)
error, try running the same command with the --resume
flag.
red animation: bafybeietacfcrgwetjwcexdakfhmig4fgsdsb7o62n2qcpybkbiupqlkxq red image: bafkreiafob6tgwkb4jla5ent7d7rw4ps7tjdhe32tlbdenyrc3lch76qfe blue animation: bafybeib43gbmeloa6o6hs7xxwioyvduohmuf6yyu2avusjuke7delbou3m blue image: bafkreicoysyc5chqjntdpxiyfojoljabycedep3mssphpwv7opfqfrlwbq
https://cloudflare-ipfs.com/ipfs/
is a good public IPFS gateway
The following auditors reviewed the protocol.
- Code4rena (report here)
All contracts except tests, interfaces, dependencies are in scope and eligible for the Quest Protocol Bug Bounty program.
The rubric we use to determine bug bounties is as follows:
Level | Example | Maximum Bug Bounty |
---|---|---|
6. Severe | - Draining or freezing of holdings protocol-wide (e.g. draining token distributor, economic attacks, reentrancy, MEV, logic errors) | Let's talk |
5. Critical | - Contracts with balances can be exploited to steal holdings under specific conditions (e.g. bypass guardrails to transfer precious NFT from parties, user can steal their party's distribution) | Up to 25 ETH |
4. High | - Contracts temporarily unable to transfer holdings - Users spoof each other |
Up to 10 ETH |
3. Medium | - Contract consumes unbounded gas - Griefing, denial of service (i.e. attacker spends as much in gas as damage to the contract) |
Up to 5 ETH |
2. Low | - Contract fails to behave as expected, but doesn't lose value | Up to 1 ETH |
1. None | - Best practices |
Any vulnerability or bug discovered must be reported only to the following email: security@rabbithole.gg.
The primary license for the Quest Protocol is the GNU General Public License 3.0 (GPL-3.0), see LICENSE.
Several interface/dependencies files from other sources maintain their original license (as indicated in their SPDX header). All files in test/ remain MIT (as indicated in their SPDX header).