Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
Nexus
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: MIT pragma solidity 0.8.19; import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import {INexusBridge} from "./interfaces/INexusBridge.sol"; import {INodeOperator} from "./interfaces/INodeOperator.sol"; import {Ownable} from "./utils/NexusOwnable.sol"; import {UUPSUpgreadable} from "./utils/UUPSUpgreadable.sol"; import {ISSVNetworkCore} from "./interfaces/ISSVNetwork.sol"; import {INexusInterface} from "./interfaces/INexusInterface.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {BytesArrayLibrary} from "./libraries/BytesArrayLibrary.sol"; /** * @title Nexus Core Contract * @author RohitAudit * @dev This contract is heart and soul of Nexus Network and is used for Operations like * 1. Onboarding of rollup to Nexus Network * 2. Change parameters for rollup * 3. Whitelisting rollup address * 4. Submitting keys to rollup bridge * 5. Submitting keyshares to SSV contract * 6. Recharge funds in SSV contract for validator operation * 7. Keep track of validator status and exits */ contract Nexus is INexusInterface, Ownable, UUPSUpgreadable { using EnumerableSet for EnumerableSet.AddressSet; using EnumerableSet for EnumerableSet.UintSet; using BytesArrayLibrary for bytes[]; EnumerableSet.AddressSet private whitelistedRollups; address public offChainBot; mapping(address => Rollup) public rollups; mapping(bytes => ValidatorStatus) public validators; mapping(uint256 => uint16) polygonCDKPartners; address public NodeOperatorContract; // Goerli Address // address public constant SSV_NETWORK = // 0xC3CD9A0aE89Fff83b71b58b6512D43F8a41f363D; // address public constant SSV_TOKEN = // 0x3a9f01091C446bdE031E39ea8354647AFef091E7; // Holesky Address address public constant SSV_NETWORK = 0x38A4794cCEd47d3baf7370CcC43B560D3a1beEFA; address public constant SSV_TOKEN = 0xad45A78180961079BFaeEe349704F411dfF947C6; uint16 private constant BASIS_POINT = 10000; modifier onlyOffChainBot() { if (msg.sender != offChainBot) revert NotNexusBot(); _; } modifier onlyWhitelistedRollup() { if (!whitelistedRollups.contains(msg.sender)) revert AddressNotWhitelisted(); _; } modifier nonZeroAddress(address _contract) { if (_contract == address(0)) revert IncorrectAddress(); _; } function initialize() public initilizeOnce { _ownableInit(msg.sender); } // admin related functions function whitelistRollup( string calldata name, address rollupAddress ) external onlyOwner { if (whitelistedRollups.add(rollupAddress)) { emit RollupWhitelisted(name, rollupAddress); } else { revert AddressAlreadyWhitelisted(); } } function setOffChainBot( address _botAddress ) external onlyOwner nonZeroAddress(_botAddress) { offChainBot = _botAddress; } function updateProxy( address newImplemetation ) public onlyOwner nonZeroAddress(newImplemetation) { updateCodeAddress(newImplemetation); } function setNodeOperatorContract( address _nodeOperator ) external onlyOwner nonZeroAddress(_nodeOperator) { NodeOperatorContract = _nodeOperator; emit NodeOperatorContractChanged(_nodeOperator); } function changeExecutionFeeAddress( address _execution_fee_address ) external onlyOwner nonZeroAddress(_execution_fee_address) { ISSVNetworkCore(SSV_NETWORK).setFeeRecipientAddress( _execution_fee_address ); } // rollup related functions function isRollupWhitelisted( address rollupAddress ) external view returns (bool) { return whitelistedRollups.contains(rollupAddress); } function registerRollup( address bridgeContract, uint64 operatorCluster, uint256 nexusFee, uint16 stakingLimit ) external onlyWhitelistedRollup { if (rollups[msg.sender].bridgeContract != address(0)) revert RollupAlreadyRegistered(); if (INexusBridge(bridgeContract).NEXUS_NETWORK() != address(this)) revert NexusAddressNotFound(); if (stakingLimit > BASIS_POINT) revert IncorrectStakingLimit(); INexusBridge(bridgeContract).setNexusFee(nexusFee); INodeOperator(NodeOperatorContract).getCluster(operatorCluster); rollups[msg.sender] = Rollup( bridgeContract, stakingLimit, operatorCluster ); emit RollupRegistered( msg.sender, bridgeContract, stakingLimit, operatorCluster, nexusFee ); } function changeStakingLimit( uint16 newStakingLimit ) external onlyWhitelistedRollup { if (newStakingLimit > BASIS_POINT) revert IncorrectStakingLimit(); rollups[msg.sender].stakingLimit = newStakingLimit; emit StakingLimitChanged(msg.sender, newStakingLimit); } function changeNexusFee(uint256 _new_fee) external onlyWhitelistedRollup { INexusBridge(rollups[msg.sender].bridgeContract).setNexusFee(_new_fee); emit NexusFeeChanged(msg.sender, _new_fee); } function changeCluster( uint64 operatorCluster ) external onlyWhitelistedRollup { INodeOperator(NodeOperatorContract).getCluster(operatorCluster); rollups[msg.sender].operatorCluster = operatorCluster; emit RollupOperatorClusterChanged(msg.sender, operatorCluster); } // validator realted function function depositValidatorRollup( address _rollupAdmin, Validator[] calldata _validators ) external override onlyOffChainBot { for (uint i = 0; i < _validators.length; i++) { if (validators[_validators[i].pubKey] != ValidatorStatus.INACTIVE) revert IncorrectValidatorStatus(); validators[_validators[i].pubKey] = ValidatorStatus.DEPOSITED; emit ValidatorSubmitted(_validators[i].pubKey, _rollupAdmin); } INexusBridge(rollups[_rollupAdmin].bridgeContract) .depositValidatorNexus( _validators, uint256(rollups[_rollupAdmin].stakingLimit) ); } function depositValidatorShares( address _rollupAdmin, ValidatorShares calldata _validatorShare ) external override onlyOffChainBot { if (validators[_validatorShare.pubKey] != ValidatorStatus.DEPOSITED) revert IncorrectValidatorStatus(); IERC20(SSV_TOKEN).approve(SSV_NETWORK, _validatorShare.amount); ISSVNetworkCore(SSV_NETWORK).registerValidator( _validatorShare.pubKey, _validatorShare.operatorIds, _validatorShare.sharesEncrypted, _validatorShare.amount, _validatorShare.cluster ); validators[_validatorShare.pubKey] = ValidatorStatus.SHARE_DEPOSITED; emit ValidatorShareSubmitted( _validatorShare.pubKey, _rollupAdmin, _validatorShare.amount ); } function validatorExit( address rollupAdmin, bytes calldata pubkey, uint64[] calldata operatorIds ) external onlyOffChainBot { if (validators[pubkey] != ValidatorStatus.SHARE_DEPOSITED) revert IncorrectValidatorStatus(); ISSVNetworkCore(SSV_NETWORK).exitValidator(pubkey, operatorIds); validators[pubkey] = ValidatorStatus.VALIDATOR_EXIT_SUBMITTED; emit ValidatorExitSubmitted(rollupAdmin, pubkey); } function validatorExitBalanceTransferred( address rollupAdmin, bytes calldata pubkey, uint64[] memory operatorIds, ISSVNetworkCore.Cluster memory cluster ) external onlyOffChainBot { if (validators[pubkey] != ValidatorStatus.VALIDATOR_EXIT_SUBMITTED) revert IncorrectValidatorStatus(); ISSVNetworkCore(SSV_NETWORK).removeValidator( pubkey, operatorIds, cluster ); INexusBridge(rollups[rollupAdmin].bridgeContract) .updateExitedValidators(); validators[pubkey] = ValidatorStatus.VALIDATOR_EXITED; emit ValidatorExited(rollupAdmin, pubkey); } function validatorSlashed( address rollupAdmin, uint256 amountSlashed ) external onlyOffChainBot { INexusBridge(rollups[rollupAdmin].bridgeContract).validatorsSlashed( amountSlashed ); emit RollupValidatorSlashed(rollupAdmin, amountSlashed); } // cluster related functions function rechargeCluster( uint64 clusterId, uint256 amount, ISSVNetworkCore.Cluster memory cluster ) external onlyOffChainBot { ISSVNetworkCore(SSV_NETWORK).deposit( address(this), INodeOperator(NodeOperatorContract).getCluster(clusterId), amount, cluster ); emit ClusterRecharged(clusterId, amount); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ```solidity * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
//SPDX-License-Identifier: MIT pragma solidity 0.8.19; import {INexusInterface} from "./INexusInterface.sol"; interface INexusBridge { function setNexusFee(uint256 _nexus_fee) external; function NEXUS_NETWORK() external view returns (address); function validatorCount() external view returns (uint256); function NexusFeePercentage() external view returns(uint256); function balance() external view returns(uint256); function validatorsSlashed(uint256 amount) external; function updateExitedValidators() external; function depositValidatorNexus(INexusInterface.Validator[] calldata _validators,uint256 stakingLimit) external; }
//SPDX-License-Identifier: MIT pragma solidity 0.8.19; import {ISSVNetworkCore} from "./ISSVNetwork.sol"; interface INexusInterface { // structs to be used for nexus interface // todo: add multiple operator cluster mapping so that rollup can select cluster and percentage per cluster struct Rollup { address bridgeContract; uint16 stakingLimit; uint64 operatorCluster; } struct Validator { bytes pubKey; bytes withdrawalAddress; bytes signature; bytes32 depositRoot; } struct ValidatorShares { bytes pubKey; uint64[] operatorIds; bytes sharesEncrypted; uint256 amount; ISSVNetworkCore.Cluster cluster; } enum ValidatorStatus{ INACTIVE, DEPOSITED, SHARE_DEPOSITED, VALIDATOR_EXIT_SUBMITTED, VALIDATOR_EXITED } // errors error NotNexusBot(); error AddressAlreadyWhitelisted(); error AddressNotWhitelisted(); error RollupAlreadyPresent(); error RollupAlreadyRegistered(); error KeyNotDeposited(); error NexusAddressNotFound(); error InvalidKeySupplied(); error ClusterAlreadyExited(); error IncorrectStakingLimit(); error IncorrectValidatorStatus(); // events event RollupWhitelisted(string name, address rollupAddress); event RollupRegistered(address rollupAdmin, address withdrawalAddress,uint16 stakingLimit,uint64 operatorCluster,uint256 nexusFee); event StakingLimitChanged(address rollupAdmin,uint16 StakingLimit); event RollupOperatorClusterChanged(address rollup_admin,uint64 operatorCluster); event NexusFeeChanged(address rollup_admin,uint256 newFee); event ValidatorSubmitted(bytes pubKey, address rolupAdmin); event ValidatorShareSubmitted(bytes pubKey, address rolupAdmin,uint256 amount); event ClusterAdded(uint64 clusterId, uint64[] operatorIds); event SSVRecharged(address sender, uint256 amount); event ClusterRecharged(uint64 clusterId,uint256 amount); event RollupValidatorSlashed(address admin,uint256 amount); event ValidatorExitSubmitted(address admin,bytes pubKey); event ValidatorExited(address admin,bytes pubKey); event NodeOperatorContractChanged(address _nodeOperatorContract); // functions function depositValidatorRollup( address _rollupAdmin, Validator[] calldata _validators ) external; function depositValidatorShares( address _rollupAdmin, ValidatorShares calldata _validatorShare ) external; }
//SPDX-License-Identifier: MIT pragma solidity 0.8.19; interface INodeOperator { error ClusterAlreadyExited(); error OperatorNotRegistered(); error OperatorAlreadyRegistered(); error ClusterNotPresent(); event ClusterAdded(uint64 clusterId, uint64[] operatorIds); event SSVOperatorRegistered(string name,uint256 indexed operatorId, string pubKey, string ip_address); event SSVOperatorUpdated(uint64 _operator_id,string _ip_address); function getCluster(uint64 clusterId) external view returns(uint64[] memory); }
//SPDX-License-Identifier: MIT pragma solidity 0.8.19; interface ISSVNetworkCore { /// @notice Represents a cluster of validators struct Cluster { /// @dev The number of validators in the cluster uint32 validatorCount; /// @dev The index of network fees related to this cluster uint64 networkFeeIndex; /// @dev The last index calculated for the cluster uint64 index; /// @dev Flag indicating whether the cluster is active bool active; /// @dev The balance of the cluster uint256 balance; } /********************************/ /* Validator External Functions */ /********************************/ function registerValidator( bytes calldata publicKey, uint64[] memory operatorIds, bytes calldata sharesEncrypted, uint256 amount, Cluster memory cluster ) external; function exitValidator(bytes calldata publicKey, uint64[] calldata operatorIds) external; function removeValidator( bytes calldata publicKey, uint64[] memory operatorIds, Cluster memory cluster ) external; function deposit( address clusterOwner, uint64[] calldata operatorIds, uint256 amount, ISSVNetworkCore.Cluster memory cluster ) external; function setFeeRecipientAddress(address feeRecipientAddress) external; }
//SPDX-License-Identifier: MIT pragma solidity 0.8.19; /** * @title BytesArray Library * @author RohitAudit * @dev This library is used for managing bytes array by providing following functionality: * 1. Removing element from the array * 2. Adding element to the array */ library BytesArrayLibrary { function addElement(bytes[] storage arr, bytes memory data) internal { arr.push(data); } function findElement( bytes[] storage arr, bytes memory target ) internal view returns (bool found, uint256 index) { for (uint256 i = 0; i < arr.length; i++) { if (keccak256(arr[i]) == keccak256(target)) { return (true, i); } } return (false, 0); } function removeElement(bytes[] storage arr, bytes memory target) internal { for (uint256 i = 0; i < arr.length; i++) { if (keccak256(arr[i]) == keccak256(target)) { if (i < arr.length - 1) { arr[i] = arr[arr.length - 1]; } arr.pop(); return; } } } }
//SPDX-License-Identifier: MIT pragma solidity 0.8.19; /** * @title Ownable Contract * @author RohitAudit * @dev This contract is used to implement ownable features to the contracts */ contract Ownable { address private owner; bool private initialized = false; event OwnerChanged(address oldOwner, address newOwner); error NotOwner(); error ContractAlreadyInitialized(); error IncorrectAddress(); modifier onlyOwner() { if (msg.sender != owner) revert NotOwner(); _; } modifier initilizeOnce() { if (initialized) revert ContractAlreadyInitialized(); _; } function getOwner() external view returns (address) { return owner; } function _ownableInit(address _owner) internal { owner = _owner; initialized = true; } /** * This function transfers the ownership of the contract * @param newOwner New Owner of the contract */ function transferOwnership(address newOwner) external onlyOwner{ if (newOwner == address(0)) revert IncorrectAddress(); emit OwnerChanged(owner, newOwner); owner = newOwner; } }
//SPDX-License-Identifier: MIT pragma solidity 0.8.19; /** * @title Proxiable * @author RohitAudit * @dev This contract is implemented in the implementation contract to make it upgreadable. Removing this contract * will remove the upgreadability feature of the contract */ contract UUPSUpgreadable { // Code position in storage is keccak256("PROXIABLE") = "0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7" bytes32 constant IMPLEMENTATION_SLOT = 0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7; error NotCompatible(); function updateCodeAddress(address newAddress) internal { if(bytes32(IMPLEMENTATION_SLOT) != UUPSUpgreadable(newAddress).proxiableUUID()) revert NotCompatible(); assembly { // solium-disable-line sstore(IMPLEMENTATION_SLOT, newAddress) } } function proxiableUUID() public pure returns (bytes32) { return IMPLEMENTATION_SLOT; } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
[{"inputs":[],"name":"AddressAlreadyWhitelisted","type":"error"},{"inputs":[],"name":"AddressNotWhitelisted","type":"error"},{"inputs":[],"name":"ClusterAlreadyExited","type":"error"},{"inputs":[],"name":"ContractAlreadyInitialized","type":"error"},{"inputs":[],"name":"IncorrectAddress","type":"error"},{"inputs":[],"name":"IncorrectStakingLimit","type":"error"},{"inputs":[],"name":"IncorrectValidatorStatus","type":"error"},{"inputs":[],"name":"InvalidKeySupplied","type":"error"},{"inputs":[],"name":"KeyNotDeposited","type":"error"},{"inputs":[],"name":"NexusAddressNotFound","type":"error"},{"inputs":[],"name":"NotCompatible","type":"error"},{"inputs":[],"name":"NotNexusBot","type":"error"},{"inputs":[],"name":"NotOwner","type":"error"},{"inputs":[],"name":"RollupAlreadyPresent","type":"error"},{"inputs":[],"name":"RollupAlreadyRegistered","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"clusterId","type":"uint64"},{"indexed":false,"internalType":"uint64[]","name":"operatorIds","type":"uint64[]"}],"name":"ClusterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"clusterId","type":"uint64"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ClusterRecharged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"rollup_admin","type":"address"},{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"NexusFeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_nodeOperatorContract","type":"address"}],"name":"NodeOperatorContractChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"rollup_admin","type":"address"},{"indexed":false,"internalType":"uint64","name":"operatorCluster","type":"uint64"}],"name":"RollupOperatorClusterChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"rollupAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"withdrawalAddress","type":"address"},{"indexed":false,"internalType":"uint16","name":"stakingLimit","type":"uint16"},{"indexed":false,"internalType":"uint64","name":"operatorCluster","type":"uint64"},{"indexed":false,"internalType":"uint256","name":"nexusFee","type":"uint256"}],"name":"RollupRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RollupValidatorSlashed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"address","name":"rollupAddress","type":"address"}],"name":"RollupWhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SSVRecharged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"rollupAdmin","type":"address"},{"indexed":false,"internalType":"uint16","name":"StakingLimit","type":"uint16"}],"name":"StakingLimitChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"bytes","name":"pubKey","type":"bytes"}],"name":"ValidatorExitSubmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"bytes","name":"pubKey","type":"bytes"}],"name":"ValidatorExited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"pubKey","type":"bytes"},{"indexed":false,"internalType":"address","name":"rolupAdmin","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ValidatorShareSubmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"pubKey","type":"bytes"},{"indexed":false,"internalType":"address","name":"rolupAdmin","type":"address"}],"name":"ValidatorSubmitted","type":"event"},{"inputs":[],"name":"NodeOperatorContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SSV_NETWORK","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SSV_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"operatorCluster","type":"uint64"}],"name":"changeCluster","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_execution_fee_address","type":"address"}],"name":"changeExecutionFeeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_new_fee","type":"uint256"}],"name":"changeNexusFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"newStakingLimit","type":"uint16"}],"name":"changeStakingLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rollupAdmin","type":"address"},{"components":[{"internalType":"bytes","name":"pubKey","type":"bytes"},{"internalType":"bytes","name":"withdrawalAddress","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes32","name":"depositRoot","type":"bytes32"}],"internalType":"struct INexusInterface.Validator[]","name":"_validators","type":"tuple[]"}],"name":"depositValidatorRollup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rollupAdmin","type":"address"},{"components":[{"internalType":"bytes","name":"pubKey","type":"bytes"},{"internalType":"uint64[]","name":"operatorIds","type":"uint64[]"},{"internalType":"bytes","name":"sharesEncrypted","type":"bytes"},{"internalType":"uint256","name":"amount","type":"uint256"},{"components":[{"internalType":"uint32","name":"validatorCount","type":"uint32"},{"internalType":"uint64","name":"networkFeeIndex","type":"uint64"},{"internalType":"uint64","name":"index","type":"uint64"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"balance","type":"uint256"}],"internalType":"struct ISSVNetworkCore.Cluster","name":"cluster","type":"tuple"}],"internalType":"struct INexusInterface.ValidatorShares","name":"_validatorShare","type":"tuple"}],"name":"depositValidatorShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"rollupAddress","type":"address"}],"name":"isRollupWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"offChainBot","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint64","name":"clusterId","type":"uint64"},{"internalType":"uint256","name":"amount","type":"uint256"},{"components":[{"internalType":"uint32","name":"validatorCount","type":"uint32"},{"internalType":"uint64","name":"networkFeeIndex","type":"uint64"},{"internalType":"uint64","name":"index","type":"uint64"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"balance","type":"uint256"}],"internalType":"struct ISSVNetworkCore.Cluster","name":"cluster","type":"tuple"}],"name":"rechargeCluster","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"bridgeContract","type":"address"},{"internalType":"uint64","name":"operatorCluster","type":"uint64"},{"internalType":"uint256","name":"nexusFee","type":"uint256"},{"internalType":"uint16","name":"stakingLimit","type":"uint16"}],"name":"registerRollup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rollups","outputs":[{"internalType":"address","name":"bridgeContract","type":"address"},{"internalType":"uint16","name":"stakingLimit","type":"uint16"},{"internalType":"uint64","name":"operatorCluster","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeOperator","type":"address"}],"name":"setNodeOperatorContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_botAddress","type":"address"}],"name":"setOffChainBot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplemetation","type":"address"}],"name":"updateProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"rollupAdmin","type":"address"},{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"uint64[]","name":"operatorIds","type":"uint64[]"}],"name":"validatorExit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"rollupAdmin","type":"address"},{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"uint64[]","name":"operatorIds","type":"uint64[]"},{"components":[{"internalType":"uint32","name":"validatorCount","type":"uint32"},{"internalType":"uint64","name":"networkFeeIndex","type":"uint64"},{"internalType":"uint64","name":"index","type":"uint64"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"balance","type":"uint256"}],"internalType":"struct ISSVNetworkCore.Cluster","name":"cluster","type":"tuple"}],"name":"validatorExitBalanceTransferred","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"rollupAdmin","type":"address"},{"internalType":"uint256","name":"amountSlashed","type":"uint256"}],"name":"validatorSlashed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"validators","outputs":[{"internalType":"enum INexusInterface.ValidatorStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"rollupAddress","type":"address"}],"name":"whitelistRollup","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040526000805460ff60a01b1916905534801561001d57600080fd5b5061253e8061002d6000396000f3fe608060405234801561001057600080fd5b506004361061018e5760003560e01c80638129fc1c116100de5780639e95514911610097578063e03ad13c11610071578063e03ad13c1461039a578063e2f4a731146103ad578063eff00f9d146103d0578063f2fde38b1461044857600080fd5b80639e95514914610361578063c37a78dc14610374578063c40e9df91461038757600080fd5b80638129fc1c146102f457806384eff0fa146102fc578063893d20e81461030f5780639164975114610320578063946cd73f1461033b5780639b17541c1461034e57600080fd5b80633d4d837f1161014b578063614080a111610125578063614080a114610280578063687abf7d146102935780636c36511a146102a65780636f2a626f146102e157600080fd5b80633d4d837f1461022c5780634fde79ad1461023f57806352d1902d1461025257600080fd5b80630df1ecfd14610193578063139b0f75146101cb5780631621eecb146101e05780633011ad9b146101f357806334439c8014610206578063383bf14214610219575b600080fd5b6101ae73ad45a78180961079bfaeee349704f411dff947c681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101de6101d93660046119e1565b61045b565b005b6101de6101ee366004611a32565b6105b7565b6101de610201366004611aaa565b61066f565b6101de610214366004611b23565b6106f6565b6101de610227366004611c15565b6108d1565b6101de61023a366004611c6c565b610b24565b6101de61024d366004611cbd565b610df1565b6040517fc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf781526020016101c2565b6003546101ae906001600160a01b031681565b6101de6102a1366004611cda565b610f00565b6102d46102b4366004611cf7565b805160208183018101805160058252928201919093012091525460ff1681565b6040516101c29190611da1565b6101de6102ef366004611dc9565b610fa1565b6101de61107a565b6007546101ae906001600160a01b031681565b6000546001600160a01b03166101ae565b6101ae7338a4794cced47d3baf7370ccc43b560d3a1beefa81565b6101de610349366004611df5565b6110c1565b6101de61035c366004611e52565b61118d565b6101de61036f366004611cda565b6113b2565b6101de610382366004611cda565b611412565b6101de610395366004611cda565b6114d6565b6101de6103a8366004611ea6565b61154c565b6103c06103bb366004611cda565b6116b1565b60405190151581526020016101c2565b6104176103de366004611cda565b6004602052600090815260409020546001600160a01b03811690600160a01b810461ffff1690600160b01b90046001600160401b031683565b604080516001600160a01b03909416845261ffff90921660208401526001600160401b0316908201526060016101c2565b6101de610456366004611cda565b6116c4565b6003546001600160a01b031633146104865760405163375152c160e01b815260040160405180910390fd5b60075460405163e596614f60e01b81526001600160401b03851660048201527338a4794cced47d3baf7370ccc43b560d3a1beefa9163bc26e7e59130916001600160a01b03169063e596614f90602401600060405180830381865afa1580156104f3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261051b9190810190611f28565b85856040518563ffffffff1660e01b815260040161053c949392919061204c565b600060405180830381600087803b15801561055657600080fd5b505af115801561056a573d6000803e3d6000fd5b5050604080516001600160401b0387168152602081018690527f50c39e9703d590409e39722da8c2ce8bfe34dded154bddaa043935c2409c80cc93500190505b60405180910390a1505050565b6105c260013361177f565b6105df5760405163ad7acb4760e01b815260040160405180910390fd5b61271061ffff821611156106065760405163013c3ba760e41b815260040160405180910390fd5b33600081815260046020908152604091829020805461ffff60a01b1916600160a01b61ffff8716908102919091179091558251938452908301527f027aba72ce53b1cf4098eff40bd649811ea216a5829fe29081fb013ae6a1b96f91015b60405180910390a150565b6000546001600160a01b0316331461069a576040516330cd747160e01b815260040160405180910390fd5b6106a56001826117a4565b156106dd577fcac241f16294cde789c1efe865bbb26d0a5d55fbf2b5b696fdb304c65f231d648383836040516105aa939291906120b9565b604051630f084ddf60e31b815260040160405180910390fd5b6003546001600160a01b031633146107215760405163375152c160e01b815260040160405180910390fd5b6003600585856040516107359291906120e5565b9081526040519081900360200190205460ff16600481111561075957610759611d8b565b14610777576040516365c4b31760e11b815260040160405180910390fd5b6040516312b3fc1960e01b81527338a4794cced47d3baf7370ccc43b560d3a1beefa906312b3fc19906107b49087908790879087906004016120f5565b600060405180830381600087803b1580156107ce57600080fd5b505af11580156107e2573d6000803e3d6000fd5b505050506001600160a01b038581166000908152600460208190526040808320548151631e5c085b60e31b8152915194169363f2e042d89382840193909282900301818387803b15801561083557600080fd5b505af1158015610849573d6000803e3d6000fd5b505050506004600585856040516108619291906120e5565b908152604051908190036020019020805460ff1916600183600481111561088a5761088a611d8b565b02179055507fcc8a7c9c5bd7463d45f32c9ffe39af44dc854cb4b8dc0329d1c3bdeb1031e0148585856040516108c29392919061212b565b60405180910390a15050505050565b6003546001600160a01b031633146108fc5760405163375152c160e01b815260040160405180910390fd5b6001600561090a8380612150565b6040516109189291906120e5565b9081526040519081900360200190205460ff16600481111561093c5761093c611d8b565b1461095a576040516365c4b31760e11b815260040160405180910390fd5b60405163095ea7b360e01b81527338a4794cced47d3baf7370ccc43b560d3a1beefa60048201526060820135602482015273ad45a78180961079bfaeee349704f411dff947c69063095ea7b3906044016020604051808303816000875af11580156109c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ed9190612196565b507338a4794cced47d3baf7370ccc43b560d3a1beefa6306e8fb9c610a128380612150565b610a1f60208601866121b3565b610a2c6040880188612150565b8860600135896080016040518963ffffffff1660e01b8152600401610a5898979695949392919061223a565b600060405180830381600087803b158015610a7257600080fd5b505af1158015610a86573d6000803e3d6000fd5b506002925060059150610a9b90508380612150565b604051610aa99291906120e5565b908152604051908190036020019020805460ff19166001836004811115610ad257610ad2611d8b565b02179055507f171bb1de68bd2c93b96f9f3f89ca7fd4a762f9459270bf93a55307be183f93f0610b028280612150565b848460600135604051610b1894939291906122f7565b60405180910390a15050565b610b2f60013361177f565b610b4c5760405163ad7acb4760e01b815260040160405180910390fd5b336000908152600460205260409020546001600160a01b031615610b83576040516312f8923160e31b815260040160405180910390fd5b306001600160a01b0316846001600160a01b031663c06546006040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bef9190612327565b6001600160a01b031614610c165760405163a714776d60e01b815260040160405180910390fd5b61271061ffff82161115610c3d5760405163013c3ba760e41b815260040160405180910390fd5b60405163142d3a2760e21b8152600481018390526001600160a01b038516906350b4e89c90602401600060405180830381600087803b158015610c7f57600080fd5b505af1158015610c93573d6000803e3d6000fd5b505060075460405163e596614f60e01b81526001600160401b03871660048201526001600160a01b03909116925063e596614f9150602401600060405180830381865afa158015610ce8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d109190810190611f28565b5060408051606080820183526001600160a01b0387811680845261ffff86811660208087018281526001600160401b038c8116898b01818152336000818152600487528d90209b518c5495519251909416600160b01b0267ffffffffffffffff60b01b1992909816600160a01b026001600160b01b0319909516939099169290921792909217169390931790965586519384529483019190915293810192909252810191909152608081018390527fb2098e6993da52c711ce658efb7338e41bcf578da2e4766a301bb62db47e33949060a00160405180910390a150505050565b610dfc60013361177f565b610e195760405163ad7acb4760e01b815260040160405180910390fd5b60075460405163e596614f60e01b81526001600160401b03831660048201526001600160a01b039091169063e596614f90602401600060405180830381865afa158015610e6a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e929190810190611f28565b5033600081815260046020908152604091829020805467ffffffffffffffff60b01b1916600160b01b6001600160401b038716908102919091179091558251938452908301527f6b15499268e2722b1ec653445be16693c8460e390b5f9c4dae011c081ee824459101610664565b6000546001600160a01b03163314610f2b576040516330cd747160e01b815260040160405180910390fd5b806001600160a01b038116610f53576040516376cb291d60e11b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b0384169081179091556040519081527f141084bbe0b806ca3d4c9dfa41d4987df8ed29c7f2ae20d4a017e87d955fb7ed90602001610b18565b6003546001600160a01b03163314610fcc5760405163375152c160e01b815260040160405180910390fd5b6001600160a01b0382811660009081526004602081905260409182902054915163043d014d60e41b81529081018490529116906343d014d090602401600060405180830381600087803b15801561102257600080fd5b505af1158015611036573d6000803e3d6000fd5b5050604080516001600160a01b0386168152602081018590527f7b3f28e29d512f36e608771705975ad5c436cf19d368573a1657c24e0db8b1209350019050610b18565b600054600160a01b900460ff16156110a557604051631ee1e30360e21b815260040160405180910390fd5b60008054600160a01b6001600160a81b03199091163317179055565b6110cc60013361177f565b6110e95760405163ad7acb4760e01b815260040160405180910390fd5b3360009081526004602081905260409182902054915163142d3a2760e21b81529081018390526001600160a01b03909116906350b4e89c90602401600060405180830381600087803b15801561113e57600080fd5b505af1158015611152573d6000803e3d6000fd5b505060408051338152602081018590527f61020a83dba6b08612f9c1dbe9e636c781693c44b062f0f4ab3307f11340b02a9350019050610664565b6003546001600160a01b031633146111b85760405163375152c160e01b815260040160405180910390fd5b60005b8181101561132c57600060058484848181106111d9576111d9612344565b90506020028101906111eb919061235a565b6111f59080612150565b6040516112039291906120e5565b9081526040519081900360200190205460ff16600481111561122757611227611d8b565b14611245576040516365c4b31760e11b815260040160405180910390fd5b6001600584848481811061125b5761125b612344565b905060200281019061126d919061235a565b6112779080612150565b6040516112859291906120e5565b908152604051908190036020019020805460ff191660018360048111156112ae576112ae611d8b565b02179055507fb7abbfc20ad848177398301a969cb076026b7c4a15b063eda34013ad984587c38383838181106112e6576112e6612344565b90506020028101906112f8919061235a565b6113029080612150565b86604051611312939291906120b9565b60405180910390a1806113248161237a565b9150506111bb565b506001600160a01b0383811660009081526004602081905260409182902054915163303f5e4160e11b81529282169263607ebc829261137b9287928792600160a01b900461ffff1691016123e6565b600060405180830381600087803b15801561139557600080fd5b505af11580156113a9573d6000803e3d6000fd5b50505050505050565b6000546001600160a01b031633146113dd576040516330cd747160e01b815260040160405180910390fd5b806001600160a01b038116611405576040516376cb291d60e11b815260040160405180910390fd5b61140e826117b9565b5050565b6000546001600160a01b0316331461143d576040516330cd747160e01b815260040160405180910390fd5b806001600160a01b038116611465576040516376cb291d60e11b815260040160405180910390fd5b6040516336f370b360e21b81526001600160a01b03831660048201527338a4794cced47d3baf7370ccc43b560d3a1beefa9063dbcdc2cc90602401600060405180830381600087803b1580156114ba57600080fd5b505af11580156114ce573d6000803e3d6000fd5b505050505050565b6000546001600160a01b03163314611501576040516330cd747160e01b815260040160405180910390fd5b806001600160a01b038116611529576040516376cb291d60e11b815260040160405180910390fd5b50600380546001600160a01b0319166001600160a01b0392909216919091179055565b6003546001600160a01b031633146115775760405163375152c160e01b815260040160405180910390fd5b60026005858560405161158b9291906120e5565b9081526040519081900360200190205460ff1660048111156115af576115af611d8b565b146115cd576040516365c4b31760e11b815260040160405180910390fd5b604051633877322b60e01b81527338a4794cced47d3baf7370ccc43b560d3a1beefa90633877322b9061160a9087908790879087906004016124c8565b600060405180830381600087803b15801561162457600080fd5b505af1158015611638573d6000803e3d6000fd5b505050506003600585856040516116509291906120e5565b908152604051908190036020019020805460ff1916600183600481111561167957611679611d8b565b02179055507f214fff527fb78557a10a93b77e999e02035639169dd2ac2c14c3c9b19f4913d38585856040516108c29392919061212b565b60006116be60018361177f565b92915050565b6000546001600160a01b031633146116ef576040516330cd747160e01b815260040160405180910390fd5b6001600160a01b038116611716576040516376cb291d60e11b815260040160405180910390fd5b600054604080516001600160a01b03928316815291831660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038116600090815260018301602052604081205415155b9392505050565b600061179d836001600160a01b03841661187e565b806001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181b91906124ef565b7fc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf71461185a5760405163f030d0ad60e01b815260040160405180910390fd5b7fc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf755565b60008181526001830160205260408120546118c5575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556116be565b5060006116be565b6001600160401b03811681146118e257600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715611923576119236118e5565b604052919050565b803563ffffffff8116811461193f57600080fd5b919050565b80151581146118e257600080fd5b600060a0828403121561196457600080fd5b60405160a081018181106001600160401b0382111715611986576119866118e5565b6040529050806119958361192b565b815260208301356119a5816118cd565b602082015260408301356119b8816118cd565b604082015260608301356119cb81611944565b6060820152608092830135920191909152919050565b600080600060e084860312156119f657600080fd5b8335611a01816118cd565b925060208401359150611a178560408601611952565b90509250925092565b803561ffff8116811461193f57600080fd5b600060208284031215611a4457600080fd5b61179d82611a20565b60008083601f840112611a5f57600080fd5b5081356001600160401b03811115611a7657600080fd5b602083019150836020828501011115611a8e57600080fd5b9250929050565b6001600160a01b03811681146118e257600080fd5b600080600060408486031215611abf57600080fd5b83356001600160401b03811115611ad557600080fd5b611ae186828701611a4d565b9094509250506020840135611af581611a95565b809150509250925092565b60006001600160401b03821115611b1957611b196118e5565b5060051b60200190565b60008060008060006101008688031215611b3c57600080fd5b8535611b4781611a95565b94506020868101356001600160401b0380821115611b6457600080fd5b611b708a838b01611a4d565b90975095506040890135915080821115611b8957600080fd5b508701601f81018913611b9b57600080fd5b8035611bae611ba982611b00565b6118fb565b81815260059190911b8201830190838101908b831115611bcd57600080fd5b928401925b82841015611bf4578335611be5816118cd565b82529284019290840190611bd2565b8096505050505050611c098760608801611952565b90509295509295909350565b60008060408385031215611c2857600080fd5b8235611c3381611a95565b915060208301356001600160401b03811115611c4e57600080fd5b83016101208186031215611c6157600080fd5b809150509250929050565b60008060008060808587031215611c8257600080fd5b8435611c8d81611a95565b93506020850135611c9d816118cd565b925060408501359150611cb260608601611a20565b905092959194509250565b600060208284031215611ccf57600080fd5b813561179d816118cd565b600060208284031215611cec57600080fd5b813561179d81611a95565b60006020808385031215611d0a57600080fd5b82356001600160401b0380821115611d2157600080fd5b818501915085601f830112611d3557600080fd5b813581811115611d4757611d476118e5565b611d59601f8201601f191685016118fb565b91508082528684828501011115611d6f57600080fd5b8084840185840137600090820190930192909252509392505050565b634e487b7160e01b600052602160045260246000fd5b6020810160058310611dc357634e487b7160e01b600052602160045260246000fd5b91905290565b60008060408385031215611ddc57600080fd5b8235611de781611a95565b946020939093013593505050565b600060208284031215611e0757600080fd5b5035919050565b60008083601f840112611e2057600080fd5b5081356001600160401b03811115611e3757600080fd5b6020830191508360208260051b8501011115611a8e57600080fd5b600080600060408486031215611e6757600080fd5b8335611e7281611a95565b925060208401356001600160401b03811115611e8d57600080fd5b611e9986828701611e0e565b9497909650939450505050565b600080600080600060608688031215611ebe57600080fd5b8535611ec981611a95565b945060208601356001600160401b0380821115611ee557600080fd5b611ef189838a01611a4d565b90965094506040880135915080821115611f0a57600080fd5b50611f1788828901611e0e565b969995985093965092949392505050565b60006020808385031215611f3b57600080fd5b82516001600160401b03811115611f5157600080fd5b8301601f81018513611f6257600080fd5b8051611f70611ba982611b00565b81815260059190911b82018301908381019087831115611f8f57600080fd5b928401925b82841015611fb6578351611fa7816118cd565b82529284019290840190611f94565b979650505050505050565b600081518084526020808501945080840160005b83811015611ffa5781516001600160401b031687529582019590820190600101611fd5565b509495945050505050565b63ffffffff815116825260208101516001600160401b0380821660208501528060408401511660408501525050606081015115156060830152608081015160808301525050565b6001600160a01b03851681526101006020820181905260009061207183820187611fc1565b9150508360408301526120876060830184612005565b95945050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6040815260006120cd604083018587612090565b905060018060a01b0383166020830152949350505050565b8183823760009101908152919050565b60e08152600061210960e083018688612090565b828103602084015261211b8186611fc1565b9150506120876040830184612005565b6001600160a01b03841681526040602082018190526000906120879083018486612090565b6000808335601e1984360301811261216757600080fd5b8301803591506001600160401b0382111561218157600080fd5b602001915036819003821315611a8e57600080fd5b6000602082840312156121a857600080fd5b815161179d81611944565b6000808335601e198436030181126121ca57600080fd5b8301803591506001600160401b038211156121e457600080fd5b6020019150600581901b3603821315611a8e57600080fd5b8183526000602080850194508260005b85811015611ffa57813561221f816118cd565b6001600160401b03168752958201959082019060010161220c565b600061012080835261224f8184018b8d612090565b9050828103602084015261226481898b6121fc565b90508281036040840152612279818789612090565b91505083606083015263ffffffff6122908461192b565b16608083015260208301356122a4816118cd565b6001600160401b0390811660a08401526040840135906122c3826118cd565b1660c083015260608301356122d781611944565b151560e08301526080929092013561010090910152979650505050505050565b60608152600061230b606083018688612090565b6001600160a01b03949094166020830152506040015292915050565b60006020828403121561233957600080fd5b815161179d81611a95565b634e487b7160e01b600052603260045260246000fd5b60008235607e1983360301811261237057600080fd5b9190910192915050565b60006001820161239a57634e487b7160e01b600052601160045260246000fd5b5060010190565b6000808335601e198436030181126123b857600080fd5b83016020810192503590506001600160401b038111156123d757600080fd5b803603821315611a8e57600080fd5b60408082528181018490526000906060808401600587901b850182018885805b8a8110156124b057888403605f190185528235368d9003607e1901811261242b578283fd5b8c01608061243982806123a1565b8288526124498389018284612090565b92505050602061245b818401846123a1565b888403838a015261246d848284612090565b9350505061247d8a8401846123a1565b8884038c8a015261248f848284612090565b948b0135988b01989098525096870196919550509290920191600101612406565b50505080945050505050826020830152949350505050565b6040815260006124dc604083018688612090565b8281036020840152611fb68185876121fc565b60006020828403121561250157600080fd5b505191905056fea26469706673582212208f183f710082f405be0e45237f9db401e444338f1b9bdbd50bc1bce45401598564736f6c63430008130033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061018e5760003560e01c80638129fc1c116100de5780639e95514911610097578063e03ad13c11610071578063e03ad13c1461039a578063e2f4a731146103ad578063eff00f9d146103d0578063f2fde38b1461044857600080fd5b80639e95514914610361578063c37a78dc14610374578063c40e9df91461038757600080fd5b80638129fc1c146102f457806384eff0fa146102fc578063893d20e81461030f5780639164975114610320578063946cd73f1461033b5780639b17541c1461034e57600080fd5b80633d4d837f1161014b578063614080a111610125578063614080a114610280578063687abf7d146102935780636c36511a146102a65780636f2a626f146102e157600080fd5b80633d4d837f1461022c5780634fde79ad1461023f57806352d1902d1461025257600080fd5b80630df1ecfd14610193578063139b0f75146101cb5780631621eecb146101e05780633011ad9b146101f357806334439c8014610206578063383bf14214610219575b600080fd5b6101ae73ad45a78180961079bfaeee349704f411dff947c681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101de6101d93660046119e1565b61045b565b005b6101de6101ee366004611a32565b6105b7565b6101de610201366004611aaa565b61066f565b6101de610214366004611b23565b6106f6565b6101de610227366004611c15565b6108d1565b6101de61023a366004611c6c565b610b24565b6101de61024d366004611cbd565b610df1565b6040517fc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf781526020016101c2565b6003546101ae906001600160a01b031681565b6101de6102a1366004611cda565b610f00565b6102d46102b4366004611cf7565b805160208183018101805160058252928201919093012091525460ff1681565b6040516101c29190611da1565b6101de6102ef366004611dc9565b610fa1565b6101de61107a565b6007546101ae906001600160a01b031681565b6000546001600160a01b03166101ae565b6101ae7338a4794cced47d3baf7370ccc43b560d3a1beefa81565b6101de610349366004611df5565b6110c1565b6101de61035c366004611e52565b61118d565b6101de61036f366004611cda565b6113b2565b6101de610382366004611cda565b611412565b6101de610395366004611cda565b6114d6565b6101de6103a8366004611ea6565b61154c565b6103c06103bb366004611cda565b6116b1565b60405190151581526020016101c2565b6104176103de366004611cda565b6004602052600090815260409020546001600160a01b03811690600160a01b810461ffff1690600160b01b90046001600160401b031683565b604080516001600160a01b03909416845261ffff90921660208401526001600160401b0316908201526060016101c2565b6101de610456366004611cda565b6116c4565b6003546001600160a01b031633146104865760405163375152c160e01b815260040160405180910390fd5b60075460405163e596614f60e01b81526001600160401b03851660048201527338a4794cced47d3baf7370ccc43b560d3a1beefa9163bc26e7e59130916001600160a01b03169063e596614f90602401600060405180830381865afa1580156104f3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261051b9190810190611f28565b85856040518563ffffffff1660e01b815260040161053c949392919061204c565b600060405180830381600087803b15801561055657600080fd5b505af115801561056a573d6000803e3d6000fd5b5050604080516001600160401b0387168152602081018690527f50c39e9703d590409e39722da8c2ce8bfe34dded154bddaa043935c2409c80cc93500190505b60405180910390a1505050565b6105c260013361177f565b6105df5760405163ad7acb4760e01b815260040160405180910390fd5b61271061ffff821611156106065760405163013c3ba760e41b815260040160405180910390fd5b33600081815260046020908152604091829020805461ffff60a01b1916600160a01b61ffff8716908102919091179091558251938452908301527f027aba72ce53b1cf4098eff40bd649811ea216a5829fe29081fb013ae6a1b96f91015b60405180910390a150565b6000546001600160a01b0316331461069a576040516330cd747160e01b815260040160405180910390fd5b6106a56001826117a4565b156106dd577fcac241f16294cde789c1efe865bbb26d0a5d55fbf2b5b696fdb304c65f231d648383836040516105aa939291906120b9565b604051630f084ddf60e31b815260040160405180910390fd5b6003546001600160a01b031633146107215760405163375152c160e01b815260040160405180910390fd5b6003600585856040516107359291906120e5565b9081526040519081900360200190205460ff16600481111561075957610759611d8b565b14610777576040516365c4b31760e11b815260040160405180910390fd5b6040516312b3fc1960e01b81527338a4794cced47d3baf7370ccc43b560d3a1beefa906312b3fc19906107b49087908790879087906004016120f5565b600060405180830381600087803b1580156107ce57600080fd5b505af11580156107e2573d6000803e3d6000fd5b505050506001600160a01b038581166000908152600460208190526040808320548151631e5c085b60e31b8152915194169363f2e042d89382840193909282900301818387803b15801561083557600080fd5b505af1158015610849573d6000803e3d6000fd5b505050506004600585856040516108619291906120e5565b908152604051908190036020019020805460ff1916600183600481111561088a5761088a611d8b565b02179055507fcc8a7c9c5bd7463d45f32c9ffe39af44dc854cb4b8dc0329d1c3bdeb1031e0148585856040516108c29392919061212b565b60405180910390a15050505050565b6003546001600160a01b031633146108fc5760405163375152c160e01b815260040160405180910390fd5b6001600561090a8380612150565b6040516109189291906120e5565b9081526040519081900360200190205460ff16600481111561093c5761093c611d8b565b1461095a576040516365c4b31760e11b815260040160405180910390fd5b60405163095ea7b360e01b81527338a4794cced47d3baf7370ccc43b560d3a1beefa60048201526060820135602482015273ad45a78180961079bfaeee349704f411dff947c69063095ea7b3906044016020604051808303816000875af11580156109c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ed9190612196565b507338a4794cced47d3baf7370ccc43b560d3a1beefa6306e8fb9c610a128380612150565b610a1f60208601866121b3565b610a2c6040880188612150565b8860600135896080016040518963ffffffff1660e01b8152600401610a5898979695949392919061223a565b600060405180830381600087803b158015610a7257600080fd5b505af1158015610a86573d6000803e3d6000fd5b506002925060059150610a9b90508380612150565b604051610aa99291906120e5565b908152604051908190036020019020805460ff19166001836004811115610ad257610ad2611d8b565b02179055507f171bb1de68bd2c93b96f9f3f89ca7fd4a762f9459270bf93a55307be183f93f0610b028280612150565b848460600135604051610b1894939291906122f7565b60405180910390a15050565b610b2f60013361177f565b610b4c5760405163ad7acb4760e01b815260040160405180910390fd5b336000908152600460205260409020546001600160a01b031615610b83576040516312f8923160e31b815260040160405180910390fd5b306001600160a01b0316846001600160a01b031663c06546006040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bef9190612327565b6001600160a01b031614610c165760405163a714776d60e01b815260040160405180910390fd5b61271061ffff82161115610c3d5760405163013c3ba760e41b815260040160405180910390fd5b60405163142d3a2760e21b8152600481018390526001600160a01b038516906350b4e89c90602401600060405180830381600087803b158015610c7f57600080fd5b505af1158015610c93573d6000803e3d6000fd5b505060075460405163e596614f60e01b81526001600160401b03871660048201526001600160a01b03909116925063e596614f9150602401600060405180830381865afa158015610ce8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d109190810190611f28565b5060408051606080820183526001600160a01b0387811680845261ffff86811660208087018281526001600160401b038c8116898b01818152336000818152600487528d90209b518c5495519251909416600160b01b0267ffffffffffffffff60b01b1992909816600160a01b026001600160b01b0319909516939099169290921792909217169390931790965586519384529483019190915293810192909252810191909152608081018390527fb2098e6993da52c711ce658efb7338e41bcf578da2e4766a301bb62db47e33949060a00160405180910390a150505050565b610dfc60013361177f565b610e195760405163ad7acb4760e01b815260040160405180910390fd5b60075460405163e596614f60e01b81526001600160401b03831660048201526001600160a01b039091169063e596614f90602401600060405180830381865afa158015610e6a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e929190810190611f28565b5033600081815260046020908152604091829020805467ffffffffffffffff60b01b1916600160b01b6001600160401b038716908102919091179091558251938452908301527f6b15499268e2722b1ec653445be16693c8460e390b5f9c4dae011c081ee824459101610664565b6000546001600160a01b03163314610f2b576040516330cd747160e01b815260040160405180910390fd5b806001600160a01b038116610f53576040516376cb291d60e11b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b0384169081179091556040519081527f141084bbe0b806ca3d4c9dfa41d4987df8ed29c7f2ae20d4a017e87d955fb7ed90602001610b18565b6003546001600160a01b03163314610fcc5760405163375152c160e01b815260040160405180910390fd5b6001600160a01b0382811660009081526004602081905260409182902054915163043d014d60e41b81529081018490529116906343d014d090602401600060405180830381600087803b15801561102257600080fd5b505af1158015611036573d6000803e3d6000fd5b5050604080516001600160a01b0386168152602081018590527f7b3f28e29d512f36e608771705975ad5c436cf19d368573a1657c24e0db8b1209350019050610b18565b600054600160a01b900460ff16156110a557604051631ee1e30360e21b815260040160405180910390fd5b60008054600160a01b6001600160a81b03199091163317179055565b6110cc60013361177f565b6110e95760405163ad7acb4760e01b815260040160405180910390fd5b3360009081526004602081905260409182902054915163142d3a2760e21b81529081018390526001600160a01b03909116906350b4e89c90602401600060405180830381600087803b15801561113e57600080fd5b505af1158015611152573d6000803e3d6000fd5b505060408051338152602081018590527f61020a83dba6b08612f9c1dbe9e636c781693c44b062f0f4ab3307f11340b02a9350019050610664565b6003546001600160a01b031633146111b85760405163375152c160e01b815260040160405180910390fd5b60005b8181101561132c57600060058484848181106111d9576111d9612344565b90506020028101906111eb919061235a565b6111f59080612150565b6040516112039291906120e5565b9081526040519081900360200190205460ff16600481111561122757611227611d8b565b14611245576040516365c4b31760e11b815260040160405180910390fd5b6001600584848481811061125b5761125b612344565b905060200281019061126d919061235a565b6112779080612150565b6040516112859291906120e5565b908152604051908190036020019020805460ff191660018360048111156112ae576112ae611d8b565b02179055507fb7abbfc20ad848177398301a969cb076026b7c4a15b063eda34013ad984587c38383838181106112e6576112e6612344565b90506020028101906112f8919061235a565b6113029080612150565b86604051611312939291906120b9565b60405180910390a1806113248161237a565b9150506111bb565b506001600160a01b0383811660009081526004602081905260409182902054915163303f5e4160e11b81529282169263607ebc829261137b9287928792600160a01b900461ffff1691016123e6565b600060405180830381600087803b15801561139557600080fd5b505af11580156113a9573d6000803e3d6000fd5b50505050505050565b6000546001600160a01b031633146113dd576040516330cd747160e01b815260040160405180910390fd5b806001600160a01b038116611405576040516376cb291d60e11b815260040160405180910390fd5b61140e826117b9565b5050565b6000546001600160a01b0316331461143d576040516330cd747160e01b815260040160405180910390fd5b806001600160a01b038116611465576040516376cb291d60e11b815260040160405180910390fd5b6040516336f370b360e21b81526001600160a01b03831660048201527338a4794cced47d3baf7370ccc43b560d3a1beefa9063dbcdc2cc90602401600060405180830381600087803b1580156114ba57600080fd5b505af11580156114ce573d6000803e3d6000fd5b505050505050565b6000546001600160a01b03163314611501576040516330cd747160e01b815260040160405180910390fd5b806001600160a01b038116611529576040516376cb291d60e11b815260040160405180910390fd5b50600380546001600160a01b0319166001600160a01b0392909216919091179055565b6003546001600160a01b031633146115775760405163375152c160e01b815260040160405180910390fd5b60026005858560405161158b9291906120e5565b9081526040519081900360200190205460ff1660048111156115af576115af611d8b565b146115cd576040516365c4b31760e11b815260040160405180910390fd5b604051633877322b60e01b81527338a4794cced47d3baf7370ccc43b560d3a1beefa90633877322b9061160a9087908790879087906004016124c8565b600060405180830381600087803b15801561162457600080fd5b505af1158015611638573d6000803e3d6000fd5b505050506003600585856040516116509291906120e5565b908152604051908190036020019020805460ff1916600183600481111561167957611679611d8b565b02179055507f214fff527fb78557a10a93b77e999e02035639169dd2ac2c14c3c9b19f4913d38585856040516108c29392919061212b565b60006116be60018361177f565b92915050565b6000546001600160a01b031633146116ef576040516330cd747160e01b815260040160405180910390fd5b6001600160a01b038116611716576040516376cb291d60e11b815260040160405180910390fd5b600054604080516001600160a01b03928316815291831660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038116600090815260018301602052604081205415155b9392505050565b600061179d836001600160a01b03841661187e565b806001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181b91906124ef565b7fc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf71461185a5760405163f030d0ad60e01b815260040160405180910390fd5b7fc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf755565b60008181526001830160205260408120546118c5575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556116be565b5060006116be565b6001600160401b03811681146118e257600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715611923576119236118e5565b604052919050565b803563ffffffff8116811461193f57600080fd5b919050565b80151581146118e257600080fd5b600060a0828403121561196457600080fd5b60405160a081018181106001600160401b0382111715611986576119866118e5565b6040529050806119958361192b565b815260208301356119a5816118cd565b602082015260408301356119b8816118cd565b604082015260608301356119cb81611944565b6060820152608092830135920191909152919050565b600080600060e084860312156119f657600080fd5b8335611a01816118cd565b925060208401359150611a178560408601611952565b90509250925092565b803561ffff8116811461193f57600080fd5b600060208284031215611a4457600080fd5b61179d82611a20565b60008083601f840112611a5f57600080fd5b5081356001600160401b03811115611a7657600080fd5b602083019150836020828501011115611a8e57600080fd5b9250929050565b6001600160a01b03811681146118e257600080fd5b600080600060408486031215611abf57600080fd5b83356001600160401b03811115611ad557600080fd5b611ae186828701611a4d565b9094509250506020840135611af581611a95565b809150509250925092565b60006001600160401b03821115611b1957611b196118e5565b5060051b60200190565b60008060008060006101008688031215611b3c57600080fd5b8535611b4781611a95565b94506020868101356001600160401b0380821115611b6457600080fd5b611b708a838b01611a4d565b90975095506040890135915080821115611b8957600080fd5b508701601f81018913611b9b57600080fd5b8035611bae611ba982611b00565b6118fb565b81815260059190911b8201830190838101908b831115611bcd57600080fd5b928401925b82841015611bf4578335611be5816118cd565b82529284019290840190611bd2565b8096505050505050611c098760608801611952565b90509295509295909350565b60008060408385031215611c2857600080fd5b8235611c3381611a95565b915060208301356001600160401b03811115611c4e57600080fd5b83016101208186031215611c6157600080fd5b809150509250929050565b60008060008060808587031215611c8257600080fd5b8435611c8d81611a95565b93506020850135611c9d816118cd565b925060408501359150611cb260608601611a20565b905092959194509250565b600060208284031215611ccf57600080fd5b813561179d816118cd565b600060208284031215611cec57600080fd5b813561179d81611a95565b60006020808385031215611d0a57600080fd5b82356001600160401b0380821115611d2157600080fd5b818501915085601f830112611d3557600080fd5b813581811115611d4757611d476118e5565b611d59601f8201601f191685016118fb565b91508082528684828501011115611d6f57600080fd5b8084840185840137600090820190930192909252509392505050565b634e487b7160e01b600052602160045260246000fd5b6020810160058310611dc357634e487b7160e01b600052602160045260246000fd5b91905290565b60008060408385031215611ddc57600080fd5b8235611de781611a95565b946020939093013593505050565b600060208284031215611e0757600080fd5b5035919050565b60008083601f840112611e2057600080fd5b5081356001600160401b03811115611e3757600080fd5b6020830191508360208260051b8501011115611a8e57600080fd5b600080600060408486031215611e6757600080fd5b8335611e7281611a95565b925060208401356001600160401b03811115611e8d57600080fd5b611e9986828701611e0e565b9497909650939450505050565b600080600080600060608688031215611ebe57600080fd5b8535611ec981611a95565b945060208601356001600160401b0380821115611ee557600080fd5b611ef189838a01611a4d565b90965094506040880135915080821115611f0a57600080fd5b50611f1788828901611e0e565b969995985093965092949392505050565b60006020808385031215611f3b57600080fd5b82516001600160401b03811115611f5157600080fd5b8301601f81018513611f6257600080fd5b8051611f70611ba982611b00565b81815260059190911b82018301908381019087831115611f8f57600080fd5b928401925b82841015611fb6578351611fa7816118cd565b82529284019290840190611f94565b979650505050505050565b600081518084526020808501945080840160005b83811015611ffa5781516001600160401b031687529582019590820190600101611fd5565b509495945050505050565b63ffffffff815116825260208101516001600160401b0380821660208501528060408401511660408501525050606081015115156060830152608081015160808301525050565b6001600160a01b03851681526101006020820181905260009061207183820187611fc1565b9150508360408301526120876060830184612005565b95945050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6040815260006120cd604083018587612090565b905060018060a01b0383166020830152949350505050565b8183823760009101908152919050565b60e08152600061210960e083018688612090565b828103602084015261211b8186611fc1565b9150506120876040830184612005565b6001600160a01b03841681526040602082018190526000906120879083018486612090565b6000808335601e1984360301811261216757600080fd5b8301803591506001600160401b0382111561218157600080fd5b602001915036819003821315611a8e57600080fd5b6000602082840312156121a857600080fd5b815161179d81611944565b6000808335601e198436030181126121ca57600080fd5b8301803591506001600160401b038211156121e457600080fd5b6020019150600581901b3603821315611a8e57600080fd5b8183526000602080850194508260005b85811015611ffa57813561221f816118cd565b6001600160401b03168752958201959082019060010161220c565b600061012080835261224f8184018b8d612090565b9050828103602084015261226481898b6121fc565b90508281036040840152612279818789612090565b91505083606083015263ffffffff6122908461192b565b16608083015260208301356122a4816118cd565b6001600160401b0390811660a08401526040840135906122c3826118cd565b1660c083015260608301356122d781611944565b151560e08301526080929092013561010090910152979650505050505050565b60608152600061230b606083018688612090565b6001600160a01b03949094166020830152506040015292915050565b60006020828403121561233957600080fd5b815161179d81611a95565b634e487b7160e01b600052603260045260246000fd5b60008235607e1983360301811261237057600080fd5b9190910192915050565b60006001820161239a57634e487b7160e01b600052601160045260246000fd5b5060010190565b6000808335601e198436030181126123b857600080fd5b83016020810192503590506001600160401b038111156123d757600080fd5b803603821315611a8e57600080fd5b60408082528181018490526000906060808401600587901b850182018885805b8a8110156124b057888403605f190185528235368d9003607e1901811261242b578283fd5b8c01608061243982806123a1565b8288526124498389018284612090565b92505050602061245b818401846123a1565b888403838a015261246d848284612090565b9350505061247d8a8401846123a1565b8884038c8a015261248f848284612090565b948b0135988b01989098525096870196919550509290920191600101612406565b50505080945050505050826020830152949350505050565b6040815260006124dc604083018688612090565b8281036020840152611fb68185876121fc565b60006020828403121561250157600080fd5b505191905056fea26469706673582212208f183f710082f405be0e45237f9db401e444338f1b9bdbd50bc1bce45401598564736f6c63430008130033
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.