> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usmewe.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SocialVault Contract

> Smart contract for social recovery and anti-kidnapping protection

# SocialVault Contract

The SocialVault contract implements social recovery with timelock, multi-signature guardians, and duress PIN protection.

## Contract Overview

```solidity theme={null}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

contract SocialVault is ReentrancyGuard {
    struct Vault {
        address owner;
        uint256 balance;
        uint256 dailyLimit;
        uint256 spentToday;
        uint256 lastSpendDate;
        uint256 timelockDuration;
        address[] guardians;
        uint256 requiredSignatures;
        bool isLocked;
        bytes32 duressCodeHash;
    }

    struct PendingWithdrawal {
        uint256 amount;
        address recipient;
        uint256 executeAfter;
        uint256 approvals;
        bool executed;
        bool cancelled;
        mapping(address => bool) hasApproved;
    }

    mapping(address => Vault) public vaults;
    mapping(address => mapping(uint256 => PendingWithdrawal)) public pendingWithdrawals;
    mapping(address => uint256) public withdrawalCounter;

    IERC20 public immutable usdc;
}
```

## Key Functions

### Create Vault

```solidity theme={null}
function createVault(
    uint256 dailyLimit,
    uint256 timelockDuration,
    address[] calldata guardians,
    uint256 requiredSignatures,
    bytes32 duressCodeHash
) external {
    require(vaults[msg.sender].owner == address(0), "Vault exists");
    require(guardians.length >= requiredSignatures, "Not enough guardians");
    require(timelockDuration >= 1 hours, "Timelock too short");

    vaults[msg.sender] = Vault({
        owner: msg.sender,
        balance: 0,
        dailyLimit: dailyLimit,
        spentToday: 0,
        lastSpendDate: 0,
        timelockDuration: timelockDuration,
        guardians: guardians,
        requiredSignatures: requiredSignatures,
        isLocked: false,
        duressCodeHash: duressCodeHash
    });

    emit VaultCreated(msg.sender, guardians.length, timelockDuration);
}
```

### Deposit

```solidity theme={null}
function deposit(uint256 amount) external nonReentrant {
    Vault storage vault = vaults[msg.sender];
    require(vault.owner != address(0), "No vault");

    usdc.transferFrom(msg.sender, address(this), amount);
    vault.balance += amount;

    emit Deposited(msg.sender, amount);
}
```

### Instant Withdrawal (Within Daily Limit)

```solidity theme={null}
function withdrawInstant(uint256 amount, address recipient) external nonReentrant {
    Vault storage vault = vaults[msg.sender];
    require(!vault.isLocked, "Vault locked");
    require(vault.balance >= amount, "Insufficient balance");

    // Reset daily spend if new day
    if (block.timestamp / 1 days > vault.lastSpendDate / 1 days) {
        vault.spentToday = 0;
        vault.lastSpendDate = block.timestamp;
    }

    require(vault.spentToday + amount <= vault.dailyLimit, "Daily limit exceeded");

    vault.spentToday += amount;
    vault.balance -= amount;
    usdc.transfer(recipient, amount);

    emit InstantWithdrawal(msg.sender, recipient, amount);
}
```

### Request Large Withdrawal (Timelock)

```solidity theme={null}
function requestWithdrawal(uint256 amount, address recipient) external returns (uint256) {
    Vault storage vault = vaults[msg.sender];
    require(!vault.isLocked, "Vault locked");
    require(vault.balance >= amount, "Insufficient balance");

    uint256 withdrawalId = ++withdrawalCounter[msg.sender];
    PendingWithdrawal storage pending = pendingWithdrawals[msg.sender][withdrawalId];

    pending.amount = amount;
    pending.recipient = recipient;
    pending.executeAfter = block.timestamp + vault.timelockDuration;
    pending.approvals = 0;
    pending.executed = false;
    pending.cancelled = false;

    // Notify guardians
    emit WithdrawalRequested(msg.sender, withdrawalId, amount, recipient, pending.executeAfter);

    return withdrawalId;
}
```

### Guardian Approval

```solidity theme={null}
function approveWithdrawal(address vaultOwner, uint256 withdrawalId) external {
    Vault storage vault = vaults[vaultOwner];
    require(isGuardian(vault, msg.sender), "Not a guardian");

    PendingWithdrawal storage pending = pendingWithdrawals[vaultOwner][withdrawalId];
    require(!pending.executed && !pending.cancelled, "Invalid state");
    require(!pending.hasApproved[msg.sender], "Already approved");

    pending.hasApproved[msg.sender] = true;
    pending.approvals++;

    emit WithdrawalApproved(vaultOwner, withdrawalId, msg.sender, pending.approvals);
}
```

### Execute Withdrawal

