Distribution V4

DistributionV4.sol is the core contract of the Techno Capital Machine. It allows Capital Providers to stake stETH (Lido Staked ETH) on Ethereum and claim MOR rewards to Arbitrum.

DistributionV4 utilizes L1Sender to bridge stETH yield and relay MOR claims to Arbitrum. LinearDistributionIntervalDecrease is used to calculate pool rewards.

This contract is also used to track other MOR emissions through private pools. For instance, pool 1 is a private pool used to track Code emissions, where deposit "amounts" correspond to weights.

Version history

The V3 version of the contract introduces the ability to lock MOR emissions for a chosen period of time. During this period, emissions cannot be claimed; however a multiplier of up to 10.7x is applied.

The V4 version of the contract introduces two new lock periods claimLockPeriodAfterClaim and claimLockPeriodAfterStake for each pool. Initially, these are set to 90 days for the capital pool (pool 0) and 0 for all other pools. During this period after claiming or staking, emissions are locked and cannot be claimed.

Public Variables

Name
Type
Description

depositToken

address

The address of the deposit token on Ethereum (stETH).

l1Sender

address

The address of the L1Sender contract.

pools

Pool[]

Configurations for all pools through which rewards are allocated.

poolsData

mapping(uint256 => PoolData)

Ongoing tracking data for all pools.

usersData

mapping(address => mapping(uint256 => UserData))

Ongoing tracking data for user participation in pools.

totalDepositedInPublicPools

uint256

The total amount of the deposit token in all public pools.

totalVirtualDeposited

uint256

The total "virtual" amount of the deposit token in all pools after accounting for claim lock multipliers.

claimLockPeriodAfterClaim

uint128

The period in seconds during which emissions cannot be claimed after claiming.

claimLockPeriodAfterStake

uint128

The period in seconds during which emissions cannot be claimed after staking.

Functions

stake

function stake(
    uint256 poolId_,
    uint256 amount_
    ) external poolExists(poolId_) poolPublic(poolId_)

Allows users to stake the deposit token (stETH) in a public pool.

Parameters

Name
Type
Description

poolId_

uint256

The ID of the public pool to stake in.

amount_

uint256

The amount of deposit tokens to stake.

lockClaim

function lockClaim(
    uint256 poolId_,
    uint128 claimLockEnd_
    ) external poolExists(poolId_)

Locks the user's claim for a specified period, during which a multiplier is applied. This incentivizes users to delay claiming emissions for higher returns.

Parameters

Name
Type
Description

poolId_

uint256

The ID of the public pool to lock for.

claimLockEnd_

uint128

The timestamp until which the claim is locked. Must be in the future.

claim

function claim(
    uint256 poolId_,
    address receiver_
    ) external payable poolExists(poolId_)

Enables users to claim their MOR rewards from a specific pool. After verifying claims internally, minting instructions are sent to L2MessageReceiver on Arbitrum via L1Sender.

Rewards can only be claimed after the claimLockPeriod.

Parameters

Name
Type
Description

poolId_

uint256

The ID of the pool to claim rewards from.

receiver_

address

The address where rewards are sent.

withdraw

function withdraw(
    uint256 poolId_,
    uint256 amount_
    ) external poolExists(poolId_) poolPublic(poolId_)

Allows users to withdraw their staked tokens from a public pool.

Withdrawals can only be made after the withdrawLockPeriod and withdrawLockPeriodAfterStake.

Parameters

Name
Type
Description

poolId_

uint256

The ID of the pool to withdraw from.

amount_

uint256

The amount of tokens to withdraw.

getCurrentUserReward

function getCurrentUserReward(
    uint256 poolId_,
    address user_
    ) external view returns (uint256)

Calculates and returns the current unclaimed reward amount for a user in a specified pool.

Parameters

Name
Type
Description

poolId_

uint256

The ID of the pool.

user_

address

The address of the user.

Return Values

Type
Description

uint256

The current unclaimed reward amount for the specified user.

Distribution_init

function Distribution_init(
    address depositToken_,
    address l1Sender_,
    Pool[] calldata poolsInfo_
    ) external initializer

