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:

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 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:

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:

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:

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.

Last updated