Builders

Overview

The Builders contract is the core component of the protocol. It manages builder pools, allowing users to stake tokens and builders to accumulate and claim MOR rewards based on those stakes.

Each pool is uniquely identified by name and includes parameters such as minimum deposit amount, pool start time, claim lock period, and withdrawal lock time after deposit... Users can deposit tokens into any existing pool, and their effective contribution (virtual deposit) is calculated using a lock multiplier based on how long rewards are locked.

Rewards are not distributed directly to users. Instead, they accumulate at the pool level and can be claimed only by the pool’s builder (admin). Builders then choose how to distribute these rewards off-chain. The global MOR reward rate is calculated across all pools, and each pool receives a share based on its total virtual deposits.

Key Features

  1. Pool creation and configuration: anyone can create a pool with custom parameters; the builder (admin) is assigned at creation.

  2. User staking: users stake tokens into any active pool, with lock-based multipliers increasing their contribution weight.

  3. Builder-controlled reward claiming: only builders can claim the total pool reward, enabling flexible distribution outside the contract scope.

  4. Reward calculation: uses a dynamic rate updated with each user action and proportional to the protocol-wide virtual deposits.

  5. Fee system: integrated with FeeConfig for applying customizable withdrawal and claim fees.

  6. Upgradeable and permissioned: built with UUPS and Ownable patterns for controlled upgrades and ownership-based access.

Storage

feeConfig

Address of the FeeConfig contract used to calculate protocol fees.

address public feeConfig;

buildersTreasury

Address of the BuildersTreasury contract which stores and distributes reward tokens.

address public buildersTreasury;

depositToken

Address of the MOR token users deposit into builder pools.

address public depositToken;

editPoolDeadline

The time window (in seconds) before the pool starts, during which pool parameters can still be edited by the pool admin.

uint128 public editPoolDeadline;

minimalWithdrawLockPeriod

Minimum duration (in seconds) after a deposit during which withdrawals are locked.

uint256 public minimalWithdrawLockPeriod;

totalPoolData

Aggregated data for all builder pools in the system.

TotalPoolData public totalPoolData;

struct TotalPoolData {
  uint256 distributedRewards;
  uint256 rate;
  uint256 totalDeposited;
  uint256 totalVirtualDeposited;
}
Name
Description

distributedRewards

Total amount of rewards distributed across all pools. Wei.

rate

The current reward rate

totalDeposited

Total tokens deposited without applying any multiplier. Wei.

totalVirtualDeposited

Total tokens deposited with multiplier (used in reward calculations). Wei

builderPools

Mapping of pool ID to pool configuration.

mapping(bytes32 => BuilderPool) public builderPools;

struct BuilderPool {
  string name;
  address admin;
  uint128 poolStart;
  uint128 withdrawLockPeriodAfterDeposit;
  uint128 claimLockEnd;
  uint256 minimalDeposit;
}
Name
Description

name

The name of the builder project.

admin

The address of the pool administrator (builder).

poolStart

Timestamp when the pool becomes active.

withdrawLockPeriodAfterDeposit

Time period after deposit during which withdrawal is locked. Seconds.

claimLockEnd

Timestamp after which rewards can be claimed by the builder admin. Seconds.

minimalDeposit

Minimum amount a user must deposit to participate. Wei.

buildersPoolData

Mapping of pool ID to the current dynamic pool state.

mapping(bytes32 => BuilderPoolData) public buildersPoolData;

struct BuilderPoolData {
  uint128 lastDeposit;
  uint256 deposited;
  uint256 virtualDeposited;
  uint256 rate;
  uint256 pendingRewards;
}
Name
Description

lastDeposit

Timestamp in seconds of the last deposit into the pool

deposited

Total amount deposited without multiplier. Wei.

virtualDeposited

Total amount deposited with multipliers applied. Wei.

rate

Current reward rate for the pool

pendingRewards

Accumulated unclaimed rewards for the pool. Wei.

usersData

Mapping of user address and pool ID to their user-specific data.

mapping(address => mapping(bytes32 => UserData)) public usersData;

struct UserData {
  uint128 lastDeposit;
  uint128 claimLockStart;
  uint256 deposited;
  uint256 virtualDeposited;
}
Name
Description

lastDeposit

Timestamp in seconds of the user's last deposit.

claimLockStart

Timestamp when the user activated the reward lock. Seconds

deposited

Total tokens the user deposited (raw amount). Wei

virtualDeposited

Tokens deposited by user with multiplier applied. Wei.

Fee oprations

The lables for fee operations, uses for fee receiving in the FeeConfig contract.

bytes32 private constant FEE_WITHDRAW_OPERATION = "withdraw";
bytes32 private constant FEE_CLAIM_OPERATION = "claim";

Write functions for the contract owner

