Skip to content

Commit

Permalink
Apply linter changes, rename forge scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
DrZoltanFazekas committed Dec 16, 2024
1 parent d303686 commit 3708ab3
Show file tree
Hide file tree
Showing 29 changed files with 183 additions and 145 deletions.
13 changes: 13 additions & 0 deletions .solhint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "solhint:recommended",
"plugins": [],
"rules": {
"no-inline-assembly": "off",
"avoid-low-level-calls": "off",
"reason-string": ["warn", {"maxLength": 70}],
"func-visibility": ["warn", {"ignoreConstructors": true}],
"gas-custom-errors": "off",
"no-empty-blocks": "off",
"no-complex-fallback": "off"
}
}
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ Before running the deployment script, set the `PRIVATE_KEY` environment variable

To deploy `LiquidDelegation` run
```bash
forge script script/deploy_Delegation.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(string,string,string)" LiquidDelegation Name Symbol
forge script script/Deploy.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(string,string,string)" LiquidDelegation Name Symbol
```
using the `Name` and the `Symbol` of your LST.

To deploy ``NonLiquidDelegation` run
```bash
forge script script/deploy_Delegation.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(string,string,string)" NonLiquidDelegation "" ""
forge script script/Deploy.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(string,string,string)" NonLiquidDelegation "" ""
```

You will see an output like this:
Expand All @@ -77,13 +77,13 @@ You will see an output like this:

You and your delegators will need the proxy address from the above output in all commands below. If you know the address of a proxy contract but don't know which variant of staking it supports, run
```bash
forge script script/variant_Delegation.s.sol --rpc-url http://localhost:4201 --sig "run(address payable)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2
forge script script/CheckVariant.s.sol --rpc-url http://localhost:4201 --sig "run(address payable)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2
```
The output will be `ILiquidStaking`, `INonLiquidStaking` or none of them if the address is not a valid delegation contract.

To use the delegation contract, upgrade it to the latest version of `LiquidDelegationV2` or `NonLiquidDelegationV2` depending on the staking model it implements, by running
```bash
forge script script/upgrade_Delegation.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(address payable)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2
forge script script/Upgrade.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(address payable)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2
```

The output will look like this:
Expand All @@ -102,7 +102,7 @@ To adapt the contract to your needs, create your own copy of `LiquidDelegationV2

Now or at a later time you can set the commission on the rewards the validator earns to e.g. 10% as follows:
```bash
forge script script/commission_Delegation.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(address payable, string, bool)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 1000 false
forge script script/ManageCommission.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(address payable, string, bool)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 1000 false
```

The output will contain the following information:
Expand All @@ -119,7 +119,7 @@ cast call 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 "DENOMINATOR()(uint256)" --

Once the validator is activated and starts earning rewards, commissions are transferred automatically to the validator node's account. Commissions of a non-liquid staking validator are deducted when delegators withdraw rewards. In case of the liquid staking variant, commissions are deducted each time delegators stake, unstake or claim what they unstaked, or when the node requests the outstanding commissions that haven't been transferred yet. To collect them, run
```bash
forge script script/commission_Delegation.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(address payable, string, bool)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 same true
forge script script/ManageCommission.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(address payable, string, bool)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 same true
```
using `same` for the second argument to leave the commission percentage unchanged and `true` for the third argument. Replacing the second argument with `same` and the third argument with `false` only displays the current commission rate.

Expand Down Expand Up @@ -168,7 +168,7 @@ Note that the deposit will not take effect and the node will not start earning r
## Staking and Unstaking
Once the delegation contract has been deployed and upgraded to the latest version, your node can accept delegations. In order to stake e.g. 200 ZIL, your delegators must run
```bash
forge script script/stake_Delegation.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(address payable, uint256)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 200000000000000000000 --private-key 0x...
forge script script/Stake.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(address payable, uint256)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 200000000000000000000 --private-key 0x...
```
with the private key of their account. It's important to make sure the account's balance can cover the transaction fees plus the 200 ZIL to be delegated.

