Skip to content

Commit

Permalink
Modify order of staking and unstaking steps
Browse files Browse the repository at this point in the history
  • Loading branch information
DrZoltanFazekas committed Oct 18, 2024
1 parent f978729 commit 518247e
Show file tree
Hide file tree
Showing 3 changed files with 326 additions and 147 deletions.
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,20 +63,28 @@ cast call 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 "DENOMINATOR()(uint256)" --
```

## Validator Activation
Now you are ready to use the contract to activate your node as a validator with a deposit of e.g. 10 million ZIL. Run
If you node's account has enough ZIL for the minimum stake required, you can activate your node as a validator with a deposit of e.g. 10 million ZIL. Run
```bash
cast send --legacy --value 10000000ether --rpc-url http://localhost:4201 --private-key $PRIVATE_KEY \
0x7a0b7e6d24ede78260c9ddbd98e828b0e11a8ea2 "deposit(bytes,bytes,bytes)" \
0x92fbe50544dce63cfdcc88301d7412f0edea024c91ae5d6a04c7cd3819edfc1b9d75d9121080af12e00f054d221f876c \
0x002408011220d5ed74b09dcbe84d3b32a56c01ab721cf82809848b6604535212a219d35c412f \
0xb14832a866a49ddf8a3104f8ee379d29c136f29aeb8fccec9d7fb17180b99e8ed29bee2ada5ce390cb704bc6fd7f5ce814f914498376c4b8bc14841a57ae22279769ec8614e2673ba7f36edc5a4bf5733aa9d70af626279ee2b2cde939b4bd8a
```
with the BLS public key, the peer id and the BLS signature of your node. Note that the peer id must be converted from base58 to hex.

Make sure your node's account has the 10 million ZIL and your node is fully synced before you run the above command.
with the BLS public key, the peer id and the BLS signature of your node. Note that the peer id must be converted from base58 to hex. Make sure your node is fully synced before you run the above command.

Note that the reward address registered for your validator node will be the address of the delegation contract (the proxy contract to be more precise).

Alternatively, you can proceed to the next section and delegate stake until the contract's balance reaches the 10 million ZIL minimum stake required for the activation, and then run
```bash
cast send --legacy --rpc-url http://localhost:4201 --private-key $PRIVATE_KEY \
0x7a0b7e6d24ede78260c9ddbd98e828b0e11a8ea2 "deposit2(bytes,bytes,bytes)" \
0x92fbe50544dce63cfdcc88301d7412f0edea024c91ae5d6a04c7cd3819edfc1b9d75d9121080af12e00f054d221f876c \
0x002408011220d5ed74b09dcbe84d3b32a56c01ab721cf82809848b6604535212a219d35c412f \
0xb14832a866a49ddf8a3104f8ee379d29c136f29aeb8fccec9d7fb17180b99e8ed29bee2ada5ce390cb704bc6fd7f5ce814f914498376c4b8bc14841a57ae22279769ec8614e2673ba7f36edc5a4bf5733aa9d70af626279ee2b2cde939b4bd8a
```
to deposit all of it.

## Staking and Unstaking
If the above transaction was successful and the node became a validator, it can accept delegations. In order to stake e.g. 200 ZIL, run
```bash
Expand Down
71 changes: 51 additions & 20 deletions src/DelegationV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import "src/NonRebasingLST.sol";

