Overview
ETH Balance
ETH Value
$0.00Latest 1 from a total of 1 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Initialize | 65925700 | 1078 days ago | IN | 0 ETH | 0.00007969 |
Latest 10 internal transactions
Cross-Chain Transactions
Contract Source Code (Solidity Standard Json-Input format)
/**
* SPDX-License-Identifier: MIT
*
* Copyright (c) 2018-2020 CENTRE SECZ
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
pragma solidity ^0.8.10;
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "../v1.1/FiatTokenV1_1.sol";
import "./AbstractFiatTokenV2.sol";
import "../util/EIP712.sol";
import "./EIP712Domain.sol";
import "./GasAbstraction.sol";
import "./Permit.sol";
/**
* @title FiatToken V2
* @notice ERC20 Token backed by fiat reserves, version 2
*/
contract FiatTokenV2 is FiatTokenV1_1, GasAbstraction, Permit {
using SafeMath for uint256;
/**
* @notice Initialize V2 contract
* @dev When upgrading to V2, this function must also be invoked by using
* upgradeToAndCall instead of upgradeTo, or by calling both from a contract
* in a single transaction.
* @param tokenName token name
* @param tokenSymbol token symbol
* @param tokenCurrency token currency
* @param tokenDecimals token decimals
* @param newMasterMinter new master minter
* @param newPauser new pauser
* @param newBlacklister new blacklister
* @param newOwner new owner
*/
function initialize(
string memory tokenName,
string memory tokenSymbol,
string memory tokenCurrency,
uint8 tokenDecimals,
address newMasterMinter,
address newPauser,
address newBlacklister,
address newOwner
) external {
_initialize(
tokenName,
tokenSymbol,
tokenCurrency,
tokenDecimals,
newMasterMinter,
newPauser,
newBlacklister,
newOwner
);
DOMAIN_SEPARATOR = EIP712.makeDomainSeparator(name, "1");
}
/**
* @notice Increase the allowance by a given increment
* @param spender Spender's address
* @param increment Amount of increase in allowance
* @return True if successful
*/
function increaseAllowance(address spender, uint256 increment)
external
whenNotPaused
notBlacklisted(msg.sender)
notBlacklisted(spender)
returns (bool)
{
_increaseAllowance(msg.sender, spender, increment);
return true;
}
/**
* @notice Decrease the allowance by a given decrement
* @param spender Spender's address
* @param decrement Amount of decrease in allowance
* @return True if successful
*/
function decreaseAllowance(address spender, uint256 decrement)
external
whenNotPaused
notBlacklisted(msg.sender)
notBlacklisted(spender)
returns (bool)
{
_decreaseAllowance(msg.sender, spender, decrement);
return true;
}
/**
* @notice Execute a transfer 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 v of the signature
* @param r r of the signature
* @param s s of the signature
*/
function transferWithAuthorization(
address from,
address to,
uint256 value,
uint256 validAfter,
uint256 validBefore,
bytes32 nonce,
uint8 v,
bytes32 r,
bytes32 s
) external whenNotPaused notBlacklisted(from) notBlacklisted(to) {
_transferWithAuthorization(
from,
to,
value,
validAfter,
validBefore,
nonce,
v,
r,
s
);
}
/**
* @notice Update allowance with a signed authorization
* @param owner Token owner's address (Authorizer)
* @param spender Spender's address
* @param value Amount of allowance
* @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 approveWithAuthorization(
address owner,
address spender,
uint256 value,
uint256 validAfter,
uint256 validBefore,
bytes32 nonce,
uint8 v,
bytes32 r,
bytes32 s
) external whenNotPaused notBlacklisted(owner) notBlacklisted(spender) {
_approveWithAuthorization(
owner,
spender,
value,
validAfter,
validBefore,
nonce,
v,
r,
s
);
}
/**
* @notice Increase allowance with a signed authorization
* @param owner Token owner's address (Authorizer)
* @param spender Spender's address
* @param increment Amount of increase in allowance
* @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 increaseAllowanceWithAuthorization(
address owner,
address spender,
uint256 increment,
uint256 validAfter,
uint256 validBefore,
bytes32 nonce,
uint8 v,
bytes32 r,
bytes32 s
) external whenNotPaused notBlacklisted(owner) notBlacklisted(spender) {
_increaseAllowanceWithAuthorization(
owner,
spender,
increment,
validAfter,
validBefore,
nonce,
v,
r,
s
);
}
/**
* @notice Decrease allowance with a signed authorization
* @param owner Token owner's address (Authorizer)
* @param spender Spender's address
* @param decrement Amount of decrease in allowance
* @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 decreaseAllowanceWithAuthorization(
address owner,
address spender,
uint256 decrement,
uint256 validAfter,
uint256 validBefore,
bytes32 nonce,
uint8 v,
bytes32 r,
bytes32 s
) external whenNotPaused notBlacklisted(owner) notBlacklisted(spender) {
_decreaseAllowanceWithAuthorization(
owner,
spender,
decrement,
validAfter,
validBefore,
nonce,
v,
r,
s
);
}
/**
* @notice Attempt to cancel an authorization
* @dev Works only if the authorization is not yet used.
* @param authorizer Authorizer's address
* @param nonce Nonce of the authorization
* @param v v of the signature
* @param r r of the signature
* @param s s of the signature
*/
function cancelAuthorization(
address authorizer,
bytes32 nonce,
uint8 v,
bytes32 r,
bytes32 s
) external whenNotPaused {
_cancelAuthorization(authorizer, nonce, v, r, s);
}
/**
* @notice Update allowance with a signed permit
* @param owner Token owner's address (Authorizer)
* @param spender Spender's address
* @param value Amount of allowance
* @param deadline Expiration time, seconds since the epoch
* @param v v of the signature
* @param r r of the signature
* @param s s of the signature
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external whenNotPaused notBlacklisted(owner) notBlacklisted(spender) {
_permit(owner, spender, value, deadline, v, r, s);
}
/**
* @notice Internal function to increase the allowance by a given increment
* @param owner Token owner's address
* @param spender Spender's address
* @param increment Amount of increase
*/
function _increaseAllowance(
address owner,
address spender,
uint256 increment
) internal override {
_approve(owner, spender, allowed[owner][spender].add(increment));
}
/**
* @notice Internal function to decrease the allowance by a given decrement
* @param owner Token owner's address
* @param spender Spender's address
* @param decrement Amount of decrease
*/
function _decreaseAllowance(
address owner,
address spender,
uint256 decrement
) internal override {
_approve(
owner,
spender,
allowed[owner][spender].sub(
decrement,
"ERC20: decreased allowance below zero"
)
);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)
pragma solidity ^0.8.0;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// 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 (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @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) {
return a + b;
}
/**
* @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 a - b;
}
/**
* @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) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting 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 a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting 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) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* 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) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}/**
* SPDX-License-Identifier: MIT
*
* Copyright (c) 2018-2020 CENTRE SECZ
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
pragma solidity ^0.8.10;
import "../v1/FiatTokenV1.sol";
import "./Rescuable.sol";
/**
* @title FiatTokenV1_1
* @dev ERC20 Token backed by fiat reserves
*/
contract FiatTokenV1_1 is FiatTokenV1, Rescuable {
}/**
* SPDX-License-Identifier: MIT
*
* Copyright (c) 2018-2020 CENTRE SECZ
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
pragma solidity ^0.8.10;
import "../v1/AbstractFiatTokenV1.sol";
abstract contract AbstractFiatTokenV2 is AbstractFiatTokenV1 {
function _increaseAllowance(
address owner,
address spender,
uint256 increment
) internal virtual;
function _decreaseAllowance(
address owner,
address spender,
uint256 decrement
) internal virtual;
}/**
* SPDX-License-Identifier: MIT
*
* Copyright (c) 2018-2020 CENTRE SECZ
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
pragma solidity ^0.8.10;
import "./ECRecover.sol";
/**
* @title EIP712
* @notice A library that provides EIP712 helper functions
*/
library EIP712 {
/**
* @notice Make EIP712 domain separator
* @param name Contract name
* @param version Contract version
* @return Domain separator
*/
function makeDomainSeparator(string memory name, string memory version)
internal
view
returns (bytes32)
{
uint256 chainId;
assembly {
chainId := chainid()
}
return
keccak256(
abi.encode(
0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,
// = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
keccak256(bytes(name)),
keccak256(bytes(version)),
chainId,
address(this)
)
);
}
/**
* @notice Recover signer's address from a EIP712 signature
* @param domainSeparator Domain separator
* @param v v of the signature
* @param r r of the signature
* @param s s of the signature
* @param typeHashAndData Type hash concatenated with data
* @return Signer's address
*/
function recover(
bytes32 domainSeparator,
uint8 v,
bytes32 r,
bytes32 s,
bytes memory typeHashAndData
) internal pure returns (address) {
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
domainSeparator,
keccak256(typeHashAndData)
)
);
return ECRecover.recover(digest, v, r, s);
}
}/**
* SPDX-License-Identifier: MIT
*
* Copyright (c) 2018-2020 CENTRE SECZ
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
pragma solidity ^0.8.10;
/**
* @title EIP712 Domain
*/
contract EIP712Domain {
/**
* @dev EIP712 Domain Separator
*/
bytes32 public DOMAIN_SEPARATOR;
}/**
* SPDX-License-Identifier: MIT
*
* Copyright (c) 2018-2020 CENTRE SECZ
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
pragma solidity ^0.8.10;
import "./AbstractFiatTokenV2.sol";
import "./EIP712Domain.sol";
import "../util/EIP712.sol";
/**
* @title Gas Abstraction
* @notice Provide internal implementation for gas-abstracted transfers and
* approvals
* @dev Contracts that inherit from this must wrap these with publicly
* accessible functions, optionally adding modifiers where necessary
*/
abstract contract GasAbstraction is AbstractFiatTokenV2, EIP712Domain {
bytes32
public constant TRANSFER_WITH_AUTHORIZATION_TYPEHASH = 0x7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267;
// = keccak256("TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)")
bytes32
public constant APPROVE_WITH_AUTHORIZATION_TYPEHASH = 0x808c10407a796f3ef2c7ea38c0638ea9d2b8a1c63e3ca9e1f56ce84ae59df73c;
// = keccak256("ApproveWithAuthorization(address owner,address spender,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)")
bytes32
public constant INCREASE_ALLOWANCE_WITH_AUTHORIZATION_TYPEHASH = 0x424222bb050a1f7f14017232a5671f2680a2d3420f504bd565cf03035c53198a;
// = keccak256("IncreaseAllowanceWithAuthorization(address owner,address spender,uint256 increment,uint256 validAfter,uint256 validBefore,bytes32 nonce)")
bytes32
public constant DECREASE_ALLOWANCE_WITH_AUTHORIZATION_TYPEHASH = 0xb70559e94cbda91958ebec07f9b65b3b490097c8d25c8dacd71105df1015b6d8;
// = keccak256("DecreaseAllowanceWithAuthorization(address owner,address spender,uint256 decrement,uint256 validAfter,uint256 validBefore,bytes32 nonce)")
bytes32
public constant CANCEL_AUTHORIZATION_TYPEHASH = 0x158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429;
// = keccak256("CancelAuthorization(address authorizer,bytes32 nonce)")
enum AuthorizationState { Unused, Used, Canceled }
/**
* @dev authorizer address => nonce => authorization state
*/
mapping(address => mapping(bytes32 => AuthorizationState))
private _authorizationStates;
event AuthorizationUsed(address indexed authorizer, bytes32 indexed nonce);
event AuthorizationCanceled(
address indexed authorizer,
bytes32 indexed nonce
);
/**
* @notice Returns the state of an authorization
* @param authorizer Authorizer's address
* @param nonce Nonce of the authorization
* @return Authorization state
*/
function authorizationState(address authorizer, bytes32 nonce)
external
view
returns (AuthorizationState)
{
return _authorizationStates[authorizer][nonce];
}
/**
* @notice Verify a signed transfer authorization and execute if valid
* @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 _transferWithAuthorization(
address from,
address to,
uint256 value,
uint256 validAfter,
uint256 validBefore,
bytes32 nonce,
uint8 v,
bytes32 r,
bytes32 s
) internal {
_requireValidAuthorization(from, nonce, validAfter, validBefore);
bytes memory data = abi.encode(
TRANSFER_WITH_AUTHORIZATION_TYPEHASH,
from,
to,
value,
validAfter,
validBefore,
nonce
);
require(
EIP712.recover(DOMAIN_SEPARATOR, v, r, s, data) == from,
"FiatTokenV2: invalid signature"
);
_markAuthorizationAsUsed(from, nonce);
_transfer(from, to, value);
}
/**
* @notice Verify a signed authorization for an increase in the allowance
* granted to the spender and execute if valid
* @param owner Token owner's address (Authorizer)
* @param spender Spender's address
* @param increment Amount of increase in allowance
* @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 _increaseAllowanceWithAuthorization(
address owner,
address spender,
uint256 increment,
uint256 validAfter,
uint256 validBefore,
bytes32 nonce,
uint8 v,
bytes32 r,
bytes32 s
) internal {
_requireValidAuthorization(owner, nonce, validAfter, validBefore);
bytes memory data = abi.encode(
INCREASE_ALLOWANCE_WITH_AUTHORIZATION_TYPEHASH,
owner,
spender,
increment,
validAfter,
validBefore,
nonce
);
require(
EIP712.recover(DOMAIN_SEPARATOR, v, r, s, data) == owner,
"FiatTokenV2: invalid signature"
);
_markAuthorizationAsUsed(owner, nonce);
_increaseAllowance(owner, spender, increment);
}
/**
* @notice Verify a signed authorization for a decrease in the allowance
* granted to the spender and execute if valid
* @param owner Token owner's address (Authorizer)
* @param spender Spender's address
* @param decrement Amount of decrease in allowance
* @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 _decreaseAllowanceWithAuthorization(
address owner,
address spender,
uint256 decrement,
uint256 validAfter,
uint256 validBefore,
bytes32 nonce,
uint8 v,
bytes32 r,
bytes32 s
) internal {
_requireValidAuthorization(owner, nonce, validAfter, validBefore);
bytes memory data = abi.encode(
DECREASE_ALLOWANCE_WITH_AUTHORIZATION_TYPEHASH,
owner,
spender,
decrement,
validAfter,
validBefore,
nonce
);
require(
EIP712.recover(DOMAIN_SEPARATOR, v, r, s, data) == owner,
"FiatTokenV2: invalid signature"
);
_markAuthorizationAsUsed(owner, nonce);
_decreaseAllowance(owner, spender, decrement);
}
/**
* @notice Verify a signed approval authorization and execute if valid
* @param owner Token owner's address (Authorizer)
* @param spender Spender's address
* @param value Amount of allowance
* @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 _approveWithAuthorization(
address owner,
address spender,
uint256 value,
uint256 validAfter,
uint256 validBefore,
bytes32 nonce,
uint8 v,
bytes32 r,
bytes32 s
) internal {
_requireValidAuthorization(owner, nonce, validAfter, validBefore);
bytes memory data = abi.encode(
APPROVE_WITH_AUTHORIZATION_TYPEHASH,
owner,
spender,
value,
validAfter,
validBefore,
nonce
);
require(
EIP712.recover(DOMAIN_SEPARATOR, v, r, s, data) == owner,
"FiatTokenV2: invalid signature"
);
_markAuthorizationAsUsed(owner, nonce);
_approve(owner, spender, value);
}
/**
* @notice Attempt to cancel an authorization
* @param authorizer Authorizer's address
* @param nonce Nonce of the authorization
* @param v v of the signature
* @param r r of the signature
* @param s s of the signature
*/
function _cancelAuthorization(
address authorizer,
bytes32 nonce,
uint8 v,
bytes32 r,
bytes32 s
) internal {
_requireUnusedAuthorization(authorizer, nonce);
bytes memory data = abi.encode(
CANCEL_AUTHORIZATION_TYPEHASH,
authorizer,
nonce
);
require(
EIP712.recover(DOMAIN_SEPARATOR, v, r, s, data) == authorizer,
"FiatTokenV2: invalid signature"
);
_authorizationStates[authorizer][nonce] = AuthorizationState.Canceled;
emit AuthorizationCanceled(authorizer, nonce);
}
/**
* @notice Check that an authorization is unused
* @param authorizer Authorizer's address
* @param nonce Nonce of the authorization
*/
function _requireUnusedAuthorization(address authorizer, bytes32 nonce)
private
view
{
require(
_authorizationStates[authorizer][nonce] ==
AuthorizationState.Unused,
"FiatTokenV2: authorization is used or canceled"
);
}
/**
* @notice Check that authorization is valid
* @param authorizer Authorizer's address
* @param nonce Nonce of the authorization
* @param validAfter The time after which this is valid (unix time)
* @param validBefore The time before which this is valid (unix time)
*/
function _requireValidAuthorization(
address authorizer,
bytes32 nonce,
uint256 validAfter,
uint256 validBefore
) private view {
require(
block.timestamp > validAfter,
"FiatTokenV2: authorization is not yet valid"
);
require(block.timestamp < validBefore, "FiatTokenV2: authorization is expired");
_requireUnusedAuthorization(authorizer, nonce);
}
/**
* @notice Mark an authorization as used
* @param authorizer Authorizer's address
* @param nonce Nonce of the authorization
*/
function _markAuthorizationAsUsed(address authorizer, bytes32 nonce)
private
{
_authorizationStates[authorizer][nonce] = AuthorizationState.Used;
emit AuthorizationUsed(authorizer, nonce);
}
}/**
* SPDX-License-Identifier: MIT
*
* Copyright (c) 2018-2020 CENTRE SECZ
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
pragma solidity ^0.8.10;
import "./AbstractFiatTokenV2.sol";
import "./EIP712Domain.sol";
import "../util/EIP712.sol";
/**
* @title Permit
* @notice An alternative to approveWithAuthorization, provided for
* compatibility with the draft EIP2612 proposed by Uniswap.
* @dev Differences:
* - Uses sequential nonce, which restricts transaction submission to one at a
* time, or else it will revert
* - Has deadline (= validBefore - 1) but does not have validAfter
* - Doesn't have a way to change allowance atomically to prevent ERC20 multiple
* withdrawal attacks
*/
abstract contract Permit is AbstractFiatTokenV2, EIP712Domain {
bytes32
public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
// = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)")
mapping(address => uint256) private _permitNonces;
/**
* @notice Nonces for permit
* @param owner Token owner's address (Authorizer)
* @return Next nonce
*/
function nonces(address owner) external view returns (uint256) {
return _permitNonces[owner];
}
/**
* @notice Verify a signed approval permit and execute if valid
* @param owner Token owner's address (Authorizer)
* @param spender Spender's address
* @param value Amount of allowance
* @param deadline The time at which this expires (unix time)
* @param v v of the signature
* @param r r of the signature
* @param s s of the signature
*/
function _permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
require(deadline >= block.timestamp, "FiatTokenV2: permit is expired");
bytes memory data = abi.encode(
PERMIT_TYPEHASH,
owner,
spender,
value,
_permitNonces[owner]++,
deadline
);
require(
EIP712.recover(DOMAIN_SEPARATOR, v, r, s, data) == owner,
"FiatTokenV2: invalid signature"
);
_approve(owner, spender, value);
}
}/**
* SPDX-License-Identifier: MIT
*
* Copyright (c) 2018-2020 CENTRE SECZ
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
pragma solidity ^0.8.10;
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "./AbstractFiatTokenV1.sol";
import "./Ownable.sol";
import "./Pausable.sol";
import "./Blacklistable.sol";
/**
* @title FiatToken
* @dev ERC20 Token backed by fiat reserves
*/
contract FiatTokenV1 is AbstractFiatTokenV1, Ownable, Pausable, Blacklistable {
using SafeMath for uint256;
string public name;
string public symbol;
uint8 public decimals;
string public currency;
address public masterMinter;
bool internal initialized;
mapping(address => uint256) internal balances;
mapping(address => mapping(address => uint256)) internal allowed;
uint256 internal totalSupply_ = 0;
mapping(address => bool) internal minters;
mapping(address => uint256) internal minterAllowed;
event Mint(address indexed minter, address indexed to, uint256 amount);
event Burn(address indexed burner, uint256 amount);
event MinterConfigured(address indexed minter, uint256 minterAllowedAmount);
event MinterRemoved(address indexed oldMinter);
event MasterMinterChanged(address indexed newMasterMinter);
function _initialize(
string memory tokenName,
string memory tokenSymbol,
string memory tokenCurrency,
uint8 tokenDecimals,
address newMasterMinter,
address newPauser,
address newBlacklister,
address newOwner
) internal {
require(!initialized, "FiatToken: contract is already initialized");
require(
newMasterMinter != address(0),
"FiatToken: new masterMinter is the zero address"
);
require(
newPauser != address(0),
"FiatToken: new pauser is the zero address"
);
require(
newBlacklister != address(0),
"FiatToken: new blacklister is the zero address"
);
require(
newOwner != address(0),
"FiatToken: new owner is the zero address"
);
name = tokenName;
symbol = tokenSymbol;
currency = tokenCurrency;
decimals = tokenDecimals;
masterMinter = newMasterMinter;
pauser = newPauser;
blacklister = newBlacklister;
setOwner(newOwner);
initialized = true;
}
/**
* @dev Throws if called by any account other than a minter
*/
modifier onlyMinters() {
require(minters[msg.sender], "FiatToken: caller is not a minter");
_;
}
/**
* @dev Function to mint tokens
* @param _to The address that will receive the minted tokens.
* @param _amount The amount of tokens to mint. Must be less than or equal
* to the minterAllowance of the caller.
* @return A boolean that indicates if the operation was successful.
*/
function mint(address _to, uint256 _amount)
external
whenNotPaused
onlyMinters
notBlacklisted(msg.sender)
notBlacklisted(_to)
returns (bool)
{
require(_to != address(0), "FiatToken: mint to the zero address");
require(_amount > 0, "FiatToken: mint amount not greater than 0");
uint256 mintingAllowedAmount = minterAllowed[msg.sender];
require(
_amount <= mintingAllowedAmount,
"FiatToken: mint amount exceeds minterAllowance"
);
totalSupply_ = totalSupply_.add(_amount);
balances[_to] = balances[_to].add(_amount);
minterAllowed[msg.sender] = mintingAllowedAmount.sub(_amount);
emit Mint(msg.sender, _to, _amount);
emit Transfer(address(0), _to, _amount);
return true;
}
/**
* @dev Throws if called by any account other than the masterMinter
*/
modifier onlyMasterMinter() {
require(
msg.sender == masterMinter,
"FiatToken: caller is not the masterMinter"
);
_;
}
/**
* @dev Get minter allowance for an account
* @param minter The address of the minter
*/
function minterAllowance(address minter) external view returns (uint256) {
return minterAllowed[minter];
}
/**
* @dev Checks if account is a minter
* @param account The address to check
*/
function isMinter(address account) external view returns (bool) {
return minters[account];
}
/**
* @notice Amount of remaining tokens spender is allowed to transfer on
* behalf of the token owner
* @param owner Token owner's address
* @param spender Spender's address
* @return Allowance amount
*/
function allowance(address owner, address spender)
external
override
view
returns (uint256)
{
return allowed[owner][spender];
}
/**
* @dev Get totalSupply of token
*/
function totalSupply() external override view returns (uint256) {
return totalSupply_;
}
/**
* @dev Get token balance of an account
* @param account address The account
*/
function balanceOf(address account)
external
override
view
returns (uint256)
{
return balances[account];
}
/**
* @notice Set spender's allowance over the caller's tokens to be a given
* value.
* @param spender Spender's address
* @param value Allowance amount
* @return True if successful
*/
function approve(address spender, uint256 value)
external
override
whenNotPaused
notBlacklisted(msg.sender)
notBlacklisted(spender)
returns (bool)
{
_approve(msg.sender, spender, value);
return true;
}
/**
* @dev Internal function to set allowance
* @param owner Token owner's address
* @param spender Spender's address
* @param value Allowance amount
*/
function _approve(
address owner,
address spender,
uint256 value
) internal override {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
allowed[owner][spender] = value;
emit Approval(owner, spender, value);
}
/**
* @notice Transfer tokens by spending allowance
* @param from Payer's address
* @param to Payee's address
* @param value Transfer amount
* @return True if successful
*/
function transferFrom(
address from,
address to,
uint256 value
)
external
override
whenNotPaused
notBlacklisted(msg.sender)
notBlacklisted(from)
notBlacklisted(to)
returns (bool)
{
require(
value <= allowed[from][msg.sender],
"ERC20: transfer amount exceeds allowance"
);
_transfer(from, to, value);
allowed[from][msg.sender] = allowed[from][msg.sender].sub(value);
return true;
}
/**
* @notice Transfer tokens from the caller
* @param to Payee's address
* @param value Transfer amount
* @return True if successful
*/
function transfer(address to, uint256 value)
external
override
whenNotPaused
notBlacklisted(msg.sender)
notBlacklisted(to)
returns (bool)
{
_transfer(msg.sender, to, value);
return true;
}
/**
* @notice Internal function to process transfers
* @param from Payer's address
* @param to Payee's address
* @param value Transfer amount
*/
function _transfer(
address from,
address to,
uint256 value
) internal override {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
require(
value <= balances[from],
"ERC20: transfer amount exceeds balance"
);
balances[from] = balances[from].sub(value);
balances[to] = balances[to].add(value);
emit Transfer(from, to, value);
}
/**
* @dev Function to add/update a new minter
* @param minter The address of the minter
* @param minterAllowedAmount The minting amount allowed for the minter
* @return True if the operation was successful.
*/
function configureMinter(address minter, uint256 minterAllowedAmount)
external
whenNotPaused
onlyMasterMinter
returns (bool)
{
minters[minter] = true;
minterAllowed[minter] = minterAllowedAmount;
emit MinterConfigured(minter, minterAllowedAmount);
return true;
}
/**
* @dev Function to remove a minter
* @param minter The address of the minter to remove
* @return True if the operation was successful.
*/
function removeMinter(address minter)
external
onlyMasterMinter
returns (bool)
{
minters[minter] = false;
minterAllowed[minter] = 0;
emit MinterRemoved(minter);
return true;
}
/**
* @dev allows a minter to burn some of its own tokens
* Validates that caller is a minter and that sender is not blacklisted
* amount is less than or equal to the minter's account balance
* @param _amount uint256 the amount of tokens to be burned
*/
function burn(uint256 _amount)
external
whenNotPaused
onlyMinters
notBlacklisted(msg.sender)
{
uint256 balance = balances[msg.sender];
require(_amount > 0, "FiatToken: burn amount not greater than 0");
require(balance >= _amount, "FiatToken: burn amount exceeds balance");
totalSupply_ = totalSupply_.sub(_amount);
balances[msg.sender] = balance.sub(_amount);
emit Burn(msg.sender, _amount);
emit Transfer(msg.sender, address(0), _amount);
}
function updateMasterMinter(address _newMasterMinter) external onlyOwner {
require(
_newMasterMinter != address(0),
"FiatToken: new masterMinter is the zero address"
);
masterMinter = _newMasterMinter;
emit MasterMinterChanged(masterMinter);
}
}/**
* SPDX-License-Identifier: MIT
*
* Copyright (c) 2018-2020 CENTRE SECZ
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
pragma solidity ^0.8.10;
import "../v1/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
contract Rescuable is Ownable {
using SafeERC20 for IERC20;
address private _rescuer;
event RescuerChanged(address indexed newRescuer);
/**
* @notice Returns current rescuer
* @return Rescuer's address
*/
function rescuer() external view returns (address) {
return _rescuer;
}
/**
* @notice Revert if called by any account other than the rescuer.
*/
modifier onlyRescuer() {
require(msg.sender == _rescuer, "Rescuable: caller is not the rescuer");
_;
}
/**
* @notice Rescue ERC20 tokens locked up in this contract.
* @param tokenContract ERC20 token contract address
* @param to Recipient address
* @param amount Amount to withdraw
*/
function rescueERC20(
IERC20 tokenContract,
address to,
uint256 amount
) external onlyRescuer {
tokenContract.safeTransfer(to, amount);
}
/**
* @notice Assign the rescuer role to a given address.
* @param newRescuer New rescuer's address
*/
function updateRescuer(address newRescuer) external onlyOwner {
require(
newRescuer != address(0),
"Rescuable: new rescuer is the zero address"
);
_rescuer = newRescuer;
emit RescuerChanged(newRescuer);
}
}/**
* SPDX-License-Identifier: MIT
*
* Copyright (c) 2018-2020 CENTRE SECZ
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
pragma solidity ^0.8.10;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
abstract contract AbstractFiatTokenV1 is IERC20 {
function _approve(
address owner,
address spender,
uint256 value
) internal virtual;
function _transfer(
address from,
address to,
uint256 value
) internal virtual;
}/**
* SPDX-License-Identifier: MIT
*
* Copyright (c) 2018 zOS Global Limited.
* Copyright (c) 2018-2020 CENTRE SECZ
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
pragma solidity ^0.8.10;
/**
* @notice The Ownable contract has an owner address, and provides basic
* authorization control functions
* @dev Forked from https://github.com/OpenZeppelin/openzeppelin-labs/blob/3887ab77b8adafba4a26ace002f3a684c1a3388b/upgradeability_ownership/contracts/ownership/Ownable.sol
* Modifications:
* 1. Consolidate OwnableStorage into this contract (7/13/18)
* 2. Reformat, conform to Solidity 0.6 syntax, and add error messages (5/13/20)
* 3. Make public functions external (5/27/20)
*/
contract Ownable {
// Owner of the contract
address private _owner;
/**
* @dev Event to show ownership has been transferred
* @param previousOwner representing the address of the previous owner
* @param newOwner representing the address of the new owner
*/
event OwnershipTransferred(address previousOwner, address newOwner);
/**
* @dev The constructor sets the original owner of the contract to the sender account.
*/
constructor() public {
setOwner(msg.sender);
}
/**
* @dev Tells the address of the owner
* @return the address of the owner
*/
function owner() external view returns (address) {
return _owner;
}
/**
* @dev Sets a new owner address
*/
function setOwner(address newOwner) internal {
_owner = newOwner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == _owner, "Ownable: caller is not the owner");
_;
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) external onlyOwner {
require(
newOwner != address(0),
"Ownable: new owner is the zero address"
);
emit OwnershipTransferred(_owner, newOwner);
setOwner(newOwner);
}
}/**
* SPDX-License-Identifier: MIT
*
* Copyright (c) 2016 Smart Contract Solutions, Inc.
* Copyright (c) 2018-2020 CENTRE SECZ0
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
pragma solidity ^0.8.10;
import "./Ownable.sol";
/**
* @notice Base contract which allows children to implement an emergency stop
* mechanism
* @dev Forked from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/feb665136c0dae9912e08397c1a21c4af3651ef3/contracts/lifecycle/Pausable.sol
* Modifications:
* 1. Added pauser role, switched pause/unpause to be onlyPauser (6/14/2018)
* 2. Removed whenNotPause/whenPaused from pause/unpause (6/14/2018)
* 3. Removed whenPaused (6/14/2018)
* 4. Switches ownable library to use ZeppelinOS (7/12/18)
* 5. Remove constructor (7/13/18)
* 6. Reformat, conform to Solidity 0.6 syntax and add error messages (5/13/20)
* 7. Make public functions external (5/27/20)
*/
contract Pausable is Ownable {
event Pause();
event Unpause();
event PauserChanged(address indexed newAddress);
address public pauser;
bool public paused = false;
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*/
modifier whenNotPaused() {
require(!paused, "Pausable: paused");
_;
}
/**
* @dev throws if called by any account other than the pauser
*/
modifier onlyPauser() {
require(msg.sender == pauser, "Pausable: caller is not the pauser");
_;
}
/**
* @dev called by the owner to pause, triggers stopped state
*/
function pause() external onlyPauser {
paused = true;
emit Pause();
}
/**
* @dev called by the owner to unpause, returns to normal state
*/
function unpause() external onlyPauser {
paused = false;
emit Unpause();
}
/**
* @dev update the pauser role
*/
function updatePauser(address _newPauser) external onlyOwner {
require(
_newPauser != address(0),
"Pausable: new pauser is the zero address"
);
pauser = _newPauser;
emit PauserChanged(pauser);
}
}/**
* SPDX-License-Identifier: MIT
*
* Copyright (c) 2018-2020 CENTRE SECZ
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
pragma solidity ^0.8.10;
import "./Ownable.sol";
/**
* @title Blacklistable Token
* @dev Allows accounts to be blacklisted by a "blacklister" role
*/
contract Blacklistable is Ownable {
address public blacklister;
mapping(address => bool) internal blacklisted;
event Blacklisted(address indexed _account);
event UnBlacklisted(address indexed _account);
event BlacklisterChanged(address indexed newBlacklister);
/**
* @dev Throws if called by any account other than the blacklister
*/
modifier onlyBlacklister() {
require(
msg.sender == blacklister,
"Blacklistable: caller is not the blacklister"
);
_;
}
/**
* @dev Throws if argument account is blacklisted
* @param _account The address to check
*/
modifier notBlacklisted(address _account) {
require(
!blacklisted[_account],
"Blacklistable: account is blacklisted"
);
_;
}
/**
* @dev Checks if account is blacklisted
* @param _account The address to check
*/
function isBlacklisted(address _account) external view returns (bool) {
return blacklisted[_account];
}
/**
* @dev Adds account to blacklist
* @param _account The address to blacklist
*/
function blacklist(address _account) external onlyBlacklister {
blacklisted[_account] = true;
emit Blacklisted(_account);
}
/**
* @dev Removes account from blacklist
* @param _account The address to remove from the blacklist
*/
function unBlacklist(address _account) external onlyBlacklister {
blacklisted[_account] = false;
emit UnBlacklisted(_account);
}
function updateBlacklister(address _newBlacklister) external onlyOwner {
require(
_newBlacklister != address(0),
"Blacklistable: new blacklister is the zero address"
);
blacklister = _newBlacklister;
emit BlacklisterChanged(blacklister);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}/**
* SPDX-License-Identifier: MIT
*
* Copyright (c) 2016-2019 zOS Global Limited
* Copyright (c) 2018-2020 CENTRE SECZ
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
pragma solidity ^0.8.10;
/**
* @title ECRecover
* @notice A library that provides a safe ECDSA recovery function
*/
library ECRecover {
/**
* @notice Recover signer's address from a signed message
* @dev Adapted from: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/65e4ffde586ec89af3b7e9140bdc9235d1254853/contracts/cryptography/ECDSA.sol
* Modifications: Accept v, r, and s as separate arguments
* @param digest Keccak-256 hash digest of the signed message
* @param v v of the signature
* @param r r of the signature
* @param s s of the signature
* @return Signer address
*/
function recover(
bytes32 digest,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address) {
// 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
) {
revert("ECRecover: invalid signature 's' value");
}
if (v != 27 && v != 28) {
revert("ECRecover: invalid signature 'v' value");
}
// If the signature is valid (and not malleable), return the signer address
address signer = ecrecover(digest, v, r, s);
require(signer != address(0), "ECRecover: invalid signature");
return signer;
}
}{
"optimizer": {
"enabled": true,
"runs": 9999999
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"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":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationUsed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_account","type":"address"}],"name":"Blacklisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newBlacklister","type":"address"}],"name":"BlacklisterChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"burner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newMasterMinter","type":"address"}],"name":"MasterMinterChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"minterAllowedAmount","type":"uint256"}],"name":"MinterConfigured","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldMinter","type":"address"}],"name":"MinterRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"PauserChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newRescuer","type":"address"}],"name":"RescuerChanged","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_account","type":"address"}],"name":"UnBlacklisted","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"inputs":[],"name":"APPROVE_WITH_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CANCEL_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DECREASE_ALLOWANCE_WITH_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INCREASE_ALLOWANCE_WITH_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TRANSFER_WITH_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"approveWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"authorizationState","outputs":[{"internalType":"enum GasAbstraction.AuthorizationState","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"blacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"blacklister","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"cancelAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"},{"internalType":"uint256","name":"minterAllowedAmount","type":"uint256"}],"name":"configureMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currency","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"decrement","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"decrement","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"decreaseAllowanceWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"increment","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"increment","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"increaseAllowanceWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"tokenName","type":"string"},{"internalType":"string","name":"tokenSymbol","type":"string"},{"internalType":"string","name":"tokenCurrency","type":"string"},{"internalType":"uint8","name":"tokenDecimals","type":"uint8"},{"internalType":"address","name":"newMasterMinter","type":"address"},{"internalType":"address","name":"newPauser","type":"address"},{"internalType":"address","name":"newBlacklister","type":"address"},{"internalType":"address","name":"newOwner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isBlacklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"masterMinter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"minterAllowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauser","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"removeMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"tokenContract","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"rescueERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rescuer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"transferWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"unBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newBlacklister","type":"address"}],"name":"updateBlacklister","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newMasterMinter","type":"address"}],"name":"updateMasterMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newPauser","type":"address"}],"name":"updatePauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRescuer","type":"address"}],"name":"updateRescuer","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040526001805460ff60a01b191690556000600b5534801561002257600080fd5b50600080546001600160a01b03191633179055615d2e80620000456000396000f3fe608060405234801561001057600080fd5b50600436106103415760003560e01c80638456cb59116101bd578063bd102430116100f9578063e1560fd3116100a2578063e94a01021161007c578063e94a010214610867578063f2fde38b146108ba578063f9f92be4146108cd578063fe575a87146108e057600080fd5b8063e1560fd314610839578063e3ee160e1461084c578063e5a6b10f1461085f57600080fd5b8063d505accf116100d3578063d505accf146107b9578063d9169487146107cc578063dd62ed3e146107f357600080fd5b8063bd1024301461075f578063c237108f1461077f578063c7b84f8d1461079257600080fd5b8063a457c2d711610166578063aa271e1a11610140578063aa271e1a146106ed578063ad38bf2214610726578063b008609514610739578063b2118a8d1461074c57600080fd5b8063a457c2d7146106b4578063a9059cbb146106c7578063aa20e1e4146106da57600080fd5b806395d89b411161019757806395d89b41146106655780639fd0506d1461066d578063a0cc6a681461068d57600080fd5b80638456cb59146106095780638a6db9c3146106115780638da5cb5b1461064757600080fd5b80633644e5151161028c5780634b71f5c3116102355780635a049a701161020f5780635a049a70146105655780635c975abb1461057857806370a082311461059d5780637ecebe00146105d357600080fd5b80634b71f5c3146105185780634e44d9561461053f578063554bab3c1461055257600080fd5b80633f4ba83a116102665780633f4ba83a146104ea57806340c10f19146104f257806342966c681461050557600080fd5b80633644e515146104b057806338a63183146104b957806339509351146104d757600080fd5b80632ab60045116102ee578063313ce567116102c8578063313ce567146104395780633357162b1461045857806335d99f351461046b57600080fd5b80632ab60045146103ec5780633092afd5146103ff57806330adf81f1461041257600080fd5b806318160ddd1161031f57806318160ddd146103bc5780631a895266146103c457806323b872dd146103d957600080fd5b806306fdde0314610346578063095ea7b31461036457806310c8b40414610387575b600080fd5b61034e610919565b60405161035b91906156d9565b60405180910390f35b610377610372366004615757565b6109a7565b604051901515815260200161035b565b6103ae7f808c10407a796f3ef2c7ea38c0638ea9d2b8a1c63e3ca9e1f56ce84ae59df73c81565b60405190815260200161035b565b600b546103ae565b6103d76103d2366004615783565b610ba2565b005b6103776103e73660046157a0565b610cbd565b6103d76103fa366004615783565b61109a565b61037761040d366004615783565b61122d565b6103ae7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6006546104469060ff1681565b60405160ff909116815260200161035b565b6103d76104663660046158cc565b61135e565b60085461048b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161035b565b6103ae600f5481565b600e5473ffffffffffffffffffffffffffffffffffffffff1661048b565b6103776104e5366004615757565b6114c8565b6103d76116b3565b610377610500366004615757565b6117ad565b6103d76105133660046159a8565b611d27565b6103ae7fb70559e94cbda91958ebec07f9b65b3b490097c8d25c8dacd71105df1015b6d881565b61037761054d366004615757565b6120be565b6103d7610560366004615783565b612282565b6103d76105733660046159c1565b612415565b6001546103779074010000000000000000000000000000000000000000900460ff1681565b6103ae6105ab366004615783565b73ffffffffffffffffffffffffffffffffffffffff1660009081526009602052604090205490565b6103ae6105e1366004615783565b73ffffffffffffffffffffffffffffffffffffffff1660009081526011602052604090205490565b6103d76124ae565b6103ae61061f366004615783565b73ffffffffffffffffffffffffffffffffffffffff166000908152600d602052604090205490565b60005473ffffffffffffffffffffffffffffffffffffffff1661048b565b61034e6125bf565b60015461048b9073ffffffffffffffffffffffffffffffffffffffff1681565b6103ae7f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a226781565b6103776106c2366004615757565b6125cc565b6103776106d5366004615757565b6127b7565b6103d76106e8366004615783565b6129a2565b6103776106fb366004615783565b73ffffffffffffffffffffffffffffffffffffffff166000908152600c602052604090205460ff1690565b6103d7610734366004615783565b612b35565b6103d7610747366004615a11565b612cc8565b6103d761075a3660046157a0565b612edb565b60025461048b9073ffffffffffffffffffffffffffffffffffffffff1681565b6103d761078d366004615a11565b612fa7565b6103ae7f424222bb050a1f7f14017232a5671f2680a2d3420f504bd565cf03035c53198a81565b6103d76107c7366004615a93565b6131ad565b6103ae7f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742981565b6103ae610801366004615b01565b73ffffffffffffffffffffffffffffffffffffffff9182166000908152600a6020908152604080832093909416825291909152205490565b6103d7610847366004615a11565b6133bc565b6103d761085a366004615a11565b6135c2565b61034e6137c8565b6108ad610875366004615757565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152601060209081526040808320938352929052205460ff1690565b60405161035b9190615b69565b6103d76108c8366004615783565b6137d5565b6103d76108db366004615783565b613993565b6103776108ee366004615783565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205460ff1690565b6004805461092690615baa565b80601f016020809104026020016040519081016040528092919081815260200182805461095290615baa565b801561099f5780601f106109745761010080835404028352916020019161099f565b820191906000526020600020905b81548152906001019060200180831161098257829003601f168201915b505050505081565b60015460009074010000000000000000000000000000000000000000900460ff1615610a34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064015b60405180910390fd5b3360008181526003602052604090205460ff1615610ad4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260036020526040902054849060ff1615610b8c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b610b97338686613ab1565b506001949350505050565b60025473ffffffffffffffffffffffffffffffffffffffff163314610c49576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f426c61636b6c69737461626c653a2063616c6c6572206973206e6f742074686560448201527f20626c61636b6c697374657200000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f117e3210bb9aa7d9baff172026820255c6f6c30ba8999d1c2fd88e2848137c4e9190a250565b60015460009074010000000000000000000000000000000000000000900460ff1615610d45576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b3360008181526003602052604090205460ff1615610de5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8516600090815260036020526040902054859060ff1615610e9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8516600090815260036020526040902054859060ff1615610f55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff87166000908152600a60209081526040808320338452909152902054851115611015576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610a2b565b611020878787613c5c565b73ffffffffffffffffffffffffffffffffffffffff87166000908152600a6020908152604080832033845290915290205461105b9086613f24565b73ffffffffffffffffffffffffffffffffffffffff88166000908152600a60209081526040808320338452909152902055600193505050509392505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461111b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff81166111be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f526573637561626c653a206e6577207265736375657220697320746865207a6560448201527f726f2061646472657373000000000000000000000000000000000000000000006064820152608401610a2b565b600e80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517fe475e580d85111348e40d8ca33cfdd74c30fe1655c2d8537a13abc10065ffa5a90600090a250565b60085460009073ffffffffffffffffffffffffffffffffffffffff1633146112d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f46696174546f6b656e3a2063616c6c6572206973206e6f7420746865206d617360448201527f7465724d696e74657200000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff82166000818152600c6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055600d909152808220829055517fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb666929190a25060015b919050565b61136e8888888888888888613f37565b6114bb6004805461137e90615baa565b80601f01602080910402602001604051908101604052809291908181526020018280546113aa90615baa565b80156113f75780601f106113cc576101008083540402835291602001916113f7565b820191906000526020600020905b8154815290600101906020018083116113da57829003601f168201915b5050604080518082018252600181527f310000000000000000000000000000000000000000000000000000000000000060209182015285519581019590952081517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81880152808301919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a0808301919091528251808303909101815260c090910190915280519401939093209392505050565b600f555050505050505050565b60015460009074010000000000000000000000000000000000000000900460ff1615611550576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b3360008181526003602052604090205460ff16156115f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260036020526040902054849060ff16156116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b610b9733868661438f565b60015473ffffffffffffffffffffffffffffffffffffffff16331461175a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f5061757361626c653a2063616c6c6572206973206e6f7420746865207061757360448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610a2b565b600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690556040517f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3390600090a1565b60015460009074010000000000000000000000000000000000000000900460ff1615611835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b336000908152600c602052604090205460ff166118d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f46696174546f6b656e3a2063616c6c6572206973206e6f742061206d696e746560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610a2b565b3360008181526003602052604090205460ff1615611974576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260036020526040902054849060ff1615611a2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8516611acf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f46696174546f6b656e3a206d696e7420746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610a2b565b60008411611b5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f46696174546f6b656e3a206d696e7420616d6f756e74206e6f7420677265617460448201527f6572207468616e203000000000000000000000000000000000000000000000006064820152608401610a2b565b336000908152600d602052604090205480851115611bff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f46696174546f6b656e3a206d696e7420616d6f756e742065786365656473206d60448201527f696e746572416c6c6f77616e63650000000000000000000000000000000000006064820152608401610a2b565b600b54611c0c90866143d9565b600b5573ffffffffffffffffffffffffffffffffffffffff8616600090815260096020526040902054611c3f90866143d9565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260096020526040902055611c6f8186613f24565b336000818152600d6020908152604091829020939093555187815273ffffffffffffffffffffffffffffffffffffffff8916927fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8910160405180910390a360405185815273ffffffffffffffffffffffffffffffffffffffff8716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a350600195945050505050565b60015474010000000000000000000000000000000000000000900460ff1615611dac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b336000908152600c602052604090205460ff16611e4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f46696174546f6b656e3a2063616c6c6572206973206e6f742061206d696e746560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610a2b565b3360008181526003602052604090205460ff1615611eeb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b3360009081526009602052604090205482611f88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f46696174546f6b656e3a206275726e20616d6f756e74206e6f7420677265617460448201527f6572207468616e203000000000000000000000000000000000000000000000006064820152608401610a2b565b82811015612018576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f46696174546f6b656e3a206275726e20616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610a2b565b600b546120259084613f24565b600b556120328184613f24565b33600081815260096020526040908190209290925590517fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5906120789086815260200190565b60405180910390a260405183815260009033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a3505050565b60015460009074010000000000000000000000000000000000000000900460ff1615612146576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b60085473ffffffffffffffffffffffffffffffffffffffff1633146121ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f46696174546f6b656e3a2063616c6c6572206973206e6f7420746865206d617360448201527f7465724d696e74657200000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff83166000818152600c6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055600d82529182902085905590518481527f46980fca912ef9bcdbd36877427b6b90e860769f604e89c0e67720cece530d20910160405180910390a250600192915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612303576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff81166123a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5061757361626c653a206e65772070617573657220697320746865207a65726f60448201527f20616464726573730000000000000000000000000000000000000000000000006064820152608401610a2b565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517fb80482a293ca2e013eda8683c9bd7fc8347cfdaeea5ede58cba46df502c2a60490600090a250565b60015474010000000000000000000000000000000000000000900460ff161561249a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b6124a785858585856143e5565b5050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314612555576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f5061757361626c653a2063616c6c6572206973206e6f7420746865207061757360448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610a2b565b600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790556040517f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62590600090a1565b6005805461092690615baa565b60015460009074010000000000000000000000000000000000000000900460ff1615612654576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b3360008181526003602052604090205460ff16156126f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260036020526040902054849060ff16156127ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b610b97338686614581565b60015460009074010000000000000000000000000000000000000000900460ff161561283f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b3360008181526003602052604090205460ff16156128df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260036020526040902054849060ff1615612997576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b610b97338686613c5c565b60005473ffffffffffffffffffffffffffffffffffffffff163314612a23576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8116612ac6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f46696174546f6b656e3a206e6577206d61737465724d696e746572206973207460448201527f6865207a65726f206164647265737300000000000000000000000000000000006064820152608401610a2b565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517fdb66dfa9c6b8f5226fe9aac7e51897ae8ee94ac31dc70bb6c9900b2574b707e690600090a250565b60005473ffffffffffffffffffffffffffffffffffffffff163314612bb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8116612c59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f426c61636b6c69737461626c653a206e657720626c61636b6c6973746572206960448201527f7320746865207a65726f206164647265737300000000000000000000000000006064820152608401610a2b565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517fc67398012c111ce95ecb7429b933096c977380ee6c421175a71a4a4c6c88c06e90600090a250565b60015474010000000000000000000000000000000000000000900460ff1615612d4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8916600090815260036020526040902054899060ff1615612e05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8916600090815260036020526040902054899060ff1615612ebd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b612ece8b8b8b8b8b8b8b8b8b6145dd565b5050505050505050505050565b600e5473ffffffffffffffffffffffffffffffffffffffff163314612f81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f526573637561626c653a2063616c6c6572206973206e6f74207468652072657360448201527f63756572000000000000000000000000000000000000000000000000000000006064820152608401610a2b565b612fa273ffffffffffffffffffffffffffffffffffffffff84168383614732565b505050565b60015474010000000000000000000000000000000000000000900460ff161561302c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8916600090815260036020526040902054899060ff16156130e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8916600090815260036020526040902054899060ff161561319c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b612ece8b8b8b8b8b8b8b8b8b6147bf565b60015474010000000000000000000000000000000000000000900460ff1615613232576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260036020526040902054879060ff16156132ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260036020526040902054879060ff16156133a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b6133b189898989898989614908565b505050505050505050565b60015474010000000000000000000000000000000000000000900460ff1615613441576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8916600090815260036020526040902054899060ff16156134f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8916600090815260036020526040902054899060ff16156135b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b612ece8b8b8b8b8b8b8b8b8b614ade565b60015474010000000000000000000000000000000000000000900460ff1615613647576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8916600090815260036020526040902054899060ff16156136ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8916600090815260036020526040902054899060ff16156137b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b612ece8b8b8b8b8b8b8b8b8b614c27565b6007805461092690615baa565b60005473ffffffffffffffffffffffffffffffffffffffff163314613856576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff81166138f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610a2b565b6000546040805173ffffffffffffffffffffffffffffffffffffffff928316815291831660208301527f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0910160405180910390a1600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff831617905550565b50565b60025473ffffffffffffffffffffffffffffffffffffffff163314613a3a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f426c61636b6c69737461626c653a2063616c6c6572206973206e6f742074686560448201527f20626c61636b6c697374657200000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517fffa4e6181777692565cf28528fc88fd1516ea86b56da075235fa575af6a4b8559190a250565b73ffffffffffffffffffffffffffffffffffffffff8316613b53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8216613bf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8381166000818152600a602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591016120b1565b73ffffffffffffffffffffffffffffffffffffffff8316613cff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8216613da2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260096020526040902054811115613e57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260096020526040902054613e879082613f24565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600960205260408082209390935590841681522054613ec390826143d9565b73ffffffffffffffffffffffffffffffffffffffff80841660008181526009602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906120b19085815260200190565b6000613f308284615c2d565b9392505050565b60085474010000000000000000000000000000000000000000900460ff1615613fe2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f46696174546f6b656e3a20636f6e747261637420697320616c7265616479206960448201527f6e697469616c697a6564000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8416614085576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f46696174546f6b656e3a206e6577206d61737465724d696e746572206973207460448201527f6865207a65726f206164647265737300000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8316614128576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f46696174546f6b656e3a206e65772070617573657220697320746865207a657260448201527f6f206164647265737300000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff82166141cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f46696174546f6b656e3a206e657720626c61636b6c697374657220697320746860448201527f65207a65726f20616464726573730000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff811661426e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f46696174546f6b656e3a206e6577206f776e657220697320746865207a65726f60448201527f20616464726573730000000000000000000000000000000000000000000000006064820152608401610a2b565b87516142819060049060208b0190615614565b5086516142959060059060208a0190615614565b5085516142a9906007906020890190615614565b50600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff8716179055600880547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff87811691909117909255600180548216868416179055600280548216858416179055600080549091169183169190911790555050600880547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055505050505050565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600a6020908152604080832093861683529290522054612fa290849084906143d490856143d9565b613ab1565b6000613f308284615c44565b6143ef8585614d70565b604080517f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429602082015273ffffffffffffffffffffffffffffffffffffffff8716918101919091526060810185905260009060800160405160208183030381529060405290508573ffffffffffffffffffffffffffffffffffffffff1661447b600f5486868686614e46565b73ffffffffffffffffffffffffffffffffffffffff16146144f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46696174546f6b656e56323a20696e76616c6964207369676e617475726500006044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8616600081815260106020908152604080832089845290915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166002179055518792917f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d8191a3505050505050565b612fa283836143d484604051806060016040528060258152602001615cd46025913973ffffffffffffffffffffffffffffffffffffffff808a166000908152600a60209081526040808320938c16835292905220549190614ec3565b6145e989858888614f09565b604080517fb70559e94cbda91958ebec07f9b65b3b490097c8d25c8dacd71105df1015b6d8602082015273ffffffffffffffffffffffffffffffffffffffff808c169282019290925290891660608201526080810188905260a0810187905260c0810186905260e081018590526000906101000160405160208183030381529060405290508973ffffffffffffffffffffffffffffffffffffffff16614694600f5486868686614e46565b73ffffffffffffffffffffffffffffffffffffffff1614614711576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46696174546f6b656e56323a20696e76616c6964207369676e617475726500006044820152606401610a2b565b61471b8a86615037565b6147268a8a8a614581565b50505050505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052612fa29084906150bc565b6147cb89858888614f09565b604080517f424222bb050a1f7f14017232a5671f2680a2d3420f504bd565cf03035c53198a602082015273ffffffffffffffffffffffffffffffffffffffff808c169282019290925290891660608201526080810188905260a0810187905260c0810186905260e081018590526000906101000160405160208183030381529060405290508973ffffffffffffffffffffffffffffffffffffffff16614876600f5486868686614e46565b73ffffffffffffffffffffffffffffffffffffffff16146148f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46696174546f6b656e56323a20696e76616c6964207369676e617475726500006044820152606401610a2b565b6148fd8a86615037565b6147268a8a8a61438f565b42841015614972576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46696174546f6b656e56323a207065726d6974206973206578706972656400006044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260116020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a9190866149cc83615c5c565b9091555060408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405290508773ffffffffffffffffffffffffffffffffffffffff16614a4c600f5486868686614e46565b73ffffffffffffffffffffffffffffffffffffffff1614614ac9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46696174546f6b656e56323a20696e76616c6964207369676e617475726500006044820152606401610a2b565b614ad4888888613ab1565b5050505050505050565b614aea89858888614f09565b604080517f808c10407a796f3ef2c7ea38c0638ea9d2b8a1c63e3ca9e1f56ce84ae59df73c602082015273ffffffffffffffffffffffffffffffffffffffff808c169282019290925290891660608201526080810188905260a0810187905260c0810186905260e081018590526000906101000160405160208183030381529060405290508973ffffffffffffffffffffffffffffffffffffffff16614b95600f5486868686614e46565b73ffffffffffffffffffffffffffffffffffffffff1614614c12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46696174546f6b656e56323a20696e76616c6964207369676e617475726500006044820152606401610a2b565b614c1c8a86615037565b6147268a8a8a613ab1565b614c3389858888614f09565b604080517f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267602082015273ffffffffffffffffffffffffffffffffffffffff808c169282019290925290891660608201526080810188905260a0810187905260c0810186905260e081018590526000906101000160405160208183030381529060405290508973ffffffffffffffffffffffffffffffffffffffff16614cde600f5486868686614e46565b73ffffffffffffffffffffffffffffffffffffffff1614614d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46696174546f6b656e56323a20696e76616c6964207369676e617475726500006044820152606401610a2b565b614d658a86615037565b6147268a8a8a613c5c565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260106020908152604080832084845290915281205460ff166002811115614db557614db5615b3a565b14614e42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f46696174546f6b656e56323a20617574686f72697a6174696f6e20697320757360448201527f6564206f722063616e63656c65640000000000000000000000000000000000006064820152608401610a2b565b5050565b600080868380519060200120604051602001614e949291907f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050614eb8818787876151c8565b979650505050505050565b60008184841115614f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2b91906156d9565b505050900390565b814211614f98576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f46696174546f6b656e56323a20617574686f72697a6174696f6e206973206e6f60448201527f74207965742076616c69640000000000000000000000000000000000000000006064820152608401610a2b565b804210615027576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f46696174546f6b656e56323a20617574686f72697a6174696f6e20697320657860448201527f70697265640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b6150318484614d70565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260106020908152604080832085845290915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055518392917f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a591a35050565b600061511e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166154249092919063ffffffff16565b805190915015612fa2578080602001905181019061513c9190615c95565b612fa2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610a2b565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a082111561527a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45435265636f7665723a20696e76616c6964207369676e61747572652027732760448201527f2076616c756500000000000000000000000000000000000000000000000000006064820152608401610a2b565b8360ff16601b1415801561529257508360ff16601c14155b1561531f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45435265636f7665723a20696e76616c6964207369676e61747572652027762760448201527f2076616c756500000000000000000000000000000000000000000000000000006064820152608401610a2b565b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa158015615373573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661541b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45435265636f7665723a20696e76616c6964207369676e6174757265000000006044820152606401610a2b565b95945050505050565b6060615433848460008561543b565b949350505050565b6060824710156154cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff85163b61554b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a2b565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516155749190615cb7565b60006040518083038185875af1925050503d80600081146155b1576040519150601f19603f3d011682016040523d82523d6000602084013e6155b6565b606091505b5091509150614eb8828286606083156155d0575081613f30565b8251156155e05782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2b91906156d9565b82805461562090615baa565b90600052602060002090601f0160209004810192826156425760008555615688565b82601f1061565b57805160ff1916838001178555615688565b82800160010185558215615688579182015b8281111561568857825182559160200191906001019061566d565b50615694929150615698565b5090565b5b808211156156945760008155600101615699565b60005b838110156156c85781810151838201526020016156b0565b838111156150315750506000910152565b60208152600082518060208401526156f88160408501602087016156ad565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461399057600080fd5b80356113598161572a565b6000806040838503121561576a57600080fd5b82356157758161572a565b946020939093013593505050565b60006020828403121561579557600080fd5b8135613f308161572a565b6000806000606084860312156157b557600080fd5b83356157c08161572a565b925060208401356157d08161572a565b929592945050506040919091013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261582157600080fd5b813567ffffffffffffffff8082111561583c5761583c6157e1565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715615882576158826157e1565b8160405283815286602085880101111561589b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b803560ff8116811461135957600080fd5b600080600080600080600080610100898b0312156158e957600080fd5b883567ffffffffffffffff8082111561590157600080fd5b61590d8c838d01615810565b995060208b013591508082111561592357600080fd5b61592f8c838d01615810565b985060408b013591508082111561594557600080fd5b506159528b828c01615810565b96505061596160608a016158bb565b945061596f60808a0161574c565b935061597d60a08a0161574c565b925061598b60c08a0161574c565b915061599960e08a0161574c565b90509295985092959890939650565b6000602082840312156159ba57600080fd5b5035919050565b600080600080600060a086880312156159d957600080fd5b85356159e48161572a565b9450602086013593506159f9604087016158bb565b94979396509394606081013594506080013592915050565b60008060008060008060008060006101208a8c031215615a3057600080fd5b8935615a3b8161572a565b985060208a0135615a4b8161572a565b975060408a0135965060608a0135955060808a0135945060a08a01359350615a7560c08b016158bb565b925060e08a013591506101008a013590509295985092959850929598565b600080600080600080600060e0888a031215615aae57600080fd5b8735615ab98161572a565b96506020880135615ac98161572a565b95506040880135945060608801359350615ae5608089016158bb565b925060a0880135915060c0880135905092959891949750929550565b60008060408385031215615b1457600080fd5b8235615b1f8161572a565b91506020830135615b2f8161572a565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310615ba4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b600181811c90821680615bbe57607f821691505b60208210811415615bf8577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015615c3f57615c3f615bfe565b500390565b60008219821115615c5757615c57615bfe565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415615c8e57615c8e615bfe565b5060010190565b600060208284031215615ca757600080fd5b81518015158114613f3057600080fd5b60008251615cc98184602087016156ad565b919091019291505056fe45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa26469706673582212204b40c0f4417904396b412d974db9c421cec7c6e2c62ce9725d7590726224a1c864736f6c634300080a0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103415760003560e01c80638456cb59116101bd578063bd102430116100f9578063e1560fd3116100a2578063e94a01021161007c578063e94a010214610867578063f2fde38b146108ba578063f9f92be4146108cd578063fe575a87146108e057600080fd5b8063e1560fd314610839578063e3ee160e1461084c578063e5a6b10f1461085f57600080fd5b8063d505accf116100d3578063d505accf146107b9578063d9169487146107cc578063dd62ed3e146107f357600080fd5b8063bd1024301461075f578063c237108f1461077f578063c7b84f8d1461079257600080fd5b8063a457c2d711610166578063aa271e1a11610140578063aa271e1a146106ed578063ad38bf2214610726578063b008609514610739578063b2118a8d1461074c57600080fd5b8063a457c2d7146106b4578063a9059cbb146106c7578063aa20e1e4146106da57600080fd5b806395d89b411161019757806395d89b41146106655780639fd0506d1461066d578063a0cc6a681461068d57600080fd5b80638456cb59146106095780638a6db9c3146106115780638da5cb5b1461064757600080fd5b80633644e5151161028c5780634b71f5c3116102355780635a049a701161020f5780635a049a70146105655780635c975abb1461057857806370a082311461059d5780637ecebe00146105d357600080fd5b80634b71f5c3146105185780634e44d9561461053f578063554bab3c1461055257600080fd5b80633f4ba83a116102665780633f4ba83a146104ea57806340c10f19146104f257806342966c681461050557600080fd5b80633644e515146104b057806338a63183146104b957806339509351146104d757600080fd5b80632ab60045116102ee578063313ce567116102c8578063313ce567146104395780633357162b1461045857806335d99f351461046b57600080fd5b80632ab60045146103ec5780633092afd5146103ff57806330adf81f1461041257600080fd5b806318160ddd1161031f57806318160ddd146103bc5780631a895266146103c457806323b872dd146103d957600080fd5b806306fdde0314610346578063095ea7b31461036457806310c8b40414610387575b600080fd5b61034e610919565b60405161035b91906156d9565b60405180910390f35b610377610372366004615757565b6109a7565b604051901515815260200161035b565b6103ae7f808c10407a796f3ef2c7ea38c0638ea9d2b8a1c63e3ca9e1f56ce84ae59df73c81565b60405190815260200161035b565b600b546103ae565b6103d76103d2366004615783565b610ba2565b005b6103776103e73660046157a0565b610cbd565b6103d76103fa366004615783565b61109a565b61037761040d366004615783565b61122d565b6103ae7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6006546104469060ff1681565b60405160ff909116815260200161035b565b6103d76104663660046158cc565b61135e565b60085461048b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161035b565b6103ae600f5481565b600e5473ffffffffffffffffffffffffffffffffffffffff1661048b565b6103776104e5366004615757565b6114c8565b6103d76116b3565b610377610500366004615757565b6117ad565b6103d76105133660046159a8565b611d27565b6103ae7fb70559e94cbda91958ebec07f9b65b3b490097c8d25c8dacd71105df1015b6d881565b61037761054d366004615757565b6120be565b6103d7610560366004615783565b612282565b6103d76105733660046159c1565b612415565b6001546103779074010000000000000000000000000000000000000000900460ff1681565b6103ae6105ab366004615783565b73ffffffffffffffffffffffffffffffffffffffff1660009081526009602052604090205490565b6103ae6105e1366004615783565b73ffffffffffffffffffffffffffffffffffffffff1660009081526011602052604090205490565b6103d76124ae565b6103ae61061f366004615783565b73ffffffffffffffffffffffffffffffffffffffff166000908152600d602052604090205490565b60005473ffffffffffffffffffffffffffffffffffffffff1661048b565b61034e6125bf565b60015461048b9073ffffffffffffffffffffffffffffffffffffffff1681565b6103ae7f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a226781565b6103776106c2366004615757565b6125cc565b6103776106d5366004615757565b6127b7565b6103d76106e8366004615783565b6129a2565b6103776106fb366004615783565b73ffffffffffffffffffffffffffffffffffffffff166000908152600c602052604090205460ff1690565b6103d7610734366004615783565b612b35565b6103d7610747366004615a11565b612cc8565b6103d761075a3660046157a0565b612edb565b60025461048b9073ffffffffffffffffffffffffffffffffffffffff1681565b6103d761078d366004615a11565b612fa7565b6103ae7f424222bb050a1f7f14017232a5671f2680a2d3420f504bd565cf03035c53198a81565b6103d76107c7366004615a93565b6131ad565b6103ae7f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742981565b6103ae610801366004615b01565b73ffffffffffffffffffffffffffffffffffffffff9182166000908152600a6020908152604080832093909416825291909152205490565b6103d7610847366004615a11565b6133bc565b6103d761085a366004615a11565b6135c2565b61034e6137c8565b6108ad610875366004615757565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152601060209081526040808320938352929052205460ff1690565b60405161035b9190615b69565b6103d76108c8366004615783565b6137d5565b6103d76108db366004615783565b613993565b6103776108ee366004615783565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205460ff1690565b6004805461092690615baa565b80601f016020809104026020016040519081016040528092919081815260200182805461095290615baa565b801561099f5780601f106109745761010080835404028352916020019161099f565b820191906000526020600020905b81548152906001019060200180831161098257829003601f168201915b505050505081565b60015460009074010000000000000000000000000000000000000000900460ff1615610a34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064015b60405180910390fd5b3360008181526003602052604090205460ff1615610ad4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260036020526040902054849060ff1615610b8c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b610b97338686613ab1565b506001949350505050565b60025473ffffffffffffffffffffffffffffffffffffffff163314610c49576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f426c61636b6c69737461626c653a2063616c6c6572206973206e6f742074686560448201527f20626c61636b6c697374657200000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f117e3210bb9aa7d9baff172026820255c6f6c30ba8999d1c2fd88e2848137c4e9190a250565b60015460009074010000000000000000000000000000000000000000900460ff1615610d45576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b3360008181526003602052604090205460ff1615610de5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8516600090815260036020526040902054859060ff1615610e9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8516600090815260036020526040902054859060ff1615610f55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff87166000908152600a60209081526040808320338452909152902054851115611015576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610a2b565b611020878787613c5c565b73ffffffffffffffffffffffffffffffffffffffff87166000908152600a6020908152604080832033845290915290205461105b9086613f24565b73ffffffffffffffffffffffffffffffffffffffff88166000908152600a60209081526040808320338452909152902055600193505050509392505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461111b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff81166111be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f526573637561626c653a206e6577207265736375657220697320746865207a6560448201527f726f2061646472657373000000000000000000000000000000000000000000006064820152608401610a2b565b600e80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517fe475e580d85111348e40d8ca33cfdd74c30fe1655c2d8537a13abc10065ffa5a90600090a250565b60085460009073ffffffffffffffffffffffffffffffffffffffff1633146112d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f46696174546f6b656e3a2063616c6c6572206973206e6f7420746865206d617360448201527f7465724d696e74657200000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff82166000818152600c6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055600d909152808220829055517fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb666929190a25060015b919050565b61136e8888888888888888613f37565b6114bb6004805461137e90615baa565b80601f01602080910402602001604051908101604052809291908181526020018280546113aa90615baa565b80156113f75780601f106113cc576101008083540402835291602001916113f7565b820191906000526020600020905b8154815290600101906020018083116113da57829003601f168201915b5050604080518082018252600181527f310000000000000000000000000000000000000000000000000000000000000060209182015285519581019590952081517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81880152808301919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a0808301919091528251808303909101815260c090910190915280519401939093209392505050565b600f555050505050505050565b60015460009074010000000000000000000000000000000000000000900460ff1615611550576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b3360008181526003602052604090205460ff16156115f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260036020526040902054849060ff16156116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b610b9733868661438f565b60015473ffffffffffffffffffffffffffffffffffffffff16331461175a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f5061757361626c653a2063616c6c6572206973206e6f7420746865207061757360448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610a2b565b600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690556040517f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3390600090a1565b60015460009074010000000000000000000000000000000000000000900460ff1615611835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b336000908152600c602052604090205460ff166118d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f46696174546f6b656e3a2063616c6c6572206973206e6f742061206d696e746560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610a2b565b3360008181526003602052604090205460ff1615611974576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260036020526040902054849060ff1615611a2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8516611acf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f46696174546f6b656e3a206d696e7420746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610a2b565b60008411611b5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f46696174546f6b656e3a206d696e7420616d6f756e74206e6f7420677265617460448201527f6572207468616e203000000000000000000000000000000000000000000000006064820152608401610a2b565b336000908152600d602052604090205480851115611bff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f46696174546f6b656e3a206d696e7420616d6f756e742065786365656473206d60448201527f696e746572416c6c6f77616e63650000000000000000000000000000000000006064820152608401610a2b565b600b54611c0c90866143d9565b600b5573ffffffffffffffffffffffffffffffffffffffff8616600090815260096020526040902054611c3f90866143d9565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260096020526040902055611c6f8186613f24565b336000818152600d6020908152604091829020939093555187815273ffffffffffffffffffffffffffffffffffffffff8916927fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8910160405180910390a360405185815273ffffffffffffffffffffffffffffffffffffffff8716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a350600195945050505050565b60015474010000000000000000000000000000000000000000900460ff1615611dac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b336000908152600c602052604090205460ff16611e4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f46696174546f6b656e3a2063616c6c6572206973206e6f742061206d696e746560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610a2b565b3360008181526003602052604090205460ff1615611eeb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b3360009081526009602052604090205482611f88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f46696174546f6b656e3a206275726e20616d6f756e74206e6f7420677265617460448201527f6572207468616e203000000000000000000000000000000000000000000000006064820152608401610a2b565b82811015612018576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f46696174546f6b656e3a206275726e20616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610a2b565b600b546120259084613f24565b600b556120328184613f24565b33600081815260096020526040908190209290925590517fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5906120789086815260200190565b60405180910390a260405183815260009033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a3505050565b60015460009074010000000000000000000000000000000000000000900460ff1615612146576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b60085473ffffffffffffffffffffffffffffffffffffffff1633146121ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f46696174546f6b656e3a2063616c6c6572206973206e6f7420746865206d617360448201527f7465724d696e74657200000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff83166000818152600c6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055600d82529182902085905590518481527f46980fca912ef9bcdbd36877427b6b90e860769f604e89c0e67720cece530d20910160405180910390a250600192915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612303576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff81166123a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5061757361626c653a206e65772070617573657220697320746865207a65726f60448201527f20616464726573730000000000000000000000000000000000000000000000006064820152608401610a2b565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517fb80482a293ca2e013eda8683c9bd7fc8347cfdaeea5ede58cba46df502c2a60490600090a250565b60015474010000000000000000000000000000000000000000900460ff161561249a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b6124a785858585856143e5565b5050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314612555576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f5061757361626c653a2063616c6c6572206973206e6f7420746865207061757360448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610a2b565b600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790556040517f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62590600090a1565b6005805461092690615baa565b60015460009074010000000000000000000000000000000000000000900460ff1615612654576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b3360008181526003602052604090205460ff16156126f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260036020526040902054849060ff16156127ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b610b97338686614581565b60015460009074010000000000000000000000000000000000000000900460ff161561283f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b3360008181526003602052604090205460ff16156128df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260036020526040902054849060ff1615612997576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b610b97338686613c5c565b60005473ffffffffffffffffffffffffffffffffffffffff163314612a23576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8116612ac6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f46696174546f6b656e3a206e6577206d61737465724d696e746572206973207460448201527f6865207a65726f206164647265737300000000000000000000000000000000006064820152608401610a2b565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517fdb66dfa9c6b8f5226fe9aac7e51897ae8ee94ac31dc70bb6c9900b2574b707e690600090a250565b60005473ffffffffffffffffffffffffffffffffffffffff163314612bb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8116612c59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f426c61636b6c69737461626c653a206e657720626c61636b6c6973746572206960448201527f7320746865207a65726f206164647265737300000000000000000000000000006064820152608401610a2b565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517fc67398012c111ce95ecb7429b933096c977380ee6c421175a71a4a4c6c88c06e90600090a250565b60015474010000000000000000000000000000000000000000900460ff1615612d4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8916600090815260036020526040902054899060ff1615612e05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8916600090815260036020526040902054899060ff1615612ebd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b612ece8b8b8b8b8b8b8b8b8b6145dd565b5050505050505050505050565b600e5473ffffffffffffffffffffffffffffffffffffffff163314612f81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f526573637561626c653a2063616c6c6572206973206e6f74207468652072657360448201527f63756572000000000000000000000000000000000000000000000000000000006064820152608401610a2b565b612fa273ffffffffffffffffffffffffffffffffffffffff84168383614732565b505050565b60015474010000000000000000000000000000000000000000900460ff161561302c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8916600090815260036020526040902054899060ff16156130e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8916600090815260036020526040902054899060ff161561319c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b612ece8b8b8b8b8b8b8b8b8b6147bf565b60015474010000000000000000000000000000000000000000900460ff1615613232576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260036020526040902054879060ff16156132ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260036020526040902054879060ff16156133a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b6133b189898989898989614908565b505050505050505050565b60015474010000000000000000000000000000000000000000900460ff1615613441576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8916600090815260036020526040902054899060ff16156134f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8916600090815260036020526040902054899060ff16156135b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b612ece8b8b8b8b8b8b8b8b8b614ade565b60015474010000000000000000000000000000000000000000900460ff1615613647576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8916600090815260036020526040902054899060ff16156136ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8916600090815260036020526040902054899060ff16156137b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c60448201527f69737465640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b612ece8b8b8b8b8b8b8b8b8b614c27565b6007805461092690615baa565b60005473ffffffffffffffffffffffffffffffffffffffff163314613856576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff81166138f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610a2b565b6000546040805173ffffffffffffffffffffffffffffffffffffffff928316815291831660208301527f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0910160405180910390a1600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff831617905550565b50565b60025473ffffffffffffffffffffffffffffffffffffffff163314613a3a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f426c61636b6c69737461626c653a2063616c6c6572206973206e6f742074686560448201527f20626c61636b6c697374657200000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517fffa4e6181777692565cf28528fc88fd1516ea86b56da075235fa575af6a4b8559190a250565b73ffffffffffffffffffffffffffffffffffffffff8316613b53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8216613bf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8381166000818152600a602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591016120b1565b73ffffffffffffffffffffffffffffffffffffffff8316613cff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8216613da2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260096020526040902054811115613e57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260096020526040902054613e879082613f24565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600960205260408082209390935590841681522054613ec390826143d9565b73ffffffffffffffffffffffffffffffffffffffff80841660008181526009602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906120b19085815260200190565b6000613f308284615c2d565b9392505050565b60085474010000000000000000000000000000000000000000900460ff1615613fe2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f46696174546f6b656e3a20636f6e747261637420697320616c7265616479206960448201527f6e697469616c697a6564000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8416614085576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f46696174546f6b656e3a206e6577206d61737465724d696e746572206973207460448201527f6865207a65726f206164647265737300000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8316614128576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f46696174546f6b656e3a206e65772070617573657220697320746865207a657260448201527f6f206164647265737300000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff82166141cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f46696174546f6b656e3a206e657720626c61636b6c697374657220697320746860448201527f65207a65726f20616464726573730000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff811661426e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f46696174546f6b656e3a206e6577206f776e657220697320746865207a65726f60448201527f20616464726573730000000000000000000000000000000000000000000000006064820152608401610a2b565b87516142819060049060208b0190615614565b5086516142959060059060208a0190615614565b5085516142a9906007906020890190615614565b50600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff8716179055600880547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff87811691909117909255600180548216868416179055600280548216858416179055600080549091169183169190911790555050600880547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055505050505050565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600a6020908152604080832093861683529290522054612fa290849084906143d490856143d9565b613ab1565b6000613f308284615c44565b6143ef8585614d70565b604080517f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429602082015273ffffffffffffffffffffffffffffffffffffffff8716918101919091526060810185905260009060800160405160208183030381529060405290508573ffffffffffffffffffffffffffffffffffffffff1661447b600f5486868686614e46565b73ffffffffffffffffffffffffffffffffffffffff16146144f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46696174546f6b656e56323a20696e76616c6964207369676e617475726500006044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8616600081815260106020908152604080832089845290915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166002179055518792917f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d8191a3505050505050565b612fa283836143d484604051806060016040528060258152602001615cd46025913973ffffffffffffffffffffffffffffffffffffffff808a166000908152600a60209081526040808320938c16835292905220549190614ec3565b6145e989858888614f09565b604080517fb70559e94cbda91958ebec07f9b65b3b490097c8d25c8dacd71105df1015b6d8602082015273ffffffffffffffffffffffffffffffffffffffff808c169282019290925290891660608201526080810188905260a0810187905260c0810186905260e081018590526000906101000160405160208183030381529060405290508973ffffffffffffffffffffffffffffffffffffffff16614694600f5486868686614e46565b73ffffffffffffffffffffffffffffffffffffffff1614614711576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46696174546f6b656e56323a20696e76616c6964207369676e617475726500006044820152606401610a2b565b61471b8a86615037565b6147268a8a8a614581565b50505050505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052612fa29084906150bc565b6147cb89858888614f09565b604080517f424222bb050a1f7f14017232a5671f2680a2d3420f504bd565cf03035c53198a602082015273ffffffffffffffffffffffffffffffffffffffff808c169282019290925290891660608201526080810188905260a0810187905260c0810186905260e081018590526000906101000160405160208183030381529060405290508973ffffffffffffffffffffffffffffffffffffffff16614876600f5486868686614e46565b73ffffffffffffffffffffffffffffffffffffffff16146148f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46696174546f6b656e56323a20696e76616c6964207369676e617475726500006044820152606401610a2b565b6148fd8a86615037565b6147268a8a8a61438f565b42841015614972576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46696174546f6b656e56323a207065726d6974206973206578706972656400006044820152606401610a2b565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260116020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a9190866149cc83615c5c565b9091555060408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405290508773ffffffffffffffffffffffffffffffffffffffff16614a4c600f5486868686614e46565b73ffffffffffffffffffffffffffffffffffffffff1614614ac9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46696174546f6b656e56323a20696e76616c6964207369676e617475726500006044820152606401610a2b565b614ad4888888613ab1565b5050505050505050565b614aea89858888614f09565b604080517f808c10407a796f3ef2c7ea38c0638ea9d2b8a1c63e3ca9e1f56ce84ae59df73c602082015273ffffffffffffffffffffffffffffffffffffffff808c169282019290925290891660608201526080810188905260a0810187905260c0810186905260e081018590526000906101000160405160208183030381529060405290508973ffffffffffffffffffffffffffffffffffffffff16614b95600f5486868686614e46565b73ffffffffffffffffffffffffffffffffffffffff1614614c12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46696174546f6b656e56323a20696e76616c6964207369676e617475726500006044820152606401610a2b565b614c1c8a86615037565b6147268a8a8a613ab1565b614c3389858888614f09565b604080517f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267602082015273ffffffffffffffffffffffffffffffffffffffff808c169282019290925290891660608201526080810188905260a0810187905260c0810186905260e081018590526000906101000160405160208183030381529060405290508973ffffffffffffffffffffffffffffffffffffffff16614cde600f5486868686614e46565b73ffffffffffffffffffffffffffffffffffffffff1614614d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46696174546f6b656e56323a20696e76616c6964207369676e617475726500006044820152606401610a2b565b614d658a86615037565b6147268a8a8a613c5c565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260106020908152604080832084845290915281205460ff166002811115614db557614db5615b3a565b14614e42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f46696174546f6b656e56323a20617574686f72697a6174696f6e20697320757360448201527f6564206f722063616e63656c65640000000000000000000000000000000000006064820152608401610a2b565b5050565b600080868380519060200120604051602001614e949291907f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050614eb8818787876151c8565b979650505050505050565b60008184841115614f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2b91906156d9565b505050900390565b814211614f98576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f46696174546f6b656e56323a20617574686f72697a6174696f6e206973206e6f60448201527f74207965742076616c69640000000000000000000000000000000000000000006064820152608401610a2b565b804210615027576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f46696174546f6b656e56323a20617574686f72697a6174696f6e20697320657860448201527f70697265640000000000000000000000000000000000000000000000000000006064820152608401610a2b565b6150318484614d70565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260106020908152604080832085845290915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055518392917f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a591a35050565b600061511e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166154249092919063ffffffff16565b805190915015612fa2578080602001905181019061513c9190615c95565b612fa2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610a2b565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a082111561527a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45435265636f7665723a20696e76616c6964207369676e61747572652027732760448201527f2076616c756500000000000000000000000000000000000000000000000000006064820152608401610a2b565b8360ff16601b1415801561529257508360ff16601c14155b1561531f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45435265636f7665723a20696e76616c6964207369676e61747572652027762760448201527f2076616c756500000000000000000000000000000000000000000000000000006064820152608401610a2b565b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa158015615373573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661541b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45435265636f7665723a20696e76616c6964207369676e6174757265000000006044820152606401610a2b565b95945050505050565b6060615433848460008561543b565b949350505050565b6060824710156154cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610a2b565b73ffffffffffffffffffffffffffffffffffffffff85163b61554b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a2b565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516155749190615cb7565b60006040518083038185875af1925050503d80600081146155b1576040519150601f19603f3d011682016040523d82523d6000602084013e6155b6565b606091505b5091509150614eb8828286606083156155d0575081613f30565b8251156155e05782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2b91906156d9565b82805461562090615baa565b90600052602060002090601f0160209004810192826156425760008555615688565b82601f1061565b57805160ff1916838001178555615688565b82800160010185558215615688579182015b8281111561568857825182559160200191906001019061566d565b50615694929150615698565b5090565b5b808211156156945760008155600101615699565b60005b838110156156c85781810151838201526020016156b0565b838111156150315750506000910152565b60208152600082518060208401526156f88160408501602087016156ad565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461399057600080fd5b80356113598161572a565b6000806040838503121561576a57600080fd5b82356157758161572a565b946020939093013593505050565b60006020828403121561579557600080fd5b8135613f308161572a565b6000806000606084860312156157b557600080fd5b83356157c08161572a565b925060208401356157d08161572a565b929592945050506040919091013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261582157600080fd5b813567ffffffffffffffff8082111561583c5761583c6157e1565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715615882576158826157e1565b8160405283815286602085880101111561589b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b803560ff8116811461135957600080fd5b600080600080600080600080610100898b0312156158e957600080fd5b883567ffffffffffffffff8082111561590157600080fd5b61590d8c838d01615810565b995060208b013591508082111561592357600080fd5b61592f8c838d01615810565b985060408b013591508082111561594557600080fd5b506159528b828c01615810565b96505061596160608a016158bb565b945061596f60808a0161574c565b935061597d60a08a0161574c565b925061598b60c08a0161574c565b915061599960e08a0161574c565b90509295985092959890939650565b6000602082840312156159ba57600080fd5b5035919050565b600080600080600060a086880312156159d957600080fd5b85356159e48161572a565b9450602086013593506159f9604087016158bb565b94979396509394606081013594506080013592915050565b60008060008060008060008060006101208a8c031215615a3057600080fd5b8935615a3b8161572a565b985060208a0135615a4b8161572a565b975060408a0135965060608a0135955060808a0135945060a08a01359350615a7560c08b016158bb565b925060e08a013591506101008a013590509295985092959850929598565b600080600080600080600060e0888a031215615aae57600080fd5b8735615ab98161572a565b96506020880135615ac98161572a565b95506040880135945060608801359350615ae5608089016158bb565b925060a0880135915060c0880135905092959891949750929550565b60008060408385031215615b1457600080fd5b8235615b1f8161572a565b91506020830135615b2f8161572a565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310615ba4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b600181811c90821680615bbe57607f821691505b60208210811415615bf8577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015615c3f57615c3f615bfe565b500390565b60008219821115615c5757615c57615bfe565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415615c8e57615c8e615bfe565b5060010190565b600060208284031215615ca757600080fd5b81518015158114613f3057600080fd5b60008251615cc98184602087016156ad565b919091019291505056fe45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa26469706673582212204b40c0f4417904396b412d974db9c421cec7c6e2c62ce9725d7590726224a1c864736f6c634300080a0033
Net Worth in USD
Net Worth in ETH
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.