Skip to content

Commit

Permalink
Merge branch 'update_vesting_docs_main' of https://github.com/LiskHQ/…
Browse files Browse the repository at this point in the history
…lisk-contracts into update_vesting_docs_main
  • Loading branch information
sergeyshemyakov committed Jun 28, 2024
2 parents 428e506 + 84ef375 commit 2bd1ec7
Show file tree
Hide file tree
Showing 59 changed files with 337 additions and 67 deletions.
2 changes: 1 addition & 1 deletion .env.mainnet
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ L2_VESTING_WALLET_OWNER_ADDRESS=0x394Ae9d48eeca1C69a989B5A8C787081595c55A7
L2_AIRDROP_OWNER_ADDRESS=0x394Ae9d48eeca1C69a989B5A8C787081595c55A7

# Airdrop wallet address where LSK tokens are transferred to after airdrop period ends
L2_AIRDROP_WALLET_ADDRESS=0x38eA61E8084E27a087cF5CdBC3f22584f18773e6
L2_AIRDROP_WALLET_ADDRESS=0x0c92121A7C15cF01041e1122483Bc173Baccd877

# Salt for deterministic smart contract address generation
DETERMINISTIC_ADDRESS_SALT="lisk_l2_token_deterministic_salt"
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ broadcast/
slither-results.json

