Skip to main content

Staking

Arthera has a number of system contracts that perform various protocol-level tasks. The choice to decouple some functionality form the main blockchain node to system contract is related to upgradeability. All System Contracts are upgradeble through a governance process, so if a vote is cast through governance to change the price of subscription plans or staking rewards, a new version of the respective contracts will be deployed without having validators upgrade their software or restart their node.


This contract is responsible for:

  • registering new validators and delegators
  • withdrawal of validators and delegators
  • distribution of epoch rewards

currentEpoch()

Returns uint256 - the current epoch

epochEndTime()

Returns uint256 - the end time epoch in epoch seconds

minSelfStake()

Returns uint256 - the minimum amount of stake for a validator

maxDelegatedRatio()

Returns uint256 - maximum ratio of delegations a validator can have

validatorCommission()

Returns uint256 - the commission fee in percentage a validator will get from a delegation

burntFeeShare()

Returns uint256 - the percentage of transaction fees to burn

treasuryFeeShare()

Returns uint256 - the percentage of fees to transfer to Arthera's treasury address

unlockedRewardRatio()

Returns uint256 - the ratio of the reward rate at base rate (no locking)

minLockupDuration()

Returns uint256 - the minimum duration of a stake/delegation lockup

maxLockupDuration()

Returns uint256 - the maximum duration of a stake/delegation lockup

withdrawalPeriodEpochs()

Returns uint256 - the number of epochs for stake to be available for withdrawal after an undelegation request

withdrawalPeriodTime()

Returns uint256 - the time it takes for stake to be available for withdrawal after an undelegation request

getEpochValidatorIDs()

Returns uint256[] - the list of validator id's that were active in the provided epoch.

Method parameters:

  • uint256 epoch the epoch

isSlashed()

Returns bool - if the validator is currently slashed

Method parameters:

  • uint256 validatorID the id of the validator

getEpochReceivedStake()

Returns uint256 the stake owned by a validator in an epoch

Method parameters:

  • uint256 epoch the epoch
  • uint256 validatorID the id of the validator

getEpochAccumulatedRewardPerToken()

Returns uint256 the reward generated by a validator for one staked token in an epoch

Method parameters:

  • uint256 epoch the epoch
  • uint256 validatorID the id of the validator

getEpochAccumulatedUptime()

Returns uint256 the total uptime for a validator in an epoch

Method parameters:

  • uint256 epoch the epoch
  • uint256 validatorID the id of the validator

getEpochOfflineTime()

Returns uint256 the total downtime for a validator in an epoch

Method parameters:

  • uint256 epoch the epoch
  • uint256 validatorID the id of the validator

getEpochOfflineBlocks()

Returns uint256 the total blocks missed by a downtime validator in an epoch

Method parameters:

  • uint256 epoch the epoch
  • uint256 validatorID the id of the validator

getEpochAccumulatedOriginatedTxsFee()

Returns uint256 total transaction fees collected by a validator in an epoch

Method parameters:

  • uint256 epoch the epoch
  • uint256 validatorID the id of the validator

getSelfStake()

Returns uint256 the validator's own stake, not including delegators

Method parameters:

  • uint256 validatorID the id of the validator

getLockedStake()

Returns uint256 the amount of locked stake for a delegator in the provided validator

Method parameters:

  • address delegator delegator
  • uint256 toValidatorID the id of the validator

createValidator() payable

Create a new validator with a minimum stake given by minSelfStake(). This method is payable, so an AA value greater than Staking.minSelfStake() needs to be sent along with the transaction. The call creates a self-delegation with the specified amount. The sender's address will be the validator's registered address in the Staking contract.

Method parameters:

  • msg.sender - the validator address
  • bytes pubkey is the validator's public key used to sign messages and cannot be changed after the validator is created.

Emits

  • event CreatedValidator(uint256 indexed validatorID, address indexed auth, uint256 createdEpoch, uint256 createdTime)

delegate() payable

Delegates an amount of AA to a validator. This method can be used to create a new delegation or increase an existing delegation. The delegated stake is always unlocked unless locked explicitly with lockStake. This method is payable, so an AA value needs to be sent with the transaction.

The maximum delegated value a validator can have is 16 * getSelfStake(validatorId). If your delegation will go over this value, the transaction will be reverted with an error.

Method parameters:

  • msg.sender- delegator
  • uint256 toValidatorId is the validator's public key used to sign messages and cannot be changed after the validator is created.

Emits

  • event Delegated(address indexed delegator, uint256 indexed toValidatorID, uint256 amount)

