Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
327 changes: 249 additions & 78 deletions docs/family-wallet-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,112 +119,283 @@ sequenceDiagram
end
```

### 2. Generic Multisig Governance Flow
**Key Security Features:**
- **Dust Attack Prevention**: `min_precision` prevents micro-transactions that could bypass limits
- **Single Transaction Limits**: `max_single_tx` prevents large withdrawals even within period limits
- **Overflow Protection**: All arithmetic uses `saturating_add()` to prevent overflow
- **Configuration Validation**: Strict parameter validation prevents invalid configurations

### 2. Rollover Behavior

The system implements daily spending periods with secure rollover handling:

```rust
/// Spending period configuration for rollover behavior
pub struct SpendingPeriod {
/// Period type: 0=Daily, 1=Weekly, 2=Monthly
pub period_type: u32,
/// Period start timestamp (aligned to period boundary)
pub period_start: u64,
/// Period duration in seconds (86400 for daily)
pub period_duration: u64,
}
```

Used by `propose_split_config_change`, `propose_role_change`, `propose_policy_cancellation`, and non-emergency-mode `propose_emergency_transfer`.
**Rollover Security:**
- **UTC Alignment**: Periods align to 00:00 UTC to prevent timezone manipulation
- **Boundary Validation**: Inclusive boundary checks prevent edge case timing attacks
- **Legitimate Rollover**: Validates rollover conditions to prevent time manipulation

### 3. Cumulative Spending Tracking

```rust
/// Cumulative spending tracking for precision validation
pub struct SpendingTracker {
/// Current period spending amount (in stroops)
pub current_spent: i128,
/// Last transaction timestamp for audit trail
pub last_tx_timestamp: u64,
/// Transaction count in current period
pub tx_count: u32,
/// Period configuration
pub period: SpendingPeriod,
}
```

```mermaid
flowchart TD
A["Propose action"] --> B{"Requires multisig?"}
B -->|No| C["Execute immediately (tx_id = 0)"]
B -->|Yes| D["Create pending tx with 24h expiry"]
D --> E["Collect authorized signatures"]
E --> F{"Threshold met?"}
F -->|No| G["Keep pending"]
F -->|Yes| H["Execute and remove pending"]
D --> I{"Expired?"}
I -->|Yes| J["Removed by cleanup_expired_pending"]
**Tracking Features:**
- **Period Persistence**: Spending accumulates across transactions within the same period
- **Automatic Reset**: Counters reset to zero on legitimate period rollover
- **Audit Trail**: Transaction count and timestamps for monitoring
- **Overflow Protection**: Uses saturating arithmetic to prevent overflow attacks

## API Reference

### Configuration Functions

#### `set_precision_spending_limit`
```rust
pub fn set_precision_spending_limit(
env: Env,
caller: Address, // Must be Owner or Admin
member_address: Address, // Target member
precision_limit: PrecisionSpendingLimit,
) -> Result<bool, Error>
```

### 3. Emergency Transfer Flow
**Purpose**: Configure enhanced precision limits for a family member
**Authorization**: Owner or Admin only
**Validation**: Validates all precision parameters for security