Initializes the contract with the deposit token (stETH) address, L1Sender address, and initial pools.

Parameters

Name
Type
Description

depositToken_

address

The address of the deposit token.

l1Sender_

address

The address of the L1Sender contract.

poolsInfo_

Pool[]

An array of pools to be initialized.

createPool

function createPool(
    Pool calldata pool_
    ) public onlyOwner

Creates a new pool based on the provided pool configuration. This function can only be called by the owner of the contract.

Parameters

Name
Type
Description

pool_

Pool

The configuration of the new pool.

editPool

function editPool(
    uint256 poolId_,
    Pool calldata pool_
    ) external onlyOwner poolExists(poolId_)

Edits an existing pool's configuration. This function can only be called by the owner of the contract.

Parameters

Name
Type
Description

poolId_

uint256

The ID of the pool to be edited.

pool_

Pool

The new configuration for the pool.

getPeriodReward

function getPeriodReward(
    uint256 poolId_,
    uint128 startTime_,
    uint128 endTime_
    ) public view returns (uint256)

Calculates the reward for a specified pool and period. Uses the LinearDistributionIntervalDecrease library.

Parameters

Name
Type
Description

poolId_

uint256

The ID of the pool.

startTime_

uint128

The start timestamp of the period.

endTime_

uint128

The end timestamp of the period.

Return Values

Type
Description

uint256

The total reward amount for the period.

getClaimLockPeriodMultiplier

function getClaimLockPeriodMultiplier(
    uint256 poolId_,
    uint128 claimLockStart_,
    uint128 claimLockEnd_
    ) public view returns (uint256)

Calculates the multiplier based on the duration between the start and end of the claim lock period. This multiplier is applied to the user’s stake (or weights) for emissions calculations.

Parameters

Name
Type
Description

poolId_

uint256

The ID of the pool.

claimLockStart_

uint128

The start timestamp of the claim lock period.

claimLockEnd_

uint128

The end timestamp of the claim lock period.

Return Values

Type
Description

uint256

The multiplier applied to the user's virtual deposit.

getCurrentUserMultiplier

function getCurrentUserMultiplier(
    uint256 poolId_,
    address user_
    ) public view returns (uint256)

Returns the current reward multiplier for a user based on their claim lock period.

Parameters

Name
Type
Description

poolId_

uint256

The ID of the pool.

user_

address

The address of the user.

Return Values

Type
Description

uint256

The reward multiplier currently applied to the user.

manageUsersInPrivatePool

function manageUsersInPrivatePool(
    uint256 poolId_,
    address[] calldata users_,
    uint256[] calldata amounts_
    ) external onlyOwner poolExists(poolId_)

Manages user stakes in a private pool used for non-Capital emissions by adjusting their deposited "amounts" based on a specified array. This function can only be called by the owner of the contract.

In the case of Code emissions (e.g. pool 1), amounts correspond to weights.

Parameters

Name
Type
Description

poolId_

uint256

The ID of the private pool to manage users in.

users_

address[]

An array of user addresses to manage stakes for.

amounts_

uint256[]

An array of amounts corresponding to each user.

overplus

function overplus(
    ) public view returns (uint256)

Calculates the amount of surplus deposit tokens (stETH yield) in the contract that are not deposited in any pools. These tokens can be bridged to Arbitrum to provision Protocol-Owned Liquidity.

Return Values

Type
Description

uint256

The amount of surplus deposit tokens in the contract.

bridgeOverplus

function bridgeOverplus(
    uint256 gasLimit_,
    uint256 maxFeePerGas_,
    uint256 maxSubmissionCost_
    ) external payable onlyOwner returns (bytes memory)

Bridges surplus deposit tokens (stETH yield) to Arbitrum via L1Sender. This function can only be called by the owner of the contract.

Parameters

Name
Type
Description

gasLimit_

uint256

The gas limit for the bridging transaction.

maxFeePerGas_

uint256

The maximum fee per gas unit willing to be paid.

maxSubmissionCost_

uint256

The maximum cost willing to be paid for submission.

Return Values

Type
Description

bytes

The ABI-encoded Arbitrum inbox sequence number.

