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

Prepare for enhancement of Stake Manager contracts #281

Merged
merged 9 commits into from
Aug 2, 2023
27 changes: 0 additions & 27 deletions contracts/lib/ChildManagerLib.sol

This file was deleted.

51 changes: 0 additions & 51 deletions contracts/lib/StakeManagerLib.sol

This file was deleted.

51 changes: 24 additions & 27 deletions contracts/root/staking/StakeManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,25 @@ pragma solidity 0.8.19;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "../../lib/ChildManagerLib.sol";
import "../../lib/StakeManagerLib.sol";
import "../../interfaces/root/staking/IStakeManager.sol";
import "./StakeManagerChildData.sol";
import "./StakeManagerStakingData.sol";

contract StakeManager is IStakeManager, Initializable {
using ChildManagerLib for ChildChains;
using StakeManagerLib for Stakes;
contract StakeManager is IStakeManager, Initializable, StakeManagerChildData, StakeManagerStakingData {
using SafeERC20 for IERC20;

IERC20 internal matic;
ChildChains private _chains;
Stakes private _stakes;
IERC20 internal stakingToken;

function initialize(address newMatic) public initializer {
matic = IERC20(newMatic);
function initialize(address newStakingToken) public initializer {
stakingToken = IERC20(newStakingToken);
}

/**
* @inheritdoc IStakeManager
*/
function registerChildChain(address manager) external returns (uint256 id) {
require(_chains.ids[manager] == 0, "StakeManager: ID_ALREADY_SET");
id = _chains.registerChild(manager);
require(_ids[manager] == 0, "StakeManager: ID_ALREADY_SET");
id = _registerChild(manager);
ISupernetManager(manager).onInit(id);
// slither-disable-next-line reentrancy-events
emit ChildManagerRegistered(id, manager);
Expand All @@ -35,12 +32,12 @@ contract StakeManager is IStakeManager, Initializable {
* @inheritdoc IStakeManager
*/
function stakeFor(uint256 id, uint256 amount) external {
require(id != 0 && id <= _chains.counter, "StakeManager: INVALID_ID");
require(id != 0 && id <= counter, "StakeManager: INVALID_ID");
// slither-disable-next-line reentrancy-benign,reentrancy-events
matic.safeTransferFrom(msg.sender, address(this), amount);
stakingToken.safeTransferFrom(msg.sender, address(this), amount);
// calling the library directly once fixes the coverage issue
// https://github.com/foundry-rs/foundry/issues/4854#issuecomment-1528897219
StakeManagerLib.addStake(_stakes, msg.sender, id, amount);
_addStake(msg.sender, id, amount);
ISupernetManager manager = managerOf(id);
manager.onStake(msg.sender, amount);
// slither-disable-next-line reentrancy-events
Expand All @@ -52,7 +49,7 @@ contract StakeManager is IStakeManager, Initializable {
*/
function releaseStakeOf(address validator, uint256 amount) external {
uint256 id = idFor(msg.sender);
_stakes.removeStake(validator, id, amount);
_removeStake(validator, id, amount);
// slither-disable-next-line reentrancy-events
emit StakeRemoved(id, validator, amount);
}
Expand All @@ -69,9 +66,9 @@ contract StakeManager is IStakeManager, Initializable {
*/
function slashStakeOf(address validator, uint256 amount) external {
uint256 id = idFor(msg.sender);
uint256 stake = stakeOf(validator, id);
uint256 stake = _stakeOf(validator, id);
if (amount > stake) amount = stake;
_stakes.removeStake(validator, id, stake);
_removeStake(validator, id, stake);
_withdrawStake(validator, msg.sender, amount);
emit StakeRemoved(id, validator, stake);
emit ValidatorSlashed(id, validator, amount);
Expand All @@ -81,55 +78,55 @@ contract StakeManager is IStakeManager, Initializable {
* @inheritdoc IStakeManager
*/
function withdrawableStake(address validator) external view returns (uint256 amount) {
amount = _stakes.withdrawableStakeOf(validator);
amount = _withdrawableStakeOf(validator);
}

/**
* @inheritdoc IStakeManager
*/
function totalStake() external view returns (uint256 amount) {
amount = _stakes.totalStake;
amount = _totalStake;
}

/**
* @inheritdoc IStakeManager
*/
function totalStakeOfChild(uint256 id) external view returns (uint256 amount) {
amount = _stakes.totalStakeOfChild(id);
amount = _totalStakeOfChild(id);
}

/**
* @inheritdoc IStakeManager
*/
function totalStakeOf(address validator) external view returns (uint256 amount) {
amount = _stakes.totalStakeOf(validator);
amount = _totalStakeOf(validator);
}

/**
* @inheritdoc IStakeManager
*/
function stakeOf(address validator, uint256 id) public view returns (uint256 amount) {
amount = _stakes.stakeOf(validator, id);
amount = _stakeOf(validator, id);
}

/**
* @inheritdoc IStakeManager
*/
function managerOf(uint256 id) public view returns (ISupernetManager manager) {
manager = ISupernetManager(_chains.managerOf(id));
manager = ISupernetManager(_managerOf(id));
}

/**
* @inheritdoc IStakeManager
*/
function idFor(address manager) public view returns (uint256 id) {
id = ChildManagerLib.idFor(_chains, manager);
id = _idFor(manager);
}

function _withdrawStake(address validator, address to, uint256 amount) private {
_stakes.withdrawStake(validator, amount);
_withdrawStake(validator, amount);
// slither-disable-next-line reentrancy-events
matic.safeTransfer(to, amount);
stakingToken.safeTransfer(to, amount);
emit StakeWithdrawn(validator, to, amount);
}

Expand Down
55 changes: 55 additions & 0 deletions contracts/root/staking/StakeManagerChildData.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

/**
* @title StakeManagerChildData
* @notice Holds data to allow look-up between child chain manager contract address and child chain id.
* Note that this is contract is designed to be included in StakeManager. It is upgradeable.
*/
abstract contract StakeManagerChildData {
// Highest child chain id allocated thus far. Child chain id 0x00 is an invalid id.
uint256 internal counter;
// child chain id to child chain manager contract address.
mapping(uint256 => address) private _managers;
// child chain manager contract address to child chain id.
// slither-disable-next-line naming-convention
mapping(address => uint256) internal _ids;

/**
* @notice Register a child chain manager contract and allocate a child chain id.
* @param manager Child chain manager contract address.
* @return id Child chain id allocated for the child chain.
*/
function _registerChild(address manager) internal returns (uint256 id) {
require(manager != address(0), "StakeManagerChildData: INVALID_ADDRESS");
unchecked {
id = ++counter;
}
_managers[id] = manager;
_ids[manager] = id;
}

/**
* @notice Get the child chain manager contract that corresponds to a child chain id.
* @param id Child chain id.
* @return manager Child chain manager contract address.
*/
function _managerOf(uint256 id) internal view returns (address manager) {
manager = _managers[id];
require(manager != address(0), "StakeManagerChildData: INVALID_ID");
}

/**
* @notice Get the child chain id that corresponds to a child chain manager contract.
* @param manager Child chain manager contract address.
* @return id Child chain id.
*/
function _idFor(address manager) internal view returns (uint256 id) {
id = _ids[manager];
require(id != 0, "StakeManagerChildData: INVALID_MANAGER");
}

// Storage gap
// slither-disable-next-line unused-state,naming-convention
uint256[50] private __gap;
}
59 changes: 59 additions & 0 deletions contracts/root/staking/StakeManagerStakingData.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

/**
* @title StakeManagerStakingData
* @notice Holds all staking related data.
* Note that this is contract is designed to be included in StakeManager. It is upgradeable.
*/
abstract contract StakeManagerStakingData {
// slither-disable-next-line naming-convention
uint256 internal _totalStake;
// validator => child => amount
mapping(address => mapping(uint256 => uint256)) private _stakes;
// child chain id => total stake
mapping(uint256 => uint256) private _totalStakePerChild;
// validator address => stake across all child chains.
mapping(address => uint256) private _totalStakes;
// validator address => withdrawable stake.
mapping(address => uint256) private _withdrawableStakes;

function _addStake(address validator, uint256 id, uint256 amount) internal {
_stakes[validator][id] += amount;
_totalStakePerChild[id] += amount;
_totalStakes[validator] += amount;
_totalStake += amount;
}

function _removeStake(address validator, uint256 id, uint256 amount) internal {
_stakes[validator][id] -= amount;
_totalStakePerChild[id] -= amount;
_totalStakes[validator] -= amount;
_totalStake -= amount;
_withdrawableStakes[validator] += amount;
}

function _withdrawStake(address validator, uint256 amount) internal {
_withdrawableStakes[validator] -= amount;
}

function _withdrawableStakeOf(address validator) internal view returns (uint256 amount) {
amount = _withdrawableStakes[validator];
}

function _totalStakeOfChild(uint256 id) internal view returns (uint256 amount) {
amount = _totalStakePerChild[id];
}

function _stakeOf(address validator, uint256 id) internal view returns (uint256 amount) {
amount = _stakes[validator][id];
}

function _totalStakeOf(address validator) internal view returns (uint256 amount) {
amount = _totalStakes[validator];
}

// Storage gap
// slither-disable-next-line unused-state,naming-convention
uint256[50] private __gap;
}
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ function propose(address[] targets, uint256[] values, bytes[] calldatas, string



*See {IGovernor-propose}.*
*See {IGovernor-propose}. This function has opt-in frontrunning protection, described in {_isValidDescriptionForProposer}.*

#### Parameters

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ function propose(address[] targets, uint256[] values, bytes[] calldatas, string



*See {IGovernor-propose}.*
*See {IGovernor-propose}. This function has opt-in frontrunning protection, described in {_isValidDescriptionForProposer}.*

#### Parameters

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ function propose(address[] targets, uint256[] values, bytes[] calldatas, string



*See {IGovernor-propose}.*
*See {IGovernor-propose}. This function has opt-in frontrunning protection, described in {_isValidDescriptionForProposer}.*

#### Parameters

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ function propose(address[] targets, uint256[] values, bytes[] calldatas, string



*See {IGovernor-propose}.*
*See {IGovernor-propose}. This function has opt-in frontrunning protection, described in {_isValidDescriptionForProposer}.*

#### Parameters

Expand Down
12 changes: 0 additions & 12 deletions docs/lib/ChildManagerLib.md

This file was deleted.

12 changes: 0 additions & 12 deletions docs/lib/StakeManagerLib.md

This file was deleted.

Loading