```mermaid
flowchart TD
A["propose_emergency_transfer"] --> B{"Emergency mode ON?"}
B -->|No| C["Create multisig pending tx (EmergencyTransfer type)"]
B -->|Yes| D["Validate max_amount"]
D --> E["Validate cooldown (EM_LAST + cooldown)"]
E --> F["Validate min_balance after transfer"]
F --> G["Execute immediate token transfer"]
G --> H["Update EM_LAST and emit events"]
### Validation Functions

#### `validate_precision_spending`
```rust
pub fn validate_precision_spending(
env: Env,
caller: Address,
amount: i128,
) -> Result<(), Error>
```

**Purpose**: Comprehensive spending validation with precision and rollover checks
**Flow**:
1. Basic validation (positive amount, valid member, role not expired)
2. Role-based bypass (Owner/Admin unlimited)
3. Precision validation (min_precision, max_single_tx)
4. Cumulative validation (period limits, rollover handling)

### Monitoring Functions

#### `get_spending_tracker`
```rust
pub fn get_spending_tracker(env: Env, member_address: Address) -> Option<SpendingTracker>
```

**Purpose**: Read-only access to current spending tracker for monitoring

## Security Assumptions

### 1. Precision Attack Prevention

**Dust Attack Mitigation:**
- `min_precision > 0` prevents micro-transactions
- Recommended minimum: 1 XLM (10^7 stroops) for meaningful amounts

**Overflow Protection:**
- All arithmetic uses `saturating_add()` and `saturating_sub()`
- Configuration validation prevents overflow conditions
- Boundary checks handle edge cases gracefully

### 2. Rollover Security

**Time Manipulation Prevention:**
- Period alignment to UTC boundaries prevents timezone exploitation
- Rollover validation ensures legitimate period transitions
- Inclusive boundary checks prevent timing attacks

**Example Rollover Validation:**
```rust
fn rollover_spending_period(
old_tracker: SpendingTracker,
current_time: u64,
) -> Result<SpendingTracker, Error> {
let new_period = Self::get_current_period(current_time);

// Validate rollover is legitimate (prevent manipulation)
if current_time < old_tracker.period.period_start.saturating_add(old_tracker.period.period_duration) {
return Err(Error::RolloverValidationFailed);
}

// Reset counters for new period
Ok(SpendingTracker {
current_spent: 0,
last_tx_timestamp: current_time,
tx_count: 0,
period: new_period,
})
}
```

*Anti-Abuse Protections:*
- **Replay Protection**: Identical emergency transfer proposals (same token, recipient, and amount) by the same proposer are rejected if one is already pending.
- **Frequency/Burst Protection**: A single proposer is limited to a maximum of 1 active pending emergency transfer proposal at a time to prevent storage bloat and spam.
- **Role Misuse**: Only active Family Members (excluding Viewers) can propose emergency transfers.
### 3. Boundary Validation

**Edge Case Handling:**
- Zero and negative amounts explicitly rejected
- Maximum single transaction enforced before cumulative checks
- Period boundary calculations handle timestamp overflow
- Configuration parameters validated for consistency

## Error Handling

### New Error Types

| Error | Description | Prevention |
|-------|-------------|------------|
| `AmountBelowPrecision` | Amount below minimum precision threshold | Set appropriate `min_precision` |
| `ExceedsMaxSingleTx` | Single transaction exceeds maximum | Configure reasonable `max_single_tx` |
| `ExceedsPeriodLimit` | Cumulative spending exceeds period limit | Monitor via `get_spending_tracker` |
| `RolloverValidationFailed` | Period rollover validation failed | System prevents time manipulation |
| `InvalidPrecisionConfig` | Invalid precision configuration | Validate parameters before setting |

### Error Prevention Strategies

**Configuration Validation:**
```rust
// Validate precision configuration
if precision_limit.limit < 0 {
return Err(Error::InvalidPrecisionConfig);
}
if precision_limit.min_precision <= 0 {
return Err(Error::InvalidPrecisionConfig);
}
if precision_limit.max_single_tx <= 0 || precision_limit.max_single_tx > precision_limit.limit {
return Err(Error::InvalidPrecisionConfig);
}
```

## Example Scenarios
## Migration and Compatibility

### Scenario A: Small household transfer
### Backward Compatibility

1. Owner configures `LargeWithdrawal` spending limit to `1000_0000000`.
2. Owner withdraws `500_0000000` to a utility provider.
3. Since amount is below threshold, transfer executes immediately and returns `tx_id = 0`.
**Legacy Support:**
- Existing members without `precision_limit` use legacy validation
- Legacy `spending_limit` field preserved
- New features are opt-in per member

### Scenario B: Large transfer requiring approvals
**Migration Path:**
1. Deploy enhanced contract
2. Existing members continue with legacy limits
3. Gradually migrate via `set_precision_spending_limit`
4. Monitor through `get_spending_tracker`

1. Admin configures `LargeWithdrawal` as `threshold=3` with 5 signers.
2. Owner proposes a `2000_0000000` withdrawal.
3. Pending tx is created with proposer auto-signed.
4. Two additional authorized signers approve.
5. Transfer executes, pending entry is removed.
### Configuration Examples

### Scenario C: Emergency payout during outage
**Production Configuration:**
```rust
PrecisionSpendingLimit {
limit: 10000_0000000, // 10,000 XLM per day
min_precision: 1_0000000, // 1 XLM minimum (prevents dust)
max_single_tx: 5000_0000000, // 5,000 XLM max per transaction
enable_rollover: true, // Enable cumulative tracking
}
```

1. Owner enables emergency mode and sets:
- `max_amount = 2000_0000000`
- `cooldown = 3600`
- `min_balance = 1000_0000000`
2. Owner proposes `1500_0000000` emergency transfer.
3. Contract validates amount, cooldown, and residual balance; executes immediately.
4. A second transfer inside cooldown window is rejected.
**Conservative Configuration:**
```rust
PrecisionSpendingLimit {
limit: 1000_0000000, // 1,000 XLM per day
min_precision: 5_0000000, // 5 XLM minimum
max_single_tx: 500_0000000, // 500 XLM max per transaction
enable_rollover: true,
}
```

## Storage Model
## Testing Strategy

### Core instance keys
### Test Coverage Areas

- `OWNER`: wallet owner
- `MEMBERS`: `Map<Address, FamilyMember>`
- `PEND_TXS`: `Map<u64, PendingTransaction>`
- `EXEC_TXS`: `Map<u64, bool>`
- `NEXT_TX`: next transaction id
1. **Precision Validation**
- Configuration parameter validation
- Minimum precision enforcement
- Maximum single transaction limits
- Authorization checks

### Policy keys
2. **Rollover Behavior**
- Period alignment and boundaries
- Spending tracker persistence
- Legitimate rollover validation
- Counter reset behavior

- `MS_WDRAW`, `MS_SPLIT`, `MS_ROLE`, `MS_EMERG`, `MS_POL`: multisig configs by transaction type
- `EM_CONF`, `EM_MODE`, `EM_LAST`: emergency controls
- `ROLE_EXP`: per-member expiry timestamps
- `PAUSED`, `PAUSE_ADM`: pause controls
- `UPG_ADM`, `VERSION`: upgrade controls
3. **Security Edge Cases**
- Dust attack prevention
- Overflow protection
- Time manipulation resistance
- Boundary condition handling

### Observability keys
4. **Compatibility**
- Legacy limit fallback
- Owner/Admin bypass
- Mixed configurations
- Migration scenarios

### Running Tests

```bash
# Run all family wallet tests
cargo test -p family_wallet

