Skip to content

Commit

Permalink
finish contracts restructuring
Browse files Browse the repository at this point in the history
  • Loading branch information
R-Santev committed Jun 24, 2024
1 parent fd07955 commit 4989500
Show file tree
Hide file tree
Showing 57 changed files with 2,795 additions and 3,110 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ pragma solidity 0.8.17;

import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

import {IAPRCalculator} from "./../../APRCalculator/IAPRCalculator.sol";

import {Unauthorized} from "./../../common/Errors.sol";
import {Unauthorized} from "./../common/Errors.sol";
import {IAPRCalculator} from "./IAPRCalculator.sol";

abstract contract APRCalculatorConnector is Initializable {
IAPRCalculator public aprCalculatorContract;
Expand Down
5 changes: 2 additions & 3 deletions contracts/HydraChain/HydraChain.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,10 @@ contract HydraChain is IHydraChain, ValidatorManager, Inspector, PowerExponent {
function initialize(
ValidatorInit[] calldata newValidators,
address governance,
IBLS newBls,
uint256 initialCommission
IBLS newBls
) external initializer onlySystemCall {
__PowerExponent_init();
__ValidatorManager_init(newValidators, newBls, governance, initialCommission);
__ValidatorManager_init(newValidators, newBls, governance);
__Inspector_init();

_initialize();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ pragma solidity 0.8.17;

import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

import {IEpochManager} from "./../../HydraChain/modules/EpochManager/IEpochManager.sol";

import {Unauthorized} from "./../../common/Errors.sol";
import {Unauthorized} from "./../../../common/Errors.sol";
import {IEpochManager} from "./IEpochManager.sol";

abstract contract EpochManagerConnector is Initializable {
IEpochManager public epochManagerContract;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,15 @@ abstract contract ValidatorManager is IValidatorManager, System, AccessControl,
function __ValidatorManager_init(
ValidatorInit[] calldata newValidators,
IBLS newBls,
address governance,
uint256 initialCommission
address governance
) internal onlyInitializing {
__AccessControl_init(governance);
__ValidatorManager_init_unchained(newValidators, newBls, initialCommission);
__ValidatorManager_init_unchained(newValidators, newBls);
}

function __ValidatorManager_init_unchained(
ValidatorInit[] calldata newValidators,
IBLS newBls,
uint256 initialCommission
IBLS newBls
) internal onlyInitializing {
bls = newBls;
// set initial validators
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import {Governed} from "./../../../common/Governed/Governed.sol";
import {Withdrawal} from "./../Withdrawal/Withdrawal.sol";
import {APRCalculatorConnector} from "./../APRCalculatorConnector.sol";
import {Governed} from "./../common/Governed/Governed.sol";
import {Withdrawal} from "./../common/Withdrawal/Withdrawal.sol";
import {APRCalculatorConnector} from "./../APRCalculator/APRCalculatorConnector.sol";
import {DelegationPoolLib} from "./DelegationPoolLib.sol";
import {IDelegation, DelegationPool} from "./IDelegation.sol";

Expand All @@ -13,13 +13,14 @@ contract Delegation is IDelegation, Governed, Withdrawal, APRCalculatorConnector
/// @notice A constant for the minimum delegation limit
uint256 public constant MIN_DELEGATION_LIMIT = 1 ether;

uint256 public totalDelegation;
/// @notice Keeps the delegation pools
mapping(address => DelegationPool) public delegationPools;
// @note maybe this must be part of the ValidatorSet
/// @notice The minimum delegation amount to be delegated
uint256 public minDelegation;

uint256 internal _totalDelegation;

function delegationOf(address staker, address delegator) public view returns (uint256) {
return delegationPools[staker].balanceOf(delegator);
}
Expand All @@ -28,6 +29,10 @@ contract Delegation is IDelegation, Governed, Withdrawal, APRCalculatorConnector
return delegationPools[staker].supply;
}

function totalDelegation() external view returns (uint256) {
return _totalDelegation;
}

/**
* @inheritdoc IDelegation
*/
Expand Down Expand Up @@ -65,7 +70,7 @@ contract Delegation is IDelegation, Governed, Withdrawal, APRCalculatorConnector
revert DelegateRequirement({src: "delegate", msg: "DELEGATION_TOO_LOW"});

delegation.deposit(delegator, amount);
totalDelegation += amount;
_totalDelegation += amount;

emit Delegated(staker, delegator, amount);
}
Expand All @@ -84,7 +89,7 @@ contract Delegation is IDelegation, Governed, Withdrawal, APRCalculatorConnector
revert DelegateRequirement({src: "undelegate", msg: "DELEGATION_TOO_LOW"});

delegation.withdraw(delegator, amount);
totalDelegation -= amount;
_totalDelegation -= amount;

emit Undelegated(validator, delegator, amount);
}
Expand All @@ -100,7 +105,7 @@ contract Delegation is IDelegation, Governed, Withdrawal, APRCalculatorConnector
_withdraw(delegator, reward);
}

function _distributeDelegatorReward(address staker, uint256 reward) internal {
function _distributeDelegationRewards(address staker, uint256 reward) internal virtual {
delegationPools[staker].distributeReward(reward);
emit DelegatorRewardDistributed(staker, reward);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import "./../../../common/libs/SafeMathInt.sol";
import "./../common/libs/SafeMathInt.sol";
import {DelegationPool} from "./IDelegation.sol";

error NoTokensDelegated(address validator);
Expand Down
82 changes: 82 additions & 0 deletions contracts/HydraDelegation/HydraDelegation.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import {Delegation} from "./Delegation.sol";
import {LiquidDelegation} from "./modules/LiquidDelegation/LiquidDelegation.sol";
import {VestedDelegation} from "./modules/VestedDelegation/VestedDelegation.sol";
import {APRCalculatorConnector} from "./../APRCalculator/APRCalculatorConnector.sol";
import {IHydraDelegation} from "./IHydraDelegation.sol";
import {StakerInit} from "./../HydraStaking/IHydraStaking.sol";
import {HydraStakingConnector} from "./../HydraStakingV2/HydraStakingConnector.sol";

contract HydraDelegation is
IHydraDelegation,
APRCalculatorConnector,
HydraStakingConnector,
Delegation,
LiquidDelegation,
VestedDelegation
{
/// @notice A constant for the maximum comission a validator can receive from the delegator's rewards
uint256 public constant MAX_COMMISSION = 100;

mapping(address => uint256) public delegationCommissionPerStaker;

// _______________ Initializer _______________

// TODO: Move commision to Delegation module
function __DelegatedStaking_init(
StakerInit[] calldata initialStakers,
uint256 initialCommission
) internal onlyInitializing {
__DelegatedStaking_init_unchained(initialStakers, initialCommission);
}

function __DelegatedStaking_init_unchained(
StakerInit[] calldata initialStakers,
uint256 initialCommission
) internal onlyInitializing {
for (uint256 i = 0; i < initialStakers.length; i++) {
_setCommission(initialStakers[i].addr, initialCommission);
}
}

function stakerDelegationCommission(address staker) external view returns (uint256) {
return delegationCommissionPerStaker[staker];
}

function distributeDelegationRewards(address staker, uint256 reward, uint256 epochId) external onlyHydraStaking {
_distributeDelegationRewards(staker, reward, epochId);
}

/**
* @inheritdoc IHydraDelegation
*/
function setCommission(uint256 newCommission) external {
_setCommission(msg.sender, newCommission);
}

function _delegate(
address staker,
address delegator,
uint256 amount
) internal virtual override(Delegation, LiquidDelegation, VestedDelegation) {
super._delegate(staker, delegator, amount);
}

function _undelegate(
address validator,
address delegator,
uint256 amount
) internal virtual override(Delegation, LiquidDelegation, VestedDelegation) {
super._undelegate(validator, delegator, amount);
}

function _setCommission(address staker, uint256 newCommission) private {
if (newCommission > MAX_COMMISSION) revert InvalidCommission(newCommission);

delegationCommissionPerStaker[staker] = newCommission;

emit CommissionUpdated(staker, newCommission);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import {IWithdrawal} from "./../Withdrawal/IWithdrawal.sol";
import {IWithdrawal} from "./../common/Withdrawal/IWithdrawal.sol";

struct DelegationPool {
uint256 supply;
Expand All @@ -21,6 +21,10 @@ interface IDelegation is IWithdrawal {

error DelegateRequirement(string src, string msg);

function totalDelegation() external view returns (uint256);

function totalDelegationOf(address staker) external view returns (uint256);

/**
* @notice Gets delegator's unclaimed rewards index (without custom APR params applied)
* @param validator Address of validator
Expand Down
22 changes: 22 additions & 0 deletions contracts/HydraDelegation/IHydraDelegation.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import {ILiquid} from "./../common/Liquid/ILiquid.sol";
import {IDelegation} from "./IDelegation.sol";
import {IVestedDelegation} from "./modules/VestedDelegation/IVestedDelegation.sol";

interface IHydraDelegation is IDelegation, IVestedDelegation, ILiquid {
event CommissionUpdated(address indexed validator, uint256 newCommission);

error InvalidCommission(uint256 commission);

function stakerDelegationCommission(address staker) external view returns (uint256);

/**
* @notice Sets commission for validator.
* @param newCommission New commission (100 = 100%)
*/
function setCommission(uint256 newCommission) external;

function distributeDelegationRewards(address staker, uint256 reward, uint256 epochId) external;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
pragma solidity 0.8.17;

import {Delegation} from "./../../Delegation.sol";
import {APRCalculatorConnector} from "./../../../APRCalculatorConnector.sol";
import {EpochManagerConnector} from "./../../../EpochManagerConnector.sol";
import {Governed} from "./../../../common/Governed/Governed.sol";
import {Withdrawal} from "./../../../common/Withdrawal/Withdrawal.sol";
import {APRCalculatorConnector} from "./../../../APRCalculator/APRCalculatorConnector.sol";
import {EpochManagerConnector} from "./../../../HydraChain/modules/EpochManager/EpochManagerConnector.sol";
import {VestingManagerFactory} from "./../VestingManagerFactory/VestingManagerFactory.sol";
import {DelegationPoolLib} from "./../../DelegationPoolLib.sol";
import {VestedPositionLib} from "./../../../common/Vesting/VestedPositionLib.sol";
import {DelegationPool} from "./../../IDelegation.sol";
import {VestingPosition} from "./../../../common/Vesting/IVesting.sol";
import {IVestedDelegation, DelegationPoolParams, RPS} from "./IVestedDelegation.sol";
import {VestingPosition} from "./../../../VestedStaking/IVesting.sol";
import {Withdrawal} from "./../../../../modules/Withdrawal/Withdrawal.sol";
import {Governed} from "./../../../../../common/Governed/Governed.sol";
import {VestedPositionLib} from "./../../../VestedStaking/VestedPositionLib.sol";
import {DelegationPoolLib} from "./../../DelegationPoolLib.sol";

contract VestedDelegation is
IVestedDelegation,
Expand Down Expand Up @@ -290,6 +290,15 @@ contract VestedDelegation is
super._undelegate(staker, delegator, amount);
}

function _distributeDelegationRewards(address staker, uint256 reward, uint256 epochId) internal virtual {
_distributeDelegationRewards(staker, reward);

// Keep history record of the rewardPerShare to be used on reward claim
if (reward > 0) {
_saveEpochRPS(staker, delegationPools[staker].magnifiedRewardPerShare, epochId);
}
}

/**
* @inheritdoc IVestedDelegation
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity 0.8.17;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts/proxy/Clones.sol";

import {VestingManager} from "./../../../../../VestingManager/VestingManager.sol";
import {VestingManager} from "./../../../VestingManager/VestingManager.sol";

// TODO: use different proxy design pattern, so implementation for all proxies can be changed at once
abstract contract VestingManagerFactory is Initializable {
Expand Down
27 changes: 9 additions & 18 deletions contracts/HydraStakingV2/HydraStaking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import {PenalizeableStaking} from "./modules/PenalizeableStaking/PenalizeableSta
import {IHydraStaking, StakerInit} from "./IHydraStaking.sol";
import {PenalizedStakeDistribution} from "./modules/PenalizeableStaking/IPenalizeableStaking.sol";
import {Uptime} from "./../HydraChain/modules/ValidatorManager/IValidatorManager.sol";
import {EpochManagerConnector} from "./modules/EpochManagerConnector.sol";
import {EpochManagerConnector} from "./../HydraChain/modules/EpochManager/EpochManagerConnector.sol";
import {Governed} from "./../common/Governed/Governed.sol";
import {DelegationPool} from "./modules/DelegatedStaking/IDelegation.sol";
import {DelegationPool} from "./../HydraDelegation/IDelegation.sol";

// TODO: An optimization we can do is keeping only once the general apr params for a block so we don' have to keep them for every single user

Expand Down Expand Up @@ -88,11 +88,11 @@ contract HydraStaking is
// _______________ Public functions _______________

function totalBalanceOf(address staker) public view returns (uint256) {
return stakeOf(staker) + totalDelegationOf(staker);
return stakeOf(staker) + _getStakerDelegatedBalance(staker);
}

function totalBalance() public view returns (uint256) {
return totalStake + totalDelegation;
return totalStake + _totalDelegation();
}

// _______________ Internal functions _______________
Expand All @@ -119,13 +119,11 @@ contract HydraStaking is
}
}

function _delegate(address staker, address delegator, uint256 amount) internal virtual override {
super._delegate(staker, delegator, amount);
function _onDelegate(address staker) internal virtual override {
_syncState(staker);
}

function _undelegate(address staker, address delegator, uint256 amount) internal virtual override {
super._undelegate(staker, delegator, amount);
function _onUndelegate(address staker) internal virtual override {
_syncState(staker);
}

Expand Down Expand Up @@ -169,10 +167,8 @@ contract HydraStaking is
require(uptime.signedBlocks <= totalBlocks, "SIGNED_BLOCKS_EXCEEDS_TOTAL");

uint256 totalStake = stakeOf(uptime.validator);
uint256 commission = delegationCommissionPerStaker[uptime.validator];

DelegationPool storage delegationPool = delegationPools[uptime.validator];
uint256 delegation = delegationPool.supply;
uint256 commission = _getstakerDelegationCommission(uptime.validator);
uint256 delegation = _getStakerDelegatedBalance(uptime.validator);
// slither-disable-next-line divide-before-multiply
uint256 validatorReward = (fullReward * (totalStake + delegation) * uptime.signedBlocks) /
(totalSupply * totalBlocks);
Expand All @@ -184,12 +180,7 @@ contract HydraStaking is
);

_distributeStakingReward(uptime.validator, validatorShares);
_distributeDelegatorReward(uptime.validator, delegatorShares);

// Keep history record of the rewardPerShare to be used on reward claim
if (delegatorShares > 0) {
_saveEpochRPS(uptime.validator, delegationPool.magnifiedRewardPerShare, epochId);
}
distributeDelegationRewards(uptime.validator, delegatorShares, epochId);

// Keep history record of the validator rewards to be used on maturing vesting reward claim
if (validatorShares > 0) {
Expand Down
Loading

0 comments on commit 4989500

Please sign in to comment.