# Devnet deployment files
deployment/devnet/
deployment/artifacts/contracts/devnet/
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ You may find the addresses of the deployed smart contracts (including vesting wa

| Name | Proxy | Implementation |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| [`L2Airdrop`](src/L2/L2Airdrop.sol) | - | [0xC7315f4FaaB2F700fc6b4704BB801c46ff6327AC](https://blockscout.lisk.com/address/0xC7315f4FaaB2F700fc6b4704BB801c46ff6327AC) |
| [`L2Claim`](src/L2/L2Claim.sol) | [0xD7BE2Fd98BfD64c1dfCf6c013fC593eF09219994](https://blockscout.lisk.com/address/0xD7BE2Fd98BfD64c1dfCf6c013fC593eF09219994) | [0x60790Dc2d45BaA8B36282889569BbB301F4D0c41](https://blockscout.lisk.com/address/0x60790Dc2d45BaA8B36282889569BbB301F4D0c41) |
| [`L2Governor`](src/L2/L2Governor.sol) | [0x58a61b1807a7bDA541855DaAEAEe89b1DDA48568](https://blockscout.lisk.com/address/0x58a61b1807a7bDA541855DaAEAEe89b1DDA48568) | [0x18a0b8c653c291D69F21A6Ef9a1000335F71618e](https://blockscout.lisk.com/address/0x18a0b8c653c291D69F21A6Ef9a1000335F71618e) |
| [`L2LiskToken`](src/L2/L2LiskToken.sol) | - | [0xac485391EB2d7D88253a7F1eF18C37f4242D1A24](https://blockscout.lisk.com/address/0xac485391EB2d7D88253a7F1eF18C37f4242D1A24) |
Expand Down
1 change: 1 addition & 0 deletions deployment/addresses/mainnet/addresses.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Below are the addresses of the deployed smart contracts on the Ethereum and Lisk

| Name | Address |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| [`L2Airdrop`](../../../src/L2/L2Airdrop.sol) | [0xC7315f4FaaB2F700fc6b4704BB801c46ff6327AC](https://blockscout.lisk.com/address/0xC7315f4FaaB2F700fc6b4704BB801c46ff6327AC) |
| [`L2Claim`](../../../src/L2/L2Claim.sol) | [0xD7BE2Fd98BfD64c1dfCf6c013fC593eF09219994](https://blockscout.lisk.com/address/0xD7BE2Fd98BfD64c1dfCf6c013fC593eF09219994) |
| [`L2ClaimImplementation`](../../../src/L2/L2Claim.sol) | [0x60790Dc2d45BaA8B36282889569BbB301F4D0c41](https://blockscout.lisk.com/address/0x60790Dc2d45BaA8B36282889569BbB301F4D0c41) |
| [`L2Governor`](../../../src/L2/L2Governor.sol) | [0x58a61b1807a7bDA541855DaAEAEe89b1DDA48568](https://blockscout.lisk.com/address/0x58a61b1807a7bDA541855DaAEAEe89b1DDA48568) |
Expand Down
1 change: 1 addition & 0 deletions deployment/addresses/sepolia/addresses.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Below are the addresses of the deployed smart contracts on the Ethereum and Lisk

| Name | Address |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| [`L2Airdrop`](../../../src/L2/L2Airdrop.sol) | [0xDdE1998B8842b1C925Eef7eDFDAA2Df24A75048a](https://sepolia-blockscout.lisk.com/address/0xDdE1998B8842b1C925Eef7eDFDAA2Df24A75048a) |
| [`L2ClaimContract`](../../../src/L2/L2Claim.sol) | [0x3D4190b08E3E30183f5AdE3A116f2534Ee3a4f94](https://sepolia-blockscout.lisk.com/address/0x3D4190b08E3E30183f5AdE3A116f2534Ee3a4f94) |
| [`L2ClaimImplementation`](../../../src/L2/L2Claim.sol) | [0xAE4A95E412d7d669AbE6bB23031Ae0250B832710](https://sepolia-blockscout.lisk.com/address/0xAE4A95E412d7d669AbE6bB23031Ae0250B832710) |
| [`L2Governor`](../../../src/L2/L2Governor.sol) | [0xf9181aaD773d423A2cc0155Cb4263E563D51B467](https://sepolia-blockscout.lisk.com/address/0xf9181aaD773d423A2cc0155Cb4263E563D51B467) |
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"L2Airdrop": "0xC7315f4FaaB2F700fc6b4704BB801c46ff6327AC",
"L2ClaimContract": "0xD7BE2Fd98BfD64c1dfCf6c013fC593eF09219994",
"L2ClaimImplementation": "0x60790Dc2d45BaA8B36282889569BbB301F4D0c41",
"L2Governor": "0x58a61b1807a7bDA541855DaAEAEe89b1DDA48568",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"L2Airdrop": "0xDdE1998B8842b1C925Eef7eDFDAA2Df24A75048a",
"L2ClaimContract": "0x3D4190b08E3E30183f5AdE3A116f2534Ee3a4f94",
"L2ClaimImplementation": "0xAE4A95E412d7d669AbE6bB23031Ae0250B832710",
"L2Governor": "0xf9181aaD773d423A2cc0155Cb4263E563D51B467",
Expand Down
File renamed without changes.
File renamed without changes.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions documentation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ This folder contains the following documents essential for understanding the dep
4. [Vesting Documentation](./vesting.md): This page explains the technical details concerning implementation, deployment and maintenance of vesting smart contracts that hold LSK tokens and release them according to predefined schedules.

5. [Migration Airdrop Documentation](./airdrop.md): This page explains the technical details concerning design and lifecycle of the migration airdrop smart contract that distributes LSK tokens as a reward to the users that migrated from the Lisk L1 network.

6. [Staking and Lisk DAO Documentation](./staking-governance.md): This page explains the technical details concerning Staking and Lisk DAO. The two topics are combined in one document as they are strongly linked to each other.
Binary file modified documentation/diagrams/delegating.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 37 additions & 20 deletions documentation/staking-governance.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,53 @@ This design with selectable locking duration helps to align token holders with t

The mechanism for locking tokens works as follows:

- Users can lock tokens for a specific locking duration (between 2 weeks and 2 years). After the locking duration ends, the users can redeem their tokens.
- Users can modify their locking positions (increase amount, extend locking duration) at any time.
- Users have the option to pause their locking period countdown. That means, the remaining locking duration remains fixed until the user decides to resume it. Note that this results in higher voting power and staking rewards as described below.
- Users can **lock** tokens for a specific locking duration (between 2 weeks and 2 years). After the locking duration ends, the users can unlock their tokens.
- Users can **modify** their locking positions (increase amount, extend locking duration) at any time.
- Users have the option to **pause** their locking period countdown. That means, the remaining locking duration remains fixed until the user decides to resume it. Note that this results in higher voting power and staking rewards as [described below](#pausing-a-locking-position).
- Each user may have multiple locking positions.
- Locking positions are represented using NFTs for composability into DeFi and potential future uses.
- In case a user wants to unlock earlier than the end of the locking duration, there is a fast unlock option. The fast unlock implies a penalty, i.e., an amount that is deducted from the locked LSK tokens. The penalty is set to `0.5 * lockedAmount * (remainingLockingDurationInDays / maximumLockingDuration)`, where `maximumLockingDuration` is set to 2 years. Users can then redeem their tokens after a 3-day emergency locking period.
- Locking positions are represented using **NFTs** for composability into DeFi and potential future uses.
- In case a user wants to unlock earlier than the end of the locking duration, there is a **fast unlock** option. The fast unlock implies a penalty, i.e., an amount that is deducted from the locked LSK tokens. The penalty is set to `0.5 * lockedAmount * (remainingLockingDurationInDays / maximumLockingDuration)`, where `maximumLockingDuration` is set to 2 years. Users can then unlock their tokens after a 3-day emergency locking period.
- Confiscated tokens are immediately redirected to the staking rewards pool to be distributed over the next 14 days period on top of the guaranteed rewards.
- Users do not have the option to cancel the fast un-stake during this 3 day window.
- Users do not have the option to cancel the fast unlock during this 3 day window.

## Voting Power

The voting power for a locked amount of tokens is computed as follows:
The voting power of an account is expressed by the account's balance of another ERC20 contract, the *Voting Power* contract. The token symbol of this contract `vpLSK`. The voting power for a locked amount of tokens is computed as follows:

- Generally, locked tokens provide a voting power proportional to the amount of locked tokens. Concretely, 1 locked LSK provides one unit of voting power.
- In case a user pauses their locking period countdown, they receives a boost of the voting power meaning the voting power is set to `lockedAmount * (1 + remainingLockingDurationInDays/365)`. Hence, the voting power can be increased by up to 200%.
- Generally, locked tokens provide a voting power proportional to the amount of locked tokens. Concretely, 1 locked LSK provides 1 vpLSK.
- In case a user pauses their locking period countdown, they receive a boost of the voting power meaning the voting power is set to `lockedAmount * (1 + remainingLockingDurationInDays/365)`. Hence, the voting power can be increased by up to 200% by pausing a locking position with the maximum locking period of 2 years.

### Voting Power for a Concrete Proposal

At the time a proposal is created, a snapshot of the delegated voting power is taken and the voting result is based on this snapshot. Consequently, neither any changes in the voting power nor any delegations made after the proposal creation have any influence on the voting result.

## Staking Rewards

Users receive rewards for their locking tokens as follows:
Users receive rewards for locking their tokens as follows:

- Rewards are calculated on a daily basis, based on the amount locked and the remaining locking duration. Concretely, the weight for a locked amount is given by `lockedAmount * (remainingLockingDurationInDays + 150)`. The total daily amount of staking rewards is then shared by all users proportional to their weight. That means, a position with weight `w` receives `totalDailyRewards * w / totalWeight`.
- Users can claim their rewards (and restake them immediately if they want) at any time.

## Pausing a Locking Position

- Rewards are calculated on a daily basis, based on the amount locked and the remaining locking duration. Concretely, the weight for a locked amount is given by `lockedAmount * (remainingLockingDurationInDays + 150)`. The total daily amount of staking rewards is then shared by all users proportional to their weight.
- Users can claim their rewards (and restake them immediately if they want) at any time.
As mentioned in several places above, it is possible *to pause* the countdown of a locking position. This can be done at any time. Once paused, the remaining locking duration does not decrease anymore. The owner of the locking position can *resume* the countdown of the locking period an any point in time. Once resumed, the remaining locking duration descreases again daily.

**Example**: A users creates a locking position on day 1 and with a locking duration of 30 days. On day 6, the remaining locking duration is 25 days. On the same day, the user pauses the locking pausition. On day 50, the remaining locking duration is still 25. The users resumes the countdown of the locking position on this day. On day 75, the reamining locking duration is zero and the user can unlock their tokens.

What are the consequences of pausing the countdown:

- The voting power is boosted, i.e. increased from `lockedAmount` to `lockedAmount * (1 + remainingLockingDurationInDays/365)`.
- The weight on the rewards calculation (`lockedAmount * (remainingLockingDurationInDays + 150)`) does not decrease daily (in contrast to unpaused locking positions) but remains fixed for the duration that the position remains paused. This results in higher staking rewards.
- The locking position does not expire.

## Onchain Governance

The main aspects of our onchain governance system are planned as follows:
The main aspects of our onchain governance system are as follows:

- We use OpenZeppelin’s Governor contract framework and also manage the Lisk DAO treasury with it.
- The following parameters are used:
- **Proposal threshold**: For creating a proposal, the voting power of the proposer must be at least 300,000, i.e., the value corresponding to 100,000 LSK locked for 2 years where the countdown is paused.
- **Quorum**: For a proposal to pass, the “yes” and “abstain” votes must sum up at least to 22,500,000, i.e., the value that corresponds to 7,500,000 LSK locked for 2 years where the countdown is paused.
- **Proposal threshold**: For creating a proposal, the voting power of the proposer must be at least 300,000 vpLSK, i.e., the value corresponding to 100,000 LSK locked for 2 years where the countdown is paused.
- **Quorum**: For a proposal to pass, the “yes” and “abstain” votes must sum up at least to 24,000,000 vpLSK, i.e., the value that corresponds to 8,000,000 LSK locked for 2 years where the countdown is paused.
- A proposal is accepted if the quorum, as defined above, is reached, and if there are strictly more “yes” than “no” votes.
- The onchain governance allows the following two proposal types:
- **Funding proposals**: A proposal for receiving a certain amount of funds to an address. If passed, the recipient receives the amount given in the proposal.
Expand All @@ -58,31 +74,32 @@ The graphic above shows all contracts involved in the staking and governance sys

### User Interaction

### Locking/Unlocking
#### Locking/Unlocking

![Locking/Unlocking/Modifying](diagrams/lock_unlock.png)

There are two ways how the user can lock/unlock/modify a staking position. In the first one, the user calls the Staking contract. The Staking contract will create/delete/modify a locking position in the Locking Position Contract which in turn forwards a call to the Voting Power Contract to adjust the voting power of the owner of the locking position. The Voting Power contract will emit events which will be used by Tally for indexing. For locking positions created like this, the user will not receive any rewards.

In the second way, the user calls the Reward contract. The Reward contract will call lock/unlock/modify in the Staking contract, which will trigger the same forwarded calls as in the first way. The difference is that the user will receive rewards for locking positions create this way.

### Delegating
#### Delegating

![Delegating](diagrams/delegating.png)

For delegating, the user is interacting with the Voting Power contract directly. The Voting Power contract will emit events which will be used by Tally for indexing.

### Creating Proposals and Voting
#### Creating Proposals and Voting

![Creating Proposals](diagrams/create_proposal.png)

For creating a proposal or voting on a proposal, the user is interacting with the Governor contract. The Governor contract will request the voting power of the proposer/voter in order to see if the user has enough voting power to create a proposal or for counting the voting results. Moreover, the Governor contract will emit events which will be used by Tally for indexing.

### Queueing and Executing Proposals
#### Queueing and Executing Proposals

![Queueing](diagrams/queue.png)

If a proposal has an attached execution, e.g. a transfer of some treasury funds, and the proposal passed, then the proposal must be queued and then executed. For this, a user (this can be any user) must interact with the Governor contract. This one is forwarding the queue/execute operation to the Timelock Controller contract, and the Governor contract additionally emits events which Tally uses for indexing. The Governor contract is the only account that is allowed to queue proposals at the Timelock Controller. As all executions are eventually executed by the Timelock Controller, contracts owned by the Lisk DAO must be owned by the Timelock Controller, and the DAO treasury must be held by it as well.

### Implementation of Lisk Staking
[See Lisk Staking implementation page](./staking.md)

For details about the implementation of the staking sytem, see the [Lisk Staking implementation page](./staking-implementation.md)
Loading

0 comments on commit 2bd1ec7

Please sign in to comment.