@keep-network/tbtc-v2 1.8.0-dev.0 → 1.8.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/artifacts/BLS.json +6 -6
  2. package/artifacts/Bank.json +11 -11
  3. package/artifacts/BeaconAuthorization.json +11 -11
  4. package/artifacts/BeaconDkg.json +9 -9
  5. package/artifacts/BeaconDkgValidator.json +12 -12
  6. package/artifacts/BeaconInactivity.json +11 -11
  7. package/artifacts/BeaconSortitionPool.json +16 -16
  8. package/artifacts/Bridge.json +32 -32
  9. package/artifacts/BridgeGovernance.json +14 -14
  10. package/artifacts/BridgeGovernanceParameters.json +6 -6
  11. package/artifacts/Deposit.json +6 -6
  12. package/artifacts/DepositSweep.json +6 -6
  13. package/artifacts/DonationVault.json +7 -7
  14. package/artifacts/EcdsaDkgValidator.json +7 -7
  15. package/artifacts/EcdsaInactivity.json +6 -6
  16. package/artifacts/EcdsaSortitionPool.json +16 -16
  17. package/artifacts/Fraud.json +6 -6
  18. package/artifacts/LightRelay.json +11 -11
  19. package/artifacts/LightRelayMaintainerProxy.json +13 -13
  20. package/artifacts/MaintainerProxy.json +13 -13
  21. package/artifacts/MovingFunds.json +6 -6
  22. package/artifacts/NuCypherToken.json +11 -11
  23. package/artifacts/RandomBeacon.json +126 -126
  24. package/artifacts/RandomBeaconChaosnet.json +13 -13
  25. package/artifacts/RandomBeaconGovernance.json +66 -66
  26. package/artifacts/Redemption.json +6 -6
  27. package/artifacts/RedemptionWatchtower.json +26 -26
  28. package/artifacts/ReimbursementPool.json +19 -19
  29. package/artifacts/T.json +11 -11
  30. package/artifacts/TBTC.json +11 -11
  31. package/artifacts/TBTCToken.json +11 -11
  32. package/artifacts/TBTCVault.json +14 -14
  33. package/artifacts/Timelock.json +80 -80
  34. package/artifacts/TokenStaking.json +156 -308
  35. package/artifacts/TokenholderGovernor.json +47 -47
  36. package/artifacts/TokenholderTimelock.json +36 -36
  37. package/artifacts/VendingMachine.json +13 -13
  38. package/artifacts/VendingMachineNuCypher.json +9 -9
  39. package/artifacts/VendingMachineV2.json +13 -13
  40. package/artifacts/VendingMachineV3.json +13 -13
  41. package/artifacts/WalletProposalValidator.json +7 -7
  42. package/artifacts/WalletRegistry.json +31 -31
  43. package/artifacts/WalletRegistryGovernance.json +56 -56
  44. package/artifacts/Wallets.json +6 -6
  45. package/export/artifacts/@keep-network/ecdsa/contracts/WalletRegistry.sol/WalletRegistry.json +4999 -4814
  46. package/export/typechain/factories/EcdsaAuthorization__factory.js +1 -1
  47. package/export/typechain/factories/IStaking__factory.js +24 -103
  48. package/export/typechain/factories/WalletRegistry__factory.js +1 -1
  49. package/package.json +4 -4
  50. package/artifacts/KeepRegistry.json +0 -99
  51. package/artifacts/KeepStake.json +0 -286
  52. package/artifacts/KeepToken.json +0 -711
  53. package/artifacts/KeepTokenStaking.json +0 -483
  54. package/artifacts/NuCypherStakingEscrow.json +0 -287
  55. package/artifacts/VendingMachineKeep.json +0 -400
