Skip to content

Commit

Permalink
Merge pull request #188 from keep-network/chaosnet
Browse files Browse the repository at this point in the history
Chaosnet
  • Loading branch information
dimpar authored Sep 22, 2022
2 parents cb05e6e + 82d14df commit aaeab6f
Show file tree
Hide file tree
Showing 3 changed files with 344 additions and 17 deletions.
84 changes: 84 additions & 0 deletions contracts/Chaosnet.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
pragma solidity 0.8.9;

/// @title Chaosnet
/// @notice This is a beta staker program for stakers willing to go the extra
/// mile with monitoring, share their logs with the dev team, and allow to more
/// carefully monitor the bootstrapping network. As the network matures, the
/// beta program will be ended.
contract Chaosnet {
/// @notice Indicates if the chaosnet is active. The chaosnet is active
/// after the contract deployment and can be ended with a call to
/// `deactivateChaosnet()`. Once deactivated chaosnet can not be activated
/// again.
bool public isChaosnetActive;

/// @notice Indicates if the given operator is a beta operator for chaosnet.
mapping(address => bool) public isBetaOperator;

/// @notice Address controlling chaosnet status and beta operator addresses.
address public chaosnetOwner;

event BetaOperatorsAdded(address[] operators);

event ChaosnetOwnerRoleTransferred(
address oldChaosnetOwner,
address newChaosnetOwner
);

event ChaosnetDeactivated();

constructor() {
_transferChaosnetOwner(msg.sender);
isChaosnetActive = true;
}

modifier onlyChaosnetOwner() {
require(msg.sender == chaosnetOwner, "Not the chaosnet owner");
_;
}

modifier onlyOnChaosnet() {
require(isChaosnetActive, "Chaosnet is not active");
_;
}

/// @notice Adds beta operator to chaosnet. Can be called only by the
/// chaosnet owner when the chaosnet is active. Once the operator is added
/// as a beta operator, it can not be removed.
function addBetaOperators(address[] calldata operators)
public
onlyOnChaosnet
onlyChaosnetOwner
{
for (uint256 i = 0; i < operators.length; i++) {
isBetaOperator[operators[i]] = true;
}

emit BetaOperatorsAdded(operators);
}

/// @notice Deactivates the chaosnet. Can be called only by the chaosnet
/// owner. Once deactivated chaosnet can not be activated again.
function deactivateChaosnet() public onlyOnChaosnet onlyChaosnetOwner {
isChaosnetActive = false;
emit ChaosnetDeactivated();
}

/// @notice Transfers the chaosnet owner role to another non-zero address.
function transferChaosnetOwnerRole(address newChaosnetOwner)
public
onlyChaosnetOwner
{
require(
newChaosnetOwner != address(0),
"New chaosnet owner must not be zero address"
);
_transferChaosnetOwner(newChaosnetOwner);
}

function _transferChaosnetOwner(address newChaosnetOwner) internal {
address oldChaosnetOwner = chaosnetOwner;
chaosnetOwner = newChaosnetOwner;
emit ChaosnetOwnerRoleTransferred(oldChaosnetOwner, newChaosnetOwner);
}
}
17 changes: 15 additions & 2 deletions contracts/SortitionPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@ import "@openzeppelin/contracts/access/Ownable.sol";
import "./RNG.sol";
import "./SortitionTree.sol";
import "./Rewards.sol";
import "./Chaosnet.sol";

/// @title Sortition Pool
/// @notice A logarithmic data structure used to store the pool of eligible
/// operators weighted by their stakes. It allows to select a group of operators
/// based on the provided pseudo-random seed.
contract SortitionPool is SortitionTree, Rewards, Ownable, IReceiveApproval {
contract SortitionPool is
SortitionTree,
Rewards,
Ownable,
Chaosnet,
IReceiveApproval
{
using Branch for uint256;
using Leaf for uint256;
using Position for uint256;
Expand Down Expand Up @@ -98,7 +105,9 @@ contract SortitionPool is SortitionTree, Rewards, Ownable, IReceiveApproval {
}

/// @notice Inserts an operator to the pool. Reverts if the operator is
/// already present.
/// already present. Reverts if the operator is not eligible because of their
/// authorized stake. Reverts if the chaosnet is active and the operator is
/// not a beta operator.
/// @dev Can be called only by the contract owner.
/// @param operator Address of the inserted operator.
/// @param authorizedStake Inserted operator's authorized stake for the application.
Expand All @@ -110,6 +119,10 @@ contract SortitionPool is SortitionTree, Rewards, Ownable, IReceiveApproval {
uint256 weight = getWeight(authorizedStake);
require(weight > 0, "Operator not eligible");

if (isChaosnetActive) {
require(isBetaOperator[operator], "Not beta operator for chaosnet");
}

_insertOperator(operator, weight);
uint32 id = getOperatorID(operator);
Rewards.updateOperatorRewards(id, uint32(weight));
Expand Down
Loading

0 comments on commit aaeab6f

Please sign in to comment.