library WithdrawalQueue {

//TODO: add it to the variables and implement a getter and an onlyOwner setter
// since a governance vote can change the unbonding period anytime
uint256 public constant UNBONDING_PERIOD = 30; //approx. 30s, used only for testing

struct Item {
Expand Down Expand Up @@ -160,9 +162,23 @@ contract DelegationV2 is Initializable, PausableUpgradeable, Ownable2StepUpgrade
require(msg.value >= MIN_DELEGATION, "delegated amount too low");
uint256 shares;
Storage storage $ = _getStorage();
// deduct commission from the rewards only if already activated as a validator
// otherwise getRewards() returns 0 but taxedRewards would be greater than 0
if ($.blsPubKey.length > 0) {
// the delegated amount is temporarily part of the rewards as it's in the balance
// add to the taxed rewards to avoid commission and remove it again after taxing
$.taxedRewards += msg.value;
// before calculating the shares deduct the commission from the yet untaxed rewards
taxRewards();
$.taxedRewards -= msg.value;
}
if (NonRebasingLST($.lst).totalSupply() == 0)
shares = msg.value;
else
shares = NonRebasingLST($.lst).totalSupply() * msg.value / (getStake() + $.taxedRewards);
NonRebasingLST($.lst).mint(msg.sender, shares);
// increase the deposit only if already activated as a validator
if ($.blsPubKey.length > 0) {
// topup the deposit before deducting the commission or calculating the shares
// otherwise the delegated amount will be treated as part of the rewards
(bool success, bytes memory data) = DEPOSIT_CONTRACT.call{
value: msg.value
}(
Expand All @@ -172,38 +188,33 @@ contract DelegationV2 is Initializable, PausableUpgradeable, Ownable2StepUpgrade
);
require(success, "deposit increase failed");
}
taxRewards(); // before calculating the shares we must deduct the commission from the yet untaxed rewards
if (NonRebasingLST($.lst).totalSupply() == 0)
shares = msg.value;
else
shares = NonRebasingLST($.lst).totalSupply() * msg.value / (getStake() + $.taxedRewards);
NonRebasingLST($.lst).mint(msg.sender, shares);
emit Staked(msg.sender, msg.value, shares);
}

function unstake(uint256 shares) public whenNotPaused {
uint256 amount;
Storage storage $ = _getStorage();
NonRebasingLST($.lst).burn(msg.sender, shares);
taxRewards(); // before calculating the amount we must deduct the commission from the yet untaxed rewards
// before calculating the amount deduct the commission from the yet untaxed rewards
taxRewards();
if (NonRebasingLST($.lst).totalSupply() == 0)
amount = shares;
else
amount = (getStake() + $.taxedRewards) * shares / NonRebasingLST($.lst).totalSupply();
$.withdrawals[msg.sender].queue(amount);
$.totalWithdrawals += amount;
if ($.blsPubKey.length > 0) {
// we shall maintain a balance that is always sufficient to cover the claims
// maintain a balance that is always sufficient to cover the claims
if (address(this).balance < $.totalWithdrawals) {
(bool success, bytes memory data) = DEPOSIT_CONTRACT.call(
abi.encodeWithSignature("tempDecreaseDeposit(bytes,uint256)",
$.blsPubKey,
$.totalWithdrawals - address(this).balance
)
);
require(success, "deposit increase failed");
require(success, "deposit decrease failed");
}
}
NonRebasingLST($.lst).burn(msg.sender, shares);
emit Unstaked(msg.sender, amount, shares);
}

Expand Down Expand Up @@ -240,8 +251,9 @@ contract DelegationV2 is Initializable, PausableUpgradeable, Ownable2StepUpgrade
total += $.withdrawals[msg.sender].dequeue().amount;
/*if (total == 0)
return;*/
taxRewards(); // before the balance changes we must deduct the commission from the yet untaxed rewards
//TODO: claim the withdrawals requested from the deposit contract
// before the balance changes deduct the commission from the yet untaxed rewards
taxRewards();
//TODO: claim all deposit withdrawals requested whose unbonding period is over
(bool success, bytes memory data) = msg.sender.call{
value: total
}("");
Expand All @@ -251,18 +263,37 @@ contract DelegationV2 is Initializable, PausableUpgradeable, Ownable2StepUpgrade
emit Claimed(msg.sender, total);
}

//TODO: call restake every time someone wants to stake, unstake or claim?
function restake() public onlyOwner {
taxRewards(); // before the balance changes, we must deduct the commission from the yet untaxed rewards
//TODO: topup the deposit by address(this).balance - $.totalWithdrawals
// i.e. the rewards accrued minus the amount needed for the pending withdrawals
}
//TODO: make it onlyOwnerOrContract and call it every time someone stakes, unstakes or claims?
function restakeRewards() public onlyOwner {
Storage storage $ = _getStorage();
// before the balance changes deduct the commission from the yet untaxed rewards
taxRewards();
if ($.blsPubKey.length > 0) {
(bool success, bytes memory data) = DEPOSIT_CONTRACT.call{
value: address(this).balance - $.totalWithdrawals
}(
abi.encodeWithSignature("tempIncreaseDeposit(bytes)",
$.blsPubKey
)
);
require(success, "deposit increase failed");
}
}

function collectCommission() public onlyOwner {
taxRewards();
}

function getTaxedRewards() public view returns(uint256) {
Storage storage $ = _getStorage();
return $.taxedRewards;
}

function getTotalWithdrawals() public view returns(uint256) {
Storage storage $ = _getStorage();
return $.totalWithdrawals;
}

function getRewards() public view returns(uint256) {
Storage storage $ = _getStorage();
if ($.blsPubKey.length == 0)
Expand Down
Loading

0 comments on commit 518247e

Please sign in to comment.