Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Write Contract
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
This contract has been verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- ArchToken
- Optimization enabled
- true
- Compiler version
- v0.7.4+commit.3f05b770
- Optimization runs
- 999999
- EVM Version
- istanbul
- Verified at
- 2026-02-08T13:17:38.096970Z
Constructor Arguments
00000000000000000000000013d5b8fc84f73fc5a0a5832aa8373044371314d30000000000000000000000004f8f512dab59f227ea70b1d8a0044afa95cc80c30000000000000000000000000000000000000000000000000000000060a4fdc0
Arg [0] (address) : 0x13d5b8fc84f73fc5a0a5832aa8373044371314d3
Arg [1] (address) : 0x4f8f512dab59f227ea70b1d8a0044afa95cc80c3
Arg [2] (uint256) : 1621425600
contracts/ArchToken.sol
/************************************************************************
~~~ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\ ~~~~
~~~ @@@@@@ ░█████╗░██████╗░░█████╗░██╗░░██╗███████╗██████╗░ @@@@@@ | ~~~
~~~ @@@@@ ██╔══██╗██╔══██╗██╔══██╗██║░░██║██╔════╝██╔══██╗ @@@@@ | ~~~
~~~ @@@@@ ███████║██████╔╝██║░░╚═╝███████║█████╗░░██████╔╝ @@@@@@ | ~~~
~~~ @@@@@ ██╔══██║██╔══██╗██║░░██╗██╔══██║██╔══╝░░██╔══██╗ @@@@@ | ~~~
~~~ @@@@@ ██║░░██║██║░░██║╚█████╔╝██║░░██║███████╗██║░░██║ @@@@@ | ~~~
~~~ @@@@@ ╚═╝░░╚═╝╚═╝░░╚═╝░╚════╝░╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝ @@@@@ | ~~~
~~~ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | ~~~
~~~ \_____________________________________________________________\| ~~~
************************************************************************/
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
import "./lib/SafeMath.sol";
/**
* @title ArchToken
* @dev The governance token for Archer DAO
* ERC-20 with supply controls + add-ons to allow for offchain signing
* See EIP-712, EIP-2612, and EIP-3009 for details
*/
contract ArchToken {
using SafeMath for uint256;
/// @notice EIP-20 token name for this token
string public name = "Archer DAO Governance Token";
/// @notice EIP-20 token symbol for this token
string public symbol = "ARCH";
/// @notice EIP-20 token decimals for this token
uint8 public constant decimals = 18;
/// @notice Total number of tokens in circulation
uint256 public totalSupply = 100_000_000e18; // 100 million
/// @notice Address which may mint/burn tokens
address public supplyManager;
/// @notice Address which may change token metadata
address public metadataManager;
/// @notice The timestamp after which a supply change may occur
uint256 public supplyChangeAllowedAfter;
/// @notice The initial minimum time between changing the token supply
uint32 public supplyChangeWaitingPeriod = 1 days * 365;
/// @notice Hard cap on the minimum time between changing the token supply
uint32 public constant supplyChangeWaitingPeriodMinimum = 1 days * 90;
/// @notice Cap on the total amount that can be minted at each mint (measured in bips: 10,000 bips = 1% of current totalSupply)
uint16 public mintCap = 20_000;
/// @dev Allowance amounts on behalf of others
mapping (address => mapping (address => uint256)) internal allowances;
/// @dev Official record of token balances for each account
mapping (address => uint256) internal balances;
/// @notice The EIP-712 typehash for the contract's domain
/// keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
bytes32 public constant DOMAIN_TYPEHASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;
/// @notice The EIP-712 version hash
/// keccak256("1");
bytes32 public constant VERSION_HASH = 0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6;
/// @notice The EIP-712 typehash for permit (EIP-2612)
/// keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
/// @notice The EIP-712 typehash for transferWithAuthorization (EIP-3009)
/// keccak256("TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)");
bytes32 public constant TRANSFER_WITH_AUTHORIZATION_TYPEHASH = 0x7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267;
/// @notice The EIP-712 typehash for receiveWithAuthorization (EIP-3009)
/// keccak256("ReceiveWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)")
bytes32 public constant RECEIVE_WITH_AUTHORIZATION_TYPEHASH = 0xd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8;
/// @notice A record of states for signing / validating signatures
mapping (address => uint) public nonces;
/// @dev authorizer address > nonce > state (true = used / false = unused)
mapping (address => mapping (bytes32 => bool)) public authorizationState;
/// @notice An event that's emitted when the mintCap is changed
event MintCapChanged(uint16 indexed oldMintCap, uint16 indexed newMintCap);
/// @notice An event that's emitted when the supplyManager address is changed
event SupplyManagerChanged(address indexed oldManager, address indexed newManager);
/// @notice An event that's emitted when the supplyChangeWaitingPeriod is changed
event SupplyChangeWaitingPeriodChanged(uint32 indexed oldWaitingPeriod, uint32 indexed newWaitingPeriod);
/// @notice An event that's emitted when the metadataManager address is changed
event MetadataManagerChanged(address indexed oldManager, address indexed newManager);
/// @notice An event that's emitted when the token name and symbol are changed
event TokenMetaUpdated(string indexed name, string indexed symbol);
/// @notice The standard EIP-20 transfer event
event Transfer(address indexed from, address indexed to, uint256 value);
/// @notice The standard EIP-20 approval event
event Approval(address indexed owner, address indexed spender, uint256 value);
/// @notice An event that's emitted whenever an authorized transfer occurs
event AuthorizationUsed(address indexed authorizer, bytes32 indexed nonce);
/**
* @notice Construct a new Arch token
* @param _metadataManager The account with the ability to change token metadata
* @param _supplyManager The address with minting ability
* @param _firstSupplyChangeAllowed The timestamp after which the first supply change may occur
*/
constructor(address _metadataManager, address _supplyManager, uint256 _firstSupplyChangeAllowed) {
require(_firstSupplyChangeAllowed >= block.timestamp, "Arch::constructor: minting can only begin after deployment");
balances[msg.sender] = totalSupply;
emit Transfer(address(0), msg.sender, totalSupply);
supplyChangeAllowedAfter = _firstSupplyChangeAllowed;
supplyManager = _supplyManager;
emit SupplyManagerChanged(address(0), _supplyManager);
metadataManager = _metadataManager;
emit MetadataManagerChanged(address(0), metadataManager);
}
/**
* @notice Change the supplyManager address
* @param newSupplyManager The address of the new supply manager
* @return true if successful
*/
function setSupplyManager(address newSupplyManager) external returns (bool) {
require(msg.sender == supplyManager, "Arch::setSupplyManager: only SM can change SM");
emit SupplyManagerChanged(supplyManager, newSupplyManager);
supplyManager = newSupplyManager;
return true;
}
/**
* @notice Change the metadataManager address
* @param newMetadataManager The address of the new metadata manager
* @return true if successful
*/
function setMetadataManager(address newMetadataManager) external returns (bool) {
require(msg.sender == metadataManager, "Arch::setMetadataManager: only MM can change MM");
emit MetadataManagerChanged(metadataManager, newMetadataManager);
metadataManager = newMetadataManager;
return true;
}
/**
* @notice Mint new tokens
* @param dst The address of the destination account
* @param amount The number of tokens to be minted
* @return Boolean indicating success of mint
*/
function mint(address dst, uint256 amount) external returns (bool) {
require(msg.sender == supplyManager, "Arch::mint: only the supplyManager can mint");
require(dst != address(0), "Arch::mint: cannot transfer to the zero address");
require(amount <= totalSupply.mul(mintCap).div(1000000), "Arch::mint: exceeded mint cap");
require(block.timestamp >= supplyChangeAllowedAfter, "Arch::mint: minting not allowed yet");
// update the next supply change allowed timestamp
supplyChangeAllowedAfter = block.timestamp.add(supplyChangeWaitingPeriod);
// mint the amount
_mint(dst, amount);
return true;
}
/**
* @notice Burn tokens
* @param src The account that will burn tokens
* @param amount The number of tokens to be burned
* @return Boolean indicating success of burn
*/
function burn(address src, uint256 amount) external returns (bool) {
address spender = msg.sender;
require(spender == supplyManager, "Arch::burn: only the supplyManager can burn");
require(src != address(0), "Arch::burn: cannot transfer from the zero address");
require(block.timestamp >= supplyChangeAllowedAfter, "Arch::burn: burning not allowed yet");
uint256 spenderAllowance = allowances[src][spender];
// check allowance and reduce by amount
if (spender != src && spenderAllowance != uint256(-1)) {
uint256 newAllowance = spenderAllowance.sub(
amount,
"Arch::burn: burn amount exceeds allowance"
);
allowances[src][spender] = newAllowance;
emit Approval(src, spender, newAllowance);
}
// update the next supply change allowed timestamp
supplyChangeAllowedAfter = block.timestamp.add(supplyChangeWaitingPeriod);
// burn the amount
_burn(src, amount);
return true;
}
/**
* @notice Set the maximum amount of tokens that can be minted at once
* @param newCap The new mint cap in bips (10,000 bips = 1% of totalSupply)
* @return true if successful
*/
function setMintCap(uint16 newCap) external returns (bool) {
require(msg.sender == supplyManager, "Arch::setMintCap: only SM can change mint cap");
emit MintCapChanged(mintCap, newCap);
mintCap = newCap;
return true;
}
/**
* @notice Set the minimum time between supply changes
* @param period The new supply change waiting period
* @return true if succssful
*/
function setSupplyChangeWaitingPeriod(uint32 period) external returns (bool) {
require(msg.sender == supplyManager, "Arch::setSupplyChangeWaitingPeriod: only SM can change waiting period");
require(period >= supplyChangeWaitingPeriodMinimum, "Arch::setSupplyChangeWaitingPeriod: waiting period must be > minimum");
emit SupplyChangeWaitingPeriodChanged(supplyChangeWaitingPeriod, period);
supplyChangeWaitingPeriod = period;
return true;
}
/**
* @notice Update the token name and symbol
* @param tokenName The new name for the token
* @param tokenSymbol The new symbol for the token
* @return true if successful
*/
function updateTokenMetadata(string memory tokenName, string memory tokenSymbol) external returns (bool) {
require(msg.sender == metadataManager, "Arch::updateTokenMeta: only MM can update token metadata");
name = tokenName;
symbol = tokenSymbol;
emit TokenMetaUpdated(name, symbol);
return true;
}
/**
* @notice Get the number of tokens `spender` is approved to spend on behalf of `account`
* @param account The address of the account holding the funds
* @param spender The address of the account spending the funds
* @return The number of tokens approved
*/
function allowance(address account, address spender) external view returns (uint) {
return allowances[account][spender];
}
/**
* @notice Approve `spender` to transfer up to `amount` from `src`
* @dev This will overwrite the approval amount for `spender`
* and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)
* It is recommended to use increaseAllowance and decreaseAllowance instead
* @param spender The address of the account which may transfer tokens
* @param amount The number of tokens that are approved (2^256-1 means infinite)
* @return Whether or not the approval succeeded
*/
function approve(address spender, uint256 amount) external returns (bool) {
_approve(msg.sender, spender, amount);
return true;
}
/**
* @notice Increase the allowance by a given amount
* @param spender Spender's address
* @param addedValue Amount of increase in allowance
* @return True if successful
*/
function increaseAllowance(address spender, uint256 addedValue)
external
returns (bool)
{
_increaseAllowance(msg.sender, spender, addedValue);
return true;
}
/**
* @notice Decrease the allowance by a given amount
* @param spender Spender's address
* @param subtractedValue Amount of decrease in allowance
* @return True if successful
*/
function decreaseAllowance(address spender, uint256 subtractedValue)
external
returns (bool)
{
_decreaseAllowance(msg.sender, spender, subtractedValue);
return true;
}
/**
* @notice Triggers an approval from owner to spender
* @param owner The address to approve from
* @param spender The address to be approved
* @param value The number of tokens that are approved (2^256-1 means infinite)
* @param deadline The time at which to expire the signature
* @param v The recovery byte of the signature
* @param r Half of the ECDSA signature pair
* @param s Half of the ECDSA signature pair
*/
function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external {
require(deadline >= block.timestamp, "Arch::permit: signature expired");
bytes32 encodeData = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline));
_validateSignedData(owner, encodeData, v, r, s);
_approve(owner, spender, value);
}
/**
* @notice Get the number of tokens held by the `account`
* @param account The address of the account to get the balance of
* @return The number of tokens held
*/
function balanceOf(address account) external view returns (uint) {
return balances[account];
}
/**
* @notice Transfer `amount` tokens from `msg.sender` to `dst`
* @param dst The address of the destination account
* @param amount The number of tokens to transfer
* @return Whether or not the transfer succeeded
*/
function transfer(address dst, uint256 amount) external returns (bool) {
_transferTokens(msg.sender, dst, amount);
return true;
}
/**
* @notice Transfer `amount` tokens from `src` to `dst`
* @param src The address of the source account
* @param dst The address of the destination account
* @param amount The number of tokens to transfer
* @return Whether or not the transfer succeeded
*/
function transferFrom(address src, address dst, uint256 amount) external returns (bool) {
address spender = msg.sender;
uint256 spenderAllowance = allowances[src][spender];
if (spender != src && spenderAllowance != uint256(-1)) {
uint256 newAllowance = spenderAllowance.sub(
amount,
"Arch::transferFrom: transfer amount exceeds allowance"
);
allowances[src][spender] = newAllowance;
emit Approval(src, spender, newAllowance);
}
_transferTokens(src, dst, amount);
return true;
}
/**
* @notice Transfer tokens with a signed authorization
* @param from Payer's address (Authorizer)
* @param to Payee's address
* @param value Amount to be transferred
* @param validAfter The time after which this is valid (unix time)
* @param validBefore The time before which this is valid (unix time)
* @param nonce Unique nonce
* @param v The recovery byte of the signature
* @param r Half of the ECDSA signature pair
* @param s Half of the ECDSA signature pair
*/
function transferWithAuthorization(
address from,
address to,
uint256 value,
uint256 validAfter,
uint256 validBefore,
bytes32 nonce,
uint8 v,
bytes32 r,
bytes32 s
)
external
{
require(block.timestamp > validAfter, "Arch::transferWithAuth: auth not yet valid");
require(block.timestamp < validBefore, "Arch::transferWithAuth: auth expired");
require(!authorizationState[from][nonce], "Arch::transferWithAuth: auth already used");
bytes32 encodeData = keccak256(abi.encode(TRANSFER_WITH_AUTHORIZATION_TYPEHASH, from, to, value, validAfter, validBefore, nonce));
_validateSignedData(from, encodeData, v, r, s);
authorizationState[from][nonce] = true;
emit AuthorizationUsed(from, nonce);
_transferTokens(from, to, value);
}
/**
* @notice Receive a transfer with a signed authorization from the payer
* @dev This has an additional check to ensure that the payee's address matches
* the caller of this function to prevent front-running attacks.
* @param from Payer's address (Authorizer)
* @param to Payee's address
* @param value Amount to be transferred
* @param validAfter The time after which this is valid (unix time)
* @param validBefore The time before which this is valid (unix time)
* @param nonce Unique nonce
* @param v v of the signature
* @param r r of the signature
* @param s s of the signature
*/
function receiveWithAuthorization(
address from,
address to,
uint256 value,
uint256 validAfter,
uint256 validBefore,
bytes32 nonce,
uint8 v,
bytes32 r,
bytes32 s
) external {
require(to == msg.sender, "Arch::receiveWithAuth: caller must be the payee");
require(block.timestamp > validAfter, "Arch::receiveWithAuth: auth not yet valid");
require(block.timestamp < validBefore, "Arch::receiveWithAuth: auth expired");
require(!authorizationState[from][nonce], "Arch::receiveWithAuth: auth already used");
bytes32 encodeData = keccak256(abi.encode(RECEIVE_WITH_AUTHORIZATION_TYPEHASH, from, to, value, validAfter, validBefore, nonce));
_validateSignedData(from, encodeData, v, r, s);
authorizationState[from][nonce] = true;
emit AuthorizationUsed(from, nonce);
_transferTokens(from, to, value);
}
/**
* @notice EIP-712 Domain separator
* @return Separator
*/
function getDomainSeparator() public view returns (bytes32) {
return keccak256(
abi.encode(
DOMAIN_TYPEHASH,
keccak256(bytes(name)),
VERSION_HASH,
_getChainId(),
address(this)
)
);
}
/**
* @notice Recovers address from signed data and validates the signature
* @param signer Address that signed the data
* @param encodeData Data signed by the address
* @param v The recovery byte of the signature
* @param r Half of the ECDSA signature pair
* @param s Half of the ECDSA signature pair
*/
function _validateSignedData(address signer, bytes32 encodeData, uint8 v, bytes32 r, bytes32 s) internal view {
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
getDomainSeparator(),
encodeData
)
);
address recoveredAddress = ecrecover(digest, v, r, s);
// Explicitly disallow authorizations for address(0) as ecrecover returns address(0) on malformed messages
require(recoveredAddress != address(0) && recoveredAddress == signer, "Arch::validateSig: invalid signature");
}
/**
* @notice Approval implementation
* @param owner The address of the account which owns tokens
* @param spender The address of the account which may transfer tokens
* @param amount The number of tokens that are approved (2^256-1 means infinite)
*/
function _approve(address owner, address spender, uint256 amount) internal {
require(owner != address(0), "Arch::_approve: approve from the zero address");
require(spender != address(0), "Arch::_approve: approve to the zero address");
allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _increaseAllowance(
address owner,
address spender,
uint256 addedValue
) internal {
_approve(owner, spender, allowances[owner][spender].add(addedValue));
}
function _decreaseAllowance(
address owner,
address spender,
uint256 subtractedValue
) internal {
_approve(
owner,
spender,
allowances[owner][spender].sub(
subtractedValue,
"Arch::_decreaseAllowance: decreased allowance below zero"
)
);
}
/**
* @notice Transfer implementation
* @param from The address of the account which owns tokens
* @param to The address of the account which is receiving tokens
* @param value The number of tokens that are being transferred
*/
function _transferTokens(address from, address to, uint256 value) internal {
require(to != address(0), "Arch::_transferTokens: cannot transfer to the zero address");
balances[from] = balances[from].sub(
value,
"Arch::_transferTokens: transfer exceeds from balance"
);
balances[to] = balances[to].add(value);
emit Transfer(from, to, value);
}
/**
* @notice Mint implementation
* @param to The address of the account which is receiving tokens
* @param value The number of tokens that are being minted
*/
function _mint(address to, uint256 value) internal {
totalSupply = totalSupply.add(value);
balances[to] = balances[to].add(value);
emit Transfer(address(0), to, value);
}
/**
* @notice Burn implementation
* @param from The address of the account which owns tokens
* @param value The number of tokens that are being burned
*/
function _burn(address from, uint256 value) internal {
balances[from] = balances[from].sub(
value,
"Arch::_burn: burn amount exceeds from balance"
);
totalSupply = totalSupply.sub(
value,
"Arch::_burn: burn amount exceeds total supply"
);
emit Transfer(from, address(0), value);
}
/**
* @notice Current id of the chain where this contract is deployed
* @return Chain id
*/
function _getChainId() internal pure returns (uint) {
uint256 chainId;
assembly { chainId := chainid() }
return chainId;
}
}
/
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
// From https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/Math.sol
// Subject to the MIT license.
/**
* @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 addition of two unsigned integers, reverting with custom message on overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, errorMessage);
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on underflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot underflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction underflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on underflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot underflow.
*/
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 multiplication of two unsigned integers, reverting on overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b, string memory errorMessage) 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, errorMessage);
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.
*/
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.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
Compiler Settings
{"remappings":[],"optimizer":{"runs":999999,"enabled":true},"metadata":{"useLiteralContent":true,"bytecodeHash":"ipfs"},"libraries":{},"evmVersion":"istanbul","compilationTarget":{"contracts/ArchToken.sol":"ArchToken"}}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_metadataManager","internalType":"address"},{"type":"address","name":"_supplyManager","internalType":"address"},{"type":"uint256","name":"_firstSupplyChangeAllowed","internalType":"uint256"}]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"AuthorizationUsed","inputs":[{"type":"address","name":"authorizer","internalType":"address","indexed":true},{"type":"bytes32","name":"nonce","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"event","name":"MetadataManagerChanged","inputs":[{"type":"address","name":"oldManager","internalType":"address","indexed":true},{"type":"address","name":"newManager","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"MintCapChanged","inputs":[{"type":"uint16","name":"oldMintCap","internalType":"uint16","indexed":true},{"type":"uint16","name":"newMintCap","internalType":"uint16","indexed":true}],"anonymous":false},{"type":"event","name":"SupplyChangeWaitingPeriodChanged","inputs":[{"type":"uint32","name":"oldWaitingPeriod","internalType":"uint32","indexed":true},{"type":"uint32","name":"newWaitingPeriod","internalType":"uint32","indexed":true}],"anonymous":false},{"type":"event","name":"SupplyManagerChanged","inputs":[{"type":"address","name":"oldManager","internalType":"address","indexed":true},{"type":"address","name":"newManager","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"TokenMetaUpdated","inputs":[{"type":"string","name":"name","internalType":"string","indexed":true},{"type":"string","name":"symbol","internalType":"string","indexed":true}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"DOMAIN_TYPEHASH","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"PERMIT_TYPEHASH","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"RECEIVE_WITH_AUTHORIZATION_TYPEHASH","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"TRANSFER_WITH_AUTHORIZATION_TYPEHASH","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"VERSION_HASH","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"authorizationState","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"burn","inputs":[{"type":"address","name":"src","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"decreaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"subtractedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getDomainSeparator","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"increaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"addedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"metadataManager","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"mint","inputs":[{"type":"address","name":"dst","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"mintCap","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"nonces","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"permit","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"},{"type":"uint256","name":"deadline","internalType":"uint256"},{"type":"uint8","name":"v","internalType":"uint8"},{"type":"bytes32","name":"r","internalType":"bytes32"},{"type":"bytes32","name":"s","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"receiveWithAuthorization","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"},{"type":"uint256","name":"validAfter","internalType":"uint256"},{"type":"uint256","name":"validBefore","internalType":"uint256"},{"type":"bytes32","name":"nonce","internalType":"bytes32"},{"type":"uint8","name":"v","internalType":"uint8"},{"type":"bytes32","name":"r","internalType":"bytes32"},{"type":"bytes32","name":"s","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"setMetadataManager","inputs":[{"type":"address","name":"newMetadataManager","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"setMintCap","inputs":[{"type":"uint16","name":"newCap","internalType":"uint16"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"setSupplyChangeWaitingPeriod","inputs":[{"type":"uint32","name":"period","internalType":"uint32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"setSupplyManager","inputs":[{"type":"address","name":"newSupplyManager","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"supplyChangeAllowedAfter","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"supplyChangeWaitingPeriod","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"supplyChangeWaitingPeriodMinimum","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"supplyManager","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"dst","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"src","internalType":"address"},{"type":"address","name":"dst","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferWithAuthorization","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"},{"type":"uint256","name":"validAfter","internalType":"uint256"},{"type":"uint256","name":"validBefore","internalType":"uint256"},{"type":"bytes32","name":"nonce","internalType":"bytes32"},{"type":"uint8","name":"v","internalType":"uint8"},{"type":"bytes32","name":"r","internalType":"bytes32"},{"type":"bytes32","name":"s","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"updateTokenMetadata","inputs":[{"type":"string","name":"tokenName","internalType":"string"},{"type":"string","name":"tokenSymbol","internalType":"string"}]}]
Contract Creation Code
0x60c0604052601b60808190527f4172636865722044414f20476f7665726e616e636520546f6b656e000000000060a0908152620000409160009190620001f5565b5060408051808201909152600480825263082a486960e31b60209092019182526200006e91600191620001f5565b506a52b7d2dcc80cd2e4000000600255600680546301e1338063ffffffff199091161761ffff60201b1916654e2000000000179055348015620000b057600080fd5b50604051620031db380380620031db833981016040819052620000d391620002be565b42811015620000ff5760405162461bcd60e51b8152600401620000f690620002fe565b60405180910390fd5b6002543360008181526008602052604080822084905551919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9162000147916200035b565b60405180910390a36005819055600380546001600160a01b0319166001600160a01b0384169081179091556040516000907f0cff5c8e2b1e51135595ff4ebaefab9ef5b26373c3b84cbdc4677bb41468843b908290a3600480546001600160a01b0319166001600160a01b0385811691909117918290556040519116906000907f65e484da94d3a093b70b54f45dda42146a4e7f7f6507a09e39f67ca388987d3e908290a350505062000364565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200022d576000855562000278565b82601f106200024857805160ff191683800117855562000278565b8280016001018555821562000278579182015b82811115620002785782518255916020019190600101906200025b565b50620002869291506200028a565b5090565b5b808211156200028657600081556001016200028b565b80516001600160a01b0381168114620002b957600080fd5b919050565b600080600060608486031215620002d3578283fd5b620002de84620002a1565b9250620002ee60208501620002a1565b9150604084015190509250925092565b6020808252603a908201527f417263683a3a636f6e7374727563746f723a206d696e74696e672063616e206f60408201527f6e6c7920626567696e206166746572206465706c6f796d656e74000000000000606082015260800190565b90815260200190565b612e6780620003746000396000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80637ecebe0011610145578063a9059cbb116100bd578063e54420261161008c578063ed24911d11610071578063ed24911d14610472578063ef55bec61461047a578063f147389f1461048d57610241565b8063e54420261461044c578063e94a01021461045f57610241565b8063a9059cbb146103fe578063d505accf14610411578063dd62ed3e14610426578063e3ee160e1461043957610241565b806395d89b41116101145780639e4e7318116100f95780639e4e7318146103db578063a0cc6a68146103e3578063a457c2d7146103eb57610241565b806395d89b41146103c05780639dc29fac146103c857610241565b80637ecebe00146103955780637f2eecc3146103a8578063892b0edf146103b0578063941acc49146103b857610241565b806320606b70116101d857806339509351116101a75780634c9e91a41161018c5780634c9e91a41461035857806370a082311461036d57806376c71ca11461038057610241565b8063395093511461033257806340c10f191461034557610241565b806320606b70146102fa57806323b872dd1461030257806330adf81f14610315578063313ce5671461031d57610241565b806318160ddd1161021457806318160ddd146102ac578063191250d7146102c15780631bb8a4c6146102d45780631d4f8072146102e757610241565b8063055c6e191461024657806306fdde0314610264578063095ea7b314610279578063124cc07714610299575b600080fd5b61024e610495565b60405161025b9190612ccd565b60405180910390f35b61026c61049c565b60405161025b9190612338565b61028c61028736600461208e565b610548565b60405161025b9190612243565b61028c6102a7366004611f21565b61055f565b6102b461064c565b60405161025b919061224e565b61028c6102cf366004611f21565b610652565b61028c6102e2366004612118565b610737565b61028c6102f536600461213a565b610807565b6102b461090f565b61028c610310366004611f6d565b610933565b6102b4610a52565b610325610a76565b60405161025b9190612cde565b61028c61034036600461208e565b610a7b565b61028c61035336600461208e565b610a88565b610360610bed565b60405161025b9190612222565b6102b461037b366004611f21565b610c09565b610388610c31565b60405161025b9190612cbe565b6102b46103a3366004611f21565b610c43565b6102b4610c55565b6102b4610c79565b61024e610c7f565b61026c610c8b565b61028c6103d636600461208e565b610d03565b6102b4610f1a565b6102b4610f3e565b61028c6103f936600461208e565b610f62565b61028c61040c36600461208e565b610f6f565b61042461041f366004612025565b610f7c565b005b6102b4610434366004611f3b565b611058565b610424610447366004611fa8565b611090565b61028c61045a3660046120b7565b61126a565b61028c61046d36600461208e565b611345565b6102b4611365565b610424610488366004611fa8565b6113fc565b610360611568565b6276a70081565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156105405780601f1061051557610100808354040283529160200191610540565b820191906000526020600020905b81548152906001019060200180831161052357829003601f168201915b505050505081565b6000610555338484611584565b5060015b92915050565b60045460009073ffffffffffffffffffffffffffffffffffffffff1633146105bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b39061260e565b60405180910390fd5b60045460405173ffffffffffffffffffffffffffffffffffffffff8085169216907f65e484da94d3a093b70b54f45dda42146a4e7f7f6507a09e39f67ca388987d3e90600090a350600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff831617905560015b919050565b60025481565b60035460009073ffffffffffffffffffffffffffffffffffffffff1633146106a6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612c61565b60035460405173ffffffffffffffffffffffffffffffffffffffff8085169216907f0cff5c8e2b1e51135595ff4ebaefab9ef5b26373c3b84cbdc4677bb41468843b90600090a3506003805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff00000000000000000000000000000000000000009091161790556001919050565b60035460009073ffffffffffffffffffffffffffffffffffffffff16331461078b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b39061257a565b60065460405161ffff80851692640100000000900416907f57fc526a0acf7c7e07dc107529df54483128b205abc107af2fa47020f82f121490600090a3506006805461ffff8316640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffff9091161790556001919050565b60035460009073ffffffffffffffffffffffffffffffffffffffff16331461085b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612bde565b6276a70063ffffffff8316101561089e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b3906128d0565b60065460405163ffffffff8085169216907f769f3176a8ee46ae63681a1a630bec4772f7af23a4eeec90eaff41a0e8f1ac6990600090a3506006805463ffffffff83167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009091161790556001919050565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b73ffffffffffffffffffffffffffffffffffffffff831660008181526007602090815260408083203380855292528220549192909190821480159061099857507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114155b15610a3b5760006109c485604051806060016040528060358152602001612d1a60359139849190611693565b73ffffffffffffffffffffffffffffffffffffffff808916600081815260076020908152604080832094891680845294909152908190208490555192935090917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610a3190859061224e565b60405180910390a3505b610a46868686611744565b50600195945050505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b6000610555338484611876565b60035460009073ffffffffffffffffffffffffffffffffffffffff163314610adc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b39061275c565b73ffffffffffffffffffffffffffffffffffffffff8316610b29576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b3906124c0565b600654600254610b5391620f424091610b4d91640100000000900461ffff166118c5565b9061193f565b821115610b8c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b3906125d7565b600554421015610bc8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612406565b600654610be090429063ffffffff9081169061198116565b60055561055583836119f5565b60045473ffffffffffffffffffffffffffffffffffffffff1681565b73ffffffffffffffffffffffffffffffffffffffff1660009081526008602052604090205490565b600654640100000000900461ffff1681565b60096020526000908152604090205481565b7fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de881565b60055481565b60065463ffffffff1681565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156105405780601f1061051557610100808354040283529160200191610540565b600354600090339073ffffffffffffffffffffffffffffffffffffffff168114610d59576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612ac7565b73ffffffffffffffffffffffffffffffffffffffff8416610da6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612a0d565b600554421015610de2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612463565b73ffffffffffffffffffffffffffffffffffffffff8085166000818152600760209081526040808320948616808452949091529020549114801590610e4757507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114155b15610eea576000610e7385604051806060016040528060298152602001612dd560299139849190611693565b73ffffffffffffffffffffffffffffffffffffffff808816600081815260076020908152604080832094891680845294909152908190208490555192935090917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610ee090859061224e565b60405180910390a3505b600654610f0290429063ffffffff9081169061198116565b600555610f0f8585611a9d565b506001949350505050565b7fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc681565b7f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a226781565b6000610555338484611b9f565b6000610555338484611744565b42841015610fb6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612725565b73ffffffffffffffffffffffffffffffffffffffff87166000908152600960209081526040808320805460018101909155905161101e927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928c928c928c92918c9101612257565b6040516020818303038152906040528051906020012090506110438882868686611bfb565b61104e888888611584565b5050505050505050565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260076020908152604080832093909416825291909152205490565b8542116110c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612b81565b844210611102576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612953565b73ffffffffffffffffffffffffffffffffffffffff89166000908152600a6020908152604080832087845290915290205460ff161561116d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612873565b6040516000906111ad907f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267908c908c908c908c908c908c90602001612298565b6040516020818303038152906040528051906020012090506111d28a82868686611bfb565b73ffffffffffffffffffffffffffffffffffffffff8a166000818152600a6020908152604080832089845290915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055518792917f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a591a361125e8a8a8a611744565b50505050505050505050565b60045460009073ffffffffffffffffffffffffffffffffffffffff1633146112be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b3906126c8565b82516112d1906000906020860190611db3565b5081516112e5906001906020850190611db3565b5060016040516112f5919061215e565b6040518091039020600060405161130c919061215e565b604051908190038120907febb95b1e6f8658c3f6a1f6f59a9bea23721d47f22a69339010082475f7db6b2c90600090a350600192915050565b600a60209081526000928352604080842090915290825290205460ff1681565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60001b600060405161139a919061215e565b6040519081900390207fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66113cc611d30565b306040516020016113e19594939291906122e1565b60405160208183030381529060405280519060200120905090565b73ffffffffffffffffffffffffffffffffffffffff8816331461144b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b39061266b565b854211611484576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612816565b8442106114bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b3906129b0565b73ffffffffffffffffffffffffffffffffffffffff89166000908152600a6020908152604080832087845290915290205460ff1615611528576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b3906123a9565b6040516000906111ad907fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8908c908c908c908c908c908c90602001612298565b60035473ffffffffffffffffffffffffffffffffffffffff1681565b73ffffffffffffffffffffffffffffffffffffffff83166115d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b3906127b9565b73ffffffffffffffffffffffffffffffffffffffff821661161e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612b24565b73ffffffffffffffffffffffffffffffffffffffff80841660008181526007602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259061168690859061224e565b60405180910390a3505050565b6000818484111561173c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156117015781810151838201526020016116e9565b50505050905090810190601f16801561172e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b73ffffffffffffffffffffffffffffffffffffffff8216611791576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612a6a565b6117db81604051806060016040528060348152602001612dfe6034913973ffffffffffffffffffffffffffffffffffffffff86166000908152600860205260409020549190611693565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526008602052604080822093909355908416815220546118179082611981565b73ffffffffffffffffffffffffffffffffffffffff80841660008181526008602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061168690859061224e565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600760209081526040808320938616835292905220546118c090849084906118bb9085611981565b611584565b505050565b6000826118d457506000610559565b828202828482816118e157fe5b0414611938576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612d4f6021913960400191505060405180910390fd5b9392505050565b600061193883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611d34565b60008282018381101561193857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600254611a029082611981565b60025573ffffffffffffffffffffffffffffffffffffffff8216600090815260086020526040902054611a359082611981565b73ffffffffffffffffffffffffffffffffffffffff83166000818152600860205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611a9190859061224e565b60405180910390a35050565b611ae7816040518060600160405280602d8152602001612ced602d913973ffffffffffffffffffffffffffffffffffffffff85166000908152600860205260409020549190611693565b600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611b51816040518060600160405280602d8152602001612da8602d91396002549190611693565b60025560405160009073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611a9190859061224e565b6118c083836118bb84604051806060016040528060388152602001612d706038913973ffffffffffffffffffffffffffffffffffffffff808a166000908152600760209081526040808320938c16835292905220549190611693565b6000611c05611365565b85604051602001611c179291906121ec565b604051602081830303815290604052805190602001209050600060018286868660405160008152602001604052604051611c54949392919061231a565b6020604051602081039080840390855afa158015611c76573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590611cf157508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b611d27576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b39061251d565b50505050505050565b4690565b60008183611d9d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482018181528351602484015283519092839260449091019190850190808383600083156117015781810151838201526020016116e9565b506000838581611da957fe5b0495945050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282611de95760008555611e2f565b82601f10611e0257805160ff1916838001178555611e2f565b82800160010185558215611e2f579182015b82811115611e2f578251825591602001919060010190611e14565b50611e3b929150611e3f565b5090565b5b80821115611e3b5760008155600101611e40565b803573ffffffffffffffffffffffffffffffffffffffff8116811461064757600080fd5b600082601f830112611e88578081fd5b813567ffffffffffffffff80821115611e9d57fe5b60405160207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501168201018181108382111715611ed957fe5b604052828152925082848301602001861015611ef457600080fd5b8260208601602083013760006020848301015250505092915050565b803560ff8116811461064757600080fd5b600060208284031215611f32578081fd5b61193882611e54565b60008060408385031215611f4d578081fd5b611f5683611e54565b9150611f6460208401611e54565b90509250929050565b600080600060608486031215611f81578081fd5b611f8a84611e54565b9250611f9860208501611e54565b9150604084013590509250925092565b60008060008060008060008060006101208a8c031215611fc6578485fd5b611fcf8a611e54565b9850611fdd60208b01611e54565b975060408a0135965060608a0135955060808a0135945060a08a0135935061200760c08b01611f10565b925060e08a013591506101008a013590509295985092959850929598565b600080600080600080600060e0888a03121561203f578283fd5b61204888611e54565b965061205660208901611e54565b9550604088013594506060880135935061207260808901611f10565b925060a0880135915060c0880135905092959891949750929550565b600080604083850312156120a0578182fd5b6120a983611e54565b946020939093013593505050565b600080604083850312156120c9578182fd5b823567ffffffffffffffff808211156120e0578384fd5b6120ec86838701611e78565b93506020850135915080821115612101578283fd5b5061210e85828601611e78565b9150509250929050565b600060208284031215612129578081fd5b813561ffff81168114611938578182fd5b60006020828403121561214b578081fd5b813563ffffffff81168114611938578182fd5b600080835460018082166000811461217d57600181146121b2576121e1565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083168652607f6002840416860193506121e1565b600283048786526020808720875b838110156121d95781548a8201529085019082016121c0565b505050860193505b509195945050505050565b7f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b901515815260200190565b90815260200190565b95865273ffffffffffffffffffffffffffffffffffffffff94851660208701529290931660408501526060840152608083019190915260a082015260c00190565b96875273ffffffffffffffffffffffffffffffffffffffff95861660208801529390941660408601526060850191909152608084015260a083019190915260c082015260e00190565b94855260208501939093526040840191909152606083015273ffffffffffffffffffffffffffffffffffffffff16608082015260a00190565b93845260ff9290921660208401526040830152606082015260800190565b6000602080835283518082850152825b8181101561236457858101830151858201604001528201612348565b818111156123755783604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60208082526028908201527f417263683a3a7265636569766557697468417574683a206175746820616c726560408201527f6164792075736564000000000000000000000000000000000000000000000000606082015260800190565b60208082526023908201527f417263683a3a6d696e743a206d696e74696e67206e6f7420616c6c6f7765642060408201527f7965740000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526023908201527f417263683a3a6275726e3a206275726e696e67206e6f7420616c6c6f7765642060408201527f7965740000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602f908201527f417263683a3a6d696e743a2063616e6e6f74207472616e7366657220746f207460408201527f6865207a65726f20616464726573730000000000000000000000000000000000606082015260800190565b60208082526024908201527f417263683a3a76616c69646174655369673a20696e76616c6964207369676e6160408201527f7475726500000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602d908201527f417263683a3a7365744d696e744361703a206f6e6c7920534d2063616e20636860408201527f616e6765206d696e742063617000000000000000000000000000000000000000606082015260800190565b6020808252601d908201527f417263683a3a6d696e743a206578636565646564206d696e7420636170000000604082015260600190565b6020808252602f908201527f417263683a3a7365744d657461646174614d616e616765723a206f6e6c79204d60408201527f4d2063616e206368616e6765204d4d0000000000000000000000000000000000606082015260800190565b6020808252602f908201527f417263683a3a7265636569766557697468417574683a2063616c6c6572206d7560408201527f7374206265207468652070617965650000000000000000000000000000000000606082015260800190565b60208082526038908201527f417263683a3a757064617465546f6b656e4d6574613a206f6e6c79204d4d206360408201527f616e2075706461746520746f6b656e206d657461646174610000000000000000606082015260800190565b6020808252601f908201527f417263683a3a7065726d69743a207369676e6174757265206578706972656400604082015260600190565b6020808252602b908201527f417263683a3a6d696e743a206f6e6c792074686520737570706c794d616e616760408201527f65722063616e206d696e74000000000000000000000000000000000000000000606082015260800190565b6020808252602d908201527f417263683a3a5f617070726f76653a20617070726f76652066726f6d2074686560408201527f207a65726f206164647265737300000000000000000000000000000000000000606082015260800190565b60208082526029908201527f417263683a3a7265636569766557697468417574683a2061757468206e6f742060408201527f7965742076616c69640000000000000000000000000000000000000000000000606082015260800190565b60208082526029908201527f417263683a3a7472616e7366657257697468417574683a206175746820616c7260408201527f6561647920757365640000000000000000000000000000000000000000000000606082015260800190565b60208082526044908201527f417263683a3a736574537570706c794368616e676557616974696e675065726960408201527f6f643a2077616974696e6720706572696f64206d757374206265203e206d696e60608201527f696d756d00000000000000000000000000000000000000000000000000000000608082015260a00190565b60208082526024908201527f417263683a3a7472616e7366657257697468417574683a20617574682065787060408201527f6972656400000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526023908201527f417263683a3a7265636569766557697468417574683a2061757468206578706960408201527f7265640000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526031908201527f417263683a3a6275726e3a2063616e6e6f74207472616e736665722066726f6d60408201527f20746865207a65726f2061646472657373000000000000000000000000000000606082015260800190565b6020808252603a908201527f417263683a3a5f7472616e73666572546f6b656e733a2063616e6e6f7420747260408201527f616e7366657220746f20746865207a65726f2061646472657373000000000000606082015260800190565b6020808252602b908201527f417263683a3a6275726e3a206f6e6c792074686520737570706c794d616e616760408201527f65722063616e206275726e000000000000000000000000000000000000000000606082015260800190565b6020808252602b908201527f417263683a3a5f617070726f76653a20617070726f766520746f20746865207a60408201527f65726f2061646472657373000000000000000000000000000000000000000000606082015260800190565b6020808252602a908201527f417263683a3a7472616e7366657257697468417574683a2061757468206e6f7460408201527f207965742076616c696400000000000000000000000000000000000000000000606082015260800190565b60208082526045908201527f417263683a3a736574537570706c794368616e676557616974696e675065726960408201527f6f643a206f6e6c7920534d2063616e206368616e67652077616974696e67207060608201527f6572696f64000000000000000000000000000000000000000000000000000000608082015260a00190565b6020808252602d908201527f417263683a3a736574537570706c794d616e616765723a206f6e6c7920534d2060408201527f63616e206368616e676520534d00000000000000000000000000000000000000606082015260800190565b61ffff91909116815260200190565b63ffffffff91909116815260200190565b60ff9190911681526020019056fe417263683a3a5f6275726e3a206275726e20616d6f756e7420657863656564732066726f6d2062616c616e6365417263683a3a7472616e7366657246726f6d3a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77417263683a3a5f6465637265617365416c6c6f77616e63653a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726f417263683a3a5f6275726e3a206275726e20616d6f756e74206578636565647320746f74616c20737570706c79417263683a3a6275726e3a206275726e20616d6f756e74206578636565647320616c6c6f77616e6365417263683a3a5f7472616e73666572546f6b656e733a207472616e7366657220657863656564732066726f6d2062616c616e6365a26469706673582212203ba25741283c711284b3bc50fdb2f81f30640e7f941172cfa544cdd94c24d6a264736f6c6343000704003300000000000000000000000013d5b8fc84f73fc5a0a5832aa8373044371314d30000000000000000000000004f8f512dab59f227ea70b1d8a0044afa95cc80c30000000000000000000000000000000000000000000000000000000060a4fdc0
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106102415760003560e01c80637ecebe0011610145578063a9059cbb116100bd578063e54420261161008c578063ed24911d11610071578063ed24911d14610472578063ef55bec61461047a578063f147389f1461048d57610241565b8063e54420261461044c578063e94a01021461045f57610241565b8063a9059cbb146103fe578063d505accf14610411578063dd62ed3e14610426578063e3ee160e1461043957610241565b806395d89b41116101145780639e4e7318116100f95780639e4e7318146103db578063a0cc6a68146103e3578063a457c2d7146103eb57610241565b806395d89b41146103c05780639dc29fac146103c857610241565b80637ecebe00146103955780637f2eecc3146103a8578063892b0edf146103b0578063941acc49146103b857610241565b806320606b70116101d857806339509351116101a75780634c9e91a41161018c5780634c9e91a41461035857806370a082311461036d57806376c71ca11461038057610241565b8063395093511461033257806340c10f191461034557610241565b806320606b70146102fa57806323b872dd1461030257806330adf81f14610315578063313ce5671461031d57610241565b806318160ddd1161021457806318160ddd146102ac578063191250d7146102c15780631bb8a4c6146102d45780631d4f8072146102e757610241565b8063055c6e191461024657806306fdde0314610264578063095ea7b314610279578063124cc07714610299575b600080fd5b61024e610495565b60405161025b9190612ccd565b60405180910390f35b61026c61049c565b60405161025b9190612338565b61028c61028736600461208e565b610548565b60405161025b9190612243565b61028c6102a7366004611f21565b61055f565b6102b461064c565b60405161025b919061224e565b61028c6102cf366004611f21565b610652565b61028c6102e2366004612118565b610737565b61028c6102f536600461213a565b610807565b6102b461090f565b61028c610310366004611f6d565b610933565b6102b4610a52565b610325610a76565b60405161025b9190612cde565b61028c61034036600461208e565b610a7b565b61028c61035336600461208e565b610a88565b610360610bed565b60405161025b9190612222565b6102b461037b366004611f21565b610c09565b610388610c31565b60405161025b9190612cbe565b6102b46103a3366004611f21565b610c43565b6102b4610c55565b6102b4610c79565b61024e610c7f565b61026c610c8b565b61028c6103d636600461208e565b610d03565b6102b4610f1a565b6102b4610f3e565b61028c6103f936600461208e565b610f62565b61028c61040c36600461208e565b610f6f565b61042461041f366004612025565b610f7c565b005b6102b4610434366004611f3b565b611058565b610424610447366004611fa8565b611090565b61028c61045a3660046120b7565b61126a565b61028c61046d36600461208e565b611345565b6102b4611365565b610424610488366004611fa8565b6113fc565b610360611568565b6276a70081565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156105405780601f1061051557610100808354040283529160200191610540565b820191906000526020600020905b81548152906001019060200180831161052357829003601f168201915b505050505081565b6000610555338484611584565b5060015b92915050565b60045460009073ffffffffffffffffffffffffffffffffffffffff1633146105bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b39061260e565b60405180910390fd5b60045460405173ffffffffffffffffffffffffffffffffffffffff8085169216907f65e484da94d3a093b70b54f45dda42146a4e7f7f6507a09e39f67ca388987d3e90600090a350600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff831617905560015b919050565b60025481565b60035460009073ffffffffffffffffffffffffffffffffffffffff1633146106a6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612c61565b60035460405173ffffffffffffffffffffffffffffffffffffffff8085169216907f0cff5c8e2b1e51135595ff4ebaefab9ef5b26373c3b84cbdc4677bb41468843b90600090a3506003805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff00000000000000000000000000000000000000009091161790556001919050565b60035460009073ffffffffffffffffffffffffffffffffffffffff16331461078b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b39061257a565b60065460405161ffff80851692640100000000900416907f57fc526a0acf7c7e07dc107529df54483128b205abc107af2fa47020f82f121490600090a3506006805461ffff8316640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffff9091161790556001919050565b60035460009073ffffffffffffffffffffffffffffffffffffffff16331461085b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612bde565b6276a70063ffffffff8316101561089e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b3906128d0565b60065460405163ffffffff8085169216907f769f3176a8ee46ae63681a1a630bec4772f7af23a4eeec90eaff41a0e8f1ac6990600090a3506006805463ffffffff83167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009091161790556001919050565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b73ffffffffffffffffffffffffffffffffffffffff831660008181526007602090815260408083203380855292528220549192909190821480159061099857507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114155b15610a3b5760006109c485604051806060016040528060358152602001612d1a60359139849190611693565b73ffffffffffffffffffffffffffffffffffffffff808916600081815260076020908152604080832094891680845294909152908190208490555192935090917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610a3190859061224e565b60405180910390a3505b610a46868686611744565b50600195945050505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b6000610555338484611876565b60035460009073ffffffffffffffffffffffffffffffffffffffff163314610adc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b39061275c565b73ffffffffffffffffffffffffffffffffffffffff8316610b29576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b3906124c0565b600654600254610b5391620f424091610b4d91640100000000900461ffff166118c5565b9061193f565b821115610b8c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b3906125d7565b600554421015610bc8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612406565b600654610be090429063ffffffff9081169061198116565b60055561055583836119f5565b60045473ffffffffffffffffffffffffffffffffffffffff1681565b73ffffffffffffffffffffffffffffffffffffffff1660009081526008602052604090205490565b600654640100000000900461ffff1681565b60096020526000908152604090205481565b7fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de881565b60055481565b60065463ffffffff1681565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156105405780601f1061051557610100808354040283529160200191610540565b600354600090339073ffffffffffffffffffffffffffffffffffffffff168114610d59576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612ac7565b73ffffffffffffffffffffffffffffffffffffffff8416610da6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612a0d565b600554421015610de2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612463565b73ffffffffffffffffffffffffffffffffffffffff8085166000818152600760209081526040808320948616808452949091529020549114801590610e4757507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114155b15610eea576000610e7385604051806060016040528060298152602001612dd560299139849190611693565b73ffffffffffffffffffffffffffffffffffffffff808816600081815260076020908152604080832094891680845294909152908190208490555192935090917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610ee090859061224e565b60405180910390a3505b600654610f0290429063ffffffff9081169061198116565b600555610f0f8585611a9d565b506001949350505050565b7fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc681565b7f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a226781565b6000610555338484611b9f565b6000610555338484611744565b42841015610fb6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612725565b73ffffffffffffffffffffffffffffffffffffffff87166000908152600960209081526040808320805460018101909155905161101e927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928c928c928c92918c9101612257565b6040516020818303038152906040528051906020012090506110438882868686611bfb565b61104e888888611584565b5050505050505050565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260076020908152604080832093909416825291909152205490565b8542116110c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612b81565b844210611102576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612953565b73ffffffffffffffffffffffffffffffffffffffff89166000908152600a6020908152604080832087845290915290205460ff161561116d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612873565b6040516000906111ad907f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267908c908c908c908c908c908c90602001612298565b6040516020818303038152906040528051906020012090506111d28a82868686611bfb565b73ffffffffffffffffffffffffffffffffffffffff8a166000818152600a6020908152604080832089845290915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055518792917f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a591a361125e8a8a8a611744565b50505050505050505050565b60045460009073ffffffffffffffffffffffffffffffffffffffff1633146112be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b3906126c8565b82516112d1906000906020860190611db3565b5081516112e5906001906020850190611db3565b5060016040516112f5919061215e565b6040518091039020600060405161130c919061215e565b604051908190038120907febb95b1e6f8658c3f6a1f6f59a9bea23721d47f22a69339010082475f7db6b2c90600090a350600192915050565b600a60209081526000928352604080842090915290825290205460ff1681565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60001b600060405161139a919061215e565b6040519081900390207fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66113cc611d30565b306040516020016113e19594939291906122e1565b60405160208183030381529060405280519060200120905090565b73ffffffffffffffffffffffffffffffffffffffff8816331461144b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b39061266b565b854211611484576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612816565b8442106114bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b3906129b0565b73ffffffffffffffffffffffffffffffffffffffff89166000908152600a6020908152604080832087845290915290205460ff1615611528576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b3906123a9565b6040516000906111ad907fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8908c908c908c908c908c908c90602001612298565b60035473ffffffffffffffffffffffffffffffffffffffff1681565b73ffffffffffffffffffffffffffffffffffffffff83166115d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b3906127b9565b73ffffffffffffffffffffffffffffffffffffffff821661161e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612b24565b73ffffffffffffffffffffffffffffffffffffffff80841660008181526007602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259061168690859061224e565b60405180910390a3505050565b6000818484111561173c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156117015781810151838201526020016116e9565b50505050905090810190601f16801561172e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b73ffffffffffffffffffffffffffffffffffffffff8216611791576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b390612a6a565b6117db81604051806060016040528060348152602001612dfe6034913973ffffffffffffffffffffffffffffffffffffffff86166000908152600860205260409020549190611693565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526008602052604080822093909355908416815220546118179082611981565b73ffffffffffffffffffffffffffffffffffffffff80841660008181526008602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061168690859061224e565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600760209081526040808320938616835292905220546118c090849084906118bb9085611981565b611584565b505050565b6000826118d457506000610559565b828202828482816118e157fe5b0414611938576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612d4f6021913960400191505060405180910390fd5b9392505050565b600061193883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611d34565b60008282018381101561193857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600254611a029082611981565b60025573ffffffffffffffffffffffffffffffffffffffff8216600090815260086020526040902054611a359082611981565b73ffffffffffffffffffffffffffffffffffffffff83166000818152600860205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611a9190859061224e565b60405180910390a35050565b611ae7816040518060600160405280602d8152602001612ced602d913973ffffffffffffffffffffffffffffffffffffffff85166000908152600860205260409020549190611693565b600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611b51816040518060600160405280602d8152602001612da8602d91396002549190611693565b60025560405160009073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611a9190859061224e565b6118c083836118bb84604051806060016040528060388152602001612d706038913973ffffffffffffffffffffffffffffffffffffffff808a166000908152600760209081526040808320938c16835292905220549190611693565b6000611c05611365565b85604051602001611c179291906121ec565b604051602081830303815290604052805190602001209050600060018286868660405160008152602001604052604051611c54949392919061231a565b6020604051602081039080840390855afa158015611c76573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590611cf157508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b611d27576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b39061251d565b50505050505050565b4690565b60008183611d9d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482018181528351602484015283519092839260449091019190850190808383600083156117015781810151838201526020016116e9565b506000838581611da957fe5b0495945050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282611de95760008555611e2f565b82601f10611e0257805160ff1916838001178555611e2f565b82800160010185558215611e2f579182015b82811115611e2f578251825591602001919060010190611e14565b50611e3b929150611e3f565b5090565b5b80821115611e3b5760008155600101611e40565b803573ffffffffffffffffffffffffffffffffffffffff8116811461064757600080fd5b600082601f830112611e88578081fd5b813567ffffffffffffffff80821115611e9d57fe5b60405160207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501168201018181108382111715611ed957fe5b604052828152925082848301602001861015611ef457600080fd5b8260208601602083013760006020848301015250505092915050565b803560ff8116811461064757600080fd5b600060208284031215611f32578081fd5b61193882611e54565b60008060408385031215611f4d578081fd5b611f5683611e54565b9150611f6460208401611e54565b90509250929050565b600080600060608486031215611f81578081fd5b611f8a84611e54565b9250611f9860208501611e54565b9150604084013590509250925092565b60008060008060008060008060006101208a8c031215611fc6578485fd5b611fcf8a611e54565b9850611fdd60208b01611e54565b975060408a0135965060608a0135955060808a0135945060a08a0135935061200760c08b01611f10565b925060e08a013591506101008a013590509295985092959850929598565b600080600080600080600060e0888a03121561203f578283fd5b61204888611e54565b965061205660208901611e54565b9550604088013594506060880135935061207260808901611f10565b925060a0880135915060c0880135905092959891949750929550565b600080604083850312156120a0578182fd5b6120a983611e54565b946020939093013593505050565b600080604083850312156120c9578182fd5b823567ffffffffffffffff808211156120e0578384fd5b6120ec86838701611e78565b93506020850135915080821115612101578283fd5b5061210e85828601611e78565b9150509250929050565b600060208284031215612129578081fd5b813561ffff81168114611938578182fd5b60006020828403121561214b578081fd5b813563ffffffff81168114611938578182fd5b600080835460018082166000811461217d57600181146121b2576121e1565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083168652607f6002840416860193506121e1565b600283048786526020808720875b838110156121d95781548a8201529085019082016121c0565b505050860193505b509195945050505050565b7f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b901515815260200190565b90815260200190565b95865273ffffffffffffffffffffffffffffffffffffffff94851660208701529290931660408501526060840152608083019190915260a082015260c00190565b96875273ffffffffffffffffffffffffffffffffffffffff95861660208801529390941660408601526060850191909152608084015260a083019190915260c082015260e00190565b94855260208501939093526040840191909152606083015273ffffffffffffffffffffffffffffffffffffffff16608082015260a00190565b93845260ff9290921660208401526040830152606082015260800190565b6000602080835283518082850152825b8181101561236457858101830151858201604001528201612348565b818111156123755783604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60208082526028908201527f417263683a3a7265636569766557697468417574683a206175746820616c726560408201527f6164792075736564000000000000000000000000000000000000000000000000606082015260800190565b60208082526023908201527f417263683a3a6d696e743a206d696e74696e67206e6f7420616c6c6f7765642060408201527f7965740000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526023908201527f417263683a3a6275726e3a206275726e696e67206e6f7420616c6c6f7765642060408201527f7965740000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602f908201527f417263683a3a6d696e743a2063616e6e6f74207472616e7366657220746f207460408201527f6865207a65726f20616464726573730000000000000000000000000000000000606082015260800190565b60208082526024908201527f417263683a3a76616c69646174655369673a20696e76616c6964207369676e6160408201527f7475726500000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602d908201527f417263683a3a7365744d696e744361703a206f6e6c7920534d2063616e20636860408201527f616e6765206d696e742063617000000000000000000000000000000000000000606082015260800190565b6020808252601d908201527f417263683a3a6d696e743a206578636565646564206d696e7420636170000000604082015260600190565b6020808252602f908201527f417263683a3a7365744d657461646174614d616e616765723a206f6e6c79204d60408201527f4d2063616e206368616e6765204d4d0000000000000000000000000000000000606082015260800190565b6020808252602f908201527f417263683a3a7265636569766557697468417574683a2063616c6c6572206d7560408201527f7374206265207468652070617965650000000000000000000000000000000000606082015260800190565b60208082526038908201527f417263683a3a757064617465546f6b656e4d6574613a206f6e6c79204d4d206360408201527f616e2075706461746520746f6b656e206d657461646174610000000000000000606082015260800190565b6020808252601f908201527f417263683a3a7065726d69743a207369676e6174757265206578706972656400604082015260600190565b6020808252602b908201527f417263683a3a6d696e743a206f6e6c792074686520737570706c794d616e616760408201527f65722063616e206d696e74000000000000000000000000000000000000000000606082015260800190565b6020808252602d908201527f417263683a3a5f617070726f76653a20617070726f76652066726f6d2074686560408201527f207a65726f206164647265737300000000000000000000000000000000000000606082015260800190565b60208082526029908201527f417263683a3a7265636569766557697468417574683a2061757468206e6f742060408201527f7965742076616c69640000000000000000000000000000000000000000000000606082015260800190565b60208082526029908201527f417263683a3a7472616e7366657257697468417574683a206175746820616c7260408201527f6561647920757365640000000000000000000000000000000000000000000000606082015260800190565b60208082526044908201527f417263683a3a736574537570706c794368616e676557616974696e675065726960408201527f6f643a2077616974696e6720706572696f64206d757374206265203e206d696e60608201527f696d756d00000000000000000000000000000000000000000000000000000000608082015260a00190565b60208082526024908201527f417263683a3a7472616e7366657257697468417574683a20617574682065787060408201527f6972656400000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526023908201527f417263683a3a7265636569766557697468417574683a2061757468206578706960408201527f7265640000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526031908201527f417263683a3a6275726e3a2063616e6e6f74207472616e736665722066726f6d60408201527f20746865207a65726f2061646472657373000000000000000000000000000000606082015260800190565b6020808252603a908201527f417263683a3a5f7472616e73666572546f6b656e733a2063616e6e6f7420747260408201527f616e7366657220746f20746865207a65726f2061646472657373000000000000606082015260800190565b6020808252602b908201527f417263683a3a6275726e3a206f6e6c792074686520737570706c794d616e616760408201527f65722063616e206275726e000000000000000000000000000000000000000000606082015260800190565b6020808252602b908201527f417263683a3a5f617070726f76653a20617070726f766520746f20746865207a60408201527f65726f2061646472657373000000000000000000000000000000000000000000606082015260800190565b6020808252602a908201527f417263683a3a7472616e7366657257697468417574683a2061757468206e6f7460408201527f207965742076616c696400000000000000000000000000000000000000000000606082015260800190565b60208082526045908201527f417263683a3a736574537570706c794368616e676557616974696e675065726960408201527f6f643a206f6e6c7920534d2063616e206368616e67652077616974696e67207060608201527f6572696f64000000000000000000000000000000000000000000000000000000608082015260a00190565b6020808252602d908201527f417263683a3a736574537570706c794d616e616765723a206f6e6c7920534d2060408201527f63616e206368616e676520534d00000000000000000000000000000000000000606082015260800190565b61ffff91909116815260200190565b63ffffffff91909116815260200190565b60ff9190911681526020019056fe417263683a3a5f6275726e3a206275726e20616d6f756e7420657863656564732066726f6d2062616c616e6365417263683a3a7472616e7366657246726f6d3a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77417263683a3a5f6465637265617365416c6c6f77616e63653a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726f417263683a3a5f6275726e3a206275726e20616d6f756e74206578636565647320746f74616c20737570706c79417263683a3a6275726e3a206275726e20616d6f756e74206578636565647320616c6c6f77616e6365417263683a3a5f7472616e73666572546f6b656e733a207472616e7366657220657863656564732066726f6d2062616c616e6365a26469706673582212203ba25741283c711284b3bc50fdb2f81f30640e7f941172cfa544cdd94c24d6a264736f6c63430007040033