Collection of the docs for Centaurify's Protocol and related products.
This project is maintained by CentaurifyOrg
VikingVault.sol is a smart contract written in Solidity language.
Context:
We wanted to develop and deploy a smart contract that would allow us to incentivize and reward our community, for being long-term token HODLERS, contributing to our community, and supporting our project.
We decided that Staking would be the safest and best solution to reach our goal, to distribute rewards among those who wants to stake their tokens with us long-term.
TicketVault is a custom developed smart-contract for single ERC20 staking and rewards distribution.
With this documentation, we will give you an in-depth description of the features in this smart contract.
To be able to follow this step-by-step tutorial, please be sure to follow the installation guide, and that you run the unit tests and they passed without errors before continuing with the following steps.
VikingVault
staking contract.Before we can deploy the VikingVault contract, there are a couple of variables that are optional to change inside the contract constructor. These variables are located at line 110
, 112
, and 113
.
stakingPeriod
is the total number of weeks for this staking vault.
stakingPeriod
value is set to 13 weeks (~3 months).withdrawPenaltyPeriod
is the number of weeks where rewards are being accumulated.
WithdrawPenaltyPeriod
, if a stakeholder wants to withdraw their position and exit the staking pool, they will not get their accumulated rewards.WithdrawPenaltyPeriod
value is set to 2 weeks (~1/2 month).withdrawFee
is the percentage value of the withdrawal fee.
Example fee values:
0.1% fee, use value 10
.
5% fee, use value 500
.
10% fee, use value 1000
.
Default withdrawFee
value is set to 700
(7%).
With these variables set in the contract code, we can now deploy the TicketVault to the network of your choice.
Open 1_deploy_contracts.js, at line 8
, change CONTRACT_ADDRESS
with the ERC20 contract address you want to use.
In your terminal, go to folder ../smart_contracts
, and enter the code below to deploy the TicketVault smart-contract.
npx hardhat run scripts/1_deploy_contracts.js --network NETWORKNAME
```text Deploying contracts with the account: 0x2fa005F3e5a5d35D431b7B8A1655d2CAc77f22AB
| Deployment Status :
| Contract owner : 0x2fa005F3e5a5d35D431b7B8A1655d2CAc77f22AB
| Fee address : 0x2fa005F3e5a5d35D431b7B8A1655d2CAc77f22AB
|
| ——————————————————————————
| Contract deployed :
| TokenAddress : 0x938f689d828D6d105BAc52F9DE605d6C6CCa1CD1
| TicketVault : 0x6Fa408C20cEC935e4e0F3227Fbb4B12499Cb99F3
| StakePeriod : 7862400 Sec.
———————————————————————————-
```
*
Description of the code in VikingVault.sol.
Parameter.
address TokenAddress
.
Status
descriptionCollecting
.
0
.Collecting
, only the public methods below is allowed to be called:
deposit()
exitWhileCollecting()
Staking
.
1
.Staking
, only the public methods below is allowed to be called:
exitWhileStaking()
.Completed
.
2
.Completed
, only the public methods below is allowed to be called:
withdraw()
.status
stakingPeriod
startTimestamp
stopTimestamp
totalVaultShares
totalVaultRewards
RewardInfo
lastRewardUpdateTimeStamp
pendingVaultRewards
is calulated.rewardRate
rewardRate = totalVaultRewards / stakingPeriod
pendingVaultRewards
claimedVaultRewards
remainingVaultRewards
Custom errors are thrown if a function call has failed and is reverted.
NotAuthorized()
.
isStakeholder
.NoZeroValues()
.
noZeroValues
.MaxStaked()
.
limiter
.NotCollecting()
.
isCollecting
.NotStaking()
.
isStaking
.NotCompleted()
.
isCompleted
.AddRewardsFailed()
.
addRewards(uint256 amount)
.DepositFailed()
.
deposit(uint256 amount)
.RewardFailed()
.
withdraw()
.WithdrawFailed()
.
withdraw()
.Public state variables, and other non-state changing methods, consumes no gas when they are executed and run.
Public state variables.
token()
.
owner()
.
feeAddress()
.
vault()
.
VaultInfo
struct.withdrawFee()
.
100
= 1%
.View methods.
getAccountErc20Balance(address account)
Returns the total user amount of the preset ERC20 token, available in the user account.
The parameter account
is the address to query.
getAccountVaultBalance(address account)
.
Returns the staked balance of the account
.
Parameter account
is the address to query.
getRewardInfo()
.
Returns values from RewardInfo
.
lastRewardUpdateTimeStamp
.
rewardRate
.pendingVaultRewards
.claimedVaultRewards
.remainingVaultRewards
.State changing methods/ transactions.
deposit(uint256 amount)
.
Requires status Collecting
.
amount
is in Wei (1 eth/erc20 = 1000000000000000000 Wei).Requires the user to have approved
TicketVault to spend the erc20 to deposit.
depositFailed()
event if the transaction fails.exitWhileCollecting()
.
Requires status Collecting
.
Allows a stakeholder to withdraw their staked amount.
A withdrawFee
is calculated from withdrawAmount
, then paid to the fee address.
Remaining withdrawAmount
is transferred to the stakeholders account.
exitWhileStaking()
.
Requires status Staking
.
Allows a stakeholder to exit their staked position.
If during withdrawPenaltyPeriod
, rewards are locked in vault.
A withdrawFee
is calculated from withdrawAmount
, then paid to the fee address.
Remaining withdrawAmount
is sent to stakeholders account.
withdraw()
.
Requires status Completed
.
Allows a stakeholder to withdraw their stake, and accumulated rewards, without any withdraw fee.
Emits the event Withdraw(address indexed User, uint256 amount, uint256 rewards)
to the network.
onlyOwner restricted (only the owner address can call these methods).
setFeeAddress(address newFeeAddress)
.
Assigns a new account to receive the withdrawal fees.
newFeeAddress
is the address to receive the withdrawal fees.addRewards(uint256 amount)
.
Deposits the amount of ERC20 tokens to be distributed among the stakeholders as a reward for staking.
Parameter amount
is in Wei (1 eth/erc20 = 1000000000000000000 Wei).
The amount
is added to the existing totalVaultRewards
variable in the VaultInfo
struct.
Throws a custom error AddRewardsFailed()
if the transaction is reverted.
startStaking()
.
Initiates the staking for the pre-set staking period.
The Vault Status is changed from Collecting
to Staking
.
Sets the vault startTimestamp
to current block.timestamp
.
Sets the vault stopTimestamp
by adding the vault stakingPeriod
value to the startTimestamp
value.
Emits the event StakingStarted
.
stopStaking()
.
Completes the staking period of this vault.
Vault Status is changed from Staking
to Completed
.
remainingVaultRewards
is added to pendingVaultRewards
, then reset to 0
.
Emits the event StakingCompleted()
.
Private methods are only visible internal and can only be called by this contract.
_deposit()
.
Deposit funds to TicketVault.
Is used by addRewards()
and deposit()
to pull funds from msg.sender, and into TicketVault.
_withdraw()
.
Withdraw funds from the TicketVault.
Is used by
withdraw()
,exitWhileStaking()
,exitWhileCollecting()
to withdraw the users stake from TicketVault.
_calculateUserReward(_totalUserShares)
.
Calculates the pending user reward.
Called by exitWhileStaking()
, and withdraw()
to calculate the user reward.
Calculation:
pendingUserReward = (pendingVaultRewards * ((_totalUserShares * 10000) / totalVaultShares)) / 10000;
_calculatefee(_amount)
.
Calculates the fee amount to pay to fee address.
Called by exitWhileStaking()
, and exitWhileCollecting()
to calculate the fee amount.
Calculation:
feeAmount = _amount * withdrawFee / 10000;
withdrawAmount = _amount - feeAmount;