Source Code
Latest 22 from a total of 22 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Update Lock Fee | 8354042 | 149 days ago | IN | 0 ETH | 0.00000139 | ||||
| Withdraw Fees | 8033703 | 152 days ago | IN | 0 ETH | 0.00000135 | ||||
| Lock Tokens | 8024093 | 153 days ago | IN | 0.0025 ETH | 0.00000454 | ||||
| Lock Tokens | 8023969 | 153 days ago | IN | 0.0025 ETH | 0.00000174 | ||||
| Lock Tokens | 8023884 | 153 days ago | IN | 0.0025 ETH | 0.00000162 | ||||
| Lock Tokens | 8023749 | 153 days ago | IN | 0.0025 ETH | 0.00000162 | ||||
| Lock Tokens | 8019304 | 153 days ago | IN | 0.0025 ETH | 0.00000171 | ||||
| Lock Tokens | 8019085 | 153 days ago | IN | 0.0025 ETH | 0.00000171 | ||||
| Lock Tokens | 8018994 | 153 days ago | IN | 0.0025 ETH | 0.00000167 | ||||
| Lock Tokens | 8018794 | 153 days ago | IN | 0.0025 ETH | 0.00000162 | ||||
| Lock Tokens | 8018655 | 153 days ago | IN | 0.0025 ETH | 0.00000164 | ||||
| Lock Tokens | 8018443 | 153 days ago | IN | 0.0025 ETH | 0.00000162 | ||||
| Lock Tokens | 8014427 | 153 days ago | IN | 0.0025 ETH | 0.00000166 | ||||
| Withdraw | 7966146 | 153 days ago | IN | 0 ETH | 0.00000144 | ||||
| Lock Tokens | 7965862 | 153 days ago | IN | 0.0025 ETH | 0.00000167 | ||||
| Withdraw | 7964986 | 153 days ago | IN | 0 ETH | 0.00000135 | ||||
| Withdraw | 7963998 | 153 days ago | IN | 0 ETH | 0.00000135 | ||||
| Lock Tokens | 7963956 | 153 days ago | IN | 0.0025 ETH | 0.00000135 | ||||
| Lock Tokens | 7963672 | 153 days ago | IN | 0.0025 ETH | 0.00000135 | ||||
| Withdraw | 7875208 | 154 days ago | IN | 0 ETH | 0.00000144 | ||||
| Withdraw Fees | 7863110 | 154 days ago | IN | 0 ETH | 0.00000135 | ||||
| Lock Tokens | 7862871 | 154 days ago | IN | 0.0025 ETH | 0.00000166 |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
TokenLocker
Compiler Version
v0.8.30+commit.73712a01
Contract Source Code (Solidity)
/**
*Submitted for verification at KatanaScan.com on 2025-08-07
*/
// File: @openzeppelin/contracts/token/ERC20/IERC20.sol
// 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);
}
// File: @openzeppelin/contracts/interfaces/IERC20.sol
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)
pragma solidity >=0.4.16;
// File: @openzeppelin/contracts/utils/introspection/IERC165.sol
// 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);
}
// File: @openzeppelin/contracts/interfaces/IERC165.sol
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)
pragma solidity >=0.4.16;
// File: @openzeppelin/contracts/interfaces/IERC1363.sol
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)
pragma solidity >=0.6.2;
/**
* @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);
}
// File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol
// OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
/**
* @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);
}
}
// File: @openzeppelin/contracts/utils/ReentrancyGuard.sol
// 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;
}
}
// File: @openzeppelin/contracts/utils/Context.sol
// 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;
}
}
// File: @openzeppelin/contracts/access/Ownable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
/**
* @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);
}
}
// File: contracts/tokelocker.sol
pragma solidity ^0.8.20;
/**
* @title TokenLocker
* @dev A smart contract for locking ERC20 tokens with time-based release mechanisms.
*
* This contract allows users to lock their ERC20 tokens for a specified period of time.
* Tokens can only be withdrawn after the unlock date has passed. Users can also transfer
* their lock ownership to another address.
*
* Features:
* - Lock tokens with custom unlock dates
* - Withdraw tokens after unlock date
* - Transfer lock ownership
* - Query locks by user or token
* - Get total locked amounts
* - View active (non-withdrawn, non-expired) locks
* - Fee mechanism for locking tokens
*
* @author jscrui | https://github.com/jscrui
* @notice This contract implements a time-locked token system
* @custom:security-contact [email protected]
*/
contract TokenLocker is ReentrancyGuard, Ownable {
using SafeERC20 for IERC20;
/// @notice The next available lock ID
uint256 public nextLockId;
/// @notice Fee required to lock tokens (in wei)
uint256 public lockFee;
/**
* @dev Structure representing a token lock
* @param id Unique identifier for the lock
* @param token Address of the locked ERC20 token
* @param owner Address of the lock owner
* @param amount Amount of tokens locked
* @param unlockDate Timestamp when tokens can be withdrawn
* @param withdrawn Whether the tokens have been withdrawn
*/
struct TokenLock {
uint256 id;
address token;
address owner;
uint256 amount;
uint256 unlockDate;
bool withdrawn;
}
/// @notice Mapping from lock ID to TokenLock struct
mapping(uint256 => TokenLock) public locks;
/// @notice Mapping from user address to array of their lock IDs
mapping(address => uint256[]) public userLockIds;
/// @notice Mapping from token address to array of lock IDs for that token
mapping(address => uint256[]) public tokenLockIds;
/**
* @dev Emitted when tokens are locked
* @param lockId The unique identifier of the lock
* @param user The address of the user who locked the tokens
* @param token The address of the locked token
* @param amount The amount of tokens locked
* @param unlockDate The timestamp when tokens can be withdrawn
* @param fee The fee paid for the lock
*/
event TokenLocked(uint256 indexed lockId, address indexed user, address indexed token, uint256 amount, uint256 unlockDate, uint256 fee);
/**
* @dev Emitted when tokens are withdrawn
* @param lockId The unique identifier of the lock
* @param user The address of the user who withdrew the tokens
*/
event TokenWithdrawn(uint256 indexed lockId, address indexed user);
/**
* @dev Emitted when a lock is transferred to a new owner
* @param lockId The unique identifier of the lock
* @param from The previous owner address
* @param to The new owner address
*/
event LockTransferred(uint256 indexed lockId, address indexed from, address indexed to);
/**
* @dev Emitted when the lock fee is updated
* @param oldFee The previous fee amount
* @param newFee The new fee amount
*/
event LockFeeUpdated(uint256 oldFee, uint256 newFee);
/**
* @dev Emitted when fees are withdrawn by the owner
* @param amount The amount of ETH withdrawn
* @param recipient The address that received the fees
*/
event FeesWithdrawn(uint256 amount, address recipient);
/**
* @dev Constructor sets the initial lock fee to 0.0025 ETH
*/
constructor() Ownable(msg.sender) {
lockFee = 0.0025 ether; // 0.0025 ETH in wei
}
/**
* @dev Locks tokens for a specified period of time
* @param token The address of the ERC20 token to lock
* @param amount The amount of tokens to lock
* @param unlockDate The timestamp when tokens can be withdrawn
*
* Requirements:
* - `unlockDate` must be in the future
* - `amount` must be greater than 0
* - Caller must have approved this contract to spend the tokens
* - Caller must send the required fee in ETH
*
* @notice This function transfers tokens from the caller to this contract
*/
function lockTokens(address token, uint256 amount, uint256 unlockDate) external payable nonReentrant {
require(unlockDate > block.timestamp, "KITSU_TOKENLOCKER: Unlock date must be in the future");
require(amount > 0, "KITSU_TOKENLOCKER: Amount must be > 0");
require(msg.value == lockFee, "KITSU_TOKENLOCKER: Incorrect fee amount");
IERC20(token).safeTransferFrom(msg.sender, address(this), amount);
TokenLock memory newLock = TokenLock({
id: nextLockId,
token: token,
owner: msg.sender,
amount: amount,
unlockDate: unlockDate,
withdrawn: false
});
locks[nextLockId] = newLock;
userLockIds[msg.sender].push(nextLockId);
tokenLockIds[token].push(nextLockId);
emit TokenLocked(nextLockId, msg.sender, token, amount, unlockDate, lockFee);
nextLockId++;
}
/**
* @dev Withdraws tokens from a lock after the unlock date has passed
* @param lockId The unique identifier of the lock to withdraw from
*
* Requirements:
* - Caller must be the owner of the lock
* - Lock must not have been already withdrawn
* - Current timestamp must be >= unlock date
*
* @notice This function transfers tokens from this contract to the lock owner
*/
function withdraw(uint256 lockId) external nonReentrant {
TokenLock storage lock = locks[lockId];
require(lock.owner == msg.sender, "KITSU_TOKENLOCKER: Not owner");
require(!lock.withdrawn, "KITSU_TOKENLOCKER: Already withdrawn");
require(block.timestamp >= lock.unlockDate, "KITSU_TOKENLOCKER: Still locked");
lock.withdrawn = true;
IERC20(lock.token).safeTransfer(msg.sender, lock.amount);
emit TokenWithdrawn(lockId, msg.sender);
}
/**
* @dev Transfers ownership of a lock to a new address
* @param lockId The unique identifier of the lock to transfer
* @param newOwner The address to transfer ownership to
*
* Requirements:
* - `newOwner` must not be the zero address
* - Caller must be the current owner of the lock
* - Lock must not have been already withdrawn
*
* @notice This function only transfers ownership, not the actual tokens
*/
function transferLock(uint256 lockId, address newOwner) external {
require(newOwner != address(0), "KITSU_TOKENLOCKER: Zero address not allowed");
TokenLock storage lock = locks[lockId];
require(lock.owner == msg.sender, "KITSU_TOKENLOCKER: Not owner");
require(!lock.withdrawn, "KITSU_TOKENLOCKER: Already withdrawn");
address previousOwner = lock.owner;
lock.owner = newOwner;
// Remove lockId from previous owner's array
uint256[] storage previousOwnerLocks = userLockIds[previousOwner];
for (uint256 i = 0; i < previousOwnerLocks.length; i++) {
if (previousOwnerLocks[i] == lockId) {
// Replace with the last element and pop
previousOwnerLocks[i] = previousOwnerLocks[previousOwnerLocks.length - 1];
previousOwnerLocks.pop();
break;
}
}
// Add lockId to new owner's array
userLockIds[newOwner].push(lockId);
emit LockTransferred(lockId, previousOwner, newOwner);
}
/**
* @dev Returns all lock IDs for a specific user
* @param user The address of the user
* @return Array of lock IDs owned by the user
*/
function getUserLocks(address user) external view returns (uint256[] memory) {
return userLockIds[user];
}
/**
* @dev Returns all lock IDs for a specific token
* @param token The address of the token
* @return Array of lock IDs for the specified token
*/
function getTokenLocks(address token) external view returns (uint256[] memory) {
return tokenLockIds[token];
}
/**
* @dev Returns the complete TokenLock struct for a specific lock ID
* @param lockId The unique identifier of the lock
* @return The TokenLock struct containing all lock information
*/
function getLock(uint256 lockId) external view returns (TokenLock memory) {
return locks[lockId];
}
/**
* @dev Returns the total amount of tokens locked by a user for a specific token
* @param user The address of the user
* @param token The address of the token
* @return total The total amount of tokens locked (excluding withdrawn locks)
*/
function getLockedAmount(address user, address token) external view returns (uint256 total) {
uint256[] memory ids = userLockIds[user];
for (uint i = 0; i < ids.length; i++) {
TokenLock storage l = locks[ids[i]];
if (l.token == token && !l.withdrawn) {
total += l.amount;
}
}
}
/**
* @dev Returns all active locks for a user (non-withdrawn and not yet expired)
* @param user The address of the user
* @return Array of TokenLock structs for active locks
*/
function getActiveLocks(address user) external view returns (TokenLock[] memory) {
uint256[] memory ids = userLockIds[user];
uint256 count;
for (uint i = 0; i < ids.length; i++) {
TokenLock storage l = locks[ids[i]];
if (!l.withdrawn && block.timestamp < l.unlockDate) count++;
}
TokenLock[] memory result = new TokenLock[](count);
uint256 idx;
for (uint i = 0; i < ids.length; i++) {
TokenLock storage l = locks[ids[i]];
if (!l.withdrawn && block.timestamp < l.unlockDate) {
result[idx] = l;
idx++;
}
}
return result;
}
/**
* @dev Updates the lock fee
* @param newFee The new fee amount in wei
*
* Requirements:
* - Caller must be the contract owner
*
* @notice Only the contract owner can update the lock fee
*/
function updateLockFee(uint256 newFee) external onlyOwner {
uint256 oldFee = lockFee;
lockFee = newFee;
emit LockFeeUpdated(oldFee, newFee);
}
/**
* @dev Withdraws accumulated fees to the owner
*
* Requirements:
* - Caller must be the contract owner
* - Contract must have ETH balance to withdraw
*
* @notice Only the contract owner can withdraw accumulated fees
*/
function withdrawFees() external onlyOwner {
uint256 fees = address(this).balance;
require(fees > 0, "KITSU_TOKENLOCKER: No fees to withdraw");
(bool success, ) = owner().call{value: fees}("");
require(success, "KITSU_TOKENLOCKER: Fee withdrawal failed");
emit FeesWithdrawn(fees, owner());
}
/**
* @dev Returns the current lock fee
* @return The current lock fee in wei
*/
function getLockFee() external view returns (uint256) {
return lockFee;
}
/**
* @dev Returns the total fees accumulated in the contract
* @return The total ETH balance of the contract
*/
function getAccumulatedFees() external view returns (uint256) {
return address(this).balance;
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"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":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"}],"name":"FeesWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"LockFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"lockId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"LockTransferred","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":"uint256","name":"lockId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unlockDate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"TokenLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"lockId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"TokenWithdrawn","type":"event"},{"inputs":[],"name":"getAccumulatedFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getActiveLocks","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"unlockDate","type":"uint256"},{"internalType":"bool","name":"withdrawn","type":"bool"}],"internalType":"struct TokenLocker.TokenLock[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"lockId","type":"uint256"}],"name":"getLock","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"unlockDate","type":"uint256"},{"internalType":"bool","name":"withdrawn","type":"bool"}],"internalType":"struct TokenLocker.TokenLock","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLockFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"getLockedAmount","outputs":[{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getTokenLocks","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserLocks","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"unlockDate","type":"uint256"}],"name":"lockTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"locks","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"unlockDate","type":"uint256"},{"internalType":"bool","name":"withdrawn","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextLockId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenLockIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"lockId","type":"uint256"},{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"updateLockFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userLockIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"lockId","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawFees","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561000f575f5ffd5b503360015f819055505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610088575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161007f91906101ad565b60405180910390fd5b610097816100ab60201b60201c565b506608e1bc9bf040006003819055506101c6565b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6101978261016e565b9050919050565b6101a78161018d565b82525050565b5f6020820190506101c05f83018461019e565b92915050565b61284b806101d35f395ff3fe60806040526004361061011e575f3560e01c80639a76d1fc1161009f578063db28dbd111610063578063db28dbd1146103b6578063f2fde38b146103e0578063f357dc0814610408578063f4dadc6114610444578063ff669879146104855761011e565b80639a76d1fc146102be578063a25983e5146102fa578063a7d8916814610316578063b48dd3be14610352578063d68f4dd11461037a5761011e565b80635e92f1ba116100e65780635e92f1ba146101f057806361496d59146102185780636518a0b314610254578063715018a61461027e5780638da5cb5b146102945761011e565b806323a35de9146101225780632e1a7d4d1461015e578063476343ee1461018657806356a062351461019c5780635df45a37146101c6575b5f5ffd5b34801561012d575f5ffd5b5061014860048036038101906101439190611bae565b6104c1565b6040516101559190611c99565b60405180910390f35b348015610169575f5ffd5b50610184600480360381019061017f9190611ce3565b610554565b005b348015610191575f5ffd5b5061019a610757565b005b3480156101a7575f5ffd5b506101b0610898565b6040516101bd9190611d1d565b60405180910390f35b3480156101d1575f5ffd5b506101da61089e565b6040516101e79190611d1d565b60405180910390f35b3480156101fb575f5ffd5b5061021660048036038101906102119190611ce3565b6108a5565b005b348015610223575f5ffd5b5061023e60048036038101906102399190611bae565b6108f7565b60405161024b9190611e80565b60405180910390f35b34801561025f575f5ffd5b50610268610bf6565b6040516102759190611d1d565b60405180910390f35b348015610289575f5ffd5b50610292610bfc565b005b34801561029f575f5ffd5b506102a8610c0f565b6040516102b59190611eaf565b60405180910390f35b3480156102c9575f5ffd5b506102e460048036038101906102df9190611ec8565b610c37565b6040516102f19190611d1d565b60405180910390f35b610314600480360381019061030f9190611f06565b610c62565b005b348015610321575f5ffd5b5061033c60048036038101906103379190611f56565b610ff6565b6040516103499190611d1d565b60405180910390f35b34801561035d575f5ffd5b5061037860048036038101906103739190611f94565b61115a565b005b348015610385575f5ffd5b506103a0600480360381019061039b9190611ce3565b6114df565b6040516103ad919061204b565b60405180910390f35b3480156103c1575f5ffd5b506103ca6115eb565b6040516103d79190611d1d565b60405180910390f35b3480156103eb575f5ffd5b5061040660048036038101906104019190611bae565b6115f4565b005b348015610413575f5ffd5b5061042e60048036038101906104299190611bae565b611678565b60405161043b9190611c99565b60405180910390f35b34801561044f575f5ffd5b5061046a60048036038101906104659190611ce3565b61170b565b60405161047c96959493929190612073565b60405180910390f35b348015610490575f5ffd5b506104ab60048036038101906104a69190611ec8565b61178d565b6040516104b89190611d1d565b60405180910390f35b606060055f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2080548060200260200160405190810160405280929190818152602001828054801561054857602002820191905f5260205f20905b815481526020019060010190808311610534575b50505050509050919050565b61055c6117b8565b5f60045f8381526020019081526020015f2090503373ffffffffffffffffffffffffffffffffffffffff16816002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610601576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105f89061212c565b60405180910390fd5b806005015f9054906101000a900460ff1615610652576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610649906121ba565b60405180910390fd5b8060040154421015610699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161069090612222565b60405180910390fd5b6001816005015f6101000a81548160ff021916908315150217905550610707338260030154836001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166117fc9092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff16827f61dc2e6e64c7a742717c1eae2958f9bc011c40d616afd06af648eff740c2b04d60405160405180910390a35061075461187b565b50565b61075f611884565b5f4790505f81116107a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161079c906122b0565b60405180910390fd5b5f6107ae610c0f565b73ffffffffffffffffffffffffffffffffffffffff16826040516107d1906122fb565b5f6040518083038185875af1925050503d805f811461080b576040519150601f19603f3d011682016040523d82523d5f602084013e610810565b606091505b5050905080610854576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084b9061237f565b60405180910390fd5b7f812bcf6853ebc81dc0a1d2323893eedad6cd086a4398311a699e0a7acdf187b38261087e610c0f565b60405161088c92919061239d565b60405180910390a15050565b60035481565b5f47905090565b6108ad611884565b5f6003549050816003819055507f58dfc23d20a390782f8a3cead1afe03996409c5373adc193bc5de9467d8d853681836040516108eb9291906123c4565b60405180910390a15050565b60605f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2080548060200260200160405190810160405280929190818152602001828054801561097f57602002820191905f5260205f20905b81548152602001906001019080831161096b575b505050505090505f5f5f90505b8251811015610a06575f60045f8584815181106109ac576109ab6123eb565b5b602002602001015181526020019081526020015f209050806005015f9054906101000a900460ff161580156109e45750806004015442105b156109f85782806109f490612445565b9350505b50808060010191505061098c565b505f8167ffffffffffffffff811115610a2257610a2161248c565b5b604051908082528060200260200182016040528015610a5b57816020015b610a48611af2565b815260200190600190039081610a405790505b5090505f5f5f90505b8451811015610be9575f60045f878481518110610a8457610a836123eb565b5b602002602001015181526020019081526020015f209050806005015f9054906101000a900460ff16158015610abc5750806004015442105b15610bdb57806040518060c00160405290815f8201548152602001600182015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016003820154815260200160048201548152602001600582015f9054906101000a900460ff161515151581525050848481518110610bc157610bc06123eb565b5b60200260200101819052508280610bd790612445565b9350505b508080600101915050610a64565b5081945050505050919050565b60025481565b610c04611884565b610c0d5f61190b565b565b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6006602052815f5260405f208181548110610c50575f80fd5b905f5260205f20015f91509150505481565b610c6a6117b8565b428111610cac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca390612529565b60405180910390fd5b5f8211610cee576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce5906125b7565b60405180910390fd5b6003543414610d32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d2990612645565b60405180910390fd5b610d5f3330848673ffffffffffffffffffffffffffffffffffffffff166119ce909392919063ffffffff16565b5f6040518060c0016040528060025481526020018573ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018381526020015f151581525090508060045f60025481526020019081526020015f205f820151815f01556020820151816001015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040820151816002015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550606082015181600301556080820151816004015560a0820151816005015f6101000a81548160ff02191690831515021790555090505060055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600254908060018154018082558091505060019003905f5260205f20015f909190919091505560065f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600254908060018154018082558091505060019003905f5260205f20015f90919091909150558373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff166002547fe0943b647311abc53881f2f9e2e52946e2ec6383bcc9a22c06b8cc25d2d71f228686600354604051610fc993929190612663565b60405180910390a460025f815480929190610fe390612445565b919050555050610ff161187b565b505050565b5f5f60055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2080548060200260200160405190810160405280929190818152602001828054801561107d57602002820191905f5260205f20905b815481526020019060010190808311611069575b505050505090505f5f90505b8151811015611152575f60045f8484815181106110a9576110a86123eb565b5b602002602001015181526020019081526020015f2090508473ffffffffffffffffffffffffffffffffffffffff16816001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614801561112c5750806005015f9054906101000a900460ff16155b15611144578060030154846111419190612698565b93505b508080600101915050611089565b505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036111c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111bf9061273b565b60405180910390fd5b5f60045f8481526020019081526020015f2090503373ffffffffffffffffffffffffffffffffffffffff16816002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461126d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112649061212c565b60405180910390fd5b806005015f9054906101000a900460ff16156112be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112b5906121ba565b60405180910390fd5b5f816002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082826002015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505f60055f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2090505f5f90505b818054905081101561141b578582828154811061138c5761138b6123eb565b5b905f5260205f2001540361140e5781600183805490506113ac9190612759565b815481106113bd576113bc6123eb565b5b905f5260205f2001548282815481106113d9576113d86123eb565b5b905f5260205f200181905550818054806113f6576113f561278c565b5b600190038181905f5260205f20015f9055905561141b565b808060010191505061136c565b5060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2085908060018154018082558091505060019003905f5260205f20015f90919091909150558373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16867f902e03d40a887f58f46d747f437ac0a7b3028d6218bc4af171aef594fcd7e3e760405160405180910390a45050505050565b6114e7611af2565b60045f8381526020019081526020015f206040518060c00160405290815f8201548152602001600182015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016003820154815260200160048201548152602001600582015f9054906101000a900460ff1615151515815250509050919050565b5f600354905090565b6115fc611884565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361166c575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016116639190611eaf565b60405180910390fd5b6116758161190b565b50565b606060065f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208054806020026020016040519081016040528092919081815260200182805480156116ff57602002820191905f5260205f20905b8154815260200190600101908083116116eb575b50505050509050919050565b6004602052805f5260405f205f91509050805f015490806001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806003015490806004015490806005015f9054906101000a900460ff16905086565b6005602052815f5260405f2081815481106117a6575f80fd5b905f5260205f20015f91509150505481565b60025f54036117f3576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025f81905550565b611876838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb858560405160240161182f9291906127b9565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611a50565b505050565b60015f81905550565b61188c611aeb565b73ffffffffffffffffffffffffffffffffffffffff166118aa610c0f565b73ffffffffffffffffffffffffffffffffffffffff1614611909576118cd611aeb565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016119009190611eaf565b60405180910390fd5b565b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611a4a848573ffffffffffffffffffffffffffffffffffffffff166323b872dd868686604051602401611a03939291906127e0565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611a50565b50505050565b5f5f60205f8451602086015f885af180611a6f576040513d5f823e3d81fd5b3d92505f519150505f8214611a88576001811415611aa3565b5f8473ffffffffffffffffffffffffffffffffffffffff163b145b15611ae557836040517f5274afe7000000000000000000000000000000000000000000000000000000008152600401611adc9190611eaf565b60405180910390fd5b50505050565b5f33905090565b6040518060c001604052805f81526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f81526020015f81526020015f151581525090565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611b7d82611b54565b9050919050565b611b8d81611b73565b8114611b97575f5ffd5b50565b5f81359050611ba881611b84565b92915050565b5f60208284031215611bc357611bc2611b50565b5b5f611bd084828501611b9a565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f819050919050565b611c1481611c02565b82525050565b5f611c258383611c0b565b60208301905092915050565b5f602082019050919050565b5f611c4782611bd9565b611c518185611be3565b9350611c5c83611bf3565b805f5b83811015611c8c578151611c738882611c1a565b9750611c7e83611c31565b925050600181019050611c5f565b5085935050505092915050565b5f6020820190508181035f830152611cb18184611c3d565b905092915050565b611cc281611c02565b8114611ccc575f5ffd5b50565b5f81359050611cdd81611cb9565b92915050565b5f60208284031215611cf857611cf7611b50565b5b5f611d0584828501611ccf565b91505092915050565b611d1781611c02565b82525050565b5f602082019050611d305f830184611d0e565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b611d6881611b73565b82525050565b5f8115159050919050565b611d8281611d6e565b82525050565b60c082015f820151611d9c5f850182611c0b565b506020820151611daf6020850182611d5f565b506040820151611dc26040850182611d5f565b506060820151611dd56060850182611c0b565b506080820151611de86080850182611c0b565b5060a0820151611dfb60a0850182611d79565b50505050565b5f611e0c8383611d88565b60c08301905092915050565b5f602082019050919050565b5f611e2e82611d36565b611e388185611d40565b9350611e4383611d50565b805f5b83811015611e73578151611e5a8882611e01565b9750611e6583611e18565b925050600181019050611e46565b5085935050505092915050565b5f6020820190508181035f830152611e988184611e24565b905092915050565b611ea981611b73565b82525050565b5f602082019050611ec25f830184611ea0565b92915050565b5f5f60408385031215611ede57611edd611b50565b5b5f611eeb85828601611b9a565b9250506020611efc85828601611ccf565b9150509250929050565b5f5f5f60608486031215611f1d57611f1c611b50565b5b5f611f2a86828701611b9a565b9350506020611f3b86828701611ccf565b9250506040611f4c86828701611ccf565b9150509250925092565b5f5f60408385031215611f6c57611f6b611b50565b5b5f611f7985828601611b9a565b9250506020611f8a85828601611b9a565b9150509250929050565b5f5f60408385031215611faa57611fa9611b50565b5b5f611fb785828601611ccf565b9250506020611fc885828601611b9a565b9150509250929050565b60c082015f820151611fe65f850182611c0b565b506020820151611ff96020850182611d5f565b50604082015161200c6040850182611d5f565b50606082015161201f6060850182611c0b565b5060808201516120326080850182611c0b565b5060a082015161204560a0850182611d79565b50505050565b5f60c08201905061205e5f830184611fd2565b92915050565b61206d81611d6e565b82525050565b5f60c0820190506120865f830189611d0e565b6120936020830188611ea0565b6120a06040830187611ea0565b6120ad6060830186611d0e565b6120ba6080830185611d0e565b6120c760a0830184612064565b979650505050505050565b5f82825260208201905092915050565b7f4b495453555f544f4b454e4c4f434b45523a204e6f74206f776e6572000000005f82015250565b5f612116601c836120d2565b9150612121826120e2565b602082019050919050565b5f6020820190508181035f8301526121438161210a565b9050919050565b7f4b495453555f544f4b454e4c4f434b45523a20416c72656164792077697468645f8201527f7261776e00000000000000000000000000000000000000000000000000000000602082015250565b5f6121a46024836120d2565b91506121af8261214a565b604082019050919050565b5f6020820190508181035f8301526121d181612198565b9050919050565b7f4b495453555f544f4b454e4c4f434b45523a205374696c6c206c6f636b6564005f82015250565b5f61220c601f836120d2565b9150612217826121d8565b602082019050919050565b5f6020820190508181035f83015261223981612200565b9050919050565b7f4b495453555f544f4b454e4c4f434b45523a204e6f206665657320746f2077695f8201527f7468647261770000000000000000000000000000000000000000000000000000602082015250565b5f61229a6026836120d2565b91506122a582612240565b604082019050919050565b5f6020820190508181035f8301526122c78161228e565b9050919050565b5f81905092915050565b50565b5f6122e65f836122ce565b91506122f1826122d8565b5f82019050919050565b5f612305826122db565b9150819050919050565b7f4b495453555f544f4b454e4c4f434b45523a20466565207769746864726177615f8201527f6c206661696c6564000000000000000000000000000000000000000000000000602082015250565b5f6123696028836120d2565b91506123748261230f565b604082019050919050565b5f6020820190508181035f8301526123968161235d565b9050919050565b5f6040820190506123b05f830185611d0e565b6123bd6020830184611ea0565b9392505050565b5f6040820190506123d75f830185611d0e565b6123e46020830184611d0e565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61244f82611c02565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361248157612480612418565b5b600182019050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4b495453555f544f4b454e4c4f434b45523a20556e6c6f636b2064617465206d5f8201527f75737420626520696e2074686520667574757265000000000000000000000000602082015250565b5f6125136034836120d2565b915061251e826124b9565b604082019050919050565b5f6020820190508181035f83015261254081612507565b9050919050565b7f4b495453555f544f4b454e4c4f434b45523a20416d6f756e74206d75737420625f8201527f65203e2030000000000000000000000000000000000000000000000000000000602082015250565b5f6125a16025836120d2565b91506125ac82612547565b604082019050919050565b5f6020820190508181035f8301526125ce81612595565b9050919050565b7f4b495453555f544f4b454e4c4f434b45523a20496e636f7272656374206665655f8201527f20616d6f756e7400000000000000000000000000000000000000000000000000602082015250565b5f61262f6027836120d2565b915061263a826125d5565b604082019050919050565b5f6020820190508181035f83015261265c81612623565b9050919050565b5f6060820190506126765f830186611d0e565b6126836020830185611d0e565b6126906040830184611d0e565b949350505050565b5f6126a282611c02565b91506126ad83611c02565b92508282019050808211156126c5576126c4612418565b5b92915050565b7f4b495453555f544f4b454e4c4f434b45523a205a65726f2061646472657373205f8201527f6e6f7420616c6c6f776564000000000000000000000000000000000000000000602082015250565b5f612725602b836120d2565b9150612730826126cb565b604082019050919050565b5f6020820190508181035f83015261275281612719565b9050919050565b5f61276382611c02565b915061276e83611c02565b925082820390508181111561278657612785612418565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffd5b5f6040820190506127cc5f830185611ea0565b6127d96020830184611d0e565b9392505050565b5f6060820190506127f35f830186611ea0565b6128006020830185611ea0565b61280d6040830184611d0e565b94935050505056fea2646970667358221220195cbae624cb6fbb7d9459878595263785c001d6efd582d7a46bbbdabe22506b64736f6c634300081e0033
Deployed Bytecode
0x60806040526004361061011e575f3560e01c80639a76d1fc1161009f578063db28dbd111610063578063db28dbd1146103b6578063f2fde38b146103e0578063f357dc0814610408578063f4dadc6114610444578063ff669879146104855761011e565b80639a76d1fc146102be578063a25983e5146102fa578063a7d8916814610316578063b48dd3be14610352578063d68f4dd11461037a5761011e565b80635e92f1ba116100e65780635e92f1ba146101f057806361496d59146102185780636518a0b314610254578063715018a61461027e5780638da5cb5b146102945761011e565b806323a35de9146101225780632e1a7d4d1461015e578063476343ee1461018657806356a062351461019c5780635df45a37146101c6575b5f5ffd5b34801561012d575f5ffd5b5061014860048036038101906101439190611bae565b6104c1565b6040516101559190611c99565b60405180910390f35b348015610169575f5ffd5b50610184600480360381019061017f9190611ce3565b610554565b005b348015610191575f5ffd5b5061019a610757565b005b3480156101a7575f5ffd5b506101b0610898565b6040516101bd9190611d1d565b60405180910390f35b3480156101d1575f5ffd5b506101da61089e565b6040516101e79190611d1d565b60405180910390f35b3480156101fb575f5ffd5b5061021660048036038101906102119190611ce3565b6108a5565b005b348015610223575f5ffd5b5061023e60048036038101906102399190611bae565b6108f7565b60405161024b9190611e80565b60405180910390f35b34801561025f575f5ffd5b50610268610bf6565b6040516102759190611d1d565b60405180910390f35b348015610289575f5ffd5b50610292610bfc565b005b34801561029f575f5ffd5b506102a8610c0f565b6040516102b59190611eaf565b60405180910390f35b3480156102c9575f5ffd5b506102e460048036038101906102df9190611ec8565b610c37565b6040516102f19190611d1d565b60405180910390f35b610314600480360381019061030f9190611f06565b610c62565b005b348015610321575f5ffd5b5061033c60048036038101906103379190611f56565b610ff6565b6040516103499190611d1d565b60405180910390f35b34801561035d575f5ffd5b5061037860048036038101906103739190611f94565b61115a565b005b348015610385575f5ffd5b506103a0600480360381019061039b9190611ce3565b6114df565b6040516103ad919061204b565b60405180910390f35b3480156103c1575f5ffd5b506103ca6115eb565b6040516103d79190611d1d565b60405180910390f35b3480156103eb575f5ffd5b5061040660048036038101906104019190611bae565b6115f4565b005b348015610413575f5ffd5b5061042e60048036038101906104299190611bae565b611678565b60405161043b9190611c99565b60405180910390f35b34801561044f575f5ffd5b5061046a60048036038101906104659190611ce3565b61170b565b60405161047c96959493929190612073565b60405180910390f35b348015610490575f5ffd5b506104ab60048036038101906104a69190611ec8565b61178d565b6040516104b89190611d1d565b60405180910390f35b606060055f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2080548060200260200160405190810160405280929190818152602001828054801561054857602002820191905f5260205f20905b815481526020019060010190808311610534575b50505050509050919050565b61055c6117b8565b5f60045f8381526020019081526020015f2090503373ffffffffffffffffffffffffffffffffffffffff16816002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610601576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105f89061212c565b60405180910390fd5b806005015f9054906101000a900460ff1615610652576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610649906121ba565b60405180910390fd5b8060040154421015610699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161069090612222565b60405180910390fd5b6001816005015f6101000a81548160ff021916908315150217905550610707338260030154836001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166117fc9092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff16827f61dc2e6e64c7a742717c1eae2958f9bc011c40d616afd06af648eff740c2b04d60405160405180910390a35061075461187b565b50565b61075f611884565b5f4790505f81116107a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161079c906122b0565b60405180910390fd5b5f6107ae610c0f565b73ffffffffffffffffffffffffffffffffffffffff16826040516107d1906122fb565b5f6040518083038185875af1925050503d805f811461080b576040519150601f19603f3d011682016040523d82523d5f602084013e610810565b606091505b5050905080610854576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084b9061237f565b60405180910390fd5b7f812bcf6853ebc81dc0a1d2323893eedad6cd086a4398311a699e0a7acdf187b38261087e610c0f565b60405161088c92919061239d565b60405180910390a15050565b60035481565b5f47905090565b6108ad611884565b5f6003549050816003819055507f58dfc23d20a390782f8a3cead1afe03996409c5373adc193bc5de9467d8d853681836040516108eb9291906123c4565b60405180910390a15050565b60605f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2080548060200260200160405190810160405280929190818152602001828054801561097f57602002820191905f5260205f20905b81548152602001906001019080831161096b575b505050505090505f5f5f90505b8251811015610a06575f60045f8584815181106109ac576109ab6123eb565b5b602002602001015181526020019081526020015f209050806005015f9054906101000a900460ff161580156109e45750806004015442105b156109f85782806109f490612445565b9350505b50808060010191505061098c565b505f8167ffffffffffffffff811115610a2257610a2161248c565b5b604051908082528060200260200182016040528015610a5b57816020015b610a48611af2565b815260200190600190039081610a405790505b5090505f5f5f90505b8451811015610be9575f60045f878481518110610a8457610a836123eb565b5b602002602001015181526020019081526020015f209050806005015f9054906101000a900460ff16158015610abc5750806004015442105b15610bdb57806040518060c00160405290815f8201548152602001600182015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016003820154815260200160048201548152602001600582015f9054906101000a900460ff161515151581525050848481518110610bc157610bc06123eb565b5b60200260200101819052508280610bd790612445565b9350505b508080600101915050610a64565b5081945050505050919050565b60025481565b610c04611884565b610c0d5f61190b565b565b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6006602052815f5260405f208181548110610c50575f80fd5b905f5260205f20015f91509150505481565b610c6a6117b8565b428111610cac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca390612529565b60405180910390fd5b5f8211610cee576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce5906125b7565b60405180910390fd5b6003543414610d32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d2990612645565b60405180910390fd5b610d5f3330848673ffffffffffffffffffffffffffffffffffffffff166119ce909392919063ffffffff16565b5f6040518060c0016040528060025481526020018573ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018381526020015f151581525090508060045f60025481526020019081526020015f205f820151815f01556020820151816001015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040820151816002015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550606082015181600301556080820151816004015560a0820151816005015f6101000a81548160ff02191690831515021790555090505060055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600254908060018154018082558091505060019003905f5260205f20015f909190919091505560065f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600254908060018154018082558091505060019003905f5260205f20015f90919091909150558373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff166002547fe0943b647311abc53881f2f9e2e52946e2ec6383bcc9a22c06b8cc25d2d71f228686600354604051610fc993929190612663565b60405180910390a460025f815480929190610fe390612445565b919050555050610ff161187b565b505050565b5f5f60055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2080548060200260200160405190810160405280929190818152602001828054801561107d57602002820191905f5260205f20905b815481526020019060010190808311611069575b505050505090505f5f90505b8151811015611152575f60045f8484815181106110a9576110a86123eb565b5b602002602001015181526020019081526020015f2090508473ffffffffffffffffffffffffffffffffffffffff16816001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614801561112c5750806005015f9054906101000a900460ff16155b15611144578060030154846111419190612698565b93505b508080600101915050611089565b505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036111c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111bf9061273b565b60405180910390fd5b5f60045f8481526020019081526020015f2090503373ffffffffffffffffffffffffffffffffffffffff16816002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461126d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112649061212c565b60405180910390fd5b806005015f9054906101000a900460ff16156112be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112b5906121ba565b60405180910390fd5b5f816002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082826002015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505f60055f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2090505f5f90505b818054905081101561141b578582828154811061138c5761138b6123eb565b5b905f5260205f2001540361140e5781600183805490506113ac9190612759565b815481106113bd576113bc6123eb565b5b905f5260205f2001548282815481106113d9576113d86123eb565b5b905f5260205f200181905550818054806113f6576113f561278c565b5b600190038181905f5260205f20015f9055905561141b565b808060010191505061136c565b5060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2085908060018154018082558091505060019003905f5260205f20015f90919091909150558373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16867f902e03d40a887f58f46d747f437ac0a7b3028d6218bc4af171aef594fcd7e3e760405160405180910390a45050505050565b6114e7611af2565b60045f8381526020019081526020015f206040518060c00160405290815f8201548152602001600182015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016003820154815260200160048201548152602001600582015f9054906101000a900460ff1615151515815250509050919050565b5f600354905090565b6115fc611884565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361166c575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016116639190611eaf565b60405180910390fd5b6116758161190b565b50565b606060065f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208054806020026020016040519081016040528092919081815260200182805480156116ff57602002820191905f5260205f20905b8154815260200190600101908083116116eb575b50505050509050919050565b6004602052805f5260405f205f91509050805f015490806001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806003015490806004015490806005015f9054906101000a900460ff16905086565b6005602052815f5260405f2081815481106117a6575f80fd5b905f5260205f20015f91509150505481565b60025f54036117f3576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025f81905550565b611876838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb858560405160240161182f9291906127b9565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611a50565b505050565b60015f81905550565b61188c611aeb565b73ffffffffffffffffffffffffffffffffffffffff166118aa610c0f565b73ffffffffffffffffffffffffffffffffffffffff1614611909576118cd611aeb565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016119009190611eaf565b60405180910390fd5b565b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611a4a848573ffffffffffffffffffffffffffffffffffffffff166323b872dd868686604051602401611a03939291906127e0565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611a50565b50505050565b5f5f60205f8451602086015f885af180611a6f576040513d5f823e3d81fd5b3d92505f519150505f8214611a88576001811415611aa3565b5f8473ffffffffffffffffffffffffffffffffffffffff163b145b15611ae557836040517f5274afe7000000000000000000000000000000000000000000000000000000008152600401611adc9190611eaf565b60405180910390fd5b50505050565b5f33905090565b6040518060c001604052805f81526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f81526020015f81526020015f151581525090565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611b7d82611b54565b9050919050565b611b8d81611b73565b8114611b97575f5ffd5b50565b5f81359050611ba881611b84565b92915050565b5f60208284031215611bc357611bc2611b50565b5b5f611bd084828501611b9a565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f819050919050565b611c1481611c02565b82525050565b5f611c258383611c0b565b60208301905092915050565b5f602082019050919050565b5f611c4782611bd9565b611c518185611be3565b9350611c5c83611bf3565b805f5b83811015611c8c578151611c738882611c1a565b9750611c7e83611c31565b925050600181019050611c5f565b5085935050505092915050565b5f6020820190508181035f830152611cb18184611c3d565b905092915050565b611cc281611c02565b8114611ccc575f5ffd5b50565b5f81359050611cdd81611cb9565b92915050565b5f60208284031215611cf857611cf7611b50565b5b5f611d0584828501611ccf565b91505092915050565b611d1781611c02565b82525050565b5f602082019050611d305f830184611d0e565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b611d6881611b73565b82525050565b5f8115159050919050565b611d8281611d6e565b82525050565b60c082015f820151611d9c5f850182611c0b565b506020820151611daf6020850182611d5f565b506040820151611dc26040850182611d5f565b506060820151611dd56060850182611c0b565b506080820151611de86080850182611c0b565b5060a0820151611dfb60a0850182611d79565b50505050565b5f611e0c8383611d88565b60c08301905092915050565b5f602082019050919050565b5f611e2e82611d36565b611e388185611d40565b9350611e4383611d50565b805f5b83811015611e73578151611e5a8882611e01565b9750611e6583611e18565b925050600181019050611e46565b5085935050505092915050565b5f6020820190508181035f830152611e988184611e24565b905092915050565b611ea981611b73565b82525050565b5f602082019050611ec25f830184611ea0565b92915050565b5f5f60408385031215611ede57611edd611b50565b5b5f611eeb85828601611b9a565b9250506020611efc85828601611ccf565b9150509250929050565b5f5f5f60608486031215611f1d57611f1c611b50565b5b5f611f2a86828701611b9a565b9350506020611f3b86828701611ccf565b9250506040611f4c86828701611ccf565b9150509250925092565b5f5f60408385031215611f6c57611f6b611b50565b5b5f611f7985828601611b9a565b9250506020611f8a85828601611b9a565b9150509250929050565b5f5f60408385031215611faa57611fa9611b50565b5b5f611fb785828601611ccf565b9250506020611fc885828601611b9a565b9150509250929050565b60c082015f820151611fe65f850182611c0b565b506020820151611ff96020850182611d5f565b50604082015161200c6040850182611d5f565b50606082015161201f6060850182611c0b565b5060808201516120326080850182611c0b565b5060a082015161204560a0850182611d79565b50505050565b5f60c08201905061205e5f830184611fd2565b92915050565b61206d81611d6e565b82525050565b5f60c0820190506120865f830189611d0e565b6120936020830188611ea0565b6120a06040830187611ea0565b6120ad6060830186611d0e565b6120ba6080830185611d0e565b6120c760a0830184612064565b979650505050505050565b5f82825260208201905092915050565b7f4b495453555f544f4b454e4c4f434b45523a204e6f74206f776e6572000000005f82015250565b5f612116601c836120d2565b9150612121826120e2565b602082019050919050565b5f6020820190508181035f8301526121438161210a565b9050919050565b7f4b495453555f544f4b454e4c4f434b45523a20416c72656164792077697468645f8201527f7261776e00000000000000000000000000000000000000000000000000000000602082015250565b5f6121a46024836120d2565b91506121af8261214a565b604082019050919050565b5f6020820190508181035f8301526121d181612198565b9050919050565b7f4b495453555f544f4b454e4c4f434b45523a205374696c6c206c6f636b6564005f82015250565b5f61220c601f836120d2565b9150612217826121d8565b602082019050919050565b5f6020820190508181035f83015261223981612200565b9050919050565b7f4b495453555f544f4b454e4c4f434b45523a204e6f206665657320746f2077695f8201527f7468647261770000000000000000000000000000000000000000000000000000602082015250565b5f61229a6026836120d2565b91506122a582612240565b604082019050919050565b5f6020820190508181035f8301526122c78161228e565b9050919050565b5f81905092915050565b50565b5f6122e65f836122ce565b91506122f1826122d8565b5f82019050919050565b5f612305826122db565b9150819050919050565b7f4b495453555f544f4b454e4c4f434b45523a20466565207769746864726177615f8201527f6c206661696c6564000000000000000000000000000000000000000000000000602082015250565b5f6123696028836120d2565b91506123748261230f565b604082019050919050565b5f6020820190508181035f8301526123968161235d565b9050919050565b5f6040820190506123b05f830185611d0e565b6123bd6020830184611ea0565b9392505050565b5f6040820190506123d75f830185611d0e565b6123e46020830184611d0e565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61244f82611c02565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361248157612480612418565b5b600182019050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4b495453555f544f4b454e4c4f434b45523a20556e6c6f636b2064617465206d5f8201527f75737420626520696e2074686520667574757265000000000000000000000000602082015250565b5f6125136034836120d2565b915061251e826124b9565b604082019050919050565b5f6020820190508181035f83015261254081612507565b9050919050565b7f4b495453555f544f4b454e4c4f434b45523a20416d6f756e74206d75737420625f8201527f65203e2030000000000000000000000000000000000000000000000000000000602082015250565b5f6125a16025836120d2565b91506125ac82612547565b604082019050919050565b5f6020820190508181035f8301526125ce81612595565b9050919050565b7f4b495453555f544f4b454e4c4f434b45523a20496e636f7272656374206665655f8201527f20616d6f756e7400000000000000000000000000000000000000000000000000602082015250565b5f61262f6027836120d2565b915061263a826125d5565b604082019050919050565b5f6020820190508181035f83015261265c81612623565b9050919050565b5f6060820190506126765f830186611d0e565b6126836020830185611d0e565b6126906040830184611d0e565b949350505050565b5f6126a282611c02565b91506126ad83611c02565b92508282019050808211156126c5576126c4612418565b5b92915050565b7f4b495453555f544f4b454e4c4f434b45523a205a65726f2061646472657373205f8201527f6e6f7420616c6c6f776564000000000000000000000000000000000000000000602082015250565b5f612725602b836120d2565b9150612730826126cb565b604082019050919050565b5f6020820190508181035f83015261275281612719565b9050919050565b5f61276382611c02565b915061276e83611c02565b925082820390508181111561278657612785612418565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffd5b5f6040820190506127cc5f830185611ea0565b6127d96020830184611d0e565b9392505050565b5f6060820190506127f35f830186611ea0565b6128006020830185611ea0565b61280d6040830184611d0e565b94935050505056fea2646970667358221220195cbae624cb6fbb7d9459878595263785c001d6efd582d7a46bbbdabe22506b64736f6c634300081e0033
Deployed Bytecode Sourcemap
27467:11125:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34729:120;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32439:516;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;37785:352;;;;;;;;;;;;;:::i;:::-;;27690:22;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38480:109;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37325:174;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;36362:707;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;27602:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25748:103;;;;;;;;;;;;;:::i;:::-;;25073:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28619:49;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31049:942;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35782:365;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33445:1108;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35383:113;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38249:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26006:220;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35034:124;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28353:42;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;:::i;:::-;;;;;;;;28478:48;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34729:120;34788:16;34824:11;:17;34836:4;34824:17;;;;;;;;;;;;;;;34817:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34729:120;;;:::o;32439:516::-;21472:21;:19;:21::i;:::-;32506:22:::1;32531:5;:13;32537:6;32531:13;;;;;;;;;;;32506:38;;32577:10;32563:24;;:4;:10;;;;;;;;;;;;:24;;;32555:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;32640:4;:14;;;;;;;;;;;;32639:15;32631:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;32733:4;:15;;;32714;:34;;32706:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;32814:4;32797;:14;;;:21;;;;;;;;;;;;;;;;;;32839:56;32871:10;32883:4;:11;;;32846:4;:10;;;;;;;;;;;;32839:31;;;;:56;;;;;:::i;:::-;32936:10;32913:34;;32928:6;32913:34;;;;;;;;;;32495:460;21516:20:::0;:18;:20::i;:::-;32439:516;:::o;37785:352::-;24959:13;:11;:13::i;:::-;37839:12:::1;37854:21;37839:36;;37901:1;37894:4;:8;37886:59;;;;;;;;;;;;:::i;:::-;;;;;;;;;37967:12;37985:7;:5;:7::i;:::-;:12;;38005:4;37985:29;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37966:48;;;38033:7;38025:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;38101:28;38115:4;38121:7;:5;:7::i;:::-;38101:28;;;;;;;:::i;:::-;;;;;;;;37828:309;;37785:352::o:0;27690:22::-;;;;:::o;38480:109::-;38533:7;38560:21;38553:28;;38480:109;:::o;37325:174::-;24959:13;:11;:13::i;:::-;37394:14:::1;37411:7;;37394:24;;37439:6;37429:7;:16;;;;37461:30;37476:6;37484;37461:30;;;;;;;:::i;:::-;;;;;;;;37383:116;37325:174:::0;:::o;36362:707::-;36423:18;36454:20;36477:11;:17;36489:4;36477:17;;;;;;;;;;;;;;;36454:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36505:13;36534:6;36543:1;36534:10;;36529:174;36550:3;:10;36546:1;:14;36529:174;;;36582:19;36604:5;:13;36610:3;36614:1;36610:6;;;;;;;;:::i;:::-;;;;;;;;36604:13;;;;;;;;;;;36582:35;;36637:1;:11;;;;;;;;;;;;36636:12;:46;;;;;36670:1;:12;;;36652:15;:30;36636:46;36632:59;;;36684:7;;;;;:::i;:::-;;;;36632:59;36567:136;36562:3;;;;;;;36529:174;;;;36715:25;36759:5;36743:22;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;36715:50;;36776:11;36803:6;36812:1;36803:10;;36798:240;36819:3;:10;36815:1;:14;36798:240;;;36851:19;36873:5;:13;36879:3;36883:1;36879:6;;;;;;;;:::i;:::-;;;;;;;;36873:13;;;;;;;;;;;36851:35;;36906:1;:11;;;;;;;;;;;;36905:12;:46;;;;;36939:1;:12;;;36921:15;:30;36905:46;36901:126;;;36986:1;36972:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:6;36979:3;36972:11;;;;;;;;:::i;:::-;;;;;;;:15;;;;37006:5;;;;;:::i;:::-;;;;36901:126;36836:202;36831:3;;;;;;;36798:240;;;;37055:6;37048:13;;;;;;36362:707;;;:::o;27602:25::-;;;;:::o;25748:103::-;24959:13;:11;:13::i;:::-;25813:30:::1;25840:1;25813:18;:30::i;:::-;25748:103::o:0;25073:87::-;25119:7;25146:6;;;;;;;;;;;25139:13;;25073:87;:::o;28619:49::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;31049:942::-;21472:21;:19;:21::i;:::-;31182:15:::1;31169:10;:28;31161:93;;;;;;;;;;;;:::i;:::-;;;;;;;;;31282:1;31273:6;:10;31265:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;31357:7;;31344:9;:20;31336:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;31421:65;31452:10;31472:4;31479:6;31428:5;31421:30;;;;:65;;;;;;:::i;:::-;31499:24;31526:207;;;;;;;;31555:10;;31526:207;;;;31587:5;31526:207;;;;;;31614:10;31526:207;;;;;;31647:6;31526:207;;;;31680:10;31526:207;;;;31716:5;31526:207;;;;::::0;31499:234:::1;;31766:7;31746:5;:17;31752:10;;31746:17;;;;;;;;;;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31784:11;:23;31796:10;31784:23;;;;;;;;;;;;;;;31813:10;;31784:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31835:12;:19;31848:5;31835:19;;;;;;;;;;;;;;;31860:10;;31835:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31925:5;31889:71;;31913:10;31889:71;;31901:10;;31889:71;31932:6;31940:10;31952:7;;31889:71;;;;;;;;:::i;:::-;;;;;;;;31971:10;;:12;;;;;;;;;:::i;:::-;;;;;;31150:841;21516:20:::0;:18;:20::i;:::-;31049:942;;;:::o;35782:365::-;35859:13;35885:20;35908:11;:17;35920:4;35908:17;;;;;;;;;;;;;;;35885:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35941:6;35950:1;35941:10;;35936:204;35957:3;:10;35953:1;:14;35936:204;;;35989:19;36011:5;:13;36017:3;36021:1;36017:6;;;;;;;;:::i;:::-;;;;;;;;36011:13;;;;;;;;;;;35989:35;;36054:5;36043:16;;:1;:7;;;;;;;;;;;;:16;;;:32;;;;;36064:1;:11;;;;;;;;;;;;36063:12;36043:32;36039:90;;;36105:1;:8;;;36096:17;;;;;:::i;:::-;;;36039:90;35974:166;35969:3;;;;;;;35936:204;;;;35874:273;35782:365;;;;:::o;33445:1108::-;33549:1;33529:22;;:8;:22;;;33521:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;33610:22;33635:5;:13;33641:6;33635:13;;;;;;;;;;;33610:38;;33681:10;33667:24;;:4;:10;;;;;;;;;;;;:24;;;33659:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;33744:4;:14;;;;;;;;;;;;33743:15;33735:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;33812:21;33836:4;:10;;;;;;;;;;;;33812:34;;33870:8;33857:4;:10;;;:21;;;;;;;;;;;;;;;;;;33953:36;33992:11;:26;34004:13;33992:26;;;;;;;;;;;;;;;33953:65;;34034:9;34046:1;34034:13;;34029:352;34053:18;:25;;;;34049:1;:29;34029:352;;;34129:6;34104:18;34123:1;34104:21;;;;;;;;:::i;:::-;;;;;;;;;;:31;34100:270;;34238:18;34285:1;34257:18;:25;;;;:29;;;;:::i;:::-;34238:49;;;;;;;;:::i;:::-;;;;;;;;;;34214:18;34233:1;34214:21;;;;;;;;:::i;:::-;;;;;;;;;:73;;;;34306:18;:24;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;34349:5;;34100:270;34080:3;;;;;;;34029:352;;;;34445:11;:21;34457:8;34445:21;;;;;;;;;;;;;;;34472:6;34445:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34536:8;34497:48;;34521:13;34497:48;;34513:6;34497:48;;;;;;;;;;33510:1043;;;33445:1108;;:::o;35383:113::-;35439:16;;:::i;:::-;35475:5;:13;35481:6;35475:13;;;;;;;;;;;35468:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35383:113;;;:::o;38249:87::-;38294:7;38321;;38314:14;;38249:87;:::o;26006:220::-;24959:13;:11;:13::i;:::-;26111:1:::1;26091:22;;:8;:22;;::::0;26087:93:::1;;26165:1;26137:31;;;;;;;;;;;:::i;:::-;;;;;;;;26087:93;26190:28;26209:8;26190:18;:28::i;:::-;26006:220:::0;:::o;35034:124::-;35095:16;35131:12;:19;35144:5;35131:19;;;;;;;;;;;;;;;35124:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35034:124;;;:::o;28353:42::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;28478:48::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;21552:315::-;20850:1;21681:7;;:18;21677:88;;21723:30;;;;;;;;;;;;;;21677:88;20850:1;21842:7;:17;;;;21552:315::o;9845:162::-;9928:71;9948:5;9970;:14;;;9987:2;9991:5;9955:43;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9928:19;:71::i;:::-;9845:162;;;:::o;21875:212::-;20807:1;22058:7;:21;;;;21875:212::o;25238:166::-;25309:12;:10;:12::i;:::-;25298:23;;:7;:5;:7::i;:::-;:23;;;25294:103;;25372:12;:10;:12::i;:::-;25345:40;;;;;;;;;;;:::i;:::-;;;;;;;;25294:103;25238:166::o;26386:191::-;26460:16;26479:6;;;;;;;;;;;26460:25;;26505:8;26496:6;;:17;;;;;;;;;;;;;;;;;;26560:8;26529:40;;26550:8;26529:40;;;;;;;;;;;;26449:128;26386:191;:::o;10252:190::-;10353:81;10373:5;10395;:18;;;10416:4;10422:2;10426:5;10380:53;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10353:19;:81::i;:::-;10252:190;;;;:::o;17136:738::-;17217:18;17246:19;17386:4;17383:1;17376:4;17370:11;17363:4;17357;17353:15;17350:1;17343:5;17336;17331:60;17445:7;17435:180;;17490:4;17484:11;17536:16;17533:1;17528:3;17513:40;17583:16;17578:3;17571:29;17435:180;17643:16;17629:30;;17694:1;17688:8;17673:23;;17301:406;17737:1;17723:10;:15;:68;;17790:1;17775:11;:16;;17723:68;;;17771:1;17749:5;17741:26;;;:31;17723:68;17719:148;;;17848:5;17815:40;;;;;;;;;;;:::i;:::-;;;;;;;;17719:148;17206:668;;17136:738;;:::o;23082:98::-;23135:7;23162:10;23155:17;;23082:98;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;88:117:1:-;197:1;194;187:12;334:126;371:7;411:42;404:5;400:54;389:65;;334:126;;;:::o;466:96::-;503:7;532:24;550:5;532:24;:::i;:::-;521:35;;466:96;;;:::o;568:122::-;641:24;659:5;641:24;:::i;:::-;634:5;631:35;621:63;;680:1;677;670:12;621:63;568:122;:::o;696:139::-;742:5;780:6;767:20;758:29;;796:33;823:5;796:33;:::i;:::-;696:139;;;;:::o;841:329::-;900:6;949:2;937:9;928:7;924:23;920:32;917:119;;;955:79;;:::i;:::-;917:119;1075:1;1100:53;1145:7;1136:6;1125:9;1121:22;1100:53;:::i;:::-;1090:63;;1046:117;841:329;;;;:::o;1176:114::-;1243:6;1277:5;1271:12;1261:22;;1176:114;;;:::o;1296:184::-;1395:11;1429:6;1424:3;1417:19;1469:4;1464:3;1460:14;1445:29;;1296:184;;;;:::o;1486:132::-;1553:4;1576:3;1568:11;;1606:4;1601:3;1597:14;1589:22;;1486:132;;;:::o;1624:77::-;1661:7;1690:5;1679:16;;1624:77;;;:::o;1707:108::-;1784:24;1802:5;1784:24;:::i;:::-;1779:3;1772:37;1707:108;;:::o;1821:179::-;1890:10;1911:46;1953:3;1945:6;1911:46;:::i;:::-;1989:4;1984:3;1980:14;1966:28;;1821:179;;;;:::o;2006:113::-;2076:4;2108;2103:3;2099:14;2091:22;;2006:113;;;:::o;2155:732::-;2274:3;2303:54;2351:5;2303:54;:::i;:::-;2373:86;2452:6;2447:3;2373:86;:::i;:::-;2366:93;;2483:56;2533:5;2483:56;:::i;:::-;2562:7;2593:1;2578:284;2603:6;2600:1;2597:13;2578:284;;;2679:6;2673:13;2706:63;2765:3;2750:13;2706:63;:::i;:::-;2699:70;;2792:60;2845:6;2792:60;:::i;:::-;2782:70;;2638:224;2625:1;2622;2618:9;2613:14;;2578:284;;;2582:14;2878:3;2871:10;;2279:608;;;2155:732;;;;:::o;2893:373::-;3036:4;3074:2;3063:9;3059:18;3051:26;;3123:9;3117:4;3113:20;3109:1;3098:9;3094:17;3087:47;3151:108;3254:4;3245:6;3151:108;:::i;:::-;3143:116;;2893:373;;;;:::o;3272:122::-;3345:24;3363:5;3345:24;:::i;:::-;3338:5;3335:35;3325:63;;3384:1;3381;3374:12;3325:63;3272:122;:::o;3400:139::-;3446:5;3484:6;3471:20;3462:29;;3500:33;3527:5;3500:33;:::i;:::-;3400:139;;;;:::o;3545:329::-;3604:6;3653:2;3641:9;3632:7;3628:23;3624:32;3621:119;;;3659:79;;:::i;:::-;3621:119;3779:1;3804:53;3849:7;3840:6;3829:9;3825:22;3804:53;:::i;:::-;3794:63;;3750:117;3545:329;;;;:::o;3880:118::-;3967:24;3985:5;3967:24;:::i;:::-;3962:3;3955:37;3880:118;;:::o;4004:222::-;4097:4;4135:2;4124:9;4120:18;4112:26;;4148:71;4216:1;4205:9;4201:17;4192:6;4148:71;:::i;:::-;4004:222;;;;:::o;4232:140::-;4325:6;4359:5;4353:12;4343:22;;4232:140;;;:::o;4378:210::-;4503:11;4537:6;4532:3;4525:19;4577:4;4572:3;4568:14;4553:29;;4378:210;;;;:::o;4594:158::-;4687:4;4710:3;4702:11;;4740:4;4735:3;4731:14;4723:22;;4594:158;;;:::o;4758:108::-;4835:24;4853:5;4835:24;:::i;:::-;4830:3;4823:37;4758:108;;:::o;4872:90::-;4906:7;4949:5;4942:13;4935:21;4924:32;;4872:90;;;:::o;4968:99::-;5039:21;5054:5;5039:21;:::i;:::-;5034:3;5027:34;4968:99;;:::o;5141:1202::-;5280:4;5275:3;5271:14;5365:4;5358:5;5354:16;5348:23;5384:63;5441:4;5436:3;5432:14;5418:12;5384:63;:::i;:::-;5295:162;5540:4;5533:5;5529:16;5523:23;5559:63;5616:4;5611:3;5607:14;5593:12;5559:63;:::i;:::-;5467:165;5715:4;5708:5;5704:16;5698:23;5734:63;5791:4;5786:3;5782:14;5768:12;5734:63;:::i;:::-;5642:165;5891:4;5884:5;5880:16;5874:23;5910:63;5967:4;5962:3;5958:14;5944:12;5910:63;:::i;:::-;5817:166;6071:4;6064:5;6060:16;6054:23;6090:63;6147:4;6142:3;6138:14;6124:12;6090:63;:::i;:::-;5993:170;6250:4;6243:5;6239:16;6233:23;6269:57;6320:4;6315:3;6311:14;6297:12;6269:57;:::i;:::-;6173:163;5249:1094;5141:1202;;:::o;6349:283::-;6470:10;6491:98;6585:3;6577:6;6491:98;:::i;:::-;6621:4;6616:3;6612:14;6598:28;;6349:283;;;;:::o;6638:139::-;6734:4;6766;6761:3;6757:14;6749:22;;6638:139;;;:::o;6855:940::-;7026:3;7055:80;7129:5;7055:80;:::i;:::-;7151:112;7256:6;7251:3;7151:112;:::i;:::-;7144:119;;7287:82;7363:5;7287:82;:::i;:::-;7392:7;7423:1;7408:362;7433:6;7430:1;7427:13;7408:362;;;7509:6;7503:13;7536:115;7647:3;7632:13;7536:115;:::i;:::-;7529:122;;7674:86;7753:6;7674:86;:::i;:::-;7664:96;;7468:302;7455:1;7452;7448:9;7443:14;;7408:362;;;7412:14;7786:3;7779:10;;7031:764;;;6855:940;;;;:::o;7801:477::-;7996:4;8034:2;8023:9;8019:18;8011:26;;8083:9;8077:4;8073:20;8069:1;8058:9;8054:17;8047:47;8111:160;8266:4;8257:6;8111:160;:::i;:::-;8103:168;;7801:477;;;;:::o;8284:118::-;8371:24;8389:5;8371:24;:::i;:::-;8366:3;8359:37;8284:118;;:::o;8408:222::-;8501:4;8539:2;8528:9;8524:18;8516:26;;8552:71;8620:1;8609:9;8605:17;8596:6;8552:71;:::i;:::-;8408:222;;;;:::o;8636:474::-;8704:6;8712;8761:2;8749:9;8740:7;8736:23;8732:32;8729:119;;;8767:79;;:::i;:::-;8729:119;8887:1;8912:53;8957:7;8948:6;8937:9;8933:22;8912:53;:::i;:::-;8902:63;;8858:117;9014:2;9040:53;9085:7;9076:6;9065:9;9061:22;9040:53;:::i;:::-;9030:63;;8985:118;8636:474;;;;;:::o;9116:619::-;9193:6;9201;9209;9258:2;9246:9;9237:7;9233:23;9229:32;9226:119;;;9264:79;;:::i;:::-;9226:119;9384:1;9409:53;9454:7;9445:6;9434:9;9430:22;9409:53;:::i;:::-;9399:63;;9355:117;9511:2;9537:53;9582:7;9573:6;9562:9;9558:22;9537:53;:::i;:::-;9527:63;;9482:118;9639:2;9665:53;9710:7;9701:6;9690:9;9686:22;9665:53;:::i;:::-;9655:63;;9610:118;9116:619;;;;;:::o;9741:474::-;9809:6;9817;9866:2;9854:9;9845:7;9841:23;9837:32;9834:119;;;9872:79;;:::i;:::-;9834:119;9992:1;10017:53;10062:7;10053:6;10042:9;10038:22;10017:53;:::i;:::-;10007:63;;9963:117;10119:2;10145:53;10190:7;10181:6;10170:9;10166:22;10145:53;:::i;:::-;10135:63;;10090:118;9741:474;;;;;:::o;10221:::-;10289:6;10297;10346:2;10334:9;10325:7;10321:23;10317:32;10314:119;;;10352:79;;:::i;:::-;10314:119;10472:1;10497:53;10542:7;10533:6;10522:9;10518:22;10497:53;:::i;:::-;10487:63;;10443:117;10599:2;10625:53;10670:7;10661:6;10650:9;10646:22;10625:53;:::i;:::-;10615:63;;10570:118;10221:474;;;;;:::o;10769:1212::-;10918:4;10913:3;10909:14;11003:4;10996:5;10992:16;10986:23;11022:63;11079:4;11074:3;11070:14;11056:12;11022:63;:::i;:::-;10933:162;11178:4;11171:5;11167:16;11161:23;11197:63;11254:4;11249:3;11245:14;11231:12;11197:63;:::i;:::-;11105:165;11353:4;11346:5;11342:16;11336:23;11372:63;11429:4;11424:3;11420:14;11406:12;11372:63;:::i;:::-;11280:165;11529:4;11522:5;11518:16;11512:23;11548:63;11605:4;11600:3;11596:14;11582:12;11548:63;:::i;:::-;11455:166;11709:4;11702:5;11698:16;11692:23;11728:63;11785:4;11780:3;11776:14;11762:12;11728:63;:::i;:::-;11631:170;11888:4;11881:5;11877:16;11871:23;11907:57;11958:4;11953:3;11949:14;11935:12;11907:57;:::i;:::-;11811:163;10887:1094;10769:1212;;:::o;11987:327::-;12132:4;12170:3;12159:9;12155:19;12147:27;;12184:123;12304:1;12293:9;12289:17;12280:6;12184:123;:::i;:::-;11987:327;;;;:::o;12320:109::-;12401:21;12416:5;12401:21;:::i;:::-;12396:3;12389:34;12320:109;;:::o;12435:763::-;12662:4;12700:3;12689:9;12685:19;12677:27;;12714:71;12782:1;12771:9;12767:17;12758:6;12714:71;:::i;:::-;12795:72;12863:2;12852:9;12848:18;12839:6;12795:72;:::i;:::-;12877;12945:2;12934:9;12930:18;12921:6;12877:72;:::i;:::-;12959;13027:2;13016:9;13012:18;13003:6;12959:72;:::i;:::-;13041:73;13109:3;13098:9;13094:19;13085:6;13041:73;:::i;:::-;13124:67;13186:3;13175:9;13171:19;13162:6;13124:67;:::i;:::-;12435:763;;;;;;;;;:::o;13204:169::-;13288:11;13322:6;13317:3;13310:19;13362:4;13357:3;13353:14;13338:29;;13204:169;;;;:::o;13379:178::-;13519:30;13515:1;13507:6;13503:14;13496:54;13379:178;:::o;13563:366::-;13705:3;13726:67;13790:2;13785:3;13726:67;:::i;:::-;13719:74;;13802:93;13891:3;13802:93;:::i;:::-;13920:2;13915:3;13911:12;13904:19;;13563:366;;;:::o;13935:419::-;14101:4;14139:2;14128:9;14124:18;14116:26;;14188:9;14182:4;14178:20;14174:1;14163:9;14159:17;14152:47;14216:131;14342:4;14216:131;:::i;:::-;14208:139;;13935:419;;;:::o;14360:223::-;14500:34;14496:1;14488:6;14484:14;14477:58;14569:6;14564:2;14556:6;14552:15;14545:31;14360:223;:::o;14589:366::-;14731:3;14752:67;14816:2;14811:3;14752:67;:::i;:::-;14745:74;;14828:93;14917:3;14828:93;:::i;:::-;14946:2;14941:3;14937:12;14930:19;;14589:366;;;:::o;14961:419::-;15127:4;15165:2;15154:9;15150:18;15142:26;;15214:9;15208:4;15204:20;15200:1;15189:9;15185:17;15178:47;15242:131;15368:4;15242:131;:::i;:::-;15234:139;;14961:419;;;:::o;15386:181::-;15526:33;15522:1;15514:6;15510:14;15503:57;15386:181;:::o;15573:366::-;15715:3;15736:67;15800:2;15795:3;15736:67;:::i;:::-;15729:74;;15812:93;15901:3;15812:93;:::i;:::-;15930:2;15925:3;15921:12;15914:19;;15573:366;;;:::o;15945:419::-;16111:4;16149:2;16138:9;16134:18;16126:26;;16198:9;16192:4;16188:20;16184:1;16173:9;16169:17;16162:47;16226:131;16352:4;16226:131;:::i;:::-;16218:139;;15945:419;;;:::o;16370:225::-;16510:34;16506:1;16498:6;16494:14;16487:58;16579:8;16574:2;16566:6;16562:15;16555:33;16370:225;:::o;16601:366::-;16743:3;16764:67;16828:2;16823:3;16764:67;:::i;:::-;16757:74;;16840:93;16929:3;16840:93;:::i;:::-;16958:2;16953:3;16949:12;16942:19;;16601:366;;;:::o;16973:419::-;17139:4;17177:2;17166:9;17162:18;17154:26;;17226:9;17220:4;17216:20;17212:1;17201:9;17197:17;17190:47;17254:131;17380:4;17254:131;:::i;:::-;17246:139;;16973:419;;;:::o;17398:147::-;17499:11;17536:3;17521:18;;17398:147;;;;:::o;17551:114::-;;:::o;17671:398::-;17830:3;17851:83;17932:1;17927:3;17851:83;:::i;:::-;17844:90;;17943:93;18032:3;17943:93;:::i;:::-;18061:1;18056:3;18052:11;18045:18;;17671:398;;;:::o;18075:379::-;18259:3;18281:147;18424:3;18281:147;:::i;:::-;18274:154;;18445:3;18438:10;;18075:379;;;:::o;18460:227::-;18600:34;18596:1;18588:6;18584:14;18577:58;18669:10;18664:2;18656:6;18652:15;18645:35;18460:227;:::o;18693:366::-;18835:3;18856:67;18920:2;18915:3;18856:67;:::i;:::-;18849:74;;18932:93;19021:3;18932:93;:::i;:::-;19050:2;19045:3;19041:12;19034:19;;18693:366;;;:::o;19065:419::-;19231:4;19269:2;19258:9;19254:18;19246:26;;19318:9;19312:4;19308:20;19304:1;19293:9;19289:17;19282:47;19346:131;19472:4;19346:131;:::i;:::-;19338:139;;19065:419;;;:::o;19490:332::-;19611:4;19649:2;19638:9;19634:18;19626:26;;19662:71;19730:1;19719:9;19715:17;19706:6;19662:71;:::i;:::-;19743:72;19811:2;19800:9;19796:18;19787:6;19743:72;:::i;:::-;19490:332;;;;;:::o;19828:::-;19949:4;19987:2;19976:9;19972:18;19964:26;;20000:71;20068:1;20057:9;20053:17;20044:6;20000:71;:::i;:::-;20081:72;20149:2;20138:9;20134:18;20125:6;20081:72;:::i;:::-;19828:332;;;;;:::o;20166:180::-;20214:77;20211:1;20204:88;20311:4;20308:1;20301:15;20335:4;20332:1;20325:15;20352:180;20400:77;20397:1;20390:88;20497:4;20494:1;20487:15;20521:4;20518:1;20511:15;20538:233;20577:3;20600:24;20618:5;20600:24;:::i;:::-;20591:33;;20646:66;20639:5;20636:77;20633:103;;20716:18;;:::i;:::-;20633:103;20763:1;20756:5;20752:13;20745:20;;20538:233;;;:::o;20777:180::-;20825:77;20822:1;20815:88;20922:4;20919:1;20912:15;20946:4;20943:1;20936:15;20963:239;21103:34;21099:1;21091:6;21087:14;21080:58;21172:22;21167:2;21159:6;21155:15;21148:47;20963:239;:::o;21208:366::-;21350:3;21371:67;21435:2;21430:3;21371:67;:::i;:::-;21364:74;;21447:93;21536:3;21447:93;:::i;:::-;21565:2;21560:3;21556:12;21549:19;;21208:366;;;:::o;21580:419::-;21746:4;21784:2;21773:9;21769:18;21761:26;;21833:9;21827:4;21823:20;21819:1;21808:9;21804:17;21797:47;21861:131;21987:4;21861:131;:::i;:::-;21853:139;;21580:419;;;:::o;22005:224::-;22145:34;22141:1;22133:6;22129:14;22122:58;22214:7;22209:2;22201:6;22197:15;22190:32;22005:224;:::o;22235:366::-;22377:3;22398:67;22462:2;22457:3;22398:67;:::i;:::-;22391:74;;22474:93;22563:3;22474:93;:::i;:::-;22592:2;22587:3;22583:12;22576:19;;22235:366;;;:::o;22607:419::-;22773:4;22811:2;22800:9;22796:18;22788:26;;22860:9;22854:4;22850:20;22846:1;22835:9;22831:17;22824:47;22888:131;23014:4;22888:131;:::i;:::-;22880:139;;22607:419;;;:::o;23032:226::-;23172:34;23168:1;23160:6;23156:14;23149:58;23241:9;23236:2;23228:6;23224:15;23217:34;23032:226;:::o;23264:366::-;23406:3;23427:67;23491:2;23486:3;23427:67;:::i;:::-;23420:74;;23503:93;23592:3;23503:93;:::i;:::-;23621:2;23616:3;23612:12;23605:19;;23264:366;;;:::o;23636:419::-;23802:4;23840:2;23829:9;23825:18;23817:26;;23889:9;23883:4;23879:20;23875:1;23864:9;23860:17;23853:47;23917:131;24043:4;23917:131;:::i;:::-;23909:139;;23636:419;;;:::o;24061:442::-;24210:4;24248:2;24237:9;24233:18;24225:26;;24261:71;24329:1;24318:9;24314:17;24305:6;24261:71;:::i;:::-;24342:72;24410:2;24399:9;24395:18;24386:6;24342:72;:::i;:::-;24424;24492:2;24481:9;24477:18;24468:6;24424:72;:::i;:::-;24061:442;;;;;;:::o;24509:191::-;24549:3;24568:20;24586:1;24568:20;:::i;:::-;24563:25;;24602:20;24620:1;24602:20;:::i;:::-;24597:25;;24645:1;24642;24638:9;24631:16;;24666:3;24663:1;24660:10;24657:36;;;24673:18;;:::i;:::-;24657:36;24509:191;;;;:::o;24706:230::-;24846:34;24842:1;24834:6;24830:14;24823:58;24915:13;24910:2;24902:6;24898:15;24891:38;24706:230;:::o;24942:366::-;25084:3;25105:67;25169:2;25164:3;25105:67;:::i;:::-;25098:74;;25181:93;25270:3;25181:93;:::i;:::-;25299:2;25294:3;25290:12;25283:19;;24942:366;;;:::o;25314:419::-;25480:4;25518:2;25507:9;25503:18;25495:26;;25567:9;25561:4;25557:20;25553:1;25542:9;25538:17;25531:47;25595:131;25721:4;25595:131;:::i;:::-;25587:139;;25314:419;;;:::o;25739:194::-;25779:4;25799:20;25817:1;25799:20;:::i;:::-;25794:25;;25833:20;25851:1;25833:20;:::i;:::-;25828:25;;25877:1;25874;25870:9;25862:17;;25901:1;25895:4;25892:11;25889:37;;;25906:18;;:::i;:::-;25889:37;25739:194;;;;:::o;25939:180::-;25987:77;25984:1;25977:88;26084:4;26081:1;26074:15;26108:4;26105:1;26098:15;26125:332;26246:4;26284:2;26273:9;26269:18;26261:26;;26297:71;26365:1;26354:9;26350:17;26341:6;26297:71;:::i;:::-;26378:72;26446:2;26435:9;26431:18;26422:6;26378:72;:::i;:::-;26125:332;;;;;:::o;26463:442::-;26612:4;26650:2;26639:9;26635:18;26627:26;;26663:71;26731:1;26720:9;26716:17;26707:6;26663:71;:::i;:::-;26744:72;26812:2;26801:9;26797:18;26788:6;26744:72;:::i;:::-;26826;26894:2;26883:9;26879:18;26870:6;26826:72;:::i;:::-;26463:442;;;;;;:::o
Swarm Source
ipfs://195cbae624cb6fbb7d9459878595263785c001d6efd582d7a46bbbdabe22506b
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.