Skip to content

Akshay473/bug-bounty-dapp

Repository files navigation

🛡️ Bug Bounty Escrow dApp

Trustless Decentralized Bug Bounty Platform on Avalanche

Avalanche Solidity License Status

Eliminate trust deadlock in bug bounties. Companies lock AVAX rewards. Researchers get paid automatically upon verified vulnerability disclosure. No middlemen. No broken promises.

Live ContractHow It WorksAvalanche FujiGet StartedSecurity


🎯 The Problem It Solves

The Trust Deadlock

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.  │
└─────────────────────────────────────────────────────────────┘

Our Solution: Smart Contract Escrow

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

👥 Who Is This For

🏢 Companies & Web3 Protocols.

  • 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

🔍 Security Researchers & Ethical Hackers.

  • 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

⚙️ Platform Admin (Deployer).

  • 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

🔄 How It Works — The 3 Phases

Phase 1️⃣: Company Posts a Bounty

┌─────────────────────────────────────────────────────────────┐
│ 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 }

Phase 2️⃣: Researcher Submits Vulnerability

┌─────────────────────────────────────────────────────────────┐
│ 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

Phase 3️⃣: Settlement & Payout

┌─────────────────────────────────────────────────────────────┐
│ 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               │
└─────────────────────────────────────────────────────────────┘

📊 Complete Flow Diagram

                    ┌─────────────────────────────────────┐
                    │   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           │
                    └─────────────────────────────────────┘

🔐 Live Deployment

Field Value
Network Avalanche Fuji Testnet
Chain ID 43113
Contract Address 0x66e9e9A4CEb59029c7C5F3DEf0C4651855f8BAee
Deployer 0x11E9a2F2c56CeC1F1bAf78A31DD6303D7A4FA64d
Explorer View on Snowtrace
Status ✅ Active & Tested

🏔️ Avalanche Fuji Network

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:

Why Avalanche Fuji?

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

How Fuji Is Used in Each Layer

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.timestamp from Fuji's ~2s blocks is used to record createdAt on each bounty

Hardhat Config (hardhat.config.js)

  • The fuji network 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 fuji targets 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

MetaMask Fuji Network Settings

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.


📁 Project Structure

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

🧠 Smart Contract Reference

Core Functions

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

Events (Forensic Audit Trail)

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

Bounty Data Structure

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
}

🔒 Security Design

✅ Reentrancy Protection

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}("");

✅ Access Control

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.

✅ No Global Withdraw

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.

✅ Front-Running Protection

submitVulnerability stores commits per (bountyId, researcherAddress) and rejects duplicates. A front-runner watching the mempool cannot overwrite a researcher's commit.

✅ Zero Address Guard

payoutBounty rejects address(0) as a researcher to prevent accidental fund burns.

✅ Commit Hash Privacy

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

🚀 Getting Started

Prerequisites

Installation

# Clone the repository
git clone https://github.com/Akshay473/bug-bounty-dapp.git
cd bug-bounty-dapp

# Install dependencies
npm install

Configure Environment

Create .env in the project root:

PRIVATE_KEY=0x<your_64_char_hex_private_key>

⚠️ NEVER commit .env to GitHub. It's already in .gitignore.

Compile Smart Contract

npm run compile
# or
npx hardhat compile

Run Tests

npm test
# or
npx hardhat test

Expected 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)

Deploy to Fuji Testnet

npm run deploy
# or
npx hardhat run scripts/deploy.js --network fuji

After deployment, contract-info.json is auto-generated with:

  • Contract address
  • Full ABI
  • Deployer address
  • Deployment timestamp

Run Frontend Locally

# 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!

💻 Tech Stack

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+

📈 Real-World Use Case

Scenario: DeFi Protocol Vulnerability

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

🎓 Why This Is Different

vs. HackerOne / Bugcrowd

  • ❌ They take 20-30% fees
  • ❌ Manual payment processing (30-90 days)
  • ❌ Centralized dispute resolution
  • This project: 0% fees, instant payment, on-chain proof

vs. Direct Payment

  • ❌ Researcher has no guarantee of payment
  • ❌ Company has no proof of discovery
  • ❌ No audit trail
  • This project: Funds locked, cryptographic proof, immutable record

vs. Escrow Services

  • ❌ Requires trusted third party
  • ❌ Manual verification process
  • ❌ Fees for escrow service
  • This project: Smart contract is the escrow, automated, zero fees

📝 License

This project is licensed under the Apache License 2.0 — see the LICENSE file for details.

Apache 2.0 License Summary

  • ✅ 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

🤝 Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📞 Support & Contact


⚠️ Disclaimer

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.


Built with ❤️ on Avalanche

⬆ Back to Top

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors