RewardsDistributor

Introduction

RewardsDistributor is a stand-alone contract that accumulates and distributes vault rewards to Superform users. Often, vaults listed on the Superform protocol reward users with an additional token reward in addition to the yield they generate by depositing to such vaults. Since all these rewards are accrued by the superforms and have to be distributed fairly to the users, this contract is being used to facilitate the distribution.

Core Concepts

The RewardDistributor contract is akin to a traditional merkle-tree-based airdrop contract. The Merkle tree with leaves indicating the user's reward tokens to be claimed is generated off-chain, and the root is updated to the reward distributor contract using the setPeriodicRewards function. Once the root is updated, users can claim their rewards from the RewardsDistributor contract using the Merkle proof.

Distribution Flow

The distribution of rewards is a multi-step process. First, the reward tokens are moved from the individual Forms to the PayMaster by using the forwardDustToPaymaster function, which is an open function called by anyone. From the PayMasterfunds are swept to the Rewards Distributor by the PaymentAdmin address. Once the funds are moved to the paymaster, the Merkle tree is constructed off-chain, and the root is updated on the RewardsDistributor contract, from which the users can claim their rewards.

Merkle Leaf Structure

Each Merkle leaf consists of the user address, a unique period ID, reward tokens (an address array of ERC20 reward token addresses), amounts to be claimed by the user, and the blockchain ID (to prevent replay attacks).

keccak256(
  bytes.concat(
     keccak256(
        abi.encode(
            receiver_, 
            periodId_, 
            rewardTokens_, 
            amountsClaimed_, 
            CHAIN_ID
        )
     )
 )
);

Protected Functions

setPeriodicRewards

Allows rewards admin to set a new Merkle root. Allocates periodId which increments on every call.

function setPeriodicRewards(bytes32 root_) external payable;

invalidatePeriod

Allows rewards admin to stop rewards claims for a specific periodId

function invalidatePeriod(uint256 periodId_) external;

rescueRewards

Allows rewards admin to move reward tokens back to PayMaster

function rescueRewards(address[] calldata rewardTokens_, uint256[] calldata amounts_) external;

Claim Functions

claim

Allows the user to claim their rewards if they pass in a valid Merkle proof.

 function claim(
   address receiver_,
   uint256 periodId_,
   address[] calldata rewardTokens_,
   uint256[] calldata amountsClaimed_,
   bytes32[] calldata proof_
 ) external;

batchClaim

Similar to the claim function, it allows users to claim rewards for multiple periods at once.

function batchClaim(
  address receiver_,
  uint256[] calldata periodIds_,
  address[][] calldata rewardTokens_,
  uint256[][] calldata amountsClaimed_,
  bytes32[][] calldata proofs_
) external;

Helper Functions

verifyClaim

Helps to verify if the Merkle proof is valid. Return true if the Merkle proof is valid.

 function verifyClaim(
   address claimer_,
   uint256 periodId_,
   address[] calldata rewardTokens_,
   uint256[] calldata amountsClaimed_,
   bytes32[] calldata proof_
) external view returns (bool valid);

Last updated