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

Chaosnet #188

Merged
merged 4 commits into from
Sep 22, 2022
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
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
nkuba marked this conversation as resolved.
Show resolved Hide resolved
/// 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;
dimpar marked this conversation as resolved.
Show resolved Hide resolved

/// @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)
dimpar marked this conversation as resolved.
Show resolved Hide resolved
public
onlyOnChaosnet
onlyChaosnetOwner
{
for (uint256 i = 0; i < operators.length; i++) {
isBetaOperator[operators[i]] = true;
dimpar marked this conversation as resolved.
Show resolved Hide resolved
}

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