Lux Docs

Fund Clawback

Recall funds from child node treasuries

Fund Clawback

Parent DAOs can recall (clawback) funds from child node treasuries. This mechanism ensures ultimate control over delegated resources while respecting the autonomy of sub-DAOs.

Overview

Clawback allows parent DAOs to:

  • Recall unused or misallocated funds
  • Recover assets during node dissolution
  • Respond to emergencies
  • Rebalance treasury allocations

When to Use Clawback

Appropriate Uses

  • Node dissolution - Returning funds when closing a sub-DAO
  • Budget reallocation - Moving unused funds to higher priorities
  • Emergency recovery - Security incident response
  • Charter violation - Funds used outside mandate
  • Period end - Returning unspent quarterly allocation

Not Appropriate

  • Punitive action without governance
  • Overriding legitimate child decisions
  • Routine budget adjustments (use transfers)
  • Political disputes

Clawback is a significant action that can disrupt child operations. Always follow proper governance and provide adequate notice.

Clawback Process

Timelock Delay

Most configurations include a clawback delay:

Parent initiates    Delay period    Execution
clawback            (3-7 days)      (funds recalled)
    │                   │                │
    ▼                   ▼                ▼
────●───────────────────●────────────────●────►
    │                   │                │
    │                   │                │
    └───── Child can ───┘                │
          respond or                     │
          appeal                         │

                            Funds transfer to
                            parent treasury

Delay Rationale

DelayUse Case
0 daysEmergency reserve (parent-controlled)
1 dayOperational funds (tight oversight)
3 daysStandard committees
7 daysAutonomous sub-DAOs
14 daysHigh-autonomy entities

Clawback Methods

Method 1: Via UI

  1. Navigate to Organization > Hierarchy
  2. Select the child node
  3. Click "Clawback Funds"
  4. Configure the clawback
┌─────────────────────────────────────────────────────────────┐
│ Clawback Funds: Research Committee                           │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  Child Treasury Balances:                                    │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  USDC     75,000.00                                  │   │
│  │  ETH      12.5                                       │   │
│  │  DAO      500,000                                    │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                              │
│  Token to recall:  [USDC ▼]                                 │
│                                                              │
│  Amount:           [50,000                    ]             │
│                                                              │
│  Reason (required):                                          │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ Q4 budget underspent - reallocating to Grants       │   │
│  │ Committee for year-end programs.                     │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                              │
│  ⏱️  Timelock: 3 days (per child configuration)             │
│                                                              │
│  [ Cancel ]                      [ Initiate Clawback ]      │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Method 2: Via Proposal

Recommended for significant clawbacks:

Proposal: "Recall Unspent Q4 Budget from Research Committee"

Description: |
  The Research Committee has $50,000 USDC remaining from
  their Q4 budget. This proposal recalls those funds for
  reallocation to the Grants Committee.

  ## Rationale
  - Research Committee spent $50K of $100K Q4 allocation
  - Grants Committee has backlog of approved applications
  - Fiscal year ends in 30 days

  ## Impact
  - Research Committee retains $25K for ongoing projects
  - $50K reallocated to high-priority grants

  ## Timeline
  - 3-day clawback delay per committee charter
  - Reallocation within 7 days of execution

Actions:
  - type: clawback
    childId: 42
    token: USDC
    amount: 50000000000  # 50K USDC (6 decimals)
    reason: "Q4 budget reallocation"

  - type: transfer
    to: grants_committee
    token: USDC
    amount: 50000000000

Method 3: Via SDK

import { HierarchyClient } from '@lux/dao-sdk';
import { ethers } from 'ethers';

const hierarchy = new HierarchyClient(signer);

// Initiate clawback
const tx = await hierarchy.clawback(
  childId,
  usdcAddress,
  ethers.parseUnits('50000', 6),  // 50K USDC
  'Q4 budget reallocation'
);

const receipt = await tx.wait();
const clawbackId = receipt.events[0].args.clawbackId;

console.log(`Clawback initiated: ${clawbackId}`);
console.log(`Executes after: ${await hierarchy.clawbackExecutionTime(clawbackId)}`);

Smart Contract Interface

interface IHierarchy {
    /// @notice Emitted when clawback is initiated
    event ClawbackInitiated(
        uint256 indexed clawbackId,
        uint256 indexed childId,
        address token,
        uint256 amount,
        string reason,
        uint256 executeAfter
    );

    /// @notice Emitted when clawback is executed
    event ClawbackExecuted(
        uint256 indexed clawbackId,
        uint256 indexed childId,
        address token,
        uint256 amount
    );

    /// @notice Emitted when clawback is cancelled
    event ClawbackCancelled(
        uint256 indexed clawbackId,
        string reason
    );

    /// @notice Initiates a clawback with timelock
    /// @param childId Child node to recall from
    /// @param token Token address (address(0) for native)
    /// @param amount Amount to recall
    /// @param reason Documented reason
    /// @return clawbackId Unique identifier for this clawback
    function clawback(
        uint256 childId,
        address token,
        uint256 amount,
        string calldata reason
    ) external returns (uint256 clawbackId);

    /// @notice Executes a clawback after timelock
    /// @param clawbackId The clawback to execute
    function executeClawback(uint256 clawbackId) external;

    /// @notice Cancels a pending clawback
    /// @param clawbackId The clawback to cancel
    /// @param reason Why it was cancelled
    function cancelClawback(
        uint256 clawbackId,
        string calldata reason
    ) external;

