Skip to content

Commit aaeab6f

Browse files
authored
Merge pull request #188 from keep-network/chaosnet
Chaosnet
2 parents cb05e6e + 82d14df commit aaeab6f

3 files changed

Lines changed: 344 additions & 17 deletions

File tree

contracts/Chaosnet.sol

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
pragma solidity 0.8.9;
2+
3+
/// @title Chaosnet
4+
/// @notice This is a beta staker program for stakers willing to go the extra
5+
/// mile with monitoring, share their logs with the dev team, and allow to more
6+
/// carefully monitor the bootstrapping network. As the network matures, the
7+
/// beta program will be ended.
8+
contract Chaosnet {
9+
/// @notice Indicates if the chaosnet is active. The chaosnet is active
10+
/// after the contract deployment and can be ended with a call to
11+
/// `deactivateChaosnet()`. Once deactivated chaosnet can not be activated
12+
/// again.
13+
bool public isChaosnetActive;
14+
15+
/// @notice Indicates if the given operator is a beta operator for chaosnet.
16+
mapping(address => bool) public isBetaOperator;
17+
18+
/// @notice Address controlling chaosnet status and beta operator addresses.
19+
address public chaosnetOwner;
20+
21+
event BetaOperatorsAdded(address[] operators);
22+
23+
event ChaosnetOwnerRoleTransferred(
24+
address oldChaosnetOwner,
25+
address newChaosnetOwner
26+
);
27+
28+
event ChaosnetDeactivated();
29+
30+
constructor() {
31+
_transferChaosnetOwner(msg.sender);
32+
isChaosnetActive = true;
33+
}
34+
35+
modifier onlyChaosnetOwner() {
36+
require(msg.sender == chaosnetOwner, "Not the chaosnet owner");
37+
_;
38+
}
39+
40+
modifier onlyOnChaosnet() {
41+
require(isChaosnetActive, "Chaosnet is not active");
42+
_;
43+
}
44+
45+
/// @notice Adds beta operator to chaosnet. Can be called only by the
46+
/// chaosnet owner when the chaosnet is active. Once the operator is added
47+
/// as a beta operator, it can not be removed.
48+
function addBetaOperators(address[] calldata operators)
49+
public
50+
onlyOnChaosnet
51+
onlyChaosnetOwner
52+
{
53+
for (uint256 i = 0; i < operators.length; i++) {
54+
isBetaOperator[operators[i]] = true;
55+
}
56+
57+
emit BetaOperatorsAdded(operators);
58+
}
59+
60+
/// @notice Deactivates the chaosnet. Can be called only by the chaosnet
61+
/// owner. Once deactivated chaosnet can not be activated again.
62+
function deactivateChaosnet() public onlyOnChaosnet onlyChaosnetOwner {
63+
isChaosnetActive = false;
64+
emit ChaosnetDeactivated();
65+
}
66+
67+
/// @notice Transfers the chaosnet owner role to another non-zero address.
68+
function transferChaosnetOwnerRole(address newChaosnetOwner)
69+
public
70+
onlyChaosnetOwner
71+
{
72+
require(
73+
newChaosnetOwner != address(0),
74+
"New chaosnet owner must not be zero address"
75+
);
76+
_transferChaosnetOwner(newChaosnetOwner);
77+
}
78+
79+
function _transferChaosnetOwner(address newChaosnetOwner) internal {
80+
address oldChaosnetOwner = chaosnetOwner;
81+
chaosnetOwner = newChaosnetOwner;
82+
emit ChaosnetOwnerRoleTransferred(oldChaosnetOwner, newChaosnetOwner);
83+
}
84+
}

contracts/SortitionPool.sol

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,19 @@ import "@openzeppelin/contracts/access/Ownable.sol";
88
import "./RNG.sol";
99
import "./SortitionTree.sol";
1010
import "./Rewards.sol";
11+
import "./Chaosnet.sol";
1112

1213
/// @title Sortition Pool
1314
/// @notice A logarithmic data structure used to store the pool of eligible
1415
/// operators weighted by their stakes. It allows to select a group of operators
1516
/// based on the provided pseudo-random seed.
16-
contract SortitionPool is SortitionTree, Rewards, Ownable, IReceiveApproval {
17+
contract SortitionPool is
18+
SortitionTree,
19+
Rewards,
20+
Ownable,
21+
Chaosnet,
22+
IReceiveApproval
23+
{
1724
using Branch for uint256;
1825
using Leaf for uint256;
1926
using Position for uint256;
@@ -98,7 +105,9 @@ contract SortitionPool is SortitionTree, Rewards, Ownable, IReceiveApproval {
98105
}
99106

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

122+
if (isChaosnetActive) {
123+
require(isBetaOperator[operator], "Not beta operator for chaosnet");
124+
}
125+
113126
_insertOperator(operator, weight);
114127
uint32 id = getOperatorID(operator);
115128
Rewards.updateOperatorRewards(id, uint32(weight));

0 commit comments

Comments
 (0)