Architecture

Skrimples for Shibarium is comprised of four main components. 1) Skrimples Token

2) The Boneyard

3) stBONE

4) Validator Registry

Skrimples Token

Skrimples is an ERC20 that powers the Skrimples ecosystem and has three primary uses:

  • Reward users who stake their $SKRIMP in the Boneyard

  • Register validators and determine their max delegation of $BONE

  • Governance of Ruffhouse Gang DAO

Skrimples has built in fees when traded on dexes. Fees are used to fund development, marketing, and for buybacks which can be redistributed as staking rewards.

Devs Bimpus and Snake have the ability to modify trading fees on $SKRIMP, but they fees cannot be raised over 5% on either buys or sells. While the contract is designed to allow the modification of fees, this is the only admin controlled function that could have any impact on the trading of the token.

The Boneyard

The Boneyard is a staking contract through which admins can create pools, and users can deposit their $SKRIMP (and other tokens) to earn rewards. Shibarium validators can secure a larger maximum delegation of $BONE from the protocol's LSD by staking $SKRIMP in pool 0.

The Boneyard is a fork of Sushiswap's MasterChef contract with some significant modifications. With the original contract it was impossible to create a staking pool for SUSHI, the reward token. The Boneyard allows the staking of $SKRIMP to be rewarded in $SKRIMP. Other changes are as follows:

  • Skrimples rewards per block is modifiable through an admin only function

  • ACL - Access Control used in favor of OpenZeppelin's Ownable contract

  • Removed the migrator and all related functions, along with the risk these posed to users

  • Skrimples is on a fixed supply, not mintable like SUSHI, so contract employs transferFrom function to move rewards from the treasury

stBONE

The stBONE contract is an ERC20 token contract which performs the following functions:

  • User interaction

  • Reward Distribution

  • Manage withdrawals

  • Manage reward fees

  • Delegate to validators

  • Mint and burn NFTs

ACL

Skrimples, stBONE, and the Boneyardcontract uses OpenZeppelin AccessControl to manage permissions.

User Interaction:

A user can interact only with the stBONE contract to:

  • Submit ERC20 BONE

  • Request Withdraw

  • Claim withdraw

  • call ERC20 functions

Users can submit BONE and get stBONE automatically by calling the submit function inside the StBone contract and passing the delegated amount.

Minting stBONE

The total amount of stBONE that a user will get when delegate his BONE tokens is calculated as follows:

sharePerUser = submittedBone * totalShares / totalPooledBone

The totalPooledBone is the total amount of the buffered tokens (submitted by the user but not yet delegated) plus the total delegated.

totalPooledBone = totalBufferedBone + totalDelegatedBones

Example:

Case 1

Initial states

totalShares0

totalPooledBone

0

User1 submit

  • submit ==> 1000 BONE

  • Gets ==> 1000 stBONE

Update states

totalShares1000

totalPooledBONE

1000

Users Shares

UseruserP = userShares / totalSharesuserBone = userP * totalPooledBone

1

1 = 1000 / 1000

1 * 1000 = 1000

Case 2

User2 submit

  • submit ==> 500 Bone

  • Gets ==> 500 * 1000 / 1000 = 500 stBone

Update states

totalShares1500

totalPooledBone

1500

Users Shares

UseruserP = userShares / totalSharesuserBone = userP * totalPooledBone

1

0.66 = 1000 / 1500

0.66 * 1500 = 1000

2

0.33 = 500/ 1500

0.33 * 1500 = 500

Case 3

The system was slashed => -100 BONE

Update states

totalShares1500

totalPooledBone

1500 - 100 = 1400

Users Shares

UseruserP = userShares / totalSharesuserBone = userP * totalPooledBone

1

0.66 = 1000 / 1500

0.66 * 1400 = 933.33

2

0.33 = 500/ 1500

0.33 * 1400 = 466.66

Case 4

User3 submit

  • submit ==> 500 Bone

  • Gets ==> 500 * 1500 / 1400 = 535.71 stBone

Update states

totalShares2035.71

totalPooledBone

1900

Users Shares

UseruserP = userShares / totalSharesuserBone= userP * totalPooledBone

1

0.4912= 1000 / 2035.71

0.4912 * 1900 = 933.33

2

0.2456= 500 / 2035.71