Events

PoolCreated

event PoolCreated(
    uint256 indexed poolId,
    Pool pool
    )

Emitted when a new pool is created.

Parameters

Name
Type
Description

poolId

uint256

The unique identifier of the created pool.

pool

Pool

The pool configuration.

PoolEdited

event PoolEdited(
    uint256 indexed poolId,
    Pool pool
    )

Emitted when an existing pool's configuration is edited.

Parameters

Name
Type
Description

poolId

uint256

The unique identifier of the pool that was edited.

pool

Pool

The pool configuration.

UserStaked

event UserStaked(
    uint256 indexed poolId,
    address indexed user,
    uint256 amount
    )

Emitted when a user stakes tokens in a pool.

Parameters

Name
Type
Description

poolId

uint256

The ID of the pool in which tokens are staked.

user

address

The address of the user who staked tokens.

amount

uint256

The amount of tokens staked by the user.

UserClaimed

event UserClaimed(
    uint256 indexed poolId,
    address indexed user,
    address receiver,
    uint256 amount
    )

Emitted when a user claims rewards from a pool.

Parameters

Name
Type
Description

poolId

uint256

The ID of the pool from which rewards are claimed.

user

address

The address of the user claiming rewards.

receiver

address

The address where the claimed rewards are sent on Arbitrum.

amount

uint256

The amount of rewards claimed by the user.

UserWithdrawn

event UserWithdrawn(
    uint256 indexed poolId,
    address indexed user,
    uint256 amount
    )

Emitted when a user withdraws from a pool.

Name
Type
Description

poolId

uint256

The ID of the pool from which tokens are withdrawn.

user

address

The address of the user withdrawing tokens.

amount

uint256

The amount of tokens withdrawn by the user.

OverplusBridged

event OverplusBridged(
    uint256 amount,
    bytes uniqueId
    )

Emitted when surplus deposit tokens are bridged to Arbitrum.

Parameters

Name
Type
Description

amount

uint256

The amount of surplus deposit tokens that were bridged.

uniqueId

bytes

The ABI-encoded Arbitrum inbox sequence number.

Structs

Pool

struct Pool {
    uint128 payoutStart;
    uint128 decreaseInterval;
    uint128 withdrawLockPeriod;
    uint128 claimLockPeriod;
    uint128 withdrawLockPeriodAfterStake;
    uint256 initialReward;
    uint256 rewardDecrease;
    uint256 minimalStake;
    bool isPublic;
    }

Configuration data for a pool, including reward distribution schedules and lock periods. Also see LinearDistributionIntervalDecrease.

Fields

Name
Type
Description

payoutStart

uint128

The timestamp at which the distribution schedule starts.

decreaseInterval

uint128

The duration of each interval in seconds.

withdrawLockPeriod

uint128

The period in seconds during which stake cannot be withdrawn.

claimLockPeriod

uint128

The period in seconds during which rewards cannot be claimed.

withdrawLockPeriodAfterStake

uint128

The lock period after staking during which stake cannot be withdrawn.

initialReward

uint256

The initial reward amount per interval.

rewardDecrease

uint256

The amount by which the reward decreases each interval.

minimalStake

uint256

The minimum stake amount required for participation in the pool.

isPublic

bool

Indicates if the pool is open to the public or private.

PoolData

struct PoolData {
    uint128 lastUpdate;
    uint256 rate;
    uint256 totalDeposited;
    }

Fields

Name
Type
Description

lastUpdate

uint128

The timestamp of the last update to the pool's data.

rate

uint256

The current reward rate for the pool.

totalDeposited

uint256

The total amount of tokens deposited in the pool.

UserData

struct UserData {
    uint128 lastStake;
    uint256 deposited;
    uint256 rate;
    uint256 pendingRewards;
    }

Fields

Name
Type
Description

lastStake

uint128

The timestamp when the user last staked tokens in the pool.

deposited

uint256

The amount of tokens the user has deposited in the pool.

rate

uint256

The current reward rate applicable to the user.

pendingRewards

uint256

The amount of rewards that the user can claim.

Last updated

Was this helpful?