Skip to Content
EconomyStaking

Staking

Stake $RUN tokens to earn $CEO continuously. The StakingRewardsV2 contract implements MasterChef-style multi-pool farming with CeosCard tranche-based boost multipliers.

How It Works

  1. Deposit $RUN into the staking pool (pid=0)
  2. Earn $CEO every second, proportional to your effective stake weight
  3. Boost your earnings by holding a CeosCard NFT (up to 5x)
  4. Claim accumulated $CEO rewards at any time
  5. Withdraw your $RUN whenever you want (no lock period)

Tranche Multipliers

Your $CEO earning rate is boosted based on the best CeosCard in your wallet. The contract checks all NFTs you hold and applies the highest available multiplier:

CeosCard TierToken ID RangeSupplyMultiplierEffective Rate
Black1 - 1,0001,0005x500% of base
Gold1,001 - 4,0003,0003x300% of base
Silver4,001 - 10,0006,0002x200% of base
NoneN/A-1x100% (base)

The multiplier is applied to your staked amount to compute your effective stake:

effectiveAmount = stakedAmount * trancheMultiplier

Your share of the pool’s $CEO emission is effectiveAmount / totalEffectiveSupply.

StakingRewardsV2 Contract

PropertyValue
Address (Base Sepolia)0x80Da869E7EFcc77044F42D5BB016e9AB3424775D
ArchitectureMasterChef-style multi-pool + Synthetix accumulator
Reward Token$CEO (minted on-demand)
Primary Poolpid=0 for $RUN staking
Max Emission10 $CEO per second (MAX_CEO_PER_SECOND)
NFT ContractCeosCompanyNFT at 0xffC3994DfCf1F0ee6D30F41D8F8AaB73bd0aEB61

Key Functions

User Functions

// Stake $RUN into a pool function stake(uint256 pid, uint256 amount) external; // Withdraw $RUN from a pool function withdraw(uint256 pid, uint256 amount) external; // Claim pending $CEO rewards function claim(uint256 pid) external; // Refresh boost multiplier (call after acquiring/selling a CeosCard) function refreshBoost(uint256 pid) external; // Emergency withdraw (forfeits pending rewards) function emergencyWithdraw(uint256 pid) external;

View Functions

// Check pending $CEO rewards for an account function pendingReward(uint256 pid, address account) external view returns (uint256); // Get user's staking info (amount, effectiveAmount, multiplier, rewardDebt) function getUserInfo(uint256 pid, address account) external view returns (UserInfo memory); // Get pool info (stakingToken, allocPoint, totalEffectiveSupply, etc.) function getPoolInfo(uint256 pid) external view returns (PoolInfo memory); // Get the tranche multiplier for any address function getTrancheMultiplier(address user) external view returns (uint256); // Total number of pools function getPoolCount() external view returns (uint256);

Reward Math

The contract uses the Synthetix reward accumulator pattern:

accCeoPerShare += (elapsed * ceoPerSecond * allocPoint / totalAllocPoint * 1e18) / totalEffectiveSupply pendingReward = (user.effectiveAmount * accCeoPerShare / 1e18) - user.rewardDebt

This ensures gas-efficient reward tracking. The accCeoPerShare accumulator is updated lazily (only when a user interacts with the pool), and $CEO is minted on-demand when users claim.

Multi-Pool System

StakingRewardsV2 supports multiple pools, each identified by a sequential pid. Pools share the global ceoPerSecond emission rate, distributed by their allocPoint weight:

poolEmission = ceoPerSecond * pool.allocPoint / totalAllocPoint

The admin can add new pools (e.g., for LP token staking) and adjust allocation weights.

Integration

Stake $RUN

import { useWriteContract } from 'wagmi'; const STAKING_V2 = '0x80Da869E7EFcc77044F42D5BB016e9AB3424775D'; const RUN_TOKEN = '0x6f64C762B1306aFdd8a831e71Ab70199fd2EADd0'; // 1. Approve $RUN spend await writeContract({ address: RUN_TOKEN, abi: erc20Abi, functionName: 'approve', args: [STAKING_V2, amount], }); // 2. Stake into pid=0 await writeContract({ address: STAKING_V2, abi: stakingRewardsV2Abi, functionName: 'stake', args: [0n, amount], // pid=0 for $RUN pool dataSuffix: '0x6263375f376e69346a756a39', });

Check Pending Rewards

const { data: pending } = useReadContract({ address: STAKING_V2, abi: stakingRewardsV2Abi, functionName: 'pendingReward', args: [0n, userAddress], });

Claim $CEO

await writeContract({ address: STAKING_V2, abi: stakingRewardsV2Abi, functionName: 'claim', args: [0n], // pid=0 dataSuffix: '0x6263375f376e69346a756a39', });

Refresh Boost After CeosCard Purchase

// Call after acquiring a CeosCard to update your multiplier await writeContract({ address: STAKING_V2, abi: stakingRewardsV2Abi, functionName: 'refreshBoost', args: [0n], dataSuffix: '0x6263375f376e69346a756a39', });

Security

  • ReentrancyGuard on all state-changing external functions
  • SafeERC20 on all token transfers
  • Emission cap at 10 $CEO/second prevents runaway inflation
  • Emergency withdraw available (forfeits rewards, returns principal)
  • No lock period on standard withdrawals