Skip to content

aragon/osx-capital-distributor

Repository files navigation

Capital Distributor Github Actions Foundry License: AGPL v3

Overview

Capital Distributor is an Aragon OSx plugin that enables onchain organizations to create and manage capital distribution campaigns. Organizations can distribute tokens to their members through various allocation strategies and payout methods, making it ideal for airdrops, gauge distributions, incentive programs, grants, and rewards.

Architecture

The system follows a modular architecture where the main plugin orchestrates campaigns using dynamically deployed strategies and encoders through factory contracts:

graph TB
    subgraph "Setup"
        PS[PluginSetup] -->|deploys| P[Plugin]
        PS -->|connects| F1[AllocatorStrategyFactory]
        PS -->|connects| F2[ActionEncoderFactory]
    end

    subgraph "Campaign Creation"
        P -->|creates campaign| C[Campaign]
        F1 -->|deploys| AS[Allocation Strategy Instance]
        F2 -->|deploys| AE[Action Encoder Instance]
        AS -->|linked to| C
        AE -->|linked to| C
    end

    subgraph "Campaign Execution"
        U[User] -->|claims from| C
        C -->|validates via| AS
        C -->|encodes payout via| AE
        AE -->|executes| T[Token Transfer]
        T -->|to| U
    end
Loading

Core Components

CapitalDistributorPlugin

The main plugin contract that manages the lifecycle of distribution campaigns. It handles:

  • Campaign creation with customizable parameters
  • Claim processing and validation
  • Campaign state management (active, paused, ended)
  • Integration with allocation strategies and payout encoders

Factory Contracts

AllocatorStrategyFactory

Manages the deployment and registration of allocation strategies. Each strategy determines how tokens are allocated to recipients.

Available Strategies:

  • MerkleDistributorStrategy: Uses Merkle trees for efficient large-scale distributions (airdrops)

ActionEncoderFactory

Manages payout action encoders that transform distribution amounts into executable DAO actions.

Available Encoders:

  • Direct Transfer: Simple ERC20 token transfers
  • VaultDepositPayoutActionEncoder: Deposits tokens into ERC-4626 vaults

Campaign Structure

struct Campaign {
    bytes metadataURI;              // Campaign metadata (IPFS)
    IAllocatorStrategy strategy;     // Allocation logic
    IERC20 token;                    // Token to distribute
    IPayoutActionEncoder encoder;    // Payout method
    CampaignState state;             // ACTIVE, PAUSED, ENDED
    uint256 startTime;               // Campaign start timestamp
    uint256 endTime;                 // Campaign end timestamp
}

Features

  • Flexible Allocation Strategies: Choose from multiple methods to determine recipient allocations
  • Multiple Payout Methods: Direct transfers, vault deposits, or streaming payments
  • Campaign Management: Full lifecycle control with pause, resume, and end capabilities
  • Batch Operations: Process multiple claims in a single transaction for gas efficiency
  • Modular Architecture: Easily extend with new strategies and encoders
  • Permission System: Integrated with Aragon's permission management
  • Event Tracking: Comprehensive events for monitoring and indexing

Installation

Prerequisites

  • Foundry development framework
  • Bun or Node.js package manager
  • Git

Setup

Clone the repository and install dependencies:

git clone https://github.com/aragon/osx-capital-distributor
cd osx-capital-distributor
bun install # or npm install

Build & Test

Build

forge build

Test

Run the test suite with verbose output:

forge test -vvv

Coverage

Generate test coverage report:

forge coverage

Gas Analysis

Generate gas reports for optimization:

# Gas report for tests
forge test --gas-report

# Create gas snapshot
forge snapshot

Deployment

The deployment process follows these steps:

  1. Deploy Factory Contracts

    AllocatorStrategyFactory allocatorFactory = new AllocatorStrategyFactory();
    ActionEncoderFactory actionFactory = new ActionEncoderFactory();
  2. Register Strategies and Encoders

    // Register allocation strategies
    allocatorFactory.registerStrategyType("merkle-distributor", merkleStrategy, ...);
    allocatorFactory.registerStrategyType("gauge-voter", gaugeStrategy, ...);
    
    // Register action encoders
    actionFactory.registerActionEncoder("vault-deposit", vaultEncoder, ...);
  3. Deploy Plugin Setup

    CapitalDistributorPluginSetup setup = new CapitalDistributorPluginSetup();
  4. Publish to Aragon Registry

    PluginRepo repo = repoFactory.createPluginRepoWithFirstVersion(
        "capital-distributor",
        address(setup),
        maintainer,
        buildMetadata,
        releaseMetadata
    );
  5. Install Plugin in DAO

    DAO.createDao(daoSettings, pluginSettings);

Deployment Script

Deploy using the provided script:

forge script script/Deploy.s.sol --rpc-url <RPC_URL> --broadcast

Required environment variables:

  • PLUGIN_REPO_FACTORY: Aragon Plugin Repository Factory address
  • DAO_FACTORY: Aragon DAO Factory address
  • ADMIN_REPO: Admin plugin repository address
  • ADMIN_OWNER: Address of the admin owner

Deployment Addresses

Network Plugin Setup AllocatorStrategyFactory ActionEncoderFactory
Ethereum Mainnet TBD TBD TBD
Polygon TBD TBD TBD
Arbitrum One TBD TBD TBD
Optimism TBD TBD TBD
Base TBD TBD TBD
Sepolia Testnet TBD TBD TBD

Usage Examples

Creating a Campaign

// Example: Create an airdrop campaign with Merkle distribution
plugin.createCampaign(
    "ipfs://QmCampaignMetadata",     // Metadata URI
    "merkle-distributor",             // Strategy ID
    address(token),                   // Token to distribute
    "direct-transfer",                // Encoder ID (simple transfer)
    false,                           // Single claim per user
    block.timestamp,                 // Start immediately
    block.timestamp + 30 days        // End in 30 days
);

Claiming from a Campaign

// User claims their allocation with proof
bytes memory proof = abi.encode(merkleProof, amount);
plugin.claimCampaignPayout(campaignId, recipient, proof);

// Batch claim for multiple recipients
plugin.batchClaimCampaignPayout(campaignId, recipients, proofs);

Security

  • Built on battle-tested Aragon OSx framework
  • Follows checks-effects-interactions pattern
  • Comprehensive access control via Aragon permissions
  • Input validation and bounds checking
  • Events for all state changes

Contributing

We welcome contributions! Please see our Contributing Guidelines for details.

Code Style

  • Run formatter: forge fmt
  • Run linter: bun run lint
  • Follow Solidity style guide and NatSpec documentation

License

This project is licensed under the GNU Affero General Public License v3.0 or later - see the LICENSE file for details.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 5