Launchpad Staking Contract

IFAllocationMaster.sol

This contract is responsible for giving allocation for staking tokens over time.

Users stake to specific tracks, where stake weight accrues. Stake weight increases over time proportional to stake amount. For each passing block, a user's stake weight increases by their staked amount the previous block (times a scaling constant).

A sale contract will calculate a user's allocation as their stake weight divided by the total stake weight (from a particular track).

Events

event AddTrack(string indexed name, address indexed token);
event DisableTrack(uint24 indexed trackId);
event ActiveRollOver(uint24 indexed trackId, address indexed user);
event BumpSaleCounter(uint24 indexed trackId, uint32 newCount);
event AddUserCheckpoint(uint24 indexed trackId, uint80 blockNumber);
event AddTrackCheckpoint(uint24 indexed trackId, uint80 blockNumber);
event Stake(uint24 indexed trackId, address indexed user, uint104 amount);
event Unstake(uint24 indexed trackId, address indexed user, uint104 amount);

Public variables

trackFinishedSaleBlocks

mapping(uint24 => mapping(uint24 => uint80))
    public trackFinishedSaleBlocks;

The number of checkpoints of a track.

(track, finished sale count) => block number

trackActiveRollOvers

mapping(uint24 => mapping(address => mapping(uint24 => uint192)))
        public trackActiveRollOvers;

Stake weight each user actively rolls over for a given track and a finished sale count.

(track, user, finished sale count) => amount of stake weight

trackTotalActiveRollOvers

mapping(uint24 => mapping(uint24 => uint192))
        public trackTotalActiveRollOvers;

Total stake weight actively rolled over for a given track and a finished sale count.

(track, finished sale count) => total amount of stake weight

tracks

TrackInfo[] public tracks;

Array of track information indexed by track number.

numTrackStakers

mapping(uint24 => uint256) public numTrackStakers;

Number of unique stakers on a track.

(track) => staker count

trackStakers

mapping(uint24 => address[]) public trackStakers;

Array of unique stakers on track.

(track) => address array

trackCheckpointCounts

mapping(uint24 => uint32) public trackCheckpointCounts;

The number of checkpoints of a track.

(track) => checkpoint count

trackCheckpoints

mapping(uint24 => mapping(uint32 => TrackCheckpoint))
        public trackCheckpoints;

Track checkpoint mapping.

(track, checkpoint number) => TrackCheckpoint

userCheckpointCounts

mapping(uint24 => mapping(address => uint32))
    public userCheckpointCounts;

The number of checkpoints of a user for a track.

(track, user address) => checkpoint count

userCheckpoints

mapping(uint24 => mapping(address => mapping(uint32 => UserCheckpoint)))
        public userCheckpoints;

User checkpoint mapping.

(track, user address, checkpoint number) => UserCheckpoint

Functions

constructor

constructor() {}

The constructor takes no parameters.

trackCount

function trackCount() external view returns (uint24)

Gets the number of tracks.

addTrack

function addTrack(
    string calldata name,
    ERC20 stakeToken,
    uint24 _weightAccrualRate,
    uint64 _passiveRolloverRate,
    uint64 _activeRolloverRate,
    uint104 _maxTotalStake
) public onlyOwner

Adds a new track.

Note: Weight accrual rate is essentially a scaling constant for calculating stake weights. Mathematically, for each block that passes, a user's stake weight increases as follows:

previous block staked amount * weight accrual rate / 10**18

The main purpose of weight accrual rate is for scaling precision, making sure even small staked amounts don't accrue 0 weight every block. Since weight accrual rate is uint24 (and it cannot be set to 0), stake weight increase per block is limited to the following range:

  • Min: previous block staked amount / 10**18

  • Max: previous block staked amount * 10**6

This is limited enough to allow weight accrual rate to increase precision without a big risk of causing overflow in stake weight.

bumpSaleCounter

function bumpSaleCounter(uint24 trackId) public onlyOwner

Bumps a track's finished sale counter.

disableTrack

function disableTrack(uint24 trackId) public onlyOwner

Disables a track.

activeRollOver

function activeRollOver(uint24 trackId) public

Perform active rollover.

getUserStakeWeight

function getUserStakeWeight(
    uint24 trackId,
    address user,
    uint80 blockNumber
) public view returns (uint104)

Gets a user's stake weight within a track at a particular block number.

getTotalStakeWeight

function getTotalStakeWeight(uint24 trackId, uint80 blockNumber)
    public
    view
    returns (uint104)

Gets total stake weight within a track at a particular block number.

stake

function stake(uint24 trackId, uint104 amount) external

Stakes on a track.

unstake

function unstake(uint24 trackId, uint104 amount) external

Unstakes from a track.

Other useful notes

Getting user's stake amount in a track

This can be obtained with the following steps:

  1. Get the number of checkpoints for the user checkpointCount = userCheckpointCounts[track ID][user address]

  2. Get the user's latest checkpoint:latestCheckpoint = userCheckpoints[track ID][user address][checkpointPount-1]

  3. Get the user's current staked amount via the staked field on the latest checkpoint.

Last updated