Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
DTX
Compiler Version
v0.8.30+commit.73712a01
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
contract DTX is ERC20, Ownable, ReentrancyGuard {
using SafeERC20 for IERC20;
struct TransferRequest {
address to;
uint amount;
bool executed;
uint signs;
mapping(address => bool) isSigned;
}
mapping(address => bool) public signers;
uint public signerCount;
uint requiredSigns = 2;
TransferRequest[] public transferRequests;
event TransferRequestCreated(
uint indexed requestId,
address indexed to,
uint amount
);
event TransferRequestSigned(
uint indexed requestId,
address indexed signer,
uint totalSigns
);
event TransferRequestExecuted(
uint indexed requestId,
address indexed to,
uint amount
);
modifier onlySigner() {
require(signers[msg.sender], "Not an authorized signer");
_;
}
constructor() ERC20("DTX", "DTX") Ownable(msg.sender) {
_mint(address(this), 475_000_000 * 10 ** decimals());
}
function createTransferRequest(
address to,
uint256 amount
) external onlySigner nonReentrant returns (uint256) {
require(to != address(0), "Invalid recipient address");
require(
amount <= balanceOf(address(this)),
"Insufficient contract balance"
);
transferRequests.push();
uint256 index = transferRequests.length - 1;
transferRequests[index].to = to;
transferRequests[index].amount = amount;
transferRequests[index].executed = false;
transferRequests[index].isSigned[msg.sender] = true;
transferRequests[index].signs = 1;
emit TransferRequestCreated(index, to, amount);
return index;
}
function signTransferRequest(
uint256 requestId
) external onlySigner nonReentrant {
require(requestId < transferRequests.length, "Invalid request ID");
TransferRequest storage request = transferRequests[requestId];
require(!request.executed, "Request already executed");
require(
!request.isSigned[msg.sender],
"Signer has already signed this request"
);
request.isSigned[msg.sender] = true;
request.signs += 1;
emit TransferRequestSigned(requestId, msg.sender, request.signs);
if (request.signs >= requiredSigns) {
request.executed = true;
IERC20(address(this)).safeTransfer(request.to, request.amount);
emit TransferRequestExecuted(requestId, request.to, request.amount);
}
}
function setRequiredSigns(uint _requiredSigns) external onlyOwner {
require(signerCount >= _requiredSigns, "Cannot be more than signers");
requiredSigns = _requiredSigns;
}
function addSigner(address signer) external onlyOwner {
require(signer != address(0), "Invalid signer address");
require(!signers[signer], "Signer already exists");
signers[signer] = true;
signerCount++;
}
function removeSigner(address signer) external onlyOwner {
require(signers[signer], "Signer does not exist");
signers[signer] = false;
signerCount--;
require(
signerCount >= requiredSigns,
"Cannot remove signer: would make required signatures impossible"
);
}
function emergencyWithdraw(
address to,
uint256 amount
) external onlyOwner nonReentrant {
require(to != address(0), "Invalid recipient address");
require(amount <= balanceOf(address(this)), "Insufficient balance");
IERC20(address(this)).safeTransfer(to, amount);
}
function emergencyWithdrawToken(
address token,
address to,
uint256 amount
) external onlyOwner nonReentrant {
require(to != address(0), "Invalid recipient address");
require(token != address(0), "Invalid token address");
require(token != address(this), "Cannot withdraw DTX Token");
IERC20(token).safeTransfer(to, amount);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
* consider using {ReentrancyGuardTransient} instead.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
_status = ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC-20 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 {
/**
* @dev An operation with an ERC-20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*
* NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
* only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
* set here.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
safeTransfer(token, to, value);
} else if (!token.transferAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
* has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferFromAndCallRelaxed(
IERC1363 token,
address from,
address to,
uint256 value,
bytes memory data
) internal {
if (to.code.length == 0) {
safeTransferFrom(token, from, to, value);
} else if (!token.transferFromAndCall(from, to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
* Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
* once without retrying, and relies on the returned value to be true.
*
* Reverts if the returned value is other than `true`.
*/
function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
forceApprove(token, to, value);
} else if (!token.approveAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @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).
*
* This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
// bubble errors
if iszero(success) {
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
returnSize := returndatasize()
returnValue := mload(0)
}
if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @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).
*
* This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
bool success;
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
returnSize := returndatasize()
returnValue := mload(0)
}
return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "./IERC20.sol";
import {IERC20Metadata} from "./extensions/IERC20Metadata.sol";
import {Context} from "../../utils/Context.sol";
import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC-20
* applications.
*/
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
mapping(address account => uint256) private _balances;
mapping(address account => mapping(address spender => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* Both values are immutable: they can only be set once during construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual returns (uint8) {
return 18;
}
/// @inheritdoc IERC20
function totalSupply() public view virtual returns (uint256) {
return _totalSupply;
}
/// @inheritdoc IERC20
function balanceOf(address account) public view virtual returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `value`.
*/
function transfer(address to, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_transfer(owner, to, value);
return true;
}
/// @inheritdoc IERC20
function allowance(address owner, address spender) public view virtual returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, value);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Skips emitting an {Approval} event indicating an allowance update. This is not
* required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `value`.
* - the caller must have allowance for ``from``'s tokens of at least
* `value`.
*/
function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, value);
_transfer(from, to, value);
return true;
}
/**
* @dev Moves a `value` amount of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _transfer(address from, address to, uint256 value) internal {
if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}
if (to == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(from, to, value);
}
/**
* @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
* (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
* this function.
*
* Emits a {Transfer} event.
*/
function _update(address from, address to, uint256 value) internal virtual {
if (from == address(0)) {
// Overflow check required: The rest of the code assumes that totalSupply never overflows
_totalSupply += value;
} else {
uint256 fromBalance = _balances[from];
if (fromBalance < value) {
revert ERC20InsufficientBalance(from, fromBalance, value);
}
unchecked {
// Overflow not possible: value <= fromBalance <= totalSupply.
_balances[from] = fromBalance - value;
}
}
if (to == address(0)) {
unchecked {
// Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
_totalSupply -= value;
}
} else {
unchecked {
// Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
_balances[to] += value;
}
}
emit Transfer(from, to, value);
}
/**
* @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
* Relies on the `_update` mechanism
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _mint(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(address(0), account, value);
}
/**
* @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
* Relies on the `_update` mechanism.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead
*/
function _burn(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidSender(address(0));
}
_update(account, address(0), value);
}
/**
* @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*
* Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
*/
function _approve(address owner, address spender, uint256 value) internal {
_approve(owner, spender, value, true);
}
/**
* @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
*
* By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
* `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
* `Approval` event during `transferFrom` operations.
*
* Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
* true using the following override:
*
* ```solidity
* function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
* super._approve(owner, spender, value, true);
* }
* ```
*
* Requirements are the same as {_approve}.
*/
function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
if (owner == address(0)) {
revert ERC20InvalidApprover(address(0));
}
if (spender == address(0)) {
revert ERC20InvalidSpender(address(0));
}
_allowances[owner][spender] = value;
if (emitEvent) {
emit Approval(owner, spender, value);
}
}
/**
* @dev Updates `owner`'s allowance for `spender` based on spent `value`.
*
* Does not update the allowance value in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Does not emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance < type(uint256).max) {
if (currentAllowance < value) {
revert ERC20InsufficientAllowance(spender, currentAllowance, value);
}
unchecked {
_approve(owner, spender, currentAllowance - value, false);
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)
pragma solidity >=0.6.2;
import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";
/**
* @title IERC1363
* @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
*
* Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
* after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
*/
interface IERC1363 is IERC20, IERC165 {
/*
* Note: the ERC-165 identifier for this interface is 0xb0202a11.
* 0xb0202a11 ===
* bytes4(keccak256('transferAndCall(address,uint256)')) ^
* bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
* bytes4(keccak256('approveAndCall(address,uint256)')) ^
* bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
*/
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @param data Additional data with no specified format, sent in call to `spender`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/draft-IERC6093.sol)
pragma solidity >=0.8.4;
/**
* @dev Standard ERC-20 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
*/
interface IERC20Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC20InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC20InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC20InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/
error ERC20InvalidSpender(address spender);
}
/**
* @dev Standard ERC-721 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.
*/
interface IERC721Errors {
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/
error ERC721InvalidOwner(address owner);
/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/
error ERC721NonexistentToken(uint256 tokenId);
/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC721InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC721InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC721InsufficientApproval(address operator, uint256 tokenId);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC721InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC721InvalidOperator(address operator);
}
/**
* @dev Standard ERC-1155 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.
*/
interface IERC1155Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC1155InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC1155InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param owner Address of the current owner of a token.
*/
error ERC1155MissingApprovalForAll(address operator, address owner);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC1155InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC1155InvalidOperator(address operator);
/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity >=0.6.2;
import {IERC20} from "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC-20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)
pragma solidity >=0.4.16;
import {IERC165} from "../utils/introspection/IERC165.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)
pragma solidity >=0.4.16;
import {IERC20} from "../token/ERC20/IERC20.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": []
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"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":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferRequestCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferRequestExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"address","name":"signer","type":"address"},{"indexed":false,"internalType":"uint256","name":"totalSigns","type":"uint256"}],"name":"TransferRequestSigned","type":"event"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"addSigner","outputs":[],"stateMutability":"nonpayable","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":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"createTransferRequest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emergencyWithdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"removeSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requiredSigns","type":"uint256"}],"name":"setRequiredSigns","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"signTransferRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signerCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"signers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"uint256","name":"","type":"uint256"}],"name":"transferRequests","outputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"executed","type":"bool"},{"internalType":"uint256","name":"signs","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60806040526002600955348015610014575f5ffd5b50336040518060400160405280600381526020017f44545800000000000000000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f44545800000000000000000000000000000000000000000000000000000000008152508160039081610091919061070f565b5080600490816100a1919061070f565b5050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610114575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161010b919061081d565b60405180910390fd5b6101238161016960201b60201c565b5060016006819055506101643061013e61022c60201b60201c565b600a61014a919061099e565b631c4fecc061015991906109e8565b61023460201b60201c565b610ab9565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f6012905090565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036102a4575f6040517fec442f0500000000000000000000000000000000000000000000000000000000815260040161029b919061081d565b60405180910390fd5b6102b55f83836102b960201b60201c565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610309578060025f8282546102fd9190610a29565b925050819055506103d7565b5f5f5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015610392578381836040517fe450d38c00000000000000000000000000000000000000000000000000000000815260040161038993929190610a6b565b60405180910390fd5b8181035f5f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361041e578060025f8282540392505081905550610468565b805f5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516104c59190610aa0565b60405180910390a3505050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061054d57607f821691505b6020821081036105605761055f610509565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026105c27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610587565b6105cc8683610587565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61061061060b610606846105e4565b6105ed565b6105e4565b9050919050565b5f819050919050565b610629836105f6565b61063d61063582610617565b848454610593565b825550505050565b5f5f905090565b610654610645565b61065f818484610620565b505050565b5b81811015610682576106775f8261064c565b600181019050610665565b5050565b601f8211156106c75761069881610566565b6106a184610578565b810160208510156106b0578190505b6106c46106bc85610578565b830182610664565b50505b505050565b5f82821c905092915050565b5f6106e75f19846008026106cc565b1980831691505092915050565b5f6106ff83836106d8565b9150826002028217905092915050565b610718826104d2565b67ffffffffffffffff811115610731576107306104dc565b5b61073b8254610536565b610746828285610686565b5f60209050601f831160018114610777575f8415610765578287015190505b61076f85826106f4565b8655506107d6565b601f19841661078586610566565b5f5b828110156107ac57848901518255600182019150602085019450602081019050610787565b868310156107c957848901516107c5601f8916826106d8565b8355505b6001600288020188555050505b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610807826107de565b9050919050565b610817816107fd565b82525050565b5f6020820190506108305f83018461080e565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f5f8291508390505b60018511156108b85780860481111561089457610893610836565b5b60018516156108a35780820291505b80810290506108b185610863565b9450610878565b94509492505050565b5f826108d0576001905061098b565b816108dd575f905061098b565b81600181146108f357600281146108fd5761092c565b600191505061098b565b60ff84111561090f5761090e610836565b5b8360020a91508482111561092657610925610836565b5b5061098b565b5060208310610133831016604e8410600b84101617156109615782820a90508381111561095c5761095b610836565b5b61098b565b61096e848484600161086f565b9250905081840481111561098557610984610836565b5b81810290505b9392505050565b5f60ff82169050919050565b5f6109a8826105e4565b91506109b383610992565b92506109e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846108c1565b905092915050565b5f6109f2826105e4565b91506109fd836105e4565b9250828202610a0b816105e4565b91508282048414831517610a2257610a21610836565b5b5092915050565b5f610a33826105e4565b9150610a3e836105e4565b9250828201905080821115610a5657610a55610836565b5b92915050565b610a65816105e4565b82525050565b5f606082019050610a7e5f83018661080e565b610a8b6020830185610a5c565b610a986040830184610a5c565b949350505050565b5f602082019050610ab35f830184610a5c565b92915050565b6127fe80610ac65f395ff3fe608060405234801561000f575f5ffd5b5060043610610140575f3560e01c8063736c0d5b116100b6578063a9059cbb1161007a578063a9059cbb14610365578063bc7b69cc14610395578063dd21b1c0146103b1578063dd62ed3e146103e1578063eb12d61e14610411578063f2fde38b1461042d57610140565b8063736c0d5b146102bf5780637ca548c6146102ef5780638da5cb5b1461030d57806395ccea671461032b57806395d89b411461034757610140565b806318b3ec301161010857806318b3ec30146101ff57806323b872dd1461021b578063277327a51461024b578063313ce5671461026757806370a0823114610285578063715018a6146102b557610140565b806303486c401461014457806306fdde0314610177578063095ea7b3146101955780630e316ab7146101c557806318160ddd146101e1575b5f5ffd5b61015e60048036038101906101599190611cdf565b610449565b60405161016e9493929190611d72565b60405180910390f35b61017f6104af565b60405161018c9190611e25565b60405180910390f35b6101af60048036038101906101aa9190611e6f565b61053f565b6040516101bc9190611ead565b60405180910390f35b6101df60048036038101906101da9190611ec6565b610561565b005b6101e96106a7565b6040516101f69190611ef1565b60405180910390f35b61021960048036038101906102149190611cdf565b6106b0565b005b61023560048036038101906102309190611f0a565b610a49565b6040516102429190611ead565b60405180910390f35b61026560048036038101906102609190611f0a565b610a77565b005b61026f610c09565b60405161027c9190611f75565b60405180910390f35b61029f600480360381019061029a9190611ec6565b610c11565b6040516102ac9190611ef1565b60405180910390f35b6102bd610c56565b005b6102d960048036038101906102d49190611ec6565b610c69565b6040516102e69190611ead565b60405180910390f35b6102f7610c86565b6040516103049190611ef1565b60405180910390f35b610315610c8c565b6040516103229190611f8e565b60405180910390f35b61034560048036038101906103409190611e6f565b610cb4565b005b61034f610db4565b60405161035c9190611e25565b60405180910390f35b61037f600480360381019061037a9190611e6f565b610e44565b60405161038c9190611ead565b60405180910390f35b6103af60048036038101906103aa9190611cdf565b610e66565b005b6103cb60048036038101906103c69190611e6f565b610ebd565b6040516103d89190611ef1565b60405180910390f35b6103fb60048036038101906103f69190611fa7565b6111fb565b6040516104089190611ef1565b60405180910390f35b61042b60048036038101906104269190611ec6565b61127d565b005b61044760048036038101906104429190611ec6565b6113ec565b005b600a8181548110610458575f80fd5b905f5260205f2090600502015f91509050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001015490806002015f9054906101000a900460ff16908060030154905084565b6060600380546104be90612012565b80601f01602080910402602001604051908101604052809291908181526020018280546104ea90612012565b80156105355780601f1061050c57610100808354040283529160200191610535565b820191905f5260205f20905b81548152906001019060200180831161051857829003601f168201915b5050505050905090565b5f5f610549611470565b9050610556818585611477565b600191505092915050565b610569611489565b60075f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff166105f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e99061208c565b60405180910390fd5b5f60075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555060085f815480929190610658906120d7565b919050555060095460085410156106a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161069b9061216e565b60405180910390fd5b50565b5f600254905090565b60075f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16610739576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610730906121d6565b60405180910390fd5b610741611510565b600a805490508110610788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161077f9061223e565b60405180910390fd5b5f600a828154811061079d5761079c61225c565b5b905f5260205f2090600502019050806002015f9054906101000a900460ff16156107fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f3906122d3565b60405180910390fd5b806004015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1615610888576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087f90612361565b60405180910390fd5b6001816004015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506001816003015f8282546108f3919061237f565b925050819055503373ffffffffffffffffffffffffffffffffffffffff16827f671249e6a8fc7432cd8da2deeb8a880c16335469b23496a6685936e8173410ce83600301546040516109459190611ef1565b60405180910390a3600954816003015410610a3d576001816002015f6101000a81548160ff0219169083151502179055506109c7815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682600101543073ffffffffffffffffffffffffffffffffffffffff166115569092919063ffffffff16565b805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16827f2ad21fc4d7e310cb1fcea49f0ea18f08b505cb2182882536e3825bdbeb9024e78360010154604051610a349190611ef1565b60405180910390a35b50610a466115d5565b50565b5f5f610a53611470565b9050610a608582856115df565b610a6b858585611672565b60019150509392505050565b610a7f611489565b610a87611510565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610af5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aec906123fc565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b63576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5a90612464565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610bd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc8906124cc565b60405180910390fd5b610bfc82828573ffffffffffffffffffffffffffffffffffffffff166115569092919063ffffffff16565b610c046115d5565b505050565b5f6012905090565b5f5f5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610c5e611489565b610c675f611762565b565b6007602052805f5260405f205f915054906101000a900460ff1681565b60085481565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610cbc611489565b610cc4611510565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610d32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d29906123fc565b60405180910390fd5b610d3b30610c11565b811115610d7d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7490612534565b60405180910390fd5b610da882823073ffffffffffffffffffffffffffffffffffffffff166115569092919063ffffffff16565b610db06115d5565b5050565b606060048054610dc390612012565b80601f0160208091040260200160405190810160405280929190818152602001828054610def90612012565b8015610e3a5780601f10610e1157610100808354040283529160200191610e3a565b820191905f5260205f20905b815481529060010190602001808311610e1d57829003601f168201915b5050505050905090565b5f5f610e4e611470565b9050610e5b818585611672565b600191505092915050565b610e6e611489565b806008541015610eb3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eaa9061259c565b60405180910390fd5b8060098190555050565b5f60075f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16610f47576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3e906121d6565b60405180910390fd5b610f4f611510565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610fbd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb4906123fc565b60405180910390fd5b610fc630610c11565b821115611008576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fff90612604565b60405180910390fd5b600a60018160018154018082558091505003905f5260205f209050505f6001600a805490506110379190612622565b905083600a828154811061104e5761104d61225c565b5b905f5260205f2090600502015f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600a82815481106110ae576110ad61225c565b5b905f5260205f209060050201600101819055505f600a82815481106110d6576110d561225c565b5b905f5260205f2090600502016002015f6101000a81548160ff0219169083151502179055506001600a82815481106111115761111061225c565b5b905f5260205f2090600502016004015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506001600a82815481106111875761118661225c565b5b905f5260205f209060050201600301819055508373ffffffffffffffffffffffffffffffffffffffff16817f4226d8f5d7de2711c5d9793318d37c1b305ed7d8c22331bcac883c1c3de6123e856040516111e19190611ef1565b60405180910390a3809150506111f56115d5565b92915050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b611285611489565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036112f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ea9061269f565b60405180910390fd5b60075f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff161561137d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137490612707565b60405180910390fd5b600160075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555060085f8154809291906113e490612725565b919050555050565b6113f4611489565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611464575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161145b9190611f8e565b60405180910390fd5b61146d81611762565b50565b5f33905090565b6114848383836001611825565b505050565b611491611470565b73ffffffffffffffffffffffffffffffffffffffff166114af610c8c565b73ffffffffffffffffffffffffffffffffffffffff161461150e576114d2611470565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016115059190611f8e565b60405180910390fd5b565b60026006540361154c576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600681905550565b6115d0838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb858560405160240161158992919061276c565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506119f4565b505050565b6001600681905550565b5f6115ea84846111fb565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81101561166c578181101561165d578281836040517ffb8f41b200000000000000000000000000000000000000000000000000000000815260040161165493929190612793565b60405180910390fd5b61166b84848484035f611825565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036116e2575f6040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081526004016116d99190611f8e565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611752575f6040517fec442f050000000000000000000000000000000000000000000000000000000081526004016117499190611f8e565b60405180910390fd5b61175d838383611a8f565b505050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611895575f6040517fe602df0500000000000000000000000000000000000000000000000000000000815260040161188c9190611f8e565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611905575f6040517f94280d620000000000000000000000000000000000000000000000000000000081526004016118fc9190611f8e565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208190555080156119ee578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516119e59190611ef1565b60405180910390a35b50505050565b5f5f60205f8451602086015f885af180611a13576040513d5f823e3d81fd5b3d92505f519150505f8214611a2c576001811415611a47565b5f8473ffffffffffffffffffffffffffffffffffffffff163b145b15611a8957836040517f5274afe7000000000000000000000000000000000000000000000000000000008152600401611a809190611f8e565b60405180910390fd5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611adf578060025f828254611ad3919061237f565b92505081905550611bad565b5f5f5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015611b68578381836040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401611b5f93929190612793565b60405180910390fd5b8181035f5f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611bf4578060025f8282540392505081905550611c3e565b805f5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611c9b9190611ef1565b60405180910390a3505050565b5f5ffd5b5f819050919050565b611cbe81611cac565b8114611cc8575f5ffd5b50565b5f81359050611cd981611cb5565b92915050565b5f60208284031215611cf457611cf3611ca8565b5b5f611d0184828501611ccb565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611d3382611d0a565b9050919050565b611d4381611d29565b82525050565b611d5281611cac565b82525050565b5f8115159050919050565b611d6c81611d58565b82525050565b5f608082019050611d855f830187611d3a565b611d926020830186611d49565b611d9f6040830185611d63565b611dac6060830184611d49565b95945050505050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f611df782611db5565b611e018185611dbf565b9350611e11818560208601611dcf565b611e1a81611ddd565b840191505092915050565b5f6020820190508181035f830152611e3d8184611ded565b905092915050565b611e4e81611d29565b8114611e58575f5ffd5b50565b5f81359050611e6981611e45565b92915050565b5f5f60408385031215611e8557611e84611ca8565b5b5f611e9285828601611e5b565b9250506020611ea385828601611ccb565b9150509250929050565b5f602082019050611ec05f830184611d63565b92915050565b5f60208284031215611edb57611eda611ca8565b5b5f611ee884828501611e5b565b91505092915050565b5f602082019050611f045f830184611d49565b92915050565b5f5f5f60608486031215611f2157611f20611ca8565b5b5f611f2e86828701611e5b565b9350506020611f3f86828701611e5b565b9250506040611f5086828701611ccb565b9150509250925092565b5f60ff82169050919050565b611f6f81611f5a565b82525050565b5f602082019050611f885f830184611f66565b92915050565b5f602082019050611fa15f830184611d3a565b92915050565b5f5f60408385031215611fbd57611fbc611ca8565b5b5f611fca85828601611e5b565b9250506020611fdb85828601611e5b565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061202957607f821691505b60208210810361203c5761203b611fe5565b5b50919050565b7f5369676e657220646f6573206e6f7420657869737400000000000000000000005f82015250565b5f612076601583611dbf565b915061208182612042565b602082019050919050565b5f6020820190508181035f8301526120a38161206a565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6120e182611cac565b91505f82036120f3576120f26120aa565b5b600182039050919050565b7f43616e6e6f742072656d6f7665207369676e65723a20776f756c64206d616b655f8201527f207265717569726564207369676e61747572657320696d706f737369626c6500602082015250565b5f612158603f83611dbf565b9150612163826120fe565b604082019050919050565b5f6020820190508181035f8301526121858161214c565b9050919050565b7f4e6f7420616e20617574686f72697a6564207369676e657200000000000000005f82015250565b5f6121c0601883611dbf565b91506121cb8261218c565b602082019050919050565b5f6020820190508181035f8301526121ed816121b4565b9050919050565b7f496e76616c6964207265717565737420494400000000000000000000000000005f82015250565b5f612228601283611dbf565b9150612233826121f4565b602082019050919050565b5f6020820190508181035f8301526122558161221c565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f5265717565737420616c726561647920657865637574656400000000000000005f82015250565b5f6122bd601883611dbf565b91506122c882612289565b602082019050919050565b5f6020820190508181035f8301526122ea816122b1565b9050919050565b7f5369676e65722068617320616c7265616479207369676e6564207468697320725f8201527f6571756573740000000000000000000000000000000000000000000000000000602082015250565b5f61234b602683611dbf565b9150612356826122f1565b604082019050919050565b5f6020820190508181035f8301526123788161233f565b9050919050565b5f61238982611cac565b915061239483611cac565b92508282019050808211156123ac576123ab6120aa565b5b92915050565b7f496e76616c696420726563697069656e742061646472657373000000000000005f82015250565b5f6123e6601983611dbf565b91506123f1826123b2565b602082019050919050565b5f6020820190508181035f830152612413816123da565b9050919050565b7f496e76616c696420746f6b656e206164647265737300000000000000000000005f82015250565b5f61244e601583611dbf565b91506124598261241a565b602082019050919050565b5f6020820190508181035f83015261247b81612442565b9050919050565b7f43616e6e6f742077697468647261772044545820546f6b656e000000000000005f82015250565b5f6124b6601983611dbf565b91506124c182612482565b602082019050919050565b5f6020820190508181035f8301526124e3816124aa565b9050919050565b7f496e73756666696369656e742062616c616e63650000000000000000000000005f82015250565b5f61251e601483611dbf565b9150612529826124ea565b602082019050919050565b5f6020820190508181035f83015261254b81612512565b9050919050565b7f43616e6e6f74206265206d6f7265207468616e207369676e65727300000000005f82015250565b5f612586601b83611dbf565b915061259182612552565b602082019050919050565b5f6020820190508181035f8301526125b38161257a565b9050919050565b7f496e73756666696369656e7420636f6e74726163742062616c616e63650000005f82015250565b5f6125ee601d83611dbf565b91506125f9826125ba565b602082019050919050565b5f6020820190508181035f83015261261b816125e2565b9050919050565b5f61262c82611cac565b915061263783611cac565b925082820390508181111561264f5761264e6120aa565b5b92915050565b7f496e76616c6964207369676e65722061646472657373000000000000000000005f82015250565b5f612689601683611dbf565b915061269482612655565b602082019050919050565b5f6020820190508181035f8301526126b68161267d565b9050919050565b7f5369676e657220616c72656164792065786973747300000000000000000000005f82015250565b5f6126f1601583611dbf565b91506126fc826126bd565b602082019050919050565b5f6020820190508181035f83015261271e816126e5565b9050919050565b5f61272f82611cac565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612761576127606120aa565b5b600182019050919050565b5f60408201905061277f5f830185611d3a565b61278c6020830184611d49565b9392505050565b5f6060820190506127a65f830186611d3a565b6127b36020830185611d49565b6127c06040830184611d49565b94935050505056fea26469706673582212206af99a3c95a657c7f0398d68e4074bfb14b11750b15d7cdaf20e0b72c1adbfc464736f6c634300081e0033
Deployed Bytecode
0x608060405234801561000f575f5ffd5b5060043610610140575f3560e01c8063736c0d5b116100b6578063a9059cbb1161007a578063a9059cbb14610365578063bc7b69cc14610395578063dd21b1c0146103b1578063dd62ed3e146103e1578063eb12d61e14610411578063f2fde38b1461042d57610140565b8063736c0d5b146102bf5780637ca548c6146102ef5780638da5cb5b1461030d57806395ccea671461032b57806395d89b411461034757610140565b806318b3ec301161010857806318b3ec30146101ff57806323b872dd1461021b578063277327a51461024b578063313ce5671461026757806370a0823114610285578063715018a6146102b557610140565b806303486c401461014457806306fdde0314610177578063095ea7b3146101955780630e316ab7146101c557806318160ddd146101e1575b5f5ffd5b61015e60048036038101906101599190611cdf565b610449565b60405161016e9493929190611d72565b60405180910390f35b61017f6104af565b60405161018c9190611e25565b60405180910390f35b6101af60048036038101906101aa9190611e6f565b61053f565b6040516101bc9190611ead565b60405180910390f35b6101df60048036038101906101da9190611ec6565b610561565b005b6101e96106a7565b6040516101f69190611ef1565b60405180910390f35b61021960048036038101906102149190611cdf565b6106b0565b005b61023560048036038101906102309190611f0a565b610a49565b6040516102429190611ead565b60405180910390f35b61026560048036038101906102609190611f0a565b610a77565b005b61026f610c09565b60405161027c9190611f75565b60405180910390f35b61029f600480360381019061029a9190611ec6565b610c11565b6040516102ac9190611ef1565b60405180910390f35b6102bd610c56565b005b6102d960048036038101906102d49190611ec6565b610c69565b6040516102e69190611ead565b60405180910390f35b6102f7610c86565b6040516103049190611ef1565b60405180910390f35b610315610c8c565b6040516103229190611f8e565b60405180910390f35b61034560048036038101906103409190611e6f565b610cb4565b005b61034f610db4565b60405161035c9190611e25565b60405180910390f35b61037f600480360381019061037a9190611e6f565b610e44565b60405161038c9190611ead565b60405180910390f35b6103af60048036038101906103aa9190611cdf565b610e66565b005b6103cb60048036038101906103c69190611e6f565b610ebd565b6040516103d89190611ef1565b60405180910390f35b6103fb60048036038101906103f69190611fa7565b6111fb565b6040516104089190611ef1565b60405180910390f35b61042b60048036038101906104269190611ec6565b61127d565b005b61044760048036038101906104429190611ec6565b6113ec565b005b600a8181548110610458575f80fd5b905f5260205f2090600502015f91509050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001015490806002015f9054906101000a900460ff16908060030154905084565b6060600380546104be90612012565b80601f01602080910402602001604051908101604052809291908181526020018280546104ea90612012565b80156105355780601f1061050c57610100808354040283529160200191610535565b820191905f5260205f20905b81548152906001019060200180831161051857829003601f168201915b5050505050905090565b5f5f610549611470565b9050610556818585611477565b600191505092915050565b610569611489565b60075f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff166105f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e99061208c565b60405180910390fd5b5f60075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555060085f815480929190610658906120d7565b919050555060095460085410156106a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161069b9061216e565b60405180910390fd5b50565b5f600254905090565b60075f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16610739576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610730906121d6565b60405180910390fd5b610741611510565b600a805490508110610788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161077f9061223e565b60405180910390fd5b5f600a828154811061079d5761079c61225c565b5b905f5260205f2090600502019050806002015f9054906101000a900460ff16156107fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f3906122d3565b60405180910390fd5b806004015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1615610888576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087f90612361565b60405180910390fd5b6001816004015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506001816003015f8282546108f3919061237f565b925050819055503373ffffffffffffffffffffffffffffffffffffffff16827f671249e6a8fc7432cd8da2deeb8a880c16335469b23496a6685936e8173410ce83600301546040516109459190611ef1565b60405180910390a3600954816003015410610a3d576001816002015f6101000a81548160ff0219169083151502179055506109c7815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682600101543073ffffffffffffffffffffffffffffffffffffffff166115569092919063ffffffff16565b805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16827f2ad21fc4d7e310cb1fcea49f0ea18f08b505cb2182882536e3825bdbeb9024e78360010154604051610a349190611ef1565b60405180910390a35b50610a466115d5565b50565b5f5f610a53611470565b9050610a608582856115df565b610a6b858585611672565b60019150509392505050565b610a7f611489565b610a87611510565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610af5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aec906123fc565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b63576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5a90612464565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610bd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc8906124cc565b60405180910390fd5b610bfc82828573ffffffffffffffffffffffffffffffffffffffff166115569092919063ffffffff16565b610c046115d5565b505050565b5f6012905090565b5f5f5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610c5e611489565b610c675f611762565b565b6007602052805f5260405f205f915054906101000a900460ff1681565b60085481565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610cbc611489565b610cc4611510565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610d32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d29906123fc565b60405180910390fd5b610d3b30610c11565b811115610d7d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7490612534565b60405180910390fd5b610da882823073ffffffffffffffffffffffffffffffffffffffff166115569092919063ffffffff16565b610db06115d5565b5050565b606060048054610dc390612012565b80601f0160208091040260200160405190810160405280929190818152602001828054610def90612012565b8015610e3a5780601f10610e1157610100808354040283529160200191610e3a565b820191905f5260205f20905b815481529060010190602001808311610e1d57829003601f168201915b5050505050905090565b5f5f610e4e611470565b9050610e5b818585611672565b600191505092915050565b610e6e611489565b806008541015610eb3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eaa9061259c565b60405180910390fd5b8060098190555050565b5f60075f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16610f47576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3e906121d6565b60405180910390fd5b610f4f611510565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610fbd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb4906123fc565b60405180910390fd5b610fc630610c11565b821115611008576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fff90612604565b60405180910390fd5b600a60018160018154018082558091505003905f5260205f209050505f6001600a805490506110379190612622565b905083600a828154811061104e5761104d61225c565b5b905f5260205f2090600502015f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600a82815481106110ae576110ad61225c565b5b905f5260205f209060050201600101819055505f600a82815481106110d6576110d561225c565b5b905f5260205f2090600502016002015f6101000a81548160ff0219169083151502179055506001600a82815481106111115761111061225c565b5b905f5260205f2090600502016004015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506001600a82815481106111875761118661225c565b5b905f5260205f209060050201600301819055508373ffffffffffffffffffffffffffffffffffffffff16817f4226d8f5d7de2711c5d9793318d37c1b305ed7d8c22331bcac883c1c3de6123e856040516111e19190611ef1565b60405180910390a3809150506111f56115d5565b92915050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b611285611489565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036112f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ea9061269f565b60405180910390fd5b60075f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff161561137d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137490612707565b60405180910390fd5b600160075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555060085f8154809291906113e490612725565b919050555050565b6113f4611489565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611464575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161145b9190611f8e565b60405180910390fd5b61146d81611762565b50565b5f33905090565b6114848383836001611825565b505050565b611491611470565b73ffffffffffffffffffffffffffffffffffffffff166114af610c8c565b73ffffffffffffffffffffffffffffffffffffffff161461150e576114d2611470565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016115059190611f8e565b60405180910390fd5b565b60026006540361154c576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600681905550565b6115d0838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb858560405160240161158992919061276c565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506119f4565b505050565b6001600681905550565b5f6115ea84846111fb565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81101561166c578181101561165d578281836040517ffb8f41b200000000000000000000000000000000000000000000000000000000815260040161165493929190612793565b60405180910390fd5b61166b84848484035f611825565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036116e2575f6040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081526004016116d99190611f8e565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611752575f6040517fec442f050000000000000000000000000000000000000000000000000000000081526004016117499190611f8e565b60405180910390fd5b61175d838383611a8f565b505050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611895575f6040517fe602df0500000000000000000000000000000000000000000000000000000000815260040161188c9190611f8e565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611905575f6040517f94280d620000000000000000000000000000000000000000000000000000000081526004016118fc9190611f8e565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208190555080156119ee578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516119e59190611ef1565b60405180910390a35b50505050565b5f5f60205f8451602086015f885af180611a13576040513d5f823e3d81fd5b3d92505f519150505f8214611a2c576001811415611a47565b5f8473ffffffffffffffffffffffffffffffffffffffff163b145b15611a8957836040517f5274afe7000000000000000000000000000000000000000000000000000000008152600401611a809190611f8e565b60405180910390fd5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611adf578060025f828254611ad3919061237f565b92505081905550611bad565b5f5f5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015611b68578381836040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401611b5f93929190612793565b60405180910390fd5b8181035f5f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611bf4578060025f8282540392505081905550611c3e565b805f5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611c9b9190611ef1565b60405180910390a3505050565b5f5ffd5b5f819050919050565b611cbe81611cac565b8114611cc8575f5ffd5b50565b5f81359050611cd981611cb5565b92915050565b5f60208284031215611cf457611cf3611ca8565b5b5f611d0184828501611ccb565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611d3382611d0a565b9050919050565b611d4381611d29565b82525050565b611d5281611cac565b82525050565b5f8115159050919050565b611d6c81611d58565b82525050565b5f608082019050611d855f830187611d3a565b611d926020830186611d49565b611d9f6040830185611d63565b611dac6060830184611d49565b95945050505050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f611df782611db5565b611e018185611dbf565b9350611e11818560208601611dcf565b611e1a81611ddd565b840191505092915050565b5f6020820190508181035f830152611e3d8184611ded565b905092915050565b611e4e81611d29565b8114611e58575f5ffd5b50565b5f81359050611e6981611e45565b92915050565b5f5f60408385031215611e8557611e84611ca8565b5b5f611e9285828601611e5b565b9250506020611ea385828601611ccb565b9150509250929050565b5f602082019050611ec05f830184611d63565b92915050565b5f60208284031215611edb57611eda611ca8565b5b5f611ee884828501611e5b565b91505092915050565b5f602082019050611f045f830184611d49565b92915050565b5f5f5f60608486031215611f2157611f20611ca8565b5b5f611f2e86828701611e5b565b9350506020611f3f86828701611e5b565b9250506040611f5086828701611ccb565b9150509250925092565b5f60ff82169050919050565b611f6f81611f5a565b82525050565b5f602082019050611f885f830184611f66565b92915050565b5f602082019050611fa15f830184611d3a565b92915050565b5f5f60408385031215611fbd57611fbc611ca8565b5b5f611fca85828601611e5b565b9250506020611fdb85828601611e5b565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061202957607f821691505b60208210810361203c5761203b611fe5565b5b50919050565b7f5369676e657220646f6573206e6f7420657869737400000000000000000000005f82015250565b5f612076601583611dbf565b915061208182612042565b602082019050919050565b5f6020820190508181035f8301526120a38161206a565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6120e182611cac565b91505f82036120f3576120f26120aa565b5b600182039050919050565b7f43616e6e6f742072656d6f7665207369676e65723a20776f756c64206d616b655f8201527f207265717569726564207369676e61747572657320696d706f737369626c6500602082015250565b5f612158603f83611dbf565b9150612163826120fe565b604082019050919050565b5f6020820190508181035f8301526121858161214c565b9050919050565b7f4e6f7420616e20617574686f72697a6564207369676e657200000000000000005f82015250565b5f6121c0601883611dbf565b91506121cb8261218c565b602082019050919050565b5f6020820190508181035f8301526121ed816121b4565b9050919050565b7f496e76616c6964207265717565737420494400000000000000000000000000005f82015250565b5f612228601283611dbf565b9150612233826121f4565b602082019050919050565b5f6020820190508181035f8301526122558161221c565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f5265717565737420616c726561647920657865637574656400000000000000005f82015250565b5f6122bd601883611dbf565b91506122c882612289565b602082019050919050565b5f6020820190508181035f8301526122ea816122b1565b9050919050565b7f5369676e65722068617320616c7265616479207369676e6564207468697320725f8201527f6571756573740000000000000000000000000000000000000000000000000000602082015250565b5f61234b602683611dbf565b9150612356826122f1565b604082019050919050565b5f6020820190508181035f8301526123788161233f565b9050919050565b5f61238982611cac565b915061239483611cac565b92508282019050808211156123ac576123ab6120aa565b5b92915050565b7f496e76616c696420726563697069656e742061646472657373000000000000005f82015250565b5f6123e6601983611dbf565b91506123f1826123b2565b602082019050919050565b5f6020820190508181035f830152612413816123da565b9050919050565b7f496e76616c696420746f6b656e206164647265737300000000000000000000005f82015250565b5f61244e601583611dbf565b91506124598261241a565b602082019050919050565b5f6020820190508181035f83015261247b81612442565b9050919050565b7f43616e6e6f742077697468647261772044545820546f6b656e000000000000005f82015250565b5f6124b6601983611dbf565b91506124c182612482565b602082019050919050565b5f6020820190508181035f8301526124e3816124aa565b9050919050565b7f496e73756666696369656e742062616c616e63650000000000000000000000005f82015250565b5f61251e601483611dbf565b9150612529826124ea565b602082019050919050565b5f6020820190508181035f83015261254b81612512565b9050919050565b7f43616e6e6f74206265206d6f7265207468616e207369676e65727300000000005f82015250565b5f612586601b83611dbf565b915061259182612552565b602082019050919050565b5f6020820190508181035f8301526125b38161257a565b9050919050565b7f496e73756666696369656e7420636f6e74726163742062616c616e63650000005f82015250565b5f6125ee601d83611dbf565b91506125f9826125ba565b602082019050919050565b5f6020820190508181035f83015261261b816125e2565b9050919050565b5f61262c82611cac565b915061263783611cac565b925082820390508181111561264f5761264e6120aa565b5b92915050565b7f496e76616c6964207369676e65722061646472657373000000000000000000005f82015250565b5f612689601683611dbf565b915061269482612655565b602082019050919050565b5f6020820190508181035f8301526126b68161267d565b9050919050565b7f5369676e657220616c72656164792065786973747300000000000000000000005f82015250565b5f6126f1601583611dbf565b91506126fc826126bd565b602082019050919050565b5f6020820190508181035f83015261271e816126e5565b9050919050565b5f61272f82611cac565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612761576127606120aa565b5b600182019050919050565b5f60408201905061277f5f830185611d3a565b61278c6020830184611d49565b9392505050565b5f6060820190506127a65f830186611d3a565b6127b36020830185611d49565b6127c06040830184611d49565b94935050505056fea26469706673582212206af99a3c95a657c7f0398d68e4074bfb14b11750b15d7cdaf20e0b72c1adbfc464736f6c634300081e0033
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.