This smart contract is a generic Staking solution that supports any number of NFT staking projects at the same time, each one with its own staking configuration (daily rewards, custom SPL token...). Its design is focused on simplifying the addition and configuration of new projects to the extent that it can be done without writing any code or re-deploying the contract. Following that idea, this smart contract serves two types of clients:
- Project owners: they can set up a new staking project (
init_stakinginstruction), edit the configuration of an existing one (set_stakinginstruction) or withdraw part of the rewards from the escrow (withdraw_rewardsinstruction). - Project NFT holders: they can stake their NFTs (
stake_nftinstruction), withdraw them (unstake_nftinstruction), and claim rewards (claim_stakinginstruction).
- The key to supporting multiple projects withing the same program is the
staking_key, which is an unique PublicKey per project used to derive the rest of project-specific accounts. - The staked NFTs, and the token rewards, are deposited in program owned project-specific escrow accounts.
- The project is using Merkle Tree verification - from Metaplex Gumdrop - to ensure an NFT is part of a collection. It will be updated to the new Metaplex collection standard once it is adopted.
Each staking project can be configured with these configuration parameters:
daily_rewards: amount of SPL tokens each NFT can claim per day. The NFT holder can get that amount multiplied by its NFTrarity_multiplier. The rarity multiplier is not stored on-chain; it is used to calculate the Merkle tree during project initialization and later when staking/unstaking/claiming (checkdevnetMints.jsonfile).start: the timestamp when the Staking goes live.mint: SPL token used for the rewards. It could be a custom token or Wrapped SOL.
- Deploy the program using
yarn deploy:mainnetoryarn deploy:devnet. This uploads to program on the solana blockchain. To work, you need to have akey.jsonfile at the root of this folder (create one usingsolana-keygen new -o key.json) and this account must have enough to pay rent.
- Run
anchor testto run tests on a local validator. Every instruction is covered by tests.
There are a set of ready to use scripts that serve as a reference CLI for trying the smart contract functionalities manually by generating a new NFT staking project and interacting with it:
- Initialize a new staking project with
yarn initialize:mainnetoryarn initialize:devnet. It reads the project configuration fromconfig.json. This generates a newstaking_key, creates the Staking main account and it's associated SPL reward token (a new one), and sends half of the supply to the staking rewards account. - Change configurations of the created project with
yarn reset:mainnetoryarn reset:devnet. It reads the existing project addresses fromdeployments.json, and updates the config with the current values ofconfig.json. - Print all the accounts used by the created project with
yarn get-accounts:mainnetoryarn get-accounts:devnet. - Top up the rewards wallet of the created project using
yarn transfer:mainnetoryarn transfer:devnet. - Withdraw rewards from the rewards wallet using
yarn withdraw:mainnetoryarn withdraw:devnet.