Files
dao/docs/content/docs/guide/hierarchy/clawback.mdx
T
Zach Kelling a902c1c1c7 feat: add wallet package, docs, LLM.md, and update submodule refs
- Add packages/wallet with Solana/EVM providers
- Add comprehensive DAO governance documentation
- Fix gitignore to cover nested node_modules
- Update submodule refs
2026-02-20 22:15:37 -08:00

473 lines
15 KiB
Plaintext

---
title: Fund Clawback
description: 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
<Callout type="warning">
Clawback is a significant action that can disrupt child operations. Always follow proper governance and provide adequate notice.
</Callout>
## 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
| Delay | Use Case |
|-------|----------|
| 0 days | Emergency reserve (parent-controlled) |
| 1 day | Operational funds (tight oversight) |
| 3 days | Standard committees |
| 7 days | Autonomous sub-DAOs |
| 14 days | High-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:
```yaml
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
```typescript
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
```solidity
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 │
└──────────┘ └──────────┘
```
| State | Description |
|-------|-------------|
| Pending | Initiated, waiting for timelock |
| Ready | Timelock passed, can be executed |
| Executed | Funds transferred to parent |
| Cancelled | Clawback cancelled before execution |
| Expired | Not executed within grace period |
### Execution Window
After timelock, there's a window to execute:
```typescript
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
```typescript
// Child prepares for reduced budget
await childTreasury.adjustBudgets(reducedAmount);
```
### 2. Request Cancellation
Appeal to parent governance:
```yaml
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:
```typescript
// 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
```yaml
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
```typescript
await hierarchy.cancelClawback(
clawbackId,
'Projects need completion - agreed with child committee'
);
```
## Emergency Clawback
For urgent situations (security breach, misconduct):
```typescript
// Emergency clawback bypasses normal timelock
// Requires GUARDIAN_ROLE
await hierarchy.emergencyClawback(
childId,
tokenAddress,
amount,
'Security incident - unauthorized access detected'
);
```
<Callout type="error">
Emergency clawback should only be used for genuine emergencies. Misuse undermines trust in the hierarchy.
</Callout>
## Clawback All Funds
For node dissolution:
```typescript
// 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
```typescript
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
| Action | Required Permission |
|--------|---------------------|
| Initiate clawback | `ADMIN_ROLE` on parent |
| Execute clawback | Any (after timelock) |
| Cancel clawback | `ADMIN_ROLE` on parent |
| Emergency clawback | `GUARDIAN_ROLE` |
## Troubleshooting
| Error | Cause | Solution |
|-------|-------|----------|
| `Unauthorized` | Missing admin role | Get proper permissions |
| `ClawbackDisabled` | Config disables clawback | Cannot clawback this child |
| `InsufficientBalance` | Child doesn't have funds | Reduce amount |
| `TimelockNotPassed` | Too early to execute | Wait for timelock |
| `ClawbackExpired` | Execution window passed | Reinitiate clawback |