Staking Contract Development

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
Staking Contract Development
Medium
~3-5 business days
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1214
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823

Staking Contract Development

A staking contract is one of the basic DeFi primitives. A user deposits tokens, receives rewards over time, and can withdraw. It sounds simple — and that's exactly why most implementations contain bugs. A correct reward calculation mechanism is non-trivial, and mistakes here cost money.

Reward Distribution: accumulated reward per token algorithm

A naive implementation iterates through all stakers and updates their balances — this is O(n) in gas and kills the contract with a large number of users.

The standard algorithm: accumulated reward per token. A global variable rewardPerTokenStored accumulates rewards per 1 token since deployment. With each deposit/withdraw it's updated. Individual reward is calculated as (rewardPerToken - userCheckpoint) × userBalance.

uint256 public rewardPerTokenStored;
uint256 public lastUpdateTime;

mapping(address => uint256) public userRewardPerTokenPaid;
mapping(address => uint256) public rewards;

function rewardPerToken() public view returns (uint256) {
    if (totalSupply == 0) return rewardPerTokenStored;
    return rewardPerTokenStored + 
        (block.timestamp - lastUpdateTime) * rewardRate * 1e18 / totalSupply;
}

function earned(address account) public view returns (uint256) {
    return balanceOf[account] * 
        (rewardPerToken() - userRewardPerTokenPaid[account]) / 1e18 
        + rewards[account];
}

This is O(1) — gas doesn't depend on the number of users. This is how Synthetix StakingRewards works, which became the reference implementation.

Core staking mechanics

Lock period: tokens are locked for N days after deposit. Reduces sell pressure. Requires storing depositTime and checking on withdraw.

Unstaking cooldown: after initiating withdrawal — waiting 7-28 days. Popular in PoS protocols (imitates unbonding period).

Early withdrawal penalty: when withdrawing before lock period expires — a penalty (for example, 10% of the amount). The penalty goes to the reward pool or is burned.

Time-based multiplier: the longer staking — the higher reward rate. Implemented through tiered multipliers or linear vesting multiplier.

Security

Reentrancy: when paying rewards via transfer → external call → function of the contract again. CEI pattern (Checks-Effects-Interactions): first update state, then make transfer.

Precision loss: division in Solidity rounds down. With small amounts or large totalSupply, precision can be lost. Use scaling factor 1e18 (or 1e27 for extra precision).

Reward token != staking token: if reward and staking tokens are the same — totalSupply includes reward tokens in the pool, which breaks rewardPerToken calculation. Need to carefully count only "staked" tokens.

Admin keys: who can change rewardRate? If it's an EOA — a single point of failure. Timelock + multisig — the standard for production contracts.

Staking contracts must pass audit before deployment — they hold user funds and are frequent targets for exploits.