mirror of
https://github.com/luxfi/dao.git
synced 2026-07-27 02:51:24 +00:00
- Add packages/wallet with Solana/EVM providers - Add comprehensive DAO governance documentation - Fix gitignore to cover nested node_modules - Update submodule refs
473 lines
15 KiB
Plaintext
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 |
|