Skip to content

Latest commit

 

History

History
346 lines (283 loc) · 10.9 KB

File metadata and controls

346 lines (283 loc) · 10.9 KB

TaskBounty Architecture

Overview

TaskBounty is a decentralized task and reward management system built on Ethereum. It provides a trustless platform for posting tasks, submitting work, and managing payments through smart contracts.

Design Principles

  1. Trustless Execution: All funds are escrowed in smart contracts
  2. Transparency: All actions are recorded on-chain with events
  3. Modularity: Separate concerns into distinct contracts
  4. Security: Reentrancy protection, access control, input validation
  5. Gas Efficiency: Optimized storage patterns and minimal operations

Contract Architecture

┌─────────────────────────────────────────────────────────────┐
│                    TaskBountyFactory                        │
│  - Deploys new TaskBounty instances                         │
│  - Tracks all deployments                                   │
└─────────────────────────────────────────────────────────────┘
                            │
                            │ creates
                            ▼
┌─────────────────────────────────────────────────────────────┐
│                    TaskBountyCore                           │
│  - Task creation and management                             │
│  - Work submission handling                                 │
│  - Approval/rejection logic                                 │
│  - Payment automation                                       │
└─────────────────────────────────────────────────────────────┘
                            │
                            │ uses
                            ▼
┌─────────────────────────────────────────────────────────────┐
│                   DisputeResolver                           │
│  - Dispute creation and tracking                            │
│  - Arbitrator management                                    │
│  - Resolution mechanism                                     │
└─────────────────────────────────────────────────────────────┘

Core Components

TaskBountyCore

Responsibilities:

  • Task lifecycle management (create, cancel, complete)
  • Work submission handling
  • Approval and rejection of submissions
  • Automatic payment distribution
  • Integration with dispute resolution

Key Features:

  • Escrows rewards when tasks are created
  • Enforces deadline constraints
  • Supports multiple submissions per task
  • Prevents duplicate submissions from same contributor
  • Emits events for off-chain indexing

State Management:

Task States:
Open → InProgress → Completed
  ↓         ↓
Cancelled  Disputed

Submission States:
Pending → Approved
   ↓
Rejected

DisputeResolver

Responsibilities:

  • Create and track disputes
  • Manage arbitrator permissions
  • Resolve disputes with binding outcomes

Key Features:

  • One dispute per submission
  • Multiple arbitrators supported
  • Owner can add/remove arbitrators
  • Disputes linked to specific submissions

Access Control:

  • Only TaskBounty contract can create disputes
  • Only arbitrators can resolve disputes
  • Only owner can manage arbitrators

TaskBountyFactory

Responsibilities:

  • Deploy new TaskBounty instances
  • Track all deployments
  • Associate deployments with creators

Use Cases:

  • Organizations creating private bounty boards
  • Different communities with custom arbitrators
  • Testing and development environments

Data Structures

Task

struct Task {
    uint256 id;              // Unique identifier
    address poster;          // Task creator
    string title;            // Short title
    string description;      // Detailed requirements
    uint256 reward;          // Escrowed payment
    uint256 deadline;        // Submission deadline
    uint256 maxSubmissions;  // Max allowed submissions
    uint256 submissionCount; // Current submission count
    TaskStatus status;       // Current state
    uint256 createdAt;       // Creation timestamp
}

Submission

struct Submission {
    uint256 id;              // Unique identifier
    uint256 taskId;          // Associated task
    address contributor;     // Submitter address
    string workUrl;          // Link to work (GitHub, IPFS, etc.)
    string description;      // Work description
    uint256 submittedAt;     // Submission timestamp
    SubmissionStatus status; // Current state
}

Dispute

struct Dispute {
    uint256 id;              // Unique identifier
    uint256 taskId;          // Associated task
    uint256 submissionId;    // Associated submission
    address raiser;          // Who raised the dispute
    string reason;           // Dispute reason
    uint256 createdAt;       // Creation timestamp
    DisputeStatus status;    // Current state
    bool favorContributor;   // Resolution outcome
    address resolver;        // Arbitrator who resolved
}

Security Considerations

Reentrancy Protection

  • All external calls use nonReentrant modifier
  • State changes before external calls (CEI pattern)
  • Uses OpenZeppelin-style reentrancy guard

Access Control

  • Task posters can only modify their own tasks
  • Contributors can only submit once per task
  • Arbitrators have limited, specific permissions
  • Owner has administrative control over arbitrators

Input Validation

  • Minimum reward requirements
  • Deadline bounds checking
  • Max submissions validation
  • Status transition validation

