Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Unstake | 10070815 | 1719 days ago | IN | 0 ETH | 0.00069167 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
AfroXToken
Compiler Version
v0.5.13+commit.5b0b510c
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2019-11-28 */ // File: @openzeppelin/upgrades/contracts/Initializable.sol pragma solidity >=0.4.24 <0.6.0; /** * @title Initializable * * @dev Helper contract to support initializer functions. To use it, replace * the constructor with a function that has the `initializer` modifier. * WARNING: Unlike constructors, initializer functions must be manually * invoked. This applies both to deploying an Initializable contract, as well * as extending an Initializable contract via inheritance. * WARNING: When used with inheritance, manual care must be taken to not invoke * a parent initializer twice, or ensure that all initializers are idempotent, * because this is not dealt with automatically as with constructors. */ contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private initializing; /** * @dev Modifier to use in the initializer function of a contract. */ modifier initializer() { require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); bool isTopLevelCall = !initializing; if (isTopLevelCall) { initializing = true; initialized = true; } _; if (isTopLevelCall) { initializing = false; } } /// @dev Returns true if and only if the function is running in the constructor function isConstructor() private view returns (bool) { // extcodesize checks the size of the code stored in an address, and // address returns the current address. Since the code is still not // deployed when running a constructor, any checks on its code size will // yield zero, making it an effective way to detect if a contract is // under construction or not. uint256 cs; assembly { cs := extcodesize(address) } return cs == 0; } // Reserved storage space to allow for layout changes in the future. uint256[50] private ______gap; } // File: @openzeppelin/contracts-ethereum-package/contracts/GSN/Context.sol pragma solidity ^0.5.0; /* * @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 GSN 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. */ contract Context is Initializable { // Empty internal constructor, to prevent people from mistakenly deploying // an instance of this contract, which should be used via inheritance. constructor () internal { } // solhint-disable-previous-line no-empty-blocks function _msgSender() internal view returns (address payable) { return msg.sender; } function _msgData() internal view returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File: @openzeppelin/contracts-ethereum-package/contracts/ownership/Ownable.sol pragma solidity ^0.5.0; /** * @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. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be aplied to your functions to restrict their use to * the owner. */ contract Ownable is Initializable, Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function initialize(address sender) public initializer { _owner = sender; emit OwnershipTransferred(address(0), _owner); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner(), "Ownable: caller is not the owner"); _; } /** * @dev Returns true if the caller is the current owner. */ function isOwner() public view returns (bool) { return _msgSender() == _owner; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * > Note: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = 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 onlyOwner { _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). */ function _transferOwnership(address newOwner) internal { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } uint256[50] private ______gap; } // File: @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol pragma solidity ^0.5.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. Does not include * the optional functions; to access them see {ERC20Detailed}. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @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); } // File: @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20Detailed.sol pragma solidity ^0.5.0; /** * @dev Optional functions from the ERC20 standard. */ contract ERC20Detailed is Initializable, IERC20 { string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of * these values are immutable: they can only be set once during * construction. */ function initialize(string memory name, string memory symbol, uint8 decimals) public initializer { _name = name; _symbol = symbol; _decimals = decimals; } /** * @dev Returns the name of the token. */ function name() public view returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view 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. * * 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 returns (uint8) { return _decimals; } uint256[50] private ______gap; } // File: @openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol pragma solidity ^0.5.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. * * _Available since v2.4.0._ */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File: @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20.sol pragma solidity ^0.5.0; /** * @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}. * For a generic mechanism see {ERC20Mintable}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Initializable, Context, IERC20 { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}; * * Requirements: * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for `sender`'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements * * - `to` cannot be the zero address. */ function _mint(address account, uint256 amount) internal { require(account != address(0), "ERC20: mint to the zero address"); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal { require(account != address(0), "ERC20: burn from the zero address"); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens. * * This is 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. */ function _approve(address owner, address spender, uint256 amount) internal { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Destroys `amount` tokens from `account`.`amount` is then deducted * from the caller's allowance. * * See {_burn} and {_approve}. */ function _burnFrom(address account, uint256 amount) internal { _burn(account, amount); _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "ERC20: burn amount exceeds allowance")); } uint256[50] private ______gap; } // File: @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20Burnable.sol pragma solidity ^0.5.0; /** * @dev Extension of {ERC20} that allows token holders to destroy both their own * tokens and those that they have an allowance for, in a way that can be * recognized off-chain (via event analysis). */ contract ERC20Burnable is Initializable, Context, ERC20 { /** * @dev Destroys `amount` tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 amount) public { _burn(_msgSender(), amount); } /** * @dev See {ERC20-_burnFrom}. */ function burnFrom(address account, uint256 amount) public { _burnFrom(account, amount); } uint256[50] private ______gap; } // File: @openzeppelin/contracts-ethereum-package/contracts/GSN/IRelayRecipient.sol pragma solidity ^0.5.0; /** * @dev Base interface for a contract that will be called via the GSN from {IRelayHub}. * * TIP: You don't need to write an implementation yourself! Inherit from {GSNRecipient} instead. */ contract IRelayRecipient { /** * @dev Returns the address of the {IRelayHub} instance this recipient interacts with. */ function getHubAddr() public view returns (address); /** * @dev Called by {IRelayHub} to validate if this recipient accepts being charged for a relayed call. Note that the * recipient will be charged regardless of the execution result of the relayed call (i.e. if it reverts or not). * * The relay request was originated by `from` and will be served by `relay`. `encodedFunction` is the relayed call * calldata, so its first four bytes are the function selector. The relayed call will be forwarded `gasLimit` gas, * and the transaction executed with a gas price of at least `gasPrice`. `relay`'s fee is `transactionFee`, and the * recipient will be charged at most `maxPossibleCharge` (in wei). `nonce` is the sender's (`from`) nonce for * replay attack protection in {IRelayHub}, and `approvalData` is a optional parameter that can be used to hold a signature * over all or some of the previous values. * * Returns a tuple, where the first value is used to indicate approval (0) or rejection (custom non-zero error code, * values 1 to 10 are reserved) and the second one is data to be passed to the other {IRelayRecipient} functions. * * {acceptRelayedCall} is called with 50k gas: if it runs out during execution, the request will be considered * rejected. A regular revert will also trigger a rejection. */ function acceptRelayedCall( address relay, address from, bytes calldata encodedFunction, uint256 transactionFee, uint256 gasPrice, uint256 gasLimit, uint256 nonce, bytes calldata approvalData, uint256 maxPossibleCharge ) external view returns (uint256, bytes memory); /** * @dev Called by {IRelayHub} on approved relay call requests, before the relayed call is executed. This allows to e.g. * pre-charge the sender of the transaction. * * `context` is the second value returned in the tuple by {acceptRelayedCall}. * * Returns a value to be passed to {postRelayedCall}. * * {preRelayedCall} is called with 100k gas: if it runs out during exection or otherwise reverts, the relayed call * will not be executed, but the recipient will still be charged for the transaction's cost. */ function preRelayedCall(bytes calldata context) external returns (bytes32); /** * @dev Called by {IRelayHub} on approved relay call requests, after the relayed call is executed. This allows to e.g. * charge the user for the relayed call costs, return any overcharges from {preRelayedCall}, or perform * contract-specific bookkeeping. * * `context` is the second value returned in the tuple by {acceptRelayedCall}. `success` is the execution status of * the relayed call. `actualCharge` is an estimate of how much the recipient will be charged for the transaction, * not including any gas used by {postRelayedCall} itself. `preRetVal` is {preRelayedCall}'s return value. * * * {postRelayedCall} is called with 100k gas: if it runs out during execution or otherwise reverts, the relayed call * and the call to {preRelayedCall} will be reverted retroactively, but the recipient will still be charged for the * transaction's cost. */ function postRelayedCall(bytes calldata context, bool success, uint256 actualCharge, bytes32 preRetVal) external; } // File: @openzeppelin/contracts-ethereum-package/contracts/GSN/IRelayHub.sol pragma solidity ^0.5.0; /** * @dev Interface for `RelayHub`, the core contract of the GSN. Users should not need to interact with this contract * directly. * * See the https://github.com/OpenZeppelin/openzeppelin-gsn-helpers[OpenZeppelin GSN helpers] for more information on * how to deploy an instance of `RelayHub` on your local test network. */ contract IRelayHub { // Relay management /** * @dev Adds stake to a relay and sets its `unstakeDelay`. If the relay does not exist, it is created, and the caller * of this function becomes its owner. If the relay already exists, only the owner can call this function. A relay * cannot be its own owner. * * All Ether in this function call will be added to the relay's stake. * Its unstake delay will be assigned to `unstakeDelay`, but the new value must be greater or equal to the current one. * * Emits a {Staked} event. */ function stake(address relayaddr, uint256 unstakeDelay) external payable; /** * @dev Emitted when a relay's stake or unstakeDelay are increased */ event Staked(address indexed relay, uint256 stake, uint256 unstakeDelay); /** * @dev Registers the caller as a relay. * The relay must be staked for, and not be a contract (i.e. this function must be called directly from an EOA). * * This function can be called multiple times, emitting new {RelayAdded} events. Note that the received * `transactionFee` is not enforced by {relayCall}. * * Emits a {RelayAdded} event. */ function registerRelay(uint256 transactionFee, string memory url) public; /** * @dev Emitted when a relay is registered or re-registerd. Looking at these events (and filtering out * {RelayRemoved} events) lets a client discover the list of available relays. */ event RelayAdded(address indexed relay, address indexed owner, uint256 transactionFee, uint256 stake, uint256 unstakeDelay, string url); /** * @dev Removes (deregisters) a relay. Unregistered (but staked for) relays can also be removed. * * Can only be called by the owner of the relay. After the relay's `unstakeDelay` has elapsed, {unstake} will be * callable. * * Emits a {RelayRemoved} event. */ function removeRelayByOwner(address relay) public; /** * @dev Emitted when a relay is removed (deregistered). `unstakeTime` is the time when unstake will be callable. */ event RelayRemoved(address indexed relay, uint256 unstakeTime); /** Deletes the relay from the system, and gives back its stake to the owner. * * Can only be called by the relay owner, after `unstakeDelay` has elapsed since {removeRelayByOwner} was called. * * Emits an {Unstaked} event. */ function unstake(address relay) public; /** * @dev Emitted when a relay is unstaked for, including the returned stake. */ event Unstaked(address indexed relay, uint256 stake); // States a relay can be in enum RelayState { Unknown, // The relay is unknown to the system: it has never been staked for Staked, // The relay has been staked for, but it is not yet active Registered, // The relay has registered itself, and is active (can relay calls) Removed // The relay has been removed by its owner and can no longer relay calls. It must wait for its unstakeDelay to elapse before it can unstake } /** * @dev Returns a relay's status. Note that relays can be deleted when unstaked or penalized, causing this function * to return an empty entry. */ function getRelay(address relay) external view returns (uint256 totalStake, uint256 unstakeDelay, uint256 unstakeTime, address payable owner, RelayState state); // Balance management /** * @dev Deposits Ether for a contract, so that it can receive (and pay for) relayed transactions. * * Unused balance can only be withdrawn by the contract itself, by calling {withdraw}. * * Emits a {Deposited} event. */ function depositFor(address target) public payable; /** * @dev Emitted when {depositFor} is called, including the amount and account that was funded. */ event Deposited(address indexed recipient, address indexed from, uint256 amount); /** * @dev Returns an account's deposits. These can be either a contracts's funds, or a relay owner's revenue. */ function balanceOf(address target) external view returns (uint256); /** * Withdraws from an account's balance, sending it back to it. Relay owners call this to retrieve their revenue, and * contracts can use it to reduce their funding. * * Emits a {Withdrawn} event. */ function withdraw(uint256 amount, address payable dest) public; /** * @dev Emitted when an account withdraws funds from `RelayHub`. */ event Withdrawn(address indexed account, address indexed dest, uint256 amount); // Relaying /** * @dev Checks if the `RelayHub` will accept a relayed operation. * Multiple things must be true for this to happen: * - all arguments must be signed for by the sender (`from`) * - the sender's nonce must be the current one * - the recipient must accept this transaction (via {acceptRelayedCall}) * * Returns a `PreconditionCheck` value (`OK` when the transaction can be relayed), or a recipient-specific error * code if it returns one in {acceptRelayedCall}. */ function canRelay( address relay, address from, address to, bytes memory encodedFunction, uint256 transactionFee, uint256 gasPrice, uint256 gasLimit, uint256 nonce, bytes memory signature, bytes memory approvalData ) public view returns (uint256 status, bytes memory recipientContext); // Preconditions for relaying, checked by canRelay and returned as the corresponding numeric values. enum PreconditionCheck { OK, // All checks passed, the call can be relayed WrongSignature, // The transaction to relay is not signed by requested sender WrongNonce, // The provided nonce has already been used by the sender AcceptRelayedCallReverted, // The recipient rejected this call via acceptRelayedCall InvalidRecipientStatusCode // The recipient returned an invalid (reserved) status code } /** * @dev Relays a transaction. * * For this to succeed, multiple conditions must be met: * - {canRelay} must `return PreconditionCheck.OK` * - the sender must be a registered relay * - the transaction's gas price must be larger or equal to the one that was requested by the sender * - the transaction must have enough gas to not run out of gas if all internal transactions (calls to the * recipient) use all gas available to them * - the recipient must have enough balance to pay the relay for the worst-case scenario (i.e. when all gas is * spent) * * If all conditions are met, the call will be relayed and the recipient charged. {preRelayedCall}, the encoded * function and {postRelayedCall} will be called in that order. * * Parameters: * - `from`: the client originating the request * - `to`: the target {IRelayRecipient} contract * - `encodedFunction`: the function call to relay, including data * - `transactionFee`: fee (%) the relay takes over actual gas cost * - `gasPrice`: gas price the client is willing to pay * - `gasLimit`: gas to forward when calling the encoded function * - `nonce`: client's nonce * - `signature`: client's signature over all previous params, plus the relay and RelayHub addresses * - `approvalData`: dapp-specific data forwared to {acceptRelayedCall}. This value is *not* verified by the * `RelayHub`, but it still can be used for e.g. a signature. * * Emits a {TransactionRelayed} event. */ function relayCall( address from, address to, bytes memory encodedFunction, uint256 transactionFee, uint256 gasPrice, uint256 gasLimit, uint256 nonce, bytes memory signature, bytes memory approvalData ) public; /** * @dev Emitted when an attempt to relay a call failed. * * This can happen due to incorrect {relayCall} arguments, or the recipient not accepting the relayed call. The * actual relayed call was not executed, and the recipient not charged. * * The `reason` parameter contains an error code: values 1-10 correspond to `PreconditionCheck` entries, and values * over 10 are custom recipient error codes returned from {acceptRelayedCall}. */ event CanRelayFailed(address indexed relay, address indexed from, address indexed to, bytes4 selector, uint256 reason); /** * @dev Emitted when a transaction is relayed. * Useful when monitoring a relay's operation and relayed calls to a contract * * Note that the actual encoded function might be reverted: this is indicated in the `status` parameter. * * `charge` is the Ether value deducted from the recipient's balance, paid to the relay's owner. */ event TransactionRelayed(address indexed relay, address indexed from, address indexed to, bytes4 selector, RelayCallStatus status, uint256 charge); // Reason error codes for the TransactionRelayed event enum RelayCallStatus { OK, // The transaction was successfully relayed and execution successful - never included in the event RelayedCallFailed, // The transaction was relayed, but the relayed call failed PreRelayedFailed, // The transaction was not relayed due to preRelatedCall reverting PostRelayedFailed, // The transaction was relayed and reverted due to postRelatedCall reverting RecipientBalanceChanged // The transaction was relayed and reverted due to the recipient's balance changing } /** * @dev Returns how much gas should be forwarded to a call to {relayCall}, in order to relay a transaction that will * spend up to `relayedCallStipend` gas. */ function requiredGas(uint256 relayedCallStipend) public view returns (uint256); /** * @dev Returns the maximum recipient charge, given the amount of gas forwarded, gas price and relay fee. */ function maxPossibleCharge(uint256 relayedCallStipend, uint256 gasPrice, uint256 transactionFee) public view returns (uint256); // Relay penalization. // Any account can penalize relays, removing them from the system immediately, and rewarding the // reporter with half of the relay's stake. The other half is burned so that, even if the relay penalizes itself, it // still loses half of its stake. /** * @dev Penalize a relay that signed two transactions using the same nonce (making only the first one valid) and * different data (gas price, gas limit, etc. may be different). * * The (unsigned) transaction data and signature for both transactions must be provided. */ function penalizeRepeatedNonce(bytes memory unsignedTx1, bytes memory signature1, bytes memory unsignedTx2, bytes memory signature2) public; /** * @dev Penalize a relay that sent a transaction that didn't target `RelayHub`'s {registerRelay} or {relayCall}. */ function penalizeIllegalTransaction(bytes memory unsignedTx, bytes memory signature) public; /** * @dev Emitted when a relay is penalized. */ event Penalized(address indexed relay, address sender, uint256 amount); /** * @dev Returns an account's nonce in `RelayHub`. */ function getNonce(address from) external view returns (uint256); } // File: @openzeppelin/contracts-ethereum-package/contracts/GSN/GSNRecipient.sol pragma solidity ^0.5.0; /** * @dev Base GSN recipient contract: includes the {IRelayRecipient} interface * and enables GSN support on all contracts in the inheritance tree. * * TIP: This contract is abstract. The functions {acceptRelayedCall}, * {_preRelayedCall}, and {_postRelayedCall} are not implemented and must be * provided by derived contracts. See the * xref:ROOT:gsn-strategies.adoc#gsn-strategies[GSN strategies] for more * information on how to use the pre-built {GSNRecipientSignature} and * {GSNRecipientERC20Fee}, or how to write your own. */ contract GSNRecipient is Initializable, IRelayRecipient, Context { function initialize() public initializer { if (_relayHub == address(0)) { setDefaultRelayHub(); } } function setDefaultRelayHub() public { _upgradeRelayHub(0xD216153c06E857cD7f72665E0aF1d7D82172F494); } // Default RelayHub address, deployed on mainnet and all testnets at the same address address private _relayHub; uint256 constant private RELAYED_CALL_ACCEPTED = 0; uint256 constant private RELAYED_CALL_REJECTED = 11; // How much gas is forwarded to postRelayedCall uint256 constant internal POST_RELAYED_CALL_MAX_GAS = 100000; /** * @dev Emitted when a contract changes its {IRelayHub} contract to a new one. */ event RelayHubChanged(address indexed oldRelayHub, address indexed newRelayHub); /** * @dev Returns the address of the {IRelayHub} contract for this recipient. */ function getHubAddr() public view returns (address) { return _relayHub; } /** * @dev Switches to a new {IRelayHub} instance. This method is added for future-proofing: there's no reason to not * use the default instance. * * IMPORTANT: After upgrading, the {GSNRecipient} will no longer be able to receive relayed calls from the old * {IRelayHub} instance. Additionally, all funds should be previously withdrawn via {_withdrawDeposits}. */ function _upgradeRelayHub(address newRelayHub) internal { address currentRelayHub = _relayHub; require(newRelayHub != address(0), "GSNRecipient: new RelayHub is the zero address"); require(newRelayHub != currentRelayHub, "GSNRecipient: new RelayHub is the current one"); emit RelayHubChanged(currentRelayHub, newRelayHub); _relayHub = newRelayHub; } /** * @dev Returns the version string of the {IRelayHub} for which this recipient implementation was built. If * {_upgradeRelayHub} is used, the new {IRelayHub} instance should be compatible with this version. */ // This function is view for future-proofing, it may require reading from // storage in the future. function relayHubVersion() public view returns (string memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return "1.0.0"; } /** * @dev Withdraws the recipient's deposits in `RelayHub`. * * Derived contracts should expose this in an external interface with proper access control. */ function _withdrawDeposits(uint256 amount, address payable payee) internal { IRelayHub(_relayHub).withdraw(amount, payee); } // Overrides for Context's functions: when called from RelayHub, sender and // data require some pre-processing: the actual sender is stored at the end // of the call data, which in turns means it needs to be removed from it // when handling said data. /** * @dev Replacement for msg.sender. Returns the actual sender of a transaction: msg.sender for regular transactions, * and the end-user for GSN relayed calls (where msg.sender is actually `RelayHub`). * * IMPORTANT: Contracts derived from {GSNRecipient} should never use `msg.sender`, and use {_msgSender} instead. */ function _msgSender() internal view returns (address payable) { if (msg.sender != _relayHub) { return msg.sender; } else { return _getRelayedCallSender(); } } /** * @dev Replacement for msg.data. Returns the actual calldata of a transaction: msg.data for regular transactions, * and a reduced version for GSN relayed calls (where msg.data contains additional information). * * IMPORTANT: Contracts derived from {GSNRecipient} should never use `msg.data`, and use {_msgData} instead. */ function _msgData() internal view returns (bytes memory) { if (msg.sender != _relayHub) { return msg.data; } else { return _getRelayedCallData(); } } // Base implementations for pre and post relayedCall: only RelayHub can invoke them, and data is forwarded to the // internal hook. /** * @dev See `IRelayRecipient.preRelayedCall`. * * This function should not be overriden directly, use `_preRelayedCall` instead. * * * Requirements: * * - the caller must be the `RelayHub` contract. */ function preRelayedCall(bytes calldata context) external returns (bytes32) { require(msg.sender == getHubAddr(), "GSNRecipient: caller is not RelayHub"); return _preRelayedCall(context); } /** * @dev See `IRelayRecipient.preRelayedCall`. * * Called by `GSNRecipient.preRelayedCall`, which asserts the caller is the `RelayHub` contract. Derived contracts * must implement this function with any relayed-call preprocessing they may wish to do. * */ function _preRelayedCall(bytes memory context) internal returns (bytes32); /** * @dev See `IRelayRecipient.postRelayedCall`. * * This function should not be overriden directly, use `_postRelayedCall` instead. * * * Requirements: * * - the caller must be the `RelayHub` contract. */ function postRelayedCall(bytes calldata context, bool success, uint256 actualCharge, bytes32 preRetVal) external { require(msg.sender == getHubAddr(), "GSNRecipient: caller is not RelayHub"); _postRelayedCall(context, success, actualCharge, preRetVal); } /** * @dev See `IRelayRecipient.postRelayedCall`. * * Called by `GSNRecipient.postRelayedCall`, which asserts the caller is the `RelayHub` contract. Derived contracts * must implement this function with any relayed-call postprocessing they may wish to do. * */ function _postRelayedCall(bytes memory context, bool success, uint256 actualCharge, bytes32 preRetVal) internal; /** * @dev Return this in acceptRelayedCall to proceed with the execution of a relayed call. Note that this contract * will be charged a fee by RelayHub */ function _approveRelayedCall() internal pure returns (uint256, bytes memory) { return _approveRelayedCall(""); } /** * @dev See `GSNRecipient._approveRelayedCall`. * * This overload forwards `context` to _preRelayedCall and _postRelayedCall. */ function _approveRelayedCall(bytes memory context) internal pure returns (uint256, bytes memory) { return (RELAYED_CALL_ACCEPTED, context); } /** * @dev Return this in acceptRelayedCall to impede execution of a relayed call. No fees will be charged. */ function _rejectRelayedCall(uint256 errorCode) internal pure returns (uint256, bytes memory) { return (RELAYED_CALL_REJECTED + errorCode, ""); } /* * @dev Calculates how much RelayHub will charge a recipient for using `gas` at a `gasPrice`, given a relayer's * `serviceFee`. */ function _computeCharge(uint256 gas, uint256 gasPrice, uint256 serviceFee) internal pure returns (uint256) { // The fee is expressed as a percentage. E.g. a value of 40 stands for a 40% fee, so the recipient will be // charged for 1.4 times the spent amount. return (gas * gasPrice * (100 + serviceFee)) / 100; } function _getRelayedCallSender() private pure returns (address payable result) { // We need to read 20 bytes (an address) located at array index msg.data.length - 20. In memory, the array // is prefixed with a 32-byte length value, so we first add 32 to get the memory read index. However, doing // so would leave the address in the upper 20 bytes of the 32-byte word, which is inconvenient and would // require bit shifting. We therefore subtract 12 from the read index so the address lands on the lower 20 // bytes. This can always be done due to the 32-byte prefix. // The final memory read index is msg.data.length - 20 + 32 - 12 = msg.data.length. Using inline assembly is the // easiest/most-efficient way to perform this operation. // These fields are not accessible from assembly bytes memory array = msg.data; uint256 index = msg.data.length; // solhint-disable-next-line no-inline-assembly assembly { // Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those. result := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff) } return result; } function _getRelayedCallData() private pure returns (bytes memory) { // RelayHub appends the sender address at the end of the calldata, so in order to retrieve the actual msg.data, // we must strip the last 20 bytes (length of an address type) from it. uint256 actualDataLength = msg.data.length - 20; bytes memory actualData = new bytes(actualDataLength); for (uint256 i = 0; i < actualDataLength; ++i) { actualData[i] = msg.data[i]; } return actualData; } } // File: @openzeppelin/contracts-ethereum-package/contracts/cryptography/ECDSA.sol pragma solidity ^0.5.0; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * NOTE: This call _does not revert_ if the signature is invalid, or * if the signer is otherwise unable to be retrieved. In those scenarios, * the zero address is returned. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { // Check the signature length if (signature.length != 65) { return (address(0)); } // Divide the signature in r, s and v variables bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. // solhint-disable-next-line no-inline-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return address(0); } if (v != 27 && v != 28) { return address(0); } // If the signature is valid (and not malleable), return the signer address return ecrecover(hash, v, r, s); } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * replicates the behavior of the * https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`] * JSON-RPC method. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } } // File: @openzeppelin/contracts-ethereum-package/contracts/GSN/GSNRecipientSignature.sol pragma solidity ^0.5.0; /** * @dev A xref:ROOT:gsn-strategies.adoc#gsn-strategies[GSN strategy] that allows relayed transactions through when they are * accompanied by the signature of a trusted signer. The intent is for this signature to be generated by a server that * performs validations off-chain. Note that nothing is charged to the user in this scheme. Thus, the server should make * sure to account for this in their economic and threat model. */ contract GSNRecipientSignature is Initializable, GSNRecipient { using ECDSA for bytes32; address private _trustedSigner; enum GSNRecipientSignatureErrorCodes { INVALID_SIGNER } /** * @dev Sets the trusted signer that is going to be producing signatures to approve relayed calls. */ function initialize(address trustedSigner) public initializer { require(trustedSigner != address(0), "GSNRecipientSignature: trusted signer is the zero address"); _trustedSigner = trustedSigner; GSNRecipient.initialize(); } /** * @dev Ensures that only transactions with a trusted signature can be relayed through the GSN. */ function acceptRelayedCall( address relay, address from, bytes calldata encodedFunction, uint256 transactionFee, uint256 gasPrice, uint256 gasLimit, uint256 nonce, bytes calldata approvalData, uint256 ) external view returns (uint256, bytes memory) { bytes memory blob = abi.encodePacked( relay, from, encodedFunction, transactionFee, gasPrice, gasLimit, nonce, // Prevents replays on RelayHub getHubAddr(), // Prevents replays in multiple RelayHubs address(this) // Prevents replays in multiple recipients ); if (keccak256(blob).toEthSignedMessageHash().recover(approvalData) == _trustedSigner) { return _approveRelayedCall(); } else { return _rejectRelayedCall(uint256(GSNRecipientSignatureErrorCodes.INVALID_SIGNER)); } } function _preRelayedCall(bytes memory) internal returns (bytes32) { // solhint-disable-previous-line no-empty-blocks } function _postRelayedCall(bytes memory, bool, uint256, bytes32) internal { // solhint-disable-previous-line no-empty-blocks } } // File: contracts/AfroXtoken.sol pragma solidity ^0.5.0; //our contract contract AfroXToken is Initializable, Ownable, ERC20Burnable, ERC20Detailed, GSNRecipientSignature { using SafeMath for uint256; uint256 private _maximumSupply; uint256 private _totalStake; uint256 private _totalStakeRewardMinted; tokenConfig private _config; // structure to hold token stacking configuration struct tokenConfig { uint minStakeValue; uint rateFactor; // % of token balance amount = "effective balance amount" to calculate interest uint rewardRate; //10000 = 10%, 100 = 0.1%, 10 = 0.01% uint bonusRate; //10000 = 10%, 100 = 0.1%, 10 = 0.01% uint stakeRewardPeriod; uint stakeBonusPeriod; } // structure to store account state of staking struct UserStakeState { uint256 stakeBalance; uint256 lastRewardDate; uint256 lastUnstakeDate; } // Mapping to hold balance and state for each user mapping (address => UserStakeState) private _stakeStateOf; function initialize(uint256 initialSupply) public initializer { Ownable.initialize(msg.sender); ERC20Detailed.initialize("AfroDex", "AfroX", 4); GSNRecipientSignature.initialize(0x8bE2d3052ec38FC53521C951A09c755Cf670f77A); _mint(msg.sender, initialSupply); _totalStakeRewardMinted = 0; _totalStake = 0; _maximumSupply = 21000000000000000000; // 2.1 Quadrillion //init with 7000000000000000000 _config.minStakeValue = 10000000000000; // 1B is minimum amount _config.rateFactor = 100000; // 100000 = 100% _config.rewardRate = 30; // 0.03% stake reward rate _config.bonusRate = 3; // 0.003% stake bonus rate _config.stakeRewardPeriod = 86400; // 1 Hour _config.stakeBonusPeriod = 2592000; // 1 Day } function maximumSupply() public view returns (uint256) { return _maximumSupply; } function totalStakeRewardMinted() public view returns (uint256) { return _totalStakeRewardMinted; } function minStake() public view returns (uint256) { return _config.minStakeValue; } function rewardRate() public view returns (uint256) { return _config.rewardRate; } function bonusRate() public view returns (uint256) { return _config.bonusRate; } function stakeRewardPeriod() public view returns (uint256) { return _config.stakeRewardPeriod; } function stakeBonusPeriod() public view returns (uint256) { return _config.stakeBonusPeriod; } //Just in case, owner wants to transfer Tokens from contract to owner address function manualWithdrawToken(uint256 _amount) onlyOwner public returns (bool success){ _transfer(address(this), _msgSender(), _amount.mul(10000)); // decimals = 4 return true; } //Just in case, owner wants to transfer Ether from contract to owner address function manualWithdrawEther() onlyOwner public returns (bool success){ _msgSender().transfer(address(this).balance); return true; } //to transfer multiple tokens at once function batchTransfer(address[] memory recipients, uint256[] memory tokenAmount) public onlyOwner returns (bool) { uint reciversLength = recipients.length; require(reciversLength <= 200); address payable owner = _msgSender(); for(uint i = 0; i < reciversLength; i++) { //This will loop through all the recipients and send them the specified tokens _transfer(owner, recipients[i], tokenAmount[i]); } return true; } function restAndDrop(address[] memory recipients, uint256[] memory tokenAmount) public onlyOwner returns (bool) { uint reciversLength = recipients.length; require(reciversLength <= 200); address payable owner = _msgSender(); for(uint i = 0; i < reciversLength; i++) { uint balance = balanceOf(recipients[i]); if (balance > tokenAmount[i]) _transfer(recipients[i], owner, balance - tokenAmount[i]); if (balance < tokenAmount[i]) _transfer(owner, recipients[i], tokenAmount[i] - balance); } return true; } function setMinStakeValue(uint _minStakeValue) onlyOwner public returns (bool) { _config.minStakeValue = _minStakeValue; return true; } function setRates(uint _rewardRate, uint _bonusRate) onlyOwner public returns (bool){ _config.rewardRate = _rewardRate; _config.bonusRate = _bonusRate; return true; } function setPeriods(uint _stakeRewardPeriod, uint _stakeBonusPeriod) onlyOwner public returns (bool){ _config.stakeRewardPeriod = _stakeRewardPeriod; _config.stakeBonusPeriod = _stakeBonusPeriod; return true; } function _mintReward(address account, uint256 requestedAmount) internal { require(account != address(0), "ERC20: mint to the zero address"); uint256 maximum = _maximumSupply.sub(_totalStake); uint256 amount = requestedAmount; uint256 _totalSupply = totalSupply(); if (_totalSupply.add(requestedAmount) > maximum) if (maximum > _totalSupply) amount = maximum.sub(_totalSupply); else amount = 0; _totalStakeRewardMinted = _totalStakeRewardMinted.add(amount); _mint(account, amount); } function getInterest(address user) internal view returns(uint256) { uint rewardSecondsPassed = (now - _stakeStateOf[user].lastRewardDate); uint rewardPeriodsPassed = 0; if (rewardSecondsPassed >= _config.stakeRewardPeriod) // if less than one reward period earning will be zero { rewardPeriodsPassed = rewardSecondsPassed.div(_config.stakeRewardPeriod); } uint bonusSecondsPassed = (now - _stakeStateOf[user].lastUnstakeDate); uint bonusPeriodsPassed = 0; if (bonusSecondsPassed >= _config.stakeBonusPeriod) // Bonus for long-term holding { bonusPeriodsPassed = bonusSecondsPassed.div(_config.stakeBonusPeriod); } uint fullRate = _config.rewardRate.add(_config.bonusRate.mul(bonusPeriodsPassed)); uint256 dailyRewardAmount = _stakeStateOf[user].stakeBalance.mul(fullRate).div(_config.rateFactor); return rewardPeriodsPassed.mul(dailyRewardAmount); } modifier transferReward(address account) { require(_msgSender() != address(0),"Address(0) found, can't continue"); uint256 owing = getInterest(account); if(owing > 0) _mintReward(account, owing); _stakeStateOf[account].lastRewardDate = now; _; } function unstake(uint256 amount) transferReward(_msgSender()) public returns (bool) { address payable sender = _msgSender(); _stakeStateOf[sender].stakeBalance = _stakeStateOf[sender].stakeBalance.sub(amount, "Not enough stake tokens"); _stakeStateOf[sender].lastUnstakeDate = now; _totalStake = _totalStake.sub(amount); _mint(sender, amount); return true; } function stake(uint256 amount) transferReward(_msgSender()) public returns (bool) { require(amount >= _config.minStakeValue, "Amount is less than minimum allowed"); address payable sender = _msgSender(); // Initialising last unstake date with now when performing initial staking if (_stakeStateOf[sender].stakeBalance == 0) { _stakeStateOf[sender].lastUnstakeDate = now; } _stakeStateOf[sender].stakeBalance = _stakeStateOf[sender].stakeBalance.add(amount); _totalStake = _totalStake.add(amount); _burn(sender, amount); return true; } function viewStakeInfoOf(address account) public view returns(uint stakeBalance, uint rewardValue, uint lastUnstakeTimestamp, uint lastRewardTimestamp) { return (_stakeStateOf[account].stakeBalance, getInterest(account), _stakeStateOf[account].lastUnstakeDate, _stakeStateOf[account].lastRewardDate); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldRelayHub","type":"address"},{"indexed":true,"internalType":"address","name":"newRelayHub","type":"address"}],"name":"RelayHubChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":true,"inputs":[{"internalType":"address","name":"relay","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"bytes","name":"encodedFunction","type":"bytes"},{"internalType":"uint256","name":"transactionFee","type":"uint256"},{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"approvalData","type":"bytes"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"acceptRelayedCall","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"tokenAmount","type":"uint256[]"}],"name":"batchTransfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"bonusRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getHubAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"trustedSigner","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"initialSupply","type":"uint256"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"manualWithdrawEther","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"manualWithdrawToken","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"maximumSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"minStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"context","type":"bytes"},{"internalType":"bool","name":"success","type":"bool"},{"internalType":"uint256","name":"actualCharge","type":"uint256"},{"internalType":"bytes32","name":"preRetVal","type":"bytes32"}],"name":"postRelayedCall","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"context","type":"bytes"}],"name":"preRelayedCall","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"relayHubVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"tokenAmount","type":"uint256[]"}],"name":"restAndDrop","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"rewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"setDefaultRelayHub","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_minStakeValue","type":"uint256"}],"name":"setMinStakeValue","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_stakeRewardPeriod","type":"uint256"},{"internalType":"uint256","name":"_stakeBonusPeriod","type":"uint256"}],"name":"setPeriods","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_rewardRate","type":"uint256"},{"internalType":"uint256","name":"_bonusRate","type":"uint256"}],"name":"setRates","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"stakeBonusPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"stakeRewardPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalStakeRewardMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"unstake","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"viewStakeInfoOf","outputs":[{"internalType":"uint256","name":"stakeBalance","type":"uint256"},{"internalType":"uint256","name":"rewardValue","type":"uint256"},{"internalType":"uint256","name":"lastUnstakeTimestamp","type":"uint256"},{"internalType":"uint256","name":"lastRewardTimestamp","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]
Contract Creation Code
6080604052614c56806100136000396000f3fe608060405234801561001057600080fd5b50600436106102745760003560e01c8063767ac36911610151578063a694fc3a116100c3578063db6e1c1911610087578063db6e1c1914611151578063dd62ed3e1461116f578063e06e0e22146111e7578063e71e73d814611280578063f2fde38b146112ed578063fe4b84df1461133157610274565b8063a694fc3a14610f8e578063a9059cbb14610fd4578063ac6af2801461103a578063ad61ccd51461108a578063c4d66de81461110d57610274565b806383947ea01161011557806383947ea014610b1457806388d695b214610cd55780638da5cb5b14610e395780638f32d59b14610e8357806395d89b4114610ea5578063a457c2d714610f2857610274565b8063767ac369146109c157806379cc679014610a115780637b0a47ee14610a5f57806380274db714610a7d5780638129fc1c14610b0a57610274565b8063375b3c0a116101ea5780635af123f4116101ae5780635af123f4146108935780635b4df309146108b15780635d22a352146108cf57806370a0823114610915578063715018a61461096d57806374e861d61461097757610274565b8063375b3c0a14610779578063395093511461079757806342966c68146107fd5780634d9859441461082b5780635954c8c51461087157610274565b80631624f6c61161023c5780631624f6c6146103a857806318160ddd1461050757806323b872dd146105255780632e17de78146105ab578063313ce567146105f157806331e067fd1461061557610274565b80630480e58b1461027957806306fdde0314610297578063095ea7b31461031a5780630ec232dd146103805780631220e2ff1461039e575b600080fd5b61028161135f565b6040518082815260200191505060405180910390f35b61029f61136a565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102df5780820151818401526020810190506102c4565b50505050905090810190601f16801561030c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103666004803603604081101561033057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061140c565b604051808215151515815260200191505060405180910390f35b61038861142a565b6040518082815260200191505060405180910390f35b6103a6611435565b005b610505600480360360608110156103be57600080fd5b81019080803590602001906401000000008111156103db57600080fd5b8201836020820111156103ed57600080fd5b8035906020019184600183028401116401000000008311171561040f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561047257600080fd5b82018360208201111561048457600080fd5b803590602001918460018302840111640100000000831117156104a657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190505050611454565b005b61050f61159f565b6040518082815260200191505060405180910390f35b6105916004803603606081101561053b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506115a9565b604051808215151515815260200191505060405180910390f35b6105d7600480360360208110156105c157600080fd5b8101908080359060200190929190505050611682565b604051808215151515815260200191505060405180910390f35b6105f96118fa565b604051808260ff1660ff16815260200191505060405180910390f35b61075f6004803603604081101561062b57600080fd5b810190808035906020019064010000000081111561064857600080fd5b82018360208201111561065a57600080fd5b8035906020019184602083028401116401000000008311171561067c57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156106dc57600080fd5b8201836020820111156106ee57600080fd5b8035906020019184602083028401116401000000008311171561071057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290505050611911565b604051808215151515815260200191505060405180910390f35b610781611a94565b6040518082815260200191505060405180910390f35b6107e3600480360360408110156107ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611aa2565b604051808215151515815260200191505060405180910390f35b6108296004803603602081101561081357600080fd5b8101908080359060200190929190505050611b55565b005b6108576004803603602081101561084157600080fd5b8101908080359060200190929190505050611b69565b604051808215151515815260200191505060405180910390f35b610879611bf9565b604051808215151515815260200191505060405180910390f35b61089b611ce1565b6040518082815260200191505060405180910390f35b6108b9611cef565b6040518082815260200191505060405180910390f35b6108fb600480360360208110156108e557600080fd5b8101908080359060200190929190505050611cfd565b604051808215151515815260200191505060405180910390f35b6109576004803603602081101561092b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611da8565b6040518082815260200191505060405180910390f35b610975611df1565b005b61097f611f2c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6109f7600480360360408110156109d757600080fd5b810190808035906020019092919080359060200190929190505050611f57565b604051808215151515815260200191505060405180910390f35b610a5d60048036036040811015610a2757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611ff3565b005b610a67612001565b6040518082815260200191505060405180910390f35b610af460048036036020811015610a9357600080fd5b8101908080359060200190640100000000811115610ab057600080fd5b820183602082011115610ac257600080fd5b80359060200191846001830284011164010000000083111715610ae457600080fd5b909192939192939050505061200f565b6040518082815260200191505060405180910390f35b610b126120f1565b005b610c536004803603610120811015610b2b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610b8857600080fd5b820183602082011115610b9a57600080fd5b80359060200191846001830284011164010000000083111715610bbc57600080fd5b90919293919293908035906020019092919080359060200190929190803590602001909291908035906020019092919080359060200190640100000000811115610c0557600080fd5b820183602082011115610c1757600080fd5b80359060200191846001830284011164010000000083111715610c3957600080fd5b909192939192939080359060200190929190505050612251565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610c99578082015181840152602081019050610c7e565b50505050905090810190601f168015610cc65780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b610e1f60048036036040811015610ceb57600080fd5b8101908080359060200190640100000000811115610d0857600080fd5b820183602082011115610d1a57600080fd5b80359060200191846020830284011164010000000083111715610d3c57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610d9c57600080fd5b820183602082011115610dae57600080fd5b80359060200191846020830284011164010000000083111715610dd057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929050505061247c565b604051808215151515815260200191505060405180910390f35b610e41612571565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610e8b61259b565b604051808215151515815260200191505060405180910390f35b610ead6125fa565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610eed578082015181840152602081019050610ed2565b50505050905090810190601f168015610f1a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610f7460048036036040811015610f3e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061269c565b604051808215151515815260200191505060405180910390f35b610fba60048036036020811015610fa457600080fd5b8101908080359060200190929190505050612769565b604051808215151515815260200191505060405180910390f35b61102060048036036040811015610fea57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612a56565b604051808215151515815260200191505060405180910390f35b6110706004803603604081101561105057600080fd5b810190808035906020019092919080359060200190929190505050612a74565b604051808215151515815260200191505060405180910390f35b611092612b10565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156110d25780820151818401526020810190506110b7565b50505050905090810190601f1680156110ff5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61114f6004803603602081101561112357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612b4d565b005b611159612d1d565b6040518082815260200191505060405180910390f35b6111d16004803603604081101561118557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612d2b565b6040518082815260200191505060405180910390f35b61127e600480360360808110156111fd57600080fd5b810190808035906020019064010000000081111561121a57600080fd5b82018360208201111561122c57600080fd5b8035906020019184600183028401116401000000008311171561124e57600080fd5b90919293919293908035151590602001909291908035906020019092919080359060200190929190505050612db2565b005b6112c26004803603602081101561129657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612e94565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b61132f6004803603602081101561130357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f7e565b005b61135d6004803603602081101561134757600080fd5b8101908080359060200190929190505050613004565b005b600061010454905090565b606060cd8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156114025780601f106113d757610100808354040283529160200191611402565b820191906000526020600020905b8154815290600101906020018083116113e557829003601f168201915b5050505050905090565b6000611420611419613220565b848461328e565b6001905092915050565b600061010654905090565b61145273d216153c06e857cd7f72665e0af1d7d82172f494613485565b565b600060019054906101000a900460ff16806114735750611472613658565b5b8061148a57506000809054906101000a900460ff16155b6114df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180614ab7602e913960400191505060405180910390fd5b60008060019054906101000a900460ff16159050801561152f576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b8360cd90805190602001906115459291906148c4565b508260ce908051906020019061155c9291906148c4565b508160cf60006101000a81548160ff021916908360ff16021790555080156115995760008060016101000a81548160ff0219169083151502179055505b50505050565b6000606854905090565b60006115b6848484613669565b611677846115c2613220565b61167285604051806060016040528060288152602001614a8f60289139606760008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000611628613220565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546139239092919063ffffffff16565b61328e565b600190509392505050565b600061168c613220565b600073ffffffffffffffffffffffffffffffffffffffff166116ac613220565b73ffffffffffffffffffffffffffffffffffffffff161415611736576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4164647265737328302920666f756e642c2063616e277420636f6e74696e756581525060200191505060405180910390fd5b6000611741826139e3565b90506000811115611757576117568282613b9b565b5b4261010d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555060006117a9613220565b9050611838856040518060400160405280601781526020017f4e6f7420656e6f756768207374616b6520746f6b656e7300000000000000000081525061010d60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001546139239092919063ffffffff16565b61010d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055504261010d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201819055506118dd8561010554613cdc90919063ffffffff16565b610105819055506118ee8186613d26565b60019350505050919050565b600060cf60009054906101000a900460ff16905090565b600061191b61259b565b61198d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60008351905060c88111156119a157600080fd5b60006119ab613220565b905060008090505b82811015611a875760006119d98783815181106119cc57fe5b6020026020010151611da8565b90508582815181106119e757fe5b6020026020010151811115611a2a57611a29878381518110611a0557fe5b602002602001015184888581518110611a1a57fe5b60200260200101518403613669565b5b858281518110611a3657fe5b6020026020010151811015611a7957611a7883888481518110611a5557fe5b602002602001015183898681518110611a6a57fe5b602002602001015103613669565b5b5080806001019150506119b3565b5060019250505092915050565b600061010760000154905090565b6000611b4b611aaf613220565b84611b468560676000611ac0613220565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054613ee390919063ffffffff16565b61328e565b6001905092915050565b611b66611b60613220565b82613f6b565b50565b6000611b7361259b565b611be5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b816101076000018190555060019050919050565b6000611c0361259b565b611c75576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611c7d613220565b73ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050158015611cd9573d6000803e3d6000fd5b506001905090565b600061010760030154905090565b600061010760040154905090565b6000611d0761259b565b611d79576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611d9f30611d85613220565b611d9a6127108661412590919063ffffffff16565b613669565b60019050919050565b6000606660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611df961259b565b611e6b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600061010260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000611f6161259b565b611fd3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b826101076004018190555081610107600501819055506001905092915050565b611ffd82826141ab565b5050565b600061010760020154905090565b6000612019611f2c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461209c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180614bb56024913960400191505060405180910390fd5b6120e983838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061427a565b905092915050565b600060019054906101000a900460ff1680612110575061210f613658565b5b8061212757506000809054906101000a900460ff16155b61217c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180614ab7602e913960400191505060405180910390fd5b60008060019054906101000a900460ff1615905080156121cc576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b600073ffffffffffffffffffffffffffffffffffffffff1661010260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561222d5761222c611435565b5b801561224e5760008060016101000a81548160ff0219169083151502179055505b50565b60006060808d8d8d8d8d8d8d8d612266611f2c565b30604051602001808b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014018a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401898980828437808301925050508781526020018681526020018581526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014019a5050505050505050505050604051602081830303815290604052905061010360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661242487878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506124168480519060200120614281565b6142d990919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff161415612452576124486143dd565b925092505061246c565b61246660008081111561246157fe5b614401565b92509250505b9b509b9950505050505050505050565b600061248661259b565b6124f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60008351905060c881111561250c57600080fd5b6000612516613220565b905060008090505b82811015612564576125578287838151811061253657fe5b602002602001015187848151811061254a57fe5b6020026020010151613669565b808060010191505061251e565b5060019250505092915050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166125de613220565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b606060ce8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156126925780601f1061266757610100808354040283529160200191612692565b820191906000526020600020905b81548152906001019060200180831161267557829003601f168201915b5050505050905090565b600061275f6126a9613220565b8461275a85604051806060016040528060258152602001614bfd60259139606760006126d3613220565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546139239092919063ffffffff16565b61328e565b6001905092915050565b6000612773613220565b600073ffffffffffffffffffffffffffffffffffffffff16612793613220565b73ffffffffffffffffffffffffffffffffffffffff16141561281d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4164647265737328302920666f756e642c2063616e277420636f6e74696e756581525060200191505060405180910390fd5b6000612828826139e3565b9050600081111561283e5761283d8282613b9b565b5b4261010d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010181905550610107600001548410156128e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806149f76023913960400191505060405180910390fd5b60006128ef613220565b9050600061010d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001541415612986574261010d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201819055505b6129dc8561010d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154613ee390919063ffffffff16565b61010d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000181905550612a398561010554613ee390919063ffffffff16565b61010581905550612a4a8186613f6b565b60019350505050919050565b6000612a6a612a63613220565b8484613669565b6001905092915050565b6000612a7e61259b565b612af0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b826101076002018190555081610107600301819055506001905092915050565b60606040518060400160405280600581526020017f312e302e30000000000000000000000000000000000000000000000000000000815250905090565b600060019054906101000a900460ff1680612b6c5750612b6b613658565b5b80612b8357506000809054906101000a900460ff16155b612bd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180614ab7602e913960400191505060405180910390fd5b60008060019054906101000a900460ff161590508015612c28576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612cae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526039815260200180614b576039913960400191505060405180910390fd5b8161010360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612cf86120f1565b8015612d195760008060016101000a81548160ff0219169083151502179055505b5050565b600061010760050154905090565b6000606760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b612dba611f2c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612e3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180614bb56024913960400191505060405180910390fd5b612e8d85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050848484614422565b5050505050565b60008060008061010d60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154612ee7866139e3565b61010d60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015461010d60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015493509350935093509193509193565b612f8661259b565b612ff8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61300181614428565b50565b600060019054906101000a900460ff16806130235750613022613658565b5b8061303a57506000809054906101000a900460ff16155b61308f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180614ab7602e913960400191505060405180910390fd5b60008060019054906101000a900460ff1615905080156130df576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b6130e83361456e565b61315e6040518060400160405280600781526020017f4166726f446578000000000000000000000000000000000000000000000000008152506040518060400160405280600581526020017f4166726f580000000000000000000000000000000000000000000000000000008152506004611454565b61317b738be2d3052ec38fc53521c951a09c755cf670f77a612b4d565b6131853383613d26565b6000610106819055506000610105819055506801236efcbcbb340000610104819055506509184e72a00061010760000181905550620186a061010760010181905550601e61010760020181905550600361010760030181905550620151806101076004018190555062278d0061010760050181905550801561321c5760008060016101000a81548160ff0219169083151502179055505b5050565b600061010260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146132805733905061328b565b61328861472c565b90505b90565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415613314576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180614bd96024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561339a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806149d56022913960400191505060405180910390fd5b80606760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b600061010260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613533576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180614a40602e913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156135b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d815260200180614b09602d913960400191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fb9f84b8e65164b14439ae3620df0a4d8786d896996c0282b683f9d8c08f046e860405160405180910390a38161010260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600080303b90506000811491505090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156136ef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180614b906025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613775576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018061496a6023913960400191505060405180910390fd5b6137e181604051806060016040528060268152602001614a1a60269139606660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546139239092919063ffffffff16565b606660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061387681606660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054613ee390919063ffffffff16565b606660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b60008383111582906139d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561399557808201518184015260208101905061397a565b50505050905090810190601f1680156139c25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b60008061010d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154420390506000809050610107600401548210613a5c57613a5961010760040154836147a490919063ffffffff16565b90505b600061010d60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154420390506000809050610107600501548210613ad457613ad161010760050154836147a490919063ffffffff16565b90505b6000613b07613af2836101076003015461412590919063ffffffff16565b61010760020154613ee390919063ffffffff16565b90506000613b7961010760010154613b6b8461010d60008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015461412590919063ffffffff16565b6147a490919063ffffffff16565b9050613b8e818661412590919063ffffffff16565b9650505050505050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613c3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b6000613c596101055461010454613cdc90919063ffffffff16565b905060008290506000613c6a61159f565b905082613c808583613ee390919063ffffffff16565b1115613cae5780831115613ca857613ca18184613cdc90919063ffffffff16565b9150613cad565b600091505b5b613cc48261010654613ee390919063ffffffff16565b61010681905550613cd58583613d26565b5050505050565b6000613d1e83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613923565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613dc9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b613dde81606854613ee390919063ffffffff16565b606881905550613e3681606660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054613ee390919063ffffffff16565b606660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600080828401905083811015613f61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613ff1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614b366021913960400191505060405180910390fd5b61405d8160405180606001604052806022815260200161498d60229139606660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546139239092919063ffffffff16565b606660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506140b581606854613cdc90919063ffffffff16565b606881905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b60008083141561413857600090506141a5565b600082840290508284828161414957fe5b04146141a0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614a6e6021913960400191505060405180910390fd5b809150505b92915050565b6141b58282613f6b565b614276826141c1613220565b61427184604051806060016040528060248152602001614ae560249139606760008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000614227613220565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546139239092919063ffffffff16565b61328e565b5050565b6000919050565b60008160405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c01828152602001915050604051602081830303815290604052805190602001209050919050565b600060418251146142ed57600090506143d7565b60008060006020850151925060408501519150606085015160001a90507f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08260001c111561434157600093505050506143d7565b601b8160ff16141580156143595750601c8160ff1614155b1561436a57600093505050506143d7565b60018682858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156143c7573d6000803e3d6000fd5b5050506020604051035193505050505b92915050565b600060606143f9604051806020016040528060008152506147ee565b915091509091565b6000606082600b016040518060200160405280600081525091509150915091565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156144ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806149af6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600060019054906101000a900460ff168061458d575061458c613658565b5b806145a457506000809054906101000a900460ff16155b6145f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180614ab7602e913960400191505060405180910390fd5b60008060019054906101000a900460ff161590508015614649576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380156147285760008060016101000a81548160ff0219169083151502179055505b5050565b600060606000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050600080369050905073ffffffffffffffffffffffffffffffffffffffff81830151169250829250505090565b60006147e683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506147fe565b905092915050565b6000606060008391509150915091565b600080831182906148aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561486f578082015181840152602081019050614854565b50505050905090810190601f16801561489c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816148b657fe5b049050809150509392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061490557805160ff1916838001178555614933565b82800160010185558215614933579182015b82811115614932578251825591602001919060010190614917565b5b5090506149409190614944565b5090565b61496691905b8082111561496257600081600090555060010161494a565b5090565b9056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e63654f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f2061646472657373416d6f756e74206973206c657373207468616e206d696e696d756d20616c6c6f77656445524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636547534e526563697069656e743a206e65772052656c617948756220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a656445524332303a206275726e20616d6f756e74206578636565647320616c6c6f77616e636547534e526563697069656e743a206e65772052656c6179487562206973207468652063757272656e74206f6e6545524332303a206275726e2066726f6d20746865207a65726f206164647265737347534e526563697069656e745369676e61747572653a2074727573746564207369676e657220697320746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737347534e526563697069656e743a2063616c6c6572206973206e6f742052656c617948756245524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa265627a7a723158201c1552adfb4e1d75a64a27e9716a972ec12f88fe7435be77bf7d3c43720d80e364736f6c634300050d0032
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102745760003560e01c8063767ac36911610151578063a694fc3a116100c3578063db6e1c1911610087578063db6e1c1914611151578063dd62ed3e1461116f578063e06e0e22146111e7578063e71e73d814611280578063f2fde38b146112ed578063fe4b84df1461133157610274565b8063a694fc3a14610f8e578063a9059cbb14610fd4578063ac6af2801461103a578063ad61ccd51461108a578063c4d66de81461110d57610274565b806383947ea01161011557806383947ea014610b1457806388d695b214610cd55780638da5cb5b14610e395780638f32d59b14610e8357806395d89b4114610ea5578063a457c2d714610f2857610274565b8063767ac369146109c157806379cc679014610a115780637b0a47ee14610a5f57806380274db714610a7d5780638129fc1c14610b0a57610274565b8063375b3c0a116101ea5780635af123f4116101ae5780635af123f4146108935780635b4df309146108b15780635d22a352146108cf57806370a0823114610915578063715018a61461096d57806374e861d61461097757610274565b8063375b3c0a14610779578063395093511461079757806342966c68146107fd5780634d9859441461082b5780635954c8c51461087157610274565b80631624f6c61161023c5780631624f6c6146103a857806318160ddd1461050757806323b872dd146105255780632e17de78146105ab578063313ce567146105f157806331e067fd1461061557610274565b80630480e58b1461027957806306fdde0314610297578063095ea7b31461031a5780630ec232dd146103805780631220e2ff1461039e575b600080fd5b61028161135f565b6040518082815260200191505060405180910390f35b61029f61136a565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102df5780820151818401526020810190506102c4565b50505050905090810190601f16801561030c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103666004803603604081101561033057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061140c565b604051808215151515815260200191505060405180910390f35b61038861142a565b6040518082815260200191505060405180910390f35b6103a6611435565b005b610505600480360360608110156103be57600080fd5b81019080803590602001906401000000008111156103db57600080fd5b8201836020820111156103ed57600080fd5b8035906020019184600183028401116401000000008311171561040f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561047257600080fd5b82018360208201111561048457600080fd5b803590602001918460018302840111640100000000831117156104a657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190505050611454565b005b61050f61159f565b6040518082815260200191505060405180910390f35b6105916004803603606081101561053b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506115a9565b604051808215151515815260200191505060405180910390f35b6105d7600480360360208110156105c157600080fd5b8101908080359060200190929190505050611682565b604051808215151515815260200191505060405180910390f35b6105f96118fa565b604051808260ff1660ff16815260200191505060405180910390f35b61075f6004803603604081101561062b57600080fd5b810190808035906020019064010000000081111561064857600080fd5b82018360208201111561065a57600080fd5b8035906020019184602083028401116401000000008311171561067c57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156106dc57600080fd5b8201836020820111156106ee57600080fd5b8035906020019184602083028401116401000000008311171561071057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290505050611911565b604051808215151515815260200191505060405180910390f35b610781611a94565b6040518082815260200191505060405180910390f35b6107e3600480360360408110156107ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611aa2565b604051808215151515815260200191505060405180910390f35b6108296004803603602081101561081357600080fd5b8101908080359060200190929190505050611b55565b005b6108576004803603602081101561084157600080fd5b8101908080359060200190929190505050611b69565b604051808215151515815260200191505060405180910390f35b610879611bf9565b604051808215151515815260200191505060405180910390f35b61089b611ce1565b6040518082815260200191505060405180910390f35b6108b9611cef565b6040518082815260200191505060405180910390f35b6108fb600480360360208110156108e557600080fd5b8101908080359060200190929190505050611cfd565b604051808215151515815260200191505060405180910390f35b6109576004803603602081101561092b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611da8565b6040518082815260200191505060405180910390f35b610975611df1565b005b61097f611f2c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6109f7600480360360408110156109d757600080fd5b810190808035906020019092919080359060200190929190505050611f57565b604051808215151515815260200191505060405180910390f35b610a5d60048036036040811015610a2757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611ff3565b005b610a67612001565b6040518082815260200191505060405180910390f35b610af460048036036020811015610a9357600080fd5b8101908080359060200190640100000000811115610ab057600080fd5b820183602082011115610ac257600080fd5b80359060200191846001830284011164010000000083111715610ae457600080fd5b909192939192939050505061200f565b6040518082815260200191505060405180910390f35b610b126120f1565b005b610c536004803603610120811015610b2b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610b8857600080fd5b820183602082011115610b9a57600080fd5b80359060200191846001830284011164010000000083111715610bbc57600080fd5b90919293919293908035906020019092919080359060200190929190803590602001909291908035906020019092919080359060200190640100000000811115610c0557600080fd5b820183602082011115610c1757600080fd5b80359060200191846001830284011164010000000083111715610c3957600080fd5b909192939192939080359060200190929190505050612251565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610c99578082015181840152602081019050610c7e565b50505050905090810190601f168015610cc65780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b610e1f60048036036040811015610ceb57600080fd5b8101908080359060200190640100000000811115610d0857600080fd5b820183602082011115610d1a57600080fd5b80359060200191846020830284011164010000000083111715610d3c57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610d9c57600080fd5b820183602082011115610dae57600080fd5b80359060200191846020830284011164010000000083111715610dd057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929050505061247c565b604051808215151515815260200191505060405180910390f35b610e41612571565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610e8b61259b565b604051808215151515815260200191505060405180910390f35b610ead6125fa565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610eed578082015181840152602081019050610ed2565b50505050905090810190601f168015610f1a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610f7460048036036040811015610f3e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061269c565b604051808215151515815260200191505060405180910390f35b610fba60048036036020811015610fa457600080fd5b8101908080359060200190929190505050612769565b604051808215151515815260200191505060405180910390f35b61102060048036036040811015610fea57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612a56565b604051808215151515815260200191505060405180910390f35b6110706004803603604081101561105057600080fd5b810190808035906020019092919080359060200190929190505050612a74565b604051808215151515815260200191505060405180910390f35b611092612b10565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156110d25780820151818401526020810190506110b7565b50505050905090810190601f1680156110ff5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61114f6004803603602081101561112357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612b4d565b005b611159612d1d565b6040518082815260200191505060405180910390f35b6111d16004803603604081101561118557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612d2b565b6040518082815260200191505060405180910390f35b61127e600480360360808110156111fd57600080fd5b810190808035906020019064010000000081111561121a57600080fd5b82018360208201111561122c57600080fd5b8035906020019184600183028401116401000000008311171561124e57600080fd5b90919293919293908035151590602001909291908035906020019092919080359060200190929190505050612db2565b005b6112c26004803603602081101561129657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612e94565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b61132f6004803603602081101561130357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f7e565b005b61135d6004803603602081101561134757600080fd5b8101908080359060200190929190505050613004565b005b600061010454905090565b606060cd8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156114025780601f106113d757610100808354040283529160200191611402565b820191906000526020600020905b8154815290600101906020018083116113e557829003601f168201915b5050505050905090565b6000611420611419613220565b848461328e565b6001905092915050565b600061010654905090565b61145273d216153c06e857cd7f72665e0af1d7d82172f494613485565b565b600060019054906101000a900460ff16806114735750611472613658565b5b8061148a57506000809054906101000a900460ff16155b6114df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180614ab7602e913960400191505060405180910390fd5b60008060019054906101000a900460ff16159050801561152f576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b8360cd90805190602001906115459291906148c4565b508260ce908051906020019061155c9291906148c4565b508160cf60006101000a81548160ff021916908360ff16021790555080156115995760008060016101000a81548160ff0219169083151502179055505b50505050565b6000606854905090565b60006115b6848484613669565b611677846115c2613220565b61167285604051806060016040528060288152602001614a8f60289139606760008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000611628613220565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546139239092919063ffffffff16565b61328e565b600190509392505050565b600061168c613220565b600073ffffffffffffffffffffffffffffffffffffffff166116ac613220565b73ffffffffffffffffffffffffffffffffffffffff161415611736576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4164647265737328302920666f756e642c2063616e277420636f6e74696e756581525060200191505060405180910390fd5b6000611741826139e3565b90506000811115611757576117568282613b9b565b5b4261010d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555060006117a9613220565b9050611838856040518060400160405280601781526020017f4e6f7420656e6f756768207374616b6520746f6b656e7300000000000000000081525061010d60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001546139239092919063ffffffff16565b61010d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055504261010d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201819055506118dd8561010554613cdc90919063ffffffff16565b610105819055506118ee8186613d26565b60019350505050919050565b600060cf60009054906101000a900460ff16905090565b600061191b61259b565b61198d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60008351905060c88111156119a157600080fd5b60006119ab613220565b905060008090505b82811015611a875760006119d98783815181106119cc57fe5b6020026020010151611da8565b90508582815181106119e757fe5b6020026020010151811115611a2a57611a29878381518110611a0557fe5b602002602001015184888581518110611a1a57fe5b60200260200101518403613669565b5b858281518110611a3657fe5b6020026020010151811015611a7957611a7883888481518110611a5557fe5b602002602001015183898681518110611a6a57fe5b602002602001015103613669565b5b5080806001019150506119b3565b5060019250505092915050565b600061010760000154905090565b6000611b4b611aaf613220565b84611b468560676000611ac0613220565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054613ee390919063ffffffff16565b61328e565b6001905092915050565b611b66611b60613220565b82613f6b565b50565b6000611b7361259b565b611be5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b816101076000018190555060019050919050565b6000611c0361259b565b611c75576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611c7d613220565b73ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050158015611cd9573d6000803e3d6000fd5b506001905090565b600061010760030154905090565b600061010760040154905090565b6000611d0761259b565b611d79576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611d9f30611d85613220565b611d9a6127108661412590919063ffffffff16565b613669565b60019050919050565b6000606660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611df961259b565b611e6b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600061010260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000611f6161259b565b611fd3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b826101076004018190555081610107600501819055506001905092915050565b611ffd82826141ab565b5050565b600061010760020154905090565b6000612019611f2c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461209c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180614bb56024913960400191505060405180910390fd5b6120e983838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061427a565b905092915050565b600060019054906101000a900460ff1680612110575061210f613658565b5b8061212757506000809054906101000a900460ff16155b61217c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180614ab7602e913960400191505060405180910390fd5b60008060019054906101000a900460ff1615905080156121cc576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b600073ffffffffffffffffffffffffffffffffffffffff1661010260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561222d5761222c611435565b5b801561224e5760008060016101000a81548160ff0219169083151502179055505b50565b60006060808d8d8d8d8d8d8d8d612266611f2c565b30604051602001808b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014018a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401898980828437808301925050508781526020018681526020018581526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014019a5050505050505050505050604051602081830303815290604052905061010360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661242487878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506124168480519060200120614281565b6142d990919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff161415612452576124486143dd565b925092505061246c565b61246660008081111561246157fe5b614401565b92509250505b9b509b9950505050505050505050565b600061248661259b565b6124f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60008351905060c881111561250c57600080fd5b6000612516613220565b905060008090505b82811015612564576125578287838151811061253657fe5b602002602001015187848151811061254a57fe5b6020026020010151613669565b808060010191505061251e565b5060019250505092915050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166125de613220565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b606060ce8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156126925780601f1061266757610100808354040283529160200191612692565b820191906000526020600020905b81548152906001019060200180831161267557829003601f168201915b5050505050905090565b600061275f6126a9613220565b8461275a85604051806060016040528060258152602001614bfd60259139606760006126d3613220565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546139239092919063ffffffff16565b61328e565b6001905092915050565b6000612773613220565b600073ffffffffffffffffffffffffffffffffffffffff16612793613220565b73ffffffffffffffffffffffffffffffffffffffff16141561281d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4164647265737328302920666f756e642c2063616e277420636f6e74696e756581525060200191505060405180910390fd5b6000612828826139e3565b9050600081111561283e5761283d8282613b9b565b5b4261010d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010181905550610107600001548410156128e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806149f76023913960400191505060405180910390fd5b60006128ef613220565b9050600061010d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001541415612986574261010d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201819055505b6129dc8561010d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154613ee390919063ffffffff16565b61010d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000181905550612a398561010554613ee390919063ffffffff16565b61010581905550612a4a8186613f6b565b60019350505050919050565b6000612a6a612a63613220565b8484613669565b6001905092915050565b6000612a7e61259b565b612af0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b826101076002018190555081610107600301819055506001905092915050565b60606040518060400160405280600581526020017f312e302e30000000000000000000000000000000000000000000000000000000815250905090565b600060019054906101000a900460ff1680612b6c5750612b6b613658565b5b80612b8357506000809054906101000a900460ff16155b612bd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180614ab7602e913960400191505060405180910390fd5b60008060019054906101000a900460ff161590508015612c28576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612cae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526039815260200180614b576039913960400191505060405180910390fd5b8161010360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612cf86120f1565b8015612d195760008060016101000a81548160ff0219169083151502179055505b5050565b600061010760050154905090565b6000606760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b612dba611f2c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612e3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180614bb56024913960400191505060405180910390fd5b612e8d85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050848484614422565b5050505050565b60008060008061010d60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154612ee7866139e3565b61010d60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015461010d60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015493509350935093509193509193565b612f8661259b565b612ff8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61300181614428565b50565b600060019054906101000a900460ff16806130235750613022613658565b5b8061303a57506000809054906101000a900460ff16155b61308f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180614ab7602e913960400191505060405180910390fd5b60008060019054906101000a900460ff1615905080156130df576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b6130e83361456e565b61315e6040518060400160405280600781526020017f4166726f446578000000000000000000000000000000000000000000000000008152506040518060400160405280600581526020017f4166726f580000000000000000000000000000000000000000000000000000008152506004611454565b61317b738be2d3052ec38fc53521c951a09c755cf670f77a612b4d565b6131853383613d26565b6000610106819055506000610105819055506801236efcbcbb340000610104819055506509184e72a00061010760000181905550620186a061010760010181905550601e61010760020181905550600361010760030181905550620151806101076004018190555062278d0061010760050181905550801561321c5760008060016101000a81548160ff0219169083151502179055505b5050565b600061010260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146132805733905061328b565b61328861472c565b90505b90565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415613314576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180614bd96024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561339a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806149d56022913960400191505060405180910390fd5b80606760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b600061010260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613533576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180614a40602e913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156135b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d815260200180614b09602d913960400191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fb9f84b8e65164b14439ae3620df0a4d8786d896996c0282b683f9d8c08f046e860405160405180910390a38161010260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600080303b90506000811491505090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156136ef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180614b906025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613775576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018061496a6023913960400191505060405180910390fd5b6137e181604051806060016040528060268152602001614a1a60269139606660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546139239092919063ffffffff16565b606660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061387681606660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054613ee390919063ffffffff16565b606660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b60008383111582906139d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561399557808201518184015260208101905061397a565b50505050905090810190601f1680156139c25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b60008061010d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154420390506000809050610107600401548210613a5c57613a5961010760040154836147a490919063ffffffff16565b90505b600061010d60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154420390506000809050610107600501548210613ad457613ad161010760050154836147a490919063ffffffff16565b90505b6000613b07613af2836101076003015461412590919063ffffffff16565b61010760020154613ee390919063ffffffff16565b90506000613b7961010760010154613b6b8461010d60008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015461412590919063ffffffff16565b6147a490919063ffffffff16565b9050613b8e818661412590919063ffffffff16565b9650505050505050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613c3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b6000613c596101055461010454613cdc90919063ffffffff16565b905060008290506000613c6a61159f565b905082613c808583613ee390919063ffffffff16565b1115613cae5780831115613ca857613ca18184613cdc90919063ffffffff16565b9150613cad565b600091505b5b613cc48261010654613ee390919063ffffffff16565b61010681905550613cd58583613d26565b5050505050565b6000613d1e83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613923565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613dc9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b613dde81606854613ee390919063ffffffff16565b606881905550613e3681606660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054613ee390919063ffffffff16565b606660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600080828401905083811015613f61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613ff1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614b366021913960400191505060405180910390fd5b61405d8160405180606001604052806022815260200161498d60229139606660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546139239092919063ffffffff16565b606660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506140b581606854613cdc90919063ffffffff16565b606881905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b60008083141561413857600090506141a5565b600082840290508284828161414957fe5b04146141a0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614a6e6021913960400191505060405180910390fd5b809150505b92915050565b6141b58282613f6b565b614276826141c1613220565b61427184604051806060016040528060248152602001614ae560249139606760008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000614227613220565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546139239092919063ffffffff16565b61328e565b5050565b6000919050565b60008160405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c01828152602001915050604051602081830303815290604052805190602001209050919050565b600060418251146142ed57600090506143d7565b60008060006020850151925060408501519150606085015160001a90507f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08260001c111561434157600093505050506143d7565b601b8160ff16141580156143595750601c8160ff1614155b1561436a57600093505050506143d7565b60018682858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156143c7573d6000803e3d6000fd5b5050506020604051035193505050505b92915050565b600060606143f9604051806020016040528060008152506147ee565b915091509091565b6000606082600b016040518060200160405280600081525091509150915091565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156144ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806149af6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600060019054906101000a900460ff168061458d575061458c613658565b5b806145a457506000809054906101000a900460ff16155b6145f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180614ab7602e913960400191505060405180910390fd5b60008060019054906101000a900460ff161590508015614649576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380156147285760008060016101000a81548160ff0219169083151502179055505b5050565b600060606000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050600080369050905073ffffffffffffffffffffffffffffffffffffffff81830151169250829250505090565b60006147e683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506147fe565b905092915050565b6000606060008391509150915091565b600080831182906148aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561486f578082015181840152602081019050614854565b50505050905090810190601f16801561489c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816148b657fe5b049050809150509392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061490557805160ff1916838001178555614933565b82800160010185558215614933579182015b82811115614932578251825591602001919060010190614917565b5b5090506149409190614944565b5090565b61496691905b8082111561496257600081600090555060010161494a565b5090565b9056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e63654f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f2061646472657373416d6f756e74206973206c657373207468616e206d696e696d756d20616c6c6f77656445524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636547534e526563697069656e743a206e65772052656c617948756220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a656445524332303a206275726e20616d6f756e74206578636565647320616c6c6f77616e636547534e526563697069656e743a206e65772052656c6179487562206973207468652063757272656e74206f6e6545524332303a206275726e2066726f6d20746865207a65726f206164647265737347534e526563697069656e745369676e61747572653a2074727573746564207369676e657220697320746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737347534e526563697069656e743a2063616c6c6572206973206e6f742052656c617948756245524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa265627a7a723158201c1552adfb4e1d75a64a27e9716a972ec12f88fe7435be77bf7d3c43720d80e364736f6c634300050d0032
Swarm Source
bzzr://1c1552adfb4e1d75a64a27e9716a972ec12f88fe7435be77bf7d3c43720d80e3
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.