    /// @notice Returns clawback details
    function getClawback(uint256 clawbackId) external view returns (
        uint256 childId,
        address token,
        uint256 amount,
        string memory reason,
        uint256 executeAfter,
        bool executed,
        bool cancelled
    );
}

Clawback Lifecycle

States

┌──────────┐     ┌──────────┐     ┌──────────┐
│ Pending  │────▶│  Ready   │────▶│ Executed │
└──────────┘     └──────────┘     └──────────┘
     │                │
     │                │
     ▼                ▼
┌──────────┐     ┌──────────┐
│Cancelled │     │ Expired  │
└──────────┘     └──────────┘
StateDescription
PendingInitiated, waiting for timelock
ReadyTimelock passed, can be executed
ExecutedFunds transferred to parent
CancelledClawback cancelled before execution
ExpiredNot executed within grace period

Execution Window

After timelock, there's a window to execute:

const clawback = await hierarchy.getClawback(clawbackId);

// Can execute between these times
const canExecuteAfter = clawback.executeAfter;
const mustExecuteBefore = clawback.executeAfter + EXECUTION_WINDOW;

if (block.timestamp > mustExecuteBefore) {
  // Clawback expired, must reinitiate
}

Child Response Options

When a clawback is initiated, the child can:

1. Accept and Prepare

// Child prepares for reduced budget
await childTreasury.adjustBudgets(reducedAmount);

2. Request Cancellation

Appeal to parent governance:

Proposal: "Cancel Clawback - Active Projects Need Funds"

Description: |
  The pending clawback of $50K would disrupt three active
  research projects. We request cancellation.

  ## Affected Projects
  1. Privacy Research - $20K committed
  2. Scalability Study - $15K committed
  3. Interop Analysis - $10K committed

  ## Alternative
  We propose returning $25K and retaining $25K for
  project completion.

3. Emergency Use

If funds are legitimately needed:

// Child spends funds before execution
// (only if within mandate - improper use is misconduct)
await childTreasury.transfer(
  projectAddress,
  usdcAddress,
  amount,
  'Committed project funding'
);

Cancelling a Clawback

Via UI

  1. Navigate to pending clawbacks
  2. Select the clawback
  3. Click "Cancel Clawback"
  4. Provide reason

Via Proposal

Proposal: "Cancel Research Committee Clawback"

Description: |
  After reviewing the Research Committee's response, we
  agree to cancel the clawback and allow completion of
  current projects.

Actions:
  - type: cancel_clawback
    clawbackId: 123
    reason: "Active projects need completion funding"

Via SDK

await hierarchy.cancelClawback(
  clawbackId,
  'Projects need completion - agreed with child committee'
);

Emergency Clawback

For urgent situations (security breach, misconduct):

// Emergency clawback bypasses normal timelock
// Requires GUARDIAN_ROLE
await hierarchy.emergencyClawback(
  childId,
  tokenAddress,
  amount,
  'Security incident - unauthorized access detected'
);

Emergency clawback should only be used for genuine emergencies. Misuse undermines trust in the hierarchy.

Clawback All Funds

For node dissolution:

// Recall all tokens from child treasury
const balances = await hierarchy.getChildBalances(childId);

for (const balance of balances) {
  if (balance.amount > 0) {
    await hierarchy.clawback(
      childId,
      balance.token,
      balance.amount,
      'Node dissolution - returning all funds'
    );
  }
}

Monitoring Clawbacks

Dashboard View

┌─────────────────────────────────────────────────────────────┐
│ Pending Clawbacks                                            │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  ID    Child               Amount      Executes    Status   │
│  ───────────────────────────────────────────────────────── │
│  123   Research Committee  50K USDC    in 2 days   Pending  │
│  124   Regional Chapter    10K USDC    in 5 days   Pending  │
│                                                              │
│  [View Details]  [Cancel]  [Execute When Ready]             │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Event Monitoring

hierarchy.on('ClawbackInitiated', (id, childId, token, amount, reason) => {
  console.log(`Clawback ${id}: ${amount} from child ${childId}`);
  notifyChildAdmin(childId, 'clawback_initiated', { amount, reason });
});

hierarchy.on('ClawbackExecuted', (id, childId, token, amount) => {
  console.log(`Clawback ${id} executed: ${amount} returned to parent`);
});

hierarchy.on('ClawbackCancelled', (id, reason) => {
  console.log(`Clawback ${id} cancelled: ${reason}`);
});

Best Practices

Before Initiating

  1. Communicate - Inform child leadership in advance
  2. Document - Clear rationale in the reason field
  3. Consider alternatives - Is clawback the right approach?
  4. Verify amounts - Check child treasury balances

During Timelock

  1. Monitor - Watch for child response
  2. Be available - Respond to questions/appeals
  3. Review - Reconsider if new information emerges

After Execution

  1. Confirm receipt - Verify funds in parent treasury
  2. Reallocate - Use funds as intended
  3. Document - Record in governance records
  4. Follow up - Address any child concerns

Access Control

ActionRequired Permission
Initiate clawbackADMIN_ROLE on parent
Execute clawbackAny (after timelock)
Cancel clawbackADMIN_ROLE on parent
Emergency clawbackGUARDIAN_ROLE

Troubleshooting

ErrorCauseSolution
UnauthorizedMissing admin roleGet proper permissions
ClawbackDisabledConfig disables clawbackCannot clawback this child
InsufficientBalanceChild doesn't have fundsReduce amount
TimelockNotPassedToo early to executeWait for timelock
ClawbackExpiredExecution window passedReinitiate clawback

On this page