Expand Down Expand Up @@ -204,7 +204,7 @@ cast to-unit $(cast call 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 "getPrice()(

To unstake e.g. 100 LST (liquid variant) or 100 ZIL (non-liquid variant), run
```bash
forge script script/unstake_Delegation.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(address payable, uint256)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 100000000000000000000 --private-key 0x...
forge script script/Unstake.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(address payable, uint256)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 100000000000000000000 --private-key 0x...
```
using the private key of an account that holds some LST in case of the liquid variant or using the private key of the delegator account in case of the non-liquid variant.

Expand All @@ -228,7 +228,7 @@ and like this for the non-liquid variant:

The ZIL balance hasn't increased because the unstaked amount can not be transferred immediately. To claim the amount that is available after the unbonding period, run
```bash
forge script script/claim_Delegation.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(address payable)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 --private-key 0x...
forge script script/Claim.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(address payable)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 --private-key 0x...
```
with the private key of the account that unstaked in the previous step above.

Expand All @@ -249,7 +249,7 @@ with the user's address as an argument.
## Staking and Withdrawing Rewards
In the liquid staking variant, only you as the node operator can stake the rewards accrued by the node. To do so, run
```bash
forge script script/stakeRewards_Delegation.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(address payable)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 --private-key 0x...
forge script script/StakeRewards.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(address payable)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 --private-key 0x...
```

In the non-liquid variant of staking, your delegators can stake or withdraw their share of the rewards. To query the amount of rewards available, run
Expand All @@ -265,13 +265,13 @@ Note that `n` actually denotes the number of additional (un)stakings so that at

To withdraw e.g. 1 ZIL of rewards using `n = 100`, run
```bash
forge script script/withdrawRewards_Delegation.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(address payable, string, string)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 1000000000000000000 100 --private-key 0x...
forge script script/WithdrawRewards.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(address payable, string, string)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 1000000000000000000 100 --private-key 0x...
```
with the private key of a delegator account. To withdraw as much as possible with the given value of `n` set the amount to `all`. To withdraw the chosen amount without setting `n` replace `n` with `all`. To withdraw all rewards replace both the amount and `n` with `all`.

Last but not least, in order to stake rewards instead of withdrawing them, your delegators can run
```bash
forge script script/stakeRewards_Delegation.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(address payable)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 --private-key 0x...
forge script script/StakeRewards.s.sol --rpc-url http://localhost:4201 --broadcast --legacy --sig "run(address payable)" 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 --private-key 0x...
```
using the private key of their account.

Expand Down
4 changes: 2 additions & 2 deletions claim.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ fi

staker=$(cast wallet address $2)

temp=$(forge script script/variant_Delegation.s.sol --rpc-url $url --sig "run(address payable)" $1 | tail -n 1)
temp=$(forge script script/CheckVariant.s.sol --rpc-url $url --sig "run(address payable)" $1 | tail -n 1)
variant=$(sed -E 's/\s\s([a-zA-Z0-9]+)/\1/' <<< "$temp")
if [[ "$variant" == "$temp" ]]; then
echo Incompatible delegation contract at $1
exit 1
fi

forge script script/claim_Delegation.s.sol --rpc-url $url --broadcast --legacy --sig "run(address payable)" $1 --private-key $2 -vvvv
forge script script/Claim.s.sol --rpc-url $url --broadcast --legacy --sig "run(address payable)" $1 --private-key $2 -vvvv

block=$(cast rpc eth_blockNumber --rpc-url $url)
block_num=$(echo $block | tr -d '"' | cast to-dec --base-in 16)
Expand Down
5 changes: 3 additions & 2 deletions script/variant_Delegation.s.sol → script/CheckVariant.s.sol
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.26;

/* solhint-disable no-console */
import {Script} from "forge-std/Script.sol";
import {ILiquidDelegation} from "src/LiquidDelegation.sol";
import {INonLiquidDelegation} from "src/NonLiquidDelegation.sol";
import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
import "forge-std/console.sol";
import {console} from "forge-std/console.sol";

contract Upgrade is Script {
contract CheckVariant is Script {
using ERC165Checker for address;

function run(address proxy) external {
Expand Down
3 changes: 2 additions & 1 deletion script/claim_Delegation.s.sol → script/Claim.s.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.26;

/* solhint-disable no-console */
import {Script} from "forge-std/Script.sol";
import {BaseDelegation} from "src/BaseDelegation.sol";
import "forge-std/console.sol";
import {console} from "forge-std/console.sol";

contract Claim is Script {
function run(address payable proxy) external {
Expand Down
3 changes: 2 additions & 1 deletion script/deploy_Delegation.s.sol → script/Deploy.s.sol
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.26;

/* solhint-disable no-console */
import {Script} from "forge-std/Script.sol";
import {BaseDelegation} from "src/BaseDelegation.sol";
import {LiquidDelegation} from "src/LiquidDelegation.sol";
import {NonLiquidDelegation} from "src/NonLiquidDelegation.sol";
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import "forge-std/console.sol";
import {console} from "forge-std/console.sol";

contract Deploy is Script {
using Strings for string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.26;

/* solhint-disable no-console */
import {Script} from "forge-std/Script.sol";
import {BaseDelegation} from "src/BaseDelegation.sol";
import {Console} from "src/Console.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import "forge-std/console.sol";
import {console} from "forge-std/console.sol";

contract Commission is Script {
contract ManageCommission is Script {
using Strings for string;

function run(address payable proxy, string calldata commissionNumerator, bool collectCommission) external {
Expand Down
3 changes: 2 additions & 1 deletion script/stake_Delegation.s.sol → script/Stake.s.sol
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.26;

/* solhint-disable no-console */
import {Script} from "forge-std/Script.sol";
import {NonRebasingLST} from "src/NonRebasingLST.sol";
import {BaseDelegation} from "src/BaseDelegation.sol";
import {ILiquidDelegation} from "src/LiquidDelegation.sol";
import {LiquidDelegationV2} from "src/LiquidDelegationV2.sol";
import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
import "forge-std/console.sol";
import {console} from "forge-std/console.sol";

contract Stake is Script {
using ERC165Checker for address;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.26;

/* solhint-disable no-console */
import {Script} from "forge-std/Script.sol";
import {BaseDelegation} from "src/BaseDelegation.sol";
import "forge-std/console.sol";
import {console} from "forge-std/console.sol";

contract StakeRewards is Script {

Expand Down
3 changes: 2 additions & 1 deletion script/unstake_Delegation.s.sol → script/Unstake.s.sol
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.26;

/* solhint-disable no-console */
import {Script} from "forge-std/Script.sol";
import {NonRebasingLST} from "src/NonRebasingLST.sol";
import {BaseDelegation} from "src/BaseDelegation.sol";
import {ILiquidDelegation} from "src/LiquidDelegation.sol";
import {INonLiquidDelegation} from "src/NonLiquidDelegation.sol";
import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
import "forge-std/console.sol";
import {console} from "forge-std/console.sol";

contract Unstake is Script {
using ERC165Checker for address;
Expand Down
3 changes: 2 additions & 1 deletion script/upgrade_Delegation.s.sol → script/Upgrade.s.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.26;

/* solhint-disable no-console */
import {Script} from "forge-std/Script.sol";
import {BaseDelegation} from "src/BaseDelegation.sol";
import {ILiquidDelegation} from "src/LiquidDelegation.sol";
import {INonLiquidDelegation} from "src/NonLiquidDelegation.sol";
import {LiquidDelegationV2} from "src/LiquidDelegationV2.sol";
import {NonLiquidDelegationV2} from "src/NonLiquidDelegationV2.sol";
import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
import "forge-std/console.sol";
import {console} from "forge-std/console.sol";

contract Upgrade is Script {
using ERC165Checker for address;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.26;

/* solhint-disable no-console */
import {Script} from "forge-std/Script.sol";
import {NonLiquidDelegation} from "src/NonLiquidDelegation.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import "forge-std/console.sol";
import {console} from "forge-std/console.sol";

contract WithdrawRewards is Script {
using Strings for string;
Expand Down
62 changes: 8 additions & 54 deletions src/BaseDelegation.sol
Original file line number Diff line number Diff line change
@@ -1,60 +1,12 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.26;

import "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol";
import "src/Delegation.sol";

library WithdrawalQueue {

address public constant DEPOSIT_CONTRACT = address(0x5A494C4445504F53495450524F5859);

struct Item {
uint256 blockNumber;
uint256 amount;
}

struct Fifo {
uint256 first;
uint256 last;
mapping(uint256 => Item) items;
}

function unbondingPeriod() view internal returns(uint256) {
(bool success, bytes memory data) = DEPOSIT_CONTRACT.staticcall(
abi.encodeWithSignature("withdrawalPeriod()")
);
require(success, "unbonding period unknown");
return abi.decode(data, (uint256));
}

function enqueue(Fifo storage fifo, uint256 amount) internal {
fifo.items[fifo.last] = Item(block.number + unbondingPeriod(), amount);
fifo.last++;
}

function dequeue(Fifo storage fifo) internal returns(Item memory result) {
require(fifo.first < fifo.last, "queue empty");
result = fifo.items[fifo.first];
delete fifo.items[fifo.first];
fifo.first++;
}

function ready(Fifo storage fifo, uint256 index) internal view returns(bool) {
return index < fifo.last && fifo.items[index].blockNumber <= block.number;
}

function notReady(Fifo storage fifo, uint256 index) internal view returns(bool) {
return index < fifo.last && fifo.items[index].blockNumber > block.number;
}

function ready(Fifo storage fifo) internal view returns(bool) {
return ready(fifo, fifo.first);
}
}
import {Delegation} from "src/Delegation.sol";
import {WithdrawalQueue} from "src/WithdrawalQueue.sol";
import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import {ERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol";

abstract contract BaseDelegation is Delegation, PausableUpgradeable, Ownable2StepUpgradeable, UUPSUpgradeable, ERC165Upgradeable {

Expand All @@ -70,6 +22,7 @@ abstract contract BaseDelegation is Delegation, PausableUpgradeable, Ownable2Ste
}

// keccak256(abi.encode(uint256(keccak256("zilliqa.storage.BaseDelegation")) - 1)) & ~bytes32(uint256(0xff))
// solhint-disable const-name-snakecase
bytes32 private constant BaseDelegationStorageLocation = 0xc8ff0e571ef581b660c1651f85bbac921a40f9489bd04631c07fa723c13c6000;

function _getBaseDelegationStorage() private pure returns (BaseDelegationStorage storage $) {
Expand All @@ -86,6 +39,7 @@ abstract contract BaseDelegation is Delegation, PausableUpgradeable, Ownable2Ste
return _getInitializedVersion();
}

// solhint-disable func-name-mixedcase
function __BaseDelegation_init(address initialOwner) internal onlyInitializing {
__Pausable_init_unchained();
__Ownable2Step_init_unchained();
Expand Down
Loading

0 comments on commit 3708ab3

Please sign in to comment.