# Run precision-specific tests
cargo test -p family_wallet test_precision
cargo test -p family_wallet test_rollover
cargo test -p family_wallet test_cumulative

# Run with detailed output
cargo test -p family_wallet -- --nocapture
```

- `ACC_AUDIT`: rolling access audit list
- `ARCH_TX`: archived executed tx metadata
- `STOR_STAT`: storage statistics snapshot
## Performance Considerations

## Events and Frontend Consumption
### Storage Efficiency

Primary emitted events:
- **Minimal Footprint**: One `SpendingTracker` per member with precision limits
- **Automatic Cleanup**: Trackers reset on period rollover
- **Efficient Access**: O(1) lookups for validation

- `(added, member)` => `MemberAddedEvent`
- `(updated, limit)` => `SpendingLimitUpdatedEvent`
- `(emerg, ModeOn|ModeOff)` => emergency mode toggles
- `(emerg, TransferInit)` and `(emerg, TransferExec)` => emergency execution lifecycle
- `(wallet, TransactionsArchived)` and `(wallet, ExpiredCleaned)` => cleanup activity
- `(wallet, paused|unpaused|upgraded)` => operational/admin lifecycle
### Gas Optimization

Frontend state handling recommendations:
- **Early Exits**: Owner/Admin bypass all precision checks
- **Conditional Logic**: Legacy members skip precision validation
- **Batch Operations**: Minimize storage reads/writes

- Treat `tx_id == 0` as synchronous completion.
- Treat `tx_id > 0` as pending multisig and poll `get_pending_transaction`.
- Use `cleanup_expired_pending` operationally to purge stale proposals.
- Handle both `Result` errors (for some methods) and panics (string-based failures) in client UX.
## Conclusion

## Current Implementation Notes
The enhanced spending limit system provides robust protection against precision attacks and rollover edge cases while maintaining backward compatibility. The implementation follows security best practices with comprehensive validation, overflow protection, and audit trails.

These are important as-implemented behaviors:
Key benefits:
- **Prevents over-withdrawal** through precision and cumulative validation
- **Secure rollover behavior** with time manipulation resistance
- **Comprehensive testing** covering security edge cases
- **Backward compatible** with existing configurations
- **Well-documented** security assumptions and validation logic

- `add_member` is strict (duplicate-safe and limit-aware), while `add_family_member`/batch add overwrite records and force spending limit to `0`.
- `archive_old_transactions` archives all `EXEC_TXS` entries currently present; `before_timestamp` is written into archived metadata but not used as a filter.
Expand Down
Loading
Loading