0.2456 * 1900 = 466.66

3

0.2631= 535.71 / 2035.71

0.2631 * 1900 = 500

Case 4

The system accumulates reward => +200 BONE

Update states

totalShares2035.71

totalPooledBone

1900 + 200 = 2100

Users Shares

UseruserP = userShares / totalSharesuserBone = userP * totalPooledBone

1

0.4912= 1000 / 2035.71

0.4912 * 2100=1031.52

2

0.2456= 500 / 2035.71

0.2456 * 2100= 515.76

3

0.2631= 535.71 / 2035.71

0.2631 * 2100= 552.62

When the system gets slashed, the total pooled BONE decreases, and it increases when a user submits BONE again or the system gets rewarded.

Delegate to Validators

The StBone contract facilitates token delegation to validators.

The delegation process relies on the bufferedBone tokens stored within the StBone contract. Once the minDelegationAmount is reached, the delegation to all Staked operators begins. Each operator is assigned a maxDelegateLimit value, determined by the DAO. For instance, trusted operators will have larger values, while non-trusted validators will have lower values. This maxDelegateLimit allows us to distribute tokens among these operators.

Trusted validators with the greatest number of shares of staked $SKRIMP in the Boneyard will receive the highest maxDelegateLimit.

Manage Withdrawals

Withdrawals are processed using the new validatorShare exit API, which introduces a unique nonce for each user request. The Bone contract keeps track of each validatorShare nonce, which increments with every new withdrawal request.

  1. When a user requests to withdraw their BONE tokens, a fresh ERC721 token is minted and associated with the request. This newly minted token can be traded, sold, or used to redeem the user's BONE tokens.

  2. The withdrawal process involves the following steps:

    1. The user initiates the withdrawal request.

    2. An NFT is minted, and its identifier is linked to the withdrawal request.

    3. The request nonce of the validatorShare and validatorShare address are stored.

    4. The sellVoucher_new function is invoked.

  3. Claim tokens:

    1. The user calls the claim token function and passes the tokenId.

    2. A check is made to ensure that the msg.sender (caller) is the owner of this NFT.

    3. Call the claim unstake tokens function on the validatorShare contract.

    4. Transfer tokens to the user

    5. Burn the NFT.

Distribute Rewards

BONE tokens are accumulated and stored inside the StBone contract upon 2 events:

  1. Each time a user requests to withdraw, the validatorShare contract transfers the rewards

  2. Scheduled job (explained below)

TOTAL_REWARDS = accumulated rewards on Skrimples + accumulated rewards on all validators

As we are going to allow the operator to stake a max number of BONE tokens, the accumulated rewards on all validator's sides are ignored. We are going to use Chainlink Keeper or Gelato to distribute rewards. We regularly check if the amount is greater than a lower bound (a variable that can be set). If that requirement is fulfilled, StBone calculates the amount that the Node Operators and the treasury get, transfers tokens to them immediately. Finally, the remaining BONE tokens are added as a buffered and re-delegated which increases totalPooledBone value. 5% of the staking rewards go to Skrimples treasury, and 5% goes to Node Operators, whereas 90% goes to the stBONE value using re-delegation.

The operator's rewards are distributed between all the staked operators using a ratio. A validator has a ratio of 100% if he was not slashed during the last period. Else if the validator was slashed his ratio is 80% of his total reward part the remainder will be distributed to the other validators.

withdrawTotalDelegated

When an operator was unstaked, the nodeOperator contract called withdrawTotalDelegated function which claims all the delegated Bone from the unstacked validator an NFT token is mint and mapped with this request later a cron job can call claimTokens2StBone to withdraw the Bone from the validatorShare.

ValidatorShare Behaviour

When a user requests withdrawal, the validatorShare contract transfers the total rewards accumulated automatically. The same thing happens when buying new vouchers. So the idea is to consider all the tokens that are not submitted (not buffered) using the submit function as rewards, and they should be distributed.

Manage reward fees:

We can manage the rewards fees using the StBone contract.

ValidatorShare API

The StBone implements the validatorShare contract API

  1. BuyVoucher_new: buy shares from a validator link.

  2. SellVouchernew: sell an amount of shares link. Also, it has a good feature that allows us to track each sell request using a nonce.

  3. unstakeClaimTokens_new: claim the token by a nonce link.

  4. getTotalStake: get the total staked amount link.

  5. getLiquidRewards: get the accumulated rewards link