undelegate()

Make a request to release an amount of delegated stake from a validator for withdrawal. The delegated stake will be released after the following both conditions are met:

  • block.timestamp >= undelegateRequestTime + Staking.withdrawalPeriodTime()
  • Staking.currentEpoch() >= undelegateRequestEpoch + Staking.withdrawalPeriodEpochs().

Once the delegated stake is release, withdraw() can be called to retrieve the funds.

Method parameters:

  • msg.sender- delegator
  • uint256 fromValidatorID the ID of the validator.
  • uint256 withdrawalRequestID a number that uniquely identifies your request for internal reference. Note that you cannot make two undelegate requests with the same withdrawalRequestID. It can be any uint256 number you want.
  • uint256 amount the amount in wei you want to undelegate.

Emits

  • event Undelegated(address indexed delegator, uint256 indexed fromValidatorID, uint256 indexed withdrawalRequestID, uint256 amount)

withdraw()

Finalizes a withdrawal request. It clears the request object and transfers the requested amount to caller's address. If validator was dishonest, the delegator's requested amount may be fully or partially slashed according to the validator's slashingRefundRatio available at Staking.slashingRefundRatio

Method parameters:

  • msg.sender- delegator where the requested amount will be sent
  • uint256 fromValidatorID the ID of the validator.
  • uint256 withdrawalRequestID a number that uniquely identifies the undelegate request, provided initially in the undelegate method.

Emits

  • Withdrawn(address indexed delegator, uint256 indexed fromValidatorID, uint256 indexed withdrawalRequestID, uint256 amount)

lockStake()

Rewards for a locked stake are higher than rewards for non-locked stake. See Locking stake for more details. A validator's stake must be locked up before the validator's delegations can lock their sake and the specified lockup period of a delegation must not exceed the validator's current lockup period. Delegations can lock only a part of their stake.

A validator can lock his stake by sending the call from the validator's registered address in createValidator().

Method parameters:

  • msg.sender - delegator
  • uint256 toValidatorID - the validator where your delegation is
  • uint256 lockupDuration - the lockup duration in seconds ( >= 14 days and <= 365 days )
  • uint256 amount - an amount in wei <= the delegator's stake

Emits

  • event LockedUpStake(address indexed delegator, uint256 indexed validatorID, uint256 duration, uint256 amount)

relockStake()

Extend the lockup period or increase the lock-up amount. The new lockup duration will not be extending the old duration, but set a new duration starting now and cannot be lower than the previous lockup duration.

Method parameters:

  • msg.sender - delegator
  • uint256 toValidatorID - the validator where your delegation is
  • uint256 lockupDuration - the now lockup duration in seconds ( >= 14 days and <= 365 days ), starting now. Cannot be lower than the previous lockup duration.
  • uint256 amount - an amount in wei <= the delegator's stake that will be added to the existing locked amount

Emits

  • event LockedUpStake(address indexed delegator, uint256 indexed validatorID, uint256 duration, uint256 amount)

unlockStake()

Unlock the stake before the lockup duration is elapsed. Please note that a penalty will be applied to the unlocked amount. See Locking stake for more details.

Method parameters:

  • msg.sender - delegator
  • uint256 toValidatorID - the validator where your locked delegation is
  • uint256 amount - an amount in wei to unlock

Emits

  • event UnlockedStake(address indexed delegator, uint256 indexed validatorID, uint256 amount, uint256 penalty)

pendingRewards()

Checks to see if there are any pending rewards to be claimed for a delegator.

Method parameters:

  • address delegator - delegator
  • uint256 toValidatorID - the validator where your delegation is

Returns uint256 the amount of pending rewards that can be claimed

claimRewards()

Claim pending rewards for a delegator.

Method parameters:

  • msg.sender - delegator where the rewards in AA will be sent
  • uint256 toValidatorID - the validator where your delegation is

Emits

  • event ClaimedRewards(address indexed delegator, uint256 indexed toValidatorID, uint256 lockupExtraReward, uint256 lockupBaseReward, uint256 unlockedReward)

restakeRewards()

Re-stakes any pending rewards. The pending rewards will be added to the staked amount. If any part of pending rewards come from locked-up stake, the entire pending amount will be added to the locked stake.

Method parameters:

  • msg.sender - delegator
  • uint256 toValidatorID - the validator where your delegation is

Emits

  • event RestakedRewards(address indexed delegator, uint256 indexed toValidatorID, uint256 lockupExtraReward, uint256 lockupBaseReward, uint256 unlockedReward)