Skip to content
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
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,16 @@ cast send --legacy --value 5000000ether --private-key $PRIVATE_KEY \
0xb14832a866a49ddf8a3104f8ee379d29c136f29aeb8fccec9d7fb17180b99e8ed29bee2ada5ce390cb704bc6fd7f5ce814f914498376c4b8bc14841a57ae22279769ec8614e2673ba7f36edc5a4bf5733aa9d70af626279ee2b2cde939b4bd8a
```

If you want to deposit only a certain amount from the delegation contract's available stake, run the following command with the amount (e.g. 10 million ZIL) specified as the last argument:
```bash
cast send --legacy --value 5000000ether --private-key $PRIVATE_KEY \
0x7a0b7e6d24ede78260c9ddbd98e828b0e11a8ea2 "depositFromPool(bytes,bytes,bytes,uint256)" \
0x92fbe50544dce63cfdcc88301d7412f0edea024c91ae5d6a04c7cd3819edfc1b9d75d9121080af12e00f054d221f876c \
0x002408011220d5ed74b09dcbe84d3b32a56c01ab721cf82809848b6604535212a219d35c412f \
0xb14832a866a49ddf8a3104f8ee379d29c136f29aeb8fccec9d7fb17180b99e8ed29bee2ada5ce390cb704bc6fd7f5ce814f914498376c4b8bc14841a57ae22279769ec8614e2673ba7f36edc5a4bf5733aa9d70af626279ee2b2cde939b4bd8a \
10000000000000000000000000
```

Note that the reward address registered for the validator node will be the address of the delegation contract (the proxy contract to be more precise), but the deposit will not take effect and the node will not start to earn rewards until the epoch after next.


Expand Down Expand Up @@ -512,6 +522,7 @@ If the execution reverts, you can look up the error based on the first 4 bytes o
0xa8ca83c9 StakerAlreadyExists(address)
0x30e667d2 IncompatibleVersion(uint64)
0x8579befe ZeroAddressNotAllowed()
0xa0753f46 InsufficientAvailableStake(uint256,uint256)
```


Expand Down
44 changes: 37 additions & 7 deletions src/BaseDelegation.sol
Original file line number Diff line number Diff line change
Expand Up @@ -237,14 +237,19 @@ abstract contract BaseDelegation is IDelegation, PausableUpgradeable, Ownable2St
*/
error ZeroAddressNotAllowed();

/**
* @dev Thrown if the `amount` to be deposited exceeds the `availableStake`.
*/
error InsufficientAvailableStake(uint256 amount, uint256 availableStake);

// ************************************************************************
//
// VERSION
//
// ************************************************************************

/// @dev The current version of all upgradeable contracts in the repository.
uint64 internal immutable VERSION = encodeVersion(1, 1, 1);
uint64 internal immutable VERSION = encodeVersion(1, 1, 2);

/**
* @dev Return the contracts' version.
Expand Down Expand Up @@ -428,6 +433,20 @@ abstract contract BaseDelegation is IDelegation, PausableUpgradeable, Ownable2St
bytes calldata signature
) public virtual payable;

/**
* @dev Turn a fully synced node into a validator using `amount` from the stake
* in the pool's balance. It must be called by the contract owner. The staking
* pool must have `amount` in its balance including the amount transferred by
* the contract owner in the current transaction and `amount` must be at least
* the minimum stake required of validators.
*/
function depositFromPool(
bytes calldata blsPubKey,
bytes calldata peerId,
bytes calldata signature,
uint256 amount
) public virtual payable;

/**
* @dev Add the validator identified by `blsPubKey` to the staking pool. It
* can be called by the contract owner if the `controlAddress` has called the
Expand Down Expand Up @@ -469,28 +488,39 @@ abstract contract BaseDelegation is IDelegation, PausableUpgradeable, Ownable2St
/**
* @dev Append an entry to the staking pool's list of validators. Use the pool
* contract's owner address as reward address and control address in the entry.
* Register a validator by transferring the stake available in the contract
* balance to `DEPOSIT_CONTRACT`.
* Register a validator by transferring `amount` or the entire stake available
* in the contract balance if `amount` is zero to the `DEPOSIT_CONTRACT`.
*
* Emit {ValidatorJoined} containing the `blsPubKey` of the validator.
*
* Revert with {TooManyValidators} containing the `blsPubKey` of the validator
* if the pool has already reached the maximum number of validators.
*
* Revert with {InsufficientAvailableStake} containing the `amount` of stake
* to be deposited and the maximum `availableStake` that can be deposited.
*
* Revert with {DepositContractCallFailed} containing the call data and the
* error data returned if the call to the `DEPOSIT_CONTRACT` fails.
*/
function _depositAndAddToPool(
bytes calldata blsPubKey,
bytes calldata peerId,
bytes calldata signature
bytes calldata signature,
uint256 amount
) internal virtual {
BaseDelegationStorage storage $ = _getBaseDelegationStorage();
if (!$.activated)
$.activated = true;
uint256 availableStake = $.nonRewards - $.withdrawnDepositedClaims - $.nonDepositedClaims;
if (amount == 0)
amount = availableStake;
else
require(amount <= availableStake, InsufficientAvailableStake(amount, availableStake));

require($.validators.length < MAX_VALIDATORS, TooManyValidators(blsPubKey));
$.validators.push(Validator(
blsPubKey,
availableStake,
amount,
owner(),
owner(),
0,
Expand All @@ -508,11 +538,11 @@ abstract contract BaseDelegation is IDelegation, PausableUpgradeable, Ownable2St
owner()
);
(bool success, bytes memory data) = DEPOSIT_CONTRACT.call{
value: availableStake
value: amount
}(callData);
require(success, DepositContractCallFailed(callData, data));

$.nonRewards = $.withdrawnDepositedClaims + $.nonDepositedClaims;
$.nonRewards -= amount;
emit ValidatorJoined(blsPubKey);
}

Expand Down
22 changes: 21 additions & 1 deletion src/LiquidDelegation.sol
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,27 @@ contract LiquidDelegation is IDelegation, BaseDelegation {
_depositAndAddToPool(
blsPubKey,
peerId,
signature
signature,
0
);
}

/// @inheritdoc BaseDelegation
function depositFromPool(
bytes calldata blsPubKey,
bytes calldata peerId,
bytes calldata signature,
uint256 amount
) public override payable onlyOwner {
if (msg.value > 0)
_stake(msg.value, _msgSender());
// the total stake must not be increased before the price is determined
_increaseStake(msg.value);
_depositAndAddToPool(
blsPubKey,
peerId,
signature,
amount
);
}

Expand Down
23 changes: 22 additions & 1 deletion src/NonLiquidDelegation.sol
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,28 @@ contract NonLiquidDelegation is IDelegation, BaseDelegation {
_depositAndAddToPool(
blsPubKey,
peerId,
signature
signature,
0
);
// the owner's deposit must also be recorded as staking otherwise
// the owner would not benefit from the rewards accrued by the deposit
if (msg.value > 0)
_appendToHistory(int256(msg.value), _msgSender());
}

/// @inheritdoc BaseDelegation
function depositFromPool(
bytes calldata blsPubKey,
bytes calldata peerId,
bytes calldata signature,
uint256 amount
) public payable override onlyOwner {
_increaseStake(msg.value);
_depositAndAddToPool(
blsPubKey,
peerId,
signature,
amount
);
// the owner's deposit must also be recorded as staking otherwise
// the owner would not benefit from the rewards accrued by the deposit
Expand Down