```solidity theme={null}
function executeWithdrawal(uint256 withdrawalId) external nonReentrant {
    Vault storage vault = vaults[msg.sender];
    PendingWithdrawal storage pending = pendingWithdrawals[msg.sender][withdrawalId];

    require(!pending.executed && !pending.cancelled, "Invalid state");
    require(block.timestamp >= pending.executeAfter, "Timelock active");
    require(pending.approvals >= vault.requiredSignatures, "Insufficient approvals");
    require(vault.balance >= pending.amount, "Insufficient balance");

    pending.executed = true;
    vault.balance -= pending.amount;
    usdc.transfer(pending.recipient, pending.amount);

    emit WithdrawalExecuted(msg.sender, withdrawalId, pending.amount);
}
```

### Duress PIN - Emergency Lock

```solidity theme={null}
function emergencyLock(bytes32 duressCode) external {
    Vault storage vault = vaults[msg.sender];
    require(keccak256(abi.encodePacked(duressCode)) == vault.duressCodeHash, "Invalid code");

    vault.isLocked = true;

    // Cancel all pending withdrawals
    for (uint256 i = 1; i <= withdrawalCounter[msg.sender]; i++) {
        if (!pendingWithdrawals[msg.sender][i].executed) {
            pendingWithdrawals[msg.sender][i].cancelled = true;
        }
    }

    // Alert guardians silently (off-chain notification)
    emit VaultLocked(msg.sender, block.timestamp);
}
```

### Guardian Recovery

```solidity theme={null}
function initiateRecovery(address vaultOwner) external {
    Vault storage vault = vaults[vaultOwner];
    require(isGuardian(vault, msg.sender), "Not a guardian");
    require(vault.isLocked, "Vault not locked");

    // Requires majority of guardians to unlock
    // Implementation uses time-delayed multi-sig
    emit RecoveryInitiated(vaultOwner, msg.sender);
}

function completeRecovery(
    address vaultOwner,
    address newOwner,
    bytes[] calldata signatures
) external {
    Vault storage vault = vaults[vaultOwner];
    require(vault.isLocked, "Vault not locked");
    require(verifyGuardianSignatures(vault, newOwner, signatures), "Invalid signatures");

    vault.owner = newOwner;
    vault.isLocked = false;

    emit RecoveryCompleted(vaultOwner, newOwner);
}
```

## Events

```solidity theme={null}
event VaultCreated(address indexed owner, uint256 guardianCount, uint256 timelockDuration);
event Deposited(address indexed owner, uint256 amount);
event InstantWithdrawal(address indexed owner, address recipient, uint256 amount);
event WithdrawalRequested(address indexed owner, uint256 indexed id, uint256 amount, address recipient, uint256 executeAfter);
event WithdrawalApproved(address indexed owner, uint256 indexed id, address guardian, uint256 totalApprovals);
event WithdrawalExecuted(address indexed owner, uint256 indexed id, uint256 amount);
event VaultLocked(address indexed owner, uint256 timestamp);
event RecoveryInitiated(address indexed owner, address indexed initiator);
event RecoveryCompleted(address indexed oldOwner, address indexed newOwner);
```

## Configuration

| Parameter            | Range              | Description                 |
| -------------------- | ------------------ | --------------------------- |
| `dailyLimit`         | 10-10,000 USDC     | Instant withdrawal limit    |
| `timelockDuration`   | 1 hour - 7 days    | Delay for large withdrawals |
| `guardians`          | 1-5 addresses      | Trusted recovery contacts   |
| `requiredSignatures` | 1 - guardian count | Multi-sig threshold         |

## Security Features

<CardGroup cols={2}>
  <Card title="Timelock" icon="clock">
    Large withdrawals require waiting period, giving time to cancel suspicious activity
  </Card>

  <Card title="Multi-Sig" icon="users">
    Guardians must approve withdrawals exceeding daily limit
  </Card>

  <Card title="Duress PIN" icon="shield">
    Secret code that locks vault and silently alerts guardians
  </Card>

  <Card title="Daily Limits" icon="calendar">
    Instant withdrawals capped to limit theft impact
  </Card>
</CardGroup>

## Integration Example

```typescript theme={null}
import { ethers } from 'ethers';

// Create vault with 3 guardians, 2 required signatures
await socialVault.createVault(
  ethers.parseUnits("100", 6),  // $100 daily limit
  86400,                         // 24h timelock
  [guardian1, guardian2, guardian3],
  2,                             // 2-of-3 multi-sig
  ethers.keccak256(ethers.toUtf8Bytes("my-duress-pin"))
);

// Instant withdrawal within limit
await socialVault.withdrawInstant(
  ethers.parseUnits("50", 6),
  recipientAddress
);

// Large withdrawal with timelock
const withdrawalId = await socialVault.requestWithdrawal(
  ethers.parseUnits("500", 6),
  recipientAddress
);
// Wait for guardian approvals and timelock...
```

## Related Documentation

<CardGroup cols={2}>
  <Card title="Guardians Guide" icon="users" href="/core-concepts/social-vault/guardians">
    How to manage guardians
  </Card>

  <Card title="Duress PIN" icon="shield" href="/core-concepts/social-vault/duress-pin">
    Anti-kidnapping feature
  </Card>
</CardGroup>
