Source Code
Latest 25 from a total of 3,465 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Deregister | 408957167 | 2 days ago | IN | 0 ETH | 0.00000055 | ||||
| Deregister | 408935307 | 2 days ago | IN | 0 ETH | 0.00000055 | ||||
| Deregister | 408935233 | 2 days ago | IN | 0 ETH | 0.00000055 | ||||
| Deregister | 408935165 | 2 days ago | IN | 0 ETH | 0.00000055 | ||||
| Deregister | 408935099 | 2 days ago | IN | 0 ETH | 0.00000055 | ||||
| Deregister | 408935025 | 2 days ago | IN | 0 ETH | 0.00000055 | ||||
| Deregister | 408934969 | 2 days ago | IN | 0 ETH | 0.00000055 | ||||
| Deregister | 408934921 | 2 days ago | IN | 0 ETH | 0.00000055 | ||||
| Deregister | 408934861 | 2 days ago | IN | 0 ETH | 0.00000059 | ||||
| Deregister | 408934734 | 2 days ago | IN | 0 ETH | 0.0000007 | ||||
| Deregister | 408934688 | 2 days ago | IN | 0 ETH | 0.00000072 | ||||
| Deregister | 408934630 | 2 days ago | IN | 0 ETH | 0.00000076 | ||||
| Deregister | 408934574 | 2 days ago | IN | 0 ETH | 0.00000079 | ||||
| Deregister | 408934526 | 2 days ago | IN | 0 ETH | 0.00000079 | ||||
| Deregister | 408934470 | 2 days ago | IN | 0 ETH | 0.00000084 | ||||
| Deregister | 408934415 | 2 days ago | IN | 0 ETH | 0.00000089 | ||||
| Deregister | 408934282 | 2 days ago | IN | 0 ETH | 0.00000091 | ||||
| Deregister | 408934228 | 2 days ago | IN | 0 ETH | 0.00000097 | ||||
| Deregister | 408934175 | 2 days ago | IN | 0 ETH | 0.00000105 | ||||
| Deregister | 408934120 | 2 days ago | IN | 0 ETH | 0.00000113 | ||||
| Deregister | 408934022 | 2 days ago | IN | 0 ETH | 0.00000128 | ||||
| Deregister | 408933952 | 2 days ago | IN | 0 ETH | 0.00000135 | ||||
| Deregister | 408933860 | 2 days ago | IN | 0 ETH | 0.00000141 | ||||
| Deregister | 408933773 | 2 days ago | IN | 0 ETH | 0.00000127 | ||||
| Deregister | 408933723 | 2 days ago | IN | 0 ETH | 0.00000116 |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
WorkerRegistration
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
/**
.::.
.=***#*+:
.=*********+.
.=++++*********=.
.=++=++++++++******-
.=++=++++++++++++******-
.=++==+++++++++++==+******+:
.=+===+++++++++++++===+*******=
.=+===+++++++++++++++===-=*******=
.=====++++++++++++++++====-=*****#*.
:-===++++++++++++++++++====--+*###=
:==+++++++++++++++++++++====---=+*-
:=++***************++++++++====--:-
.-+*########*************++++++===-:
.=##%%##################*****++++===-.
=#%%%%%%###########%%#######***+++==--
+%@@#****************##%%%#####**++==-.
-%#==*##**********##*****#%%%####**+==:
*-=*%+##*******##%@@#******#%%###**+=-
:=+%%#@%******#%=*@@%*********#%##*++-
:=*%@@@**####*#@@@@@%********++*###*+.
=+**##*#######*#@@@%#####****++++**+-
+*- .+**#**#########*****######****+++=+-
-#**+:-**++**########***###%%%%##**+++++=.
::-**+-=*#*=+**#######***#*###%%%##**++++*+= :=-
-###****##%==+**######*******#######**+===*#*+-::::-=*##*
.#%#******==+***##%%%#********######**++==+%%%##**#####%*
+#%##******###%%%####****+++*#%%%##*********#%%%%%%%%*.
:%%%%%%%#%%%%###=.+##**********##########%%##%%%###=
#%#%%%%%##**=. :########%%#:-**#%%%%%##*+++*+-:
::+#**#+=-. =#%%%%#%%#*. :=*****=:
:+##*##+= ..
:-.::
*/
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.20;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "./interfaces/INetworkController.sol";
import "./interfaces/IStaking.sol";
import "./interfaces/IWorkerRegistration.sol";
import "./interfaces/IRouter.sol";
import "./AccessControlledPausable.sol";
/**
* @title Worker Registration Contract
* @dev Worker registration and managing
* - A single account can register multiple workers
* - Worker becomes active and eligible for rewards only after the next epoch after registration has started
* - Active worker can be deregistered
* - After worker is deregistered, it becomes inactive only after the next epoch has started
* - Worker bond can be withdrawn after the lock period has passed after the worker has been deregistered
*/
contract WorkerRegistration is AccessControlledPausable, IWorkerRegistration {
using EnumerableSet for EnumerableSet.AddressSet;
using EnumerableSet for EnumerableSet.UintSet;
uint256 private workerIdTracker;
struct Worker {
address creator;
bytes peerId;
uint256 bond;
uint128 registeredAt;
uint128 deregisteredAt;
string metadata;
}
IERC20 public immutable SQD;
IRouter public immutable router;
mapping(uint256 => Worker) public workers;
mapping(bytes peerId => uint256 id) public workerIds;
EnumerableSet.UintSet activeWorkerIds;
mapping(address creator => EnumerableSet.UintSet) internal ownedWorkers;
/**
* @param _SQD SQD token.
* @param _router Countract router
*/
constructor(IERC20 _SQD, IRouter _router) {
SQD = _SQD;
router = _router;
}
function register(bytes calldata peerId) external {
register(peerId, "");
}
/**
* @dev Registers a worker.
* @param peerId The unique peer ID of the worker.
* @notice Peer ID is a unique identifier of the worker. It is expected to be a hex representation of the libp2p peer ID of the worker
* @notice bondAmount of SQD tokens will be transferred from the caller to this contract
*/
function register(bytes calldata peerId, string memory metadata) public whenNotPaused {
require(peerId.length <= 64, "Peer ID too large");
uint256 workerId;
if (workerIds[peerId] != 0) {
require(workers[workerIds[peerId]].registeredAt == 0, "Worker already exists");
require(ownedWorkers[msg.sender].contains(workerIds[peerId]), "Worker already registered by different account");
workerId = workerIds[peerId];
} else {
workerIdTracker++;
workerId = workerIdTracker;
}
uint256 _bondAmount = bondAmount();
workers[workerId] = Worker({
creator: msg.sender,
peerId: peerId,
bond: _bondAmount,
registeredAt: nextEpoch(),
deregisteredAt: 0,
metadata: metadata
});
workerIds[peerId] = workerId;
activeWorkerIds.add(workerId);
ownedWorkers[msg.sender].add(workerId);
SQD.transferFrom(msg.sender, address(this), _bondAmount);
emit WorkerRegistered(workerId, peerId, msg.sender, workers[workerId].registeredAt, metadata);
}
/**
* @dev Deregisters a worker.
* @param peerId The unique peer ID of the worker.
* @notice Worker must be active
* @notice Worker must be registered by the caller
* @notice Worker becomes inactive after current epoch ends
*/
function deregister(bytes calldata peerId) external whenNotPaused {
uint256 workerId = workerIds[peerId];
require(workerId != 0, "Worker not registered");
require(isWorkerActive(workers[workerId]), "Worker not active");
require(workers[workerId].creator == msg.sender, "Not worker creator");
workers[workerId].deregisteredAt = nextEpoch();
emit WorkerDeregistered(workerId, msg.sender, workers[workerId].deregisteredAt);
}
/**
* @dev Withdraws the bond of a worker.
* @param peerId The unique peer ID of the worker.
* @notice Worker must be inactive
* @notice Worker must be registered by the caller
* @notice Worker must be deregistered for at least lockPeriod
*/
function withdraw(bytes calldata peerId) external whenNotPaused {
uint256 workerId = workerIds[peerId];
require(workerId != 0, "Worker not registered");
Worker storage worker = workers[workerId];
require(!isWorkerActive(worker), "Worker is active");
require(worker.creator == msg.sender, "Not worker creator");
require(worker.deregisteredAt > 0 && block.number >= worker.deregisteredAt + lockPeriod(), "Worker is locked");
activeWorkerIds.remove(workerId);
uint256 bond = worker.bond;
delete workers[workerId];
SQD.transfer(msg.sender, bond);
emit WorkerWithdrawn(workerId, msg.sender);
}
function updateMetadata(bytes calldata peerId, string memory metadata) external whenNotPaused {
uint256 workerId = workerIds[peerId];
require(workers[workerId].creator == msg.sender, "Not worker creator");
workers[workerId].metadata = metadata;
emit MetadataUpdated(workerId, metadata);
}
/**
* @dev Returns the excessive bond of a worker.
* In case bond has been reduced, the difference can be returned to the worker creator.
* @param peerId The unique peer ID of the worker.
* @notice Worker must be registered by the caller
*/
function returnExcessiveBond(bytes calldata peerId) external whenNotPaused {
uint256 workerId = workerIds[peerId];
require(workerId != 0, "Worker not registered");
require(workers[workerId].creator == msg.sender, "Not worker creator");
uint256 _bondAmount = bondAmount();
uint256 excessiveBond = workers[workerId].bond - _bondAmount;
workers[workerId].bond = _bondAmount;
SQD.transfer(msg.sender, excessiveBond);
emit ExcessiveBondReturned(workerId, excessiveBond);
}
/// @dev Next epoch start block number.
function nextEpoch() public view returns (uint128) {
return router.networkController().nextEpoch();
}
/// @dev Returns the list of active workers.
function getActiveWorkers() external view returns (Worker[] memory) {
Worker[] memory activeWorkers = new Worker[](getActiveWorkerCount());
uint256[] memory _activeWorkerIds = activeWorkerIds.values();
uint256 activeIndex = 0;
for (uint256 i = 0; i < _activeWorkerIds.length; i++) {
uint256 workerId = _activeWorkerIds[i];
Worker storage worker = workers[workerId];
if (isWorkerActive(worker)) {
activeWorkers[activeIndex] = worker;
activeIndex++;
}
}
return activeWorkers;
}
/// @dev Returns the list of active worker IDs.
function getActiveWorkerIds() public view returns (uint256[] memory) {
uint256[] memory activeWorkers = new uint256[](getActiveWorkerCount());
uint256[] memory _activeWorkerIds = activeWorkerIds.values();
uint256 activeIndex = 0;
for (uint256 i = 0; i < _activeWorkerIds.length; i++) {
uint256 workerId = _activeWorkerIds[i];
Worker storage worker = workers[workerId];
if (isWorkerActive(worker)) {
activeWorkers[activeIndex] = workerId;
activeIndex++;
}
}
return activeWorkers;
}
function isWorkerActive(uint256 workerId) external view returns (bool) {
return isWorkerActive(workers[workerId]);
}
/// @dev Returns true if worker is active.
/// @notice Worker is considered active if it has been registered and not deregistered yet
function isWorkerActive(Worker storage worker) internal view returns (bool) {
return worker.registeredAt > 0 && worker.registeredAt <= block.number
&& (worker.deregisteredAt == 0 || worker.deregisteredAt > block.number);
}
/// @dev Returns the number of active workers.
/// @notice Worker is considered active if it has been registered and not deregistered yet
function getActiveWorkerCount() public view returns (uint256) {
uint256 activeCount = 0;
uint256[] memory _activeWorkerIds = activeWorkerIds.values();
for (uint256 i = 0; i < _activeWorkerIds.length; i++) {
uint256 workerId = _activeWorkerIds[i];
Worker storage worker = workers[workerId];
if (isWorkerActive(worker)) {
activeCount++;
}
}
return activeCount;
}
/// @dev Get worker by index
/// @param workerId ID of the worker
/// @return Worker under the index
function getWorker(uint256 workerId) external view returns (Worker memory) {
return workers[workerId];
}
/// @dev Returns the ids of all worker created by the owner account
function getOwnedWorkers(address owner) external view returns (uint256[] memory) {
return ownedWorkers[owner].values();
}
/// @dev get count of all workers
function getAllWorkersCount() external view returns (uint256) {
return activeWorkerIds.length();
}
function getMetadata(bytes calldata peerId) external view returns (string memory) {
uint256 workerId = workerIds[peerId];
require(workerId != 0, "Worker not registered");
return workers[workerId].metadata;
}
/// @dev Get current bond amount
function bondAmount() public view returns (uint256) {
return router.networkController().bondAmount();
}
/// @dev Get current epoch length in blocks
function epochLength() public view returns (uint128) {
return router.networkController().epochLength();
}
/// @dev Get current lock period for a worker which is equal to one epoch
function lockPeriod() public view returns (uint128) {
return router.networkController().epochLength();
}
function nextWorkerId() external view returns (uint256) {
return workerIdTracker + 1;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
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 value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` 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 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
pragma solidity ^0.8.20;
/**
* @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 is the index of the value in the `values` array plus 1.
// Position 0 is used to mean a value is not in the set.
mapping(bytes32 value => uint256) _positions;
}
/**
* @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._positions[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 cache the value's position to prevent multiple reads from the same storage slot
uint256 position = set._positions[value];
if (position != 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 valueIndex = position - 1;
uint256 lastIndex = set._values.length - 1;
if (valueIndex != lastIndex) {
bytes32 lastValue = set._values[lastIndex];
// Move the lastValue to the index where the value to delete is
set._values[valueIndex] = lastValue;
// Update the tracked position of the lastValue (that was just moved)
set._positions[lastValue] = position;
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the tracked position for the deleted slot
delete set._positions[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._positions[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: GPL-3.0-only
pragma solidity 0.8.20;
interface INetworkController {
/// @dev Emitted when epoch length is updated
event EpochLengthUpdated(uint128 epochLength);
/// @dev Emitted when bond amount is updated
event BondAmountUpdated(uint256 bondAmount);
/// @dev Emitted when storage per worker is updated
event StoragePerWorkerInGbUpdated(uint128 storagePerWorkerInGb);
event StakingDeadlockUpdated(uint256 stakingDeadlock);
event AllowedVestedTargetUpdated(address target, bool isAllowed);
event TargetCapacityUpdated(uint256 target);
event RewardCoefficientUpdated(uint256 coefficient);
/// @dev Amount of blocks in one epoch
function epochLength() external view returns (uint128);
/// @dev Amount of tokens required to register a worker
function bondAmount() external view returns (uint256);
/// @dev Block when next epoch starts
function nextEpoch() external view returns (uint128);
/// @dev Number of current epoch (starting from 0 when contract is deployed)
function epochNumber() external view returns (uint128);
/// @dev Number of unrewarded epochs after which staking will be blocked
function stakingDeadlock() external view returns (uint256);
/// @dev Number of current epoch (starting from 0 when contract is deployed)
function targetCapacityGb() external view returns (uint256);
/// @dev Amount of storage in GB each worker is expected to provide
function storagePerWorkerInGb() external view returns (uint128);
/// @dev Can the `target` be used as a called by the vesting contract
function isAllowedVestedTarget(address target) external view returns (bool);
/// @dev Max part of initial reward pool that can be allocated during a year, in basis points
/// example: 3000 will mean that on each epoch, max 30% of the initial pool * epoch length / 1 year can be allocated
function yearlyRewardCapCoefficient() external view returns (uint256);
}// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.20;
interface IStaking {
struct StakerRewards {
/// @dev the sum of (amount_i / totalStaked_i) for each distribution of amount_i when totalStaked_i was staked
uint256 cumulatedRewardsPerShare;
/// @dev the value of cumulatedRewardsPerShare when the user's last action was performed (deposit or withdraw)
mapping(address staker => uint256) checkpoint;
/// @dev the amount of tokens staked by the user
mapping(address staker => uint256) depositAmount;
/// @dev block from which withdraw is allowed for staker
mapping(address staker => uint128) withdrawAllowed;
/// @dev the total amount of tokens staked
uint256 totalStaked;
}
/// @dev Emitted when rewards where distributed by the distributor
event Distributed(uint256 epoch);
/// @dev Emitted when a staker delegates amount to the worker
event Deposited(uint256 indexed worker, address indexed staker, uint256 amount);
/// @dev Emitted when a staker undelegates amount to the worker
event Withdrawn(uint256 indexed worker, address indexed staker, uint256 amount);
/// @dev Emitted when new claimable reward arrives
event Rewarded(uint256 indexed workerId, address indexed staker, uint256 amount);
/// @dev Emitted when a staker claims rewards
event Claimed(address indexed staker, uint256 amount, uint256[] workerIds);
/// @dev Emitted when max delegations is changed
event EpochsLockChanged(uint128 epochsLock);
event MaxDelegationsChanged(uint256 maxDelegations);
/// @dev Deposit amount of tokens in favour of a worker
/// @param worker workerId in WorkerRegistration contract
/// @param amount amount of tokens to deposit
function deposit(uint256 worker, uint256 amount) external;
/// @dev Withdraw amount of tokens staked in favour of a worker
/// @param worker workerId in WorkerRegistration contract
/// @param amount amount of tokens to withdraw
function withdraw(uint256 worker, uint256 amount) external;
/// @dev Claim rewards for a staker
/// @return amount of tokens claimed
function claim(address staker) external returns (uint256);
/// @return claimable amount
/// MUST return same value as claim(address staker) but without modifying state
function claimable(address staker) external view returns (uint256);
/// @dev total staked amount for the worker
function delegated(uint256 worker) external view returns (uint256);
/// @dev Distribute tokens to stakers in favour of a worker
/// @param workers array of workerIds in WorkerRegistration contract
/// @param amounts array of amounts of tokens to distribute for i-th worker
function distribute(uint256[] calldata workers, uint256[] calldata amounts) external;
}// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.20;
interface IWorkerRegistration {
/// @dev Emitted when a worker is registered
event WorkerRegistered(
uint256 indexed workerId, bytes peerId, address indexed registrar, uint256 registeredAt, string metadata
);
/// @dev Emitted when a worker is deregistered
event WorkerDeregistered(uint256 indexed workerId, address indexed account, uint256 deregistedAt);
/// @dev Emitted when the bond is withdrawn
event WorkerWithdrawn(uint256 indexed workerId, address indexed account);
/// @dev Emitted when a excessive bond is withdrawn
event ExcessiveBondReturned(uint256 indexed workerId, uint256 amount);
/// @dev Emitted when metadata is updated
event MetadataUpdated(uint256 indexed workerId, string metadata);
function register(bytes calldata peerId, string calldata metadata) external;
/// @return The number of active workers.
function getActiveWorkerCount() external view returns (uint256);
function getActiveWorkerIds() external view returns (uint256[] memory);
/// @return The ids of all worker created by the owner account
function getOwnedWorkers(address who) external view returns (uint256[] memory);
function nextWorkerId() external view returns (uint256);
function isWorkerActive(uint256 workerId) external view returns (bool);
}// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.20;
import "./IWorkerRegistration.sol";
import "./IStaking.sol";
import "./INetworkController.sol";
import "./IRewardCalculation.sol";
interface IRouter {
function workerRegistration() external view returns (IWorkerRegistration);
function staking() external view returns (IStaking);
function rewardTreasury() external view returns (address);
function networkController() external view returns (INetworkController);
function rewardCalculation() external view returns (IRewardCalculation);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import "@openzeppelin/contracts/utils/Pausable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
/// @dev abstract contract that allows wallets with special pauser role to pause contracts
abstract contract AccessControlledPausable is Pausable, AccessControl {
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
constructor() {
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(PAUSER_ROLE, msg.sender);
}
function pause() public virtual onlyRole(PAUSER_ROLE) {
_pause();
}
function unpause() public virtual onlyRole(PAUSER_ROLE) {
_unpause();
}
}// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.20;
interface IRewardCalculation {
function currentApy() external view returns (uint256);
function boostFactor(uint256 duration) external pure returns (uint256);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
bool private _paused;
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
/**
* @dev The operation failed because the contract is paused.
*/
error EnforcedPause();
/**
* @dev The operation failed because the contract is not paused.
*/
error ExpectedPause();
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
if (paused()) {
revert EnforcedPause();
}
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
if (!paused()) {
revert ExpectedPause();
}
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)
pragma solidity ^0.8.20;
import {IAccessControl} from "./IAccessControl.sol";
import {Context} from "../utils/Context.sol";
import {ERC165} from "../utils/introspection/ERC165.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```solidity
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```solidity
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
* to enforce additional security measures for this role.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address account => bool) hasRole;
bytes32 adminRole;
}
mapping(bytes32 role => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with an {AccessControlUnauthorizedAccount} error including the required role.
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view virtual returns (bool) {
return _roles[role].hasRole[account];
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
* is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
* is missing `role`.
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert AccessControlUnauthorizedAccount(account, role);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleGranted} event.
*/
function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleRevoked} event.
*/
function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address callerConfirmation) public virtual {
if (callerConfirmation != _msgSender()) {
revert AccessControlBadConfirmation();
}
_revokeRole(role, callerConfirmation);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
if (!hasRole(role, account)) {
_roles[role].hasRole[account] = true;
emit RoleGranted(role, account, _msgSender());
return true;
} else {
return false;
}
}
/**
* @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
if (hasRole(role, account)) {
_roles[role].hasRole[account] = false;
emit RoleRevoked(role, account, _msgSender());
return true;
} else {
return false;
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol)
pragma solidity ^0.8.20;
/**
* @dev External interface of AccessControl declared to support ERC-165 detection.
*/
interface IAccessControl {
/**
* @dev The `account` is missing a role.
*/
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
/**
* @dev The caller of a function is not the expected one.
*
* NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
*/
error AccessControlBadConfirmation();
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {AccessControl-_setupRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*/
function renounceRole(bytes32 role, address callerConfirmation) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"remappings": [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"openzeppelin-contracts/contracts/=lib/openzeppelin-contracts/contracts/",
"@prb/math/=lib/prb-math/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"@prb/test/=lib/prb-math/node_modules/@prb/test/",
"ds-test/=lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"prb-math/=lib/prb-math/src/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "shanghai",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IERC20","name":"_SQD","type":"address"},{"internalType":"contract IRouter","name":"_router","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"workerId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ExcessiveBondReturned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"workerId","type":"uint256"},{"indexed":false,"internalType":"string","name":"metadata","type":"string"}],"name":"MetadataUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"workerId","type":"uint256"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"deregistedAt","type":"uint256"}],"name":"WorkerDeregistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"workerId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"peerId","type":"bytes"},{"indexed":true,"internalType":"address","name":"registrar","type":"address"},{"indexed":false,"internalType":"uint256","name":"registeredAt","type":"uint256"},{"indexed":false,"internalType":"string","name":"metadata","type":"string"}],"name":"WorkerRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"workerId","type":"uint256"},{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"WorkerWithdrawn","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SQD","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bondAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"peerId","type":"bytes"}],"name":"deregister","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"epochLength","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getActiveWorkerCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getActiveWorkerIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getActiveWorkers","outputs":[{"components":[{"internalType":"address","name":"creator","type":"address"},{"internalType":"bytes","name":"peerId","type":"bytes"},{"internalType":"uint256","name":"bond","type":"uint256"},{"internalType":"uint128","name":"registeredAt","type":"uint128"},{"internalType":"uint128","name":"deregisteredAt","type":"uint128"},{"internalType":"string","name":"metadata","type":"string"}],"internalType":"struct WorkerRegistration.Worker[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllWorkersCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"peerId","type":"bytes"}],"name":"getMetadata","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"getOwnedWorkers","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"workerId","type":"uint256"}],"name":"getWorker","outputs":[{"components":[{"internalType":"address","name":"creator","type":"address"},{"internalType":"bytes","name":"peerId","type":"bytes"},{"internalType":"uint256","name":"bond","type":"uint256"},{"internalType":"uint128","name":"registeredAt","type":"uint128"},{"internalType":"uint128","name":"deregisteredAt","type":"uint128"},{"internalType":"string","name":"metadata","type":"string"}],"internalType":"struct WorkerRegistration.Worker","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"workerId","type":"uint256"}],"name":"isWorkerActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockPeriod","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextEpoch","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextWorkerId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"peerId","type":"bytes"}],"name":"register","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"peerId","type":"bytes"},{"internalType":"string","name":"metadata","type":"string"}],"name":"register","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"peerId","type":"bytes"}],"name":"returnExcessiveBond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"contract IRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"peerId","type":"bytes"},{"internalType":"string","name":"metadata","type":"string"}],"name":"updateMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"peerId","type":"bytes"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"peerId","type":"bytes"}],"name":"workerIds","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"workers","outputs":[{"internalType":"address","name":"creator","type":"address"},{"internalType":"bytes","name":"peerId","type":"bytes"},{"internalType":"uint256","name":"bond","type":"uint256"},{"internalType":"uint128","name":"registeredAt","type":"uint128"},{"internalType":"uint128","name":"deregisteredAt","type":"uint128"},{"internalType":"string","name":"metadata","type":"string"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60c060405234801562000010575f80fd5b50604051620029393803806200293983398101604081905262000033916200013a565b5f805460ff191681556200004890336200008e565b50620000757f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a336200008e565b506001600160a01b039182166080521660a05262000177565b5f8281526001602090815260408083206001600160a01b038516845290915281205460ff1662000119575f8381526001602081815260408084206001600160a01b0387168086529252808420805460ff19169093179092559051339286917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45060016200011c565b505f5b92915050565b6001600160a01b038116811462000137575f80fd5b50565b5f80604083850312156200014c575f80fd5b8251620001598162000122565b60208401519092506200016c8162000122565b809150509250929050565b60805160a051612776620001c35f395f81816104c601528181610b5c01528181610d49015261147901525f81816102e9015281816106ff015281816111eb015261194a01526127765ff3fe608060405234801561000f575f80fd5b50600436106101fd575f3560e01c80638456cb5911610114578063c0a0d6cf116100a9578063e4e3369211610079578063e4e3369214610462578063e63ab1e914610475578063f1a22dc21461049c578063f887ea40146104c1578063f905aaf6146104e8575f80fd5b8063c0a0d6cf1461042c578063c84a492214610434578063d547741f1461043c578063ddc651c31461044f575f80fd5b8063a39dbdb9116100e4578063a39dbdb9146103de578063aea0e78b146103fe578063b036482f14610406578063b4d0a56414610419575f80fd5b80638456cb59146103a957806391d14854146103b157806392255fbf146103c4578063a217fddf146103d7575f80fd5b80633fd8b02f1161019557806375734be81161016557806375734be81461032357806375b80f11146103435780637a39cb2b1461036357806380f323a71461038e57806382fbdc9c14610396575f80fd5b80633fd8b02f146102ba57806357d775f8146102ba5780635c975abb146102da5780636aa54679146102e4575f80fd5b806336568abe116101d057806336568abe14610282578063393bc3d9146102955780633e556827146102aa5780633f4ba83a146102b2575f80fd5b806301ffc9a7146102015780630968f26414610229578063248a9ca31461023e5780632f2ff15d1461026f575b5f80fd5b61021461020f366004611fe5565b6104f0565b60405190151581526020015b60405180910390f35b61023c610237366004612051565b610526565b005b61026161024c366004612090565b5f908152600160208190526040909120015490565b604051908152602001610220565b61023c61027d3660046120bb565b6107a5565b61023c6102903660046120bb565b6107d0565b61029d610808565b60405161022091906121a1565b610261610aa0565b61023c610b24565b6102c2610b59565b6040516001600160801b039091168152602001610220565b5f5460ff16610214565b61030b7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610220565b610336610331366004612051565b610c3e565b6040516102209190612201565b610356610351366004612213565b610d23565b604051610220919061222e565b6102616103713660046122f8565b805160208183018101805160048252928201919093012091525481565b610261610d46565b61023c6103a4366004612051565b610e26565b61023c610e43565b6102146103bf3660046120bb565b610e75565b61023c6103d2366004612345565b610e9f565b6102615f81565b6103f16103ec366004612090565b6112c3565b60405161022091906123bc565b6102c2611476565b610214610414366004612090565b611532565b61023c610427366004612051565b611548565b610356611694565b61026161177c565b61023c61044a3660046120bb565b61178c565b61023c61045d366004612345565b6117b1565b61023c610470366004612051565b61186f565b6102617f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b6104af6104aa366004612090565b6119fe565b604051610220969594939291906123ce565b61030b7f000000000000000000000000000000000000000000000000000000000000000081565b610261611b5c565b5f6001600160e01b03198216637965db0b60e01b148061052057506301ffc9a760e01b6001600160e01b03198316145b92915050565b61052e611b67565b5f6004838360405161054192919061242e565b9081526020016040518091039020549050805f0361057a5760405162461bcd60e51b81526004016105719061243d565b60405180910390fd5b5f81815260036020526040902061059081611b8c565b156105d05760405162461bcd60e51b815260206004820152601060248201526f576f726b65722069732061637469766560801b6044820152606401610571565b80546001600160a01b031633146105f95760405162461bcd60e51b81526004016105719061246c565b6003810154600160801b90046001600160801b03161580159061064b575061061f610b59565b600382015461063e9190600160801b90046001600160801b03166124ac565b6001600160801b03164310155b61068a5760405162461bcd60e51b815260206004820152601060248201526f15dbdc9ad95c881a5cc81b1bd8dad95960821b6044820152606401610571565b610695600583611bf7565b5060028101545f83815260036020526040812080546001600160a01b0319168155906106c46001830182611f9b565b5f60028301819055600383018190556106e1906004840190611f9b565b505060405163a9059cbb60e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb906044016020604051808303815f875af115801561074d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061077191906124cc565b50604051339084907fb6ee3a0ef8982f0f296a13a075fe56e5fd8c1bc2282a3c5b54f12d514ed7a956905f90a35050505050565b5f82815260016020819052604090912001546107c081611c09565b6107ca8383611c13565b50505050565b6001600160a01b03811633146107f95760405163334bd91960e11b815260040160405180910390fd5b6108038282611c89565b505050565b60605f610813610aa0565b67ffffffffffffffff81111561082b5761082b612271565b60405190808252806020026020018201604052801561088c57816020015b6040805160c0810182525f808252606060208301819052928201819052828201819052608082015260a08101919091528152602001906001900390816108495790505b5090505f61089a6005611cf4565b90505f805b8251811015610a97575f8382815181106108bb576108bb6124eb565b602002602001015190505f60035f8381526020019081526020015f2090506108e281611b8c565b15610a82576040805160c0810190915281546001600160a01b0316815260018201805483916020840191610915906124ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610941906124ff565b801561098c5780601f106109635761010080835404028352916020019161098c565b820191905f5260205f20905b81548152906001019060200180831161096f57829003601f168201915b50505091835250506002820154602082015260038201546001600160801b038082166040840152600160801b9091041660608201526004820180546080909201916109d6906124ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610a02906124ff565b8015610a4d5780601f10610a2457610100808354040283529160200191610a4d565b820191905f5260205f20905b815481529060010190602001808311610a3057829003601f168201915b505050505081525050868581518110610a6857610a686124eb565b60200260200101819052508380610a7e90612537565b9450505b50508080610a8f90612537565b91505061089f565b50919392505050565b5f8080610aad6005611cf4565b90505f5b8151811015610b1c575f828281518110610acd57610acd6124eb565b602002602001015190505f60035f8381526020019081526020015f209050610af481611b8c565b15610b075784610b0381612537565b9550505b50508080610b1490612537565b915050610ab1565b509092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610b4e81611c09565b610b56611d00565b50565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663853b97c26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bda919061254f565b6001600160a01b03166357d775f86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c15573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c39919061256a565b905090565b60605f60048484604051610c5392919061242e565b9081526020016040518091039020549050805f03610c835760405162461bcd60e51b81526004016105719061243d565b5f8181526003602052604090206004018054610c9e906124ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610cca906124ff565b8015610d155780601f10610cec57610100808354040283529160200191610d15565b820191905f5260205f20905b815481529060010190602001808311610cf857829003601f168201915b505050505091505092915050565b6001600160a01b0381165f90815260076020526040902060609061052090611cf4565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663853b97c26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610da3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610dc7919061254f565b6001600160a01b03166380f323a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e02573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c399190612590565b610e3f828260405180602001604052805f815250610e9f565b5050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610e6d81611c09565b610b56611d51565b5f9182526001602090815260408084206001600160a01b0393909316845291905290205460ff1690565b610ea7611b67565b6040821115610eec5760405162461bcd60e51b81526020600482015260116024820152705065657220494420746f6f206c6172676560781b6044820152606401610571565b5f60048484604051610eff92919061242e565b9081526020016040518091039020545f1461105d5760035f60048686604051610f2992919061242e565b908152604080516020928190038301902054835290820192909252015f20600301546001600160801b031615610f995760405162461bcd60e51b8152602060048201526015602482015274576f726b657220616c72656164792065786973747360581b6044820152606401610571565b610fd260048585604051610fae92919061242e565b908152604080516020928190038301902054335f9081526007909352912090611d8d565b6110355760405162461bcd60e51b815260206004820152602e60248201527f576f726b657220616c726561647920726567697374657265642062792064696660448201526d19995c995b9d081858d8dbdd5b9d60921b6064820152608401610571565b6004848460405161104792919061242e565b9081526020016040518091039020549050611077565b60028054905f61106c83612537565b919050555060025490505b5f611080610d46565b90506040518060c00160405280336001600160a01b0316815260200186868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250505090825250602081018390526040016110e6611476565b6001600160801b031681525f6020808301829052604092830187905285825260038152919020825181546001600160a01b0319166001600160a01b0390911617815590820151600182019061113b90826125f4565b5060408201516002820155606082015160808301516001600160801b03908116600160801b02911617600382015560a0820151600482019061117d90826125f4565b50905050816004868660405161119492919061242e565b908152604051908190036020019020556111af600583611da4565b50335f9081526007602052604090206111c89083611da4565b506040516323b872dd60e01b8152336004820152306024820152604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906323b872dd906064016020604051808303815f875af1158015611239573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061125d91906124cc565b505f8281526003602081905260409182902001549051339184917fa7a0c37f13c7accf7ec7771a2531c06e0183a37162a8e036039b241eab784156916112b4918a918a916001600160801b03909116908a906126b0565b60405180910390a35050505050565b6040805160c0810182525f808252606060208301819052928201819052828201819052608082015260a08101919091525f82815260036020908152604091829020825160c0810190935280546001600160a01b03168352600181018054919284019161132e906124ff565b80601f016020809104026020016040519081016040528092919081815260200182805461135a906124ff565b80156113a55780601f1061137c576101008083540402835291602001916113a5565b820191905f5260205f20905b81548152906001019060200180831161138857829003601f168201915b50505091835250506002820154602082015260038201546001600160801b038082166040840152600160801b9091041660608201526004820180546080909201916113ef906124ff565b80601f016020809104026020016040519081016040528092919081815260200182805461141b906124ff565b80156114665780601f1061143d57610100808354040283529160200191611466565b820191905f5260205f20905b81548152906001019060200180831161144957829003601f168201915b5050505050815250509050919050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663853b97c26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114f7919061254f565b6001600160a01b031663aea0e78b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c15573d5f803e3d5ffd5b5f81815260036020526040812061052090611b8c565b611550611b67565b5f6004838360405161156392919061242e565b9081526020016040518091039020549050805f036115935760405162461bcd60e51b81526004016105719061243d565b5f8181526003602052604090206115a990611b8c565b6115e95760405162461bcd60e51b8152602060048201526011602482015270576f726b6572206e6f742061637469766560781b6044820152606401610571565b5f818152600360205260409020546001600160a01b0316331461161e5760405162461bcd60e51b81526004016105719061246c565b611626611476565b5f8281526003602081815260409283902090910180546001600160801b03908116600160801b9582168602179182905592519390049091168252339183917f4a7ca6c9178181481ac5c6e9ed0965213ae489c4aaf53323bd5e1f318a9d77c3910160405180910390a3505050565b60605f61169f610aa0565b67ffffffffffffffff8111156116b7576116b7612271565b6040519080825280602002602001820160405280156116e0578160200160208202803683370190505b5090505f6116ee6005611cf4565b90505f805b8251811015610a97575f83828151811061170f5761170f6124eb565b602002602001015190505f60035f8381526020019081526020015f20905061173681611b8c565b15611767578186858151811061174e5761174e6124eb565b60209081029190910101528361176381612537565b9450505b5050808061177490612537565b9150506116f3565b5f6002546001610c399190612706565b5f82815260016020819052604090912001546117a781611c09565b6107ca8383611c89565b6117b9611b67565b5f600484846040516117cc92919061242e565b90815260408051918290036020908101909220545f81815260039093529120549091506001600160a01b031633146118165760405162461bcd60e51b81526004016105719061246c565b5f81815260036020526040902060040161183083826125f4565b50807f459157ba24c7ab9878b165ef465fa6ae2ab42bcd8445f576be378768b0c47309836040516118619190612201565b60405180910390a250505050565b611877611b67565b5f6004838360405161188a92919061242e565b9081526020016040518091039020549050805f036118ba5760405162461bcd60e51b81526004016105719061243d565b5f818152600360205260409020546001600160a01b031633146118ef5760405162461bcd60e51b81526004016105719061246c565b5f6118f8610d46565b5f8381526003602052604081206002015491925090611918908390612719565b5f84815260036020526040908190206002018490555163a9059cbb60e01b8152336004820152602481018290529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb906044016020604051808303815f875af1158015611998573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119bc91906124cc565b50827f54ebfb2891f338e31ae38698df33da34d539ea1aa57fa0a1900a3b9d845d4f54826040516119ef91815260200190565b60405180910390a25050505050565b60036020525f9081526040902080546001820180546001600160a01b039092169291611a29906124ff565b80601f0160208091040260200160405190810160405280929190818152602001828054611a55906124ff565b8015611aa05780601f10611a7757610100808354040283529160200191611aa0565b820191905f5260205f20905b815481529060010190602001808311611a8357829003601f168201915b50505060028401546003850154600486018054959692956001600160801b038084169650600160801b909304909216935090611adb906124ff565b80601f0160208091040260200160405190810160405280929190818152602001828054611b07906124ff565b8015611b525780601f10611b2957610100808354040283529160200191611b52565b820191905f5260205f20905b815481529060010190602001808311611b3557829003601f168201915b5050505050905086565b5f610c396005611daf565b5f5460ff1615611b8a5760405163d93c066560e01b815260040160405180910390fd5b565b60038101545f906001600160801b031615801590611bb957506003820154436001600160801b0390911611155b801561052057506003820154600160801b90046001600160801b031615806105205750506003015443600160801b9091046001600160801b03161190565b5f611c028383611db8565b9392505050565b610b568133611ea2565b5f611c1e8383610e75565b611c82575f8381526001602081815260408084206001600160a01b0387168086529252808420805460ff19169093179092559051339286917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a4506001610520565b505f610520565b5f611c948383610e75565b15611c82575f8381526001602090815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4506001610520565b60605f611c0283611edb565b611d08611f34565b5f805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b611d59611b67565b5f805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611d343390565b5f8181526001830160205260408120541515611c02565b5f611c028383611f56565b5f610520825490565b5f8181526001830160205260408120548015611e92575f611dda600183612719565b85549091505f90611ded90600190612719565b9050808214611e4c575f865f018281548110611e0b57611e0b6124eb565b905f5260205f200154905080875f018481548110611e2b57611e2b6124eb565b5f918252602080832090910192909255918252600188019052604090208390555b8554869080611e5d57611e5d61272c565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610520565b5f915050610520565b5092915050565b611eac8282610e75565b610e3f5760405163e2517d3f60e01b81526001600160a01b038216600482015260248101839052604401610571565b6060815f01805480602002602001604051908101604052809291908181526020018280548015611f2857602002820191905f5260205f20905b815481526020019060010190808311611f14575b50505050509050919050565b5f5460ff16611b8a57604051638dfc202b60e01b815260040160405180910390fd5b5f818152600183016020526040812054611c8257508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610520565b508054611fa7906124ff565b5f825580601f10611fb6575050565b601f0160209004905f5260205f2090810190610b5691905b80821115611fe1575f8155600101611fce565b5090565b5f60208284031215611ff5575f80fd5b81356001600160e01b031981168114611c02575f80fd5b5f8083601f84011261201c575f80fd5b50813567ffffffffffffffff811115612033575f80fd5b60208301915083602082850101111561204a575f80fd5b9250929050565b5f8060208385031215612062575f80fd5b823567ffffffffffffffff811115612078575f80fd5b6120848582860161200c565b90969095509350505050565b5f602082840312156120a0575f80fd5b5035919050565b6001600160a01b0381168114610b56575f80fd5b5f80604083850312156120cc575f80fd5b8235915060208301356120de816120a7565b809150509250929050565b5f81518084525f5b8181101561210d576020818501810151868301820152016120f1565b505f602082860101526020601f19601f83011685010191505092915050565b60018060a01b0381511682525f602082015160c0602085015261215260c08501826120e9565b90506040830151604085015260608301516001600160801b038082166060870152806080860151166080870152505060a083015184820360a086015261219882826120e9565b95945050505050565b5f602080830181845280855180835260408601915060408160051b87010192508387015f5b828110156121f457603f198886030184526121e285835161212c565b945092850192908501906001016121c6565b5092979650505050505050565b602081525f611c0260208301846120e9565b5f60208284031215612223575f80fd5b8135611c02816120a7565b602080825282518282018190525f9190848201906040850190845b8181101561226557835183529284019291840191600101612249565b50909695505050505050565b634e487b7160e01b5f52604160045260245ffd5b5f67ffffffffffffffff8084111561229f5761229f612271565b604051601f8501601f19908116603f011681019082821181831017156122c7576122c7612271565b816040528093508581528686860111156122df575f80fd5b858560208301375f602087830101525050509392505050565b5f60208284031215612308575f80fd5b813567ffffffffffffffff81111561231e575f80fd5b8201601f8101841361232e575f80fd5b61233d84823560208401612285565b949350505050565b5f805f60408486031215612357575f80fd5b833567ffffffffffffffff8082111561236e575f80fd5b61237a8783880161200c565b90955093506020860135915080821115612392575f80fd5b508401601f810186136123a3575f80fd5b6123b286823560208401612285565b9150509250925092565b602081525f611c02602083018461212c565b6001600160a01b038716815260c0602082018190525f906123f1908301886120e9565b604083018790526001600160801b0386811660608501528516608084015282810360a084015261242181856120e9565b9998505050505050505050565b818382375f9101908152919050565b60208082526015908201527415dbdc9ad95c881b9bdd081c9959da5cdd195c9959605a1b604082015260600190565b6020808252601290820152712737ba103bb7b935b2b91031b932b0ba37b960711b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b6001600160801b03818116838216019080821115611e9b57611e9b612498565b5f602082840312156124dc575f80fd5b81518015158114611c02575f80fd5b634e487b7160e01b5f52603260045260245ffd5b600181811c9082168061251357607f821691505b60208210810361253157634e487b7160e01b5f52602260045260245ffd5b50919050565b5f6001820161254857612548612498565b5060010190565b5f6020828403121561255f575f80fd5b8151611c02816120a7565b5f6020828403121561257a575f80fd5b81516001600160801b0381168114611c02575f80fd5b5f602082840312156125a0575f80fd5b5051919050565b601f821115610803575f81815260208120601f850160051c810160208610156125cd5750805b601f850160051c820191505b818110156125ec578281556001016125d9565b505050505050565b815167ffffffffffffffff81111561260e5761260e612271565b6126228161261c84546124ff565b846125a7565b602080601f831160018114612655575f841561263e5750858301515b5f19600386901b1c1916600185901b1785556125ec565b5f85815260208120601f198616915b8281101561268357888601518255948401946001909101908401612664565b50858210156126a057878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b60608152836060820152838560808301375f608085830101525f601f19601f86011682016001600160801b038516602084015260808382030160408401526126fb60808201856120e9565b979650505050505050565b8082018082111561052057610520612498565b8181038181111561052057610520612498565b634e487b7160e01b5f52603160045260245ffdfea264697066735822122080d9e0a82d70901d1b1884fded598f76a0deb940b10bf74dfd1b15ff0fb90def64736f6c634300081400330000000000000000000000001337420ded5adb9980cfc35f8f2b054ea86f8ab100000000000000000000000067f56d27dab93eeb07f6372274aca277f49da941
Deployed Bytecode
0x608060405234801561000f575f80fd5b50600436106101fd575f3560e01c80638456cb5911610114578063c0a0d6cf116100a9578063e4e3369211610079578063e4e3369214610462578063e63ab1e914610475578063f1a22dc21461049c578063f887ea40146104c1578063f905aaf6146104e8575f80fd5b8063c0a0d6cf1461042c578063c84a492214610434578063d547741f1461043c578063ddc651c31461044f575f80fd5b8063a39dbdb9116100e4578063a39dbdb9146103de578063aea0e78b146103fe578063b036482f14610406578063b4d0a56414610419575f80fd5b80638456cb59146103a957806391d14854146103b157806392255fbf146103c4578063a217fddf146103d7575f80fd5b80633fd8b02f1161019557806375734be81161016557806375734be81461032357806375b80f11146103435780637a39cb2b1461036357806380f323a71461038e57806382fbdc9c14610396575f80fd5b80633fd8b02f146102ba57806357d775f8146102ba5780635c975abb146102da5780636aa54679146102e4575f80fd5b806336568abe116101d057806336568abe14610282578063393bc3d9146102955780633e556827146102aa5780633f4ba83a146102b2575f80fd5b806301ffc9a7146102015780630968f26414610229578063248a9ca31461023e5780632f2ff15d1461026f575b5f80fd5b61021461020f366004611fe5565b6104f0565b60405190151581526020015b60405180910390f35b61023c610237366004612051565b610526565b005b61026161024c366004612090565b5f908152600160208190526040909120015490565b604051908152602001610220565b61023c61027d3660046120bb565b6107a5565b61023c6102903660046120bb565b6107d0565b61029d610808565b60405161022091906121a1565b610261610aa0565b61023c610b24565b6102c2610b59565b6040516001600160801b039091168152602001610220565b5f5460ff16610214565b61030b7f0000000000000000000000001337420ded5adb9980cfc35f8f2b054ea86f8ab181565b6040516001600160a01b039091168152602001610220565b610336610331366004612051565b610c3e565b6040516102209190612201565b610356610351366004612213565b610d23565b604051610220919061222e565b6102616103713660046122f8565b805160208183018101805160048252928201919093012091525481565b610261610d46565b61023c6103a4366004612051565b610e26565b61023c610e43565b6102146103bf3660046120bb565b610e75565b61023c6103d2366004612345565b610e9f565b6102615f81565b6103f16103ec366004612090565b6112c3565b60405161022091906123bc565b6102c2611476565b610214610414366004612090565b611532565b61023c610427366004612051565b611548565b610356611694565b61026161177c565b61023c61044a3660046120bb565b61178c565b61023c61045d366004612345565b6117b1565b61023c610470366004612051565b61186f565b6102617f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b6104af6104aa366004612090565b6119fe565b604051610220969594939291906123ce565b61030b7f00000000000000000000000067f56d27dab93eeb07f6372274aca277f49da94181565b610261611b5c565b5f6001600160e01b03198216637965db0b60e01b148061052057506301ffc9a760e01b6001600160e01b03198316145b92915050565b61052e611b67565b5f6004838360405161054192919061242e565b9081526020016040518091039020549050805f0361057a5760405162461bcd60e51b81526004016105719061243d565b60405180910390fd5b5f81815260036020526040902061059081611b8c565b156105d05760405162461bcd60e51b815260206004820152601060248201526f576f726b65722069732061637469766560801b6044820152606401610571565b80546001600160a01b031633146105f95760405162461bcd60e51b81526004016105719061246c565b6003810154600160801b90046001600160801b03161580159061064b575061061f610b59565b600382015461063e9190600160801b90046001600160801b03166124ac565b6001600160801b03164310155b61068a5760405162461bcd60e51b815260206004820152601060248201526f15dbdc9ad95c881a5cc81b1bd8dad95960821b6044820152606401610571565b610695600583611bf7565b5060028101545f83815260036020526040812080546001600160a01b0319168155906106c46001830182611f9b565b5f60028301819055600383018190556106e1906004840190611f9b565b505060405163a9059cbb60e01b8152336004820152602481018290527f0000000000000000000000001337420ded5adb9980cfc35f8f2b054ea86f8ab16001600160a01b03169063a9059cbb906044016020604051808303815f875af115801561074d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061077191906124cc565b50604051339084907fb6ee3a0ef8982f0f296a13a075fe56e5fd8c1bc2282a3c5b54f12d514ed7a956905f90a35050505050565b5f82815260016020819052604090912001546107c081611c09565b6107ca8383611c13565b50505050565b6001600160a01b03811633146107f95760405163334bd91960e11b815260040160405180910390fd5b6108038282611c89565b505050565b60605f610813610aa0565b67ffffffffffffffff81111561082b5761082b612271565b60405190808252806020026020018201604052801561088c57816020015b6040805160c0810182525f808252606060208301819052928201819052828201819052608082015260a08101919091528152602001906001900390816108495790505b5090505f61089a6005611cf4565b90505f805b8251811015610a97575f8382815181106108bb576108bb6124eb565b602002602001015190505f60035f8381526020019081526020015f2090506108e281611b8c565b15610a82576040805160c0810190915281546001600160a01b0316815260018201805483916020840191610915906124ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610941906124ff565b801561098c5780601f106109635761010080835404028352916020019161098c565b820191905f5260205f20905b81548152906001019060200180831161096f57829003601f168201915b50505091835250506002820154602082015260038201546001600160801b038082166040840152600160801b9091041660608201526004820180546080909201916109d6906124ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610a02906124ff565b8015610a4d5780601f10610a2457610100808354040283529160200191610a4d565b820191905f5260205f20905b815481529060010190602001808311610a3057829003601f168201915b505050505081525050868581518110610a6857610a686124eb565b60200260200101819052508380610a7e90612537565b9450505b50508080610a8f90612537565b91505061089f565b50919392505050565b5f8080610aad6005611cf4565b90505f5b8151811015610b1c575f828281518110610acd57610acd6124eb565b602002602001015190505f60035f8381526020019081526020015f209050610af481611b8c565b15610b075784610b0381612537565b9550505b50508080610b1490612537565b915050610ab1565b509092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610b4e81611c09565b610b56611d00565b50565b5f7f00000000000000000000000067f56d27dab93eeb07f6372274aca277f49da9416001600160a01b031663853b97c26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bda919061254f565b6001600160a01b03166357d775f86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c15573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c39919061256a565b905090565b60605f60048484604051610c5392919061242e565b9081526020016040518091039020549050805f03610c835760405162461bcd60e51b81526004016105719061243d565b5f8181526003602052604090206004018054610c9e906124ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610cca906124ff565b8015610d155780601f10610cec57610100808354040283529160200191610d15565b820191905f5260205f20905b815481529060010190602001808311610cf857829003601f168201915b505050505091505092915050565b6001600160a01b0381165f90815260076020526040902060609061052090611cf4565b5f7f00000000000000000000000067f56d27dab93eeb07f6372274aca277f49da9416001600160a01b031663853b97c26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610da3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610dc7919061254f565b6001600160a01b03166380f323a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e02573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c399190612590565b610e3f828260405180602001604052805f815250610e9f565b5050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610e6d81611c09565b610b56611d51565b5f9182526001602090815260408084206001600160a01b0393909316845291905290205460ff1690565b610ea7611b67565b6040821115610eec5760405162461bcd60e51b81526020600482015260116024820152705065657220494420746f6f206c6172676560781b6044820152606401610571565b5f60048484604051610eff92919061242e565b9081526020016040518091039020545f1461105d5760035f60048686604051610f2992919061242e565b908152604080516020928190038301902054835290820192909252015f20600301546001600160801b031615610f995760405162461bcd60e51b8152602060048201526015602482015274576f726b657220616c72656164792065786973747360581b6044820152606401610571565b610fd260048585604051610fae92919061242e565b908152604080516020928190038301902054335f9081526007909352912090611d8d565b6110355760405162461bcd60e51b815260206004820152602e60248201527f576f726b657220616c726561647920726567697374657265642062792064696660448201526d19995c995b9d081858d8dbdd5b9d60921b6064820152608401610571565b6004848460405161104792919061242e565b9081526020016040518091039020549050611077565b60028054905f61106c83612537565b919050555060025490505b5f611080610d46565b90506040518060c00160405280336001600160a01b0316815260200186868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250505090825250602081018390526040016110e6611476565b6001600160801b031681525f6020808301829052604092830187905285825260038152919020825181546001600160a01b0319166001600160a01b0390911617815590820151600182019061113b90826125f4565b5060408201516002820155606082015160808301516001600160801b03908116600160801b02911617600382015560a0820151600482019061117d90826125f4565b50905050816004868660405161119492919061242e565b908152604051908190036020019020556111af600583611da4565b50335f9081526007602052604090206111c89083611da4565b506040516323b872dd60e01b8152336004820152306024820152604481018290527f0000000000000000000000001337420ded5adb9980cfc35f8f2b054ea86f8ab16001600160a01b0316906323b872dd906064016020604051808303815f875af1158015611239573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061125d91906124cc565b505f8281526003602081905260409182902001549051339184917fa7a0c37f13c7accf7ec7771a2531c06e0183a37162a8e036039b241eab784156916112b4918a918a916001600160801b03909116908a906126b0565b60405180910390a35050505050565b6040805160c0810182525f808252606060208301819052928201819052828201819052608082015260a08101919091525f82815260036020908152604091829020825160c0810190935280546001600160a01b03168352600181018054919284019161132e906124ff565b80601f016020809104026020016040519081016040528092919081815260200182805461135a906124ff565b80156113a55780601f1061137c576101008083540402835291602001916113a5565b820191905f5260205f20905b81548152906001019060200180831161138857829003601f168201915b50505091835250506002820154602082015260038201546001600160801b038082166040840152600160801b9091041660608201526004820180546080909201916113ef906124ff565b80601f016020809104026020016040519081016040528092919081815260200182805461141b906124ff565b80156114665780601f1061143d57610100808354040283529160200191611466565b820191905f5260205f20905b81548152906001019060200180831161144957829003601f168201915b5050505050815250509050919050565b5f7f00000000000000000000000067f56d27dab93eeb07f6372274aca277f49da9416001600160a01b031663853b97c26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114f7919061254f565b6001600160a01b031663aea0e78b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c15573d5f803e3d5ffd5b5f81815260036020526040812061052090611b8c565b611550611b67565b5f6004838360405161156392919061242e565b9081526020016040518091039020549050805f036115935760405162461bcd60e51b81526004016105719061243d565b5f8181526003602052604090206115a990611b8c565b6115e95760405162461bcd60e51b8152602060048201526011602482015270576f726b6572206e6f742061637469766560781b6044820152606401610571565b5f818152600360205260409020546001600160a01b0316331461161e5760405162461bcd60e51b81526004016105719061246c565b611626611476565b5f8281526003602081815260409283902090910180546001600160801b03908116600160801b9582168602179182905592519390049091168252339183917f4a7ca6c9178181481ac5c6e9ed0965213ae489c4aaf53323bd5e1f318a9d77c3910160405180910390a3505050565b60605f61169f610aa0565b67ffffffffffffffff8111156116b7576116b7612271565b6040519080825280602002602001820160405280156116e0578160200160208202803683370190505b5090505f6116ee6005611cf4565b90505f805b8251811015610a97575f83828151811061170f5761170f6124eb565b602002602001015190505f60035f8381526020019081526020015f20905061173681611b8c565b15611767578186858151811061174e5761174e6124eb565b60209081029190910101528361176381612537565b9450505b5050808061177490612537565b9150506116f3565b5f6002546001610c399190612706565b5f82815260016020819052604090912001546117a781611c09565b6107ca8383611c89565b6117b9611b67565b5f600484846040516117cc92919061242e565b90815260408051918290036020908101909220545f81815260039093529120549091506001600160a01b031633146118165760405162461bcd60e51b81526004016105719061246c565b5f81815260036020526040902060040161183083826125f4565b50807f459157ba24c7ab9878b165ef465fa6ae2ab42bcd8445f576be378768b0c47309836040516118619190612201565b60405180910390a250505050565b611877611b67565b5f6004838360405161188a92919061242e565b9081526020016040518091039020549050805f036118ba5760405162461bcd60e51b81526004016105719061243d565b5f818152600360205260409020546001600160a01b031633146118ef5760405162461bcd60e51b81526004016105719061246c565b5f6118f8610d46565b5f8381526003602052604081206002015491925090611918908390612719565b5f84815260036020526040908190206002018490555163a9059cbb60e01b8152336004820152602481018290529091507f0000000000000000000000001337420ded5adb9980cfc35f8f2b054ea86f8ab16001600160a01b03169063a9059cbb906044016020604051808303815f875af1158015611998573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119bc91906124cc565b50827f54ebfb2891f338e31ae38698df33da34d539ea1aa57fa0a1900a3b9d845d4f54826040516119ef91815260200190565b60405180910390a25050505050565b60036020525f9081526040902080546001820180546001600160a01b039092169291611a29906124ff565b80601f0160208091040260200160405190810160405280929190818152602001828054611a55906124ff565b8015611aa05780601f10611a7757610100808354040283529160200191611aa0565b820191905f5260205f20905b815481529060010190602001808311611a8357829003601f168201915b50505060028401546003850154600486018054959692956001600160801b038084169650600160801b909304909216935090611adb906124ff565b80601f0160208091040260200160405190810160405280929190818152602001828054611b07906124ff565b8015611b525780601f10611b2957610100808354040283529160200191611b52565b820191905f5260205f20905b815481529060010190602001808311611b3557829003601f168201915b5050505050905086565b5f610c396005611daf565b5f5460ff1615611b8a5760405163d93c066560e01b815260040160405180910390fd5b565b60038101545f906001600160801b031615801590611bb957506003820154436001600160801b0390911611155b801561052057506003820154600160801b90046001600160801b031615806105205750506003015443600160801b9091046001600160801b03161190565b5f611c028383611db8565b9392505050565b610b568133611ea2565b5f611c1e8383610e75565b611c82575f8381526001602081815260408084206001600160a01b0387168086529252808420805460ff19169093179092559051339286917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a4506001610520565b505f610520565b5f611c948383610e75565b15611c82575f8381526001602090815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4506001610520565b60605f611c0283611edb565b611d08611f34565b5f805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b611d59611b67565b5f805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611d343390565b5f8181526001830160205260408120541515611c02565b5f611c028383611f56565b5f610520825490565b5f8181526001830160205260408120548015611e92575f611dda600183612719565b85549091505f90611ded90600190612719565b9050808214611e4c575f865f018281548110611e0b57611e0b6124eb565b905f5260205f200154905080875f018481548110611e2b57611e2b6124eb565b5f918252602080832090910192909255918252600188019052604090208390555b8554869080611e5d57611e5d61272c565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610520565b5f915050610520565b5092915050565b611eac8282610e75565b610e3f5760405163e2517d3f60e01b81526001600160a01b038216600482015260248101839052604401610571565b6060815f01805480602002602001604051908101604052809291908181526020018280548015611f2857602002820191905f5260205f20905b815481526020019060010190808311611f14575b50505050509050919050565b5f5460ff16611b8a57604051638dfc202b60e01b815260040160405180910390fd5b5f818152600183016020526040812054611c8257508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610520565b508054611fa7906124ff565b5f825580601f10611fb6575050565b601f0160209004905f5260205f2090810190610b5691905b80821115611fe1575f8155600101611fce565b5090565b5f60208284031215611ff5575f80fd5b81356001600160e01b031981168114611c02575f80fd5b5f8083601f84011261201c575f80fd5b50813567ffffffffffffffff811115612033575f80fd5b60208301915083602082850101111561204a575f80fd5b9250929050565b5f8060208385031215612062575f80fd5b823567ffffffffffffffff811115612078575f80fd5b6120848582860161200c565b90969095509350505050565b5f602082840312156120a0575f80fd5b5035919050565b6001600160a01b0381168114610b56575f80fd5b5f80604083850312156120cc575f80fd5b8235915060208301356120de816120a7565b809150509250929050565b5f81518084525f5b8181101561210d576020818501810151868301820152016120f1565b505f602082860101526020601f19601f83011685010191505092915050565b60018060a01b0381511682525f602082015160c0602085015261215260c08501826120e9565b90506040830151604085015260608301516001600160801b038082166060870152806080860151166080870152505060a083015184820360a086015261219882826120e9565b95945050505050565b5f602080830181845280855180835260408601915060408160051b87010192508387015f5b828110156121f457603f198886030184526121e285835161212c565b945092850192908501906001016121c6565b5092979650505050505050565b602081525f611c0260208301846120e9565b5f60208284031215612223575f80fd5b8135611c02816120a7565b602080825282518282018190525f9190848201906040850190845b8181101561226557835183529284019291840191600101612249565b50909695505050505050565b634e487b7160e01b5f52604160045260245ffd5b5f67ffffffffffffffff8084111561229f5761229f612271565b604051601f8501601f19908116603f011681019082821181831017156122c7576122c7612271565b816040528093508581528686860111156122df575f80fd5b858560208301375f602087830101525050509392505050565b5f60208284031215612308575f80fd5b813567ffffffffffffffff81111561231e575f80fd5b8201601f8101841361232e575f80fd5b61233d84823560208401612285565b949350505050565b5f805f60408486031215612357575f80fd5b833567ffffffffffffffff8082111561236e575f80fd5b61237a8783880161200c565b90955093506020860135915080821115612392575f80fd5b508401601f810186136123a3575f80fd5b6123b286823560208401612285565b9150509250925092565b602081525f611c02602083018461212c565b6001600160a01b038716815260c0602082018190525f906123f1908301886120e9565b604083018790526001600160801b0386811660608501528516608084015282810360a084015261242181856120e9565b9998505050505050505050565b818382375f9101908152919050565b60208082526015908201527415dbdc9ad95c881b9bdd081c9959da5cdd195c9959605a1b604082015260600190565b6020808252601290820152712737ba103bb7b935b2b91031b932b0ba37b960711b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b6001600160801b03818116838216019080821115611e9b57611e9b612498565b5f602082840312156124dc575f80fd5b81518015158114611c02575f80fd5b634e487b7160e01b5f52603260045260245ffd5b600181811c9082168061251357607f821691505b60208210810361253157634e487b7160e01b5f52602260045260245ffd5b50919050565b5f6001820161254857612548612498565b5060010190565b5f6020828403121561255f575f80fd5b8151611c02816120a7565b5f6020828403121561257a575f80fd5b81516001600160801b0381168114611c02575f80fd5b5f602082840312156125a0575f80fd5b5051919050565b601f821115610803575f81815260208120601f850160051c810160208610156125cd5750805b601f850160051c820191505b818110156125ec578281556001016125d9565b505050505050565b815167ffffffffffffffff81111561260e5761260e612271565b6126228161261c84546124ff565b846125a7565b602080601f831160018114612655575f841561263e5750858301515b5f19600386901b1c1916600185901b1785556125ec565b5f85815260208120601f198616915b8281101561268357888601518255948401946001909101908401612664565b50858210156126a057878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b60608152836060820152838560808301375f608085830101525f601f19601f86011682016001600160801b038516602084015260808382030160408401526126fb60808201856120e9565b979650505050505050565b8082018082111561052057610520612498565b8181038181111561052057610520612498565b634e487b7160e01b5f52603160045260245ffdfea264697066735822122080d9e0a82d70901d1b1884fded598f76a0deb940b10bf74dfd1b15ff0fb90def64736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000001337420ded5adb9980cfc35f8f2b054ea86f8ab100000000000000000000000067f56d27dab93eeb07f6372274aca277f49da941
-----Decoded View---------------
Arg [0] : _SQD (address): 0x1337420dED5ADb9980CFc35f8f2B054ea86f8aB1
Arg [1] : _router (address): 0x67F56D27dab93eEb07f6372274aCa277F49dA941
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000001337420ded5adb9980cfc35f8f2b054ea86f8ab1
Arg [1] : 00000000000000000000000067f56d27dab93eeb07f6372274aca277f49da941
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
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.