knBONE

Link to knBONE source code on Ethereum

Link to knBONE source code on Shibarium

knBONE is the core contract which acts as a liquid staking pool. The contract is responsible for deposits, withdrawals, minting and burning liquid tokens, delegating funds to node operators, applying fees and distributing rewards.

knBONE contract also defines knBONE, an ERC20 token that represents the account's share of the BONE tokens inside K9 Finance DAO protocol. It is a non-rebasable token, which means that the amount of tokens in the user's wallet is not going to change by itself, only by user actions. During time, the value of this token is changing, since the amount of BONE tokens inside the protocol is not constant. knBONE will be integrated in variety of DeFi applications across Ethereum and Shibarium.

knBONE is inherited from IKnBONE, ERC20Upgradeable, AccessControlUpgradeable, PausableUpgradeable

Variables

IERC20Upgradeable public token; - BONE token address INodeOperatorRegistry public nodeOperatorRegistry; - NodeOpeartorRegistry contract address IStakeManager public stakeManager; - Shibarium StakeManager contract address IUnstBONE public unstBONE; - UnstBONE contract address IInstantPool public instantPool; - InstantPool contract address IDepositManager public depositManager; - DepositManager address of the bridge in Shibarium (this bridge is owned by K9 Finance DAO) IBridge public bridge; - Bridge contract address in Ethereum address public l2Staking; - Real Yield Staking contract address that will receive a share of rewards from Liquid Staking address public dao; - DAO Treasury reward address (this address does not necessarily have a DAO role) that will receive a share of rewards from Liquid Staking FeeDistribution public entityFees; - Protocol fee distribution structure uint256 public instantPoolUsageFee; - Fee percentage that user pays when withdrawing instant reward uint256 public totalBuffered; - amount of BONE that is buffered but not delegated, includes reservedFunds uint256 public delegationLowerBound; - the minimum required for successful delegate() on this contract uint256 public rewardDistributionLowerBound; - the minimum reward amount that is required for successful distributeRewards() on this contract uint256 public reservedFunds; - replenished if, when creating a request from a user, some amount did not fit into our requests to validators (included in totalBuffered) bytes32 public constant DAO_ROLE = keccak256("DAO_ROLE"); - dao role identifier bytes32 public constant PAUSE_ROLE = keccak256("PAUSE_ROLE"); - pauser role identifier bytes32 public constant UNPAUSE_ROLE = keccak256("UNPAUSE_ROLE"); - unpauser role identifier bytes32 public constant BRIDGE_ROLE = keccak256("BRIDGE_ROLE"); - bridge executor role identifier (should be granted to bridge) RequestWithdraw[] public knBONEWithdrawRequest; - an array of withdrawal request structures specifically for withdrawal to this contract (will be filled in only when creating a withdrawal request from the validator to KnBONE for reasons other than the user’s withdrawal, filled in when rebalanceDelegatedTokens() and withdrawTotalDelegated()) mapping(uint256 => RequestWithdraw[]) public token2WithdrawRequests; - for each unstBONE tokenID returns an array of withdrawal request structures uint8 public protocolFee; - Protocol fee total percentage which will then be distributed in accordance with entityFees

Structures

RequestWithdraw

Withdrawal requests structure

Name
Description

uint256 amount2WithdrawFromKnBONE

BONE amount to withdraw

uint256 validatorNonce

filled in as ValidatorShare.unboundNonces(address(this)) or 0 if the sub-application amount did not fit into our requests to validators

uint256 requestEpoch

when withdrawal is available, filled in as StakeManager.epoch() + StakeManager.withdrawalDelay()

address validatorAddress

ValidatorShare address or zero address in case if the sub-request amount does not fit into our requests to validators

struct RequestWithdraw {
uint256 amount2WithdrawFromKnBONE;
uint256 validatorNonce;
uint256 requestEpoch;
address validatorAddress;
}

FeeDistribution

Protocol fee distribution structure

Name
Description

dao

DAO Treasury protocol fee share

operators

Node operators protocol fee share

instantPool

Instant reward pool protocol fee share

staking

Real Yield Staking rewards protocol fee share

Events

event SubmitEvent(address indexed _from, uint256 _amount, address indexed _receiver, bool _transferToL2); - upon submit() call

event InstantPoolWithdraw(address indexed _from, uint256 _amountWithFeeInBONE, uint256 _feeAmountInBONE); - when withdrawing using only instant pool, BONE amounts are provided

event RequestWithdrawEvent(address indexed _from, uint256 _amountInBONE); - when withdrawing using only withdrawal request, BONE amount is provided

event RequestWithdrawSplit(address indexed _from, uint256 _totalAmountInKnBONE); - upon completion of the transaction requestWithdrawSplit(), amount knBONE amount is provided

event DistributeRewardsEvent(uint256 indexed _amount, uint256 indexed totalPooledBefore, uint256 indexed totalPooledAfter); - upon distribureRewards() call

event WithdrawTotalDelegatedEvent( address indexed _from, uint256 indexed _amount ); - upon withdrawTotalDelegated() call

event DelegateEvent(uint256 indexed _amountDelegated, uint256 indexed _remainder ); - upon delegate() call

eventClaimTokensEvent(address indexed _from, uint256 indexed _id, uint256 indexed _amountClaimed); - upon claimTokens() call

event SetNodeOperatorRegistryAddress(address indexed _newNodeOperatorRegistryAddress ); - upon setNodeOperatorRegistryAddress() call

event SetDelegationLowerBound(uint256 indexed _delegationLowerBound); - upon setDelegationLowerBound() call