Builders_init

Initializes the contract with essential parameters and configuration contracts. This function must be called once after deployment.

function Builders_init(
    address depositToken_,
    address feeConfig_,
    address buildersTreasury_,
    uint128 editPoolDeadline_,
    uint256 minimalWithdrawLockPeriod_
) external initializer
Name
Description

depositToken_

Address of the token that users will deposit in builder pools. MOR token.

feeConfig_

Address of the FeeConfig contract used to calculate protocol fees.

buildersTreasury_

Address of the BuildersTreasury contract used to store and distribute rewards.

editPoolDeadline_

Time (in seconds) before pool start when editing is still allowed.

minimalWithdrawLockPeriod_

Minimum lock duration after deposit in seconds before users can withdraw staked MOR.

setFeeConfig

Sets the address of the FeeConfig contract.

function setFeeConfig(address feeConfig_) public onlyOwner
Name
Description

feeConfig_

Address of a contract that implements IFeeConfig

setBuildersTreasury

Sets the address of the BuildersTreasury contract.

function setBuildersTreasury(address buildersTreasury_) public onlyOwner
Name
Description

buildersTreasury_

Address of a contract that implements IBuildersTreasury

setEditPoolDeadline

Sets the edit deadline (in seconds) for a builder pools relative to its start time.

function setEditPoolDeadline(uint128 editPoolDeadline_) public onlyOwner
Name
Description

editPoolDeadline_

Number of seconds before start when edit is allowed

setMinimalWithdrawLockPeriod

Sets the minimum lock period that must pass before a user can withdraw MOR after depositing.

function setMinimalWithdrawLockPeriod(
  uint256 minimalWithdrawLockPeriod_
) public onlyOwner
Name
Description

minimalWithdrawLockPeriod_

Minimum lock period (in seconds) after deposit before withdrawal

Write functions

createBuilderPool

Creates a new builder pool with specific parameters.

function createBuilderPool(BuilderPool calldata builderPool_) public
Name
Description

builderPool_

Struct with the new pool’s parameters: name, admin, start time, etc.

editBuilderPool

Edits an existing builder pool’s configuration before its edit deadline expires. The caller should be the builder pool admin.

function editBuilderPool(BuilderPool calldata builderPool_) external
Name
Description

builderPool_

Updated struct data of the builder pool to overwrite existing configuration

deposit

Allows a user to deposit MOR into a builder pool.

function deposit(bytes32 builderPoolId_, uint256 amount_) external
Name
Description

builderPoolId_

ID of the builder pool to deposit into.

amount_

Amount of MOR to deposit. Wei.

withdraw

Withdraws tokens from a specific builder pool.

function withdraw(bytes32 builderPoolId_, uint256 amount_) external
Name
Description

builderPoolId_

Identifier of the builder pool from which tokens will be withdrawn

amount_

Amount of tokens to withdraw; will be limited by user balance if too high. Wei.

claim

Allows the builder pool admin to claim the pool’s accumulated MOR rewards.

function claim(bytes32 builderPoolId_, address receiver_) external
Name
Description

builderPoolId_

Identifier of the builder pool from which tokens will be withdrawn

receiver_

Address to receive the claimed MOR rewards

Read functions

getNotDistributedRewards

Returns the total unclaimed MOR rewards stored in the BuildersTreasury.

function getNotDistributedRewards() public view returns (uint256)

getCurrentUserMultiplier

Returns the reward multiplier based on the user’s lock period for a pool.

function getCurrentUserMultiplier(
  bytes32 builderPoolId_,
  address user_
) public view returns (uint256)
Name
Description

builderPoolId_

Identifier of the builder pool from which tokens will be withdrawn

user_

User address whose multiplier is being calculated

getCurrentBuilderReward

Returns the current calculated reward for a builder pool.

function getCurrentBuilderReward(
  bytes32 builderPoolId_
) external view returns (uint256)
Name
Description

builderPoolId_

Identifier of the builder pool from which tokens will be withdrawn

getLockPeriodMultiplier

Returns the multiplier for rewards based on a lock period.

function getLockPeriodMultiplier(
  uint128 lockStart_,
  uint128 lockEnd_
) public pure returns (uint256)
Name
Description

lockStart_

Timestamp in seconds when the lock started.

lockEnd_

Timestamp in seconds when the lock ends.

getPoolId

Computes the unique ID of a builder pool based on its name.

function getPoolId(string memory builderPoolName_) public pure returns (bytes32)
Name
Description

builderPoolName_

Name of the builder pool

supportsInterface

Used for interface detection (ERC165). Returns true if the contract supports a specific interfaceId_. Supports IBuilders, IERC165.

function supportsInterface(bytes4 interfaceId_) external pure returns (bool)

Last updated

Was this helpful?