Fund Safety

  • Rewards escrowed at task creation
  • Payments only released on approval
  • Refunds only on cancellation
  • No partial withdrawals

Gas Optimization

Storage Patterns

// Packed struct (saves gas)
struct Task {
    uint256 id;           // slot 0
    address poster;       // slot 1 (20 bytes)
    // ... strings in separate slots
    uint256 reward;       // slot N
    uint256 deadline;     // slot N+1
    uint256 maxSubmissions;   // slot N+2 (could pack with smaller types)
    uint256 submissionCount;  // slot N+3
    TaskStatus status;    // slot N+4 (1 byte, could pack)
    uint256 createdAt;    // slot N+5
}

Optimization Techniques

  1. Minimal Storage Reads: Cache storage variables in memory
  2. Batch Operations: Process multiple items in single transaction
  3. Event Emission: Use events for off-chain data instead of storage
  4. Short-Circuit Logic: Early returns to save gas
  5. Immutable Variables: Use immutable for deployment-time constants

Event System

All state changes emit events for off-chain indexing:

// Task events
event TaskCreated(uint256 indexed taskId, address indexed poster, ...);
event TaskCancelled(uint256 indexed taskId, address indexed poster);

// Submission events
event WorkSubmitted(uint256 indexed taskId, uint256 indexed submissionId, ...);
event SubmissionApproved(uint256 indexed taskId, uint256 indexed submissionId, ...);
event SubmissionRejected(uint256 indexed taskId, uint256 indexed submissionId, ...);

// Dispute events
event DisputeRaised(uint256 indexed taskId, uint256 indexed submissionId, ...);
event DisputeCreated(uint256 indexed disputeId, ...);
event DisputeResolved(uint256 indexed disputeId, ...);

Extension Points

1. Reputation System

Track contributor and poster reputation based on completed tasks and quality.

mapping(address => uint256) public reputation;
mapping(address => uint256) public completedTasks;

2. Milestone-Based Tasks

Break large tasks into smaller milestones with partial payments.

struct Milestone {
    string description;
    uint256 reward;
    bool completed;
}

3. Multi-Token Support

Accept ERC20 tokens as rewards instead of just ETH.

struct Task {
    // ... existing fields
    address rewardToken;  // address(0) for ETH
}

4. Staking Mechanism

Require contributors to stake tokens to submit work.

mapping(uint256 => mapping(address => uint256)) public stakes;

5. DAO Governance

Replace single arbitrator with DAO voting for disputes.

interface IGovernance {
    function vote(uint256 disputeId, bool favorContributor) external;
    function executeResolution(uint256 disputeId) external;
}

6. Drips Integration

Stream rewards over time instead of lump sum payments.

import {Drips} from "drips-protocol/Drips.sol";

function streamReward(address contributor, uint256 amount, uint256 duration) internal {
    // Configure streaming payment
}

Testing Strategy

Unit Tests

  • Test individual contract functions
  • Test error conditions and edge cases
  • Test access control
  • Test state transitions

Integration Tests

  • Test complete workflows
  • Test contract interactions
  • Test dispute resolution flow
  • Test factory deployments

Gas Benchmarking

  • Measure gas costs for common operations
  • Optimize hot paths
  • Compare against alternatives

Security Tests

  • Reentrancy attack scenarios
  • Access control bypass attempts
  • Integer overflow/underflow
  • Front-running scenarios

Deployment Strategy

Local Development

anvil  # Start local node
forge script script/Deploy.s.sol --rpc-url http://localhost:8545 --broadcast

Testnet Deployment

forge script script/Deploy.s.sol \
  --rpc-url $SEPOLIA_RPC_URL \
  --private-key $PRIVATE_KEY \
  --broadcast \
  --verify

Mainnet Deployment

  1. Audit contracts thoroughly
  2. Deploy to testnet first
  3. Test all functionality
  4. Deploy with multisig owner
  5. Verify on Etherscan
  6. Transfer ownership to DAO/multisig

Future Enhancements

  1. NFT Certificates: Issue NFTs for completed tasks
  2. Skill Tags: Categorize tasks by required skills
  3. Escrow Extensions: Allow deadline extensions with mutual consent
  4. Partial Payments: Split rewards among multiple contributors
  5. Automated Arbitration: Use Kleros or similar for disputes
  6. Cross-Chain: Deploy on multiple chains with bridge support
  7. Privacy: Use zero-knowledge proofs for private tasks
  8. Social Features: Profiles, ratings, portfolios

Resources