event SetRewardDistributionLowerBound(uint256 oldRewardDistributionLowerBound, uint256 newRewardDistributionLowerBound ); - upon setRewardDistributionLowerBound() call

event SetUnstBONE(address oldUnstBONE, address newUnstBONE); - upon setUnstBONE() call

event SetDaoAddress(address oldDaoAddress, address newDaoAddress); - upon setDaoAddress() call

event SetFees(uint256 daoFee, uint256 operatorsFee, uint256 instantPoolFee, uint256 stakingFee); - upon setFees() call

event SetProtocolFee(uint8 oldProtocolFee, uint8 newProtocolFee); - upon setProtocolFee() call

event SetInstantPoolUsageFee(uint256 oldInstantPoolUsageFee, uint256 newInstantPoolUsageFee); - upon setInstantPoolUsageFee() call

event SetInstantPool(address instantPool); - upon setInstantPool() call

event SetDepositManager(address depositManager);- upon setDepositManager() call

event SetBridge(address bridge); - upon setBridge() call

event SetL2Staking(address l2Staking); - upon setL2Staking() call

event ClaimTotalDelegatedEvent(address indexed validatorShare, uint256 indexed amountClaimed ); - upon claimTokensFromValidatorToContract() call

View functions

name()

Returns the name of the token

symbol()

Returns the symbol of the token, usually a shorter version of the name

decimals()

Returns the number of decimals for getting user representation of a token amount.

totalSupply()

Returns the amount of tokens in existence.

balanceOf()

Returns the amount of tokens owned by the _account

getTotalWithdrawRequest

Returns the entire knBONEWithdrawRequest array.

getTotalStake

The same as ValidatorShare.getTotalStake(address(this)). API for getting total stake of this contract from validatorShare.

getLiquidRewards

The same as ValidatorShare.getLiquidRewards(address(this)). API for liquid rewards of this contract from validatorShare.

getTotalStakeAcrossAllValidators

Returns the BONE amount staked in all validators.

getTotalPooledBONE

Returns total pooled BONE as getTotalStakeAcrossAllValidators() + totalBuffered + calculatePendingBufferedTokens() - reservedFunds

getToken2WithdrawRequests

Returns the withdrawal request structure for tokenID.

getBONEFromTokenId

Retrieves the amount of BONE that will be claimed from the unstBONE NFT request.

convertKnBONEToBONE

Calculates BONE amount from the provided knBONE amount.

convertBONEToKnBONE

Calculates knBONE amount from the provided BONE amount.

Methods

initialize

Initializer function, not called after initialization.

submit

Send funds to knBONE contract and mint knBONE to receiver. Requires that msg.sender has approved _amount of BONE to this contract.

  • _amount - Amount of BONE sent from msg.sender to this contract

  • _receiver - receiver address

  • _transferToL2 - whether or not transfer knBONE to Shibarium

requestWithdrawSplit

Request withdrawal function, allows using the instant pool and/or creating requests. _user must be the sender or any address if the function is called from BRIDGE_EXECUTOR_ROLE. When executed:

  • knBONE amount of the withdrawal request is burned

  • knBONE amount that is withdrawn through the Instant pool is sent to the DAO Treasury address.

Returns tokenID if there was a request or 0 if there was no request.

  • _instantPoolAmount - Amount of knBONE that is requested to withdraw using instant reward pool

  • _requestWithdrawAmount - Amount of knBONE that is requested to withdraw using withdrawal request

  • _user - user to withdraw from

delegate

Delegates the amount of BONE (totalBuffered - reservedFunds) to validator.

claimTokens

Claims tokens from validator share and sends them to the user. Requires the processed withdrawal request associated with unstBONE NFT.

distributeRewards

Distributes the protocol rewards received from validator.

  • Creates a variable totalRewards equal to (contract balance - totalBuffered).

  • Calculates the protocol fee amount based on protocolFee%.

  • Then distributes the protocol fee amount according to the entity fees, the rest is added to totalBuffered for re-delegation.

withdrawTotalDelegated

Called only by NodeOperatorRegistry contract. Creates a withdrawal request of the total delegated amount from the specified ValidatorShare. Withdraws funds from stopped validator.

rebalanceDelegatedTokens

Rebalane the system by request withdraw from the validators that contains more token delegated to them.

  • Calculates amountToReDelegate as (totalBuffered - reservedFunds + calculatePendingBufferedTokens()).

  • Sends it intoNodeOperatorRegistry.getValidatorsRebalanceAmount() and gets a response.

  • Based on the response, creates a withdrawal request for each ValidatorShare.

calculatePendingBufferedTokens

Calculate the total amount of BONE stored in knBONEWithdrawRequest array that can not be delegated.

claimTokensFromValidatorToContract

Processes the specified request in knBONEWithdrawRequest. Claims tokens from validator share and sends them to the knBONE contract.

Admin Methods

This method can be called by ADMIN-only roles

pause

Pause knBONE contract

unpause

Unpause knBONE contract

DAO Methods - setters

These methods can be called by DAO-only roles

setProtocolFee

Sets protocolFee value that will be distributed between receivers.

setInstantPoolUsageFee

Sets fee percentage that user pays when withdrawing instant reward

setDaoAddress

Sets the DAO Treasury reward address

setNodeOperatorRegistryAddress

Sets nodeOperatorRegistry address

setInstantPool

Sets InstantPool address

setDepositManager

Sets depositManager address

setBridge

Sets K9 bridge address

setL2Staking

Sets Real Yield Staking address

setDelegationLowerBound

Function that sets new lower bound for delegation

setRewardDistributionLowerBound

Function that sets new lower bound for rewards distribution

Last updated