SkrimplesNFT

The SkrimplesNFT contract is an ERC721 contract used by the StBone contract to manage withdrawal requests.

Each time a user calls the requestWithdraw function inside the StBonecontract a new NFT is minted and mapped with the request.

When a user owns an NFT he can:

  • Claim a tokens from the withdraw request

  • Trade NFT to someone else, who will then be able to claim

  • Approve it to someone else who willl then also be able to claim

This ERC721 is slightly modified so it returns a list of owned tokens of an address by using the public mapping owner2Tokens. Same goes for retrieving the list of approved tokens by using the mapping address2Approved.

Validator Registry

The Validatory Registry is Skrimples' system for onboarding eligible validators and determining their maximum delegation of BONE from the Skrimples protocol.

Validators are incentivized to stake their Skrimples tokens in Skrimples' Boneyard. The greater the stake, the greater their maximum delegation of Skrimples.

Validators are added by the registry by holding Skrimples and by applying to be added by the Ruffhouse Gang DAO.

Operator contract

  • Manage operators

    The validator contract is used to stake on the polygon stake manager. Each operator gets a new validatorProxy contract created each time the addOperator function is called, this validatorProxy is used as the owner of the validator on the Polygon stakeManager.Thought it an operator’s owner can interact with the stakeManager API to:

    • stakeFor: stake a validator link.

    • unstake: unstake a validator link.

    • topUpForFee: topUpHeimdallFees for a validator link.

    • validatorStake: get the total staked by a validator link.

    • restake: restake amount link.

    • getValidatorContract: get validator share contract link.

    • updateSIgner: allows to update signer pubkey

    • claimFee: allows to withdraw heimdall fees

    • updateCommisionRate: allows to update commision

    • withdrawRewards: withdraw rewards link

Manage Operators

  1. Add an operator

    1. A new Operator expresses their interest to join the Skrimples protocol.

    2. The DAO votes to include the new operator. After successful voting for inclusion, the Node Operator becomes active:

      1. A new validator contract is created.

      2. Set the status to NotStaked.

      3. A default max delegation value is set that means the system will delegate this amount (at max) each time the delegate function is called.

    Each operator owner can interact with his operator using the reward address to do the following actions:

    • stake

    • join

    • Unstake

    • topUpHeimdallFees

    • unjail

    • restake

    • update signer pub key

    • unstake claim.

    • claim fee.

Stake an operator

  1. The operator calls the stake function, including the amount of BONE and heimdallFees.

  2. The operator is switched to staked status and becomes ready to accept delegation.

Join

  1. Allows already staked validators to join the Skrimples protocol.

  2. They have first to approve the NFT token to the specific validatorProxy contract.

  3. Call this function to join the system.

Unstake an Operator

When an operator is ongoing to be unstaked, the NodeOperator contract calls the StBone contract in his turn calls the validatorShare contract and withdraws the total delegated BONE tokens. After the withdrawal delay the lido contract can claim those tokens. This last step claiming the tokens can be done using a cron job.

Remove an Operator

Remove an operator is the last step after it was unstaked and he claimed his staked tokens. The DAO can call this function to remove the operator and delete the validatorProxy contract.

Top Up Heimdall Fees

A validator has the possibility to topup the heimdall fees used by the heimdall and the Bor node for validating new blocks

Unjail

Allows a validator to switch his status from locked to ative.

Restake

Allows a validator to stake more BONE, by default this feature is disabled.

Update Signer Public Key

Allows the operator to update the Signer Public key used by the heimdall.

Unstake Claim

Allows the operator owner to claim his staked BONE tokens.

Claim Fee

Allows the operator owner to claim his heimdall fees.

Update Operator Commision Rate

Update the operator's commission rate.

Set Stake Amount And Fees

Set the min and max amount and heimdall fees an operator can use to stake or topup heimdall fees.

Validator Factory

The validator Factory is used to deploy new validatorProxy that is later added to an array of validators.

create

  • permission:

    • OPERATOR

  • description:

    • Creates a new ValidatorProxy and appends it to array of validators

remove

  • permission:

    • OPERATOR

  • description:

    • Removes a ValidatorProxy determined by its address from the array of validators

Last updated