Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply guidelines, improve tests and docs, support solo staker migration #24

Merged
merged 15 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .solhint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"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",
"interface-starts-with-i": "warn",
"func-param-name-mixedcase": "warn",
"modifier-name-mixedcase": "warn",
"gas-calldata-parameters": "warn",
"gas-indexed-events": "warn",
"gas-length-in-loops": "warn",
"comprehensive-interface": "warn",
"gas-increment-by-one": "off",
"private-vars-leading-underscore": ["off", {"strict": false}],
"named-parameters-mapping": "off",
"foundry-test-functions": ["off"],
"imports-order": "off",
"max-line-length": ["off", 120]
}
}
183 changes: 144 additions & 39 deletions README.md

Large diffs are not rendered by default.

22 changes: 12 additions & 10 deletions claim.sh
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
#!/bin/bash

url=http://localhost:4201

if [ $# -ne 2 ]; then
echo "Provide the delegation contract address and a staker private key as arguments."
exit 1
fi

staker=$(cast wallet address $2)

temp=$(forge script script/variant_Delegation.s.sol --rpc-url http://localhost:4201 --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 http://localhost:4201 --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 http://localhost:4201)
block=$(cast rpc eth_blockNumber --rpc-url $url)
block_num=$(echo $block | tr -d '"' | cast to-dec --base-in 16)

echo rewardsAfterClaiming = $(cast call $1 "getRewards()(uint256)" --block $block_num --rpc-url http://localhost:4201 | sed 's/\[[^]]*\]//g')
echo rewardsAfterClaiming = $(cast call $1 "getRewards()(uint256)" --block $block_num --rpc-url $url | sed 's/\[[^]]*\]//g')
if [[ "$variant" == "ILiquidDelegation" ]]; then
echo taxedRewardsAfterClaiming = $(cast call $1 "getTaxedRewards()(uint256)" --block $block_num --rpc-url http://localhost:4201 | sed 's/\[[^]]*\]//g')
echo taxedRewardsAfterClaiming = $(cast call $1 "getTaxedRewards()(uint256)" --block $block_num --rpc-url $url | sed 's/\[[^]]*\]//g')
fi

stakerWeiAfter=$(cast rpc eth_getBalance $staker $block --rpc-url http://localhost:4201 | tr -d '"' | cast to-dec --base-in 16)
stakerWeiAfter=$(cast rpc eth_getBalance $staker $block --rpc-url $url | tr -d '"' | cast to-dec --base-in 16)

tmp=$(cast logs --from-block $block_num --to-block $block_num --address $1 "Claimed(address,uint256,bytes)" --rpc-url http://localhost:4201 | grep "data")
tmp=$(cast logs --from-block $block_num --to-block $block_num --address $1 "Claimed(address,uint256,bytes)" --rpc-url $url | grep "data")
if [[ "$tmp" != "" ]]; then
tmp=${tmp#*: }
tmp=$(cast abi-decode --input "x(uint256,bytes)" $tmp | sed 's/\[[^]]*\]//g')
Expand All @@ -43,12 +45,12 @@ echo $(date +"%T,%3N") $block_num
block_num=$((block_num-1))
block=$(echo $block_num | cast to-hex --base-in 10)

echo rewardsBeforeClaiming = $(cast call $1 "getRewards()(uint256)" --block $block_num --rpc-url http://localhost:4201 | sed 's/\[[^]]*\]//g')
echo rewardsBeforeClaiming = $(cast call $1 "getRewards()(uint256)" --block $block_num --rpc-url $url | sed 's/\[[^]]*\]//g')
if [[ "$variant" == "ILiquidDelegation" ]]; then
echo taxedRewardsBeforeClaiming = $(cast call $1 "getTaxedRewards()(uint256)" --block $block_num --rpc-url http://localhost:4201 | sed 's/\[[^]]*\]//g')
echo taxedRewardsBeforeClaiming = $(cast call $1 "getTaxedRewards()(uint256)" --block $block_num --rpc-url $url | sed 's/\[[^]]*\]//g')
fi

stakerWeiBefore=$(cast rpc eth_getBalance $staker $block --rpc-url http://localhost:4201 | tr -d '"' | cast to-dec --base-in 16)
stakerWeiBefore=$(cast rpc eth_getBalance $staker $block --rpc-url $url | tr -d '"' | cast to-dec --base-in 16)

echo claimed amount - gas fee = $(bc -l <<< "scale=18; $stakerWeiAfter-$stakerWeiBefore") wei

Expand Down
7 changes: 4 additions & 3 deletions script/variant_Delegation.s.sol → script/CheckVariant.s.sol
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
// 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 {
function run(address proxy) external view {

if (proxy.supportsInterface(type(ILiquidDelegation).interfaceId))
console.log("ILiquidDelegation");
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
27 changes: 17 additions & 10 deletions script/deploy_Delegation.s.sol → script/Deploy.s.sol
Original file line number Diff line number Diff line change
@@ -1,38 +1,45 @@
// 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;

function run(string calldata variant) external {
function run(string calldata variant, string calldata name, string calldata symbol) external {
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
address owner = vm.addr(deployerPrivateKey);
console.log("Signer is %s", owner);

vm.startBroadcast(deployerPrivateKey);

address implementation;
bytes memory initializerCall;

if (variant.equal("LiquidDelegation"))
if (variant.equal("LiquidDelegation")) {
implementation = address(new LiquidDelegation());
else if (variant.equal("NonLiquidDelegation"))
initializerCall = abi.encodeWithSignature(
"initialize(address,string,string)",
owner,
name,
symbol
);
} else if (variant.equal("NonLiquidDelegation")) {
implementation = address(new NonLiquidDelegation());
else
initializerCall = abi.encodeWithSignature(
"initialize(address)",
owner
);
} else
return;

bytes memory initializerCall = abi.encodeWithSignature(
"initialize(address)",
owner
);

address payable proxy = payable(
new ERC1967Proxy(implementation, initializerCall)
);
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
13 changes: 8 additions & 5 deletions 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 All @@ -34,9 +35,10 @@ contract Stake is Script {
address(lst)
);

console.log("Staker balance before: %s wei %s LST",
console.log("Staker balance before: %s wei %s %s",
staker.balance,
lst.balanceOf(staker)
lst.balanceOf(staker),
lst.symbol()
);
} else {
console.log("Staker balance before: %s wei",
Expand All @@ -52,9 +54,10 @@ contract Stake is Script {

if (address(delegation).supportsInterface(type(ILiquidDelegation).interfaceId)) {
NonRebasingLST lst = NonRebasingLST(LiquidDelegationV2(payable(address(delegation))).getLST());
console.log("Staker balance after: %s wei %s LST",
console.log("Staker balance after: %s wei %s %s",
staker.balance,
lst.balanceOf(staker)
lst.balanceOf(staker),
lst.symbol()
);
} else {
console.log("Staker balance after: %s wei",
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
13 changes: 8 additions & 5 deletions 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 All @@ -34,9 +35,10 @@ contract Unstake is Script {
address(lst)
);

console.log("Staker balance before: %s wei %s LST",
console.log("Staker balance before: %s wei %s %s",
staker.balance,
lst.balanceOf(staker)
lst.balanceOf(staker),
lst.symbol()
);

if (amount == 0) {
Expand All @@ -63,9 +65,10 @@ contract Unstake is Script {

if (address(delegation).supportsInterface(type(ILiquidDelegation).interfaceId)) {
NonRebasingLST lst = NonRebasingLST(ILiquidDelegation(payable(address(delegation))).getLST());
console.log("Staker balance after: %s wei %s LST",
console.log("Staker balance after: %s wei %s %s",
staker.balance,
lst.balanceOf(staker)
lst.balanceOf(staker),
lst.symbol()
);
} else {
console.log("Staker balance after: %s wei",
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
Loading
Loading