Eliminate trust deadlock in bug bounties. Companies lock AVAX rewards. Researchers get paid automatically upon verified vulnerability disclosure. No middlemen. No broken promises.
Live Contract • How It Works • Avalanche Fuji • Get Started • Security
Traditional bug bounty platforms face an unsolvable paradox:
┌─────────────────────────────────────────────────────────────┐
│ RESEARCHER COMPANY │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Won't reveal bug │◄────────────►│ Won't pay first │ │
│ │ without payment │ │ without seeing │ │
│ └──────────────────┘ │ the bug │ │
│ └──────────────────┘ │
│ │
│ Result: Stalemate. Trust issues. Platform fees. Delays. │
└─────────────────────────────────────────────────────────────┘
| Challenge | Traditional Way | This Project |
|---|---|---|
| Payment Trust | Company promises to pay | ✅ AVAX locked in contract BEFORE work starts |
| Discovery Proof | Email timestamp (easily faked) | ✅ keccak256 commit hash permanently on-chain |
| Audit Trail | PDF report (can be lost/altered) | ✅ Every payout is immutable blockchain event |
| Platform Fees | 20-30% taken by middleman | ✅ Zero fees — direct peer-to-peer |
| Payment Speed | 30-90 days | ✅ Instant on-chain settlement |
| Dispute Resolution | Slow, manual process | ✅ Admin arbitration with on-chain proof |
- Post bounties without paying 20-30% fees to HackerOne or Bugcrowd
- Only pay when a real, verified vulnerability is found
- Get a permanent on-chain record of every patched vulnerability
- Reduce liability with cryptographic proof of disclosure
- Payment is guaranteed before revealing findings — AVAX is already locked
- Cryptographic timestamp proves discovery date, protecting against disputes
- Build a verifiable on-chain reputation across protocols
- Get paid instantly without waiting for manual approval
- Acts as a neutral arbitrator in disputes
- Can trigger payouts if a company goes unresponsive
- Can cancel a bounty and refund the company if needed
- Cannot steal funds — no global withdraw function exists
┌─────────────────────────────────────────────────────────────┐
│ COMPANY │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 1. Calls: createBounty("Scope: Check reentrancy") │ │
│ │ 2. Sends: 5 AVAX with transaction │ │
│ │ 3. Result: 5 AVAX locked in contract │ │
│ │ Bounty ID created │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ ✅ Funds are now LOCKED and SAFE │
│ ✅ Researcher can see the bounty is real │
└─────────────────────────────────────────────────────────────┘
Code Example:
createBounty("ipfs://QmScopeHash") + { value: 1 AVAX }┌─────────────────────────────────────────────────────────────┐
│ RESEARCHER │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 1. Finds vulnerability in code │ │
│ │ 2. Creates commit hash: │ │
│ │ hash = keccak256(bugDetails + secretSalt) │ │
│ │ 3. Calls: submitVulnerability(bountyId, hash) │ │
│ │ 4. Shares actual bug details PRIVATELY with company │ │
│ │ │ │
│ │ ✅ Hash stored on-chain (timestamps discovery) │ │
│ │ ✅ Bug details NOT revealed publicly │ │
│ │ ✅ Researcher's discovery is now cryptographically │ │
│ │ proven │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Why This Matters:
- Researcher's discovery is timestamped on-chain before revealing details
- Company can't claim they found it first
- Mempool watchers can't see the actual vulnerability
- Researcher has cryptographic proof of discovery
┌─────────────────────────────────────────────────────────────┐
│ COMPANY VERIFIES BUG OFF-CHAIN │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 1. Reviews bug details (shared privately) │ │
│ │ 2. Confirms it's a real vulnerability │ │
│ │ 3. Calls: payoutBounty(bountyId, researcherAddr) │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ SMART CONTRACT EXECUTES: │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ ✅ Step 1: Set bounty.active = false │ │
│ │ ✅ Step 2: Set bounty.reward = 0 │ │
│ │ ✅ Step 3: Transfer 5 AVAX to researcher │ │
│ │ ✅ Step 4: Emit BountyPaid event │ │
│ │ │ │
│ │ (Reentrancy protection: state changes BEFORE │ │
│ │ fund transfer) │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ RESULT: │
│ ✅ Researcher receives 5 AVAX instantly │
│ ✅ Permanent on-chain record created │
│ ✅ Bounty closed, no double-payout possible │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────┐
│ RESEARCHER FINDS VULNERABILITY │
└────────────────┬────────────────────┘
│
┌────────────────▼────────────────────┐
│ CREATES COMMIT HASH │
│ hash = keccak256(details + salt) │
└────────────────┬────────────────────┘
│
┌────────────────▼────────────────────┐
│ SUBMITS HASH ON-CHAIN │
│ submitVulnerability(id, hash) │
└────────────────┬────────────────────┘
│
┌────────────────▼────────────────────┐
│ SHARES BUG DETAILS PRIVATELY │
│ (encrypted email/chat) │
└────────────────┬────────────────────┘
│
┌────────────────▼────────────────────┐
│ COMPANY VERIFIES BUG │
│ (off-chain review) │
└────────────────┬────────────────────┘
│
┌────────────────▼────────────────────┐
│ COMPANY CALLS payoutBounty() │
└────────────────┬────────────────────┘
│
┌────────────────────────────┼────────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌──────────────┐ ┌──────────────┐
│ Deactivate │ │ Set active=false │ │ Transfer AVAX │
│ bounty │ │ Set reward=0 │ │ to researcher │
└─────────┘ └──────────────┘ └──────────────┘
│ │ │
└────────────────────────────┼────────────────────────────┘
│
┌────────────────▼────────────────────┐
│ EMIT BountyPaid EVENT │
│ (permanent on-chain record) │
└────────────────┬────────────────────┘
│
┌────────────────▼────────────────────┐
│ ✅ RESEARCHER PAID │
│ ✅ BOUNTY CLOSED │
│ ✅ DISPUTE PROOF CREATED │
└─────────────────────────────────────┘
| Field | Value |
|---|---|
| Network | Avalanche Fuji Testnet |
| Chain ID | 43113 |
| Contract Address | 0x66e9e9A4CEb59029c7C5F3DEf0C4651855f8BAee |
| Deployer | 0x11E9a2F2c56CeC1F1bAf78A31DD6303D7A4FA64d |
| Explorer | View on Snowtrace |
| Status | ✅ Active & Tested |
This project is deployed on and purpose-built for the Avalanche Fuji Testnet (Chain ID: 43113). Here's exactly how Fuji is used at each layer:
| Property | Value | Why It Matters |
|---|---|---|
| Block time | ~2 seconds | Near-instant confirmation when locking/paying bounties |
| Finality | ~2 seconds (single-slot) | No waiting for multiple confirmations — payout is final immediately |
| Gas fees | Fractions of a cent (test AVAX) | Researchers and companies can transact without fee friction |
| EVM compatible | Full EVM support | Standard Solidity + Hardhat + ethers.js toolchain works out of the box |
| Native token | AVAX | Used directly as the bounty reward currency — no ERC-20 wrapping needed |
Smart Contract (BugBounty.sol)
- Deployed to Fuji at
0x66e9e9A4CEb59029c7C5F3DEf0C4651855f8BAee - Bounty rewards are locked and transferred in native AVAX (not a wrapped token)
- All events (
BountyCreated,BountyPaid, etc.) are permanently recorded on the Fuji chain block.timestampfrom Fuji's ~2s blocks is used to recordcreatedAton each bounty
Hardhat Config (hardhat.config.js)
- The
fujinetwork is configured with the official Avalanche Fuji RPC endpoint:fuji: { url: "https://api.avax-test.network/ext/bc/C/rpc", chainId: 43113, accounts: [process.env.PRIVATE_KEY] }
- Running
npx hardhat run scripts/deploy.js --network fujitargets this network directly
Frontend (app.js)
- MetaMask is prompted to switch to Fuji (Chain ID
0xA869= 43113) automatically - ethers.js connects to the deployed contract on Fuji via the user's MetaMask provider
- All transactions (createBounty, submitVulnerability, payoutBounty) are sent as Fuji transactions
Testing
- Tests run on Hardhat's local in-process network (a Fuji-compatible EVM fork) — no real AVAX needed
- The same contract bytecode that passes tests is deployed to Fuji unchanged
To interact with the frontend, add Fuji to MetaMask manually or let the app auto-add it:
| Field | Value |
|---|---|
| Network Name | Avalanche Fuji Testnet |
| RPC URL | https://api.avax-test.network/ext/bc/C/rpc |
| Chain ID | 43113 |
| Currency Symbol | AVAX |
| Block Explorer | https://testnet.snowtrace.io |
Get free test AVAX from the Avalanche Fuji Faucet to post and test bounties.
bug-bounty-dapp/
├── contracts/
│ └── BugBounty.sol # Core escrow smart contract (Solidity)
├── scripts/
│ └── deploy.js # Deployment script (exports contract-info.json)
├── test/
│ └── BugBounty.test.js # Full test suite (13 tests)
├── frontend/
│ ├── index.html # Web UI (responsive design)
│ ├── app.js # Frontend logic (ethers.js v6)
│ └── style.css # Professional styling
├── hardhat.config.js # Hardhat + Fuji network config
├── package.json # Dependencies
├── .env # Private key (never commit)
├── .gitignore # Git ignore rules
├── LICENSE # Apache 2.0 License
└── README.md # This file
| Function | Who Can Call | Description |
|---|---|---|
createBounty(string description) |
Anyone (payable) | Lock AVAX and open a new bounty |
submitVulnerability(uint256 id, bytes32 commitHash) |
Anyone | Timestamp a vulnerability discovery |
payoutBounty(uint256 id, address researcher) |
Company or Admin | Pay researcher and close bounty |
deactivateBounty(uint256 id) |
Company or Admin | Cancel bounty and refund company |
getBounty(uint256 id) |
Anyone (view) | Read bounty details |
getContractBalance() |
Anyone (view) | Read total locked AVAX |
| Event | Emitted When | Data |
|---|---|---|
BountyCreated |
New bounty posted | id, company, reward, description |
BountySubmitted |
Vulnerability committed | id, researcher, commitHash |
BountyPaid |
Reward transferred | id, company, researcher, amount |
BountyDeactivated |
Bounty closed/cancelled | id |
struct Bounty {
address company; // Who posted and funded the bounty
uint256 reward; // Locked AVAX in Wei
string description; // Scope metadata or IPFS link
bool active; // true = open, false = settled/cancelled
address lastSubmitter; // Most recent researcher who committed
uint256 createdAt; // Block timestamp of creation
}State changes (active = false, reward = 0) happen before any AVAX transfer, following the Checks-Effects-Interactions pattern.
// SAFE: State changes first
bounty.active = false;
bounty.reward = 0;
(bool success, ) = payable(researcher).call{value: amount}("");payoutBounty and deactivateBounty require msg.sender to be either:
- The company that posted the bounty, OR
- The platform admin
No unauthorized address can touch the funds.
There is no emergencyWithdraw function. The admin cannot drain all locked funds. Refunds are scoped per-bounty and always go back to the original company.
submitVulnerability stores commits per (bountyId, researcherAddress) and rejects duplicates. A front-runner watching the mempool cannot overwrite a researcher's commit.
payoutBounty rejects address(0) as a researcher to prevent accidental fund burns.
Researchers submit keccak256(bugDetails + salt) instead of raw details. This:
- Timestamps discovery on-chain
- Prevents mempool snooping
- Allows off-chain verification
- Protects researcher's work
- Node.js v18+ (Download)
- npm (comes with Node.js)
- MetaMask wallet (Install)
- Fuji testnet AVAX (Get from faucet)
# Clone the repository
git clone https://github.com/Akshay473/bug-bounty-dapp.git
cd bug-bounty-dapp
# Install dependencies
npm installCreate .env in the project root:
PRIVATE_KEY=0x<your_64_char_hex_private_key>
⚠️ NEVER commit.envto GitHub. It's already in.gitignore.
npm run compile
# or
npx hardhat compilenpm test
# or
npx hardhat testExpected Output — 13 Passing Tests:
BugBounty
createBounty
✓ locks AVAX and emits BountyCreated
✓ reverts when no AVAX sent
submitVulnerability
✓ stores commit hash and emits BountySubmitted
✓ prevents duplicate commits from same researcher
payoutBounty
✓ company can pay researcher and emits BountyPaid
✓ admin can also trigger payout
✓ reverts when called by unauthorized address
✓ reverts on second payout (active = false)
✓ reverts on zero address researcher
deactivateBounty
✓ refunds company and emits BountyDeactivated
✓ admin can also deactivate and refund company
✓ reverts when called by unauthorized address
getBounty
✓ returns correct bounty data
13 passing (1.2s)
npm run deploy
# or
npx hardhat run scripts/deploy.js --network fujiAfter deployment, contract-info.json is auto-generated with:
- Contract address
- Full ABI
- Deployer address
- Deployment timestamp
# Start HTTP server on port 3000
npx http-server frontend -p 3000 -c-1
# Open browser to http://localhost:3000
# Connect MetaMask to Fuji Testnet
# Start posting bounties!| Layer | Technology | Version |
|---|---|---|
| Smart Contract | Solidity | ^0.8.20 |
| Development Framework | Hardhat | ^2.19.0 |
| Blockchain Interaction | Ethers.js | v6 |
| Testing | Hardhat + Chai | Latest |
| Network | Avalanche Fuji Testnet | ChainID: 43113 |
| Environment Config | dotenv | ^16.3.1 |
| Frontend | HTML5 + CSS3 + JavaScript | ES6+ |
1. PROTOCOL POSTS BOUNTY
└─ Posts 5 AVAX bounty for reentrancy bugs
└─ Scope: "Staking contract at 0x..."
└─ 5 AVAX locked in contract
2. RESEARCHER FINDS BUG
└─ Discovers reentrancy in staking contract
└─ Creates commit hash: keccak256(bugDetails + salt)
└─ Submits hash on-chain (timestamps discovery)
3. RESEARCHER SHARES DETAILS
└─ Sends encrypted bug report to protocol
└─ Includes proof-of-concept code
└─ Requests 5 AVAX payment
4. PROTOCOL VERIFIES
└─ Reviews bug details
└─ Confirms it's a real vulnerability
└─ Calls payoutBounty()
5. RESEARCHER GETS PAID
└─ Receives 5 AVAX instantly
└─ Permanent on-chain record created
└─ Reputation increased
RESULT:
✅ No lawyers
✅ No NDAs
✅ No platform fees
✅ No waiting 90 days
✅ Instant settlement
✅ Cryptographic proof
- ❌ They take 20-30% fees
- ❌ Manual payment processing (30-90 days)
- ❌ Centralized dispute resolution
- ✅ This project: 0% fees, instant payment, on-chain proof
- ❌ Researcher has no guarantee of payment
- ❌ Company has no proof of discovery
- ❌ No audit trail
- ✅ This project: Funds locked, cryptographic proof, immutable record
- ❌ Requires trusted third party
- ❌ Manual verification process
- ❌ Fees for escrow service
- ✅ This project: Smart contract is the escrow, automated, zero fees
This project is licensed under the Apache License 2.0 — see the LICENSE file for details.
- ✅ You can use this code commercially
- ✅ You can modify and distribute it
- ✅ You must include the license and copyright notice
- ✅ Patent grant included
- ✅ Changes must be documented
- ✅ No warranty provided
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Contract: Snowtrace Explorer
This project is provided as-is for educational and testing purposes. While the smart contract has been tested, always conduct your own security audit before deploying to mainnet with real funds.