# Payout Vaults

A Payout Vault is a way to manage distributions of slashed Safety Module assets to a set of addresses via an off-chain Merkle tree.

## Deploying a Payout Vault

The PayoutVaultFactory's `deployPayoutVault` function can be used to deploy a Payout Vault:

```solidity
function deployPayoutVault(address owner_, IERC20[] calldata assets_, bytes32 baseSalt_)
    external
    returns (IPayoutVault payoutVault_)
```

The `owner_` is the manager of the Payout Vault that will be responsible for registering new payout assets, setting the Merkle tree root, and withdrawing assets once payouts have been processed.

The `assets_` argument is a list of registered assets (see [below](#registering-assets) for more details).

## Managing a Payout Vault

### Registering Assets

All assets that will eventually be distributed need to be registered with the Payout Vault. In most cases, these assets are simply a Safety Module's reserve assets. The owner can register new assets by calling `PayoutVault.registerPayoutAssets`.

### Merkle Tree and Setting the Root

Each address claiming payout assets is entitled to a `claimableShare` of each registered asset's balance in the Payout Vault (represented as a WAD, so 50% is 0.5e18).

It is assumed an off-chain Merkle tree of all eligible addresses has been computed, where each leaf represents a single eligible user encoded as:

```solidity
bytes32 leaf = 
    keccak256(bytes.concat(keccak256(abi.encode(userAddress, claimableShare))));
```

To set the Merkle tree root, the owner can call `PayoutVault.setRoot`.

### Setting Claims Deadline

The owner also sets a deadline by which all users must claim by calling `PayoutVault.setClaimsDeadline`.

### Initializing Claims

The preferred way to initialize claims is by the owner calling:

```solidity
function initializeClaims(bytes32 root_, uint256 claimsDeadline_) external onlyOwner;
```

Note that this call sets the Merkle root and the claims deadline. It also takes a snapshot of the PayoutVault's balances of all registered assets. These balances are the total amounts of each asset that are eventually paid out to users.

### Withdrawing Assets

Once the `PayoutVault.claimsDeadline` has passed, the owner can withdraw any remaining assets in the vault by calling `PayoutVault.withdraw`.

### Pause

In case of an emergency, the owner can also pause claims, by calling `PayoutVault.pause`.

## Claiming Payouts

An address that wishes to claim payouts from the vault must call:

```solidity
function claim(bytes32[] calldata proof_, uint256 claimableShare_) external;
```

where `proof_` is the appropriate Merkle tree proof and `claimableShare_` is that address's appropriate share of the vault assets. It is assumed that an off-chain service will help users generate these values for them given the Merkle tree.

Payouts must be claimed by the `PayoutVault.claimsDeadline` or they may be withdrawn.
