Address Details
contract
0xf666D879e0480f0Dd9F64D3c31Abd9F89ffA85C9
- Contract Name
- SpiralsStaking
- Creator
- 0xe1c46d–097af5 at 0x83e468–aa82d2
- Balance
- 0 CELO ( )
- Locked CELO Balance
- 0.16 CELO
- Voting CELO Balance
- 0.16 CELO
- Pending Unlocked Gold
- 0.00 CELO
- Tokens
-
Fetching tokens...
- Transactions
- Fetching transactions...
- Transfers
- Fetching transfers...
- Gas Used
- Fetching gas used...
- Last Balance Update
- 13967913
Transactions
Token Transfers
Internal Transactions
Coin Balance History
Logs
Celo Info
Code
Read Contract
Write Contract
This contract has been verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- SpiralsStaking
- Optimization enabled
- true
- Compiler version
- v0.8.10+commit.fc410830
- Optimization runs
- 200
- EVM Version
- london
- Verified at
- 2022-07-18T22:28:55.265843Z
src/SpiralsStaking.sol
// SPDX-License-Identifier: Apache-2.0 // https://docs.soliditylang.org/en/v0.8.10/style-guide.html pragma solidity ^0.8.10; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; import "./IAccounts.sol"; import "./ILockedGold.sol"; import "./IElection.sol"; import "./IRegistry.sol"; import "./IValidators.sol"; contract SpiralsStaking { using SafeMath for uint256; address public validatorGroup; address public owner; uint256 public totalStaked; IRegistry constant c_celoRegistry = IRegistry(0x000000000000000000000000000000000000ce10); mapping(address => uint256) stakeByAccount; event VotesCast( address indexed _address, address indexed _validatorGroup, uint256 indexed amount ); event VotesActivated( address indexed _validatorGroup, uint256 indexed amount ); event Unstake( address indexed _address, address indexed _validatorGroup, uint256 indexed amount ); constructor(address _validatorGroup) { validatorGroup = _validatorGroup; owner = msg.sender; require(getAccounts().createAccount(), "CREATE_ACCOUNT"); } /// @dev Modifier for checking whether function caller is `_owner`. modifier onlyOwner() { require(msg.sender == owner, "Only owner can call this function!"); _; } /* * STAKING */ /// @notice Main function for staking with Spirals protocol /// @dev function stake() external payable { require(msg.value != 0, "NO_VALUE_STAKED"); lock(msg.value); vote(msg.value); stakeByAccount[msg.sender] = stakeByAccount[msg.sender].add(msg.value); totalStaked = totalStaked.add(msg.value); // all pending -> active for this group emit VotesCast(msg.sender, validatorGroup, msg.value); } /// @dev Helper function for locking CELO function lock(uint256 _value) internal { getLockedGold().lock{value: _value}(); } /// @dev Helper function for casting votes with a given validator group function vote(uint256 _value) internal { (address lesser, address greater) = getLesserGreater(); require( !(lesser == address(0) && greater == address(0)), "NO_LESSER_GREATER" ); // Can't both be null address require( getElection().vote(validatorGroup, _value, lesser, greater), "VOTE_FAILED" ); } /// @dev Helper function for getting the 2 validator groups that /// our target validator group is sandwiched between. function getLesserGreater() internal view returns (address, address) { (address[] memory validatorGroups, ) = getElection() .getTotalVotesForEligibleValidatorGroups(); // sorted by votes desc address lesser = address(0); address greater = address(0); for (uint256 i = 0; i < validatorGroups.length; i++) { if (validatorGroup == validatorGroups[i]) { if (i > 0) { greater = validatorGroups[i - 1]; } if (i < validatorGroups.length - 1) { lesser = validatorGroups[i + 1]; } break; } } return (lesser, greater); } /// @dev Activates pending votes (if ready) with a given validator group. function activate() external onlyOwner { IElection c_election = getElection(); require( c_election.hasActivatablePendingVotes( address(this), validatorGroup ), "NOT_READY_TO_ACTIVATE" ); uint256 pendingVotes = getElection().getPendingVotesForGroupByAccount( validatorGroup, address(this) ); require(c_election.activate(validatorGroup), "ACTIVATE_FAILED"); // all pending -> active for this group emit VotesActivated(validatorGroup, pendingVotes); } /* * UNSTAKING */ // function unstake() public {} // function revoke() public {} // function unlock() public {} // function withdraw() public {} /* * OTHER */ /// @notice For updating with validator group we stake with. Performs /// some simple checks to make sure address given is an eligible /// validator group (limited to 1 for now). function setValidatorGroup(address _newValidatorGroup) external onlyOwner { require( getValidators().isValidatorGroup(_newValidatorGroup), "NOT_VALIDATOR_GROUP" ); require( getElection().getGroupEligibility(_newValidatorGroup), "NOT_ELIGIBLE_VG" ); validatorGroup = _newValidatorGroup; } /// @notice Get active votes (staked + rewards) for this smart contract. function getRewards() public view returns (uint256) { uint256 activeVotes = getActiveVotes(); (uint256 pendingVotes, ) = getPendingVotes(); require( activeVotes.add(pendingVotes) >= totalStaked, "NEGATIVE_REWARDS" ); return activeVotes.add(pendingVotes).sub(totalStaked); } /// @notice Get pending votes for this smart contract. function getPendingVotes() public view returns (uint256, bool) { return ( getElection().getPendingVotesForGroupByAccount( validatorGroup, address(this) ), getElection().hasActivatablePendingVotes( validatorGroup, address(this) ) ); } /// @notice Get active votes (staked + rewards) for this smart contract. function getActiveVotes() public view returns (uint256) { return getElection().getActiveVotesForGroupByAccount( validatorGroup, address(this) ); } /// @notice Returns the amount a certain address is currently staking /// with Spirals. function getStakeForAccount(address _address) public view returns (uint256) { return stakeByAccount[_address]; } /* * CELO SMART CONTRACT HELPERS */ /// @dev Returns a Accounts.sol interface for interacting with the smart contract. function getAccounts() internal view returns (IAccounts) { address accountsAddr = c_celoRegistry.getAddressForStringOrDie( "Accounts" ); return IAccounts(accountsAddr); } /// @dev Returns an Election.sol interface for interacting with the smart contract. function getElection() internal view returns (IElection) { address electionAddr = c_celoRegistry.getAddressForStringOrDie( "Election" ); return IElection(electionAddr); } /// @dev Returns a LockedGold.sol interface for interacting with the smart contract. function getLockedGold() internal view returns (ILockedGold) { address lockedGoldAddr = c_celoRegistry.getAddressForStringOrDie( "LockedGold" ); return ILockedGold(lockedGoldAddr); } /// @dev Returns a Validators.sol interface for interacting with the smart contract. function getValidators() internal view returns (IValidators) { address validatorsAddr = c_celoRegistry.getAddressForStringOrDie( "Validators" ); return IValidators(validatorsAddr); } }
/_openzeppelin/contracts/utils/math/SafeMath.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol) pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } }
/src/IAccounts.sol
// SPDX-License-Identifier: Apache-2.0 // https://github.com/celo-org/celo-monorepo/tree/master/packages/protocol/contracts/governance/interfaces/ILockedGold.sol pragma solidity >=0.5.13; interface IAccounts { function isAccount(address) external view returns (bool); function voteSignerToAccount(address) external view returns (address); function validatorSignerToAccount(address) external view returns (address); function attestationSignerToAccount(address) external view returns (address); function signerToAccount(address) external view returns (address); function getAttestationSigner(address) external view returns (address); function getValidatorSigner(address) external view returns (address); function getVoteSigner(address) external view returns (address); function hasAuthorizedVoteSigner(address) external view returns (bool); function hasAuthorizedValidatorSigner(address) external view returns (bool); function hasAuthorizedAttestationSigner(address) external view returns (bool); function setAccountDataEncryptionKey(bytes calldata) external; function setMetadataURL(string calldata) external; function setName(string calldata) external; function setWalletAddress( address, uint8, bytes32, bytes32 ) external; function setAccount( string calldata, bytes calldata, address, uint8, bytes32, bytes32 ) external; function getDataEncryptionKey(address) external view returns (bytes memory); function getWalletAddress(address) external view returns (address); function getMetadataURL(address) external view returns (string memory); function batchGetMetadataURL(address[] calldata) external view returns (uint256[] memory, bytes memory); function getName(address) external view returns (string memory); function authorizeVoteSigner( address, uint8, bytes32, bytes32 ) external; function authorizeValidatorSigner( address, uint8, bytes32, bytes32 ) external; function authorizeValidatorSignerWithPublicKey( address, uint8, bytes32, bytes32, bytes calldata ) external; function authorizeValidatorSignerWithKeys( address, uint8, bytes32, bytes32, bytes calldata, bytes calldata, bytes calldata ) external; function authorizeAttestationSigner( address, uint8, bytes32, bytes32 ) external; function createAccount() external returns (bool); function setPaymentDelegation(address, uint256) external; function getPaymentDelegation(address) external view returns (address, uint256); }
/src/IElection.sol
// SPDX-License-Identifier: Apache-2.0 // https://github.com/celo-org/celo-monorepo/tree/master/packages/protocol/contracts/governance/interfaces/IElection.sol pragma solidity >=0.5.13; interface IElection { function electValidatorSigners() external view returns (address[] memory); function electNValidatorSigners(uint256, uint256) external view returns (address[] memory); function vote( address, uint256, address, address ) external returns (bool); function activate(address) external returns (bool); function revokeActive( address, uint256, address, address, uint256 ) external returns (bool); function revokeAllActive( address, address, address, uint256 ) external returns (bool); function revokePending( address, uint256, address, address, uint256 ) external returns (bool); function markGroupIneligible(address) external; function markGroupEligible( address, address, address ) external; function forceDecrementVotes( address, uint256, address[] calldata, address[] calldata, uint256[] calldata ) external returns (uint256); // view functions function getEpochNumber() external view returns (uint256); function getElectableValidators() external view returns (uint256, uint256); function getElectabilityThreshold() external view returns (uint256); function getNumVotesReceivable(address) external view returns (uint256); function getTotalVotes() external view returns (uint256); function getActiveVotes() external view returns (uint256); function getTotalVotesByAccount(address) external view returns (uint256); function getPendingVotesForGroupByAccount(address, address) external view returns (uint256); function getActiveVotesForGroupByAccount(address, address) external view returns (uint256); function getTotalVotesForGroupByAccount(address, address) external view returns (uint256); function getActiveVoteUnitsForGroupByAccount(address, address) external view returns (uint256); function getTotalVotesForGroup(address) external view returns (uint256); function getActiveVotesForGroup(address) external view returns (uint256); function getPendingVotesForGroup(address) external view returns (uint256); function getGroupEligibility(address) external view returns (bool); function getGroupEpochRewards( address, uint256, uint256[] calldata ) external view returns (uint256); function getGroupsVotedForByAccount(address) external view returns (address[] memory); function getEligibleValidatorGroups() external view returns (address[] memory); function getTotalVotesForEligibleValidatorGroups() external view returns (address[] memory, uint256[] memory); function getCurrentValidatorSigners() external view returns (address[] memory); function canReceiveVotes(address, uint256) external view returns (bool); function hasActivatablePendingVotes(address, address) external view returns (bool); // only owner function setElectableValidators(uint256, uint256) external returns (bool); function setMaxNumGroupsVotedFor(uint256) external returns (bool); function setElectabilityThreshold(uint256) external returns (bool); // only VM function distributeEpochRewards( address, uint256, address, address ) external; event ElectableValidatorsSet(uint256 min, uint256 max); event MaxNumGroupsVotedForSet(uint256 maxNumGroupsVotedFor); event ElectabilityThresholdSet(uint256 electabilityThreshold); event ValidatorGroupMarkedEligible(address indexed group); event ValidatorGroupMarkedIneligible(address indexed group); event ValidatorGroupVoteCast( address indexed account, address indexed group, uint256 value ); event ValidatorGroupVoteActivated( address indexed account, address indexed group, uint256 value, uint256 units ); event ValidatorGroupPendingVoteRevoked( address indexed account, address indexed group, uint256 value ); event ValidatorGroupActiveVoteRevoked( address indexed account, address indexed group, uint256 value, uint256 units ); event EpochRewardsDistributedToVoters(address indexed group, uint256 value); }
/src/ILockedGold.sol
// SPDX-License-Identifier: Apache-2.0 // https://github.com/celo-org/celo-monorepo/tree/master/packages/protocol/contracts/governance/interfaces/ILockedGold.sol pragma solidity >=0.5.13; interface ILockedGold { function incrementNonvotingAccountBalance(address, uint256) external; function decrementNonvotingAccountBalance(address, uint256) external; function getAccountTotalLockedGold(address) external view returns (uint256); function getAccountNonvotingLockedGold(address) external view returns (uint256); function getTotalLockedGold() external view returns (uint256); function getPendingWithdrawals(address) external view returns (uint256[] memory, uint256[] memory); function getTotalPendingWithdrawals(address) external view returns (uint256); function lock() external payable; function unlock(uint256) external; function relock(uint256, uint256) external; function withdraw(uint256) external; function slash( address account, uint256 penalty, address reporter, uint256 reward, address[] calldata lessers, address[] calldata greaters, uint256[] calldata indices ) external; function isSlasher(address) external view returns (bool); }
/src/IRegistry.sol
// SPDX-License-Identifier: Apache-2.0 // https://docs.soliditylang.org/en/v0.8.10/style-guide.html pragma solidity >=0.8.0; interface IRegistry { function setAddressFor(string calldata, address) external; function getAddressForOrDie(bytes32) external view returns (address); function getAddressFor(bytes32) external view returns (address); function getAddressForStringOrDie(string calldata identifier) external view returns (address); function getAddressForString(string calldata identifier) external view returns (address); function isOneOf(bytes32[] calldata, address) external view returns (bool); }
/src/IValidators.sol
pragma solidity >=0.8.0; interface IValidators { function registerValidator( bytes calldata, bytes calldata, bytes calldata ) external returns (bool); function deregisterValidator(uint256) external returns (bool); function affiliate(address) external returns (bool); function deaffiliate() external returns (bool); function updateBlsPublicKey(bytes calldata, bytes calldata) external returns (bool); function registerValidatorGroup(uint256) external returns (bool); function deregisterValidatorGroup(uint256) external returns (bool); function addMember(address) external returns (bool); function addFirstMember( address, address, address ) external returns (bool); function removeMember(address) external returns (bool); function reorderMember( address, address, address ) external returns (bool); function updateCommission() external; function setNextCommissionUpdate(uint256) external; function resetSlashingMultiplier() external; // only owner function setCommissionUpdateDelay(uint256) external; function setMaxGroupSize(uint256) external returns (bool); function setMembershipHistoryLength(uint256) external returns (bool); function setValidatorScoreParameters(uint256, uint256) external returns (bool); function setGroupLockedGoldRequirements(uint256, uint256) external returns (bool); function setValidatorLockedGoldRequirements(uint256, uint256) external returns (bool); function setSlashingMultiplierResetPeriod(uint256) external; // view functions function getMaxGroupSize() external view returns (uint256); function getCommissionUpdateDelay() external view returns (uint256); function getValidatorScoreParameters() external view returns (uint256, uint256); function getMembershipHistory(address) external view returns ( uint256[] memory, address[] memory, uint256, uint256 ); function calculateEpochScore(uint256) external view returns (uint256); function calculateGroupEpochScore(uint256[] calldata) external view returns (uint256); function getAccountLockedGoldRequirement(address) external view returns (uint256); function meetsAccountLockedGoldRequirements(address) external view returns (bool); function getValidatorBlsPublicKeyFromSigner(address) external view returns (bytes memory); function getValidator(address account) external view returns ( bytes memory, bytes memory, address, uint256, address ); function getValidatorGroup(address) external view returns ( address[] memory, uint256, uint256, uint256, uint256[] memory, uint256, uint256 ); function getGroupNumMembers(address) external view returns (uint256); function getTopGroupValidators(address, uint256) external view returns (address[] memory); function getGroupsNumMembers(address[] calldata accounts) external view returns (uint256[] memory); function getNumRegisteredValidators() external view returns (uint256); function groupMembershipInEpoch( address, uint256, uint256 ) external view returns (address); // only registered contract function updateEcdsaPublicKey( address, address, bytes calldata ) external returns (bool); function updatePublicKeys( address, address, bytes calldata, bytes calldata, bytes calldata ) external returns (bool); function getValidatorLockedGoldRequirements() external view returns (uint256, uint256); function getGroupLockedGoldRequirements() external view returns (uint256, uint256); function getRegisteredValidators() external view returns (address[] memory); function getRegisteredValidatorSigners() external view returns (address[] memory); function getRegisteredValidatorGroups() external view returns (address[] memory); function isValidatorGroup(address) external view returns (bool); function isValidator(address) external view returns (bool); function getValidatorGroupSlashingMultiplier(address) external view returns (uint256); function getMembershipInLastEpoch(address) external view returns (address); function getMembershipInLastEpochFromSigner(address) external view returns (address); // only VM function updateValidatorScoreFromSigner(address, uint256) external; function distributeEpochPaymentsFromSigner(address, uint256) external returns (uint256); // only slasher function forceDeaffiliateIfValidator(address) external; function halveSlashingMultiplier(address) external; }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_validatorGroup","internalType":"address"}]},{"type":"event","name":"Unstake","inputs":[{"type":"address","name":"_address","internalType":"address","indexed":true},{"type":"address","name":"_validatorGroup","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"VotesActivated","inputs":[{"type":"address","name":"_validatorGroup","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"VotesCast","inputs":[{"type":"address","name":"_address","internalType":"address","indexed":true},{"type":"address","name":"_validatorGroup","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"activate","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getActiveVotes","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"bool","name":"","internalType":"bool"}],"name":"getPendingVotes","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getRewards","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getStakeForAccount","inputs":[{"type":"address","name":"_address","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setValidatorGroup","inputs":[{"type":"address","name":"_newValidatorGroup","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"stake","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalStaked","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"validatorGroup","inputs":[]}]
Contract Creation Code
0x60806040523480156200001157600080fd5b50604051620011e7380380620011e783398101604081905262000034916200019e565b600080546001600160a01b0383166001600160a01b03199182161790915560018054909116331790556200006762000116565b6001600160a01b0316639dca362f6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015620000a7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000cd9190620001d0565b6200010f5760405162461bcd60e51b815260206004820152600e60248201526d10d49150551157d050d0d3d5539560921b604482015260640160405180910390fd5b50620001f4565b60405163224cb2fd60e21b81526020600482015260086024820152674163636f756e747360c01b6044820152600090819061ce1090638932cbf490606401602060405180830381865afa15801562000172573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200019891906200019e565b92915050565b600060208284031215620001b157600080fd5b81516001600160a01b0381168114620001c957600080fd5b9392505050565b600060208284031215620001e357600080fd5b81518015158114620001c957600080fd5b610fe380620002046000396000f3fe6080604052600436106100915760003560e01c8063417c393d11610059578063417c393d1461011c578063680104c514610154578063817b1cd2146101745780638da5cb5b1461018a578063c0c62018146101aa57600080fd5b80630572b0cc146100965780630f15f4c0146100be5780631f604243146100d55780631f8dfbd3146100ea5780633a4b66f114610114575b600080fd5b3480156100a257600080fd5b506100ab6101e0565b6040519081526020015b60405180910390f35b3480156100ca57600080fd5b506100d361026c565b005b3480156100e157600080fd5b506100ab6104c3565b3480156100f657600080fd5b506100ff610545565b604080519283529015156020830152016100b5565b6100d3610646565b34801561012857600080fd5b5060005461013c906001600160a01b031681565b6040516001600160a01b0390911681526020016100b5565b34801561016057600080fd5b506100d361016f366004610ce5565b61070e565b34801561018057600080fd5b506100ab60025481565b34801561019657600080fd5b5060015461013c906001600160a01b031681565b3480156101b657600080fd5b506100ab6101c5366004610ce5565b6001600160a01b031660009081526003602052604090205490565b6000806101eb6104c3565b905060006101f7610545565b5060025490915061020883836108c2565b101561024e5760405162461bcd60e51b815260206004820152601060248201526f4e454741544956455f5245574152445360801b60448201526064015b60405180910390fd5b6002546102659061025f84846108c2565b906108d5565b9250505090565b6001546001600160a01b031633146102965760405162461bcd60e51b815260040161024590610d02565b60006102a06108e1565b60005460405163098fb3dd60e21b81523060048201526001600160a01b03918216602482015291925082169063263ecf7490604401602060405180830381865afa1580156102f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103169190610d44565b61035a5760405162461bcd60e51b81526020600482015260156024820152744e4f545f52454144595f544f5f414354495641544560581b6044820152606401610245565b60006103646108e1565b600054604051639b95975f60e01b81526001600160a01b039182166004820152306024820152911690639b95975f90604401602060405180830381865afa1580156103b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d79190610d66565b600054604051630716a76760e21b81526001600160a01b039182166004820152919250831690631c5a9d9c906024016020604051808303816000875af1158015610425573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104499190610d44565b6104875760405162461bcd60e51b815260206004820152600f60248201526e1050d5125590551157d19052531151608a1b6044820152606401610245565b6000805460405183926001600160a01b03909216917ffdb3176a1ebea0dc05bd03e3910d445075e04e92e0b93908f75b4d64a18effaa91a35050565b60006104cd6108e1565b6000546040516334f890a960e21b81526001600160a01b03918216600482015230602482015291169063d3e242a490604401602060405180830381865afa15801561051c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105409190610d66565b905090565b6000806105506108e1565b600054604051639b95975f60e01b81526001600160a01b039182166004820152306024820152911690639b95975f90604401602060405180830381865afa15801561059f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c39190610d66565b6105cb6108e1565b60005460405163098fb3dd60e21b81526001600160a01b03918216600482015230602482015291169063263ecf7490604401602060405180830381865afa15801561061a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063e9190610d44565b915091509091565b346106855760405162461bcd60e51b815260206004820152600f60248201526e1393d7d59053155157d4d51052d151608a1b6044820152606401610245565b61068e34610967565b610697346109c5565b336000908152600360205260409020546106b190346108c2565b336000908152600360205260409020556002546106ce90346108c2565b6002556000805460405134926001600160a01b039092169133917fc903789bc217ae62d94ab93c15368f82a58d0e1c9d1724fce2b4cd9a6a24f6009190a4565b6001546001600160a01b031633146107385760405162461bcd60e51b815260040161024590610d02565b610740610b01565b6040516329789d2760e11b81526001600160a01b03838116600483015291909116906352f13a4e90602401602060405180830381865afa158015610788573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ac9190610d44565b6107ee5760405162461bcd60e51b815260206004820152601360248201527204e4f545f56414c494441544f525f47524f555606c1b6044820152606401610245565b6107f66108e1565b604051638c66677560e01b81526001600160a01b0383811660048301529190911690638c66677590602401602060405180830381865afa15801561083e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108629190610d44565b6108a05760405162461bcd60e51b815260206004820152600f60248201526e4e4f545f454c494749424c455f564760881b6044820152606401610245565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60006108ce8284610d95565b9392505050565b60006108ce8284610dad565b60405163224cb2fd60e21b815260206004820152600860248201526722b632b1ba34b7b760c11b6044820152600090819061ce1090638932cbf4906064015b602060405180830381865afa15801561093d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109619190610dc4565b92915050565b61096f610b46565b6001600160a01b031663f83d08ba826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156109a957600080fd5b505af11580156109bd573d6000803e3d6000fd5b505050505050565b6000806109d0610b8b565b90925090506001600160a01b0382161580156109f357506001600160a01b038116155b15610a345760405162461bcd60e51b81526020600482015260116024820152702727afa622a9a9a2a92fa3a922a0aa22a960791b6044820152606401610245565b610a3c6108e1565b600054604051632c06ba3d60e11b81526001600160a01b039182166004820152602481018690528482166044820152838216606482015291169063580d747a906084016020604051808303816000875af1158015610a9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac29190610d44565b610afc5760405162461bcd60e51b815260206004820152600b60248201526a1593d51157d1905253115160aa1b6044820152606401610245565b505050565b60405163224cb2fd60e21b815260206004820152600a60248201526956616c696461746f727360b01b6044820152600090819061ce1090638932cbf490606401610920565b60405163224cb2fd60e21b815260206004820152600a602482015269131bd8dad95911dbdb1960b21b6044820152600090819061ce1090638932cbf490606401610920565b6000806000610b986108e1565b6001600160a01b0316637046c96b6040518163ffffffff1660e01b8152600401600060405180830381865afa158015610bd5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610bfd9190810190610eb7565b50905060008060005b8351811015610cc257838181518110610c2157610c21610f7c565b60209081029190910101516000546001600160a01b0390811691161415610cb0578015610c6f5783610c54600183610dad565b81518110610c6457610c64610f7c565b602002602001015191505b60018451610c7d9190610dad565b811015610cab5783610c90826001610d95565b81518110610ca057610ca0610f7c565b602002602001015192505b610cc2565b80610cba81610f92565b915050610c06565b509094909350915050565b6001600160a01b0381168114610ce257600080fd5b50565b600060208284031215610cf757600080fd5b81356108ce81610ccd565b60208082526022908201527f4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6040820152616e2160f01b606082015260800190565b600060208284031215610d5657600080fd5b815180151581146108ce57600080fd5b600060208284031215610d7857600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b60008219821115610da857610da8610d7f565b500190565b600082821015610dbf57610dbf610d7f565b500390565b600060208284031215610dd657600080fd5b81516108ce81610ccd565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610e2057610e20610de1565b604052919050565b600067ffffffffffffffff821115610e4257610e42610de1565b5060051b60200190565b600082601f830112610e5d57600080fd5b81516020610e72610e6d83610e28565b610df7565b82815260059290921b84018101918181019086841115610e9157600080fd5b8286015b84811015610eac5780518352918301918301610e95565b509695505050505050565b60008060408385031215610eca57600080fd5b825167ffffffffffffffff80821115610ee257600080fd5b818501915085601f830112610ef657600080fd5b81516020610f06610e6d83610e28565b82815260059290921b84018101918181019089841115610f2557600080fd5b948201945b83861015610f4c578551610f3d81610ccd565b82529482019490820190610f2a565b91880151919650909350505080821115610f6557600080fd5b50610f7285828601610e4c565b9150509250929050565b634e487b7160e01b600052603260045260246000fd5b6000600019821415610fa657610fa6610d7f565b506001019056fea2646970667358221220d65163872280a1d2367f72846fdece6e94157181552595b456b19c996085ae5f64736f6c634300080a003300000000000000000000000070fc0b021dfdbb9a106d1ed8f35f59d3f23ecb7b
Deployed ByteCode
0x6080604052600436106100915760003560e01c8063417c393d11610059578063417c393d1461011c578063680104c514610154578063817b1cd2146101745780638da5cb5b1461018a578063c0c62018146101aa57600080fd5b80630572b0cc146100965780630f15f4c0146100be5780631f604243146100d55780631f8dfbd3146100ea5780633a4b66f114610114575b600080fd5b3480156100a257600080fd5b506100ab6101e0565b6040519081526020015b60405180910390f35b3480156100ca57600080fd5b506100d361026c565b005b3480156100e157600080fd5b506100ab6104c3565b3480156100f657600080fd5b506100ff610545565b604080519283529015156020830152016100b5565b6100d3610646565b34801561012857600080fd5b5060005461013c906001600160a01b031681565b6040516001600160a01b0390911681526020016100b5565b34801561016057600080fd5b506100d361016f366004610ce5565b61070e565b34801561018057600080fd5b506100ab60025481565b34801561019657600080fd5b5060015461013c906001600160a01b031681565b3480156101b657600080fd5b506100ab6101c5366004610ce5565b6001600160a01b031660009081526003602052604090205490565b6000806101eb6104c3565b905060006101f7610545565b5060025490915061020883836108c2565b101561024e5760405162461bcd60e51b815260206004820152601060248201526f4e454741544956455f5245574152445360801b60448201526064015b60405180910390fd5b6002546102659061025f84846108c2565b906108d5565b9250505090565b6001546001600160a01b031633146102965760405162461bcd60e51b815260040161024590610d02565b60006102a06108e1565b60005460405163098fb3dd60e21b81523060048201526001600160a01b03918216602482015291925082169063263ecf7490604401602060405180830381865afa1580156102f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103169190610d44565b61035a5760405162461bcd60e51b81526020600482015260156024820152744e4f545f52454144595f544f5f414354495641544560581b6044820152606401610245565b60006103646108e1565b600054604051639b95975f60e01b81526001600160a01b039182166004820152306024820152911690639b95975f90604401602060405180830381865afa1580156103b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d79190610d66565b600054604051630716a76760e21b81526001600160a01b039182166004820152919250831690631c5a9d9c906024016020604051808303816000875af1158015610425573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104499190610d44565b6104875760405162461bcd60e51b815260206004820152600f60248201526e1050d5125590551157d19052531151608a1b6044820152606401610245565b6000805460405183926001600160a01b03909216917ffdb3176a1ebea0dc05bd03e3910d445075e04e92e0b93908f75b4d64a18effaa91a35050565b60006104cd6108e1565b6000546040516334f890a960e21b81526001600160a01b03918216600482015230602482015291169063d3e242a490604401602060405180830381865afa15801561051c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105409190610d66565b905090565b6000806105506108e1565b600054604051639b95975f60e01b81526001600160a01b039182166004820152306024820152911690639b95975f90604401602060405180830381865afa15801561059f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c39190610d66565b6105cb6108e1565b60005460405163098fb3dd60e21b81526001600160a01b03918216600482015230602482015291169063263ecf7490604401602060405180830381865afa15801561061a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063e9190610d44565b915091509091565b346106855760405162461bcd60e51b815260206004820152600f60248201526e1393d7d59053155157d4d51052d151608a1b6044820152606401610245565b61068e34610967565b610697346109c5565b336000908152600360205260409020546106b190346108c2565b336000908152600360205260409020556002546106ce90346108c2565b6002556000805460405134926001600160a01b039092169133917fc903789bc217ae62d94ab93c15368f82a58d0e1c9d1724fce2b4cd9a6a24f6009190a4565b6001546001600160a01b031633146107385760405162461bcd60e51b815260040161024590610d02565b610740610b01565b6040516329789d2760e11b81526001600160a01b03838116600483015291909116906352f13a4e90602401602060405180830381865afa158015610788573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ac9190610d44565b6107ee5760405162461bcd60e51b815260206004820152601360248201527204e4f545f56414c494441544f525f47524f555606c1b6044820152606401610245565b6107f66108e1565b604051638c66677560e01b81526001600160a01b0383811660048301529190911690638c66677590602401602060405180830381865afa15801561083e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108629190610d44565b6108a05760405162461bcd60e51b815260206004820152600f60248201526e4e4f545f454c494749424c455f564760881b6044820152606401610245565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60006108ce8284610d95565b9392505050565b60006108ce8284610dad565b60405163224cb2fd60e21b815260206004820152600860248201526722b632b1ba34b7b760c11b6044820152600090819061ce1090638932cbf4906064015b602060405180830381865afa15801561093d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109619190610dc4565b92915050565b61096f610b46565b6001600160a01b031663f83d08ba826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156109a957600080fd5b505af11580156109bd573d6000803e3d6000fd5b505050505050565b6000806109d0610b8b565b90925090506001600160a01b0382161580156109f357506001600160a01b038116155b15610a345760405162461bcd60e51b81526020600482015260116024820152702727afa622a9a9a2a92fa3a922a0aa22a960791b6044820152606401610245565b610a3c6108e1565b600054604051632c06ba3d60e11b81526001600160a01b039182166004820152602481018690528482166044820152838216606482015291169063580d747a906084016020604051808303816000875af1158015610a9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac29190610d44565b610afc5760405162461bcd60e51b815260206004820152600b60248201526a1593d51157d1905253115160aa1b6044820152606401610245565b505050565b60405163224cb2fd60e21b815260206004820152600a60248201526956616c696461746f727360b01b6044820152600090819061ce1090638932cbf490606401610920565b60405163224cb2fd60e21b815260206004820152600a602482015269131bd8dad95911dbdb1960b21b6044820152600090819061ce1090638932cbf490606401610920565b6000806000610b986108e1565b6001600160a01b0316637046c96b6040518163ffffffff1660e01b8152600401600060405180830381865afa158015610bd5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610bfd9190810190610eb7565b50905060008060005b8351811015610cc257838181518110610c2157610c21610f7c565b60209081029190910101516000546001600160a01b0390811691161415610cb0578015610c6f5783610c54600183610dad565b81518110610c6457610c64610f7c565b602002602001015191505b60018451610c7d9190610dad565b811015610cab5783610c90826001610d95565b81518110610ca057610ca0610f7c565b602002602001015192505b610cc2565b80610cba81610f92565b915050610c06565b509094909350915050565b6001600160a01b0381168114610ce257600080fd5b50565b600060208284031215610cf757600080fd5b81356108ce81610ccd565b60208082526022908201527f4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6040820152616e2160f01b606082015260800190565b600060208284031215610d5657600080fd5b815180151581146108ce57600080fd5b600060208284031215610d7857600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b60008219821115610da857610da8610d7f565b500190565b600082821015610dbf57610dbf610d7f565b500390565b600060208284031215610dd657600080fd5b81516108ce81610ccd565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610e2057610e20610de1565b604052919050565b600067ffffffffffffffff821115610e4257610e42610de1565b5060051b60200190565b600082601f830112610e5d57600080fd5b81516020610e72610e6d83610e28565b610df7565b82815260059290921b84018101918181019086841115610e9157600080fd5b8286015b84811015610eac5780518352918301918301610e95565b509695505050505050565b60008060408385031215610eca57600080fd5b825167ffffffffffffffff80821115610ee257600080fd5b818501915085601f830112610ef657600080fd5b81516020610f06610e6d83610e28565b82815260059290921b84018101918181019089841115610f2557600080fd5b948201945b83861015610f4c578551610f3d81610ccd565b82529482019490820190610f2a565b91880151919650909350505080821115610f6557600080fd5b50610f7285828601610e4c565b9150509250929050565b634e487b7160e01b600052603260045260246000fd5b6000600019821415610fa657610fa6610d7f565b506001019056fea2646970667358221220d65163872280a1d2367f72846fdece6e94157181552595b456b19c996085ae5f64736f6c634300080a0033