Source Code
Overview
ETH Balance
0.2152138 ETH
More Info
ContractCreator
Multichain Info
N/A
Latest 25 from a total of 2,506,016 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
Amount
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Submit Share | 39631296 | 16 days ago | IN | 0.0000001 ETH | 0.00000108 | ||||
| Submit Share | 39631291 | 16 days ago | IN | 0.0000001 ETH | 0.00000095 | ||||
| Submit Share | 39631271 | 16 days ago | IN | 0.0000001 ETH | 0.00000108 | ||||
| Submit Share | 39631266 | 16 days ago | IN | 0.0000001 ETH | 0.00000095 | ||||
| Submit Share | 39631246 | 16 days ago | IN | 0.0000001 ETH | 0.00000108 | ||||
| Submit Share | 39631241 | 16 days ago | IN | 0.0000001 ETH | 0.00000095 | ||||
| Submit Share | 39631218 | 16 days ago | IN | 0.0000001 ETH | 0.00000108 | ||||
| Submit Share | 39631215 | 16 days ago | IN | 0.0000001 ETH | 0.00000095 | ||||
| Submit Share | 39631195 | 16 days ago | IN | 0.0000001 ETH | 0.00000119 | ||||
| Submit Share | 39631190 | 16 days ago | IN | 0.0000001 ETH | 0.00000137 | ||||
| Claim Rewards | 30617424 | 224 days ago | IN | 0 ETH | 0.00000004 | ||||
| Claim Rewards | 30617411 | 224 days ago | IN | 0 ETH | 0.00000005 | ||||
| Claim Rewards | 30617363 | 224 days ago | IN | 0 ETH | 0.00000005 | ||||
| Claim Rewards | 30599087 | 225 days ago | IN | 0 ETH | 0.00000005 | ||||
| Claim Rewards | 30589917 | 225 days ago | IN | 0 ETH | 0.00000004 | ||||
| Submit Share | 30578062 | 225 days ago | IN | 0.0000001 ETH | 0.00000014 | ||||
| Submit Share | 30578052 | 225 days ago | IN | 0.0000001 ETH | 0.00000018 | ||||
| Submit Share | 30578044 | 225 days ago | IN | 0.0000001 ETH | 0.00000018 | ||||
| Submit Share | 30578026 | 225 days ago | IN | 0.0000001 ETH | 0.00000014 | ||||
| Submit Share | 30578025 | 225 days ago | IN | 0.0000001 ETH | 0.00000018 | ||||
| Submit Share | 30578018 | 225 days ago | IN | 0.0000001 ETH | 0.00000022 | ||||
| Submit Share | 30578002 | 225 days ago | IN | 0.0000001 ETH | 0.00000014 | ||||
| Submit Share | 30577998 | 225 days ago | IN | 0.0000001 ETH | 0.00000014 | ||||
| Submit Share | 30577997 | 225 days ago | IN | 0.0000001 ETH | 0.00000014 | ||||
| Submit Share | 30577990 | 225 days ago | IN | 0.0000001 ETH | 0.00000018 |
Loading...
Loading
Contract Name:
HashcashMiningPool
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
// https://x.com/hashcash_base
pragma solidity ^0.8.24;
import "./HashcashToken.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
contract HashcashMiningPool is ReentrancyGuard {
/*=====================================================================
STATE
=====================================================================*/
HashcashToken public token;
address public owner;
uint256 public constant SUBMIT_FEE = 0.0000001 ether;
uint256 public constant TOKEN_DECIMALS = 10**18;
uint256 public constant MAX_SUPPLY = 21_000_000 * TOKEN_DECIMALS;
uint256 public difficulty = 2**245;
bool public miningStarted = false;
bool public roundCompleted = false;
uint256 public batchSize = 500;
bytes32 public challengeNumber;
uint256 public roundNumber;
uint256 public roundStartBlock;
uint256 public constant ROUND_LENGTH = 20;
address[] private currentMinerList;
mapping(address => bool) private isInCurrentMiners;
mapping(address => bool) public hasSubmittedInBlock;
mapping(uint256 => uint256) public minersInRound;
mapping(uint256 => address[]) public batchMiners;
mapping(address => uint256) public pendingRewards;
uint256 public totalMined;
uint256 public submitFeesCollected;
uint256 public currentMinerIndex;
uint256 public residualDust;
mapping(address => uint256) public sharesSubmitted;
/*=====================================================================
EVENTS
=====================================================================*/
event ShareSubmitted (address indexed miner, bytes32 digest, uint256 round);
event BatchMinerAssigned (address indexed miner, uint256 round);
event RewardsAssigned (uint256 mainReward, uint256 bonusReward, uint256 numMiners, uint256 numBatchMiners, uint256 round);
event RoundEnded (uint256 round);
event NewChallenge (bytes32 newChallenge, uint256 round);
event FeeCollected (address indexed from, uint256 amount, string feeType);
event BatchSizeChanged (uint256 newBatchSize);
event RewardsClaimed (address indexed miner, uint256 amount);
event RoundStarted (uint256 round, uint256 startBlock);
event MinerPaid (address indexed miner, uint256 amount);
event BatchMinerPaid (address indexed miner, uint256 amount);
event ShareRejected (address indexed miner, string reason);
event FeesWithdrawn (uint256 amount);
event FirstBatchMinerFullReward(address indexed miner, uint256 round);
event DustCollected(uint256 amount, uint256 round);
event DustWithdrawn(address indexed to, uint256 amount);
modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_;
}
constructor(HashcashToken _token) {
token = _token;
owner = msg.sender;
}
function startMining() external onlyOwner {
require(!miningStarted, "Mining already started");
miningStarted = true;
challengeNumber = blockhash(block.number - 1);
roundStartBlock = block.number;
roundNumber = 1;
emit NewChallenge(challengeNumber, roundNumber);
emit RoundStarted(roundNumber, roundStartBlock);
}
function setDifficulty(uint256 d) external onlyOwner {
require(d > 0, "Invalid diff");
difficulty = d;
}
function setBatchSize(uint256 b) external onlyOwner {
require(b > 0, "batchSize>0");
batchSize = b;
emit BatchSizeChanged(b);
}
function withdrawFees() external onlyOwner {
uint256 bal = address(this).balance;
require(bal > 0, "No ETH");
(bool ok,) = payable(owner).call{value: bal}("");
require(ok, "withdraw failed");
emit FeesWithdrawn(bal);
}
function submitShare(uint256 nonce) external payable nonReentrant {
require(miningStarted, "Mining not started");
require(msg.value == SUBMIT_FEE, "Fee = 0.0001 ETH");
require(totalMined < MAX_SUPPLY, "All tokens mined");
submitFeesCollected += msg.value;
emit FeeCollected(msg.sender, msg.value, "submit");
bytes32 digest = keccak256(abi.encodePacked(challengeNumber, msg.sender, nonce));
if (uint256(digest) >= difficulty) {
emit ShareRejected(msg.sender, "Digest >= difficulty");
revert("Invalid share");
}
bool expired = block.number >= roundStartBlock + ROUND_LENGTH;
if (expired) {
batchMiners[roundNumber].push(msg.sender);
emit BatchMinerAssigned(msg.sender, roundNumber);
_distributeAndReset();
return;
}
require(!hasSubmittedInBlock[msg.sender], "Already submitted in this block");
hasSubmittedInBlock[msg.sender] = true;
if (!isInCurrentMiners[msg.sender]) {
isInCurrentMiners[msg.sender] = true;
currentMinerList.push(msg.sender);
minersInRound[roundNumber]++;
}
sharesSubmitted[msg.sender]++;
emit ShareSubmitted(msg.sender, digest, roundNumber);
}
function _distributeAndReset() internal {
address[] memory minersSnapshot = currentMinerList;
uint256 numMiners = minersSnapshot.length;
address[] storage bMin = batchMiners[roundNumber];
uint256 totalReward = getRoundReward();
if (numMiners == 0 && bMin.length > 0) {
address first = bMin[0];
pendingRewards[first] += totalReward;
totalMined += totalReward;
emit FirstBatchMinerFullReward(first, roundNumber);
emit RewardsAssigned(0, totalReward, 0, bMin.length, roundNumber);
emit RoundEnded(roundNumber);
_advanceRound();
return;
}
if (numMiners == 0) {
emit RoundEnded(roundNumber);
_advanceRound();
return;
}
uint256 mainReward = (totalReward * 95) / 100;
uint256 batchReward = totalReward - mainReward;
uint256 remMain = mainReward % numMiners;
uint256 shareMain = mainReward / numMiners;
uint256 nbatch = bMin.length;
uint256 shareBonus = nbatch > 0 ? batchReward / nbatch : 0;
uint256 remBonus = nbatch > 0 ? batchReward % nbatch : batchReward;
uint256 end = currentMinerIndex + batchSize;
if (end > numMiners) end = numMiners;
for (uint256 i = currentMinerIndex; i < end; i++) {
address m = minersSnapshot[i];
pendingRewards[m] += shareMain;
totalMined += shareMain;
hasSubmittedInBlock[m] = false;
emit MinerPaid(m, shareMain);
}
currentMinerIndex = end;
if (currentMinerIndex >= numMiners && !roundCompleted) {
roundCompleted = true;
if (nbatch > 0) {
for (uint256 j; j < nbatch; j++) {
address bm = bMin[j];
pendingRewards[bm] += shareBonus;
totalMined += shareBonus;
emit BatchMinerPaid(bm, shareBonus);
}
}
residualDust += remMain + remBonus;
emit DustCollected(remMain + remBonus, roundNumber);
// 🔁 Now auto-distribute dust to owner at round end
if (residualDust > 0) {
uint256 dust = residualDust;
residualDust = 0;
token.mint(owner, dust);
emit DustWithdrawn(owner, dust);
}
emit RewardsAssigned(mainReward, batchReward, numMiners, nbatch, roundNumber);
_advanceRound();
}
}
function _advanceRound() internal {
for (uint256 i = 0; i < currentMinerList.length; i++) {
isInCurrentMiners[currentMinerList[i]] = false;
}
delete currentMinerList;
currentMinerIndex = 0;
roundCompleted = false;
roundNumber++;
roundStartBlock = block.number;
challengeNumber = keccak256(abi.encodePacked(challengeNumber, blockhash(block.number - 1)));
emit NewChallenge(challengeNumber, roundNumber);
emit RoundStarted(roundNumber, roundStartBlock);
}
function claimRewards() external nonReentrant {
uint256 amt = pendingRewards[msg.sender];
require(amt > 0, "No rewards");
pendingRewards[msg.sender] = 0;
token.mint(msg.sender, amt);
emit RewardsClaimed(msg.sender, amt);
}
function getRoundReward() public view returns (uint256) {
uint256 mined = totalMined;
if (mined < 5_000_000 * TOKEN_DECIMALS) {
return 200 * TOKEN_DECIMALS;
} else if (mined < 10_000_000 * TOKEN_DECIMALS) {
return 100 * TOKEN_DECIMALS;
} else if (mined < 15_000_000 * TOKEN_DECIMALS) {
return 50 * TOKEN_DECIMALS;
} else if (mined < 20_000_000 * TOKEN_DECIMALS) {
return 25 * TOKEN_DECIMALS;
} else {
return (1225 * TOKEN_DECIMALS) / 100; // 12.25
}
}
function getMinersCount(uint256 r) external view returns (uint256) {
return minersInRound[r];
}
function getBatchMiners(uint256 r) external view returns (address[] memory) {
return batchMiners[r];
}
function getCurrentRound() external view returns (uint256) {
return roundNumber;
}
function getCurrentMiners() external view returns (address[] memory) {
return currentMinerList;
}
function getSharesSubmitted(address miner) external view returns (uint256) {
return sharesSubmitted[miner];
}
function getResidualDust() external view returns (uint256) {
return residualDust;
}
function getDustBalance() external view returns (uint256) {
return residualDust;
}
function withdrawDust() external onlyOwner {
require(residualDust > 0, "No dust to withdraw");
uint256 amount = residualDust;
residualDust = 0;
token.mint(owner, amount);
emit DustWithdrawn(owner, amount);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
* consider using {ReentrancyGuardTransient} instead.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
_status = ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract HashcashToken is ERC20, Ownable {
uint256 public constant MAX_SUPPLY = 21000000 * 10**18;
address public minter;
event MinterChanged(address indexed newMinter);
constructor() ERC20("Hashcash", "HASH") Ownable(msg.sender) {
minter = msg.sender;
}
modifier onlyMinter() {
require(msg.sender == minter, "Caller is not the minter");
_;
}
function setMinter(address _minter) external onlyOwner {
minter = _minter;
emit MinterChanged(_minter);
}
function mint(address to, uint256 amount) external onlyMinter {
require(totalSupply() + amount <= MAX_SUPPLY, "Exceeds max supply");
_mint(to, amount);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "./IERC20.sol";
import {IERC20Metadata} from "./extensions/IERC20Metadata.sol";
import {Context} from "../../utils/Context.sol";
import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC-20
* applications.
*/
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
mapping(address account => uint256) private _balances;
mapping(address account => mapping(address spender => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* Both values are immutable: they can only be set once during construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `value`.
*/
function transfer(address to, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_transfer(owner, to, value);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, value);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Skips emitting an {Approval} event indicating an allowance update. This is not
* required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `value`.
* - the caller must have allowance for ``from``'s tokens of at least
* `value`.
*/
function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, value);
_transfer(from, to, value);
return true;
}
/**
* @dev Moves a `value` amount of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _transfer(address from, address to, uint256 value) internal {
if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}
if (to == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(from, to, value);
}
/**
* @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
* (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
* this function.
*
* Emits a {Transfer} event.
*/
function _update(address from, address to, uint256 value) internal virtual {
if (from == address(0)) {
// Overflow check required: The rest of the code assumes that totalSupply never overflows
_totalSupply += value;
} else {
uint256 fromBalance = _balances[from];
if (fromBalance < value) {
revert ERC20InsufficientBalance(from, fromBalance, value);
}
unchecked {
// Overflow not possible: value <= fromBalance <= totalSupply.
_balances[from] = fromBalance - value;
}
}
if (to == address(0)) {
unchecked {
// Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
_totalSupply -= value;
}
} else {
unchecked {
// Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
_balances[to] += value;
}
}
emit Transfer(from, to, value);
}
/**
* @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
* Relies on the `_update` mechanism
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _mint(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(address(0), account, value);
}
/**
* @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
* Relies on the `_update` mechanism.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead
*/
function _burn(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidSender(address(0));
}
_update(account, address(0), value);
}
/**
* @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*
* Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
*/
function _approve(address owner, address spender, uint256 value) internal {
_approve(owner, spender, value, true);
}
/**
* @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
*
* By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
* `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
* `Approval` event during `transferFrom` operations.
*
* Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
* true using the following override:
*
* ```solidity
* function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
* super._approve(owner, spender, value, true);
* }
* ```
*
* Requirements are the same as {_approve}.
*/
function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
if (owner == address(0)) {
revert ERC20InvalidApprover(address(0));
}
if (spender == address(0)) {
revert ERC20InvalidSpender(address(0));
}
_allowances[owner][spender] = value;
if (emitEvent) {
emit Approval(owner, spender, value);
}
}
/**
* @dev Updates `owner`'s allowance for `spender` based on spent `value`.
*
* Does not update the allowance value in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Does not emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance < type(uint256).max) {
if (currentAllowance < value) {
revert ERC20InsufficientAllowance(spender, currentAllowance, value);
}
unchecked {
_approve(owner, spender, currentAllowance - value, false);
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard ERC-20 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
*/
interface IERC20Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC20InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC20InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC20InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/
error ERC20InvalidSpender(address spender);
}
/**
* @dev Standard ERC-721 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.
*/
interface IERC721Errors {
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/
error ERC721InvalidOwner(address owner);
/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/
error ERC721NonexistentToken(uint256 tokenId);
/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC721InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC721InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC721InsufficientApproval(address operator, uint256 tokenId);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC721InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC721InvalidOperator(address operator);
}
/**
* @dev Standard ERC-1155 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.
*/
interface IERC1155Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC1155InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC1155InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param owner Address of the current owner of a token.
*/
error ERC1155MissingApprovalForAll(address operator, address owner);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC1155InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC1155InvalidOperator(address operator);
/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}// 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.1.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC-20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.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);
}{
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": []
}Contract ABI
API[{"inputs":[{"internalType":"contract HashcashToken","name":"_token","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"miner","type":"address"},{"indexed":false,"internalType":"uint256","name":"round","type":"uint256"}],"name":"BatchMinerAssigned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"miner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BatchMinerPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newBatchSize","type":"uint256"}],"name":"BatchSizeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"round","type":"uint256"}],"name":"DustCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DustWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"feeType","type":"string"}],"name":"FeeCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeesWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"miner","type":"address"},{"indexed":false,"internalType":"uint256","name":"round","type":"uint256"}],"name":"FirstBatchMinerFullReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"miner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"MinerPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"newChallenge","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"round","type":"uint256"}],"name":"NewChallenge","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"mainReward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bonusReward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"numMiners","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"numBatchMiners","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"round","type":"uint256"}],"name":"RewardsAssigned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"miner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardsClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"round","type":"uint256"}],"name":"RoundEnded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"round","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startBlock","type":"uint256"}],"name":"RoundStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"miner","type":"address"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"ShareRejected","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"miner","type":"address"},{"indexed":false,"internalType":"bytes32","name":"digest","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"round","type":"uint256"}],"name":"ShareSubmitted","type":"event"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROUND_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUBMIT_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOKEN_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"batchMiners","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"batchSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"challengeNumber","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentMinerIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"difficulty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"r","type":"uint256"}],"name":"getBatchMiners","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentMiners","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentRound","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDustBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"r","type":"uint256"}],"name":"getMinersCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getResidualDust","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRoundReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"miner","type":"address"}],"name":"getSharesSubmitted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasSubmittedInBlock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"minersInRound","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"miningStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"pendingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"residualDust","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"roundCompleted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"roundNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"roundStartBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"b","type":"uint256"}],"name":"setBatchSize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"d","type":"uint256"}],"name":"setDifficulty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"sharesSubmitted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startMining","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"submitFeesCollected","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"submitShare","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract HashcashToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMined","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawDust","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawFees","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040527e200000000000000000000000000000000000000000000000000000000000006003555f60045f6101000a81548160ff0219169083151502179055505f600460016101000a81548160ff0219169083151502179055506101f460055534801561006b575f80fd5b50604051613529380380613529833981810160405281019061008d9190610189565b60015f819055508060015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503360025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506101b4565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6101478261011e565b9050919050565b5f6101588261013d565b9050919050565b6101688161014e565b8114610172575f80fd5b50565b5f815190506101838161015f565b92915050565b5f6020828403121561019e5761019d61011a565b5b5f6101ab84828501610175565b91505092915050565b613368806101c15f395ff3fe608060405260043610610219575f3560e01c80638ae0368b11610122578063b5190633116100aa578063e5ef622b1161006e578063e5ef622b14610767578063eed5e628146107a3578063f4daaba1146107df578063f56491b914610809578063fc0c546a1461083357610219565b8063b5190633146106b7578063ba2c0f2f146106e1578063c9ab3586146106fd578063cfb550f114610727578063d07d01151461073d57610219565b80639e817c03116100f15780639e817c03146105d3578063a00d2bca146105fd578063a29611de14610627578063a32bf59714610651578063ac3385431461067b57610219565b80638ae0368b1461052b5780638da5cb5b14610555578063954dee2c1461057f57806399310e05146105a957610219565b80633bb45586116101a55780635556db65116101745780635556db651461044b578063576f35e3146104755780635b7f415c1461049d578063602512e1146104c757806388b62d2d146104ef57610219565b80633bb45586146103b7578063476343ee146103e15780634e2786fb146103f757806350ba55341461042157610219565b806331786649116101ec57806331786649146102c357806331d7a262146102ff57806332cb6b0c1461033b5780633605b83414610365578063372500ab146103a157610219565b806304856ace1461021d5780630be19a041461025957806319cae4621461028357806321b79d98146102ad575b5f80fd5b348015610228575f80fd5b50610243600480360381019061023e91906125e4565b61085d565b6040516102509190612629565b60405180910390f35b348015610264575f80fd5b5061026d61087a565b60405161027a919061265a565b60405180910390f35b34801561028e575f80fd5b50610297610880565b6040516102a4919061265a565b60405180910390f35b3480156102b8575f80fd5b506102c1610886565b005b3480156102ce575f80fd5b506102e960048036038101906102e491906125e4565b610a1d565b6040516102f6919061265a565b60405180910390f35b34801561030a575f80fd5b50610325600480360381019061032091906125e4565b610a63565b604051610332919061265a565b60405180910390f35b348015610346575f80fd5b5061034f610a78565b60405161035c919061265a565b60405180910390f35b348015610370575f80fd5b5061038b6004803603810190610386919061269d565b610a93565b604051610398919061277f565b60405180910390f35b3480156103ac575f80fd5b506103b5610b2f565b005b3480156103c2575f80fd5b506103cb610cde565b6040516103d8919061265a565b60405180910390f35b3480156103ec575f80fd5b506103f5610ce7565b005b348015610402575f80fd5b5061040b610ec0565b604051610418919061265a565b60405180910390f35b34801561042c575f80fd5b50610435610ec6565b604051610442919061265a565b60405180910390f35b348015610456575f80fd5b5061045f610fe3565b60405161046c919061265a565b60405180910390f35b348015610480575f80fd5b5061049b6004803603810190610496919061269d565b610fe9565b005b3480156104a8575f80fd5b506104b16110fb565b6040516104be919061265a565b60405180910390f35b3480156104d2575f80fd5b506104ed60048036038101906104e8919061269d565b611107565b005b3480156104fa575f80fd5b506105156004803603810190610510919061269d565b6111e2565b604051610522919061265a565b60405180910390f35b348015610536575f80fd5b5061053f6111fc565b60405161054c91906127b7565b60405180910390f35b348015610560575f80fd5b50610569611202565b60405161057691906127df565b60405180910390f35b34801561058a575f80fd5b50610593611227565b6040516105a0919061265a565b60405180910390f35b3480156105b4575f80fd5b506105bd61122d565b6040516105ca919061277f565b60405180910390f35b3480156105de575f80fd5b506105e76112b8565b6040516105f4919061265a565b60405180910390f35b348015610608575f80fd5b506106116112bd565b60405161061e919061265a565b60405180910390f35b348015610632575f80fd5b5061063b6112c6565b6040516106489190612629565b60405180910390f35b34801561065c575f80fd5b506106656112d8565b604051610672919061265a565b60405180910390f35b348015610686575f80fd5b506106a1600480360381019061069c919061269d565b6112e1565b6040516106ae919061265a565b60405180910390f35b3480156106c2575f80fd5b506106cb6112f6565b6040516106d8919061265a565b60405180910390f35b6106fb60048036038101906106f6919061269d565b6112fc565b005b348015610708575f80fd5b506107116118c4565b60405161071e919061265a565b60405180910390f35b348015610732575f80fd5b5061073b6118cd565b005b348015610748575f80fd5b50610751611ac9565b60405161075e919061265a565b60405180910390f35b348015610772575f80fd5b5061078d600480360381019061078891906127f8565b611acf565b60405161079a91906127df565b60405180910390f35b3480156107ae575f80fd5b506107c960048036038101906107c491906125e4565b611b17565b6040516107d6919061265a565b60405180910390f35b3480156107ea575f80fd5b506107f3611b2c565b604051610800919061265a565b60405180910390f35b348015610814575f80fd5b5061081d611b32565b60405161082a9190612629565b60405180910390f35b34801561083e575f80fd5b50610847611b45565b6040516108549190612891565b60405180910390f35b600b602052805f5260405f205f915054906101000a900460ff1681565b60085481565b60035481565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610915576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090c90612904565b60405180910390fd5b60045f9054906101000a900460ff1615610964576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095b9061296c565b60405180910390fd5b600160045f6101000a81548160ff02191690831515021790555060014361098b91906129b7565b406006819055504360088190555060016007819055507ff53320c7bea311c1a67ca6053613b9d60d5b1dc0a8f3537b0d8004a9507cb91e6006546007546040516109d69291906129ea565b60405180910390a17f278844837bcf8364a705384bf3a2812901f54155bae86dea81dd52aa5b9ec0e3600754600854604051610a13929190612a11565b60405180910390a1565b5f60135f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b600e602052805f5260405f205f915090505481565b670de0b6b3a76400006301406f40610a909190612a38565b81565b6060600d5f8381526020019081526020015f20805480602002602001604051908101604052809291908181526020018280548015610b2357602002820191905f5260205f20905b815f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610ada575b50505050509050919050565b610b37611b6a565b5f600e5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490505f8111610bba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bb190612ac3565b60405180910390fd5b5f600e5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208190555060015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1933836040518363ffffffff1660e01b8152600401610c58929190612ae1565b5f604051808303815f87803b158015610c6f575f80fd5b505af1158015610c81573d5f803e3d5ffd5b505050503373ffffffffffffffffffffffffffffffffffffffff167ffc30cddea38e2bf4d6ea7d3f9ed3b6ad7f176419f4963bd81318067a4aee73fe82604051610ccb919061265a565b60405180910390a250610cdc611bae565b565b64174876e80081565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6d90612904565b60405180910390fd5b5f4790505f8111610dbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db390612b52565b60405180910390fd5b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1682604051610e0290612b9d565b5f6040518083038185875af1925050503d805f8114610e3c576040519150601f19603f3d011682016040523d82523d5f602084013e610e41565b606091505b5050905080610e85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e7c90612bfb565b60405180910390fd5b7f9800e6f57aeb4360eaa72295a820a4293e1e66fbfcabcd8874ae141304a76deb82604051610eb4919061265a565b60405180910390a15050565b60075481565b5f80600f549050670de0b6b3a7640000624c4b40610ee49190612a38565b811015610f0857670de0b6b3a764000060c8610f009190612a38565b915050610fe0565b670de0b6b3a764000062989680610f1f9190612a38565b811015610f4357670de0b6b3a76400006064610f3b9190612a38565b915050610fe0565b670de0b6b3a764000062e4e1c0610f5a9190612a38565b811015610f7e57670de0b6b3a76400006032610f769190612a38565b915050610fe0565b670de0b6b3a76400006301312d00610f969190612a38565b811015610fba57670de0b6b3a76400006019610fb29190612a38565b915050610fe0565b6064670de0b6b3a76400006104c9610fd29190612a38565b610fdc9190612c46565b9150505b90565b600f5481565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611078576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106f90612904565b60405180910390fd5b5f81116110ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b190612cc0565b60405180910390fd5b806005819055507f4fb697dd6b680637dcef5063e86283f64908d814c11c3f862690cbeab38227a0816040516110f0919061265a565b60405180910390a150565b670de0b6b3a764000081565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611196576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118d90612904565b60405180910390fd5b5f81116111d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111cf90612d28565b60405180910390fd5b8060038190555050565b5f600c5f8381526020019081526020015f20549050919050565b60065481565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60115481565b606060098054806020026020016040519081016040528092919081815260200182805480156112ae57602002820191905f5260205f20905b815f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611265575b5050505050905090565b601481565b5f601254905090565b60045f9054906101000a900460ff1681565b5f600754905090565b600c602052805f5260405f205f915090505481565b60105481565b611304611b6a565b60045f9054906101000a900460ff16611352576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134990612d90565b60405180910390fd5b64174876e8003414611399576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139090612df8565b60405180910390fd5b670de0b6b3a76400006301406f406113b19190612a38565b600f54106113f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113eb90612e60565b60405180910390fd5b3460105f8282546114059190612e7e565b925050819055503373ffffffffffffffffffffffffffffffffffffffff167fbde344b6f67c3bf7e0ecbbf22b04267d5d3ae0aa1909c0000b812f6b14ce45b9346040516114529190612efb565b60405180910390a25f600654338360405160200161147293929190612fac565b604051602081830303815290604052805190602001209050600354815f1c1061151c573373ffffffffffffffffffffffffffffffffffffffff167f39e1c44ef8a94fc55be7148c94442a71aaddd6eaac83f58dc5b3831487ae15c06040516114d990613032565b60405180910390a26040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115139061309a565b60405180910390fd5b5f601460085461152c9190612e7e565b4310159050801561160757600d5f60075481526020019081526020015f2033908060018154018082558091505060019003905f5260205f20015f9091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff167fca26c05c75177aabf5472f087e8d23118750e3c0040447f549bbb9234d1e12216007546040516115f0919061265a565b60405180910390a2611600611bb7565b50506118b9565b600b5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1615611691576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168890613102565b60405180910390fd5b6001600b5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16611812576001600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550600933908060018154018082558091505060019003905f5260205f20015f9091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600c5f60075481526020019081526020015f205f81548092919061180c90613120565b91905055505b60135f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f81548092919061185f90613120565b91905055503373ffffffffffffffffffffffffffffffffffffffff167f1d9518a98d44ffe2feec763f319a664258e459fcb0d38697f1f042b570362c59836007546040516118ae9291906129ea565b60405180910390a250505b6118c1611bae565b50565b5f601254905090565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461195c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195390612904565b60405180910390fd5b5f601254116119a0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611997906131b1565b60405180910390fd5b5f60125490505f60128190555060015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1960025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b8152600401611a2a929190612ae1565b5f604051808303815f87803b158015611a41575f80fd5b505af1158015611a53573d5f803e3d5ffd5b5050505060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f1a196790e94751831fb9ca8c3f72d91d761b8d6815921535b5d8545d72f07bb182604051611abe919061265a565b60405180910390a250565b60125481565b600d602052815f5260405f208181548110611ae8575f80fd5b905f5260205f20015f915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6013602052805f5260405f205f915090505481565b60055481565b600460019054906101000a900460ff1681565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60025f5403611ba5576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025f81905550565b60015f81905550565b5f6009805480602002602001604051908101604052809291908181526020018280548015611c3757602002820191905f5260205f20905b815f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611bee575b505050505090505f815190505f600d5f60075481526020019081526020015f2090505f611c62610ec6565b90505f83148015611c7657505f8280549050115b15611e04575f825f81548110611c8f57611c8e6131cf565b5b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600e5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611d059190612e7e565b9250508190555081600f5f828254611d1d9190612e7e565b925050819055508073ffffffffffffffffffffffffffffffffffffffff167f4ba9dab8b38361beda736852f303d9deaf9e0a15ca5101b310f0d4111c92fca1600754604051611d6c919061265a565b60405180910390a27f2265959809fb7a8e7b9b167869fd1e33d7f4bc1b8a47d9343bf70c692455191e5f835f8680549050600754604051611db1959493929190613235565b60405180910390a17faa97d4a7b3afec5f55c25ca8593dde6929d4455fad650a16fa4334004293a618600754604051611dea919061265a565b60405180910390a1611dfa61239b565b5050505050612399565b5f8303611e55577faa97d4a7b3afec5f55c25ca8593dde6929d4455fad650a16fa4334004293a618600754604051611e3c919061265a565b60405180910390a1611e4c61239b565b50505050612399565b5f6064605f83611e659190612a38565b611e6f9190612c46565b90505f8183611e7e91906129b7565b90505f8583611e8d9190613286565b90505f8684611e9c9190612c46565b90505f868054905090505f808211611eb4575f611ec1565b8185611ec09190612c46565b5b90505f808311611ed15785611ede565b8286611edd9190613286565b5b90505f600554601154611ef19190612e7e565b90508a811115611eff578a90505b5f60115490505b81811015612047575f8d8281518110611f2257611f216131cf565b5b6020026020010151905086600e5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611f789190612e7e565b9250508190555086600f5f828254611f909190612e7e565b925050819055505f600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167fe70d1c5fc8ebf59bc1e9c86d898e48249762d7dd2542f64796f06f4d272b623588604051612031919061265a565b60405180910390a2508080600101915050611f06565b50806011819055508a6011541015801561206e5750600460019054906101000a900460ff16155b1561238c576001600460016101000a81548160ff0219169083151502179055505f8411156121a7575f5b848110156121a5575f8b82815481106120b4576120b36131cf565b5b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905084600e5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461212a9190612e7e565b9250508190555084600f5f8282546121429190612e7e565b925050819055508073ffffffffffffffffffffffffffffffffffffffff167fe7d6fd96cf67c8dbc6a3cce2814d934671c821436d4b8d6d8db23b1b27c53d6e8660405161218f919061265a565b60405180910390a2508080600101915050612098565b505b81866121b39190612e7e565b60125f8282546121c39190612e7e565b925050819055507f931c7081fcda171bb0075764141c9c7441e8ca358ae156c727e9d9cfd48a4e1f82876121f79190612e7e565b600754604051612208929190612a11565b60405180910390a15f6012541115612342575f60125490505f60128190555060015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1960025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b81526004016122a4929190612ae1565b5f604051808303815f87803b1580156122bb575f80fd5b505af11580156122cd573d5f803e3d5ffd5b5050505060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f1a196790e94751831fb9ca8c3f72d91d761b8d6815921535b5d8545d72f07bb182604051612338919061265a565b60405180910390a2505b7f2265959809fb7a8e7b9b167869fd1e33d7f4bc1b8a47d9343bf70c692455191e88888d8760075460405161237b9594939291906132b6565b60405180910390a161238b61239b565b5b5050505050505050505050505b565b5f5b600980549050811015612446575f600a5f600984815481106123c2576123c16131cf565b5b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550808060010191505061239d565b5060095f612454919061254d565b5f6011819055505f600460016101000a81548160ff02191690831515021790555060075f81548092919061248790613120565b9190505550436008819055506006546001436124a391906129b7565b406040516020016124b5929190613307565b604051602081830303815290604052805190602001206006819055507ff53320c7bea311c1a67ca6053613b9d60d5b1dc0a8f3537b0d8004a9507cb91e6006546007546040516125069291906129ea565b60405180910390a17f278844837bcf8364a705384bf3a2812901f54155bae86dea81dd52aa5b9ec0e3600754600854604051612543929190612a11565b60405180910390a1565b5080545f8255905f5260205f2090810190612568919061256b565b50565b5b80821115612582575f815f90555060010161256c565b5090565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6125b38261258a565b9050919050565b6125c3816125a9565b81146125cd575f80fd5b50565b5f813590506125de816125ba565b92915050565b5f602082840312156125f9576125f8612586565b5b5f612606848285016125d0565b91505092915050565b5f8115159050919050565b6126238161260f565b82525050565b5f60208201905061263c5f83018461261a565b92915050565b5f819050919050565b61265481612642565b82525050565b5f60208201905061266d5f83018461264b565b92915050565b61267c81612642565b8114612686575f80fd5b50565b5f8135905061269781612673565b92915050565b5f602082840312156126b2576126b1612586565b5b5f6126bf84828501612689565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6126fa816125a9565b82525050565b5f61270b83836126f1565b60208301905092915050565b5f602082019050919050565b5f61272d826126c8565b61273781856126d2565b9350612742836126e2565b805f5b838110156127725781516127598882612700565b975061276483612717565b925050600181019050612745565b5085935050505092915050565b5f6020820190508181035f8301526127978184612723565b905092915050565b5f819050919050565b6127b18161279f565b82525050565b5f6020820190506127ca5f8301846127a8565b92915050565b6127d9816125a9565b82525050565b5f6020820190506127f25f8301846127d0565b92915050565b5f806040838503121561280e5761280d612586565b5b5f61281b85828601612689565b925050602061282c85828601612689565b9150509250929050565b5f819050919050565b5f61285961285461284f8461258a565b612836565b61258a565b9050919050565b5f61286a8261283f565b9050919050565b5f61287b82612860565b9050919050565b61288b81612871565b82525050565b5f6020820190506128a45f830184612882565b92915050565b5f82825260208201905092915050565b7f4e6f74206f776e657200000000000000000000000000000000000000000000005f82015250565b5f6128ee6009836128aa565b91506128f9826128ba565b602082019050919050565b5f6020820190508181035f83015261291b816128e2565b9050919050565b7f4d696e696e6720616c72656164792073746172746564000000000000000000005f82015250565b5f6129566016836128aa565b915061296182612922565b602082019050919050565b5f6020820190508181035f8301526129838161294a565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6129c182612642565b91506129cc83612642565b92508282039050818111156129e4576129e361298a565b5b92915050565b5f6040820190506129fd5f8301856127a8565b612a0a602083018461264b565b9392505050565b5f604082019050612a245f83018561264b565b612a31602083018461264b565b9392505050565b5f612a4282612642565b9150612a4d83612642565b9250828202612a5b81612642565b91508282048414831517612a7257612a7161298a565b5b5092915050565b7f4e6f2072657761726473000000000000000000000000000000000000000000005f82015250565b5f612aad600a836128aa565b9150612ab882612a79565b602082019050919050565b5f6020820190508181035f830152612ada81612aa1565b9050919050565b5f604082019050612af45f8301856127d0565b612b01602083018461264b565b9392505050565b7f4e6f2045544800000000000000000000000000000000000000000000000000005f82015250565b5f612b3c6006836128aa565b9150612b4782612b08565b602082019050919050565b5f6020820190508181035f830152612b6981612b30565b9050919050565b5f81905092915050565b50565b5f612b885f83612b70565b9150612b9382612b7a565b5f82019050919050565b5f612ba782612b7d565b9150819050919050565b7f7769746864726177206661696c656400000000000000000000000000000000005f82015250565b5f612be5600f836128aa565b9150612bf082612bb1565b602082019050919050565b5f6020820190508181035f830152612c1281612bd9565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f612c5082612642565b9150612c5b83612642565b925082612c6b57612c6a612c19565b5b828204905092915050565b7f626174636853697a653e300000000000000000000000000000000000000000005f82015250565b5f612caa600b836128aa565b9150612cb582612c76565b602082019050919050565b5f6020820190508181035f830152612cd781612c9e565b9050919050565b7f496e76616c6964206469666600000000000000000000000000000000000000005f82015250565b5f612d12600c836128aa565b9150612d1d82612cde565b602082019050919050565b5f6020820190508181035f830152612d3f81612d06565b9050919050565b7f4d696e696e67206e6f74207374617274656400000000000000000000000000005f82015250565b5f612d7a6012836128aa565b9150612d8582612d46565b602082019050919050565b5f6020820190508181035f830152612da781612d6e565b9050919050565b7f466565203d20302e3030303120455448000000000000000000000000000000005f82015250565b5f612de26010836128aa565b9150612ded82612dae565b602082019050919050565b5f6020820190508181035f830152612e0f81612dd6565b9050919050565b7f416c6c20746f6b656e73206d696e6564000000000000000000000000000000005f82015250565b5f612e4a6010836128aa565b9150612e5582612e16565b602082019050919050565b5f6020820190508181035f830152612e7781612e3e565b9050919050565b5f612e8882612642565b9150612e9383612642565b9250828201905080821115612eab57612eaa61298a565b5b92915050565b7f7375626d697400000000000000000000000000000000000000000000000000005f82015250565b5f612ee56006836128aa565b9150612ef082612eb1565b602082019050919050565b5f604082019050612f0e5f83018461264b565b8181036020830152612f1f81612ed9565b905092915050565b5f819050919050565b612f41612f3c8261279f565b612f27565b82525050565b5f8160601b9050919050565b5f612f5d82612f47565b9050919050565b5f612f6e82612f53565b9050919050565b612f86612f81826125a9565b612f64565b82525050565b5f819050919050565b612fa6612fa182612642565b612f8c565b82525050565b5f612fb78286612f30565b602082019150612fc78285612f75565b601482019150612fd78284612f95565b602082019150819050949350505050565b7f446967657374203e3d20646966666963756c74790000000000000000000000005f82015250565b5f61301c6014836128aa565b915061302782612fe8565b602082019050919050565b5f6020820190508181035f83015261304981613010565b9050919050565b7f496e76616c6964207368617265000000000000000000000000000000000000005f82015250565b5f613084600d836128aa565b915061308f82613050565b602082019050919050565b5f6020820190508181035f8301526130b181613078565b9050919050565b7f416c7265616479207375626d697474656420696e207468697320626c6f636b005f82015250565b5f6130ec601f836128aa565b91506130f7826130b8565b602082019050919050565b5f6020820190508181035f830152613119816130e0565b9050919050565b5f61312a82612642565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361315c5761315b61298a565b5b600182019050919050565b7f4e6f206475737420746f207769746864726177000000000000000000000000005f82015250565b5f61319b6013836128aa565b91506131a682613167565b602082019050919050565b5f6020820190508181035f8301526131c88161318f565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f819050919050565b5f61321f61321a613215846131fc565b612836565b612642565b9050919050565b61322f81613205565b82525050565b5f60a0820190506132485f830188613226565b613255602083018761264b565b6132626040830186613226565b61326f606083018561264b565b61327c608083018461264b565b9695505050505050565b5f61329082612642565b915061329b83612642565b9250826132ab576132aa612c19565b5b828206905092915050565b5f60a0820190506132c95f83018861264b565b6132d6602083018761264b565b6132e3604083018661264b565b6132f0606083018561264b565b6132fd608083018461264b565b9695505050505050565b5f6133128285612f30565b6020820191506133228284612f30565b602082019150819050939250505056fea2646970667358221220c318b21329c4ad52b95c7306a67ffd120a4fb47e1ccda9ea541ed0eed249fa0c64736f6c634300081a0033000000000000000000000000e4a7760e721c444c5b1244d38d9bc140cf4e6575
Deployed Bytecode
0x608060405260043610610219575f3560e01c80638ae0368b11610122578063b5190633116100aa578063e5ef622b1161006e578063e5ef622b14610767578063eed5e628146107a3578063f4daaba1146107df578063f56491b914610809578063fc0c546a1461083357610219565b8063b5190633146106b7578063ba2c0f2f146106e1578063c9ab3586146106fd578063cfb550f114610727578063d07d01151461073d57610219565b80639e817c03116100f15780639e817c03146105d3578063a00d2bca146105fd578063a29611de14610627578063a32bf59714610651578063ac3385431461067b57610219565b80638ae0368b1461052b5780638da5cb5b14610555578063954dee2c1461057f57806399310e05146105a957610219565b80633bb45586116101a55780635556db65116101745780635556db651461044b578063576f35e3146104755780635b7f415c1461049d578063602512e1146104c757806388b62d2d146104ef57610219565b80633bb45586146103b7578063476343ee146103e15780634e2786fb146103f757806350ba55341461042157610219565b806331786649116101ec57806331786649146102c357806331d7a262146102ff57806332cb6b0c1461033b5780633605b83414610365578063372500ab146103a157610219565b806304856ace1461021d5780630be19a041461025957806319cae4621461028357806321b79d98146102ad575b5f80fd5b348015610228575f80fd5b50610243600480360381019061023e91906125e4565b61085d565b6040516102509190612629565b60405180910390f35b348015610264575f80fd5b5061026d61087a565b60405161027a919061265a565b60405180910390f35b34801561028e575f80fd5b50610297610880565b6040516102a4919061265a565b60405180910390f35b3480156102b8575f80fd5b506102c1610886565b005b3480156102ce575f80fd5b506102e960048036038101906102e491906125e4565b610a1d565b6040516102f6919061265a565b60405180910390f35b34801561030a575f80fd5b50610325600480360381019061032091906125e4565b610a63565b604051610332919061265a565b60405180910390f35b348015610346575f80fd5b5061034f610a78565b60405161035c919061265a565b60405180910390f35b348015610370575f80fd5b5061038b6004803603810190610386919061269d565b610a93565b604051610398919061277f565b60405180910390f35b3480156103ac575f80fd5b506103b5610b2f565b005b3480156103c2575f80fd5b506103cb610cde565b6040516103d8919061265a565b60405180910390f35b3480156103ec575f80fd5b506103f5610ce7565b005b348015610402575f80fd5b5061040b610ec0565b604051610418919061265a565b60405180910390f35b34801561042c575f80fd5b50610435610ec6565b604051610442919061265a565b60405180910390f35b348015610456575f80fd5b5061045f610fe3565b60405161046c919061265a565b60405180910390f35b348015610480575f80fd5b5061049b6004803603810190610496919061269d565b610fe9565b005b3480156104a8575f80fd5b506104b16110fb565b6040516104be919061265a565b60405180910390f35b3480156104d2575f80fd5b506104ed60048036038101906104e8919061269d565b611107565b005b3480156104fa575f80fd5b506105156004803603810190610510919061269d565b6111e2565b604051610522919061265a565b60405180910390f35b348015610536575f80fd5b5061053f6111fc565b60405161054c91906127b7565b60405180910390f35b348015610560575f80fd5b50610569611202565b60405161057691906127df565b60405180910390f35b34801561058a575f80fd5b50610593611227565b6040516105a0919061265a565b60405180910390f35b3480156105b4575f80fd5b506105bd61122d565b6040516105ca919061277f565b60405180910390f35b3480156105de575f80fd5b506105e76112b8565b6040516105f4919061265a565b60405180910390f35b348015610608575f80fd5b506106116112bd565b60405161061e919061265a565b60405180910390f35b348015610632575f80fd5b5061063b6112c6565b6040516106489190612629565b60405180910390f35b34801561065c575f80fd5b506106656112d8565b604051610672919061265a565b60405180910390f35b348015610686575f80fd5b506106a1600480360381019061069c919061269d565b6112e1565b6040516106ae919061265a565b60405180910390f35b3480156106c2575f80fd5b506106cb6112f6565b6040516106d8919061265a565b60405180910390f35b6106fb60048036038101906106f6919061269d565b6112fc565b005b348015610708575f80fd5b506107116118c4565b60405161071e919061265a565b60405180910390f35b348015610732575f80fd5b5061073b6118cd565b005b348015610748575f80fd5b50610751611ac9565b60405161075e919061265a565b60405180910390f35b348015610772575f80fd5b5061078d600480360381019061078891906127f8565b611acf565b60405161079a91906127df565b60405180910390f35b3480156107ae575f80fd5b506107c960048036038101906107c491906125e4565b611b17565b6040516107d6919061265a565b60405180910390f35b3480156107ea575f80fd5b506107f3611b2c565b604051610800919061265a565b60405180910390f35b348015610814575f80fd5b5061081d611b32565b60405161082a9190612629565b60405180910390f35b34801561083e575f80fd5b50610847611b45565b6040516108549190612891565b60405180910390f35b600b602052805f5260405f205f915054906101000a900460ff1681565b60085481565b60035481565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610915576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090c90612904565b60405180910390fd5b60045f9054906101000a900460ff1615610964576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095b9061296c565b60405180910390fd5b600160045f6101000a81548160ff02191690831515021790555060014361098b91906129b7565b406006819055504360088190555060016007819055507ff53320c7bea311c1a67ca6053613b9d60d5b1dc0a8f3537b0d8004a9507cb91e6006546007546040516109d69291906129ea565b60405180910390a17f278844837bcf8364a705384bf3a2812901f54155bae86dea81dd52aa5b9ec0e3600754600854604051610a13929190612a11565b60405180910390a1565b5f60135f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b600e602052805f5260405f205f915090505481565b670de0b6b3a76400006301406f40610a909190612a38565b81565b6060600d5f8381526020019081526020015f20805480602002602001604051908101604052809291908181526020018280548015610b2357602002820191905f5260205f20905b815f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610ada575b50505050509050919050565b610b37611b6a565b5f600e5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490505f8111610bba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bb190612ac3565b60405180910390fd5b5f600e5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208190555060015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1933836040518363ffffffff1660e01b8152600401610c58929190612ae1565b5f604051808303815f87803b158015610c6f575f80fd5b505af1158015610c81573d5f803e3d5ffd5b505050503373ffffffffffffffffffffffffffffffffffffffff167ffc30cddea38e2bf4d6ea7d3f9ed3b6ad7f176419f4963bd81318067a4aee73fe82604051610ccb919061265a565b60405180910390a250610cdc611bae565b565b64174876e80081565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6d90612904565b60405180910390fd5b5f4790505f8111610dbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db390612b52565b60405180910390fd5b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1682604051610e0290612b9d565b5f6040518083038185875af1925050503d805f8114610e3c576040519150601f19603f3d011682016040523d82523d5f602084013e610e41565b606091505b5050905080610e85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e7c90612bfb565b60405180910390fd5b7f9800e6f57aeb4360eaa72295a820a4293e1e66fbfcabcd8874ae141304a76deb82604051610eb4919061265a565b60405180910390a15050565b60075481565b5f80600f549050670de0b6b3a7640000624c4b40610ee49190612a38565b811015610f0857670de0b6b3a764000060c8610f009190612a38565b915050610fe0565b670de0b6b3a764000062989680610f1f9190612a38565b811015610f4357670de0b6b3a76400006064610f3b9190612a38565b915050610fe0565b670de0b6b3a764000062e4e1c0610f5a9190612a38565b811015610f7e57670de0b6b3a76400006032610f769190612a38565b915050610fe0565b670de0b6b3a76400006301312d00610f969190612a38565b811015610fba57670de0b6b3a76400006019610fb29190612a38565b915050610fe0565b6064670de0b6b3a76400006104c9610fd29190612a38565b610fdc9190612c46565b9150505b90565b600f5481565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611078576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106f90612904565b60405180910390fd5b5f81116110ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b190612cc0565b60405180910390fd5b806005819055507f4fb697dd6b680637dcef5063e86283f64908d814c11c3f862690cbeab38227a0816040516110f0919061265a565b60405180910390a150565b670de0b6b3a764000081565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611196576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118d90612904565b60405180910390fd5b5f81116111d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111cf90612d28565b60405180910390fd5b8060038190555050565b5f600c5f8381526020019081526020015f20549050919050565b60065481565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60115481565b606060098054806020026020016040519081016040528092919081815260200182805480156112ae57602002820191905f5260205f20905b815f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611265575b5050505050905090565b601481565b5f601254905090565b60045f9054906101000a900460ff1681565b5f600754905090565b600c602052805f5260405f205f915090505481565b60105481565b611304611b6a565b60045f9054906101000a900460ff16611352576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134990612d90565b60405180910390fd5b64174876e8003414611399576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139090612df8565b60405180910390fd5b670de0b6b3a76400006301406f406113b19190612a38565b600f54106113f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113eb90612e60565b60405180910390fd5b3460105f8282546114059190612e7e565b925050819055503373ffffffffffffffffffffffffffffffffffffffff167fbde344b6f67c3bf7e0ecbbf22b04267d5d3ae0aa1909c0000b812f6b14ce45b9346040516114529190612efb565b60405180910390a25f600654338360405160200161147293929190612fac565b604051602081830303815290604052805190602001209050600354815f1c1061151c573373ffffffffffffffffffffffffffffffffffffffff167f39e1c44ef8a94fc55be7148c94442a71aaddd6eaac83f58dc5b3831487ae15c06040516114d990613032565b60405180910390a26040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115139061309a565b60405180910390fd5b5f601460085461152c9190612e7e565b4310159050801561160757600d5f60075481526020019081526020015f2033908060018154018082558091505060019003905f5260205f20015f9091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff167fca26c05c75177aabf5472f087e8d23118750e3c0040447f549bbb9234d1e12216007546040516115f0919061265a565b60405180910390a2611600611bb7565b50506118b9565b600b5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1615611691576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168890613102565b60405180910390fd5b6001600b5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16611812576001600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550600933908060018154018082558091505060019003905f5260205f20015f9091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600c5f60075481526020019081526020015f205f81548092919061180c90613120565b91905055505b60135f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f81548092919061185f90613120565b91905055503373ffffffffffffffffffffffffffffffffffffffff167f1d9518a98d44ffe2feec763f319a664258e459fcb0d38697f1f042b570362c59836007546040516118ae9291906129ea565b60405180910390a250505b6118c1611bae565b50565b5f601254905090565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461195c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195390612904565b60405180910390fd5b5f601254116119a0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611997906131b1565b60405180910390fd5b5f60125490505f60128190555060015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1960025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b8152600401611a2a929190612ae1565b5f604051808303815f87803b158015611a41575f80fd5b505af1158015611a53573d5f803e3d5ffd5b5050505060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f1a196790e94751831fb9ca8c3f72d91d761b8d6815921535b5d8545d72f07bb182604051611abe919061265a565b60405180910390a250565b60125481565b600d602052815f5260405f208181548110611ae8575f80fd5b905f5260205f20015f915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6013602052805f5260405f205f915090505481565b60055481565b600460019054906101000a900460ff1681565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60025f5403611ba5576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025f81905550565b60015f81905550565b5f6009805480602002602001604051908101604052809291908181526020018280548015611c3757602002820191905f5260205f20905b815f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611bee575b505050505090505f815190505f600d5f60075481526020019081526020015f2090505f611c62610ec6565b90505f83148015611c7657505f8280549050115b15611e04575f825f81548110611c8f57611c8e6131cf565b5b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600e5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611d059190612e7e565b9250508190555081600f5f828254611d1d9190612e7e565b925050819055508073ffffffffffffffffffffffffffffffffffffffff167f4ba9dab8b38361beda736852f303d9deaf9e0a15ca5101b310f0d4111c92fca1600754604051611d6c919061265a565b60405180910390a27f2265959809fb7a8e7b9b167869fd1e33d7f4bc1b8a47d9343bf70c692455191e5f835f8680549050600754604051611db1959493929190613235565b60405180910390a17faa97d4a7b3afec5f55c25ca8593dde6929d4455fad650a16fa4334004293a618600754604051611dea919061265a565b60405180910390a1611dfa61239b565b5050505050612399565b5f8303611e55577faa97d4a7b3afec5f55c25ca8593dde6929d4455fad650a16fa4334004293a618600754604051611e3c919061265a565b60405180910390a1611e4c61239b565b50505050612399565b5f6064605f83611e659190612a38565b611e6f9190612c46565b90505f8183611e7e91906129b7565b90505f8583611e8d9190613286565b90505f8684611e9c9190612c46565b90505f868054905090505f808211611eb4575f611ec1565b8185611ec09190612c46565b5b90505f808311611ed15785611ede565b8286611edd9190613286565b5b90505f600554601154611ef19190612e7e565b90508a811115611eff578a90505b5f60115490505b81811015612047575f8d8281518110611f2257611f216131cf565b5b6020026020010151905086600e5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611f789190612e7e565b9250508190555086600f5f828254611f909190612e7e565b925050819055505f600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167fe70d1c5fc8ebf59bc1e9c86d898e48249762d7dd2542f64796f06f4d272b623588604051612031919061265a565b60405180910390a2508080600101915050611f06565b50806011819055508a6011541015801561206e5750600460019054906101000a900460ff16155b1561238c576001600460016101000a81548160ff0219169083151502179055505f8411156121a7575f5b848110156121a5575f8b82815481106120b4576120b36131cf565b5b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905084600e5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461212a9190612e7e565b9250508190555084600f5f8282546121429190612e7e565b925050819055508073ffffffffffffffffffffffffffffffffffffffff167fe7d6fd96cf67c8dbc6a3cce2814d934671c821436d4b8d6d8db23b1b27c53d6e8660405161218f919061265a565b60405180910390a2508080600101915050612098565b505b81866121b39190612e7e565b60125f8282546121c39190612e7e565b925050819055507f931c7081fcda171bb0075764141c9c7441e8ca358ae156c727e9d9cfd48a4e1f82876121f79190612e7e565b600754604051612208929190612a11565b60405180910390a15f6012541115612342575f60125490505f60128190555060015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1960025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b81526004016122a4929190612ae1565b5f604051808303815f87803b1580156122bb575f80fd5b505af11580156122cd573d5f803e3d5ffd5b5050505060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f1a196790e94751831fb9ca8c3f72d91d761b8d6815921535b5d8545d72f07bb182604051612338919061265a565b60405180910390a2505b7f2265959809fb7a8e7b9b167869fd1e33d7f4bc1b8a47d9343bf70c692455191e88888d8760075460405161237b9594939291906132b6565b60405180910390a161238b61239b565b5b5050505050505050505050505b565b5f5b600980549050811015612446575f600a5f600984815481106123c2576123c16131cf565b5b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550808060010191505061239d565b5060095f612454919061254d565b5f6011819055505f600460016101000a81548160ff02191690831515021790555060075f81548092919061248790613120565b9190505550436008819055506006546001436124a391906129b7565b406040516020016124b5929190613307565b604051602081830303815290604052805190602001206006819055507ff53320c7bea311c1a67ca6053613b9d60d5b1dc0a8f3537b0d8004a9507cb91e6006546007546040516125069291906129ea565b60405180910390a17f278844837bcf8364a705384bf3a2812901f54155bae86dea81dd52aa5b9ec0e3600754600854604051612543929190612a11565b60405180910390a1565b5080545f8255905f5260205f2090810190612568919061256b565b50565b5b80821115612582575f815f90555060010161256c565b5090565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6125b38261258a565b9050919050565b6125c3816125a9565b81146125cd575f80fd5b50565b5f813590506125de816125ba565b92915050565b5f602082840312156125f9576125f8612586565b5b5f612606848285016125d0565b91505092915050565b5f8115159050919050565b6126238161260f565b82525050565b5f60208201905061263c5f83018461261a565b92915050565b5f819050919050565b61265481612642565b82525050565b5f60208201905061266d5f83018461264b565b92915050565b61267c81612642565b8114612686575f80fd5b50565b5f8135905061269781612673565b92915050565b5f602082840312156126b2576126b1612586565b5b5f6126bf84828501612689565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6126fa816125a9565b82525050565b5f61270b83836126f1565b60208301905092915050565b5f602082019050919050565b5f61272d826126c8565b61273781856126d2565b9350612742836126e2565b805f5b838110156127725781516127598882612700565b975061276483612717565b925050600181019050612745565b5085935050505092915050565b5f6020820190508181035f8301526127978184612723565b905092915050565b5f819050919050565b6127b18161279f565b82525050565b5f6020820190506127ca5f8301846127a8565b92915050565b6127d9816125a9565b82525050565b5f6020820190506127f25f8301846127d0565b92915050565b5f806040838503121561280e5761280d612586565b5b5f61281b85828601612689565b925050602061282c85828601612689565b9150509250929050565b5f819050919050565b5f61285961285461284f8461258a565b612836565b61258a565b9050919050565b5f61286a8261283f565b9050919050565b5f61287b82612860565b9050919050565b61288b81612871565b82525050565b5f6020820190506128a45f830184612882565b92915050565b5f82825260208201905092915050565b7f4e6f74206f776e657200000000000000000000000000000000000000000000005f82015250565b5f6128ee6009836128aa565b91506128f9826128ba565b602082019050919050565b5f6020820190508181035f83015261291b816128e2565b9050919050565b7f4d696e696e6720616c72656164792073746172746564000000000000000000005f82015250565b5f6129566016836128aa565b915061296182612922565b602082019050919050565b5f6020820190508181035f8301526129838161294a565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6129c182612642565b91506129cc83612642565b92508282039050818111156129e4576129e361298a565b5b92915050565b5f6040820190506129fd5f8301856127a8565b612a0a602083018461264b565b9392505050565b5f604082019050612a245f83018561264b565b612a31602083018461264b565b9392505050565b5f612a4282612642565b9150612a4d83612642565b9250828202612a5b81612642565b91508282048414831517612a7257612a7161298a565b5b5092915050565b7f4e6f2072657761726473000000000000000000000000000000000000000000005f82015250565b5f612aad600a836128aa565b9150612ab882612a79565b602082019050919050565b5f6020820190508181035f830152612ada81612aa1565b9050919050565b5f604082019050612af45f8301856127d0565b612b01602083018461264b565b9392505050565b7f4e6f2045544800000000000000000000000000000000000000000000000000005f82015250565b5f612b3c6006836128aa565b9150612b4782612b08565b602082019050919050565b5f6020820190508181035f830152612b6981612b30565b9050919050565b5f81905092915050565b50565b5f612b885f83612b70565b9150612b9382612b7a565b5f82019050919050565b5f612ba782612b7d565b9150819050919050565b7f7769746864726177206661696c656400000000000000000000000000000000005f82015250565b5f612be5600f836128aa565b9150612bf082612bb1565b602082019050919050565b5f6020820190508181035f830152612c1281612bd9565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f612c5082612642565b9150612c5b83612642565b925082612c6b57612c6a612c19565b5b828204905092915050565b7f626174636853697a653e300000000000000000000000000000000000000000005f82015250565b5f612caa600b836128aa565b9150612cb582612c76565b602082019050919050565b5f6020820190508181035f830152612cd781612c9e565b9050919050565b7f496e76616c6964206469666600000000000000000000000000000000000000005f82015250565b5f612d12600c836128aa565b9150612d1d82612cde565b602082019050919050565b5f6020820190508181035f830152612d3f81612d06565b9050919050565b7f4d696e696e67206e6f74207374617274656400000000000000000000000000005f82015250565b5f612d7a6012836128aa565b9150612d8582612d46565b602082019050919050565b5f6020820190508181035f830152612da781612d6e565b9050919050565b7f466565203d20302e3030303120455448000000000000000000000000000000005f82015250565b5f612de26010836128aa565b9150612ded82612dae565b602082019050919050565b5f6020820190508181035f830152612e0f81612dd6565b9050919050565b7f416c6c20746f6b656e73206d696e6564000000000000000000000000000000005f82015250565b5f612e4a6010836128aa565b9150612e5582612e16565b602082019050919050565b5f6020820190508181035f830152612e7781612e3e565b9050919050565b5f612e8882612642565b9150612e9383612642565b9250828201905080821115612eab57612eaa61298a565b5b92915050565b7f7375626d697400000000000000000000000000000000000000000000000000005f82015250565b5f612ee56006836128aa565b9150612ef082612eb1565b602082019050919050565b5f604082019050612f0e5f83018461264b565b8181036020830152612f1f81612ed9565b905092915050565b5f819050919050565b612f41612f3c8261279f565b612f27565b82525050565b5f8160601b9050919050565b5f612f5d82612f47565b9050919050565b5f612f6e82612f53565b9050919050565b612f86612f81826125a9565b612f64565b82525050565b5f819050919050565b612fa6612fa182612642565b612f8c565b82525050565b5f612fb78286612f30565b602082019150612fc78285612f75565b601482019150612fd78284612f95565b602082019150819050949350505050565b7f446967657374203e3d20646966666963756c74790000000000000000000000005f82015250565b5f61301c6014836128aa565b915061302782612fe8565b602082019050919050565b5f6020820190508181035f83015261304981613010565b9050919050565b7f496e76616c6964207368617265000000000000000000000000000000000000005f82015250565b5f613084600d836128aa565b915061308f82613050565b602082019050919050565b5f6020820190508181035f8301526130b181613078565b9050919050565b7f416c7265616479207375626d697474656420696e207468697320626c6f636b005f82015250565b5f6130ec601f836128aa565b91506130f7826130b8565b602082019050919050565b5f6020820190508181035f830152613119816130e0565b9050919050565b5f61312a82612642565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361315c5761315b61298a565b5b600182019050919050565b7f4e6f206475737420746f207769746864726177000000000000000000000000005f82015250565b5f61319b6013836128aa565b91506131a682613167565b602082019050919050565b5f6020820190508181035f8301526131c88161318f565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f819050919050565b5f61321f61321a613215846131fc565b612836565b612642565b9050919050565b61322f81613205565b82525050565b5f60a0820190506132485f830188613226565b613255602083018761264b565b6132626040830186613226565b61326f606083018561264b565b61327c608083018461264b565b9695505050505050565b5f61329082612642565b915061329b83612642565b9250826132ab576132aa612c19565b5b828206905092915050565b5f60a0820190506132c95f83018861264b565b6132d6602083018761264b565b6132e3604083018661264b565b6132f0606083018561264b565b6132fd608083018461264b565b9695505050505050565b5f6133128285612f30565b6020820191506133228284612f30565b602082019150819050939250505056fea2646970667358221220c318b21329c4ad52b95c7306a67ffd120a4fb47e1ccda9ea541ed0eed249fa0c64736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000e4a7760e721c444c5b1244d38d9bc140cf4e6575
-----Decoded View---------------
Arg [0] : _token (address): 0xE4A7760E721c444C5b1244D38d9BC140CF4E6575
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000e4a7760e721c444c5b1244d38d9bc140cf4e6575
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.