@@ -1,5 +1,5 @@
1
1
  {
2
- "address": "0x505d59ffFd312983Cc0eD114d7F117B91520d742",
2
+ "address": "0x5C7c905B505f0Cf40Ab6600d05e677F717916F6B",
3
3
  "abi": [
4
4
  {
5
5
  "anonymous": false,
@@ -171,27 +171,27 @@
171
171
  "type": "event"
172
172
  }
173
173
  ],
174
- "transactionHash": "0x203c536bcaa71cca909d87ad6f04f0f746949582ac44b31a7152e5976acd7907",
174
+ "transactionHash": "0x826ba68890e0e4bb159956444552784d4c3501fb5c59428120ac27cba2d64055",
175
175
  "receipt": {
176
176
  "to": null,
177
177
  "from": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
178
- "contractAddress": "0x505d59ffFd312983Cc0eD114d7F117B91520d742",
178
+ "contractAddress": "0x5C7c905B505f0Cf40Ab6600d05e677F717916F6B",
179
179
  "transactionIndex": 0,
180
- "gasUsed": "1295311",
180
+ "gasUsed": "1295299",
181
181
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
182
- "blockHash": "0xcc4a8b28ecc962c20fbfb40dfe16a90b2d9d17b126048c2e1c29df011d58b0f7",
183
- "transactionHash": "0x203c536bcaa71cca909d87ad6f04f0f746949582ac44b31a7152e5976acd7907",
182
+ "blockHash": "0x384565c79aaecb76d2e6a8b86afc9092ea78d412d0f53036a55accad45d0b368",
183
+ "transactionHash": "0x826ba68890e0e4bb159956444552784d4c3501fb5c59428120ac27cba2d64055",
184
184
  "logs": [],
185
- "blockNumber": 27,
186
- "cumulativeGasUsed": "1295311",
185
+ "blockNumber": 18,
186
+ "cumulativeGasUsed": "1295299",
187
187
  "status": 1,
188
188
  "byzantium": true
189
189
  },
190
190
  "args": [],
191
191
  "numDeployments": 1,
192
- "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"stakingProvider\",\"type\":\"address\"}],\"name\":\"AuthorizationDecreaseApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"stakingProvider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"fromAmount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"toAmount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"decreasingAt\",\"type\":\"uint64\"}],\"name\":\"AuthorizationDecreaseRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"stakingProvider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"fromAmount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"toAmount\",\"type\":\"uint96\"}],\"name\":\"AuthorizationIncreased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"stakingProvider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"fromAmount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"toAmount\",\"type\":\"uint96\"}],\"name\":\"InvoluntaryAuthorizationDecreaseFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"stakingProvider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"OperatorJoinedSortitionPool\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"stakingProvider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"OperatorRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"stakingProvider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"OperatorStatusUpdated\",\"type\":\"event\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"authorizationDecreaseRequested(BeaconAuthorization.Data storage,address,uint96,uint96)\":{\"details\":\"Should only be callable by T staking contract.\"},\"authorizationIncreased(BeaconAuthorization.Data storage,address,uint96,uint96)\":{\"details\":\"Should only be callable by T staking contract.\"},\"eligibleStake(BeaconAuthorization.Data storage,IStaking,address)\":{\"details\":\"This function can be exposed to the public in contrast to the second variant accepting `decreasingBy` as a parameter.\"},\"eligibleStake(BeaconAuthorization.Data storage,IStaking,address,uint96)\":{\"details\":\"This function is not intended to be exposes to the public. `decreasingBy` must be fetched from `pendingDecreases` mapping and it is passed as a parameter to optimize gas usage of functions that call `eligibleStake` and need to use `AuthorizationDecrease` fetched from `pendingDecreases` for some additional logic.\"},\"involuntaryAuthorizationDecrease(BeaconAuthorization.Data storage,IStaking,SortitionPool,address,uint96,uint96)\":{\"details\":\"Should only be callable by T staking contract.\"},\"setParameters(BeaconAuthorization.Data storage,uint96,uint64,uint64)\":{\"params\":{\"_authorizationDecreaseChangePeriod\":\"New value of the authorization decrease change period. It is the time in seconds, before authorization decrease delay end, during which the pending authorization decrease request can be overwritten. If set to 0, pending authorization decrease request can not be overwritten until the entire `authorizationDecreaseDelay` ends. If set to value equal `authorizationDecreaseDelay`, request can always be overwritten.\",\"_authorizationDecreaseDelay\":\"New value of the authorization decrease delay. It is the time in seconds that needs to pass between the time authorization decrease is requested and the time the authorization decrease can be approved, no matter the authorization decrease amount.\",\"_minimumAuthorization\":\"New value of the minimum authorization for the beacon. Without at least the minimum authorization, staking provider is not eligible to join and operate in the network.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"approveAuthorizationDecrease(BeaconAuthorization.Data storage,IStaking,address)\":{\"notice\":\"Approves the previously registered authorization decrease request. Reverts if authorization decrease delay have not passed yet or if the authorization decrease was not requested for the given staking provider.\"},\"authorizationDecreaseRequested(BeaconAuthorization.Data storage,address,uint96,uint96)\":{\"notice\":\"Used by T staking contract to inform the beacon that the authorization decrease for the given staking provider has been requested. Reverts if the amount after deauthorization would be non-zero and lower than the minimum authorization. Reverts if another authorization decrease request is pending for the staking provider and not enough time passed since the original request (see `authorizationDecreaseChangePeriod`). If the operator is not known (`registerOperator` was not called) it lets to `approveAuthorizationDecrease` immediately. If the operator is known (`registerOperator` was called), the operator needs to update state of the sortition pool with a call to `joinSortitionPool` or `updateOperatorStatus`. After the sortition pool state is in sync, authorization decrease delay starts. After authorization decrease delay passes, authorization decrease request needs to be approved with a call to `approveAuthorizationDecrease` function. If there is a pending authorization decrease request, it is overwritten, but only if enough time passed since the original request. Otherwise, the function reverts.\"},\"authorizationIncreased(BeaconAuthorization.Data storage,address,uint96,uint96)\":{\"notice\":\"Used by T staking contract to inform the beacon that the authorized stake amount for the given staking provider increased. Reverts if the authorization amount is below the minimum. The function is not updating the sortition pool. Sortition pool state needs to be updated by the operator with a call to `joinSortitionPool` or `updateOperatorStatus`.\"},\"eligibleStake(BeaconAuthorization.Data storage,IStaking,address)\":{\"notice\":\"Returns the current value of the staking provider's eligible stake. Eligible stake is defined as the currently authorized stake minus the pending authorization decrease. Eligible stake is what is used for operator's weight in the pool. If the authorized stake minus the pending authorization decrease is below the minimum authorization, eligible stake is 0.\"},\"eligibleStake(BeaconAuthorization.Data storage,IStaking,address,uint96)\":{\"notice\":\"Returns the current value of the staking provider's eligible stake. Eligible stake is defined as the currently authorized stake minus the pending authorization decrease. Eligible stake is what is used for operator's weight in the pool. If the authorized stake minus the pending authorization decrease is below the minimum authorization, eligible stake is 0.\"},\"involuntaryAuthorizationDecrease(BeaconAuthorization.Data storage,IStaking,SortitionPool,address,uint96,uint96)\":{\"notice\":\"Used by T staking contract to inform the beacon the authorization has been decreased for the given staking provider involuntarily, as a result of slashing. If the operator is not known (`registerOperator` was not called) the function does nothing. The operator was never in a sortition pool so there is nothing to update. If the operator is known, sortition pool is unlocked, and the operator is in the sortition pool, the sortition pool state is updated. If the sortition pool is locked, update needs to be postponed. Every other staker is incentivized to call `updateOperatorStatus` for the problematic operator to increase their own rewards in the pool.\"},\"isOperatorUpToDate(BeaconAuthorization.Data storage,IStaking,SortitionPool,address)\":{\"notice\":\"Checks if the operator's authorized stake is in sync with operator's weight in the sortition pool. If the operator is not in the sortition pool and their authorized stake is non-zero, function returns false.\"},\"joinSortitionPool(BeaconAuthorization.Data storage,IStaking,SortitionPool)\":{\"notice\":\"Lets the operator join the sortition pool. The operator address must be known - before calling this function, it has to be appointed by the staking provider by calling `registerOperator`. Also, the operator must have the minimum authorization required by the beacon. Function reverts if there is no minimum stake authorized or if the operator is not known. If there was an authorization decrease requested, it is activated by starting the authorization decrease delay.\"},\"pendingAuthorizationDecrease(BeaconAuthorization.Data storage,address)\":{\"notice\":\"Returns the amount of stake that is pending authorization decrease for the given staking provider. If no authorization decrease has been requested, returns zero.\"},\"registerOperator(BeaconAuthorization.Data storage,address)\":{\"notice\":\"Used by staking provider to set operator address that will operate a node. The given staking provider can set operator address only one time. The operator address can not be changed and must be unique. Reverts if the operator is already set for the staking provider or if the operator address is already in use. Reverts if there is a pending authorization decrease for the staking provider.\"},\"remainingAuthorizationDecreaseDelay(BeaconAuthorization.Data storage,address)\":{\"notice\":\"Returns the remaining time in seconds that needs to pass before the requested authorization decrease can be approved. If the sortition pool state was not updated yet by the operator after requesting the authorization decrease, returns `type(uint64).max`.\"},\"setParameters(BeaconAuthorization.Data storage,uint96,uint64,uint64)\":{\"notice\":\"Updates authorization-related parameters.\"},\"updateOperatorStatus(BeaconAuthorization.Data storage,IStaking,SortitionPool,address)\":{\"notice\":\"Updates status of the operator in the sortition pool. If there was an authorization decrease requested, it is activated by starting the authorization decrease delay. Function reverts if the operator is not known.\"}},\"notice\":\"Library managing the state of stake authorizations for the operator contract and the presence of operators in the sortition pool based on the stake authorized for them.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/libraries/BeaconAuthorization.sol\":\"BeaconAuthorization\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@keep-network/sortition-pools/contracts/Branch.sol\":{\"content\":\"pragma solidity 0.8.17;\\n\\nimport \\\"./Constants.sol\\\";\\n\\n/// @notice The implicit 8-ary trees of the sortition pool\\n/// rely on packing 8 \\\"slots\\\" of 32-bit values into each uint256.\\n/// The Branch library permits efficient calculations on these slots.\\nlibrary Branch {\\n /// @notice Calculate the right shift required\\n /// to make the 32 least significant bits of an uint256\\n /// be the bits of the `position`th slot\\n /// when treating the uint256 as a uint32[8].\\n ///\\n /// @dev Not used for efficiency reasons,\\n /// but left to illustrate the meaning of a common pattern.\\n /// I wish solidity had macros, even C macros.\\n function slotShift(uint256 position) internal pure returns (uint256) {\\n unchecked {\\n return position * Constants.SLOT_WIDTH;\\n }\\n }\\n\\n /// @notice Return the `position`th slot of the `node`,\\n /// treating `node` as a uint32[32].\\n function getSlot(uint256 node, uint256 position)\\n internal\\n pure\\n returns (uint256)\\n {\\n unchecked {\\n uint256 shiftBits = position * Constants.SLOT_WIDTH;\\n // Doing a bitwise AND with `SLOT_MAX`\\n // clears all but the 32 least significant bits.\\n // Because of the right shift by `slotShift(position)` bits,\\n // those 32 bits contain the 32 bits in the `position`th slot of `node`.\\n return (node >> shiftBits) & Constants.SLOT_MAX;\\n }\\n }\\n\\n /// @notice Return `node` with the `position`th slot set to zero.\\n function clearSlot(uint256 node, uint256 position)\\n internal\\n pure\\n returns (uint256)\\n {\\n unchecked {\\n uint256 shiftBits = position * Constants.SLOT_WIDTH;\\n // Shifting `SLOT_MAX` left by `slotShift(position)` bits\\n // gives us a number where all bits of the `position`th slot are set,\\n // and all other bits are unset.\\n //\\n // Using a bitwise NOT on this number,\\n // we get a uint256 where all bits are set\\n // except for those of the `position`th slot.\\n //\\n // Bitwise ANDing the original `node` with this number\\n // sets the bits of `position`th slot to zero,\\n // leaving all other bits unchanged.\\n return node & ~(Constants.SLOT_MAX << shiftBits);\\n }\\n }\\n\\n /// @notice Return `node` with the `position`th slot set to `weight`.\\n ///\\n /// @param weight The weight of of the node.\\n /// Safely truncated to a 32-bit number,\\n /// but this should never be called with an overflowing weight regardless.\\n function setSlot(\\n uint256 node,\\n uint256 position,\\n uint256 weight\\n ) internal pure returns (uint256) {\\n unchecked {\\n uint256 shiftBits = position * Constants.SLOT_WIDTH;\\n // Clear the `position`th slot like in `clearSlot()`.\\n uint256 clearedNode = node & ~(Constants.SLOT_MAX << shiftBits);\\n // Bitwise AND `weight` with `SLOT_MAX`\\n // to clear all but the 32 least significant bits.\\n //\\n // Shift this left by `slotShift(position)` bits\\n // to obtain a uint256 with all bits unset\\n // except in the `position`th slot\\n // which contains the 32-bit value of `weight`.\\n uint256 shiftedWeight = (weight & Constants.SLOT_MAX) << shiftBits;\\n // When we bitwise OR these together,\\n // all other slots except the `position`th one come from the left argument,\\n // and the `position`th gets filled with `weight` from the right argument.\\n return clearedNode | shiftedWeight;\\n }\\n }\\n\\n /// @notice Calculate the summed weight of all slots in the `node`.\\n function sumWeight(uint256 node) internal pure returns (uint256 sum) {\\n unchecked {\\n sum = node & Constants.SLOT_MAX;\\n // Iterate through each slot\\n // by shifting `node` right in increments of 32 bits,\\n // and adding the 32 least significant bits to the `sum`.\\n uint256 newNode = node >> Constants.SLOT_WIDTH;\\n while (newNode > 0) {\\n sum += (newNode & Constants.SLOT_MAX);\\n newNode = newNode >> Constants.SLOT_WIDTH;\\n }\\n return sum;\\n }\\n }\\n\\n /// @notice Pick a slot in `node` that corresponds to `index`.\\n /// Treats the node like an array of virtual stakers,\\n /// the number of virtual stakers in each slot corresponding to its weight,\\n /// and picks which slot contains the `index`th virtual staker.\\n ///\\n /// @dev Requires that `index` be lower than `sumWeight(node)`.\\n /// However, this is not enforced for performance reasons.\\n /// If `index` exceeds the permitted range,\\n /// `pickWeightedSlot()` returns the rightmost slot\\n /// and an excessively high `newIndex`.\\n ///\\n /// @return slot The slot of `node` containing the `index`th virtual staker.\\n ///\\n /// @return newIndex The index of the `index`th virtual staker of `node`\\n /// within the returned slot.\\n function pickWeightedSlot(uint256 node, uint256 index)\\n internal\\n pure\\n returns (uint256 slot, uint256 newIndex)\\n {\\n unchecked {\\n newIndex = index;\\n uint256 newNode = node;\\n uint256 currentSlotWeight = newNode & Constants.SLOT_MAX;\\n while (newIndex >= currentSlotWeight) {\\n newIndex -= currentSlotWeight;\\n slot++;\\n newNode = newNode >> Constants.SLOT_WIDTH;\\n currentSlotWeight = newNode & Constants.SLOT_MAX;\\n }\\n return (slot, newIndex);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa7fb1c9c9789f30493e9a40e24a24f46875dc5e7630b4f67478167759f6d1882\"},\"@keep-network/sortition-pools/contracts/Chaosnet.sol\":{\"content\":\"pragma solidity 0.8.17;\\n\\n/// @title Chaosnet\\n/// @notice This is a beta staker program for stakers willing to go the extra\\n/// mile with monitoring, share their logs with the dev team, and allow to more\\n/// carefully monitor the bootstrapping network. As the network matures, the\\n/// beta program will be ended.\\ncontract Chaosnet {\\n /// @notice Indicates if the chaosnet is active. The chaosnet is active\\n /// after the contract deployment and can be ended with a call to\\n /// `deactivateChaosnet()`. Once deactivated chaosnet can not be activated\\n /// again.\\n bool public isChaosnetActive;\\n\\n /// @notice Indicates if the given operator is a beta operator for chaosnet.\\n mapping(address => bool) public isBetaOperator;\\n\\n /// @notice Address controlling chaosnet status and beta operator addresses.\\n address public chaosnetOwner;\\n\\n event BetaOperatorsAdded(address[] operators);\\n\\n event ChaosnetOwnerRoleTransferred(\\n address oldChaosnetOwner,\\n address newChaosnetOwner\\n );\\n\\n event ChaosnetDeactivated();\\n\\n constructor() {\\n _transferChaosnetOwner(msg.sender);\\n isChaosnetActive = true;\\n }\\n\\n modifier onlyChaosnetOwner() {\\n require(msg.sender == chaosnetOwner, \\\"Not the chaosnet owner\\\");\\n _;\\n }\\n\\n modifier onlyOnChaosnet() {\\n require(isChaosnetActive, \\\"Chaosnet is not active\\\");\\n _;\\n }\\n\\n /// @notice Adds beta operator to chaosnet. Can be called only by the\\n /// chaosnet owner when the chaosnet is active. Once the operator is added\\n /// as a beta operator, it can not be removed.\\n function addBetaOperators(address[] calldata operators)\\n public\\n onlyOnChaosnet\\n onlyChaosnetOwner\\n {\\n for (uint256 i = 0; i < operators.length; i++) {\\n isBetaOperator[operators[i]] = true;\\n }\\n\\n emit BetaOperatorsAdded(operators);\\n }\\n\\n /// @notice Deactivates the chaosnet. Can be called only by the chaosnet\\n /// owner. Once deactivated chaosnet can not be activated again.\\n function deactivateChaosnet() public onlyOnChaosnet onlyChaosnetOwner {\\n isChaosnetActive = false;\\n emit ChaosnetDeactivated();\\n }\\n\\n /// @notice Transfers the chaosnet owner role to another non-zero address.\\n function transferChaosnetOwnerRole(address newChaosnetOwner)\\n public\\n onlyChaosnetOwner\\n {\\n require(\\n newChaosnetOwner != address(0),\\n \\\"New chaosnet owner must not be zero address\\\"\\n );\\n _transferChaosnetOwner(newChaosnetOwner);\\n }\\n\\n function _transferChaosnetOwner(address newChaosnetOwner) internal {\\n address oldChaosnetOwner = chaosnetOwner;\\n chaosnetOwner = newChaosnetOwner;\\n emit ChaosnetOwnerRoleTransferred(oldChaosnetOwner, newChaosnetOwner);\\n }\\n}\\n\",\"keccak256\":\"0xeaf7bdd5626f88c329793a012621039692ce1b6e1f13013997ddb13d7e3032df\"},\"@keep-network/sortition-pools/contracts/Constants.sol\":{\"content\":\"pragma solidity 0.8.17;\\n\\nlibrary Constants {\\n ////////////////////////////////////////////////////////////////////////////\\n // Parameters for configuration\\n\\n // How many bits a position uses per level of the tree;\\n // each branch of the tree contains 2**SLOT_BITS slots.\\n uint256 constant SLOT_BITS = 3;\\n uint256 constant LEVELS = 7;\\n ////////////////////////////////////////////////////////////////////////////\\n\\n ////////////////////////////////////////////////////////////////////////////\\n // Derived constants, do not touch\\n uint256 constant SLOT_COUNT = 2**SLOT_BITS;\\n uint256 constant SLOT_WIDTH = 256 / SLOT_COUNT;\\n uint256 constant LAST_SLOT = SLOT_COUNT - 1;\\n uint256 constant SLOT_MAX = (2**SLOT_WIDTH) - 1;\\n uint256 constant POOL_CAPACITY = SLOT_COUNT**LEVELS;\\n\\n uint256 constant ID_WIDTH = SLOT_WIDTH;\\n uint256 constant ID_MAX = SLOT_MAX;\\n\\n uint256 constant BLOCKHEIGHT_WIDTH = 96 - ID_WIDTH;\\n uint256 constant BLOCKHEIGHT_MAX = (2**BLOCKHEIGHT_WIDTH) - 1;\\n\\n uint256 constant SLOT_POINTER_MAX = (2**SLOT_BITS) - 1;\\n uint256 constant LEAF_FLAG = 1 << 255;\\n\\n uint256 constant WEIGHT_WIDTH = 256 / SLOT_COUNT;\\n ////////////////////////////////////////////////////////////////////////////\\n}\\n\",\"keccak256\":\"0xaef690ced707935745ff1482b7bb9bd9eb77bf6a39c717465e64cf12db8a7d39\"},\"@keep-network/sortition-pools/contracts/Leaf.sol\":{\"content\":\"pragma solidity 0.8.17;\\n\\nimport \\\"./Constants.sol\\\";\\n\\nlibrary Leaf {\\n function make(\\n address _operator,\\n uint256 _creationBlock,\\n uint256 _id\\n ) internal pure returns (uint256) {\\n assert(_creationBlock <= type(uint64).max);\\n assert(_id <= type(uint32).max);\\n // Converting a bytesX type into a larger type\\n // adds zero bytes on the right.\\n uint256 op = uint256(bytes32(bytes20(_operator)));\\n // Bitwise AND the id to erase\\n // all but the 32 least significant bits\\n uint256 uid = _id & Constants.ID_MAX;\\n // Erase all but the 64 least significant bits,\\n // then shift left by 32 bits to make room for the id\\n uint256 cb = (_creationBlock & Constants.BLOCKHEIGHT_MAX) <<\\n Constants.ID_WIDTH;\\n // Bitwise OR them all together to get\\n // [address operator || uint64 creationBlock || uint32 id]\\n return (op | cb | uid);\\n }\\n\\n function operator(uint256 leaf) internal pure returns (address) {\\n // Converting a bytesX type into a smaller type\\n // truncates it on the right.\\n return address(bytes20(bytes32(leaf)));\\n }\\n\\n /// @notice Return the block number the leaf was created in.\\n function creationBlock(uint256 leaf) internal pure returns (uint256) {\\n return ((leaf >> Constants.ID_WIDTH) & Constants.BLOCKHEIGHT_MAX);\\n }\\n\\n function id(uint256 leaf) internal pure returns (uint32) {\\n // Id is stored in the 32 least significant bits.\\n // Bitwise AND ensures that we only get the contents of those bits.\\n return uint32(leaf & Constants.ID_MAX);\\n }\\n}\\n\",\"keccak256\":\"0xbd107a1a43e48884885e5e966ffcbcd8fa5e89863715d717bb4006e9f89cdc2b\"},\"@keep-network/sortition-pools/contracts/Position.sol\":{\"content\":\"pragma solidity 0.8.17;\\n\\nimport \\\"./Constants.sol\\\";\\n\\nlibrary Position {\\n // Return the last 3 bits of a position number,\\n // corresponding to its slot in its parent\\n function slot(uint256 a) internal pure returns (uint256) {\\n return a & Constants.SLOT_POINTER_MAX;\\n }\\n\\n // Return the parent of a position number\\n function parent(uint256 a) internal pure returns (uint256) {\\n return a >> Constants.SLOT_BITS;\\n }\\n\\n // Return the location of the child of a at the given slot\\n function child(uint256 a, uint256 s) internal pure returns (uint256) {\\n return (a << Constants.SLOT_BITS) | (s & Constants.SLOT_POINTER_MAX); // slot(s)\\n }\\n\\n // Return the uint p as a flagged position uint:\\n // the least significant 21 bits contain the position\\n // and the 22nd bit is set as a flag\\n // to distinguish the position 0x000000 from an empty field.\\n function setFlag(uint256 p) internal pure returns (uint256) {\\n return p | Constants.LEAF_FLAG;\\n }\\n\\n // Turn a flagged position into an unflagged position\\n // by removing the flag at the 22nd least significant bit.\\n //\\n // We shouldn't _actually_ need this\\n // as all position-manipulating code should ignore non-position bits anyway\\n // but it's cheap to call so might as well do it.\\n function unsetFlag(uint256 p) internal pure returns (uint256) {\\n return p & (~Constants.LEAF_FLAG);\\n }\\n}\\n\",\"keccak256\":\"0xd3a927908080ac21353a92a6bce3d69e94a5c30f6b51f16b271b6cc679f110e2\"},\"@keep-network/sortition-pools/contracts/RNG.sol\":{\"content\":\"pragma solidity 0.8.17;\\n\\nimport \\\"./Leaf.sol\\\";\\nimport \\\"./Constants.sol\\\";\\n\\nlibrary RNG {\\n /// @notice Get an index in the range `[0 .. range-1]`\\n /// and the new state of the RNG,\\n /// using the provided `state` of the RNG.\\n ///\\n /// @param range The upper bound of the index, exclusive.\\n ///\\n /// @param state The previous state of the RNG.\\n /// The initial state needs to be obtained\\n /// from a trusted randomness oracle (the random beacon),\\n /// or from a chain of earlier calls to `RNG.getIndex()`\\n /// on an originally trusted seed.\\n ///\\n /// @dev Calculates the number of bits required for the desired range,\\n /// takes the least significant bits of `state`\\n /// and checks if the obtained index is within the desired range.\\n /// The original state is hashed with `keccak256` to get a new state.\\n /// If the index is outside the range,\\n /// the function retries until it gets a suitable index.\\n ///\\n /// @return index A random integer between `0` and `range - 1`, inclusive.\\n ///\\n /// @return newState The new state of the RNG.\\n /// When `getIndex()` is called one or more times,\\n /// care must be taken to always use the output `state`\\n /// of the most recent call as the input `state` of a subsequent call.\\n /// At the end of a transaction calling `RNG.getIndex()`,\\n /// the previous stored state must be overwritten with the latest output.\\n function getIndex(\\n uint256 range,\\n bytes32 state,\\n uint256 bits\\n ) internal view returns (uint256, bytes32) {\\n bool found = false;\\n uint256 index = 0;\\n bytes32 newState = state;\\n while (!found) {\\n index = truncate(bits, uint256(newState));\\n newState = keccak256(abi.encodePacked(newState, address(this)));\\n if (index < range) {\\n found = true;\\n }\\n }\\n return (index, newState);\\n }\\n\\n /// @notice Calculate how many bits are required\\n /// for an index in the range `[0 .. range-1]`.\\n ///\\n /// @param range The upper bound of the desired range, exclusive.\\n ///\\n /// @return uint The smallest number of bits\\n /// that can contain the number `range-1`.\\n function bitsRequired(uint256 range) internal pure returns (uint256) {\\n unchecked {\\n if (range == 1) {\\n return 0;\\n }\\n\\n uint256 bits = Constants.WEIGHT_WIDTH - 1;\\n\\n // Left shift by `bits`,\\n // so we have a 1 in the (bits + 1)th least significant bit\\n // and 0 in other bits.\\n // If this number is equal or greater than `range`,\\n // the range [0, range-1] fits in `bits` bits.\\n //\\n // Because we loop from high bits to low bits,\\n // we find the highest number of bits that doesn't fit the range,\\n // and return that number + 1.\\n while (1 << bits >= range) {\\n bits--;\\n }\\n\\n return bits + 1;\\n }\\n }\\n\\n /// @notice Truncate `input` to the `bits` least significant bits.\\n function truncate(uint256 bits, uint256 input)\\n internal\\n pure\\n returns (uint256)\\n {\\n unchecked {\\n return input & ((1 << bits) - 1);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x67f87f589cd5123ffa32f883ea2f09b0e56258508bae82b8c655b3c27c71eb5e\"},\"@keep-network/sortition-pools/contracts/Rewards.sol\":{\"content\":\"pragma solidity 0.8.17;\\n\\n/// @title Rewards\\n/// @notice Rewards are allocated proportionally to operators\\n/// present in the pool at payout based on their weight in the pool.\\n///\\n/// To facilitate this, we use a global accumulator value\\n/// to track the total rewards one unit of weight would've earned\\n/// since the creation of the pool.\\n///\\n/// Whenever a reward is paid, the accumulator is increased\\n/// by the size of the reward divided by the total weight\\n/// of all eligible operators in the pool.\\n///\\n/// Each operator has an individual accumulator value,\\n/// set to equal the global accumulator when the operator joins the pool.\\n/// This accumulator reflects the amount of rewards\\n/// that have already been accounted for with that operator.\\n///\\n/// Whenever an operator's weight in the pool changes,\\n/// we can update the amount of rewards the operator has earned\\n/// by subtracting the operator's accumulator from the global accumulator.\\n/// This gives us the amount of rewards one unit of weight has earned\\n/// since the last time the operator's rewards have been updated.\\n/// Then we multiply that by the operator's previous (pre-change) weight\\n/// to determine how much rewards in total the operator has earned,\\n/// and add this to the operator's earned rewards.\\n/// Finally, we set the operator's accumulator to the global accumulator value.\\ncontract Rewards {\\n struct OperatorRewards {\\n // The state of the global accumulator\\n // when the operator's rewards were last updated\\n uint96 accumulated;\\n // The amount of rewards collected by the operator after the latest update.\\n // The amount the operator could withdraw may equal `available`\\n // or it may be greater, if more rewards have been paid in since then.\\n // To evaulate the most recent amount including rewards potentially paid\\n // since the last update, use `availableRewards` function.\\n uint96 available;\\n // If nonzero, the operator is ineligible for rewards\\n // and may only re-enable rewards after the specified timestamp.\\n // XXX: unsigned 32-bit integer unix seconds, will break around 2106\\n uint32 ineligibleUntil;\\n // Locally cached weight of the operator,\\n // used to reduce the cost of setting operators ineligible.\\n uint32 weight;\\n }\\n\\n // The global accumulator of how much rewards\\n // a hypothetical operator of weight 1 would have earned\\n // since the creation of the pool.\\n uint96 internal globalRewardAccumulator;\\n // If the amount of reward tokens paid in\\n // does not divide cleanly by pool weight,\\n // the difference is recorded as rounding dust\\n // and added to the next reward.\\n uint96 internal rewardRoundingDust;\\n\\n // The amount of rewards that would've been earned by ineligible operators\\n // had they not been ineligible.\\n uint96 public ineligibleEarnedRewards;\\n\\n // Ineligibility times are calculated from this offset,\\n // set at contract creation.\\n uint256 internal immutable ineligibleOffsetStart;\\n\\n mapping(uint32 => OperatorRewards) internal operatorRewards;\\n\\n constructor() {\\n // solhint-disable-next-line not-rely-on-time\\n ineligibleOffsetStart = block.timestamp;\\n }\\n\\n /// @notice Return whether the operator is eligible for rewards or not.\\n function isEligibleForRewards(uint32 operator) internal view returns (bool) {\\n return operatorRewards[operator].ineligibleUntil == 0;\\n }\\n\\n /// @notice Return the time the operator's reward eligibility can be restored.\\n function rewardsEligibilityRestorableAt(uint32 operator)\\n internal\\n view\\n returns (uint256)\\n {\\n uint32 until = operatorRewards[operator].ineligibleUntil;\\n require(until != 0, \\\"Operator already eligible\\\");\\n return (uint256(until) + ineligibleOffsetStart);\\n }\\n\\n /// @notice Return whether the operator is able to restore their eligibility\\n /// for rewards right away.\\n function canRestoreRewardEligibility(uint32 operator)\\n internal\\n view\\n returns (bool)\\n {\\n // solhint-disable-next-line not-rely-on-time\\n return rewardsEligibilityRestorableAt(operator) <= block.timestamp;\\n }\\n\\n /// @notice Internal function for updating the global state of rewards.\\n function addRewards(uint96 rewardAmount, uint32 currentPoolWeight) internal {\\n require(currentPoolWeight > 0, \\\"No recipients in pool\\\");\\n\\n uint96 totalAmount = rewardAmount + rewardRoundingDust;\\n uint96 perWeightReward = totalAmount / currentPoolWeight;\\n uint96 newRoundingDust = totalAmount % currentPoolWeight;\\n\\n globalRewardAccumulator += perWeightReward;\\n rewardRoundingDust = newRoundingDust;\\n }\\n\\n /// @notice Internal function for updating the operator's reward state.\\n function updateOperatorRewards(uint32 operator, uint32 newWeight) internal {\\n uint96 acc = globalRewardAccumulator;\\n OperatorRewards memory o = operatorRewards[operator];\\n uint96 accruedRewards = (acc - o.accumulated) * uint96(o.weight);\\n if (o.ineligibleUntil == 0) {\\n // If operator is not ineligible, update their earned rewards\\n o.available += accruedRewards;\\n } else {\\n // If ineligible, put the rewards into the ineligible pot\\n ineligibleEarnedRewards += accruedRewards;\\n }\\n // In any case, update their accumulator and weight\\n o.accumulated = acc;\\n o.weight = newWeight;\\n operatorRewards[operator] = o;\\n }\\n\\n /// @notice Set the amount of withdrawable tokens to zero\\n /// and return the previous withdrawable amount.\\n /// @dev Does not update the withdrawable amount,\\n /// but should usually be accompanied by an update.\\n function withdrawOperatorRewards(uint32 operator)\\n internal\\n returns (uint96 withdrawable)\\n {\\n OperatorRewards storage o = operatorRewards[operator];\\n withdrawable = o.available;\\n o.available = 0;\\n }\\n\\n /// @notice Set the amount of ineligible-earned tokens to zero\\n /// and return the previous amount.\\n function withdrawIneligibleRewards() internal returns (uint96 withdrawable) {\\n withdrawable = ineligibleEarnedRewards;\\n ineligibleEarnedRewards = 0;\\n }\\n\\n /// @notice Set the given operators as ineligible for rewards.\\n /// The operators can restore their eligibility at the given time.\\n function setIneligible(uint32[] memory operators, uint256 until) internal {\\n OperatorRewards memory o = OperatorRewards(0, 0, 0, 0);\\n uint96 globalAcc = globalRewardAccumulator;\\n uint96 accrued = 0;\\n // Record ineligibility as seconds after contract creation\\n uint32 _until = uint32(until - ineligibleOffsetStart);\\n\\n for (uint256 i = 0; i < operators.length; i++) {\\n uint32 operator = operators[i];\\n OperatorRewards storage r = operatorRewards[operator];\\n o.available = r.available;\\n o.accumulated = r.accumulated;\\n o.ineligibleUntil = r.ineligibleUntil;\\n o.weight = r.weight;\\n\\n if (o.ineligibleUntil != 0) {\\n // If operator is already ineligible,\\n // don't earn rewards or shorten its ineligibility\\n if (o.ineligibleUntil < _until) {\\n o.ineligibleUntil = _until;\\n }\\n } else {\\n // The operator becomes ineligible -> earn rewards\\n o.ineligibleUntil = _until;\\n accrued = (globalAcc - o.accumulated) * uint96(o.weight);\\n o.available += accrued;\\n }\\n o.accumulated = globalAcc;\\n\\n r.available = o.available;\\n r.accumulated = o.accumulated;\\n r.ineligibleUntil = o.ineligibleUntil;\\n r.weight = o.weight;\\n }\\n }\\n\\n /// @notice Restore the given operator's eligibility for rewards.\\n function restoreEligibility(uint32 operator) internal {\\n // solhint-disable-next-line not-rely-on-time\\n require(canRestoreRewardEligibility(operator), \\\"Operator still ineligible\\\");\\n uint96 acc = globalRewardAccumulator;\\n OperatorRewards memory o = operatorRewards[operator];\\n uint96 accruedRewards = (acc - o.accumulated) * uint96(o.weight);\\n ineligibleEarnedRewards += accruedRewards;\\n o.accumulated = acc;\\n o.ineligibleUntil = 0;\\n operatorRewards[operator] = o;\\n }\\n\\n /// @notice Returns the amount of rewards currently available for withdrawal\\n /// for the given operator.\\n function availableRewards(uint32 operator) internal view returns (uint96) {\\n uint96 acc = globalRewardAccumulator;\\n OperatorRewards memory o = operatorRewards[operator];\\n if (o.ineligibleUntil == 0) {\\n // If operator is not ineligible, calculate newly accrued rewards and add\\n // them to the available ones, calculated during the last update.\\n uint96 accruedRewards = (acc - o.accumulated) * uint96(o.weight);\\n return o.available + accruedRewards;\\n } else {\\n // If ineligible, return only the rewards calculated during the last\\n // update.\\n return o.available;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3a10abb408b44335a092387b2c7ee01db3b27997f1f2c888d9b7a2d92934c4e2\"},\"@keep-network/sortition-pools/contracts/SortitionPool.sol\":{\"content\":\"pragma solidity 0.8.17;\\n\\nimport \\\"@thesis/solidity-contracts/contracts/token/IERC20WithPermit.sol\\\";\\nimport \\\"@thesis/solidity-contracts/contracts/token/IReceiveApproval.sol\\\";\\n\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\nimport \\\"./RNG.sol\\\";\\nimport \\\"./SortitionTree.sol\\\";\\nimport \\\"./Rewards.sol\\\";\\nimport \\\"./Chaosnet.sol\\\";\\n\\n/// @title Sortition Pool\\n/// @notice A logarithmic data structure used to store the pool of eligible\\n/// operators weighted by their stakes. It allows to select a group of operators\\n/// based on the provided pseudo-random seed.\\ncontract SortitionPool is\\n SortitionTree,\\n Rewards,\\n Ownable,\\n Chaosnet,\\n IReceiveApproval\\n{\\n using Branch for uint256;\\n using Leaf for uint256;\\n using Position for uint256;\\n\\n IERC20WithPermit public immutable rewardToken;\\n\\n uint256 public immutable poolWeightDivisor;\\n\\n bool public isLocked;\\n\\n event IneligibleForRewards(uint32[] ids, uint256 until);\\n\\n event RewardEligibilityRestored(address indexed operator, uint32 indexed id);\\n\\n /// @notice Reverts if called while pool is locked.\\n modifier onlyUnlocked() {\\n require(!isLocked, \\\"Sortition pool locked\\\");\\n _;\\n }\\n\\n /// @notice Reverts if called while pool is unlocked.\\n modifier onlyLocked() {\\n require(isLocked, \\\"Sortition pool unlocked\\\");\\n _;\\n }\\n\\n constructor(IERC20WithPermit _rewardToken, uint256 _poolWeightDivisor) {\\n rewardToken = _rewardToken;\\n poolWeightDivisor = _poolWeightDivisor;\\n }\\n\\n function receiveApproval(\\n address sender,\\n uint256 amount,\\n address token,\\n bytes calldata\\n ) external override {\\n require(token == address(rewardToken), \\\"Unsupported token\\\");\\n rewardToken.transferFrom(sender, address(this), amount);\\n Rewards.addRewards(uint96(amount), uint32(root.sumWeight()));\\n }\\n\\n /// @notice Withdraws all available rewards for the given operator to the\\n /// given beneficiary.\\n /// @dev Can be called only be the owner. Does not validate if the provided\\n /// beneficiary is associated with the provided operator - this needs to\\n /// be done by the owner calling this function.\\n /// @return The amount of rewards withdrawn in this call.\\n function withdrawRewards(address operator, address beneficiary)\\n public\\n onlyOwner\\n returns (uint96)\\n {\\n uint32 id = getOperatorID(operator);\\n Rewards.updateOperatorRewards(id, uint32(getPoolWeight(operator)));\\n uint96 earned = Rewards.withdrawOperatorRewards(id);\\n rewardToken.transfer(beneficiary, uint256(earned));\\n return earned;\\n }\\n\\n /// @notice Withdraws rewards not allocated to operators marked as ineligible\\n /// to the given recipient address.\\n /// @dev Can be called only by the owner.\\n function withdrawIneligible(address recipient) public onlyOwner {\\n uint96 earned = Rewards.withdrawIneligibleRewards();\\n rewardToken.transfer(recipient, uint256(earned));\\n }\\n\\n /// @notice Locks the sortition pool. In locked state, members cannot be\\n /// inserted and removed from the pool. Members statuses cannot\\n /// be updated as well.\\n /// @dev Can be called only by the contract owner.\\n function lock() public onlyOwner {\\n isLocked = true;\\n }\\n\\n /// @notice Unlocks the sortition pool. Removes all restrictions set by\\n /// the `lock` method.\\n /// @dev Can be called only by the contract owner.\\n function unlock() public onlyOwner {\\n isLocked = false;\\n }\\n\\n /// @notice Inserts an operator to the pool. Reverts if the operator is\\n /// already present. Reverts if the operator is not eligible because of their\\n /// authorized stake. Reverts if the chaosnet is active and the operator is\\n /// not a beta operator.\\n /// @dev Can be called only by the contract owner.\\n /// @param operator Address of the inserted operator.\\n /// @param authorizedStake Inserted operator's authorized stake for the application.\\n function insertOperator(address operator, uint256 authorizedStake)\\n public\\n onlyOwner\\n onlyUnlocked\\n {\\n uint256 weight = getWeight(authorizedStake);\\n require(weight > 0, \\\"Operator not eligible\\\");\\n\\n if (isChaosnetActive) {\\n require(isBetaOperator[operator], \\\"Not beta operator for chaosnet\\\");\\n }\\n\\n _insertOperator(operator, weight);\\n uint32 id = getOperatorID(operator);\\n Rewards.updateOperatorRewards(id, uint32(weight));\\n }\\n\\n /// @notice Update the operator's weight if present and eligible,\\n /// or remove from the pool if present and ineligible.\\n /// @dev Can be called only by the contract owner.\\n /// @param operator Address of the updated operator.\\n /// @param authorizedStake Operator's authorized stake for the application.\\n function updateOperatorStatus(address operator, uint256 authorizedStake)\\n public\\n onlyOwner\\n onlyUnlocked\\n {\\n uint256 weight = getWeight(authorizedStake);\\n\\n uint32 id = getOperatorID(operator);\\n Rewards.updateOperatorRewards(id, uint32(weight));\\n\\n if (weight == 0) {\\n _removeOperator(operator);\\n } else {\\n updateOperator(operator, weight);\\n }\\n }\\n\\n /// @notice Set the given operators as ineligible for rewards.\\n /// The operators can restore their eligibility at the given time.\\n function setRewardIneligibility(uint32[] calldata operators, uint256 until)\\n public\\n onlyOwner\\n {\\n Rewards.setIneligible(operators, until);\\n emit IneligibleForRewards(operators, until);\\n }\\n\\n /// @notice Restores reward eligibility for the operator.\\n function restoreRewardEligibility(address operator) public {\\n uint32 id = getOperatorID(operator);\\n Rewards.restoreEligibility(id);\\n emit RewardEligibilityRestored(operator, id);\\n }\\n\\n /// @notice Returns whether the operator is eligible for rewards or not.\\n function isEligibleForRewards(address operator) public view returns (bool) {\\n uint32 id = getOperatorID(operator);\\n return Rewards.isEligibleForRewards(id);\\n }\\n\\n /// @notice Returns the time the operator's reward eligibility can be restored.\\n function rewardsEligibilityRestorableAt(address operator)\\n public\\n view\\n returns (uint256)\\n {\\n uint32 id = getOperatorID(operator);\\n return Rewards.rewardsEligibilityRestorableAt(id);\\n }\\n\\n /// @notice Returns whether the operator is able to restore their eligibility\\n /// for rewards right away.\\n function canRestoreRewardEligibility(address operator)\\n public\\n view\\n returns (bool)\\n {\\n uint32 id = getOperatorID(operator);\\n return Rewards.canRestoreRewardEligibility(id);\\n }\\n\\n /// @notice Returns the amount of rewards withdrawable for the given operator.\\n function getAvailableRewards(address operator) public view returns (uint96) {\\n uint32 id = getOperatorID(operator);\\n return availableRewards(id);\\n }\\n\\n /// @notice Return whether the operator is present in the pool.\\n function isOperatorInPool(address operator) public view returns (bool) {\\n return getFlaggedLeafPosition(operator) != 0;\\n }\\n\\n /// @notice Return whether the operator's weight in the pool\\n /// matches their eligible weight.\\n function isOperatorUpToDate(address operator, uint256 authorizedStake)\\n public\\n view\\n returns (bool)\\n {\\n return getWeight(authorizedStake) == getPoolWeight(operator);\\n }\\n\\n /// @notice Return the weight of the operator in the pool,\\n /// which may or may not be out of date.\\n function getPoolWeight(address operator) public view returns (uint256) {\\n uint256 flaggedPosition = getFlaggedLeafPosition(operator);\\n if (flaggedPosition == 0) {\\n return 0;\\n } else {\\n uint256 leafPosition = flaggedPosition.unsetFlag();\\n uint256 leafWeight = getLeafWeight(leafPosition);\\n return leafWeight;\\n }\\n }\\n\\n /// @notice Selects a new group of operators of the provided size based on\\n /// the provided pseudo-random seed. At least one operator has to be\\n /// registered in the pool, otherwise the function fails reverting the\\n /// transaction.\\n /// @param groupSize Size of the requested group\\n /// @param seed Pseudo-random number used to select operators to group\\n /// @return selected Members of the selected group\\n function selectGroup(uint256 groupSize, bytes32 seed)\\n public\\n view\\n onlyLocked\\n returns (uint32[] memory)\\n {\\n uint256 _root = root;\\n\\n bytes32 rngState = seed;\\n uint256 rngRange = _root.sumWeight();\\n require(rngRange > 0, \\\"Not enough operators in pool\\\");\\n uint256 currentIndex;\\n\\n uint256 bits = RNG.bitsRequired(rngRange);\\n\\n uint32[] memory selected = new uint32[](groupSize);\\n\\n for (uint256 i = 0; i < groupSize; i++) {\\n (currentIndex, rngState) = RNG.getIndex(rngRange, rngState, bits);\\n\\n uint256 leafPosition = pickWeightedLeaf(currentIndex, _root);\\n\\n uint256 leaf = leaves[leafPosition];\\n selected[i] = leaf.id();\\n }\\n return selected;\\n }\\n\\n function getWeight(uint256 authorization) internal view returns (uint256) {\\n return authorization / poolWeightDivisor;\\n }\\n}\\n\",\"keccak256\":\"0xab42e7c5b1828f42a73f699eb2dc96d4f793572a6323b8b1fbd7c5e0c065bda7\"},\"@keep-network/sortition-pools/contracts/SortitionTree.sol\":{\"content\":\"pragma solidity 0.8.17;\\n\\nimport \\\"./Branch.sol\\\";\\nimport \\\"./Position.sol\\\";\\nimport \\\"./Leaf.sol\\\";\\nimport \\\"./Constants.sol\\\";\\n\\ncontract SortitionTree {\\n using Branch for uint256;\\n using Position for uint256;\\n using Leaf for uint256;\\n\\n // implicit tree\\n // root 8\\n // level2 64\\n // level3 512\\n // level4 4k\\n // level5 32k\\n // level6 256k\\n // level7 2M\\n uint256 internal root;\\n\\n // A 2-index mapping from layer => (index (0-index) => branch). For example,\\n // to access the 6th branch in the 2nd layer (right below the root node; the\\n // first branch layer), call branches[2][5]. Mappings are used in place of\\n // arrays for efficiency. The root is the first layer, the branches occupy\\n // layers 2 through 7, and layer 8 is for the leaves. Following this\\n // convention, the first index in `branches` is `2`, and the last index is\\n // `7`.\\n mapping(uint256 => mapping(uint256 => uint256)) internal branches;\\n\\n // A 0-index mapping from index => leaf, acting as an array. For example, to\\n // access the 42nd leaf, call leaves[41].\\n mapping(uint256 => uint256) internal leaves;\\n\\n // the flagged (see setFlag() and unsetFlag() in Position.sol) positions\\n // of all operators present in the pool\\n mapping(address => uint256) internal flaggedLeafPosition;\\n\\n // the leaf after the rightmost occupied leaf of each stack\\n uint256 internal rightmostLeaf;\\n\\n // the empty leaves in each stack\\n // between 0 and the rightmost occupied leaf\\n uint256[] internal emptyLeaves;\\n\\n // Each operator has an uint32 ID number\\n // which is allocated when they first join the pool\\n // and remains unchanged even if they leave and rejoin the pool.\\n mapping(address => uint32) internal operatorID;\\n\\n // The idAddress array records the address corresponding to each ID number.\\n // The ID number 0 is initialized with a zero address and is not used.\\n address[] internal idAddress;\\n\\n constructor() {\\n root = 0;\\n rightmostLeaf = 0;\\n idAddress.push();\\n }\\n\\n /// @notice Return the ID number of the given operator address. An ID number\\n /// of 0 means the operator has not been allocated an ID number yet.\\n /// @param operator Address of the operator.\\n /// @return the ID number of the given operator address\\n function getOperatorID(address operator) public view returns (uint32) {\\n return operatorID[operator];\\n }\\n\\n /// @notice Get the operator address corresponding to the given ID number. A\\n /// zero address means the ID number has not been allocated yet.\\n /// @param id ID of the operator\\n /// @return the address of the operator\\n function getIDOperator(uint32 id) public view returns (address) {\\n return idAddress.length > id ? idAddress[id] : address(0);\\n }\\n\\n /// @notice Gets the operator addresses corresponding to the given ID\\n /// numbers. A zero address means the ID number has not been allocated yet.\\n /// This function works just like getIDOperator except that it allows to fetch\\n /// operator addresses for multiple IDs in one call.\\n /// @param ids the array of the operator ids\\n /// @return an array of the associated operator addresses\\n function getIDOperators(uint32[] calldata ids)\\n public\\n view\\n returns (address[] memory)\\n {\\n uint256 idCount = idAddress.length;\\n\\n address[] memory operators = new address[](ids.length);\\n for (uint256 i = 0; i < ids.length; i++) {\\n uint32 id = ids[i];\\n operators[i] = idCount > id ? idAddress[id] : address(0);\\n }\\n return operators;\\n }\\n\\n /// @notice Checks if operator is already registered in the pool.\\n /// @param operator the address of the operator\\n /// @return whether or not the operator is already registered in the pool\\n function isOperatorRegistered(address operator) public view returns (bool) {\\n return getFlaggedLeafPosition(operator) != 0;\\n }\\n\\n /// @notice Sum the number of operators in each trunk.\\n /// @return the number of operators in the pool\\n function operatorsInPool() public view returns (uint256) {\\n // Get the number of leaves that might be occupied;\\n // if `rightmostLeaf` equals `firstLeaf()` the tree must be empty,\\n // otherwise the difference between these numbers\\n // gives the number of leaves that may be occupied.\\n uint256 nPossiblyUsedLeaves = rightmostLeaf;\\n // Get the number of empty leaves\\n // not accounted for by the `rightmostLeaf`\\n uint256 nEmptyLeaves = emptyLeaves.length;\\n\\n return (nPossiblyUsedLeaves - nEmptyLeaves);\\n }\\n\\n /// @notice Convenience method to return the total weight of the pool\\n /// @return the total weight of the pool\\n function totalWeight() public view returns (uint256) {\\n return root.sumWeight();\\n }\\n\\n /// @notice Give the operator a new ID number.\\n /// Does not check if the operator already has an ID number.\\n /// @param operator the address of the operator\\n /// @return a new ID for that operator\\n function allocateOperatorID(address operator) internal returns (uint256) {\\n uint256 id = idAddress.length;\\n\\n require(id <= type(uint32).max, \\\"Pool capacity exceeded\\\");\\n\\n operatorID[operator] = uint32(id);\\n idAddress.push(operator);\\n return id;\\n }\\n\\n /// @notice Inserts an operator into the sortition pool\\n /// @param operator the address of an operator to insert\\n /// @param weight how much weight that operator has in the pool\\n function _insertOperator(address operator, uint256 weight) internal {\\n require(\\n !isOperatorRegistered(operator),\\n \\\"Operator is already registered in the pool\\\"\\n );\\n\\n // Fetch the operator's ID, and if they don't have one, allocate them one.\\n uint256 id = getOperatorID(operator);\\n if (id == 0) {\\n id = allocateOperatorID(operator);\\n }\\n\\n // Determine which leaf to insert them into\\n uint256 position = getEmptyLeafPosition();\\n // Record the block the operator was inserted in\\n uint256 theLeaf = Leaf.make(operator, block.number, id);\\n\\n // Update the leaf, and propagate the weight changes all the way up to the\\n // root.\\n root = setLeaf(position, theLeaf, weight, root);\\n\\n // Without position flags,\\n // the position 0x000000 would be treated as empty\\n flaggedLeafPosition[operator] = position.setFlag();\\n }\\n\\n /// @notice Remove an operator (and their weight) from the pool.\\n /// @param operator the address of the operator to remove\\n function _removeOperator(address operator) internal {\\n uint256 flaggedPosition = getFlaggedLeafPosition(operator);\\n require(flaggedPosition != 0, \\\"Operator is not registered in the pool\\\");\\n uint256 unflaggedPosition = flaggedPosition.unsetFlag();\\n\\n // Update the leaf, and propagate the weight changes all the way up to the\\n // root.\\n root = removeLeaf(unflaggedPosition, root);\\n removeLeafPositionRecord(operator);\\n }\\n\\n /// @notice Update an operator's weight in the pool.\\n /// @param operator the address of the operator to update\\n /// @param weight the new weight\\n function updateOperator(address operator, uint256 weight) internal {\\n require(\\n isOperatorRegistered(operator),\\n \\\"Operator is not registered in the pool\\\"\\n );\\n\\n uint256 flaggedPosition = getFlaggedLeafPosition(operator);\\n uint256 unflaggedPosition = flaggedPosition.unsetFlag();\\n root = updateLeaf(unflaggedPosition, weight, root);\\n }\\n\\n /// @notice Helper method to remove a leaf position record for an operator.\\n /// @param operator the address of the operator to remove the record for\\n function removeLeafPositionRecord(address operator) internal {\\n flaggedLeafPosition[operator] = 0;\\n }\\n\\n /// @notice Removes the data and weight from a particular leaf.\\n /// @param position the leaf index to remove\\n /// @param _root the root node containing the leaf\\n /// @return the updated root node\\n function removeLeaf(uint256 position, uint256 _root)\\n internal\\n returns (uint256)\\n {\\n uint256 rightmostSubOne = rightmostLeaf - 1;\\n bool isRightmost = position == rightmostSubOne;\\n\\n // Clears out the data in the leaf node, and then propagates the weight\\n // changes all the way up to the root.\\n uint256 newRoot = setLeaf(position, 0, 0, _root);\\n\\n // Infer if need to fall back on emptyLeaves yet\\n if (isRightmost) {\\n rightmostLeaf = rightmostSubOne;\\n } else {\\n emptyLeaves.push(position);\\n }\\n return newRoot;\\n }\\n\\n /// @notice Updates the tree to give a particular leaf a new weight.\\n /// @param position the index of the leaf to update\\n /// @param weight the new weight\\n /// @param _root the root node containing the leaf\\n /// @return the updated root node\\n function updateLeaf(\\n uint256 position,\\n uint256 weight,\\n uint256 _root\\n ) internal returns (uint256) {\\n if (getLeafWeight(position) != weight) {\\n return updateTree(position, weight, _root);\\n } else {\\n return _root;\\n }\\n }\\n\\n /// @notice Places a leaf into a particular position, with a given weight and\\n /// propagates that change.\\n /// @param position the index to place the leaf in\\n /// @param theLeaf the new leaf to place in the position\\n /// @param leafWeight the weight of the leaf\\n /// @param _root the root containing the new leaf\\n /// @return the updated root node\\n function setLeaf(\\n uint256 position,\\n uint256 theLeaf,\\n uint256 leafWeight,\\n uint256 _root\\n ) internal returns (uint256) {\\n // set leaf\\n leaves[position] = theLeaf;\\n\\n return (updateTree(position, leafWeight, _root));\\n }\\n\\n /// @notice Propagates a weight change at a position through the tree,\\n /// eventually returning the updated root.\\n /// @param position the index of leaf to update\\n /// @param weight the new weight of the leaf\\n /// @param _root the root node containing the leaf\\n /// @return the updated root node\\n function updateTree(\\n uint256 position,\\n uint256 weight,\\n uint256 _root\\n ) internal returns (uint256) {\\n uint256 childSlot;\\n uint256 treeNode;\\n uint256 newNode;\\n uint256 nodeWeight = weight;\\n\\n uint256 parent = position;\\n // set levels 7 to 2\\n for (uint256 level = Constants.LEVELS; level >= 2; level--) {\\n childSlot = parent.slot();\\n parent = parent.parent();\\n treeNode = branches[level][parent];\\n newNode = treeNode.setSlot(childSlot, nodeWeight);\\n branches[level][parent] = newNode;\\n nodeWeight = newNode.sumWeight();\\n }\\n\\n // set level Root\\n childSlot = parent.slot();\\n return _root.setSlot(childSlot, nodeWeight);\\n }\\n\\n /// @notice Retrieves the next available empty leaf position. Tries to fill\\n /// left to right first, ignoring leaf removals, and then fills\\n /// most-recent-removals first.\\n /// @return the position of the empty leaf\\n function getEmptyLeafPosition() internal returns (uint256) {\\n uint256 rLeaf = rightmostLeaf;\\n bool spaceOnRight = (rLeaf + 1) < Constants.POOL_CAPACITY;\\n if (spaceOnRight) {\\n rightmostLeaf = rLeaf + 1;\\n return rLeaf;\\n } else {\\n uint256 emptyLeafCount = emptyLeaves.length;\\n require(emptyLeafCount > 0, \\\"Pool is full\\\");\\n uint256 emptyLeaf = emptyLeaves[emptyLeafCount - 1];\\n emptyLeaves.pop();\\n return emptyLeaf;\\n }\\n }\\n\\n /// @notice Gets the flagged leaf position for an operator.\\n /// @param operator the address of the operator\\n /// @return the leaf position of that operator\\n function getFlaggedLeafPosition(address operator)\\n internal\\n view\\n returns (uint256)\\n {\\n return flaggedLeafPosition[operator];\\n }\\n\\n /// @notice Gets the weight of a leaf at a particular position.\\n /// @param position the index of the leaf\\n /// @return the weight of the leaf at that position\\n function getLeafWeight(uint256 position) internal view returns (uint256) {\\n uint256 slot = position.slot();\\n uint256 parent = position.parent();\\n\\n // A leaf's weight information is stored a 32-bit slot in the branch layer\\n // directly above the leaf layer. To access it, we calculate that slot and\\n // parent position, and always know the hard-coded layer index.\\n uint256 node = branches[Constants.LEVELS][parent];\\n return node.getSlot(slot);\\n }\\n\\n /// @notice Picks a leaf given a random index.\\n /// @param index a number in `[0, _root.totalWeight())` used to decide\\n /// between leaves\\n /// @param _root the root of the tree\\n function pickWeightedLeaf(uint256 index, uint256 _root)\\n internal\\n view\\n returns (uint256 leafPosition)\\n {\\n uint256 currentIndex = index;\\n uint256 currentNode = _root;\\n uint256 currentPosition = 0;\\n uint256 currentSlot;\\n\\n require(index < currentNode.sumWeight(), \\\"Index exceeds weight\\\");\\n\\n // get root slot\\n (currentSlot, currentIndex) = currentNode.pickWeightedSlot(currentIndex);\\n\\n // get slots from levels 2 to 7\\n for (uint256 level = 2; level <= Constants.LEVELS; level++) {\\n currentPosition = currentPosition.child(currentSlot);\\n currentNode = branches[level][currentPosition];\\n (currentSlot, currentIndex) = currentNode.pickWeightedSlot(currentIndex);\\n }\\n\\n // get leaf position\\n leafPosition = currentPosition.child(currentSlot);\\n }\\n}\\n\",\"keccak256\":\"0x51daeca62ef52be78a1a9de4d2a1c5900c873165f59eda14d5965d7d7da90a03\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@thesis/solidity-contracts/contracts/token/IApproveAndCall.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.4;\\n\\n/// @notice An interface that should be implemented by tokens supporting\\n/// `approveAndCall`/`receiveApproval` pattern.\\ninterface IApproveAndCall {\\n /// @notice Executes `receiveApproval` function on spender as specified in\\n /// `IReceiveApproval` interface. Approves spender to withdraw from\\n /// the caller multiple times, up to the `amount`. If this\\n /// function is called again, it overwrites the current allowance\\n /// with `amount`. Reverts if the approval reverted or if\\n /// `receiveApproval` call on the spender reverted.\\n function approveAndCall(\\n address spender,\\n uint256 amount,\\n bytes memory extraData\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x393d18ef81a57dcc96fff4c340cc2945deaebb37b9796c322cf2bc96872c3df8\",\"license\":\"MIT\"},\"@thesis/solidity-contracts/contracts/token/IERC20WithPermit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.4;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\n\\nimport \\\"./IApproveAndCall.sol\\\";\\n\\n/// @title IERC20WithPermit\\n/// @notice Burnable ERC20 token with EIP2612 permit functionality. User can\\n/// authorize a transfer of their token with a signature conforming\\n/// EIP712 standard instead of an on-chain transaction from their\\n/// address. Anyone can submit this signature on the user's behalf by\\n/// calling the permit function, as specified in EIP2612 standard,\\n/// paying gas fees, and possibly performing other actions in the same\\n/// transaction.\\ninterface IERC20WithPermit is IERC20, IERC20Metadata, IApproveAndCall {\\n /// @notice EIP2612 approval made with secp256k1 signature.\\n /// Users can authorize a transfer of their tokens with a signature\\n /// conforming EIP712 standard, rather than an on-chain transaction\\n /// from their address. Anyone can submit this signature on the\\n /// user's behalf by calling the permit function, paying gas fees,\\n /// and possibly performing other actions in the same transaction.\\n /// @dev The deadline argument can be set to `type(uint256).max to create\\n /// permits that effectively never expire.\\n function permit(\\n address owner,\\n address spender,\\n uint256 amount,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /// @notice Destroys `amount` tokens from the caller.\\n function burn(uint256 amount) external;\\n\\n /// @notice Destroys `amount` of tokens from `account`, deducting the amount\\n /// from caller's allowance.\\n function burnFrom(address account, uint256 amount) external;\\n\\n /// @notice Returns hash of EIP712 Domain struct with the token name as\\n /// a signing domain and token contract as a verifying contract.\\n /// Used to construct EIP2612 signature provided to `permit`\\n /// function.\\n /* solhint-disable-next-line func-name-mixedcase */\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n\\n /// @notice Returns the current nonce for EIP2612 permission for the\\n /// provided token owner for a replay protection. Used to construct\\n /// EIP2612 signature provided to `permit` function.\\n function nonce(address owner) external view returns (uint256);\\n\\n /// @notice Returns EIP2612 Permit message hash. Used to construct EIP2612\\n /// signature provided to `permit` function.\\n /* solhint-disable-next-line func-name-mixedcase */\\n function PERMIT_TYPEHASH() external pure returns (bytes32);\\n}\\n\",\"keccak256\":\"0xdac9a5086c19a7128b505a7be1ab0ac1aa314f6989cb88d2417e9d7383f89fa9\",\"license\":\"MIT\"},\"@thesis/solidity-contracts/contracts/token/IReceiveApproval.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.4;\\n\\n/// @notice An interface that should be implemented by contracts supporting\\n/// `approveAndCall`/`receiveApproval` pattern.\\ninterface IReceiveApproval {\\n /// @notice Receives approval to spend tokens. Called as a result of\\n /// `approveAndCall` call on the token.\\n function receiveApproval(\\n address from,\\n uint256 amount,\\n address token,\\n bytes calldata extraData\\n ) external;\\n}\\n\",\"keccak256\":\"0x6a30d83ad230548b1e7839737affc8489a035314209de14b89dbef7fb0f66395\",\"license\":\"MIT\"},\"@threshold-network/solidity-contracts/contracts/staking/IStaking.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\n// \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\n// \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\n// \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c\\n// \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c\\n// \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\n// \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\n// \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c\\n// \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c\\n// \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c\\n// \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c\\n// \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c\\n// \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c\\n\\npragma solidity ^0.8.9;\\n\\n/// @title Interface of Threshold Network staking contract\\n/// @notice The staking contract enables T owners to have their wallets offline\\n/// and their stake managed by staking providers on their behalf.\\n/// The staking contract does not define operator role. The operator\\n/// responsible for running off-chain client software is appointed by\\n/// the staking provider in the particular application utilizing the\\n/// staking contract. All off-chain client software should be able\\n/// to run without exposing operator's or staking provider\\u2019s private\\n/// key and should not require any owner\\u2019s keys at all. The stake\\n/// delegation optimizes the network throughput without compromising the\\n/// security of the owners\\u2019 stake.\\ninterface IStaking {\\n enum StakeType {\\n NU,\\n KEEP,\\n T\\n }\\n\\n //\\n //\\n // Delegating a stake\\n //\\n //\\n\\n /// @notice Creates a delegation with `msg.sender` owner with the given\\n /// staking provider, beneficiary, and authorizer. Transfers the\\n /// given amount of T to the staking contract.\\n /// @dev The owner of the delegation needs to have the amount approved to\\n /// transfer to the staking contract.\\n function stake(\\n address stakingProvider,\\n address payable beneficiary,\\n address authorizer,\\n uint96 amount\\n ) external;\\n\\n /// @notice Copies delegation from the legacy KEEP staking contract to T\\n /// staking contract. No tokens are transferred. Caches the active\\n /// stake amount from KEEP staking contract. Can be called by\\n /// anyone.\\n /// @dev The staking provider in T staking contract is the legacy KEEP\\n /// staking contract operator.\\n function stakeKeep(address stakingProvider) external;\\n\\n /// @notice Copies delegation from the legacy NU staking contract to T\\n /// staking contract, additionally appointing staking provider,\\n /// beneficiary and authorizer roles. Caches the amount staked in NU\\n /// staking contract. Can be called only by the original delegation\\n /// owner.\\n function stakeNu(\\n address stakingProvider,\\n address payable beneficiary,\\n address authorizer\\n ) external;\\n\\n /// @notice Allows the Governance to set the minimum required stake amount.\\n /// This amount is required to protect against griefing the staking\\n /// contract and individual applications are allowed to require\\n /// higher minimum stakes if necessary.\\n function setMinimumStakeAmount(uint96 amount) external;\\n\\n //\\n //\\n // Authorizing an application\\n //\\n //\\n\\n /// @notice Allows the Governance to approve the particular application\\n /// before individual stake authorizers are able to authorize it.\\n function approveApplication(address application) external;\\n\\n /// @notice Increases the authorization of the given staking provider for\\n /// the given application by the given amount. Can only be called by\\n /// the authorizer for that staking provider.\\n /// @dev Calls `authorizationIncreased(address stakingProvider, uint256 amount)`\\n /// on the given application to notify the application about\\n /// authorization change. See `IApplication`.\\n function increaseAuthorization(\\n address stakingProvider,\\n address application,\\n uint96 amount\\n ) external;\\n\\n /// @notice Requests decrease of the authorization for the given staking\\n /// provider on the given application by the provided amount.\\n /// It may not change the authorized amount immediatelly. When\\n /// it happens depends on the application. Can only be called by the\\n /// given staking provider\\u2019s authorizer. Overwrites pending\\n /// authorization decrease for the given staking provider and\\n /// application if the application agrees for that. If the\\n /// application does not agree for overwriting, the function\\n /// reverts.\\n /// @dev Calls `authorizationDecreaseRequested(address stakingProvider, uint256 amount)`\\n /// on the given application. See `IApplication`.\\n function requestAuthorizationDecrease(\\n address stakingProvider,\\n address application,\\n uint96 amount\\n ) external;\\n\\n /// @notice Requests decrease of all authorizations for the given staking\\n /// provider on all applications by all authorized amount.\\n /// It may not change the authorized amount immediatelly. When\\n /// it happens depends on the application. Can only be called by the\\n /// given staking provider\\u2019s authorizer. Overwrites pending\\n /// authorization decrease for the given staking provider and\\n /// application.\\n /// @dev Calls `authorizationDecreaseRequested(address stakingProvider, uint256 amount)`\\n /// for each authorized application. See `IApplication`.\\n function requestAuthorizationDecrease(address stakingProvider) external;\\n\\n /// @notice Called by the application at its discretion to approve the\\n /// previously requested authorization decrease request. Can only be\\n /// called by the application that was previously requested to\\n /// decrease the authorization for that staking provider.\\n /// Returns resulting authorized amount for the application.\\n function approveAuthorizationDecrease(address stakingProvider)\\n external\\n returns (uint96);\\n\\n /// @notice Decreases the authorization for the given `stakingProvider` on\\n /// the given disabled `application`, for all authorized amount.\\n /// Can be called by anyone.\\n function forceDecreaseAuthorization(\\n address stakingProvider,\\n address application\\n ) external;\\n\\n /// @notice Pauses the given application\\u2019s eligibility to slash stakes.\\n /// Besides that stakers can't change authorization to the application.\\n /// Can be called only by the Panic Button of the particular\\n /// application. The paused application can not slash stakes until\\n /// it is approved again by the Governance using `approveApplication`\\n /// function. Should be used only in case of an emergency.\\n function pauseApplication(address application) external;\\n\\n /// @notice Disables the given application. The disabled application can't\\n /// slash stakers. Also stakers can't increase authorization to that\\n /// application but can decrease without waiting by calling\\n /// `requestAuthorizationDecrease` at any moment. Can be called only\\n /// by the governance. The disabled application can't be approved\\n /// again. Should be used only in case of an emergency.\\n function disableApplication(address application) external;\\n\\n /// @notice Sets the Panic Button role for the given application to the\\n /// provided address. Can only be called by the Governance. If the\\n /// Panic Button for the given application should be disabled, the\\n /// role address should be set to 0x0 address.\\n function setPanicButton(address application, address panicButton) external;\\n\\n /// @notice Sets the maximum number of applications one staking provider can\\n /// have authorized. Used to protect against DoSing slashing queue.\\n /// Can only be called by the Governance.\\n function setAuthorizationCeiling(uint256 ceiling) external;\\n\\n //\\n //\\n // Stake top-up\\n //\\n //\\n\\n /// @notice Increases the amount of the stake for the given staking provider.\\n /// @dev The sender of this transaction needs to have the amount approved to\\n /// transfer to the staking contract.\\n function topUp(address stakingProvider, uint96 amount) external;\\n\\n /// @notice Propagates information about stake top-up from the legacy KEEP\\n /// staking contract to T staking contract. Can be called only by\\n /// the owner or the staking provider.\\n function topUpKeep(address stakingProvider) external;\\n\\n /// @notice Propagates information about stake top-up from the legacy NU\\n /// staking contract to T staking contract. Can be called only by\\n /// the owner or the staking provider.\\n function topUpNu(address stakingProvider) external;\\n\\n //\\n //\\n // Undelegating a stake (unstaking)\\n //\\n //\\n\\n /// @notice Reduces the liquid T stake amount by the provided amount and\\n /// withdraws T to the owner. Reverts if there is at least one\\n /// authorization higher than the sum of the legacy stake and\\n /// remaining liquid T stake or if the unstake amount is higher than\\n /// the liquid T stake amount. Can be called only by the delegation\\n /// owner or the staking provider.\\n function unstakeT(address stakingProvider, uint96 amount) external;\\n\\n /// @notice Sets the legacy KEEP staking contract active stake amount cached\\n /// in T staking contract to 0. Reverts if the amount of liquid T\\n /// staked in T staking contract is lower than the highest\\n /// application authorization. This function allows to unstake from\\n /// KEEP staking contract and still being able to operate in T\\n /// network and earning rewards based on the liquid T staked. Can be\\n /// called only by the delegation owner or the staking provider.\\n function unstakeKeep(address stakingProvider) external;\\n\\n /// @notice Reduces cached legacy NU stake amount by the provided amount.\\n /// Reverts if there is at least one authorization higher than the\\n /// sum of remaining legacy NU stake and liquid T stake for that\\n /// staking provider or if the untaked amount is higher than the\\n /// cached legacy stake amount. If succeeded, the legacy NU stake\\n /// can be partially or fully undelegated on the legacy staking\\n /// contract. This function allows to unstake from NU staking\\n /// contract and still being able to operate in T network and\\n /// earning rewards based on the liquid T staked. Can be called only\\n /// by the delegation owner or the staking provider.\\n function unstakeNu(address stakingProvider, uint96 amount) external;\\n\\n /// @notice Sets cached legacy stake amount to 0, sets the liquid T stake\\n /// amount to 0 and withdraws all liquid T from the stake to the\\n /// owner. Reverts if there is at least one non-zero authorization.\\n /// Can be called only by the delegation owner or the staking\\n /// provider.\\n function unstakeAll(address stakingProvider) external;\\n\\n //\\n //\\n // Keeping information in sync\\n //\\n //\\n\\n /// @notice Notifies about the discrepancy between legacy KEEP active stake\\n /// and the amount cached in T staking contract. Slashes the staking\\n /// provider in case the amount cached is higher than the actual\\n /// active stake amount in KEEP staking contract. Needs to update\\n /// authorizations of all affected applications and execute an\\n /// involuntary allocation decrease on all affected applications.\\n /// Can be called by anyone, notifier receives a reward.\\n function notifyKeepStakeDiscrepancy(address stakingProvider) external;\\n\\n /// @notice Notifies about the discrepancy between legacy NU active stake\\n /// and the amount cached in T staking contract. Slashes the\\n /// staking provider in case the amount cached is higher than the\\n /// actual active stake amount in NU staking contract. Needs to\\n /// update authorizations of all affected applications and execute\\n /// an involuntary allocation decrease on all affected applications.\\n /// Can be called by anyone, notifier receives a reward.\\n function notifyNuStakeDiscrepancy(address stakingProvider) external;\\n\\n /// @notice Sets the penalty amount for stake discrepancy and reward\\n /// multiplier for reporting it. The penalty is seized from the\\n /// delegated stake, and 5% of the penalty, scaled by the\\n /// multiplier, is given to the notifier. The rest of the tokens are\\n /// burned. Can only be called by the Governance. See `seize` function.\\n function setStakeDiscrepancyPenalty(\\n uint96 penalty,\\n uint256 rewardMultiplier\\n ) external;\\n\\n /// @notice Sets reward in T tokens for notification of misbehaviour\\n /// of one staking provider. Can only be called by the governance.\\n function setNotificationReward(uint96 reward) external;\\n\\n /// @notice Transfer some amount of T tokens as reward for notifications\\n /// of misbehaviour\\n function pushNotificationReward(uint96 reward) external;\\n\\n /// @notice Withdraw some amount of T tokens from notifiers treasury.\\n /// Can only be called by the governance.\\n function withdrawNotificationReward(address recipient, uint96 amount)\\n external;\\n\\n /// @notice Adds staking providers to the slashing queue along with the\\n /// amount that should be slashed from each one of them. Can only be\\n /// called by application authorized for all staking providers in\\n /// the array.\\n function slash(uint96 amount, address[] memory stakingProviders) external;\\n\\n /// @notice Adds staking providers to the slashing queue along with the\\n /// amount. The notifier will receive reward per each staking\\n /// provider from notifiers treasury. Can only be called by\\n /// application authorized for all staking providers in the array.\\n function seize(\\n uint96 amount,\\n uint256 rewardMultipier,\\n address notifier,\\n address[] memory stakingProviders\\n ) external;\\n\\n /// @notice Takes the given number of queued slashing operations and\\n /// processes them. Receives 5% of the slashed amount.\\n /// Executes `involuntaryAllocationDecrease` function on each\\n /// affected application.\\n function processSlashing(uint256 count) external;\\n\\n //\\n //\\n // Auxiliary functions\\n //\\n //\\n\\n /// @notice Returns the authorized stake amount of the staking provider for\\n /// the application.\\n function authorizedStake(address stakingProvider, address application)\\n external\\n view\\n returns (uint96);\\n\\n /// @notice Returns staked amount of T, Keep and Nu for the specified\\n /// staking provider.\\n /// @dev All values are in T denomination\\n function stakes(address stakingProvider)\\n external\\n view\\n returns (\\n uint96 tStake,\\n uint96 keepInTStake,\\n uint96 nuInTStake\\n );\\n\\n /// @notice Returns start staking timestamp.\\n /// @dev This value is set at most once.\\n function getStartStakingTimestamp(address stakingProvider)\\n external\\n view\\n returns (uint256);\\n\\n /// @notice Returns staked amount of NU for the specified staking provider.\\n function stakedNu(address stakingProvider) external view returns (uint256);\\n\\n /// @notice Gets the stake owner, the beneficiary and the authorizer\\n /// for the specified staking provider address.\\n /// @return owner Stake owner address.\\n /// @return beneficiary Beneficiary address.\\n /// @return authorizer Authorizer address.\\n function rolesOf(address stakingProvider)\\n external\\n view\\n returns (\\n address owner,\\n address payable beneficiary,\\n address authorizer\\n );\\n\\n /// @notice Returns length of application array\\n function getApplicationsLength() external view returns (uint256);\\n\\n /// @notice Returns length of slashing queue\\n function getSlashingQueueLength() external view returns (uint256);\\n\\n /// @notice Returns minimum possible stake for T, KEEP or NU in T\\n /// denomination.\\n /// @dev For example, suppose the given staking provider has 10 T, 20 T\\n /// worth of KEEP, and 30 T worth of NU all staked, and the maximum\\n /// application authorization is 40 T, then `getMinStaked` for\\n /// that staking provider returns:\\n /// * 0 T if KEEP stake type specified i.e.\\n /// min = 40 T max - (10 T + 30 T worth of NU) = 0 T\\n /// * 10 T if NU stake type specified i.e.\\n /// min = 40 T max - (10 T + 20 T worth of KEEP) = 10 T\\n /// * 0 T if T stake type specified i.e.\\n /// min = 40 T max - (20 T worth of KEEP + 30 T worth of NU) < 0 T\\n /// In other words, the minimum stake amount for the specified\\n /// stake type is the minimum amount of stake of the given type\\n /// needed to satisfy the maximum application authorization given the\\n /// staked amounts of the other stake types for that staking provider.\\n function getMinStaked(address stakingProvider, StakeType stakeTypes)\\n external\\n view\\n returns (uint96);\\n\\n /// @notice Returns available amount to authorize for the specified application\\n function getAvailableToAuthorize(\\n address stakingProvider,\\n address application\\n ) external view returns (uint96);\\n}\\n\",\"keccak256\":\"0x45c15ff4a9a47024ce413da249a6a77cc2f20a81909e7536d4c5198c92f3f148\",\"license\":\"GPL-3.0-or-later\"},\"contracts/libraries/BeaconAuthorization.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\n//\\n// \\u2593\\u2593\\u258c \\u2593\\u2593 \\u2590\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u258c\\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2584\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u258c\\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u258c \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2584\\u2584\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2584\\u2584\\u2584\\u2584 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2584\\u2584\\u2584\\u2584 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u258c \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580\\u2580\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2584 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580\\u2580\\u2580\\u2580 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580\\u2580\\u2580\\u2580 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2580\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2584 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u258c\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2588\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\n//\\n//\\n\\n// Initial version copied from Keep Network ECDSA Wallets:\\n// https://github.com/keep-network/keep-core/blob/5286ebc8ff99b2aa6569f9dd97fd6995f25b4630/solidity/ecdsa/contracts/libraries/EcdsaAuthorization.sol\\n//\\n// With the following differences:\\n// - functions' visibility was changed to public/external to deploy it as a linked\\n// library.\\n// - documentation was updated to be more generic.\\n\\npragma solidity 0.8.17;\\n\\nimport \\\"@keep-network/sortition-pools/contracts/SortitionPool.sol\\\";\\nimport \\\"@threshold-network/solidity-contracts/contracts/staking/IStaking.sol\\\";\\n\\n/// @notice Library managing the state of stake authorizations for the operator\\n/// contract and the presence of operators in the sortition\\n/// pool based on the stake authorized for them.\\nlibrary BeaconAuthorization {\\n struct Parameters {\\n // The minimum authorization required by the beacon so that\\n // operator can join the sortition pool and do the work.\\n uint96 minimumAuthorization;\\n // Authorization decrease delay in seconds between the time\\n // authorization decrease is requested and the time the authorization\\n // decrease can be approved. It is always the same value, no matter if\\n // authorization decrease amount is small, significant, or if it is\\n // a decrease to zero.\\n uint64 authorizationDecreaseDelay;\\n // The time period before the authorization decrease delay end,\\n // during which the authorization decrease request can be overwritten.\\n //\\n // When the request is overwritten, the authorization decrease delay is\\n // reset.\\n //\\n // For example, if `authorizationDecraseChangePeriod` is set to 4\\n // days, `authorizationDecreaseDelay` is set to 14 days, and someone\\n // requested authorization decrease, it means they can not\\n // request another decrease for the first 10 days. After 10 days pass,\\n // they can request again and overwrite the previous authorization\\n // decrease request. The delay time will reset for them and they\\n // will have to wait another 10 days to alter it and 14 days to\\n // approve it.\\n //\\n // This value protects against malicious operators who manipulate\\n // their weight by overwriting authorization decrease request, and\\n // lowering or increasing their eligible stake this way.\\n //\\n // If set to a value equal to `authorizationDecreaseDelay, it means\\n // that authorization decrease request can be always overwritten.\\n // If set to zero, it means authorization decrease request can not be\\n // overwritten until the delay end, and one needs to wait for the entire\\n // authorization decrease delay to approve their decrease and request\\n // for another one or to overwrite the pending one.\\n //\\n // (1) authorization decrease requested timestamp\\n // (2) from this moment authorization decrease request can be\\n // overwritten\\n // (3) from this moment authorization decrease request can be\\n // approved, assuming it was NOT overwritten in (2)\\n //\\n // (1) (2) (3)\\n // --x------------------------------x--------------------------x---->\\n // | \\\\________________________/\\n // | authorizationDecreaseChangePeriod\\n // \\\\______________________________________________________/\\n // authorizationDecreaseDelay\\n //\\n uint64 authorizationDecreaseChangePeriod;\\n }\\n\\n struct AuthorizationDecrease {\\n uint96 decreasingBy; // amount\\n uint64 decreasingAt; // timestamp\\n }\\n\\n struct Data {\\n Parameters parameters;\\n mapping(address => address) stakingProviderToOperator;\\n mapping(address => address) operatorToStakingProvider;\\n mapping(address => AuthorizationDecrease) pendingDecreases;\\n }\\n\\n event OperatorRegistered(\\n address indexed stakingProvider,\\n address indexed operator\\n );\\n\\n event AuthorizationIncreased(\\n address indexed stakingProvider,\\n address indexed operator,\\n uint96 fromAmount,\\n uint96 toAmount\\n );\\n\\n event AuthorizationDecreaseRequested(\\n address indexed stakingProvider,\\n address indexed operator,\\n uint96 fromAmount,\\n uint96 toAmount,\\n uint64 decreasingAt\\n );\\n\\n event AuthorizationDecreaseApproved(address indexed stakingProvider);\\n\\n event InvoluntaryAuthorizationDecreaseFailed(\\n address indexed stakingProvider,\\n address indexed operator,\\n uint96 fromAmount,\\n uint96 toAmount\\n );\\n\\n event OperatorJoinedSortitionPool(\\n address indexed stakingProvider,\\n address indexed operator\\n );\\n\\n event OperatorStatusUpdated(\\n address indexed stakingProvider,\\n address indexed operator\\n );\\n\\n /// @notice Updates authorization-related parameters.\\n /// @param _minimumAuthorization New value of the minimum authorization for\\n /// the beacon. Without at least the minimum authorization, staking\\n /// provider is not eligible to join and operate in the network.\\n /// @param _authorizationDecreaseDelay New value of the authorization\\n /// decrease delay. It is the time in seconds that needs to pass\\n /// between the time authorization decrease is requested and the time\\n /// the authorization decrease can be approved, no matter the\\n /// authorization decrease amount.\\n /// @param _authorizationDecreaseChangePeriod New value of the authorization\\n /// decrease change period. It is the time in seconds, before\\n /// authorization decrease delay end, during which the pending\\n /// authorization decrease request can be overwritten.\\n /// If set to 0, pending authorization decrease request can not be\\n /// overwritten until the entire `authorizationDecreaseDelay` ends.\\n /// If set to value equal `authorizationDecreaseDelay`, request can\\n /// always be overwritten.\\n function setParameters(\\n Data storage self,\\n uint96 _minimumAuthorization,\\n uint64 _authorizationDecreaseDelay,\\n uint64 _authorizationDecreaseChangePeriod\\n ) external {\\n self.parameters.minimumAuthorization = _minimumAuthorization;\\n self\\n .parameters\\n .authorizationDecreaseDelay = _authorizationDecreaseDelay;\\n self\\n .parameters\\n .authorizationDecreaseChangePeriod = _authorizationDecreaseChangePeriod;\\n }\\n\\n /// @notice Used by staking provider to set operator address that will\\n /// operate a node. The given staking provider can set operator\\n /// address only one time. The operator address can not be changed\\n /// and must be unique. Reverts if the operator is already set for\\n /// the staking provider or if the operator address is already in\\n /// use. Reverts if there is a pending authorization decrease for\\n /// the staking provider.\\n function registerOperator(Data storage self, address operator) public {\\n address stakingProvider = msg.sender;\\n\\n require(operator != address(0), \\\"Operator can not be zero address\\\");\\n require(\\n self.stakingProviderToOperator[stakingProvider] == address(0),\\n \\\"Operator already set for the staking provider\\\"\\n );\\n require(\\n self.operatorToStakingProvider[operator] == address(0),\\n \\\"Operator address already in use\\\"\\n );\\n\\n // Authorization request for a staking provider who has not yet\\n // registered their operator can be approved immediately.\\n // We need to make sure that the approval happens before operator\\n // is registered to do not let the operator join the sortition pool\\n // with an unresolved authorization decrease request that can be\\n // approved at any point.\\n AuthorizationDecrease storage decrease = self.pendingDecreases[\\n stakingProvider\\n ];\\n require(\\n decrease.decreasingAt == 0,\\n \\\"There is a pending authorization decrease request\\\"\\n );\\n\\n emit OperatorRegistered(stakingProvider, operator);\\n\\n self.stakingProviderToOperator[stakingProvider] = operator;\\n self.operatorToStakingProvider[operator] = stakingProvider;\\n }\\n\\n /// @notice Used by T staking contract to inform the beacon that the\\n /// authorized stake amount for the given staking provider increased.\\n ///\\n /// Reverts if the authorization amount is below the minimum.\\n ///\\n /// The function is not updating the sortition pool. Sortition pool\\n /// state needs to be updated by the operator with a call to\\n /// `joinSortitionPool` or `updateOperatorStatus`.\\n ///\\n /// @dev Should only be callable by T staking contract.\\n function authorizationIncreased(\\n Data storage self,\\n address stakingProvider,\\n uint96 fromAmount,\\n uint96 toAmount\\n ) external {\\n require(\\n toAmount >= self.parameters.minimumAuthorization,\\n \\\"Authorization below the minimum\\\"\\n );\\n\\n // Note that this function does not require the operator address to be\\n // set for the given staking provider. This allows the stake owner\\n // who is also an authorizer to increase the authorization before the\\n // staking provider sets the operator. This allows delegating stake\\n // and increasing authorization immediately one after another without\\n // having to wait for the staking provider to do their part.\\n\\n address operator = self.stakingProviderToOperator[stakingProvider];\\n emit AuthorizationIncreased(\\n stakingProvider,\\n operator,\\n fromAmount,\\n toAmount\\n );\\n }\\n\\n /// @notice Used by T staking contract to inform the beacon that the\\n /// authorization decrease for the given staking provider has been\\n /// requested.\\n ///\\n /// Reverts if the amount after deauthorization would be non-zero\\n /// and lower than the minimum authorization.\\n ///\\n /// Reverts if another authorization decrease request is pending for\\n /// the staking provider and not enough time passed since the\\n /// original request (see `authorizationDecreaseChangePeriod`).\\n ///\\n /// If the operator is not known (`registerOperator` was not called)\\n /// it lets to `approveAuthorizationDecrease` immediately. If the\\n /// operator is known (`registerOperator` was called), the operator\\n /// needs to update state of the sortition pool with a call to\\n /// `joinSortitionPool` or `updateOperatorStatus`. After the\\n /// sortition pool state is in sync, authorization decrease delay\\n /// starts.\\n ///\\n /// After authorization decrease delay passes, authorization\\n /// decrease request needs to be approved with a call to\\n /// `approveAuthorizationDecrease` function.\\n ///\\n /// If there is a pending authorization decrease request, it is\\n /// overwritten, but only if enough time passed since the original\\n /// request. Otherwise, the function reverts.\\n ///\\n /// @dev Should only be callable by T staking contract.\\n function authorizationDecreaseRequested(\\n Data storage self,\\n address stakingProvider,\\n uint96 fromAmount,\\n uint96 toAmount\\n ) public {\\n require(\\n toAmount == 0 || toAmount >= self.parameters.minimumAuthorization,\\n \\\"Authorization amount should be 0 or above the minimum\\\"\\n );\\n\\n address operator = self.stakingProviderToOperator[stakingProvider];\\n\\n uint64 decreasingAt;\\n\\n if (operator == address(0)) {\\n // Operator is not known. It means `registerOperator` was not\\n // called yet, and there is no chance the operator could\\n // call `joinSortitionPool`. We can let to approve authorization\\n // decrease immediately because that operator was never in the\\n // sortition pool.\\n\\n // solhint-disable-next-line not-rely-on-time\\n decreasingAt = uint64(block.timestamp);\\n } else {\\n // Operator is known. It means that this operator is or was in\\n // the sortition pool. Before authorization decrease delay starts,\\n // the operator needs to update the state of the sortition pool\\n // with a call to `joinSortitionPool` or `updateOperatorStatus`.\\n // For now, we set `decreasingAt` as \\\"never decreasing\\\" and let\\n // it be updated by `joinSortitionPool` or `updateOperatorStatus`\\n // once we know the sortition pool is in sync.\\n decreasingAt = type(uint64).max;\\n }\\n\\n uint96 decreasingBy = fromAmount - toAmount;\\n\\n AuthorizationDecrease storage decreaseRequest = self.pendingDecreases[\\n stakingProvider\\n ];\\n\\n uint64 pendingDecreaseAt = decreaseRequest.decreasingAt;\\n if (pendingDecreaseAt != 0 && pendingDecreaseAt != type(uint64).max) {\\n // If there is already a pending authorization decrease request for\\n // this staking provider and that request has been activated\\n // (sortition pool was updated), require enough time to pass before\\n // it can be overwritten.\\n require(\\n // solhint-disable-next-line not-rely-on-time\\n block.timestamp >=\\n pendingDecreaseAt -\\n self.parameters.authorizationDecreaseChangePeriod,\\n \\\"Not enough time passed since the original request\\\"\\n );\\n }\\n\\n decreaseRequest.decreasingBy = decreasingBy;\\n decreaseRequest.decreasingAt = decreasingAt;\\n\\n emit AuthorizationDecreaseRequested(\\n stakingProvider,\\n operator,\\n fromAmount,\\n toAmount,\\n decreasingAt\\n );\\n }\\n\\n /// @notice Approves the previously registered authorization decrease\\n /// request. Reverts if authorization decrease delay have not passed\\n /// yet or if the authorization decrease was not requested for the\\n /// given staking provider.\\n function approveAuthorizationDecrease(\\n Data storage self,\\n IStaking tokenStaking,\\n address stakingProvider\\n ) public {\\n AuthorizationDecrease storage decrease = self.pendingDecreases[\\n stakingProvider\\n ];\\n require(\\n decrease.decreasingAt > 0,\\n \\\"Authorization decrease not requested\\\"\\n );\\n require(\\n decrease.decreasingAt != type(uint64).max,\\n \\\"Authorization decrease request not activated\\\"\\n );\\n require(\\n // solhint-disable-next-line not-rely-on-time\\n block.timestamp >= decrease.decreasingAt,\\n \\\"Authorization decrease delay not passed\\\"\\n );\\n\\n emit AuthorizationDecreaseApproved(stakingProvider);\\n\\n // slither-disable-next-line unused-return\\n tokenStaking.approveAuthorizationDecrease(stakingProvider);\\n delete self.pendingDecreases[stakingProvider];\\n }\\n\\n /// @notice Used by T staking contract to inform the beacon the\\n /// authorization has been decreased for the given staking provider\\n /// involuntarily, as a result of slashing.\\n ///\\n /// If the operator is not known (`registerOperator` was not called)\\n /// the function does nothing. The operator was never in a sortition\\n /// pool so there is nothing to update.\\n ///\\n /// If the operator is known, sortition pool is unlocked, and the\\n /// operator is in the sortition pool, the sortition pool state is\\n /// updated. If the sortition pool is locked, update needs to be\\n /// postponed. Every other staker is incentivized to call\\n /// `updateOperatorStatus` for the problematic operator to increase\\n /// their own rewards in the pool.\\n ///\\n /// @dev Should only be callable by T staking contract.\\n function involuntaryAuthorizationDecrease(\\n Data storage self,\\n IStaking tokenStaking,\\n SortitionPool sortitionPool,\\n address stakingProvider,\\n uint96 fromAmount,\\n uint96 toAmount\\n ) external {\\n address operator = self.stakingProviderToOperator[stakingProvider];\\n\\n if (operator == address(0)) {\\n // Operator is not known. It means `registerOperator` was not\\n // called yet, and there is no chance the operator could\\n // call `joinSortitionPool`. We can just ignore this update because\\n // operator was never in the sortition pool.\\n return;\\n } else {\\n // Operator is known. It means that this operator is or was in the\\n // sortition pool and the sortition pool may need to be updated.\\n //\\n // If the sortition pool is not locked and the operator is in the\\n // sortition pool, we are updating it.\\n //\\n // To keep stakes synchronized between applications when staking\\n // providers are slashed, without the risk of running out of gas,\\n // the staking contract queues up slashings and let users process\\n // the transactions. When an application slashes one or more staking\\n // providers, it adds them to the slashing queue on the staking\\n // contract. A queue entry contains the staking provider\\u2019s address\\n // and the amount they are due to be slashed.\\n //\\n // When there is at least one staking provider in the slashing\\n // queue, any account can submit a transaction processing one or\\n // more staking providers' slashings, and collecting a reward for\\n // doing so. A queued slashing is processed by updating the staking\\n // provider\\u2019s stake to the post-slashing amount, updating authorized\\n // amount for each affected application, and notifying all affected\\n // applications that the staking provider\\u2019s authorized stake has\\n // been reduced due to slashing.\\n //\\n // The entire idea is that the process transaction is expensive\\n // because each application needs to be updated, so the reward for\\n // the processor is hefty and comes from the slashed tokens.\\n // Practically, it means that if the sortition pool is unlocked, and\\n // can be updated, it should be updated because we already paid\\n // someone for updating it.\\n //\\n // If the sortition pool is locked, update needs to wait. Other\\n // sortition pool members are incentivized to call\\n // `updateOperatorStatus` for the problematic operator because they\\n // will increase their rewards this way.\\n if (sortitionPool.isOperatorInPool(operator)) {\\n if (sortitionPool.isLocked()) {\\n emit InvoluntaryAuthorizationDecreaseFailed(\\n stakingProvider,\\n operator,\\n fromAmount,\\n toAmount\\n );\\n } else {\\n updateOperatorStatus(\\n self,\\n tokenStaking,\\n sortitionPool,\\n operator\\n );\\n }\\n }\\n }\\n }\\n\\n /// @notice Lets the operator join the sortition pool. The operator address\\n /// must be known - before calling this function, it has to be\\n /// appointed by the staking provider by calling `registerOperator`.\\n /// Also, the operator must have the minimum authorization required\\n /// by the beacon. Function reverts if there is no minimum stake\\n /// authorized or if the operator is not known. If there was an\\n /// authorization decrease requested, it is activated by starting\\n /// the authorization decrease delay.\\n function joinSortitionPool(\\n Data storage self,\\n IStaking tokenStaking,\\n SortitionPool sortitionPool\\n ) public {\\n address operator = msg.sender;\\n\\n address stakingProvider = self.operatorToStakingProvider[operator];\\n require(stakingProvider != address(0), \\\"Unknown operator\\\");\\n\\n AuthorizationDecrease storage decrease = self.pendingDecreases[\\n stakingProvider\\n ];\\n\\n uint96 _eligibleStake = eligibleStake(\\n self,\\n tokenStaking,\\n stakingProvider,\\n decrease.decreasingBy\\n );\\n\\n require(_eligibleStake != 0, \\\"Authorization below the minimum\\\");\\n\\n emit OperatorJoinedSortitionPool(stakingProvider, operator);\\n\\n sortitionPool.insertOperator(operator, _eligibleStake);\\n\\n // If there is a pending authorization decrease request, activate it.\\n // At this point, the sortition pool state is up to date so the\\n // authorization decrease delay can start counting.\\n if (decrease.decreasingAt == type(uint64).max) {\\n decrease.decreasingAt =\\n // solhint-disable-next-line not-rely-on-time\\n uint64(block.timestamp) +\\n self.parameters.authorizationDecreaseDelay;\\n }\\n }\\n\\n /// @notice Updates status of the operator in the sortition pool. If there\\n /// was an authorization decrease requested, it is activated by\\n /// starting the authorization decrease delay.\\n /// Function reverts if the operator is not known.\\n function updateOperatorStatus(\\n Data storage self,\\n IStaking tokenStaking,\\n SortitionPool sortitionPool,\\n address operator\\n ) public {\\n address stakingProvider = self.operatorToStakingProvider[operator];\\n require(stakingProvider != address(0), \\\"Unknown operator\\\");\\n\\n AuthorizationDecrease storage decrease = self.pendingDecreases[\\n stakingProvider\\n ];\\n\\n emit OperatorStatusUpdated(stakingProvider, operator);\\n\\n if (sortitionPool.isOperatorInPool(operator)) {\\n uint96 _eligibleStake = eligibleStake(\\n self,\\n tokenStaking,\\n stakingProvider,\\n decrease.decreasingBy\\n );\\n\\n sortitionPool.updateOperatorStatus(operator, _eligibleStake);\\n }\\n\\n // If there is a pending authorization decrease request, activate it.\\n // At this point, the sortition pool state is up to date so the\\n // authorization decrease delay can start counting.\\n if (decrease.decreasingAt == type(uint64).max) {\\n decrease.decreasingAt =\\n // solhint-disable-next-line not-rely-on-time\\n uint64(block.timestamp) +\\n self.parameters.authorizationDecreaseDelay;\\n }\\n }\\n\\n /// @notice Checks if the operator's authorized stake is in sync with\\n /// operator's weight in the sortition pool.\\n /// If the operator is not in the sortition pool and their\\n /// authorized stake is non-zero, function returns false.\\n function isOperatorUpToDate(\\n Data storage self,\\n IStaking tokenStaking,\\n SortitionPool sortitionPool,\\n address operator\\n ) external view returns (bool) {\\n address stakingProvider = self.operatorToStakingProvider[operator];\\n require(stakingProvider != address(0), \\\"Unknown operator\\\");\\n\\n AuthorizationDecrease storage decrease = self.pendingDecreases[\\n stakingProvider\\n ];\\n\\n uint96 _eligibleStake = eligibleStake(\\n self,\\n tokenStaking,\\n stakingProvider,\\n decrease.decreasingBy\\n );\\n\\n if (!sortitionPool.isOperatorInPool(operator)) {\\n return _eligibleStake == 0;\\n } else {\\n return sortitionPool.isOperatorUpToDate(operator, _eligibleStake);\\n }\\n }\\n\\n /// @notice Returns the current value of the staking provider's eligible\\n /// stake. Eligible stake is defined as the currently authorized\\n /// stake minus the pending authorization decrease. Eligible stake\\n /// is what is used for operator's weight in the pool. If the\\n /// authorized stake minus the pending authorization decrease is\\n /// below the minimum authorization, eligible stake is 0.\\n /// @dev This function can be exposed to the public in contrast to the\\n /// second variant accepting `decreasingBy` as a parameter.\\n function eligibleStake(\\n Data storage self,\\n IStaking tokenStaking,\\n address stakingProvider\\n ) external view returns (uint96) {\\n return\\n eligibleStake(\\n self,\\n tokenStaking,\\n stakingProvider,\\n pendingAuthorizationDecrease(self, stakingProvider)\\n );\\n }\\n\\n /// @notice Returns the current value of the staking provider's eligible\\n /// stake. Eligible stake is defined as the currently authorized\\n /// stake minus the pending authorization decrease. Eligible stake\\n /// is what is used for operator's weight in the pool. If the\\n /// authorized stake minus the pending authorization decrease is\\n /// below the minimum authorization, eligible stake is 0.\\n /// @dev This function is not intended to be exposes to the public.\\n /// `decreasingBy` must be fetched from `pendingDecreases` mapping and\\n /// it is passed as a parameter to optimize gas usage of functions that\\n /// call `eligibleStake` and need to use `AuthorizationDecrease`\\n /// fetched from `pendingDecreases` for some additional logic.\\n function eligibleStake(\\n Data storage self,\\n IStaking tokenStaking,\\n address stakingProvider,\\n uint96 decreasingBy\\n ) public view returns (uint96) {\\n uint96 authorizedStake = tokenStaking.authorizedStake(\\n stakingProvider,\\n address(this)\\n );\\n\\n uint96 _eligibleStake = authorizedStake > decreasingBy\\n ? authorizedStake - decreasingBy\\n : 0;\\n\\n if (_eligibleStake < self.parameters.minimumAuthorization) {\\n return 0;\\n } else {\\n return _eligibleStake;\\n }\\n }\\n\\n /// @notice Returns the amount of stake that is pending authorization\\n /// decrease for the given staking provider. If no authorization\\n /// decrease has been requested, returns zero.\\n function pendingAuthorizationDecrease(\\n Data storage self,\\n address stakingProvider\\n ) public view returns (uint96) {\\n AuthorizationDecrease storage decrease = self.pendingDecreases[\\n stakingProvider\\n ];\\n\\n return decrease.decreasingBy;\\n }\\n\\n /// @notice Returns the remaining time in seconds that needs to pass before\\n /// the requested authorization decrease can be approved.\\n /// If the sortition pool state was not updated yet by the operator\\n /// after requesting the authorization decrease, returns\\n /// `type(uint64).max`.\\n function remainingAuthorizationDecreaseDelay(\\n Data storage self,\\n address stakingProvider\\n ) external view returns (uint64) {\\n AuthorizationDecrease storage decrease = self.pendingDecreases[\\n stakingProvider\\n ];\\n\\n if (decrease.decreasingAt == type(uint64).max) {\\n return type(uint64).max;\\n }\\n\\n // solhint-disable-next-line not-rely-on-time\\n uint64 _now = uint64(block.timestamp);\\n return _now > decrease.decreasingAt ? 0 : decrease.decreasingAt - _now;\\n }\\n}\\n\",\"keccak256\":\"0xe146f4a3c662e971317d0189b2fca613f9f83a163ef682ed1e536e6c1f919a08\",\"license\":\"GPL-3.0-only\"}},\"version\":1}",
193
- "bytecode": "0x61167561003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100d85760003560e01c8063b86b341e11610096578063d563485c11610070578063d563485c14610233578063db82504e14610253578063ee7ae2a914610273578063f4dbcff41461028657600080fd5b8063b86b341e146101b2578063bf865212146101dd578063c6e1c8391461021357600080fd5b80624f4ac7146100dd578063251db5981461010d57806345e592941461012f578063475592631461014f578063520502841461016f578063520c3d3114610192575b600080fd5b6100f06100eb3660046112f2565b6102f1565b6040516001600160401b0390911681526020015b60405180910390f35b81801561011957600080fd5b5061012d610128366004611322565b61038b565b005b81801561013b57600080fd5b5061012d61014a366004611379565b6105d1565b81801561015b57600080fd5b5061012d61016a3660046112f2565b61073d565b61018261017d3660046113f2565b6109a0565b6040519015158152602001610104565b81801561019e57600080fd5b5061012d6101ad366004611322565b610b16565b6101c56101c0366004611322565b610cf0565b6040516001600160601b039091168152602001610104565b6101c56101eb3660046112f2565b6001600160a01b0316600090815260039190910160205260409020546001600160601b031690565b81801561021f57600080fd5b5061012d61022e3660046113f2565b610d23565b81801561023f57600080fd5b5061012d61024e366004611445565b610f02565b81801561025f57600080fd5b5061012d61026e366004611445565b610fcf565b6101c561028136600461148d565b61120a565b81801561029257600080fd5b5061012d6102a13660046114e1565b83546001600160601b03939093166001600160a01b031990931692909217600160601b6001600160401b03928316021767ffffffffffffffff60a01b1916600160a01b9290911691909102179055565b6001600160a01b03811660009081526003830160205260408120805467fffffffffffffffe19600160601b9091046001600160401b03160161033d576001600160401b03915050610385565b805442906001600160401b03600160601b90910481169082161161037d578154610378908290600160601b90046001600160401b0316611546565b610380565b60005b925050505b92915050565b6001600160a01b038116600090815260038401602052604090208054600160601b90046001600160401b03166104145760405162461bcd60e51b8152602060048201526024808201527f417574686f72697a6174696f6e206465637265617365206e6f742072657175656044820152631cdd195960e21b60648201526084015b60405180910390fd5b805467fffffffffffffffe19600160601b9091046001600160401b0316016104935760405162461bcd60e51b815260206004820152602c60248201527f417574686f72697a6174696f6e2064656372656173652072657175657374206e60448201526b1bdd081858dd1a5d985d195960a21b606482015260840161040b565b8054600160601b90046001600160401b03164210156105045760405162461bcd60e51b815260206004820152602760248201527f417574686f72697a6174696f6e2064656372656173652064656c6179206e6f74604482015266081c185cdcd95960ca1b606482015260840161040b565b6040516001600160a01b038316907f50270a522c2fef97b6b7385c2aa4a4518adda681530e0a1fe9f5e840f6f2cd9d90600090a2604051633af0572d60e11b81526001600160a01b0383811660048301528416906375e0ae5a906024016020604051808303816000875af1158015610580573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a4919061156d565b50506001600160a01b031660009081526003909201602052506040902080546001600160a01b0319169055565b6001600160a01b03808416600090815260018801602052604090205416806105f95750610735565b6040516307b8c36760e51b81526001600160a01b03828116600483015286169063f7186ce090602401602060405180830381865afa15801561063f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106639190611591565b1561073357846001600160a01b031663a4e2d6346040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ca9190611591565b1561072757604080516001600160601b038086168252841660208201526001600160a01b0380841692908716917f1b09380d63e78fd72c1d79a805a7e2dfadf02b22418e24bebff51376b7df33b0910160405180910390a3610733565b61073387878784610d23565b505b505050505050565b336001600160a01b0382166107945760405162461bcd60e51b815260206004820181905260248201527f4f70657261746f722063616e206e6f74206265207a65726f2061646472657373604482015260640161040b565b6001600160a01b03818116600090815260018501602052604090205416156108145760405162461bcd60e51b815260206004820152602d60248201527f4f70657261746f7220616c72656164792073657420666f72207468652073746160448201526c35b4b73390383937bb34b232b960991b606482015260840161040b565b6001600160a01b038281166000908152600285016020526040902054161561087e5760405162461bcd60e51b815260206004820152601f60248201527f4f70657261746f72206164647265737320616c726561647920696e2075736500604482015260640161040b565b6001600160a01b038116600090815260038401602052604090208054600160601b90046001600160401b0316156109115760405162461bcd60e51b815260206004820152603160248201527f546865726520697320612070656e64696e6720617574686f72697a6174696f6e60448201527008191958dc99585cd9481c995c5d595cdd607a1b606482015260840161040b565b826001600160a01b0316826001600160a01b03167fa453db612af59e5521d6ab9284dc3e2d06af286eb1b1b7b771fce4716c19f2c160405160405180910390a3506001600160a01b03908116600081815260018501602090815260408083208054959096166001600160a01b031995861681179096559482526002909501909452919092208054909216179055565b6001600160a01b038082166000908152600286016020526040812054909116806109dc5760405162461bcd60e51b815260040161040b906115b3565b6001600160a01b038116600090815260038701602052604081208054909190610a13908990899086906001600160601b031661120a565b6040516307b8c36760e51b81526001600160a01b0387811660048301529192509087169063f7186ce090602401602060405180830381865afa158015610a5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a819190611591565b610a99576001600160601b0316159250610b0e915050565b6040516304de824f60e41b81526001600160a01b03871690634de824f090610ac790889085906004016115dd565b602060405180830381865afa158015610ae4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b089190611591565b93505050505b949350505050565b3360008181526002850160205260409020546001600160a01b031680610b4e5760405162461bcd60e51b815260040161040b906115b3565b6001600160a01b038116600090815260038601602052604081208054909190610b85908890889086906001600160601b031661120a565b9050806001600160601b0316600003610be05760405162461bcd60e51b815260206004820152601f60248201527f417574686f72697a6174696f6e2062656c6f7720746865206d696e696d756d00604482015260640161040b565b836001600160a01b0316836001600160a01b03167f5075aaa89894a888eb2cac81a27320c60855febb0cf1706b66bdc754e640d43360405160405180910390a3604051630483483160e31b81526001600160a01b0386169063241a418890610c4e90879085906004016115dd565b600060405180830381600087803b158015610c6857600080fd5b505af1158015610c7c573d6000803e3d6000fd5b5050835467fffffffffffffffe19600160601b9091046001600160401b03160191506107339050578654610cc090600160601b90046001600160401b0316426115ff565b82546001600160401b0391909116600160601b0267ffffffffffffffff60601b1990911617825550505050505050565b6001600160a01b0381166000908152600384016020526040812054610b0e908590859085906001600160601b031661120a565b6001600160a01b0380821660009081526002860160205260409020541680610d5d5760405162461bcd60e51b815260040161040b906115b3565b6001600160a01b03808216600081815260038801602052604080822090519093861692917f1231fe5ee649a593b524a494cd53146a196380a872115a0d0fe16c0735afdf2691a36040516307b8c36760e51b81526001600160a01b03848116600483015285169063f7186ce090602401602060405180830381865afa158015610dea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0e9190611591565b15610e95578054600090610e30908890889086906001600160601b031661120a565b60405163dc7520c560e01b81529091506001600160a01b0386169063dc7520c590610e6190879085906004016115dd565b600060405180830381600087803b158015610e7b57600080fd5b505af1158015610e8f573d6000803e3d6000fd5b50505050505b805467fffffffffffffffe19600160601b9091046001600160401b031601610735578554610ed390600160601b90046001600160401b0316426115ff565b81546001600160401b0391909116600160601b0267ffffffffffffffff60601b19909116178155505050505050565b83546001600160601b039081169082161015610f605760405162461bcd60e51b815260206004820152601f60248201527f417574686f72697a6174696f6e2062656c6f7720746865206d696e696d756d00604482015260640161040b565b6001600160a01b0383811660008181526001870160209081526040918290205482516001600160601b03888116825287169281019290925282519416938493927f87f9f9f59204f53d57a89a817c6083a17979cd0531791c91e18551a56e3cfdd7928290030190a35050505050565b6001600160601b0381161580610ff3575083546001600160601b0390811690821610155b61105d5760405162461bcd60e51b815260206004820152603560248201527f417574686f72697a6174696f6e20616d6f756e742073686f756c642062652030604482015274206f722061626f766520746865206d696e696d756d60581b606482015260840161040b565b6001600160a01b0380841660009081526001860160205260408120549091169081611089575042611093565b506001600160401b035b600061109f848661161f565b6001600160a01b03871660009081526003890160205260409020805491925090600160601b90046001600160401b031680158015906110e757506001600160401b0381811614155b1561117a57885461110890600160a01b90046001600160401b031682611546565b6001600160401b031642101561117a5760405162461bcd60e51b815260206004820152603160248201527f4e6f7420656e6f7567682074696d65207061737365642073696e636520746865604482015270081bdc9a59da5b985b081c995c5d595cdd607a1b606482015260840161040b565b81546001600160401b038516600160601b81026001600160a01b03199092166001600160601b0386811691909117929092178455604080518a8416815292891660208401528201526001600160a01b0386811691908a16907f545cbf267cef6fe43f11f6219417ab43a0e8e345adbaae5f626d9bc325e8535a9060600160405180910390a3505050505050505050565b604051637004922d60e11b81526001600160a01b038381166004830152306024830152600091829186169063e009245a90604401602060405180830381865afa15801561125b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127f919061156d565b90506000836001600160601b0316826001600160601b0316116112a35760006112ad565b6112ad848361161f565b87549091506001600160601b0390811690821610156112d157600092505050610b0e565b9150610b0e9050565b6001600160a01b03811681146112ef57600080fd5b50565b6000806040838503121561130557600080fd5b823591506020830135611317816112da565b809150509250929050565b60008060006060848603121561133757600080fd5b833592506020840135611349816112da565b91506040840135611359816112da565b809150509250925092565b6001600160601b03811681146112ef57600080fd5b60008060008060008060c0878903121561139257600080fd5b8635955060208701356113a4816112da565b945060408701356113b4816112da565b935060608701356113c4816112da565b925060808701356113d481611364565b915060a08701356113e481611364565b809150509295509295509295565b6000806000806080858703121561140857600080fd5b84359350602085013561141a816112da565b9250604085013561142a816112da565b9150606085013561143a816112da565b939692955090935050565b6000806000806080858703121561145b57600080fd5b84359350602085013561146d816112da565b9250604085013561147d81611364565b9150606085013561143a81611364565b600080600080608085870312156114a357600080fd5b8435935060208501356114b5816112da565b9250604085013561147d816112da565b80356001600160401b03811681146114dc57600080fd5b919050565b600080600080608085870312156114f757600080fd5b84359350602085013561150981611364565b9250611517604086016114c5565b9150611525606086016114c5565b905092959194509250565b634e487b7160e01b600052601160045260246000fd5b6001600160401b0382811682821603908082111561156657611566611530565b5092915050565b60006020828403121561157f57600080fd5b815161158a81611364565b9392505050565b6000602082840312156115a357600080fd5b8151801515811461158a57600080fd5b60208082526010908201526f2ab735b737bbb71037b832b930ba37b960811b604082015260600190565b6001600160a01b039290921682526001600160601b0316602082015260400190565b6001600160401b0381811683821601908082111561156657611566611530565b6001600160601b038281168282160390808211156115665761156661153056fea2646970667358221220ad4d9c70f3de9064783e7987b074929bfa09dbb743989b1fd35e372d981d37b964736f6c63430008110033",
194
- "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600436106100d85760003560e01c8063b86b341e11610096578063d563485c11610070578063d563485c14610233578063db82504e14610253578063ee7ae2a914610273578063f4dbcff41461028657600080fd5b8063b86b341e146101b2578063bf865212146101dd578063c6e1c8391461021357600080fd5b80624f4ac7146100dd578063251db5981461010d57806345e592941461012f578063475592631461014f578063520502841461016f578063520c3d3114610192575b600080fd5b6100f06100eb3660046112f2565b6102f1565b6040516001600160401b0390911681526020015b60405180910390f35b81801561011957600080fd5b5061012d610128366004611322565b61038b565b005b81801561013b57600080fd5b5061012d61014a366004611379565b6105d1565b81801561015b57600080fd5b5061012d61016a3660046112f2565b61073d565b61018261017d3660046113f2565b6109a0565b6040519015158152602001610104565b81801561019e57600080fd5b5061012d6101ad366004611322565b610b16565b6101c56101c0366004611322565b610cf0565b6040516001600160601b039091168152602001610104565b6101c56101eb3660046112f2565b6001600160a01b0316600090815260039190910160205260409020546001600160601b031690565b81801561021f57600080fd5b5061012d61022e3660046113f2565b610d23565b81801561023f57600080fd5b5061012d61024e366004611445565b610f02565b81801561025f57600080fd5b5061012d61026e366004611445565b610fcf565b6101c561028136600461148d565b61120a565b81801561029257600080fd5b5061012d6102a13660046114e1565b83546001600160601b03939093166001600160a01b031990931692909217600160601b6001600160401b03928316021767ffffffffffffffff60a01b1916600160a01b9290911691909102179055565b6001600160a01b03811660009081526003830160205260408120805467fffffffffffffffe19600160601b9091046001600160401b03160161033d576001600160401b03915050610385565b805442906001600160401b03600160601b90910481169082161161037d578154610378908290600160601b90046001600160401b0316611546565b610380565b60005b925050505b92915050565b6001600160a01b038116600090815260038401602052604090208054600160601b90046001600160401b03166104145760405162461bcd60e51b8152602060048201526024808201527f417574686f72697a6174696f6e206465637265617365206e6f742072657175656044820152631cdd195960e21b60648201526084015b60405180910390fd5b805467fffffffffffffffe19600160601b9091046001600160401b0316016104935760405162461bcd60e51b815260206004820152602c60248201527f417574686f72697a6174696f6e2064656372656173652072657175657374206e60448201526b1bdd081858dd1a5d985d195960a21b606482015260840161040b565b8054600160601b90046001600160401b03164210156105045760405162461bcd60e51b815260206004820152602760248201527f417574686f72697a6174696f6e2064656372656173652064656c6179206e6f74604482015266081c185cdcd95960ca1b606482015260840161040b565b6040516001600160a01b038316907f50270a522c2fef97b6b7385c2aa4a4518adda681530e0a1fe9f5e840f6f2cd9d90600090a2604051633af0572d60e11b81526001600160a01b0383811660048301528416906375e0ae5a906024016020604051808303816000875af1158015610580573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a4919061156d565b50506001600160a01b031660009081526003909201602052506040902080546001600160a01b0319169055565b6001600160a01b03808416600090815260018801602052604090205416806105f95750610735565b6040516307b8c36760e51b81526001600160a01b03828116600483015286169063f7186ce090602401602060405180830381865afa15801561063f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106639190611591565b1561073357846001600160a01b031663a4e2d6346040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ca9190611591565b1561072757604080516001600160601b038086168252841660208201526001600160a01b0380841692908716917f1b09380d63e78fd72c1d79a805a7e2dfadf02b22418e24bebff51376b7df33b0910160405180910390a3610733565b61073387878784610d23565b505b505050505050565b336001600160a01b0382166107945760405162461bcd60e51b815260206004820181905260248201527f4f70657261746f722063616e206e6f74206265207a65726f2061646472657373604482015260640161040b565b6001600160a01b03818116600090815260018501602052604090205416156108145760405162461bcd60e51b815260206004820152602d60248201527f4f70657261746f7220616c72656164792073657420666f72207468652073746160448201526c35b4b73390383937bb34b232b960991b606482015260840161040b565b6001600160a01b038281166000908152600285016020526040902054161561087e5760405162461bcd60e51b815260206004820152601f60248201527f4f70657261746f72206164647265737320616c726561647920696e2075736500604482015260640161040b565b6001600160a01b038116600090815260038401602052604090208054600160601b90046001600160401b0316156109115760405162461bcd60e51b815260206004820152603160248201527f546865726520697320612070656e64696e6720617574686f72697a6174696f6e60448201527008191958dc99585cd9481c995c5d595cdd607a1b606482015260840161040b565b826001600160a01b0316826001600160a01b03167fa453db612af59e5521d6ab9284dc3e2d06af286eb1b1b7b771fce4716c19f2c160405160405180910390a3506001600160a01b03908116600081815260018501602090815260408083208054959096166001600160a01b031995861681179096559482526002909501909452919092208054909216179055565b6001600160a01b038082166000908152600286016020526040812054909116806109dc5760405162461bcd60e51b815260040161040b906115b3565b6001600160a01b038116600090815260038701602052604081208054909190610a13908990899086906001600160601b031661120a565b6040516307b8c36760e51b81526001600160a01b0387811660048301529192509087169063f7186ce090602401602060405180830381865afa158015610a5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a819190611591565b610a99576001600160601b0316159250610b0e915050565b6040516304de824f60e41b81526001600160a01b03871690634de824f090610ac790889085906004016115dd565b602060405180830381865afa158015610ae4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b089190611591565b93505050505b949350505050565b3360008181526002850160205260409020546001600160a01b031680610b4e5760405162461bcd60e51b815260040161040b906115b3565b6001600160a01b038116600090815260038601602052604081208054909190610b85908890889086906001600160601b031661120a565b9050806001600160601b0316600003610be05760405162461bcd60e51b815260206004820152601f60248201527f417574686f72697a6174696f6e2062656c6f7720746865206d696e696d756d00604482015260640161040b565b836001600160a01b0316836001600160a01b03167f5075aaa89894a888eb2cac81a27320c60855febb0cf1706b66bdc754e640d43360405160405180910390a3604051630483483160e31b81526001600160a01b0386169063241a418890610c4e90879085906004016115dd565b600060405180830381600087803b158015610c6857600080fd5b505af1158015610c7c573d6000803e3d6000fd5b5050835467fffffffffffffffe19600160601b9091046001600160401b03160191506107339050578654610cc090600160601b90046001600160401b0316426115ff565b82546001600160401b0391909116600160601b0267ffffffffffffffff60601b1990911617825550505050505050565b6001600160a01b0381166000908152600384016020526040812054610b0e908590859085906001600160601b031661120a565b6001600160a01b0380821660009081526002860160205260409020541680610d5d5760405162461bcd60e51b815260040161040b906115b3565b6001600160a01b03808216600081815260038801602052604080822090519093861692917f1231fe5ee649a593b524a494cd53146a196380a872115a0d0fe16c0735afdf2691a36040516307b8c36760e51b81526001600160a01b03848116600483015285169063f7186ce090602401602060405180830381865afa158015610dea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0e9190611591565b15610e95578054600090610e30908890889086906001600160601b031661120a565b60405163dc7520c560e01b81529091506001600160a01b0386169063dc7520c590610e6190879085906004016115dd565b600060405180830381600087803b158015610e7b57600080fd5b505af1158015610e8f573d6000803e3d6000fd5b50505050505b805467fffffffffffffffe19600160601b9091046001600160401b031601610735578554610ed390600160601b90046001600160401b0316426115ff565b81546001600160401b0391909116600160601b0267ffffffffffffffff60601b19909116178155505050505050565b83546001600160601b039081169082161015610f605760405162461bcd60e51b815260206004820152601f60248201527f417574686f72697a6174696f6e2062656c6f7720746865206d696e696d756d00604482015260640161040b565b6001600160a01b0383811660008181526001870160209081526040918290205482516001600160601b03888116825287169281019290925282519416938493927f87f9f9f59204f53d57a89a817c6083a17979cd0531791c91e18551a56e3cfdd7928290030190a35050505050565b6001600160601b0381161580610ff3575083546001600160601b0390811690821610155b61105d5760405162461bcd60e51b815260206004820152603560248201527f417574686f72697a6174696f6e20616d6f756e742073686f756c642062652030604482015274206f722061626f766520746865206d696e696d756d60581b606482015260840161040b565b6001600160a01b0380841660009081526001860160205260408120549091169081611089575042611093565b506001600160401b035b600061109f848661161f565b6001600160a01b03871660009081526003890160205260409020805491925090600160601b90046001600160401b031680158015906110e757506001600160401b0381811614155b1561117a57885461110890600160a01b90046001600160401b031682611546565b6001600160401b031642101561117a5760405162461bcd60e51b815260206004820152603160248201527f4e6f7420656e6f7567682074696d65207061737365642073696e636520746865604482015270081bdc9a59da5b985b081c995c5d595cdd607a1b606482015260840161040b565b81546001600160401b038516600160601b81026001600160a01b03199092166001600160601b0386811691909117929092178455604080518a8416815292891660208401528201526001600160a01b0386811691908a16907f545cbf267cef6fe43f11f6219417ab43a0e8e345adbaae5f626d9bc325e8535a9060600160405180910390a3505050505050505050565b604051637004922d60e11b81526001600160a01b038381166004830152306024830152600091829186169063e009245a90604401602060405180830381865afa15801561125b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127f919061156d565b90506000836001600160601b0316826001600160601b0316116112a35760006112ad565b6112ad848361161f565b87549091506001600160601b0390811690821610156112d157600092505050610b0e565b9150610b0e9050565b6001600160a01b03811681146112ef57600080fd5b50565b6000806040838503121561130557600080fd5b823591506020830135611317816112da565b809150509250929050565b60008060006060848603121561133757600080fd5b833592506020840135611349816112da565b91506040840135611359816112da565b809150509250925092565b6001600160601b03811681146112ef57600080fd5b60008060008060008060c0878903121561139257600080fd5b8635955060208701356113a4816112da565b945060408701356113b4816112da565b935060608701356113c4816112da565b925060808701356113d481611364565b915060a08701356113e481611364565b809150509295509295509295565b6000806000806080858703121561140857600080fd5b84359350602085013561141a816112da565b9250604085013561142a816112da565b9150606085013561143a816112da565b939692955090935050565b6000806000806080858703121561145b57600080fd5b84359350602085013561146d816112da565b9250604085013561147d81611364565b9150606085013561143a81611364565b600080600080608085870312156114a357600080fd5b8435935060208501356114b5816112da565b9250604085013561147d816112da565b80356001600160401b03811681146114dc57600080fd5b919050565b600080600080608085870312156114f757600080fd5b84359350602085013561150981611364565b9250611517604086016114c5565b9150611525606086016114c5565b905092959194509250565b634e487b7160e01b600052601160045260246000fd5b6001600160401b0382811682821603908082111561156657611566611530565b5092915050565b60006020828403121561157f57600080fd5b815161158a81611364565b9392505050565b6000602082840312156115a357600080fd5b8151801515811461158a57600080fd5b60208082526010908201526f2ab735b737bbb71037b832b930ba37b960811b604082015260600190565b6001600160a01b039290921682526001600160601b0316602082015260400190565b6001600160401b0381811683821601908082111561156657611566611530565b6001600160601b038281168282160390808211156115665761156661153056fea2646970667358221220ad4d9c70f3de9064783e7987b074929bfa09dbb743989b1fd35e372d981d37b964736f6c63430008110033",
192
+ "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"stakingProvider\",\"type\":\"address\"}],\"name\":\"AuthorizationDecreaseApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"stakingProvider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"fromAmount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"toAmount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"decreasingAt\",\"type\":\"uint64\"}],\"name\":\"AuthorizationDecreaseRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"stakingProvider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"fromAmount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"toAmount\",\"type\":\"uint96\"}],\"name\":\"AuthorizationIncreased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"stakingProvider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"fromAmount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"toAmount\",\"type\":\"uint96\"}],\"name\":\"InvoluntaryAuthorizationDecreaseFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"stakingProvider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"OperatorJoinedSortitionPool\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"stakingProvider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"OperatorRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"stakingProvider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"OperatorStatusUpdated\",\"type\":\"event\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"authorizationDecreaseRequested(BeaconAuthorization.Data storage,address,uint96,uint96)\":{\"details\":\"Should only be callable by T staking contract.\"},\"authorizationIncreased(BeaconAuthorization.Data storage,address,uint96,uint96)\":{\"details\":\"Should only be callable by T staking contract.\"},\"eligibleStake(BeaconAuthorization.Data storage,IStaking,address)\":{\"details\":\"This function can be exposed to the public in contrast to the second variant accepting `decreasingBy` as a parameter.\"},\"eligibleStake(BeaconAuthorization.Data storage,IStaking,address,uint96)\":{\"details\":\"This function is not intended to be exposes to the public. `decreasingBy` must be fetched from `pendingDecreases` mapping and it is passed as a parameter to optimize gas usage of functions that call `eligibleStake` and need to use `AuthorizationDecrease` fetched from `pendingDecreases` for some additional logic.\"},\"involuntaryAuthorizationDecrease(BeaconAuthorization.Data storage,IStaking,SortitionPool,address,uint96,uint96)\":{\"details\":\"Should only be callable by T staking contract.\"},\"setParameters(BeaconAuthorization.Data storage,uint96,uint64,uint64)\":{\"params\":{\"_authorizationDecreaseChangePeriod\":\"New value of the authorization decrease change period. It is the time in seconds, before authorization decrease delay end, during which the pending authorization decrease request can be overwritten. If set to 0, pending authorization decrease request can not be overwritten until the entire `authorizationDecreaseDelay` ends. If set to value equal `authorizationDecreaseDelay`, request can always be overwritten.\",\"_authorizationDecreaseDelay\":\"New value of the authorization decrease delay. It is the time in seconds that needs to pass between the time authorization decrease is requested and the time the authorization decrease can be approved, no matter the authorization decrease amount.\",\"_minimumAuthorization\":\"New value of the minimum authorization for the beacon. Without at least the minimum authorization, staking provider is not eligible to join and operate in the network.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"approveAuthorizationDecrease(BeaconAuthorization.Data storage,IStaking,address)\":{\"notice\":\"Approves the previously registered authorization decrease request. Reverts if authorization decrease delay have not passed yet or if the authorization decrease was not requested for the given staking provider.\"},\"authorizationDecreaseRequested(BeaconAuthorization.Data storage,address,uint96,uint96)\":{\"notice\":\"Used by T staking contract to inform the beacon that the authorization decrease for the given staking provider has been requested. Reverts if the amount after deauthorization would be non-zero and lower than the minimum authorization. Reverts if another authorization decrease request is pending for the staking provider and not enough time passed since the original request (see `authorizationDecreaseChangePeriod`). If the operator is not known (`registerOperator` was not called) it lets to `approveAuthorizationDecrease` immediately. If the operator is known (`registerOperator` was called), the operator needs to update state of the sortition pool with a call to `joinSortitionPool` or `updateOperatorStatus`. After the sortition pool state is in sync, authorization decrease delay starts. After authorization decrease delay passes, authorization decrease request needs to be approved with a call to `approveAuthorizationDecrease` function. If there is a pending authorization decrease request, it is overwritten, but only if enough time passed since the original request. Otherwise, the function reverts.\"},\"authorizationIncreased(BeaconAuthorization.Data storage,address,uint96,uint96)\":{\"notice\":\"Used by T staking contract to inform the beacon that the authorized stake amount for the given staking provider increased. Reverts if the authorization amount is below the minimum. The function is not updating the sortition pool. Sortition pool state needs to be updated by the operator with a call to `joinSortitionPool` or `updateOperatorStatus`.\"},\"eligibleStake(BeaconAuthorization.Data storage,IStaking,address)\":{\"notice\":\"Returns the current value of the staking provider's eligible stake. Eligible stake is defined as the currently authorized stake minus the pending authorization decrease. Eligible stake is what is used for operator's weight in the pool. If the authorized stake minus the pending authorization decrease is below the minimum authorization, eligible stake is 0.\"},\"eligibleStake(BeaconAuthorization.Data storage,IStaking,address,uint96)\":{\"notice\":\"Returns the current value of the staking provider's eligible stake. Eligible stake is defined as the currently authorized stake minus the pending authorization decrease. Eligible stake is what is used for operator's weight in the pool. If the authorized stake minus the pending authorization decrease is below the minimum authorization, eligible stake is 0.\"},\"involuntaryAuthorizationDecrease(BeaconAuthorization.Data storage,IStaking,SortitionPool,address,uint96,uint96)\":{\"notice\":\"Used by T staking contract to inform the beacon the authorization has been decreased for the given staking provider involuntarily, as a result of slashing. If the operator is not known (`registerOperator` was not called) the function does nothing. The operator was never in a sortition pool so there is nothing to update. If the operator is known, sortition pool is unlocked, and the operator is in the sortition pool, the sortition pool state is updated. If the sortition pool is locked, update needs to be postponed. Every other staker is incentivized to call `updateOperatorStatus` for the problematic operator to increase their own rewards in the pool.\"},\"isOperatorUpToDate(BeaconAuthorization.Data storage,IStaking,SortitionPool,address)\":{\"notice\":\"Checks if the operator's authorized stake is in sync with operator's weight in the sortition pool. If the operator is not in the sortition pool and their authorized stake is non-zero, function returns false.\"},\"joinSortitionPool(BeaconAuthorization.Data storage,IStaking,SortitionPool)\":{\"notice\":\"Lets the operator join the sortition pool. The operator address must be known - before calling this function, it has to be appointed by the staking provider by calling `registerOperator`. Also, the operator must have the minimum authorization required by the beacon. Function reverts if there is no minimum stake authorized or if the operator is not known. If there was an authorization decrease requested, it is activated by starting the authorization decrease delay.\"},\"pendingAuthorizationDecrease(BeaconAuthorization.Data storage,address)\":{\"notice\":\"Returns the amount of stake that is pending authorization decrease for the given staking provider. If no authorization decrease has been requested, returns zero.\"},\"registerOperator(BeaconAuthorization.Data storage,address)\":{\"notice\":\"Used by staking provider to set operator address that will operate a node. The given staking provider can set operator address only one time. The operator address can not be changed and must be unique. Reverts if the operator is already set for the staking provider or if the operator address is already in use. Reverts if there is a pending authorization decrease for the staking provider.\"},\"remainingAuthorizationDecreaseDelay(BeaconAuthorization.Data storage,address)\":{\"notice\":\"Returns the remaining time in seconds that needs to pass before the requested authorization decrease can be approved. If the sortition pool state was not updated yet by the operator after requesting the authorization decrease, returns `type(uint64).max`.\"},\"setParameters(BeaconAuthorization.Data storage,uint96,uint64,uint64)\":{\"notice\":\"Updates authorization-related parameters.\"},\"updateOperatorStatus(BeaconAuthorization.Data storage,IStaking,SortitionPool,address)\":{\"notice\":\"Updates status of the operator in the sortition pool. If there was an authorization decrease requested, it is activated by starting the authorization decrease delay. Function reverts if the operator is not known.\"}},\"notice\":\"Library managing the state of stake authorizations for the operator contract and the presence of operators in the sortition pool based on the stake authorized for them.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/libraries/BeaconAuthorization.sol\":\"BeaconAuthorization\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@keep-network/sortition-pools/contracts/Branch.sol\":{\"content\":\"pragma solidity 0.8.17;\\n\\nimport \\\"./Constants.sol\\\";\\n\\n/// @notice The implicit 8-ary trees of the sortition pool\\n/// rely on packing 8 \\\"slots\\\" of 32-bit values into each uint256.\\n/// The Branch library permits efficient calculations on these slots.\\nlibrary Branch {\\n /// @notice Calculate the right shift required\\n /// to make the 32 least significant bits of an uint256\\n /// be the bits of the `position`th slot\\n /// when treating the uint256 as a uint32[8].\\n ///\\n /// @dev Not used for efficiency reasons,\\n /// but left to illustrate the meaning of a common pattern.\\n /// I wish solidity had macros, even C macros.\\n function slotShift(uint256 position) internal pure returns (uint256) {\\n unchecked {\\n return position * Constants.SLOT_WIDTH;\\n }\\n }\\n\\n /// @notice Return the `position`th slot of the `node`,\\n /// treating `node` as a uint32[32].\\n function getSlot(uint256 node, uint256 position)\\n internal\\n pure\\n returns (uint256)\\n {\\n unchecked {\\n uint256 shiftBits = position * Constants.SLOT_WIDTH;\\n // Doing a bitwise AND with `SLOT_MAX`\\n // clears all but the 32 least significant bits.\\n // Because of the right shift by `slotShift(position)` bits,\\n // those 32 bits contain the 32 bits in the `position`th slot of `node`.\\n return (node >> shiftBits) & Constants.SLOT_MAX;\\n }\\n }\\n\\n /// @notice Return `node` with the `position`th slot set to zero.\\n function clearSlot(uint256 node, uint256 position)\\n internal\\n pure\\n returns (uint256)\\n {\\n unchecked {\\n uint256 shiftBits = position * Constants.SLOT_WIDTH;\\n // Shifting `SLOT_MAX` left by `slotShift(position)` bits\\n // gives us a number where all bits of the `position`th slot are set,\\n // and all other bits are unset.\\n //\\n // Using a bitwise NOT on this number,\\n // we get a uint256 where all bits are set\\n // except for those of the `position`th slot.\\n //\\n // Bitwise ANDing the original `node` with this number\\n // sets the bits of `position`th slot to zero,\\n // leaving all other bits unchanged.\\n return node & ~(Constants.SLOT_MAX << shiftBits);\\n }\\n }\\n\\n /// @notice Return `node` with the `position`th slot set to `weight`.\\n ///\\n /// @param weight The weight of of the node.\\n /// Safely truncated to a 32-bit number,\\n /// but this should never be called with an overflowing weight regardless.\\n function setSlot(\\n uint256 node,\\n uint256 position,\\n uint256 weight\\n ) internal pure returns (uint256) {\\n unchecked {\\n uint256 shiftBits = position * Constants.SLOT_WIDTH;\\n // Clear the `position`th slot like in `clearSlot()`.\\n uint256 clearedNode = node & ~(Constants.SLOT_MAX << shiftBits);\\n // Bitwise AND `weight` with `SLOT_MAX`\\n // to clear all but the 32 least significant bits.\\n //\\n // Shift this left by `slotShift(position)` bits\\n // to obtain a uint256 with all bits unset\\n // except in the `position`th slot\\n // which contains the 32-bit value of `weight`.\\n uint256 shiftedWeight = (weight & Constants.SLOT_MAX) << shiftBits;\\n // When we bitwise OR these together,\\n // all other slots except the `position`th one come from the left argument,\\n // and the `position`th gets filled with `weight` from the right argument.\\n return clearedNode | shiftedWeight;\\n }\\n }\\n\\n /// @notice Calculate the summed weight of all slots in the `node`.\\n function sumWeight(uint256 node) internal pure returns (uint256 sum) {\\n unchecked {\\n sum = node & Constants.SLOT_MAX;\\n // Iterate through each slot\\n // by shifting `node` right in increments of 32 bits,\\n // and adding the 32 least significant bits to the `sum`.\\n uint256 newNode = node >> Constants.SLOT_WIDTH;\\n while (newNode > 0) {\\n sum += (newNode & Constants.SLOT_MAX);\\n newNode = newNode >> Constants.SLOT_WIDTH;\\n }\\n return sum;\\n }\\n }\\n\\n /// @notice Pick a slot in `node` that corresponds to `index`.\\n /// Treats the node like an array of virtual stakers,\\n /// the number of virtual stakers in each slot corresponding to its weight,\\n /// and picks which slot contains the `index`th virtual staker.\\n ///\\n /// @dev Requires that `index` be lower than `sumWeight(node)`.\\n /// However, this is not enforced for performance reasons.\\n /// If `index` exceeds the permitted range,\\n /// `pickWeightedSlot()` returns the rightmost slot\\n /// and an excessively high `newIndex`.\\n ///\\n /// @return slot The slot of `node` containing the `index`th virtual staker.\\n ///\\n /// @return newIndex The index of the `index`th virtual staker of `node`\\n /// within the returned slot.\\n function pickWeightedSlot(uint256 node, uint256 index)\\n internal\\n pure\\n returns (uint256 slot, uint256 newIndex)\\n {\\n unchecked {\\n newIndex = index;\\n uint256 newNode = node;\\n uint256 currentSlotWeight = newNode & Constants.SLOT_MAX;\\n while (newIndex >= currentSlotWeight) {\\n newIndex -= currentSlotWeight;\\n slot++;\\n newNode = newNode >> Constants.SLOT_WIDTH;\\n currentSlotWeight = newNode & Constants.SLOT_MAX;\\n }\\n return (slot, newIndex);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa7fb1c9c9789f30493e9a40e24a24f46875dc5e7630b4f67478167759f6d1882\"},\"@keep-network/sortition-pools/contracts/Chaosnet.sol\":{\"content\":\"pragma solidity 0.8.17;\\n\\n/// @title Chaosnet\\n/// @notice This is a beta staker program for stakers willing to go the extra\\n/// mile with monitoring, share their logs with the dev team, and allow to more\\n/// carefully monitor the bootstrapping network. As the network matures, the\\n/// beta program will be ended.\\ncontract Chaosnet {\\n /// @notice Indicates if the chaosnet is active. The chaosnet is active\\n /// after the contract deployment and can be ended with a call to\\n /// `deactivateChaosnet()`. Once deactivated chaosnet can not be activated\\n /// again.\\n bool public isChaosnetActive;\\n\\n /// @notice Indicates if the given operator is a beta operator for chaosnet.\\n mapping(address => bool) public isBetaOperator;\\n\\n /// @notice Address controlling chaosnet status and beta operator addresses.\\n address public chaosnetOwner;\\n\\n event BetaOperatorsAdded(address[] operators);\\n\\n event ChaosnetOwnerRoleTransferred(\\n address oldChaosnetOwner,\\n address newChaosnetOwner\\n );\\n\\n event ChaosnetDeactivated();\\n\\n constructor() {\\n _transferChaosnetOwner(msg.sender);\\n isChaosnetActive = true;\\n }\\n\\n modifier onlyChaosnetOwner() {\\n require(msg.sender == chaosnetOwner, \\\"Not the chaosnet owner\\\");\\n _;\\n }\\n\\n modifier onlyOnChaosnet() {\\n require(isChaosnetActive, \\\"Chaosnet is not active\\\");\\n _;\\n }\\n\\n /// @notice Adds beta operator to chaosnet. Can be called only by the\\n /// chaosnet owner when the chaosnet is active. Once the operator is added\\n /// as a beta operator, it can not be removed.\\n function addBetaOperators(address[] calldata operators)\\n public\\n onlyOnChaosnet\\n onlyChaosnetOwner\\n {\\n for (uint256 i = 0; i < operators.length; i++) {\\n isBetaOperator[operators[i]] = true;\\n }\\n\\n emit BetaOperatorsAdded(operators);\\n }\\n\\n /// @notice Deactivates the chaosnet. Can be called only by the chaosnet\\n /// owner. Once deactivated chaosnet can not be activated again.\\n function deactivateChaosnet() public onlyOnChaosnet onlyChaosnetOwner {\\n isChaosnetActive = false;\\n emit ChaosnetDeactivated();\\n }\\n\\n /// @notice Transfers the chaosnet owner role to another non-zero address.\\n function transferChaosnetOwnerRole(address newChaosnetOwner)\\n public\\n onlyChaosnetOwner\\n {\\n require(\\n newChaosnetOwner != address(0),\\n \\\"New chaosnet owner must not be zero address\\\"\\n );\\n _transferChaosnetOwner(newChaosnetOwner);\\n }\\n\\n function _transferChaosnetOwner(address newChaosnetOwner) internal {\\n address oldChaosnetOwner = chaosnetOwner;\\n chaosnetOwner = newChaosnetOwner;\\n emit ChaosnetOwnerRoleTransferred(oldChaosnetOwner, newChaosnetOwner);\\n }\\n}\\n\",\"keccak256\":\"0xeaf7bdd5626f88c329793a012621039692ce1b6e1f13013997ddb13d7e3032df\"},\"@keep-network/sortition-pools/contracts/Constants.sol\":{\"content\":\"pragma solidity 0.8.17;\\n\\nlibrary Constants {\\n ////////////////////////////////////////////////////////////////////////////\\n // Parameters for configuration\\n\\n // How many bits a position uses per level of the tree;\\n // each branch of the tree contains 2**SLOT_BITS slots.\\n uint256 constant SLOT_BITS = 3;\\n uint256 constant LEVELS = 7;\\n ////////////////////////////////////////////////////////////////////////////\\n\\n ////////////////////////////////////////////////////////////////////////////\\n // Derived constants, do not touch\\n uint256 constant SLOT_COUNT = 2**SLOT_BITS;\\n uint256 constant SLOT_WIDTH = 256 / SLOT_COUNT;\\n uint256 constant LAST_SLOT = SLOT_COUNT - 1;\\n uint256 constant SLOT_MAX = (2**SLOT_WIDTH) - 1;\\n uint256 constant POOL_CAPACITY = SLOT_COUNT**LEVELS;\\n\\n uint256 constant ID_WIDTH = SLOT_WIDTH;\\n uint256 constant ID_MAX = SLOT_MAX;\\n\\n uint256 constant BLOCKHEIGHT_WIDTH = 96 - ID_WIDTH;\\n uint256 constant BLOCKHEIGHT_MAX = (2**BLOCKHEIGHT_WIDTH) - 1;\\n\\n uint256 constant SLOT_POINTER_MAX = (2**SLOT_BITS) - 1;\\n uint256 constant LEAF_FLAG = 1 << 255;\\n\\n uint256 constant WEIGHT_WIDTH = 256 / SLOT_COUNT;\\n ////////////////////////////////////////////////////////////////////////////\\n}\\n\",\"keccak256\":\"0xaef690ced707935745ff1482b7bb9bd9eb77bf6a39c717465e64cf12db8a7d39\"},\"@keep-network/sortition-pools/contracts/Leaf.sol\":{\"content\":\"pragma solidity 0.8.17;\\n\\nimport \\\"./Constants.sol\\\";\\n\\nlibrary Leaf {\\n function make(\\n address _operator,\\n uint256 _creationBlock,\\n uint256 _id\\n ) internal pure returns (uint256) {\\n assert(_creationBlock <= type(uint64).max);\\n assert(_id <= type(uint32).max);\\n // Converting a bytesX type into a larger type\\n // adds zero bytes on the right.\\n uint256 op = uint256(bytes32(bytes20(_operator)));\\n // Bitwise AND the id to erase\\n // all but the 32 least significant bits\\n uint256 uid = _id & Constants.ID_MAX;\\n // Erase all but the 64 least significant bits,\\n // then shift left by 32 bits to make room for the id\\n uint256 cb = (_creationBlock & Constants.BLOCKHEIGHT_MAX) <<\\n Constants.ID_WIDTH;\\n // Bitwise OR them all together to get\\n // [address operator || uint64 creationBlock || uint32 id]\\n return (op | cb | uid);\\n }\\n\\n function operator(uint256 leaf) internal pure returns (address) {\\n // Converting a bytesX type into a smaller type\\n // truncates it on the right.\\n return address(bytes20(bytes32(leaf)));\\n }\\n\\n /// @notice Return the block number the leaf was created in.\\n function creationBlock(uint256 leaf) internal pure returns (uint256) {\\n return ((leaf >> Constants.ID_WIDTH) & Constants.BLOCKHEIGHT_MAX);\\n }\\n\\n function id(uint256 leaf) internal pure returns (uint32) {\\n // Id is stored in the 32 least significant bits.\\n // Bitwise AND ensures that we only get the contents of those bits.\\n return uint32(leaf & Constants.ID_MAX);\\n }\\n}\\n\",\"keccak256\":\"0xbd107a1a43e48884885e5e966ffcbcd8fa5e89863715d717bb4006e9f89cdc2b\"},\"@keep-network/sortition-pools/contracts/Position.sol\":{\"content\":\"pragma solidity 0.8.17;\\n\\nimport \\\"./Constants.sol\\\";\\n\\nlibrary Position {\\n // Return the last 3 bits of a position number,\\n // corresponding to its slot in its parent\\n function slot(uint256 a) internal pure returns (uint256) {\\n return a & Constants.SLOT_POINTER_MAX;\\n }\\n\\n // Return the parent of a position number\\n function parent(uint256 a) internal pure returns (uint256) {\\n return a >> Constants.SLOT_BITS;\\n }\\n\\n // Return the location of the child of a at the given slot\\n function child(uint256 a, uint256 s) internal pure returns (uint256) {\\n return (a << Constants.SLOT_BITS) | (s & Constants.SLOT_POINTER_MAX); // slot(s)\\n }\\n\\n // Return the uint p as a flagged position uint:\\n // the least significant 21 bits contain the position\\n // and the 22nd bit is set as a flag\\n // to distinguish the position 0x000000 from an empty field.\\n function setFlag(uint256 p) internal pure returns (uint256) {\\n return p | Constants.LEAF_FLAG;\\n }\\n\\n // Turn a flagged position into an unflagged position\\n // by removing the flag at the 22nd least significant bit.\\n //\\n // We shouldn't _actually_ need this\\n // as all position-manipulating code should ignore non-position bits anyway\\n // but it's cheap to call so might as well do it.\\n function unsetFlag(uint256 p) internal pure returns (uint256) {\\n return p & (~Constants.LEAF_FLAG);\\n }\\n}\\n\",\"keccak256\":\"0xd3a927908080ac21353a92a6bce3d69e94a5c30f6b51f16b271b6cc679f110e2\"},\"@keep-network/sortition-pools/contracts/RNG.sol\":{\"content\":\"pragma solidity 0.8.17;\\n\\nimport \\\"./Leaf.sol\\\";\\nimport \\\"./Constants.sol\\\";\\n\\nlibrary RNG {\\n /// @notice Get an index in the range `[0 .. range-1]`\\n /// and the new state of the RNG,\\n /// using the provided `state` of the RNG.\\n ///\\n /// @param range The upper bound of the index, exclusive.\\n ///\\n /// @param state The previous state of the RNG.\\n /// The initial state needs to be obtained\\n /// from a trusted randomness oracle (the random beacon),\\n /// or from a chain of earlier calls to `RNG.getIndex()`\\n /// on an originally trusted seed.\\n ///\\n /// @dev Calculates the number of bits required for the desired range,\\n /// takes the least significant bits of `state`\\n /// and checks if the obtained index is within the desired range.\\n /// The original state is hashed with `keccak256` to get a new state.\\n /// If the index is outside the range,\\n /// the function retries until it gets a suitable index.\\n ///\\n /// @return index A random integer between `0` and `range - 1`, inclusive.\\n ///\\n /// @return newState The new state of the RNG.\\n /// When `getIndex()` is called one or more times,\\n /// care must be taken to always use the output `state`\\n /// of the most recent call as the input `state` of a subsequent call.\\n /// At the end of a transaction calling `RNG.getIndex()`,\\n /// the previous stored state must be overwritten with the latest output.\\n function getIndex(\\n uint256 range,\\n bytes32 state,\\n uint256 bits\\n ) internal view returns (uint256, bytes32) {\\n bool found = false;\\n uint256 index = 0;\\n bytes32 newState = state;\\n while (!found) {\\n index = truncate(bits, uint256(newState));\\n newState = keccak256(abi.encodePacked(newState, address(this)));\\n if (index < range) {\\n found = true;\\n }\\n }\\n return (index, newState);\\n }\\n\\n /// @notice Calculate how many bits are required\\n /// for an index in the range `[0 .. range-1]`.\\n ///\\n /// @param range The upper bound of the desired range, exclusive.\\n ///\\n /// @return uint The smallest number of bits\\n /// that can contain the number `range-1`.\\n function bitsRequired(uint256 range) internal pure returns (uint256) {\\n unchecked {\\n if (range == 1) {\\n return 0;\\n }\\n\\n uint256 bits = Constants.WEIGHT_WIDTH - 1;\\n\\n // Left shift by `bits`,\\n // so we have a 1 in the (bits + 1)th least significant bit\\n // and 0 in other bits.\\n // If this number is equal or greater than `range`,\\n // the range [0, range-1] fits in `bits` bits.\\n //\\n // Because we loop from high bits to low bits,\\n // we find the highest number of bits that doesn't fit the range,\\n // and return that number + 1.\\n while (1 << bits >= range) {\\n bits--;\\n }\\n\\n return bits + 1;\\n }\\n }\\n\\n /// @notice Truncate `input` to the `bits` least significant bits.\\n function truncate(uint256 bits, uint256 input)\\n internal\\n pure\\n returns (uint256)\\n {\\n unchecked {\\n return input & ((1 << bits) - 1);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x67f87f589cd5123ffa32f883ea2f09b0e56258508bae82b8c655b3c27c71eb5e\"},\"@keep-network/sortition-pools/contracts/Rewards.sol\":{\"content\":\"pragma solidity 0.8.17;\\n\\n/// @title Rewards\\n/// @notice Rewards are allocated proportionally to operators\\n/// present in the pool at payout based on their weight in the pool.\\n///\\n/// To facilitate this, we use a global accumulator value\\n/// to track the total rewards one unit of weight would've earned\\n/// since the creation of the pool.\\n///\\n/// Whenever a reward is paid, the accumulator is increased\\n/// by the size of the reward divided by the total weight\\n/// of all eligible operators in the pool.\\n///\\n/// Each operator has an individual accumulator value,\\n/// set to equal the global accumulator when the operator joins the pool.\\n/// This accumulator reflects the amount of rewards\\n/// that have already been accounted for with that operator.\\n///\\n/// Whenever an operator's weight in the pool changes,\\n/// we can update the amount of rewards the operator has earned\\n/// by subtracting the operator's accumulator from the global accumulator.\\n/// This gives us the amount of rewards one unit of weight has earned\\n/// since the last time the operator's rewards have been updated.\\n/// Then we multiply that by the operator's previous (pre-change) weight\\n/// to determine how much rewards in total the operator has earned,\\n/// and add this to the operator's earned rewards.\\n/// Finally, we set the operator's accumulator to the global accumulator value.\\ncontract Rewards {\\n struct OperatorRewards {\\n // The state of the global accumulator\\n // when the operator's rewards were last updated\\n uint96 accumulated;\\n // The amount of rewards collected by the operator after the latest update.\\n // The amount the operator could withdraw may equal `available`\\n // or it may be greater, if more rewards have been paid in since then.\\n // To evaulate the most recent amount including rewards potentially paid\\n // since the last update, use `availableRewards` function.\\n uint96 available;\\n // If nonzero, the operator is ineligible for rewards\\n // and may only re-enable rewards after the specified timestamp.\\n // XXX: unsigned 32-bit integer unix seconds, will break around 2106\\n uint32 ineligibleUntil;\\n // Locally cached weight of the operator,\\n // used to reduce the cost of setting operators ineligible.\\n uint32 weight;\\n }\\n\\n // The global accumulator of how much rewards\\n // a hypothetical operator of weight 1 would have earned\\n // since the creation of the pool.\\n uint96 internal globalRewardAccumulator;\\n // If the amount of reward tokens paid in\\n // does not divide cleanly by pool weight,\\n // the difference is recorded as rounding dust\\n // and added to the next reward.\\n uint96 internal rewardRoundingDust;\\n\\n // The amount of rewards that would've been earned by ineligible operators\\n // had they not been ineligible.\\n uint96 public ineligibleEarnedRewards;\\n\\n // Ineligibility times are calculated from this offset,\\n // set at contract creation.\\n uint256 internal immutable ineligibleOffsetStart;\\n\\n mapping(uint32 => OperatorRewards) internal operatorRewards;\\n\\n constructor() {\\n // solhint-disable-next-line not-rely-on-time\\n ineligibleOffsetStart = block.timestamp;\\n }\\n\\n /// @notice Return whether the operator is eligible for rewards or not.\\n function isEligibleForRewards(uint32 operator) internal view returns (bool) {\\n return operatorRewards[operator].ineligibleUntil == 0;\\n }\\n\\n /// @notice Return the time the operator's reward eligibility can be restored.\\n function rewardsEligibilityRestorableAt(uint32 operator)\\n internal\\n view\\n returns (uint256)\\n {\\n uint32 until = operatorRewards[operator].ineligibleUntil;\\n require(until != 0, \\\"Operator already eligible\\\");\\n return (uint256(until) + ineligibleOffsetStart);\\n }\\n\\n /// @notice Return whether the operator is able to restore their eligibility\\n /// for rewards right away.\\n function canRestoreRewardEligibility(uint32 operator)\\n internal\\n view\\n returns (bool)\\n {\\n // solhint-disable-next-line not-rely-on-time\\n return rewardsEligibilityRestorableAt(operator) <= block.timestamp;\\n }\\n\\n /// @notice Internal function for updating the global state of rewards.\\n function addRewards(uint96 rewardAmount, uint32 currentPoolWeight) internal {\\n require(currentPoolWeight > 0, \\\"No recipients in pool\\\");\\n\\n uint96 totalAmount = rewardAmount + rewardRoundingDust;\\n uint96 perWeightReward = totalAmount / currentPoolWeight;\\n uint96 newRoundingDust = totalAmount % currentPoolWeight;\\n\\n globalRewardAccumulator += perWeightReward;\\n rewardRoundingDust = newRoundingDust;\\n }\\n\\n /// @notice Internal function for updating the operator's reward state.\\n function updateOperatorRewards(uint32 operator, uint32 newWeight) internal {\\n uint96 acc = globalRewardAccumulator;\\n OperatorRewards memory o = operatorRewards[operator];\\n uint96 accruedRewards = (acc - o.accumulated) * uint96(o.weight);\\n if (o.ineligibleUntil == 0) {\\n // If operator is not ineligible, update their earned rewards\\n o.available += accruedRewards;\\n } else {\\n // If ineligible, put the rewards into the ineligible pot\\n ineligibleEarnedRewards += accruedRewards;\\n }\\n // In any case, update their accumulator and weight\\n o.accumulated = acc;\\n o.weight = newWeight;\\n operatorRewards[operator] = o;\\n }\\n\\n /// @notice Set the amount of withdrawable tokens to zero\\n /// and return the previous withdrawable amount.\\n /// @dev Does not update the withdrawable amount,\\n /// but should usually be accompanied by an update.\\n function withdrawOperatorRewards(uint32 operator)\\n internal\\n returns (uint96 withdrawable)\\n {\\n OperatorRewards storage o = operatorRewards[operator];\\n withdrawable = o.available;\\n o.available = 0;\\n }\\n\\n /// @notice Set the amount of ineligible-earned tokens to zero\\n /// and return the previous amount.\\n function withdrawIneligibleRewards() internal returns (uint96 withdrawable) {\\n withdrawable = ineligibleEarnedRewards;\\n ineligibleEarnedRewards = 0;\\n }\\n\\n /// @notice Set the given operators as ineligible for rewards.\\n /// The operators can restore their eligibility at the given time.\\n function setIneligible(uint32[] memory operators, uint256 until) internal {\\n OperatorRewards memory o = OperatorRewards(0, 0, 0, 0);\\n uint96 globalAcc = globalRewardAccumulator;\\n uint96 accrued = 0;\\n // Record ineligibility as seconds after contract creation\\n uint32 _until = uint32(until - ineligibleOffsetStart);\\n\\n for (uint256 i = 0; i < operators.length; i++) {\\n uint32 operator = operators[i];\\n OperatorRewards storage r = operatorRewards[operator];\\n o.available = r.available;\\n o.accumulated = r.accumulated;\\n o.ineligibleUntil = r.ineligibleUntil;\\n o.weight = r.weight;\\n\\n if (o.ineligibleUntil != 0) {\\n // If operator is already ineligible,\\n // don't earn rewards or shorten its ineligibility\\n if (o.ineligibleUntil < _until) {\\n o.ineligibleUntil = _until;\\n }\\n } else {\\n // The operator becomes ineligible -> earn rewards\\n o.ineligibleUntil = _until;\\n accrued = (globalAcc - o.accumulated) * uint96(o.weight);\\n o.available += accrued;\\n }\\n o.accumulated = globalAcc;\\n\\n r.available = o.available;\\n r.accumulated = o.accumulated;\\n r.ineligibleUntil = o.ineligibleUntil;\\n r.weight = o.weight;\\n }\\n }\\n\\n /// @notice Restore the given operator's eligibility for rewards.\\n function restoreEligibility(uint32 operator) internal {\\n // solhint-disable-next-line not-rely-on-time\\n require(canRestoreRewardEligibility(operator), \\\"Operator still ineligible\\\");\\n uint96 acc = globalRewardAccumulator;\\n OperatorRewards memory o = operatorRewards[operator];\\n uint96 accruedRewards = (acc - o.accumulated) * uint96(o.weight);\\n ineligibleEarnedRewards += accruedRewards;\\n o.accumulated = acc;\\n o.ineligibleUntil = 0;\\n operatorRewards[operator] = o;\\n }\\n\\n /// @notice Returns the amount of rewards currently available for withdrawal\\n /// for the given operator.\\n function availableRewards(uint32 operator) internal view returns (uint96) {\\n uint96 acc = globalRewardAccumulator;\\n OperatorRewards memory o = operatorRewards[operator];\\n if (o.ineligibleUntil == 0) {\\n // If operator is not ineligible, calculate newly accrued rewards and add\\n // them to the available ones, calculated during the last update.\\n uint96 accruedRewards = (acc - o.accumulated) * uint96(o.weight);\\n return o.available + accruedRewards;\\n } else {\\n // If ineligible, return only the rewards calculated during the last\\n // update.\\n return o.available;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3a10abb408b44335a092387b2c7ee01db3b27997f1f2c888d9b7a2d92934c4e2\"},\"@keep-network/sortition-pools/contracts/SortitionPool.sol\":{\"content\":\"pragma solidity 0.8.17;\\n\\nimport \\\"@thesis/solidity-contracts/contracts/token/IERC20WithPermit.sol\\\";\\nimport \\\"@thesis/solidity-contracts/contracts/token/IReceiveApproval.sol\\\";\\n\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\nimport \\\"./RNG.sol\\\";\\nimport \\\"./SortitionTree.sol\\\";\\nimport \\\"./Rewards.sol\\\";\\nimport \\\"./Chaosnet.sol\\\";\\n\\n/// @title Sortition Pool\\n/// @notice A logarithmic data structure used to store the pool of eligible\\n/// operators weighted by their stakes. It allows to select a group of operators\\n/// based on the provided pseudo-random seed.\\ncontract SortitionPool is\\n SortitionTree,\\n Rewards,\\n Ownable,\\n Chaosnet,\\n IReceiveApproval\\n{\\n using Branch for uint256;\\n using Leaf for uint256;\\n using Position for uint256;\\n\\n IERC20WithPermit public immutable rewardToken;\\n\\n uint256 public immutable poolWeightDivisor;\\n\\n bool public isLocked;\\n\\n event IneligibleForRewards(uint32[] ids, uint256 until);\\n\\n event RewardEligibilityRestored(address indexed operator, uint32 indexed id);\\n\\n /// @notice Reverts if called while pool is locked.\\n modifier onlyUnlocked() {\\n require(!isLocked, \\\"Sortition pool locked\\\");\\n _;\\n }\\n\\n /// @notice Reverts if called while pool is unlocked.\\n modifier onlyLocked() {\\n require(isLocked, \\\"Sortition pool unlocked\\\");\\n _;\\n }\\n\\n constructor(IERC20WithPermit _rewardToken, uint256 _poolWeightDivisor) {\\n rewardToken = _rewardToken;\\n poolWeightDivisor = _poolWeightDivisor;\\n }\\n\\n function receiveApproval(\\n address sender,\\n uint256 amount,\\n address token,\\n bytes calldata\\n ) external override {\\n require(token == address(rewardToken), \\\"Unsupported token\\\");\\n rewardToken.transferFrom(sender, address(this), amount);\\n Rewards.addRewards(uint96(amount), uint32(root.sumWeight()));\\n }\\n\\n /// @notice Withdraws all available rewards for the given operator to the\\n /// given beneficiary.\\n /// @dev Can be called only be the owner. Does not validate if the provided\\n /// beneficiary is associated with the provided operator - this needs to\\n /// be done by the owner calling this function.\\n /// @return The amount of rewards withdrawn in this call.\\n function withdrawRewards(address operator, address beneficiary)\\n public\\n onlyOwner\\n returns (uint96)\\n {\\n uint32 id = getOperatorID(operator);\\n Rewards.updateOperatorRewards(id, uint32(getPoolWeight(operator)));\\n uint96 earned = Rewards.withdrawOperatorRewards(id);\\n rewardToken.transfer(beneficiary, uint256(earned));\\n return earned;\\n }\\n\\n /// @notice Withdraws rewards not allocated to operators marked as ineligible\\n /// to the given recipient address.\\n /// @dev Can be called only by the owner.\\n function withdrawIneligible(address recipient) public onlyOwner {\\n uint96 earned = Rewards.withdrawIneligibleRewards();\\n rewardToken.transfer(recipient, uint256(earned));\\n }\\n\\n /// @notice Locks the sortition pool. In locked state, members cannot be\\n /// inserted and removed from the pool. Members statuses cannot\\n /// be updated as well.\\n /// @dev Can be called only by the contract owner.\\n function lock() public onlyOwner {\\n isLocked = true;\\n }\\n\\n /// @notice Unlocks the sortition pool. Removes all restrictions set by\\n /// the `lock` method.\\n /// @dev Can be called only by the contract owner.\\n function unlock() public onlyOwner {\\n isLocked = false;\\n }\\n\\n /// @notice Inserts an operator to the pool. Reverts if the operator is\\n /// already present. Reverts if the operator is not eligible because of their\\n /// authorized stake. Reverts if the chaosnet is active and the operator is\\n /// not a beta operator.\\n /// @dev Can be called only by the contract owner.\\n /// @param operator Address of the inserted operator.\\n /// @param authorizedStake Inserted operator's authorized stake for the application.\\n function insertOperator(address operator, uint256 authorizedStake)\\n public\\n onlyOwner\\n onlyUnlocked\\n {\\n uint256 weight = getWeight(authorizedStake);\\n require(weight > 0, \\\"Operator not eligible\\\");\\n\\n if (isChaosnetActive) {\\n require(isBetaOperator[operator], \\\"Not beta operator for chaosnet\\\");\\n }\\n\\n _insertOperator(operator, weight);\\n uint32 id = getOperatorID(operator);\\n Rewards.updateOperatorRewards(id, uint32(weight));\\n }\\n\\n /// @notice Update the operator's weight if present and eligible,\\n /// or remove from the pool if present and ineligible.\\n /// @dev Can be called only by the contract owner.\\n /// @param operator Address of the updated operator.\\n /// @param authorizedStake Operator's authorized stake for the application.\\n function updateOperatorStatus(address operator, uint256 authorizedStake)\\n public\\n onlyOwner\\n onlyUnlocked\\n {\\n uint256 weight = getWeight(authorizedStake);\\n\\n uint32 id = getOperatorID(operator);\\n Rewards.updateOperatorRewards(id, uint32(weight));\\n\\n if (weight == 0) {\\n _removeOperator(operator);\\n } else {\\n updateOperator(operator, weight);\\n }\\n }\\n\\n /// @notice Set the given operators as ineligible for rewards.\\n /// The operators can restore their eligibility at the given time.\\n function setRewardIneligibility(uint32[] calldata operators, uint256 until)\\n public\\n onlyOwner\\n {\\n Rewards.setIneligible(operators, until);\\n emit IneligibleForRewards(operators, until);\\n }\\n\\n /// @notice Restores reward eligibility for the operator.\\n function restoreRewardEligibility(address operator) public {\\n uint32 id = getOperatorID(operator);\\n Rewards.restoreEligibility(id);\\n emit RewardEligibilityRestored(operator, id);\\n }\\n\\n /// @notice Returns whether the operator is eligible for rewards or not.\\n function isEligibleForRewards(address operator) public view returns (bool) {\\n uint32 id = getOperatorID(operator);\\n return Rewards.isEligibleForRewards(id);\\n }\\n\\n /// @notice Returns the time the operator's reward eligibility can be restored.\\n function rewardsEligibilityRestorableAt(address operator)\\n public\\n view\\n returns (uint256)\\n {\\n uint32 id = getOperatorID(operator);\\n return Rewards.rewardsEligibilityRestorableAt(id);\\n }\\n\\n /// @notice Returns whether the operator is able to restore their eligibility\\n /// for rewards right away.\\n function canRestoreRewardEligibility(address operator)\\n public\\n view\\n returns (bool)\\n {\\n uint32 id = getOperatorID(operator);\\n return Rewards.canRestoreRewardEligibility(id);\\n }\\n\\n /// @notice Returns the amount of rewards withdrawable for the given operator.\\n function getAvailableRewards(address operator) public view returns (uint96) {\\n uint32 id = getOperatorID(operator);\\n return availableRewards(id);\\n }\\n\\n /// @notice Return whether the operator is present in the pool.\\n function isOperatorInPool(address operator) public view returns (bool) {\\n return getFlaggedLeafPosition(operator) != 0;\\n }\\n\\n /// @notice Return whether the operator's weight in the pool\\n /// matches their eligible weight.\\n function isOperatorUpToDate(address operator, uint256 authorizedStake)\\n public\\n view\\n returns (bool)\\n {\\n return getWeight(authorizedStake) == getPoolWeight(operator);\\n }\\n\\n /// @notice Return the weight of the operator in the pool,\\n /// which may or may not be out of date.\\n function getPoolWeight(address operator) public view returns (uint256) {\\n uint256 flaggedPosition = getFlaggedLeafPosition(operator);\\n if (flaggedPosition == 0) {\\n return 0;\\n } else {\\n uint256 leafPosition = flaggedPosition.unsetFlag();\\n uint256 leafWeight = getLeafWeight(leafPosition);\\n return leafWeight;\\n }\\n }\\n\\n /// @notice Selects a new group of operators of the provided size based on\\n /// the provided pseudo-random seed. At least one operator has to be\\n /// registered in the pool, otherwise the function fails reverting the\\n /// transaction.\\n /// @param groupSize Size of the requested group\\n /// @param seed Pseudo-random number used to select operators to group\\n /// @return selected Members of the selected group\\n function selectGroup(uint256 groupSize, bytes32 seed)\\n public\\n view\\n onlyLocked\\n returns (uint32[] memory)\\n {\\n uint256 _root = root;\\n\\n bytes32 rngState = seed;\\n uint256 rngRange = _root.sumWeight();\\n require(rngRange > 0, \\\"Not enough operators in pool\\\");\\n uint256 currentIndex;\\n\\n uint256 bits = RNG.bitsRequired(rngRange);\\n\\n uint32[] memory selected = new uint32[](groupSize);\\n\\n for (uint256 i = 0; i < groupSize; i++) {\\n (currentIndex, rngState) = RNG.getIndex(rngRange, rngState, bits);\\n\\n uint256 leafPosition = pickWeightedLeaf(currentIndex, _root);\\n\\n uint256 leaf = leaves[leafPosition];\\n selected[i] = leaf.id();\\n }\\n return selected;\\n }\\n\\n function getWeight(uint256 authorization) internal view returns (uint256) {\\n return authorization / poolWeightDivisor;\\n }\\n}\\n\",\"keccak256\":\"0xab42e7c5b1828f42a73f699eb2dc96d4f793572a6323b8b1fbd7c5e0c065bda7\"},\"@keep-network/sortition-pools/contracts/SortitionTree.sol\":{\"content\":\"pragma solidity 0.8.17;\\n\\nimport \\\"./Branch.sol\\\";\\nimport \\\"./Position.sol\\\";\\nimport \\\"./Leaf.sol\\\";\\nimport \\\"./Constants.sol\\\";\\n\\ncontract SortitionTree {\\n using Branch for uint256;\\n using Position for uint256;\\n using Leaf for uint256;\\n\\n // implicit tree\\n // root 8\\n // level2 64\\n // level3 512\\n // level4 4k\\n // level5 32k\\n // level6 256k\\n // level7 2M\\n uint256 internal root;\\n\\n // A 2-index mapping from layer => (index (0-index) => branch). For example,\\n // to access the 6th branch in the 2nd layer (right below the root node; the\\n // first branch layer), call branches[2][5]. Mappings are used in place of\\n // arrays for efficiency. The root is the first layer, the branches occupy\\n // layers 2 through 7, and layer 8 is for the leaves. Following this\\n // convention, the first index in `branches` is `2`, and the last index is\\n // `7`.\\n mapping(uint256 => mapping(uint256 => uint256)) internal branches;\\n\\n // A 0-index mapping from index => leaf, acting as an array. For example, to\\n // access the 42nd leaf, call leaves[41].\\n mapping(uint256 => uint256) internal leaves;\\n\\n // the flagged (see setFlag() and unsetFlag() in Position.sol) positions\\n // of all operators present in the pool\\n mapping(address => uint256) internal flaggedLeafPosition;\\n\\n // the leaf after the rightmost occupied leaf of each stack\\n uint256 internal rightmostLeaf;\\n\\n // the empty leaves in each stack\\n // between 0 and the rightmost occupied leaf\\n uint256[] internal emptyLeaves;\\n\\n // Each operator has an uint32 ID number\\n // which is allocated when they first join the pool\\n // and remains unchanged even if they leave and rejoin the pool.\\n mapping(address => uint32) internal operatorID;\\n\\n // The idAddress array records the address corresponding to each ID number.\\n // The ID number 0 is initialized with a zero address and is not used.\\n address[] internal idAddress;\\n\\n constructor() {\\n root = 0;\\n rightmostLeaf = 0;\\n idAddress.push();\\n }\\n\\n /// @notice Return the ID number of the given operator address. An ID number\\n /// of 0 means the operator has not been allocated an ID number yet.\\n /// @param operator Address of the operator.\\n /// @return the ID number of the given operator address\\n function getOperatorID(address operator) public view returns (uint32) {\\n return operatorID[operator];\\n }\\n\\n /// @notice Get the operator address corresponding to the given ID number. A\\n /// zero address means the ID number has not been allocated yet.\\n /// @param id ID of the operator\\n /// @return the address of the operator\\n function getIDOperator(uint32 id) public view returns (address) {\\n return idAddress.length > id ? idAddress[id] : address(0);\\n }\\n\\n /// @notice Gets the operator addresses corresponding to the given ID\\n /// numbers. A zero address means the ID number has not been allocated yet.\\n /// This function works just like getIDOperator except that it allows to fetch\\n /// operator addresses for multiple IDs in one call.\\n /// @param ids the array of the operator ids\\n /// @return an array of the associated operator addresses\\n function getIDOperators(uint32[] calldata ids)\\n public\\n view\\n returns (address[] memory)\\n {\\n uint256 idCount = idAddress.length;\\n\\n address[] memory operators = new address[](ids.length);\\n for (uint256 i = 0; i < ids.length; i++) {\\n uint32 id = ids[i];\\n operators[i] = idCount > id ? idAddress[id] : address(0);\\n }\\n return operators;\\n }\\n\\n /// @notice Checks if operator is already registered in the pool.\\n /// @param operator the address of the operator\\n /// @return whether or not the operator is already registered in the pool\\n function isOperatorRegistered(address operator) public view returns (bool) {\\n return getFlaggedLeafPosition(operator) != 0;\\n }\\n\\n /// @notice Sum the number of operators in each trunk.\\n /// @return the number of operators in the pool\\n function operatorsInPool() public view returns (uint256) {\\n // Get the number of leaves that might be occupied;\\n // if `rightmostLeaf` equals `firstLeaf()` the tree must be empty,\\n // otherwise the difference between these numbers\\n // gives the number of leaves that may be occupied.\\n uint256 nPossiblyUsedLeaves = rightmostLeaf;\\n // Get the number of empty leaves\\n // not accounted for by the `rightmostLeaf`\\n uint256 nEmptyLeaves = emptyLeaves.length;\\n\\n return (nPossiblyUsedLeaves - nEmptyLeaves);\\n }\\n\\n /// @notice Convenience method to return the total weight of the pool\\n /// @return the total weight of the pool\\n function totalWeight() public view returns (uint256) {\\n return root.sumWeight();\\n }\\n\\n /// @notice Give the operator a new ID number.\\n /// Does not check if the operator already has an ID number.\\n /// @param operator the address of the operator\\n /// @return a new ID for that operator\\n function allocateOperatorID(address operator) internal returns (uint256) {\\n uint256 id = idAddress.length;\\n\\n require(id <= type(uint32).max, \\\"Pool capacity exceeded\\\");\\n\\n operatorID[operator] = uint32(id);\\n idAddress.push(operator);\\n return id;\\n }\\n\\n /// @notice Inserts an operator into the sortition pool\\n /// @param operator the address of an operator to insert\\n /// @param weight how much weight that operator has in the pool\\n function _insertOperator(address operator, uint256 weight) internal {\\n require(\\n !isOperatorRegistered(operator),\\n \\\"Operator is already registered in the pool\\\"\\n );\\n\\n // Fetch the operator's ID, and if they don't have one, allocate them one.\\n uint256 id = getOperatorID(operator);\\n if (id == 0) {\\n id = allocateOperatorID(operator);\\n }\\n\\n // Determine which leaf to insert them into\\n uint256 position = getEmptyLeafPosition();\\n // Record the block the operator was inserted in\\n uint256 theLeaf = Leaf.make(operator, block.number, id);\\n\\n // Update the leaf, and propagate the weight changes all the way up to the\\n // root.\\n root = setLeaf(position, theLeaf, weight, root);\\n\\n // Without position flags,\\n // the position 0x000000 would be treated as empty\\n flaggedLeafPosition[operator] = position.setFlag();\\n }\\n\\n /// @notice Remove an operator (and their weight) from the pool.\\n /// @param operator the address of the operator to remove\\n function _removeOperator(address operator) internal {\\n uint256 flaggedPosition = getFlaggedLeafPosition(operator);\\n require(flaggedPosition != 0, \\\"Operator is not registered in the pool\\\");\\n uint256 unflaggedPosition = flaggedPosition.unsetFlag();\\n\\n // Update the leaf, and propagate the weight changes all the way up to the\\n // root.\\n root = removeLeaf(unflaggedPosition, root);\\n removeLeafPositionRecord(operator);\\n }\\n\\n /// @notice Update an operator's weight in the pool.\\n /// @param operator the address of the operator to update\\n /// @param weight the new weight\\n function updateOperator(address operator, uint256 weight) internal {\\n require(\\n isOperatorRegistered(operator),\\n \\\"Operator is not registered in the pool\\\"\\n );\\n\\n uint256 flaggedPosition = getFlaggedLeafPosition(operator);\\n uint256 unflaggedPosition = flaggedPosition.unsetFlag();\\n root = updateLeaf(unflaggedPosition, weight, root);\\n }\\n\\n /// @notice Helper method to remove a leaf position record for an operator.\\n /// @param operator the address of the operator to remove the record for\\n function removeLeafPositionRecord(address operator) internal {\\n flaggedLeafPosition[operator] = 0;\\n }\\n\\n /// @notice Removes the data and weight from a particular leaf.\\n /// @param position the leaf index to remove\\n /// @param _root the root node containing the leaf\\n /// @return the updated root node\\n function removeLeaf(uint256 position, uint256 _root)\\n internal\\n returns (uint256)\\n {\\n uint256 rightmostSubOne = rightmostLeaf - 1;\\n bool isRightmost = position == rightmostSubOne;\\n\\n // Clears out the data in the leaf node, and then propagates the weight\\n // changes all the way up to the root.\\n uint256 newRoot = setLeaf(position, 0, 0, _root);\\n\\n // Infer if need to fall back on emptyLeaves yet\\n if (isRightmost) {\\n rightmostLeaf = rightmostSubOne;\\n } else {\\n emptyLeaves.push(position);\\n }\\n return newRoot;\\n }\\n\\n /// @notice Updates the tree to give a particular leaf a new weight.\\n /// @param position the index of the leaf to update\\n /// @param weight the new weight\\n /// @param _root the root node containing the leaf\\n /// @return the updated root node\\n function updateLeaf(\\n uint256 position,\\n uint256 weight,\\n uint256 _root\\n ) internal returns (uint256) {\\n if (getLeafWeight(position) != weight) {\\n return updateTree(position, weight, _root);\\n } else {\\n return _root;\\n }\\n }\\n\\n /// @notice Places a leaf into a particular position, with a given weight and\\n /// propagates that change.\\n /// @param position the index to place the leaf in\\n /// @param theLeaf the new leaf to place in the position\\n /// @param leafWeight the weight of the leaf\\n /// @param _root the root containing the new leaf\\n /// @return the updated root node\\n function setLeaf(\\n uint256 position,\\n uint256 theLeaf,\\n uint256 leafWeight,\\n uint256 _root\\n ) internal returns (uint256) {\\n // set leaf\\n leaves[position] = theLeaf;\\n\\n return (updateTree(position, leafWeight, _root));\\n }\\n\\n /// @notice Propagates a weight change at a position through the tree,\\n /// eventually returning the updated root.\\n /// @param position the index of leaf to update\\n /// @param weight the new weight of the leaf\\n /// @param _root the root node containing the leaf\\n /// @return the updated root node\\n function updateTree(\\n uint256 position,\\n uint256 weight,\\n uint256 _root\\n ) internal returns (uint256) {\\n uint256 childSlot;\\n uint256 treeNode;\\n uint256 newNode;\\n uint256 nodeWeight = weight;\\n\\n uint256 parent = position;\\n // set levels 7 to 2\\n for (uint256 level = Constants.LEVELS; level >= 2; level--) {\\n childSlot = parent.slot();\\n parent = parent.parent();\\n treeNode = branches[level][parent];\\n newNode = treeNode.setSlot(childSlot, nodeWeight);\\n branches[level][parent] = newNode;\\n nodeWeight = newNode.sumWeight();\\n }\\n\\n // set level Root\\n childSlot = parent.slot();\\n return _root.setSlot(childSlot, nodeWeight);\\n }\\n\\n /// @notice Retrieves the next available empty leaf position. Tries to fill\\n /// left to right first, ignoring leaf removals, and then fills\\n /// most-recent-removals first.\\n /// @return the position of the empty leaf\\n function getEmptyLeafPosition() internal returns (uint256) {\\n uint256 rLeaf = rightmostLeaf;\\n bool spaceOnRight = (rLeaf + 1) < Constants.POOL_CAPACITY;\\n if (spaceOnRight) {\\n rightmostLeaf = rLeaf + 1;\\n return rLeaf;\\n } else {\\n uint256 emptyLeafCount = emptyLeaves.length;\\n require(emptyLeafCount > 0, \\\"Pool is full\\\");\\n uint256 emptyLeaf = emptyLeaves[emptyLeafCount - 1];\\n emptyLeaves.pop();\\n return emptyLeaf;\\n }\\n }\\n\\n /// @notice Gets the flagged leaf position for an operator.\\n /// @param operator the address of the operator\\n /// @return the leaf position of that operator\\n function getFlaggedLeafPosition(address operator)\\n internal\\n view\\n returns (uint256)\\n {\\n return flaggedLeafPosition[operator];\\n }\\n\\n /// @notice Gets the weight of a leaf at a particular position.\\n /// @param position the index of the leaf\\n /// @return the weight of the leaf at that position\\n function getLeafWeight(uint256 position) internal view returns (uint256) {\\n uint256 slot = position.slot();\\n uint256 parent = position.parent();\\n\\n // A leaf's weight information is stored a 32-bit slot in the branch layer\\n // directly above the leaf layer. To access it, we calculate that slot and\\n // parent position, and always know the hard-coded layer index.\\n uint256 node = branches[Constants.LEVELS][parent];\\n return node.getSlot(slot);\\n }\\n\\n /// @notice Picks a leaf given a random index.\\n /// @param index a number in `[0, _root.totalWeight())` used to decide\\n /// between leaves\\n /// @param _root the root of the tree\\n function pickWeightedLeaf(uint256 index, uint256 _root)\\n internal\\n view\\n returns (uint256 leafPosition)\\n {\\n uint256 currentIndex = index;\\n uint256 currentNode = _root;\\n uint256 currentPosition = 0;\\n uint256 currentSlot;\\n\\n require(index < currentNode.sumWeight(), \\\"Index exceeds weight\\\");\\n\\n // get root slot\\n (currentSlot, currentIndex) = currentNode.pickWeightedSlot(currentIndex);\\n\\n // get slots from levels 2 to 7\\n for (uint256 level = 2; level <= Constants.LEVELS; level++) {\\n currentPosition = currentPosition.child(currentSlot);\\n currentNode = branches[level][currentPosition];\\n (currentSlot, currentIndex) = currentNode.pickWeightedSlot(currentIndex);\\n }\\n\\n // get leaf position\\n leafPosition = currentPosition.child(currentSlot);\\n }\\n}\\n\",\"keccak256\":\"0x51daeca62ef52be78a1a9de4d2a1c5900c873165f59eda14d5965d7d7da90a03\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@thesis/solidity-contracts/contracts/token/IApproveAndCall.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.4;\\n\\n/// @notice An interface that should be implemented by tokens supporting\\n/// `approveAndCall`/`receiveApproval` pattern.\\ninterface IApproveAndCall {\\n /// @notice Executes `receiveApproval` function on spender as specified in\\n /// `IReceiveApproval` interface. Approves spender to withdraw from\\n /// the caller multiple times, up to the `amount`. If this\\n /// function is called again, it overwrites the current allowance\\n /// with `amount`. Reverts if the approval reverted or if\\n /// `receiveApproval` call on the spender reverted.\\n function approveAndCall(\\n address spender,\\n uint256 amount,\\n bytes memory extraData\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x393d18ef81a57dcc96fff4c340cc2945deaebb37b9796c322cf2bc96872c3df8\",\"license\":\"MIT\"},\"@thesis/solidity-contracts/contracts/token/IERC20WithPermit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.4;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\n\\nimport \\\"./IApproveAndCall.sol\\\";\\n\\n/// @title IERC20WithPermit\\n/// @notice Burnable ERC20 token with EIP2612 permit functionality. User can\\n/// authorize a transfer of their token with a signature conforming\\n/// EIP712 standard instead of an on-chain transaction from their\\n/// address. Anyone can submit this signature on the user's behalf by\\n/// calling the permit function, as specified in EIP2612 standard,\\n/// paying gas fees, and possibly performing other actions in the same\\n/// transaction.\\ninterface IERC20WithPermit is IERC20, IERC20Metadata, IApproveAndCall {\\n /// @notice EIP2612 approval made with secp256k1 signature.\\n /// Users can authorize a transfer of their tokens with a signature\\n /// conforming EIP712 standard, rather than an on-chain transaction\\n /// from their address. Anyone can submit this signature on the\\n /// user's behalf by calling the permit function, paying gas fees,\\n /// and possibly performing other actions in the same transaction.\\n /// @dev The deadline argument can be set to `type(uint256).max to create\\n /// permits that effectively never expire.\\n function permit(\\n address owner,\\n address spender,\\n uint256 amount,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /// @notice Destroys `amount` tokens from the caller.\\n function burn(uint256 amount) external;\\n\\n /// @notice Destroys `amount` of tokens from `account`, deducting the amount\\n /// from caller's allowance.\\n function burnFrom(address account, uint256 amount) external;\\n\\n /// @notice Returns hash of EIP712 Domain struct with the token name as\\n /// a signing domain and token contract as a verifying contract.\\n /// Used to construct EIP2612 signature provided to `permit`\\n /// function.\\n /* solhint-disable-next-line func-name-mixedcase */\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n\\n /// @notice Returns the current nonce for EIP2612 permission for the\\n /// provided token owner for a replay protection. Used to construct\\n /// EIP2612 signature provided to `permit` function.\\n function nonce(address owner) external view returns (uint256);\\n\\n /// @notice Returns EIP2612 Permit message hash. Used to construct EIP2612\\n /// signature provided to `permit` function.\\n /* solhint-disable-next-line func-name-mixedcase */\\n function PERMIT_TYPEHASH() external pure returns (bytes32);\\n}\\n\",\"keccak256\":\"0xdac9a5086c19a7128b505a7be1ab0ac1aa314f6989cb88d2417e9d7383f89fa9\",\"license\":\"MIT\"},\"@thesis/solidity-contracts/contracts/token/IReceiveApproval.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.4;\\n\\n/// @notice An interface that should be implemented by contracts supporting\\n/// `approveAndCall`/`receiveApproval` pattern.\\ninterface IReceiveApproval {\\n /// @notice Receives approval to spend tokens. Called as a result of\\n /// `approveAndCall` call on the token.\\n function receiveApproval(\\n address from,\\n uint256 amount,\\n address token,\\n bytes calldata extraData\\n ) external;\\n}\\n\",\"keccak256\":\"0x6a30d83ad230548b1e7839737affc8489a035314209de14b89dbef7fb0f66395\",\"license\":\"MIT\"},\"@threshold-network/solidity-contracts/contracts/staking/IStaking.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\n// \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\n// \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\n// \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c\\n// \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c\\n// \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\n// \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\n// \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c\\n// \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c\\n// \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c\\n// \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c\\n// \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c\\n// \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c \\u2590\\u2588\\u2588\\u2588\\u2588\\u258c\\n\\npragma solidity ^0.8.9;\\n\\n/// @title Interface of Threshold Network staking contract\\n/// @notice The staking contract enables T owners to have their wallets offline\\n/// and their stake managed by staking providers on their behalf.\\n/// The staking contract does not define operator role. The operator\\n/// responsible for running off-chain client software is appointed by\\n/// the staking provider in the particular application utilizing the\\n/// staking contract. All off-chain client software should be able\\n/// to run without exposing operator's or staking provider\\u2019s private\\n/// key and should not require any owner\\u2019s keys at all. The stake\\n/// delegation optimizes the network throughput without compromising the\\n/// security of the owners\\u2019 stake.\\ninterface IStaking {\\n enum StakeType {\\n NU,\\n KEEP,\\n T\\n }\\n\\n //\\n //\\n // Delegating a stake\\n //\\n //\\n\\n /// @notice Creates a delegation with `msg.sender` owner with the given\\n /// staking provider, beneficiary, and authorizer. Transfers the\\n /// given amount of T to the staking contract.\\n /// @dev The owner of the delegation needs to have the amount approved to\\n /// transfer to the staking contract.\\n function stake(\\n address stakingProvider,\\n address payable beneficiary,\\n address authorizer,\\n uint96 amount\\n ) external;\\n\\n /// @notice Allows the Governance to set the minimum required stake amount.\\n /// This amount is required to protect against griefing the staking\\n /// contract and individual applications are allowed to require\\n /// higher minimum stakes if necessary.\\n function setMinimumStakeAmount(uint96 amount) external;\\n\\n //\\n //\\n // Authorizing an application\\n //\\n //\\n\\n /// @notice Allows the Governance to approve the particular application\\n /// before individual stake authorizers are able to authorize it.\\n function approveApplication(address application) external;\\n\\n /// @notice Increases the authorization of the given staking provider for\\n /// the given application by the given amount. Can only be called by\\n /// the authorizer for that staking provider.\\n /// @dev Calls `authorizationIncreased(address stakingProvider, uint256 amount)`\\n /// on the given application to notify the application about\\n /// authorization change. See `IApplication`.\\n function increaseAuthorization(\\n address stakingProvider,\\n address application,\\n uint96 amount\\n ) external;\\n\\n /// @notice Requests decrease of the authorization for the given staking\\n /// provider on the given application by the provided amount.\\n /// It may not change the authorized amount immediatelly. When\\n /// it happens depends on the application. Can only be called by the\\n /// given staking provider\\u2019s authorizer. Overwrites pending\\n /// authorization decrease for the given staking provider and\\n /// application if the application agrees for that. If the\\n /// application does not agree for overwriting, the function\\n /// reverts.\\n /// @dev Calls `authorizationDecreaseRequested(address stakingProvider, uint256 amount)`\\n /// on the given application. See `IApplication`.\\n function requestAuthorizationDecrease(\\n address stakingProvider,\\n address application,\\n uint96 amount\\n ) external;\\n\\n /// @notice Requests decrease of all authorizations for the given staking\\n /// provider on all applications by all authorized amount.\\n /// It may not change the authorized amount immediatelly. When\\n /// it happens depends on the application. Can only be called by the\\n /// given staking provider\\u2019s authorizer. Overwrites pending\\n /// authorization decrease for the given staking provider and\\n /// application.\\n /// @dev Calls `authorizationDecreaseRequested(address stakingProvider, uint256 amount)`\\n /// for each authorized application. See `IApplication`.\\n function requestAuthorizationDecrease(address stakingProvider) external;\\n\\n /// @notice Called by the application at its discretion to approve the\\n /// previously requested authorization decrease request. Can only be\\n /// called by the application that was previously requested to\\n /// decrease the authorization for that staking provider.\\n /// Returns resulting authorized amount for the application.\\n function approveAuthorizationDecrease(address stakingProvider)\\n external\\n returns (uint96);\\n\\n /// @notice Decreases the authorization for the given `stakingProvider` on\\n /// the given disabled `application`, for all authorized amount.\\n /// Can be called by anyone.\\n function forceDecreaseAuthorization(\\n address stakingProvider,\\n address application\\n ) external;\\n\\n /// @notice Pauses the given application\\u2019s eligibility to slash stakes.\\n /// Besides that stakers can't change authorization to the application.\\n /// Can be called only by the Panic Button of the particular\\n /// application. The paused application can not slash stakes until\\n /// it is approved again by the Governance using `approveApplication`\\n /// function. Should be used only in case of an emergency.\\n function pauseApplication(address application) external;\\n\\n /// @notice Disables the given application. The disabled application can't\\n /// slash stakers. Also stakers can't increase authorization to that\\n /// application but can decrease without waiting by calling\\n /// `requestAuthorizationDecrease` at any moment. Can be called only\\n /// by the governance. The disabled application can't be approved\\n /// again. Should be used only in case of an emergency.\\n function disableApplication(address application) external;\\n\\n /// @notice Sets the Panic Button role for the given application to the\\n /// provided address. Can only be called by the Governance. If the\\n /// Panic Button for the given application should be disabled, the\\n /// role address should be set to 0x0 address.\\n function setPanicButton(address application, address panicButton) external;\\n\\n /// @notice Sets the maximum number of applications one staking provider can\\n /// have authorized. Used to protect against DoSing slashing queue.\\n /// Can only be called by the Governance.\\n function setAuthorizationCeiling(uint256 ceiling) external;\\n\\n //\\n //\\n // Stake top-up\\n //\\n //\\n\\n /// @notice Increases the amount of the stake for the given staking provider.\\n /// If `autoIncrease` flag is true then the amount will be added for\\n /// all authorized applications.\\n /// @dev The sender of this transaction needs to have the amount approved to\\n /// transfer to the staking contract.\\n function topUp(address stakingProvider, uint96 amount) external;\\n\\n /// @notice Toggle `autoIncrease` flag. If true then the complete amount\\n /// in top-up will be added to already authorized applications.\\n function toggleAutoAuthorizationIncrease(address stakingProvider) external;\\n\\n //\\n //\\n // Undelegating a stake (unstaking)\\n //\\n //\\n\\n /// @notice Reduces the liquid T stake amount by the provided amount and\\n /// withdraws T to the owner. Reverts if there is at least one\\n /// authorization higher than the sum of the legacy stake and\\n /// remaining liquid T stake or if the unstake amount is higher than\\n /// the liquid T stake amount. Can be called only by the delegation\\n /// owner or the staking provider.\\n function unstakeT(address stakingProvider, uint96 amount) external;\\n\\n /// @notice Sets the legacy KEEP staking contract active stake amount cached\\n /// in T staking contract to 0. Reverts if the amount of liquid T\\n /// staked in T staking contract is lower than the highest\\n /// application authorization. This function allows to unstake from\\n /// KEEP staking contract and still being able to operate in T\\n /// network and earning rewards based on the liquid T staked. Can be\\n /// called only by the delegation owner or the staking provider.\\n function unstakeKeep(address stakingProvider) external;\\n\\n /// @notice Sets to 0 the amount of T that is cached from the legacy\\n /// NU staking contract. Reverts if there is at least one\\n /// authorization higher than the sum of remaining legacy NU stake\\n /// and native T stake for that staking provider or if the unstaked\\n /// amount is higher than the cached legacy stake amount. If succeeded,\\n /// the legacy NU stake can be partially or fully undelegated on\\n /// the legacy NU staking contract. This function allows to unstake\\n /// from NU staking contract while still being able to operate in\\n /// T network and earning rewards based on the native T staked.\\n /// Can be called only by the stake owner or the staking provider.\\n function unstakeNu(address stakingProvider) external;\\n\\n /// @notice Sets cached legacy stake amount to 0, sets the liquid T stake\\n /// amount to 0 and withdraws all liquid T from the stake to the\\n /// owner. Reverts if there is at least one non-zero authorization.\\n /// Can be called only by the delegation owner or the staking\\n /// provider.\\n function unstakeAll(address stakingProvider) external;\\n\\n //\\n //\\n // Keeping information in sync\\n //\\n //\\n\\n /// @notice Sets reward in T tokens for notification of misbehaviour\\n /// of one staking provider. Can only be called by the governance.\\n function setNotificationReward(uint96 reward) external;\\n\\n /// @notice Transfer some amount of T tokens as reward for notifications\\n /// of misbehaviour\\n function pushNotificationReward(uint96 reward) external;\\n\\n /// @notice Withdraw some amount of T tokens from notifiers treasury.\\n /// Can only be called by the governance.\\n function withdrawNotificationReward(address recipient, uint96 amount)\\n external;\\n\\n /// @notice Adds staking providers to the slashing queue along with the\\n /// amount that should be slashed from each one of them. Can only be\\n /// called by application authorized for all staking providers in\\n /// the array.\\n function slash(uint96 amount, address[] memory stakingProviders) external;\\n\\n /// @notice Adds staking providers to the slashing queue along with the\\n /// amount. The notifier will receive reward per each staking\\n /// provider from notifiers treasury. Can only be called by\\n /// application authorized for all staking providers in the array.\\n function seize(\\n uint96 amount,\\n uint256 rewardMultipier,\\n address notifier,\\n address[] memory stakingProviders\\n ) external;\\n\\n /// @notice Takes the given number of queued slashing operations and\\n /// processes them. Receives 5% of the slashed amount.\\n /// Executes `involuntaryAllocationDecrease` function on each\\n /// affected application.\\n function processSlashing(uint256 count) external;\\n\\n //\\n //\\n // Auxiliary functions\\n //\\n //\\n\\n /// @notice Returns the authorized stake amount of the staking provider for\\n /// the application.\\n function authorizedStake(address stakingProvider, address application)\\n external\\n view\\n returns (uint96);\\n\\n /// @notice Returns staked amount of T, Keep and Nu for the specified\\n /// staking provider.\\n /// @dev All values are in T denomination\\n function stakes(address stakingProvider)\\n external\\n view\\n returns (\\n uint96 tStake,\\n uint96 keepInTStake,\\n uint96 nuInTStake\\n );\\n\\n /// @notice Returns start staking timestamp.\\n /// @dev This value is set at most once.\\n function getStartStakingTimestamp(address stakingProvider)\\n external\\n view\\n returns (uint256);\\n\\n /// @notice Returns auto-increase flag.\\n function getAutoIncreaseFlag(address stakingProvider)\\n external\\n view\\n returns (bool);\\n\\n /// @notice Returns staked amount of NU for the specified staking provider.\\n function stakedNu(address stakingProvider) external view returns (uint256);\\n\\n /// @notice Gets the stake owner, the beneficiary and the authorizer\\n /// for the specified staking provider address.\\n /// @return owner Stake owner address.\\n /// @return beneficiary Beneficiary address.\\n /// @return authorizer Authorizer address.\\n function rolesOf(address stakingProvider)\\n external\\n view\\n returns (\\n address owner,\\n address payable beneficiary,\\n address authorizer\\n );\\n\\n /// @notice Returns length of application array\\n function getApplicationsLength() external view returns (uint256);\\n\\n /// @notice Returns length of slashing queue\\n function getSlashingQueueLength() external view returns (uint256);\\n\\n /// @notice Returns minimum possible stake for T, KEEP or NU in T\\n /// denomination.\\n /// @dev For example, suppose the given staking provider has 10 T, 20 T worth\\n /// of KEEP, and 30 T worth of NU all staked, and the maximum\\n /// application authorization is 40 T, then `getMinStaked` for\\n /// that staking provider returns:\\n /// * 0 T if KEEP stake type specified i.e.\\n /// min = 40 T max - (10 T) = 30 T\\n /// * 10 T if NU stake type specified i.e.\\n /// min = 40 T max - (10 T) = 30 T\\n /// * 0 T if T stake type specified i.e.\\n /// min = 40 T max = 40 T\\n /// In other words, the minimum stake amount for the specified\\n /// stake type is the minimum amount of stake of the given type\\n /// needed to satisfy the maximum application authorization given\\n /// the staked amounts of the T stake types for that staking provider.\\n function getMinStaked(address stakingProvider, StakeType stakeTypes)\\n external\\n view\\n returns (uint96);\\n\\n /// @notice Returns available amount to authorize for the specified application\\n function getAvailableToAuthorize(\\n address stakingProvider,\\n address application\\n ) external view returns (uint96);\\n}\\n\",\"keccak256\":\"0xc8fbea45ba10de0383d6e7b2dd0f3931971e1b702e4a308ff8325bb23fdff81c\",\"license\":\"GPL-3.0-or-later\"},\"contracts/libraries/BeaconAuthorization.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\n//\\n// \\u2593\\u2593\\u258c \\u2593\\u2593 \\u2590\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u258c\\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2584\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u258c\\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u258c \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2584\\u2584\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2584\\u2584\\u2584\\u2584 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2584\\u2584\\u2584\\u2584 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u258c \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580\\u2580\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2584 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580\\u2580\\u2580\\u2580 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580\\u2580\\u2580\\u2580 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2580\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2584 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u258c\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2588\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\n//\\n//\\n\\n// Initial version copied from Keep Network ECDSA Wallets:\\n// https://github.com/keep-network/keep-core/blob/5286ebc8ff99b2aa6569f9dd97fd6995f25b4630/solidity/ecdsa/contracts/libraries/EcdsaAuthorization.sol\\n//\\n// With the following differences:\\n// - functions' visibility was changed to public/external to deploy it as a linked\\n// library.\\n// - documentation was updated to be more generic.\\n\\npragma solidity 0.8.17;\\n\\nimport \\\"@keep-network/sortition-pools/contracts/SortitionPool.sol\\\";\\nimport \\\"@threshold-network/solidity-contracts/contracts/staking/IStaking.sol\\\";\\n\\n/// @notice Library managing the state of stake authorizations for the operator\\n/// contract and the presence of operators in the sortition\\n/// pool based on the stake authorized for them.\\nlibrary BeaconAuthorization {\\n struct Parameters {\\n // The minimum authorization required by the beacon so that\\n // operator can join the sortition pool and do the work.\\n uint96 minimumAuthorization;\\n // Authorization decrease delay in seconds between the time\\n // authorization decrease is requested and the time the authorization\\n // decrease can be approved. It is always the same value, no matter if\\n // authorization decrease amount is small, significant, or if it is\\n // a decrease to zero.\\n uint64 authorizationDecreaseDelay;\\n // The time period before the authorization decrease delay end,\\n // during which the authorization decrease request can be overwritten.\\n //\\n // When the request is overwritten, the authorization decrease delay is\\n // reset.\\n //\\n // For example, if `authorizationDecraseChangePeriod` is set to 4\\n // days, `authorizationDecreaseDelay` is set to 14 days, and someone\\n // requested authorization decrease, it means they can not\\n // request another decrease for the first 10 days. After 10 days pass,\\n // they can request again and overwrite the previous authorization\\n // decrease request. The delay time will reset for them and they\\n // will have to wait another 10 days to alter it and 14 days to\\n // approve it.\\n //\\n // This value protects against malicious operators who manipulate\\n // their weight by overwriting authorization decrease request, and\\n // lowering or increasing their eligible stake this way.\\n //\\n // If set to a value equal to `authorizationDecreaseDelay, it means\\n // that authorization decrease request can be always overwritten.\\n // If set to zero, it means authorization decrease request can not be\\n // overwritten until the delay end, and one needs to wait for the entire\\n // authorization decrease delay to approve their decrease and request\\n // for another one or to overwrite the pending one.\\n //\\n // (1) authorization decrease requested timestamp\\n // (2) from this moment authorization decrease request can be\\n // overwritten\\n // (3) from this moment authorization decrease request can be\\n // approved, assuming it was NOT overwritten in (2)\\n //\\n // (1) (2) (3)\\n // --x------------------------------x--------------------------x---->\\n // | \\\\________________________/\\n // | authorizationDecreaseChangePeriod\\n // \\\\______________________________________________________/\\n // authorizationDecreaseDelay\\n //\\n uint64 authorizationDecreaseChangePeriod;\\n }\\n\\n struct AuthorizationDecrease {\\n uint96 decreasingBy; // amount\\n uint64 decreasingAt; // timestamp\\n }\\n\\n struct Data {\\n Parameters parameters;\\n mapping(address => address) stakingProviderToOperator;\\n mapping(address => address) operatorToStakingProvider;\\n mapping(address => AuthorizationDecrease) pendingDecreases;\\n }\\n\\n event OperatorRegistered(\\n address indexed stakingProvider,\\n address indexed operator\\n );\\n\\n event AuthorizationIncreased(\\n address indexed stakingProvider,\\n address indexed operator,\\n uint96 fromAmount,\\n uint96 toAmount\\n );\\n\\n event AuthorizationDecreaseRequested(\\n address indexed stakingProvider,\\n address indexed operator,\\n uint96 fromAmount,\\n uint96 toAmount,\\n uint64 decreasingAt\\n );\\n\\n event AuthorizationDecreaseApproved(address indexed stakingProvider);\\n\\n event InvoluntaryAuthorizationDecreaseFailed(\\n address indexed stakingProvider,\\n address indexed operator,\\n uint96 fromAmount,\\n uint96 toAmount\\n );\\n\\n event OperatorJoinedSortitionPool(\\n address indexed stakingProvider,\\n address indexed operator\\n );\\n\\n event OperatorStatusUpdated(\\n address indexed stakingProvider,\\n address indexed operator\\n );\\n\\n /// @notice Updates authorization-related parameters.\\n /// @param _minimumAuthorization New value of the minimum authorization for\\n /// the beacon. Without at least the minimum authorization, staking\\n /// provider is not eligible to join and operate in the network.\\n /// @param _authorizationDecreaseDelay New value of the authorization\\n /// decrease delay. It is the time in seconds that needs to pass\\n /// between the time authorization decrease is requested and the time\\n /// the authorization decrease can be approved, no matter the\\n /// authorization decrease amount.\\n /// @param _authorizationDecreaseChangePeriod New value of the authorization\\n /// decrease change period. It is the time in seconds, before\\n /// authorization decrease delay end, during which the pending\\n /// authorization decrease request can be overwritten.\\n /// If set to 0, pending authorization decrease request can not be\\n /// overwritten until the entire `authorizationDecreaseDelay` ends.\\n /// If set to value equal `authorizationDecreaseDelay`, request can\\n /// always be overwritten.\\n function setParameters(\\n Data storage self,\\n uint96 _minimumAuthorization,\\n uint64 _authorizationDecreaseDelay,\\n uint64 _authorizationDecreaseChangePeriod\\n ) external {\\n self.parameters.minimumAuthorization = _minimumAuthorization;\\n self\\n .parameters\\n .authorizationDecreaseDelay = _authorizationDecreaseDelay;\\n self\\n .parameters\\n .authorizationDecreaseChangePeriod = _authorizationDecreaseChangePeriod;\\n }\\n\\n /// @notice Used by staking provider to set operator address that will\\n /// operate a node. The given staking provider can set operator\\n /// address only one time. The operator address can not be changed\\n /// and must be unique. Reverts if the operator is already set for\\n /// the staking provider or if the operator address is already in\\n /// use. Reverts if there is a pending authorization decrease for\\n /// the staking provider.\\n function registerOperator(Data storage self, address operator) public {\\n address stakingProvider = msg.sender;\\n\\n require(operator != address(0), \\\"Operator can not be zero address\\\");\\n require(\\n self.stakingProviderToOperator[stakingProvider] == address(0),\\n \\\"Operator already set for the staking provider\\\"\\n );\\n require(\\n self.operatorToStakingProvider[operator] == address(0),\\n \\\"Operator address already in use\\\"\\n );\\n\\n // Authorization request for a staking provider who has not yet\\n // registered their operator can be approved immediately.\\n // We need to make sure that the approval happens before operator\\n // is registered to do not let the operator join the sortition pool\\n // with an unresolved authorization decrease request that can be\\n // approved at any point.\\n AuthorizationDecrease storage decrease = self.pendingDecreases[\\n stakingProvider\\n ];\\n require(\\n decrease.decreasingAt == 0,\\n \\\"There is a pending authorization decrease request\\\"\\n );\\n\\n emit OperatorRegistered(stakingProvider, operator);\\n\\n self.stakingProviderToOperator[stakingProvider] = operator;\\n self.operatorToStakingProvider[operator] = stakingProvider;\\n }\\n\\n /// @notice Used by T staking contract to inform the beacon that the\\n /// authorized stake amount for the given staking provider increased.\\n ///\\n /// Reverts if the authorization amount is below the minimum.\\n ///\\n /// The function is not updating the sortition pool. Sortition pool\\n /// state needs to be updated by the operator with a call to\\n /// `joinSortitionPool` or `updateOperatorStatus`.\\n ///\\n /// @dev Should only be callable by T staking contract.\\n function authorizationIncreased(\\n Data storage self,\\n address stakingProvider,\\n uint96 fromAmount,\\n uint96 toAmount\\n ) external {\\n require(\\n toAmount >= self.parameters.minimumAuthorization,\\n \\\"Authorization below the minimum\\\"\\n );\\n\\n // Note that this function does not require the operator address to be\\n // set for the given staking provider. This allows the stake owner\\n // who is also an authorizer to increase the authorization before the\\n // staking provider sets the operator. This allows delegating stake\\n // and increasing authorization immediately one after another without\\n // having to wait for the staking provider to do their part.\\n\\n address operator = self.stakingProviderToOperator[stakingProvider];\\n emit AuthorizationIncreased(\\n stakingProvider,\\n operator,\\n fromAmount,\\n toAmount\\n );\\n }\\n\\n /// @notice Used by T staking contract to inform the beacon that the\\n /// authorization decrease for the given staking provider has been\\n /// requested.\\n ///\\n /// Reverts if the amount after deauthorization would be non-zero\\n /// and lower than the minimum authorization.\\n ///\\n /// Reverts if another authorization decrease request is pending for\\n /// the staking provider and not enough time passed since the\\n /// original request (see `authorizationDecreaseChangePeriod`).\\n ///\\n /// If the operator is not known (`registerOperator` was not called)\\n /// it lets to `approveAuthorizationDecrease` immediately. If the\\n /// operator is known (`registerOperator` was called), the operator\\n /// needs to update state of the sortition pool with a call to\\n /// `joinSortitionPool` or `updateOperatorStatus`. After the\\n /// sortition pool state is in sync, authorization decrease delay\\n /// starts.\\n ///\\n /// After authorization decrease delay passes, authorization\\n /// decrease request needs to be approved with a call to\\n /// `approveAuthorizationDecrease` function.\\n ///\\n /// If there is a pending authorization decrease request, it is\\n /// overwritten, but only if enough time passed since the original\\n /// request. Otherwise, the function reverts.\\n ///\\n /// @dev Should only be callable by T staking contract.\\n function authorizationDecreaseRequested(\\n Data storage self,\\n address stakingProvider,\\n uint96 fromAmount,\\n uint96 toAmount\\n ) public {\\n require(\\n toAmount == 0 || toAmount >= self.parameters.minimumAuthorization,\\n \\\"Authorization amount should be 0 or above the minimum\\\"\\n );\\n\\n address operator = self.stakingProviderToOperator[stakingProvider];\\n\\n uint64 decreasingAt;\\n\\n if (operator == address(0)) {\\n // Operator is not known. It means `registerOperator` was not\\n // called yet, and there is no chance the operator could\\n // call `joinSortitionPool`. We can let to approve authorization\\n // decrease immediately because that operator was never in the\\n // sortition pool.\\n\\n // solhint-disable-next-line not-rely-on-time\\n decreasingAt = uint64(block.timestamp);\\n } else {\\n // Operator is known. It means that this operator is or was in\\n // the sortition pool. Before authorization decrease delay starts,\\n // the operator needs to update the state of the sortition pool\\n // with a call to `joinSortitionPool` or `updateOperatorStatus`.\\n // For now, we set `decreasingAt` as \\\"never decreasing\\\" and let\\n // it be updated by `joinSortitionPool` or `updateOperatorStatus`\\n // once we know the sortition pool is in sync.\\n decreasingAt = type(uint64).max;\\n }\\n\\n uint96 decreasingBy = fromAmount - toAmount;\\n\\n AuthorizationDecrease storage decreaseRequest = self.pendingDecreases[\\n stakingProvider\\n ];\\n\\n uint64 pendingDecreaseAt = decreaseRequest.decreasingAt;\\n if (pendingDecreaseAt != 0 && pendingDecreaseAt != type(uint64).max) {\\n // If there is already a pending authorization decrease request for\\n // this staking provider and that request has been activated\\n // (sortition pool was updated), require enough time to pass before\\n // it can be overwritten.\\n require(\\n // solhint-disable-next-line not-rely-on-time\\n block.timestamp >=\\n pendingDecreaseAt -\\n self.parameters.authorizationDecreaseChangePeriod,\\n \\\"Not enough time passed since the original request\\\"\\n );\\n }\\n\\n decreaseRequest.decreasingBy = decreasingBy;\\n decreaseRequest.decreasingAt = decreasingAt;\\n\\n emit AuthorizationDecreaseRequested(\\n stakingProvider,\\n operator,\\n fromAmount,\\n toAmount,\\n decreasingAt\\n );\\n }\\n\\n /// @notice Approves the previously registered authorization decrease\\n /// request. Reverts if authorization decrease delay have not passed\\n /// yet or if the authorization decrease was not requested for the\\n /// given staking provider.\\n function approveAuthorizationDecrease(\\n Data storage self,\\n IStaking tokenStaking,\\n address stakingProvider\\n ) public {\\n AuthorizationDecrease storage decrease = self.pendingDecreases[\\n stakingProvider\\n ];\\n require(\\n decrease.decreasingAt > 0,\\n \\\"Authorization decrease not requested\\\"\\n );\\n require(\\n decrease.decreasingAt != type(uint64).max,\\n \\\"Authorization decrease request not activated\\\"\\n );\\n require(\\n // solhint-disable-next-line not-rely-on-time\\n block.timestamp >= decrease.decreasingAt,\\n \\\"Authorization decrease delay not passed\\\"\\n );\\n\\n emit AuthorizationDecreaseApproved(stakingProvider);\\n\\n // slither-disable-next-line unused-return\\n tokenStaking.approveAuthorizationDecrease(stakingProvider);\\n delete self.pendingDecreases[stakingProvider];\\n }\\n\\n /// @notice Used by T staking contract to inform the beacon the\\n /// authorization has been decreased for the given staking provider\\n /// involuntarily, as a result of slashing.\\n ///\\n /// If the operator is not known (`registerOperator` was not called)\\n /// the function does nothing. The operator was never in a sortition\\n /// pool so there is nothing to update.\\n ///\\n /// If the operator is known, sortition pool is unlocked, and the\\n /// operator is in the sortition pool, the sortition pool state is\\n /// updated. If the sortition pool is locked, update needs to be\\n /// postponed. Every other staker is incentivized to call\\n /// `updateOperatorStatus` for the problematic operator to increase\\n /// their own rewards in the pool.\\n ///\\n /// @dev Should only be callable by T staking contract.\\n function involuntaryAuthorizationDecrease(\\n Data storage self,\\n IStaking tokenStaking,\\n SortitionPool sortitionPool,\\n address stakingProvider,\\n uint96 fromAmount,\\n uint96 toAmount\\n ) external {\\n address operator = self.stakingProviderToOperator[stakingProvider];\\n\\n if (operator == address(0)) {\\n // Operator is not known. It means `registerOperator` was not\\n // called yet, and there is no chance the operator could\\n // call `joinSortitionPool`. We can just ignore this update because\\n // operator was never in the sortition pool.\\n return;\\n } else {\\n // Operator is known. It means that this operator is or was in the\\n // sortition pool and the sortition pool may need to be updated.\\n //\\n // If the sortition pool is not locked and the operator is in the\\n // sortition pool, we are updating it.\\n //\\n // To keep stakes synchronized between applications when staking\\n // providers are slashed, without the risk of running out of gas,\\n // the staking contract queues up slashings and let users process\\n // the transactions. When an application slashes one or more staking\\n // providers, it adds them to the slashing queue on the staking\\n // contract. A queue entry contains the staking provider\\u2019s address\\n // and the amount they are due to be slashed.\\n //\\n // When there is at least one staking provider in the slashing\\n // queue, any account can submit a transaction processing one or\\n // more staking providers' slashings, and collecting a reward for\\n // doing so. A queued slashing is processed by updating the staking\\n // provider\\u2019s stake to the post-slashing amount, updating authorized\\n // amount for each affected application, and notifying all affected\\n // applications that the staking provider\\u2019s authorized stake has\\n // been reduced due to slashing.\\n //\\n // The entire idea is that the process transaction is expensive\\n // because each application needs to be updated, so the reward for\\n // the processor is hefty and comes from the slashed tokens.\\n // Practically, it means that if the sortition pool is unlocked, and\\n // can be updated, it should be updated because we already paid\\n // someone for updating it.\\n //\\n // If the sortition pool is locked, update needs to wait. Other\\n // sortition pool members are incentivized to call\\n // `updateOperatorStatus` for the problematic operator because they\\n // will increase their rewards this way.\\n if (sortitionPool.isOperatorInPool(operator)) {\\n if (sortitionPool.isLocked()) {\\n emit InvoluntaryAuthorizationDecreaseFailed(\\n stakingProvider,\\n operator,\\n fromAmount,\\n toAmount\\n );\\n } else {\\n updateOperatorStatus(\\n self,\\n tokenStaking,\\n sortitionPool,\\n operator\\n );\\n }\\n }\\n }\\n }\\n\\n /// @notice Lets the operator join the sortition pool. The operator address\\n /// must be known - before calling this function, it has to be\\n /// appointed by the staking provider by calling `registerOperator`.\\n /// Also, the operator must have the minimum authorization required\\n /// by the beacon. Function reverts if there is no minimum stake\\n /// authorized or if the operator is not known. If there was an\\n /// authorization decrease requested, it is activated by starting\\n /// the authorization decrease delay.\\n function joinSortitionPool(\\n Data storage self,\\n IStaking tokenStaking,\\n SortitionPool sortitionPool\\n ) public {\\n address operator = msg.sender;\\n\\n address stakingProvider = self.operatorToStakingProvider[operator];\\n require(stakingProvider != address(0), \\\"Unknown operator\\\");\\n\\n AuthorizationDecrease storage decrease = self.pendingDecreases[\\n stakingProvider\\n ];\\n\\n uint96 _eligibleStake = eligibleStake(\\n self,\\n tokenStaking,\\n stakingProvider,\\n decrease.decreasingBy\\n );\\n\\n require(_eligibleStake != 0, \\\"Authorization below the minimum\\\");\\n\\n emit OperatorJoinedSortitionPool(stakingProvider, operator);\\n\\n sortitionPool.insertOperator(operator, _eligibleStake);\\n\\n // If there is a pending authorization decrease request, activate it.\\n // At this point, the sortition pool state is up to date so the\\n // authorization decrease delay can start counting.\\n if (decrease.decreasingAt == type(uint64).max) {\\n decrease.decreasingAt =\\n // solhint-disable-next-line not-rely-on-time\\n uint64(block.timestamp) +\\n self.parameters.authorizationDecreaseDelay;\\n }\\n }\\n\\n /// @notice Updates status of the operator in the sortition pool. If there\\n /// was an authorization decrease requested, it is activated by\\n /// starting the authorization decrease delay.\\n /// Function reverts if the operator is not known.\\n function updateOperatorStatus(\\n Data storage self,\\n IStaking tokenStaking,\\n SortitionPool sortitionPool,\\n address operator\\n ) public {\\n address stakingProvider = self.operatorToStakingProvider[operator];\\n require(stakingProvider != address(0), \\\"Unknown operator\\\");\\n\\n AuthorizationDecrease storage decrease = self.pendingDecreases[\\n stakingProvider\\n ];\\n\\n emit OperatorStatusUpdated(stakingProvider, operator);\\n\\n if (sortitionPool.isOperatorInPool(operator)) {\\n uint96 _eligibleStake = eligibleStake(\\n self,\\n tokenStaking,\\n stakingProvider,\\n decrease.decreasingBy\\n );\\n\\n sortitionPool.updateOperatorStatus(operator, _eligibleStake);\\n }\\n\\n // If there is a pending authorization decrease request, activate it.\\n // At this point, the sortition pool state is up to date so the\\n // authorization decrease delay can start counting.\\n if (decrease.decreasingAt == type(uint64).max) {\\n decrease.decreasingAt =\\n // solhint-disable-next-line not-rely-on-time\\n uint64(block.timestamp) +\\n self.parameters.authorizationDecreaseDelay;\\n }\\n }\\n\\n /// @notice Checks if the operator's authorized stake is in sync with\\n /// operator's weight in the sortition pool.\\n /// If the operator is not in the sortition pool and their\\n /// authorized stake is non-zero, function returns false.\\n function isOperatorUpToDate(\\n Data storage self,\\n IStaking tokenStaking,\\n SortitionPool sortitionPool,\\n address operator\\n ) external view returns (bool) {\\n address stakingProvider = self.operatorToStakingProvider[operator];\\n require(stakingProvider != address(0), \\\"Unknown operator\\\");\\n\\n AuthorizationDecrease storage decrease = self.pendingDecreases[\\n stakingProvider\\n ];\\n\\n uint96 _eligibleStake = eligibleStake(\\n self,\\n tokenStaking,\\n stakingProvider,\\n decrease.decreasingBy\\n );\\n\\n if (!sortitionPool.isOperatorInPool(operator)) {\\n return _eligibleStake == 0;\\n } else {\\n return sortitionPool.isOperatorUpToDate(operator, _eligibleStake);\\n }\\n }\\n\\n /// @notice Returns the current value of the staking provider's eligible\\n /// stake. Eligible stake is defined as the currently authorized\\n /// stake minus the pending authorization decrease. Eligible stake\\n /// is what is used for operator's weight in the pool. If the\\n /// authorized stake minus the pending authorization decrease is\\n /// below the minimum authorization, eligible stake is 0.\\n /// @dev This function can be exposed to the public in contrast to the\\n /// second variant accepting `decreasingBy` as a parameter.\\n function eligibleStake(\\n Data storage self,\\n IStaking tokenStaking,\\n address stakingProvider\\n ) external view returns (uint96) {\\n return\\n eligibleStake(\\n self,\\n tokenStaking,\\n stakingProvider,\\n pendingAuthorizationDecrease(self, stakingProvider)\\n );\\n }\\n\\n /// @notice Returns the current value of the staking provider's eligible\\n /// stake. Eligible stake is defined as the currently authorized\\n /// stake minus the pending authorization decrease. Eligible stake\\n /// is what is used for operator's weight in the pool. If the\\n /// authorized stake minus the pending authorization decrease is\\n /// below the minimum authorization, eligible stake is 0.\\n /// @dev This function is not intended to be exposes to the public.\\n /// `decreasingBy` must be fetched from `pendingDecreases` mapping and\\n /// it is passed as a parameter to optimize gas usage of functions that\\n /// call `eligibleStake` and need to use `AuthorizationDecrease`\\n /// fetched from `pendingDecreases` for some additional logic.\\n function eligibleStake(\\n Data storage self,\\n IStaking tokenStaking,\\n address stakingProvider,\\n uint96 decreasingBy\\n ) public view returns (uint96) {\\n uint96 authorizedStake = tokenStaking.authorizedStake(\\n stakingProvider,\\n address(this)\\n );\\n\\n uint96 _eligibleStake = authorizedStake > decreasingBy\\n ? authorizedStake - decreasingBy\\n : 0;\\n\\n if (_eligibleStake < self.parameters.minimumAuthorization) {\\n return 0;\\n } else {\\n return _eligibleStake;\\n }\\n }\\n\\n /// @notice Returns the amount of stake that is pending authorization\\n /// decrease for the given staking provider. If no authorization\\n /// decrease has been requested, returns zero.\\n function pendingAuthorizationDecrease(\\n Data storage self,\\n address stakingProvider\\n ) public view returns (uint96) {\\n AuthorizationDecrease storage decrease = self.pendingDecreases[\\n stakingProvider\\n ];\\n\\n return decrease.decreasingBy;\\n }\\n\\n /// @notice Returns the remaining time in seconds that needs to pass before\\n /// the requested authorization decrease can be approved.\\n /// If the sortition pool state was not updated yet by the operator\\n /// after requesting the authorization decrease, returns\\n /// `type(uint64).max`.\\n function remainingAuthorizationDecreaseDelay(\\n Data storage self,\\n address stakingProvider\\n ) external view returns (uint64) {\\n AuthorizationDecrease storage decrease = self.pendingDecreases[\\n stakingProvider\\n ];\\n\\n if (decrease.decreasingAt == type(uint64).max) {\\n return type(uint64).max;\\n }\\n\\n // solhint-disable-next-line not-rely-on-time\\n uint64 _now = uint64(block.timestamp);\\n return _now > decrease.decreasingAt ? 0 : decrease.decreasingAt - _now;\\n }\\n}\\n\",\"keccak256\":\"0xe146f4a3c662e971317d0189b2fca613f9f83a163ef682ed1e536e6c1f919a08\",\"license\":\"GPL-3.0-only\"}},\"version\":1}",
193
+ "bytecode": "0x61167561003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100d85760003560e01c8063b86b341e11610096578063d563485c11610070578063d563485c14610233578063db82504e14610253578063ee7ae2a914610273578063f4dbcff41461028657600080fd5b8063b86b341e146101b2578063bf865212146101dd578063c6e1c8391461021357600080fd5b80624f4ac7146100dd578063251db5981461010d57806345e592941461012f578063475592631461014f578063520502841461016f578063520c3d3114610192575b600080fd5b6100f06100eb3660046112f2565b6102f1565b6040516001600160401b0390911681526020015b60405180910390f35b81801561011957600080fd5b5061012d610128366004611322565b61038b565b005b81801561013b57600080fd5b5061012d61014a366004611379565b6105d1565b81801561015b57600080fd5b5061012d61016a3660046112f2565b61073d565b61018261017d3660046113f2565b6109a0565b6040519015158152602001610104565b81801561019e57600080fd5b5061012d6101ad366004611322565b610b16565b6101c56101c0366004611322565b610cf0565b6040516001600160601b039091168152602001610104565b6101c56101eb3660046112f2565b6001600160a01b0316600090815260039190910160205260409020546001600160601b031690565b81801561021f57600080fd5b5061012d61022e3660046113f2565b610d23565b81801561023f57600080fd5b5061012d61024e366004611445565b610f02565b81801561025f57600080fd5b5061012d61026e366004611445565b610fcf565b6101c561028136600461148d565b61120a565b81801561029257600080fd5b5061012d6102a13660046114e1565b83546001600160601b03939093166001600160a01b031990931692909217600160601b6001600160401b03928316021767ffffffffffffffff60a01b1916600160a01b9290911691909102179055565b6001600160a01b03811660009081526003830160205260408120805467fffffffffffffffe19600160601b9091046001600160401b03160161033d576001600160401b03915050610385565b805442906001600160401b03600160601b90910481169082161161037d578154610378908290600160601b90046001600160401b0316611546565b610380565b60005b925050505b92915050565b6001600160a01b038116600090815260038401602052604090208054600160601b90046001600160401b03166104145760405162461bcd60e51b8152602060048201526024808201527f417574686f72697a6174696f6e206465637265617365206e6f742072657175656044820152631cdd195960e21b60648201526084015b60405180910390fd5b805467fffffffffffffffe19600160601b9091046001600160401b0316016104935760405162461bcd60e51b815260206004820152602c60248201527f417574686f72697a6174696f6e2064656372656173652072657175657374206e60448201526b1bdd081858dd1a5d985d195960a21b606482015260840161040b565b8054600160601b90046001600160401b03164210156105045760405162461bcd60e51b815260206004820152602760248201527f417574686f72697a6174696f6e2064656372656173652064656c6179206e6f74604482015266081c185cdcd95960ca1b606482015260840161040b565b6040516001600160a01b038316907f50270a522c2fef97b6b7385c2aa4a4518adda681530e0a1fe9f5e840f6f2cd9d90600090a2604051633af0572d60e11b81526001600160a01b0383811660048301528416906375e0ae5a906024016020604051808303816000875af1158015610580573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a4919061156d565b50506001600160a01b031660009081526003909201602052506040902080546001600160a01b0319169055565b6001600160a01b03808416600090815260018801602052604090205416806105f95750610735565b6040516307b8c36760e51b81526001600160a01b03828116600483015286169063f7186ce090602401602060405180830381865afa15801561063f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106639190611591565b1561073357846001600160a01b031663a4e2d6346040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ca9190611591565b1561072757604080516001600160601b038086168252841660208201526001600160a01b0380841692908716917f1b09380d63e78fd72c1d79a805a7e2dfadf02b22418e24bebff51376b7df33b0910160405180910390a3610733565b61073387878784610d23565b505b505050505050565b336001600160a01b0382166107945760405162461bcd60e51b815260206004820181905260248201527f4f70657261746f722063616e206e6f74206265207a65726f2061646472657373604482015260640161040b565b6001600160a01b03818116600090815260018501602052604090205416156108145760405162461bcd60e51b815260206004820152602d60248201527f4f70657261746f7220616c72656164792073657420666f72207468652073746160448201526c35b4b73390383937bb34b232b960991b606482015260840161040b565b6001600160a01b038281166000908152600285016020526040902054161561087e5760405162461bcd60e51b815260206004820152601f60248201527f4f70657261746f72206164647265737320616c726561647920696e2075736500604482015260640161040b565b6001600160a01b038116600090815260038401602052604090208054600160601b90046001600160401b0316156109115760405162461bcd60e51b815260206004820152603160248201527f546865726520697320612070656e64696e6720617574686f72697a6174696f6e60448201527008191958dc99585cd9481c995c5d595cdd607a1b606482015260840161040b565b826001600160a01b0316826001600160a01b03167fa453db612af59e5521d6ab9284dc3e2d06af286eb1b1b7b771fce4716c19f2c160405160405180910390a3506001600160a01b03908116600081815260018501602090815260408083208054959096166001600160a01b031995861681179096559482526002909501909452919092208054909216179055565b6001600160a01b038082166000908152600286016020526040812054909116806109dc5760405162461bcd60e51b815260040161040b906115b3565b6001600160a01b038116600090815260038701602052604081208054909190610a13908990899086906001600160601b031661120a565b6040516307b8c36760e51b81526001600160a01b0387811660048301529192509087169063f7186ce090602401602060405180830381865afa158015610a5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a819190611591565b610a99576001600160601b0316159250610b0e915050565b6040516304de824f60e41b81526001600160a01b03871690634de824f090610ac790889085906004016115dd565b602060405180830381865afa158015610ae4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b089190611591565b93505050505b949350505050565b3360008181526002850160205260409020546001600160a01b031680610b4e5760405162461bcd60e51b815260040161040b906115b3565b6001600160a01b038116600090815260038601602052604081208054909190610b85908890889086906001600160601b031661120a565b9050806001600160601b0316600003610be05760405162461bcd60e51b815260206004820152601f60248201527f417574686f72697a6174696f6e2062656c6f7720746865206d696e696d756d00604482015260640161040b565b836001600160a01b0316836001600160a01b03167f5075aaa89894a888eb2cac81a27320c60855febb0cf1706b66bdc754e640d43360405160405180910390a3604051630483483160e31b81526001600160a01b0386169063241a418890610c4e90879085906004016115dd565b600060405180830381600087803b158015610c6857600080fd5b505af1158015610c7c573d6000803e3d6000fd5b5050835467fffffffffffffffe19600160601b9091046001600160401b03160191506107339050578654610cc090600160601b90046001600160401b0316426115ff565b82546001600160401b0391909116600160601b0267ffffffffffffffff60601b1990911617825550505050505050565b6001600160a01b0381166000908152600384016020526040812054610b0e908590859085906001600160601b031661120a565b6001600160a01b0380821660009081526002860160205260409020541680610d5d5760405162461bcd60e51b815260040161040b906115b3565b6001600160a01b03808216600081815260038801602052604080822090519093861692917f1231fe5ee649a593b524a494cd53146a196380a872115a0d0fe16c0735afdf2691a36040516307b8c36760e51b81526001600160a01b03848116600483015285169063f7186ce090602401602060405180830381865afa158015610dea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0e9190611591565b15610e95578054600090610e30908890889086906001600160601b031661120a565b60405163dc7520c560e01b81529091506001600160a01b0386169063dc7520c590610e6190879085906004016115dd565b600060405180830381600087803b158015610e7b57600080fd5b505af1158015610e8f573d6000803e3d6000fd5b50505050505b805467fffffffffffffffe19600160601b9091046001600160401b031601610735578554610ed390600160601b90046001600160401b0316426115ff565b81546001600160401b0391909116600160601b0267ffffffffffffffff60601b19909116178155505050505050565b83546001600160601b039081169082161015610f605760405162461bcd60e51b815260206004820152601f60248201527f417574686f72697a6174696f6e2062656c6f7720746865206d696e696d756d00604482015260640161040b565b6001600160a01b0383811660008181526001870160209081526040918290205482516001600160601b03888116825287169281019290925282519416938493927f87f9f9f59204f53d57a89a817c6083a17979cd0531791c91e18551a56e3cfdd7928290030190a35050505050565b6001600160601b0381161580610ff3575083546001600160601b0390811690821610155b61105d5760405162461bcd60e51b815260206004820152603560248201527f417574686f72697a6174696f6e20616d6f756e742073686f756c642062652030604482015274206f722061626f766520746865206d696e696d756d60581b606482015260840161040b565b6001600160a01b0380841660009081526001860160205260408120549091169081611089575042611093565b506001600160401b035b600061109f848661161f565b6001600160a01b03871660009081526003890160205260409020805491925090600160601b90046001600160401b031680158015906110e757506001600160401b0381811614155b1561117a57885461110890600160a01b90046001600160401b031682611546565b6001600160401b031642101561117a5760405162461bcd60e51b815260206004820152603160248201527f4e6f7420656e6f7567682074696d65207061737365642073696e636520746865604482015270081bdc9a59da5b985b081c995c5d595cdd607a1b606482015260840161040b565b81546001600160401b038516600160601b81026001600160a01b03199092166001600160601b0386811691909117929092178455604080518a8416815292891660208401528201526001600160a01b0386811691908a16907f545cbf267cef6fe43f11f6219417ab43a0e8e345adbaae5f626d9bc325e8535a9060600160405180910390a3505050505050505050565b604051637004922d60e11b81526001600160a01b038381166004830152306024830152600091829186169063e009245a90604401602060405180830381865afa15801561125b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127f919061156d565b90506000836001600160601b0316826001600160601b0316116112a35760006112ad565b6112ad848361161f565b87549091506001600160601b0390811690821610156112d157600092505050610b0e565b9150610b0e9050565b6001600160a01b03811681146112ef57600080fd5b50565b6000806040838503121561130557600080fd5b823591506020830135611317816112da565b809150509250929050565b60008060006060848603121561133757600080fd5b833592506020840135611349816112da565b91506040840135611359816112da565b809150509250925092565b6001600160601b03811681146112ef57600080fd5b60008060008060008060c0878903121561139257600080fd5b8635955060208701356113a4816112da565b945060408701356113b4816112da565b935060608701356113c4816112da565b925060808701356113d481611364565b915060a08701356113e481611364565b809150509295509295509295565b6000806000806080858703121561140857600080fd5b84359350602085013561141a816112da565b9250604085013561142a816112da565b9150606085013561143a816112da565b939692955090935050565b6000806000806080858703121561145b57600080fd5b84359350602085013561146d816112da565b9250604085013561147d81611364565b9150606085013561143a81611364565b600080600080608085870312156114a357600080fd5b8435935060208501356114b5816112da565b9250604085013561147d816112da565b80356001600160401b03811681146114dc57600080fd5b919050565b600080600080608085870312156114f757600080fd5b84359350602085013561150981611364565b9250611517604086016114c5565b9150611525606086016114c5565b905092959194509250565b634e487b7160e01b600052601160045260246000fd5b6001600160401b0382811682821603908082111561156657611566611530565b5092915050565b60006020828403121561157f57600080fd5b815161158a81611364565b9392505050565b6000602082840312156115a357600080fd5b8151801515811461158a57600080fd5b60208082526010908201526f2ab735b737bbb71037b832b930ba37b960811b604082015260600190565b6001600160a01b039290921682526001600160601b0316602082015260400190565b6001600160401b0381811683821601908082111561156657611566611530565b6001600160601b038281168282160390808211156115665761156661153056fea264697066735822122041e6fbf54d81e891b2e7016f9d9bae1ca0beea482da4cc00d21eb702caaa884364736f6c63430008110033",
194
+ "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600436106100d85760003560e01c8063b86b341e11610096578063d563485c11610070578063d563485c14610233578063db82504e14610253578063ee7ae2a914610273578063f4dbcff41461028657600080fd5b8063b86b341e146101b2578063bf865212146101dd578063c6e1c8391461021357600080fd5b80624f4ac7146100dd578063251db5981461010d57806345e592941461012f578063475592631461014f578063520502841461016f578063520c3d3114610192575b600080fd5b6100f06100eb3660046112f2565b6102f1565b6040516001600160401b0390911681526020015b60405180910390f35b81801561011957600080fd5b5061012d610128366004611322565b61038b565b005b81801561013b57600080fd5b5061012d61014a366004611379565b6105d1565b81801561015b57600080fd5b5061012d61016a3660046112f2565b61073d565b61018261017d3660046113f2565b6109a0565b6040519015158152602001610104565b81801561019e57600080fd5b5061012d6101ad366004611322565b610b16565b6101c56101c0366004611322565b610cf0565b6040516001600160601b039091168152602001610104565b6101c56101eb3660046112f2565b6001600160a01b0316600090815260039190910160205260409020546001600160601b031690565b81801561021f57600080fd5b5061012d61022e3660046113f2565b610d23565b81801561023f57600080fd5b5061012d61024e366004611445565b610f02565b81801561025f57600080fd5b5061012d61026e366004611445565b610fcf565b6101c561028136600461148d565b61120a565b81801561029257600080fd5b5061012d6102a13660046114e1565b83546001600160601b03939093166001600160a01b031990931692909217600160601b6001600160401b03928316021767ffffffffffffffff60a01b1916600160a01b9290911691909102179055565b6001600160a01b03811660009081526003830160205260408120805467fffffffffffffffe19600160601b9091046001600160401b03160161033d576001600160401b03915050610385565b805442906001600160401b03600160601b90910481169082161161037d578154610378908290600160601b90046001600160401b0316611546565b610380565b60005b925050505b92915050565b6001600160a01b038116600090815260038401602052604090208054600160601b90046001600160401b03166104145760405162461bcd60e51b8152602060048201526024808201527f417574686f72697a6174696f6e206465637265617365206e6f742072657175656044820152631cdd195960e21b60648201526084015b60405180910390fd5b805467fffffffffffffffe19600160601b9091046001600160401b0316016104935760405162461bcd60e51b815260206004820152602c60248201527f417574686f72697a6174696f6e2064656372656173652072657175657374206e60448201526b1bdd081858dd1a5d985d195960a21b606482015260840161040b565b8054600160601b90046001600160401b03164210156105045760405162461bcd60e51b815260206004820152602760248201527f417574686f72697a6174696f6e2064656372656173652064656c6179206e6f74604482015266081c185cdcd95960ca1b606482015260840161040b565b6040516001600160a01b038316907f50270a522c2fef97b6b7385c2aa4a4518adda681530e0a1fe9f5e840f6f2cd9d90600090a2604051633af0572d60e11b81526001600160a01b0383811660048301528416906375e0ae5a906024016020604051808303816000875af1158015610580573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a4919061156d565b50506001600160a01b031660009081526003909201602052506040902080546001600160a01b0319169055565b6001600160a01b03808416600090815260018801602052604090205416806105f95750610735565b6040516307b8c36760e51b81526001600160a01b03828116600483015286169063f7186ce090602401602060405180830381865afa15801561063f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106639190611591565b1561073357846001600160a01b031663a4e2d6346040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ca9190611591565b1561072757604080516001600160601b038086168252841660208201526001600160a01b0380841692908716917f1b09380d63e78fd72c1d79a805a7e2dfadf02b22418e24bebff51376b7df33b0910160405180910390a3610733565b61073387878784610d23565b505b505050505050565b336001600160a01b0382166107945760405162461bcd60e51b815260206004820181905260248201527f4f70657261746f722063616e206e6f74206265207a65726f2061646472657373604482015260640161040b565b6001600160a01b03818116600090815260018501602052604090205416156108145760405162461bcd60e51b815260206004820152602d60248201527f4f70657261746f7220616c72656164792073657420666f72207468652073746160448201526c35b4b73390383937bb34b232b960991b606482015260840161040b565b6001600160a01b038281166000908152600285016020526040902054161561087e5760405162461bcd60e51b815260206004820152601f60248201527f4f70657261746f72206164647265737320616c726561647920696e2075736500604482015260640161040b565b6001600160a01b038116600090815260038401602052604090208054600160601b90046001600160401b0316156109115760405162461bcd60e51b815260206004820152603160248201527f546865726520697320612070656e64696e6720617574686f72697a6174696f6e60448201527008191958dc99585cd9481c995c5d595cdd607a1b606482015260840161040b565b826001600160a01b0316826001600160a01b03167fa453db612af59e5521d6ab9284dc3e2d06af286eb1b1b7b771fce4716c19f2c160405160405180910390a3506001600160a01b03908116600081815260018501602090815260408083208054959096166001600160a01b031995861681179096559482526002909501909452919092208054909216179055565b6001600160a01b038082166000908152600286016020526040812054909116806109dc5760405162461bcd60e51b815260040161040b906115b3565b6001600160a01b038116600090815260038701602052604081208054909190610a13908990899086906001600160601b031661120a565b6040516307b8c36760e51b81526001600160a01b0387811660048301529192509087169063f7186ce090602401602060405180830381865afa158015610a5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a819190611591565b610a99576001600160601b0316159250610b0e915050565b6040516304de824f60e41b81526001600160a01b03871690634de824f090610ac790889085906004016115dd565b602060405180830381865afa158015610ae4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b089190611591565b93505050505b949350505050565b3360008181526002850160205260409020546001600160a01b031680610b4e5760405162461bcd60e51b815260040161040b906115b3565b6001600160a01b038116600090815260038601602052604081208054909190610b85908890889086906001600160601b031661120a565b9050806001600160601b0316600003610be05760405162461bcd60e51b815260206004820152601f60248201527f417574686f72697a6174696f6e2062656c6f7720746865206d696e696d756d00604482015260640161040b565b836001600160a01b0316836001600160a01b03167f5075aaa89894a888eb2cac81a27320c60855febb0cf1706b66bdc754e640d43360405160405180910390a3604051630483483160e31b81526001600160a01b0386169063241a418890610c4e90879085906004016115dd565b600060405180830381600087803b158015610c6857600080fd5b505af1158015610c7c573d6000803e3d6000fd5b5050835467fffffffffffffffe19600160601b9091046001600160401b03160191506107339050578654610cc090600160601b90046001600160401b0316426115ff565b82546001600160401b0391909116600160601b0267ffffffffffffffff60601b1990911617825550505050505050565b6001600160a01b0381166000908152600384016020526040812054610b0e908590859085906001600160601b031661120a565b6001600160a01b0380821660009081526002860160205260409020541680610d5d5760405162461bcd60e51b815260040161040b906115b3565b6001600160a01b03808216600081815260038801602052604080822090519093861692917f1231fe5ee649a593b524a494cd53146a196380a872115a0d0fe16c0735afdf2691a36040516307b8c36760e51b81526001600160a01b03848116600483015285169063f7186ce090602401602060405180830381865afa158015610dea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0e9190611591565b15610e95578054600090610e30908890889086906001600160601b031661120a565b60405163dc7520c560e01b81529091506001600160a01b0386169063dc7520c590610e6190879085906004016115dd565b600060405180830381600087803b158015610e7b57600080fd5b505af1158015610e8f573d6000803e3d6000fd5b50505050505b805467fffffffffffffffe19600160601b9091046001600160401b031601610735578554610ed390600160601b90046001600160401b0316426115ff565b81546001600160401b0391909116600160601b0267ffffffffffffffff60601b19909116178155505050505050565b83546001600160601b039081169082161015610f605760405162461bcd60e51b815260206004820152601f60248201527f417574686f72697a6174696f6e2062656c6f7720746865206d696e696d756d00604482015260640161040b565b6001600160a01b0383811660008181526001870160209081526040918290205482516001600160601b03888116825287169281019290925282519416938493927f87f9f9f59204f53d57a89a817c6083a17979cd0531791c91e18551a56e3cfdd7928290030190a35050505050565b6001600160601b0381161580610ff3575083546001600160601b0390811690821610155b61105d5760405162461bcd60e51b815260206004820152603560248201527f417574686f72697a6174696f6e20616d6f756e742073686f756c642062652030604482015274206f722061626f766520746865206d696e696d756d60581b606482015260840161040b565b6001600160a01b0380841660009081526001860160205260408120549091169081611089575042611093565b506001600160401b035b600061109f848661161f565b6001600160a01b03871660009081526003890160205260409020805491925090600160601b90046001600160401b031680158015906110e757506001600160401b0381811614155b1561117a57885461110890600160a01b90046001600160401b031682611546565b6001600160401b031642101561117a5760405162461bcd60e51b815260206004820152603160248201527f4e6f7420656e6f7567682074696d65207061737365642073696e636520746865604482015270081bdc9a59da5b985b081c995c5d595cdd607a1b606482015260840161040b565b81546001600160401b038516600160601b81026001600160a01b03199092166001600160601b0386811691909117929092178455604080518a8416815292891660208401528201526001600160a01b0386811691908a16907f545cbf267cef6fe43f11f6219417ab43a0e8e345adbaae5f626d9bc325e8535a9060600160405180910390a3505050505050505050565b604051637004922d60e11b81526001600160a01b038381166004830152306024830152600091829186169063e009245a90604401602060405180830381865afa15801561125b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127f919061156d565b90506000836001600160601b0316826001600160601b0316116112a35760006112ad565b6112ad848361161f565b87549091506001600160601b0390811690821610156112d157600092505050610b0e565b9150610b0e9050565b6001600160a01b03811681146112ef57600080fd5b50565b6000806040838503121561130557600080fd5b823591506020830135611317816112da565b809150509250929050565b60008060006060848603121561133757600080fd5b833592506020840135611349816112da565b91506040840135611359816112da565b809150509250925092565b6001600160601b03811681146112ef57600080fd5b60008060008060008060c0878903121561139257600080fd5b8635955060208701356113a4816112da565b945060408701356113b4816112da565b935060608701356113c4816112da565b925060808701356113d481611364565b915060a08701356113e481611364565b809150509295509295509295565b6000806000806080858703121561140857600080fd5b84359350602085013561141a816112da565b9250604085013561142a816112da565b9150606085013561143a816112da565b939692955090935050565b6000806000806080858703121561145b57600080fd5b84359350602085013561146d816112da565b9250604085013561147d81611364565b9150606085013561143a81611364565b600080600080608085870312156114a357600080fd5b8435935060208501356114b5816112da565b9250604085013561147d816112da565b80356001600160401b03811681146114dc57600080fd5b919050565b600080600080608085870312156114f757600080fd5b84359350602085013561150981611364565b9250611517604086016114c5565b9150611525606086016114c5565b905092959194509250565b634e487b7160e01b600052601160045260246000fd5b6001600160401b0382811682821603908082111561156657611566611530565b5092915050565b60006020828403121561157f57600080fd5b815161158a81611364565b9392505050565b6000602082840312156115a357600080fd5b8151801515811461158a57600080fd5b60208082526010908201526f2ab735b737bbb71037b832b930ba37b960811b604082015260600190565b6001600160a01b039290921682526001600160601b0316602082015260400190565b6001600160401b0381811683821601908082111561156657611566611530565b6001600160601b038281168282160390808211156115665761156661153056fea264697066735822122041e6fbf54d81e891b2e7016f9d9bae1ca0beea482da4cc00d21eb702caaa884364736f6c63430008110033",
195
195
  "devdoc": {
196
196
  "kind": "dev",
197
197
  "methods": {