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;
NameDescription

root_

The merkle root generated off-chain

invalidatePeriod

Allows rewards admin to stop rewards claims for a specific periodId

function invalidatePeriod(uint256 periodId_) external;
NameDescription

periodId_

The periodId allocated to each Merkle root during the setPeriodicRewards call

rescueRewards

Allows rewards admin to move reward tokens back to PayMaster

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

rewardTokens_

The ERC20 token address to move from the rewards distributor to paymaster

amounts_

The amount of reward tokens to move from the rewards distributor to paymaster

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;
NameDescription

receiver_

The user address to claim the rewards for

periodId_

The unique identifier of the claim period allocated while updating the Merkle root

rewardTokens_

The addresses of reward tokens to be claimed in the form of an array

amountsClaimed_

The amounts of reward tokens to be claimed in the form of an array

proof_

The merkle proof to validate the claim

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;
NameDescription

receiver_

The user address to claim the rewards for

periodIds_

The unique identifier of the claim periods in the form of an array

rewardTokens_

The addresses of reward tokens to be claimed

amountsClaimed_

The amounts of reward tokens to be claimed

proof_

The merkle proofs to validate the claim

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);
NameDescription

claimer_

The user address to claim the rewards for

periodId_

The unique identifier of the claim period allocated while updating the Merkle root

rewardTokens_

The addresses of reward tokens to be claimed in the form of an array

amountsClaimed_

The amounts of reward tokens to be claimed in the form of an array

proof_

The merkle proof to validate the claim

Last updated