Staking contract

The following staking contract is designed to allow users to stake tokens in exchange for reward tokens over a specified duration. Here’s a quick summary of how it operates and what functionalities it supports:

Key Features:

  1. Token staking and unstaking:
    • Users can stake an ERC20 token, specified at deployment.
    • Users can withdraw their staked tokens at any time.
  2. Reward calculation and distribution:
    • The rewards are distributed as an ERC20, also specified at deployment (can be different from the staking token).
    • Rewards are calculated based on the duration of staking and the amount the user staked relative to the total staked amount by all users.
    • A user’s reward accumulates over time up until the reward period’s end and can be claimed anytime by the user.
  3. Dynamic reward rates:
    • The reward rate is determined by the total amount of reward tokens over a set period (duration).
    • The reward rate can be adjusted during the rewards period if new rewards are added before the current reward period finishes.
    • Even after a reward period finishes, a new reward duration and new rewards can be set up if desired.
  4. Ownership and administration:
    • Only the owner of the contract can set the rewards amount and duration.
:::note The reward mechanism ensures that rewards are distributed fairly based on the amount and duration of tokens staked by each user. ::: The following implementation is the Cairo adaptation of the Solidity by Example - Staking Rewards contract. It includes a small adaptation to keep track of the amount of total distributed reward tokens and emit an event when the remaining reward token amount reaches 0.
// [!include ~/listings/applications/staking/src/contract.cairo]