Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 737 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer | 21341671 | 27 hrs ago | IN | 0 ETH | 0.00064286 | ||||
Transfer | 21335872 | 46 hrs ago | IN | 0 ETH | 0.00117835 | ||||
Transfer | 21329054 | 2 days ago | IN | 0 ETH | 0.00068732 | ||||
Transfer | 21328615 | 2 days ago | IN | 0 ETH | 0.00108653 | ||||
Approve | 21320337 | 4 days ago | IN | 0 ETH | 0.00109095 | ||||
Transfer | 21320317 | 4 days ago | IN | 0 ETH | 0.00093709 | ||||
Approve | 21320218 | 4 days ago | IN | 0 ETH | 0.00097181 | ||||
Approve | 21320049 | 4 days ago | IN | 0 ETH | 0.00080331 | ||||
Approve | 21308616 | 5 days ago | IN | 0 ETH | 0.00110855 | ||||
Approve | 21307269 | 5 days ago | IN | 0 ETH | 0.00022531 | ||||
Approve | 21305598 | 6 days ago | IN | 0 ETH | 0.0003761 | ||||
Approve | 21303218 | 6 days ago | IN | 0 ETH | 0.00039895 | ||||
Transfer | 21303091 | 6 days ago | IN | 0 ETH | 0.00063347 | ||||
Approve | 21300515 | 6 days ago | IN | 0 ETH | 0.00046852 | ||||
Transfer | 21297923 | 7 days ago | IN | 0 ETH | 0.00058996 | ||||
Approve | 21297864 | 7 days ago | IN | 0 ETH | 0.00040808 | ||||
Approve | 21294716 | 7 days ago | IN | 0 ETH | 0.00086253 | ||||
Approve | 21291457 | 8 days ago | IN | 0 ETH | 0.00039417 | ||||
Transfer | 21290260 | 8 days ago | IN | 0 ETH | 0.0005508 | ||||
Transfer | 21289942 | 8 days ago | IN | 0 ETH | 0.00034919 | ||||
Transfer | 21289796 | 8 days ago | IN | 0 ETH | 0.00022079 | ||||
Transfer | 21289458 | 8 days ago | IN | 0 ETH | 0.00039234 | ||||
Transfer | 21289389 | 8 days ago | IN | 0 ETH | 0.0004292 | ||||
Approve | 21286145 | 8 days ago | IN | 0 ETH | 0.00040236 | ||||
Approve | 21270882 | 11 days ago | IN | 0 ETH | 0.00058287 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
21344287 | 18 hrs ago | 0.00000144 ETH | ||||
21344287 | 18 hrs ago | 0.00000144 ETH | ||||
21337356 | 41 hrs ago | 0.00000144 ETH | ||||
21337356 | 41 hrs ago | 0.00000144 ETH | ||||
21337169 | 42 hrs ago | 0.00000144 ETH | ||||
21337169 | 42 hrs ago | 0.00000144 ETH | ||||
21337159 | 42 hrs ago | 0.00000144 ETH | ||||
21337159 | 42 hrs ago | 0.00000144 ETH | ||||
21337059 | 42 hrs ago | 0.00000144 ETH | ||||
21337059 | 42 hrs ago | 0.00000144 ETH | ||||
21336453 | 44 hrs ago | 0.00000144 ETH | ||||
21336453 | 44 hrs ago | 0.00000144 ETH | ||||
21334945 | 2 days ago | 0.00000144 ETH | ||||
21334945 | 2 days ago | 0.00000144 ETH | ||||
21334941 | 2 days ago | 0.00000144 ETH | ||||
21334941 | 2 days ago | 0.00000144 ETH | ||||
21334922 | 2 days ago | 0.00000144 ETH | ||||
21334922 | 2 days ago | 0.00000144 ETH | ||||
21334877 | 2 days ago | 0.00000144 ETH | ||||
21334877 | 2 days ago | 0.00000144 ETH | ||||
21333721 | 2 days ago | 0.00000144 ETH | ||||
21333721 | 2 days ago | 0.00000144 ETH | ||||
21333312 | 2 days ago | 0.00000144 ETH | ||||
21333312 | 2 days ago | 0.00000144 ETH | ||||
21333252 | 2 days ago | 0.00000144 ETH |
Loading...
Loading
Contract Name:
MORC20PermitToken
Compiler Version
v0.8.20+commit.a1b79de6
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import "../morc20/MORC20Token.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; contract MORC20PermitToken is MORC20Token, ERC20Permit { constructor( string memory _name, string memory _symbol, address _mosAddress, uint256 _initialSupply, address _owner ) MORC20Token(_name, _symbol, _mosAddress) ERC20Permit(_name) { _transferOwnership(_owner); _mint(_owner, _initialSupply); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; interface IMapoExecutor { function mapoExecute( uint256 _fromChain, uint256 _toChain, bytes calldata _fromAddress, bytes32 _orderId, bytes calldata _message ) external returns (bytes memory newMessage); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IMOSV3 { enum ChainType { NULL, EVM, NEAR } enum MessageType { CALLDATA, MESSAGE } // @notice This is the configuration you need across the chain. // @param relay - When it is true, the relay chain is required to perform a special execution to continue across the chain. // @param msgType - Different execution patterns of messages across chains. // @param target - The contract address of the target chain. // @param payload - Cross-chain data. // @param gasLimit - The gasLimit allowed to be consumed by an operation performed on the target chain. // @param value - Collateral value cross-chain, currently not supported, default is 0. struct MessageData { bool relay; MessageType msgType; bytes target; bytes payload; uint256 gasLimit; uint256 value; } // @notice Gets the fee to cross to the target chain. // @param toChain - Target chain chainID. // @param feeToken - Token address that supports payment fee,if it's native, it's address(0). // @param gasLimit - The gasLimit allowed to be consumed by an operation performed on the target chain. function getMessageFee( uint256 toChain, address feeToken, uint256 gasLimit ) external view returns (uint256, address); function getOrderStatus( uint256 _chainId, uint256 _blockNum, bytes32 _orderId ) external view returns (bool exists, bool verifiable, uint256 nodeType); // @notice Initiate cross-chain transactions. Generate cross-chain logs. // @param toChain - Target chain chainID. // @param messageData - Structure MessageData encoding. // @param feeToken - In what Token would you like to pay the fee. function transferOut( uint256 toChain, bytes memory messageData, address feeToken ) external payable returns (bytes32); // @notice Add remote address permission. // @param fromChain - The chain id of the source chain. // @param fromAddress - The call address of the source chain. // @param tag - Permission,false: revoke permission. function addRemoteCaller(uint256 fromChain, bytes memory fromAddress, bool tag) external; // @notice Query whether the contract has execution permission. // @param targetAddress - The target address. // @param fromChain - The chain id of the source chain. // @param fromAddress - The call address of the source chain. function getExecutePermission( address targetAddress, uint256 fromChain, bytes memory fromAddress ) external view returns (bool); event mapMessageOut( uint256 indexed fromChain, uint256 indexed toChain, bytes32 orderId, bytes fromAddrss, bytes callData ); event mapMessageIn( uint256 indexed fromChain, uint256 indexed toChain, bytes32 orderId, bytes fromAddrss, bytes callData, bool result, bytes reason ); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. 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; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @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 { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @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 { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol) pragma solidity ^0.8.0; interface IERC5267 { /** * @dev MAY be emitted to signal that the domain could have changed. */ event EIP712DomainChanged(); /** * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712 * signature. */ function eip712Domain() external view returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20.sol"; import "./extensions/IERC20Metadata.sol"; import "../../utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the default value returned by this function, unless * it's overridden. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer(address from, address to, uint256 amount) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. _balances[to] += amount; } emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _balances[account] += amount; } emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol) pragma solidity ^0.8.0; import "../ERC20.sol"; import "../../../utils/Context.sol"; /** * @dev Extension of {ERC20} that allows token holders to destroy both their own * tokens and those that they have an allowance for, in a way that can be * recognized off-chain (via event analysis). */ abstract contract ERC20Burnable is Context, ERC20 { /** * @dev Destroys `amount` tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 amount) public virtual { _burn(_msgSender(), amount); } /** * @dev Destroys `amount` tokens from `account`, deducting from the caller's * allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `amount`. */ function burnFrom(address account, uint256 amount) public virtual { _spendAllowance(account, _msgSender(), amount); _burn(account, amount); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Capped.sol) pragma solidity ^0.8.0; import "../ERC20.sol"; /** * @dev Extension of {ERC20} that adds a cap to the supply of tokens. */ abstract contract ERC20Capped is ERC20 { uint256 private immutable _cap; /** * @dev Sets the value of the `cap`. This value is immutable, it can only be * set once during construction. */ constructor(uint256 cap_) { require(cap_ > 0, "ERC20Capped: cap is 0"); _cap = cap_; } /** * @dev Returns the cap on the token's total supply. */ function cap() public view virtual returns (uint256) { return _cap; } /** * @dev See {ERC20-_mint}. */ function _mint(address account, uint256 amount) internal virtual override { require(ERC20.totalSupply() + amount <= cap(), "ERC20Capped: cap exceeded"); super._mint(account, amount); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/ERC20Permit.sol) pragma solidity ^0.8.0; import "./IERC20Permit.sol"; import "../ERC20.sol"; import "../../../utils/cryptography/ECDSA.sol"; import "../../../utils/cryptography/EIP712.sol"; import "../../../utils/Counters.sol"; /** * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * _Available since v3.4._ */ abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 { using Counters for Counters.Counter; mapping(address => Counters.Counter) private _nonces; // solhint-disable-next-line var-name-mixedcase bytes32 private constant _PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); /** * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`. * However, to ensure consistency with the upgradeable transpiler, we will continue * to reserve a slot. * @custom:oz-renamed-from _PERMIT_TYPEHASH */ // solhint-disable-next-line var-name-mixedcase bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT; /** * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`. * * It's a good idea to use the same `name` that is defined as the ERC20 token name. */ constructor(string memory name) EIP712(name, "1") {} /** * @inheritdoc IERC20Permit */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual override { require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)); bytes32 hash = _hashTypedDataV4(structHash); address signer = ECDSA.recover(hash, v, r, s); require(signer == owner, "ERC20Permit: invalid signature"); _approve(owner, spender, value); } /** * @inheritdoc IERC20Permit */ function nonces(address owner) public view virtual override returns (uint256) { return _nonces[owner].current(); } /** * @inheritdoc IERC20Permit */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view override returns (bytes32) { return _domainSeparatorV4(); } /** * @dev "Consume a nonce": return the current value and increment. * * _Available since v4.1._ */ function _useNonce(address owner) internal virtual returns (uint256 current) { Counters.Counter storage nonce = _nonces[owner]; current = nonce.current(); nonce.increment(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @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.encodeWithSelector(token.transfer.selector, 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.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @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. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @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 silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol) pragma solidity ^0.8.8; import "./ECDSA.sol"; import "../ShortStrings.sol"; import "../../interfaces/IERC5267.sol"; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the * separator from the immutable values, which is cheaper than accessing a cached version in cold storage. * * _Available since v3.4._ * * @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment */ abstract contract EIP712 is IERC5267 { using ShortStrings for *; bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private immutable _cachedDomainSeparator; uint256 private immutable _cachedChainId; address private immutable _cachedThis; bytes32 private immutable _hashedName; bytes32 private immutable _hashedVersion; ShortString private immutable _name; ShortString private immutable _version; string private _nameFallback; string private _versionFallback; /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) { _name = name.toShortStringWithFallback(_nameFallback); _version = version.toShortStringWithFallback(_versionFallback); _hashedName = keccak256(bytes(name)); _hashedVersion = keccak256(bytes(version)); _cachedChainId = block.chainid; _cachedDomainSeparator = _buildDomainSeparator(); _cachedThis = address(this); } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _cachedThis && block.chainid == _cachedChainId) { return _cachedDomainSeparator; } else { return _buildDomainSeparator(); } } function _buildDomainSeparator() private view returns (bytes32) { return keccak256(abi.encode(_TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev See {EIP-5267}. * * _Available since v4.9._ */ function eip712Domain() public view virtual override returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ) { return ( hex"0f", // 01111 _name.toStringWithFallback(_nameFallback), _version.toStringWithFallback(_versionFallback), block.chainid, address(this), bytes32(0), new uint256[](0) ); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * 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[EIP 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/ShortStrings.sol) pragma solidity ^0.8.8; import "./StorageSlot.sol"; // | string | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | // | length | 0x BB | type ShortString is bytes32; /** * @dev This library provides functions to convert short memory strings * into a `ShortString` type that can be used as an immutable variable. * * Strings of arbitrary length can be optimized using this library if * they are short enough (up to 31 bytes) by packing them with their * length (1 byte) in a single EVM word (32 bytes). Additionally, a * fallback mechanism can be used for every other case. * * Usage example: * * ```solidity * contract Named { * using ShortStrings for *; * * ShortString private immutable _name; * string private _nameFallback; * * constructor(string memory contractName) { * _name = contractName.toShortStringWithFallback(_nameFallback); * } * * function name() external view returns (string memory) { * return _name.toStringWithFallback(_nameFallback); * } * } * ``` */ library ShortStrings { // Used as an identifier for strings longer than 31 bytes. bytes32 private constant _FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF; error StringTooLong(string str); error InvalidShortString(); /** * @dev Encode a string of at most 31 chars into a `ShortString`. * * This will trigger a `StringTooLong` error is the input string is too long. */ function toShortString(string memory str) internal pure returns (ShortString) { bytes memory bstr = bytes(str); if (bstr.length > 31) { revert StringTooLong(str); } return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length)); } /** * @dev Decode a `ShortString` back to a "normal" string. */ function toString(ShortString sstr) internal pure returns (string memory) { uint256 len = byteLength(sstr); // using `new string(len)` would work locally but is not memory safe. string memory str = new string(32); /// @solidity memory-safe-assembly assembly { mstore(str, len) mstore(add(str, 0x20), sstr) } return str; } /** * @dev Return the length of a `ShortString`. */ function byteLength(ShortString sstr) internal pure returns (uint256) { uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF; if (result > 31) { revert InvalidShortString(); } return result; } /** * @dev Encode a string into a `ShortString`, or write it to storage if it is too long. */ function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) { if (bytes(value).length < 32) { return toShortString(value); } else { StorageSlot.getStringSlot(store).value = value; return ShortString.wrap(_FALLBACK_SENTINEL); } } /** * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}. */ function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) { if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) { return toString(value); } else { return store; } } /** * @dev Return the length of a string that was encoded to `ShortString` or written to storage using {setWithFallback}. * * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of * actual characters as the UTF-8 encoding of a single character can span over multiple bytes. */ function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) { if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) { return byteLength(value); } else { return bytes(store).length; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@mapprotocol/mos/contracts/interface/IMOSV3.sol"; import "@mapprotocol/mos/contracts/interface/IMapoExecutor.sol"; import "../lib/Helper.sol"; abstract contract MapoExecutor is Ownable, IMapoExecutor { uint256 public constant MESSAGE_TYPE_MESSAGE = 0; uint256 public constant MESSAGE_TYPE_CALL_DATA = 1; uint256 public constant gasLimitMin = 21000; uint256 public constant gasLimitMax = 10000000; IMOSV3 public mos; address public feeToken; mapping(uint256 => bytes) public trustedList; event SetTrustedAddress(uint256 indexed toChainId, bytes toAddress); event SetFeeToken(address indexed feeToken); event SetMosAddress(address indexed mos); constructor(address _mosAddress) { require(_mosAddress != address(0), "MapoExecutor: invalid mos address"); mos = IMOSV3(_mosAddress); } function mapoExecute( uint256 _fromChain, uint256 _toChain, bytes calldata _fromAddress, bytes32 _orderId, bytes calldata _message ) external virtual override returns (bytes memory newMessage) { require(_msgSender() == address(mos), "MapoExecutor: invalid mos caller"); bytes memory tempFromAddress = trustedList[_fromChain]; require( _fromAddress.length == tempFromAddress.length && tempFromAddress.length > 0 && keccak256(_fromAddress) == keccak256(tempFromAddress), "MapoExecutor: invalid source chain address" ); newMessage = _execute(_fromChain, _toChain, _fromAddress, _orderId, _message); } function _execute( uint256 _fromChain, uint256 _toChain, bytes memory _fromAddress, bytes32 _orderId, bytes memory _message ) internal virtual returns (bytes memory); function _mosTransferOut( uint256 _toChain, uint256 _toType, bytes memory _payload, uint256 _gasLimit ) internal virtual returns (bytes32) { bytes memory toAddress = trustedList[_toChain]; require(toAddress.length > 0, "MapoExecutor: invalid remote trust address"); bytes memory messageDataBytes; if (_toType == MESSAGE_TYPE_MESSAGE) { messageDataBytes = abi.encode(false, IMOSV3.MessageType.MESSAGE, toAddress, _payload, _gasLimit, 0); } else if (_toType == MESSAGE_TYPE_CALL_DATA) { messageDataBytes = abi.encode(false, IMOSV3.MessageType.CALLDATA, toAddress, _payload, _gasLimit, 0); } else { require(false, "MapoExecutor: invalid message type"); } (address token, uint256 fee) = _getMessageFee(_toChain, _gasLimit); require(fee > 0, "MapoExecutor: invalid fee value"); if (token == address(0)) { require(msg.value >= fee, "MapoExecutor: invalid fee"); } else { SafeERC20.safeTransferFrom(IERC20(token), msg.sender, address(this), fee); SafeERC20.safeApprove(IERC20(token), address(mos), fee); } return mos.transferOut{value: msg.value}(_toChain, messageDataBytes, token); } function _getMessageFee(uint256 _toChain, uint256 _gasLimit) internal view returns (address token, uint256 amount) { (uint256 fee, ) = mos.getMessageFee(_toChain, feeToken, _gasLimit); return (feeToken, fee); } function getTrustedAddress(uint256 _remoteChainId) external view returns (bytes memory) { return trustedList[_remoteChainId]; } function setTrustedAddress( uint256[] calldata _remoteChainIds, bytes[] calldata _remoteAddresses ) external onlyOwner { require(_remoteChainIds.length == _remoteAddresses.length, "MapoExecutor: address or chainId not match"); for (uint256 i = 0; i < _remoteChainIds.length; i++) { trustedList[_remoteChainIds[i]] = _remoteAddresses[i]; emit SetTrustedAddress(_remoteChainIds[i], _remoteAddresses[i]); } } function setFeeToken(address _feeToken) external onlyOwner { require(_feeToken != address(0), "MapoExecutor: invalid fee token"); feeToken = _feeToken; emit SetFeeToken(_feeToken); } function setMosAddress(address _mos) external onlyOwner { require(_mos != address(0), "MapoExecutor: invalid mos address"); mos = IMOSV3(_mos); emit SetMosAddress(_mos); } function rescueFunds(address _token, uint256 _amount) external onlyOwner { Helper._transfer(_token, msg.sender, _amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../morc20/MORC20Token.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol"; contract MORC20Capped is MORC20Token, ERC20Capped { constructor( string memory _name, string memory _symbol, uint256 _cappded, address _mosAddress ) MORC20Token(_name, _symbol, _mosAddress) ERC20Capped(_cappded) {} function _mint(address account, uint amount) internal virtual override(ERC20, ERC20Capped) { ERC20Capped._mint(account, amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../morc20/MORC20Token.sol"; import "@openzeppelin/contracts/security/Pausable.sol"; contract MORC20Pausable is MORC20Token, Pausable { constructor( string memory _name, string memory _symbol, address _mosAddress ) MORC20Token(_name, _symbol, _mosAddress) {} function interTransfer( address _fromAddress, uint256 _toChainId, bytes memory _toAddress, uint256 _fromAmount, uint256 _gasLimit ) external payable virtual override whenNotPaused { return _interTransfer(_fromAddress, _toChainId, _toAddress, _fromAmount, _gasLimit); } function interTransferAndCall( address _fromAddress, uint256 _toChainId, bytes memory _toAddress, uint256 _fromAmount, uint256 _gasLimit, bytes memory _refundAddress, bytes memory _messageData ) external payable virtual override whenNotPaused { _interTransferAndCall( _fromAddress, _toChainId, _toAddress, _fromAmount, _gasLimit, _refundAddress, _messageData ); } function pauseSendTokens(bool pause) external onlyOwner { pause ? _pause() : _unpause(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; /** * @dev Interface of the IMORC20 core standard */ interface IMORC20 is IERC165 { event InterTransfer( bytes32 indexed orderId, address indexed fromAddress, uint256 indexed toChainId, bytes toAddress, uint256 fromAmount ); event InterTransferAndCall( bytes32 indexed orderId, address indexed fromAddress, uint256 indexed toChainId, bytes toAddress, uint256 fromAmount, bytes payLoad ); event InterReceive( bytes32 indexed orderId, uint256 indexed fromChain, bytes fromAddress, address toAddress, uint256 amount ); event InterReceiveAndExecute( bytes32 indexed orderId, uint256 indexed fromchain, bytes srcAddress, address toAddress, bool result, bytes reason ); /** * estimate interchain transfer fee */ function estimateFee(uint256 toChain, uint256 gasLimit) external view returns (address feeToken, uint256 fee); /** * returns the circulating supply on current chain */ function currentChainSupply() external view returns (uint); /** * returns the address of the ERC20 token */ function token() external view returns (address); function interTransfer( address _fromAddress, uint256 _toChainId, bytes memory _toAddress, uint256 _fromAmount, uint256 _gasLimit ) external payable; function interTransferAndCall( address _fromAddress, uint256 _toChainId, bytes memory _toAddress, uint256 _fromAmount, uint256 _gasLimit, bytes memory _refundAddress, bytes memory _messageData ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IMORC20Receiver { function onMORC20Received( uint256 _fromChainId, bytes memory _fromAddress, uint256 _amount, bytes32 _orderId, bytes calldata _message ) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity >=0.7.6; library ExcessivelySafeCall { uint256 constant LOW_28_MASK = 0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff; /// @notice Use when you _really_ really _really_ don't trust the called /// contract. This prevents the called contract from causing reversion of /// the caller in as many ways as we can. /// @dev The main difference between this and a solidity low-level call is /// that we limit the number of bytes that the callee can cause to be /// copied to caller memory. This prevents stupid things like malicious /// contracts returning 10,000,000 bytes causing a local OOG when copying /// to memory. /// @param _target The address to call /// @param _gas The amount of gas to forward to the remote contract /// @param _maxCopy The maximum number of bytes of returndata to copy /// to memory. /// @param _calldata The data to send to the remote contract /// @return success and returndata, as `.call()`. Returndata is capped to /// `_maxCopy` bytes. function excessivelySafeCall( address _target, uint256 _gas, uint16 _maxCopy, bytes memory _calldata ) internal returns (bool, bytes memory) { // set up for assembly call uint256 _toCopy; bool _success; bytes memory _returnData = new bytes(_maxCopy); // dispatch message to recipient // by assembly calling "handle" function // we call via assembly to avoid memcopying a very large returndata // returned by a malicious contract assembly { _success := call( _gas, // gas _target, // recipient 0, // ether value add(_calldata, 0x20), // inloc mload(_calldata), // inlen 0, // outloc 0 // outlen ) // limit our copy to 256 bytes _toCopy := returndatasize() if gt(_toCopy, _maxCopy) { _toCopy := _maxCopy } // Store the length of the copied bytes mstore(_returnData, _toCopy) // copy the bytes from returndata[0:_toCopy] returndatacopy(add(_returnData, 0x20), 0, _toCopy) } return (_success, _returnData); } /// @notice Use when you _really_ really _really_ don't trust the called /// contract. This prevents the called contract from causing reversion of /// the caller in as many ways as we can. /// @dev The main difference between this and a solidity low-level call is /// that we limit the number of bytes that the callee can cause to be /// copied to caller memory. This prevents stupid things like malicious /// contracts returning 10,000,000 bytes causing a local OOG when copying /// to memory. /// @param _target The address to call /// @param _gas The amount of gas to forward to the remote contract /// @param _maxCopy The maximum number of bytes of returndata to copy /// to memory. /// @param _calldata The data to send to the remote contract /// @return success and returndata, as `.call()`. Returndata is capped to /// `_maxCopy` bytes. function excessivelySafeStaticCall( address _target, uint256 _gas, uint16 _maxCopy, bytes memory _calldata ) internal view returns (bool, bytes memory) { // set up for assembly call uint256 _toCopy; bool _success; bytes memory _returnData = new bytes(_maxCopy); // dispatch message to recipient // by assembly calling "handle" function // we call via assembly to avoid memcopying a very large returndata // returned by a malicious contract assembly { _success := staticcall( _gas, // gas _target, // recipient add(_calldata, 0x20), // inloc mload(_calldata), // inlen 0, // outloc 0 // outlen ) // limit our copy to 256 bytes _toCopy := returndatasize() if gt(_toCopy, _maxCopy) { _toCopy := _maxCopy } // Store the length of the copied bytes mstore(_returnData, _toCopy) // copy the bytes from returndata[0:_toCopy] returndatacopy(add(_returnData, 0x20), 0, _toCopy) } return (_success, _returnData); } /** * @notice Swaps function selectors in encoded contract calls * @dev Allows reuse of encoded calldata for functions with identical * argument types but different names. It simply swaps out the first 4 bytes * for the new selector. This function modifies memory in place, and should * only be used with caution. * @param _newSelector The new 4-byte selector * @param _buf The encoded contract args */ function swapSelector(bytes4 _newSelector, bytes memory _buf) internal pure { require(_buf.length >= 4); uint256 _mask = LOW_28_MASK; assembly { // load the first word of let _word := mload(add(_buf, 0x20)) // mask out the top 4 bytes // /x _word := and(_word, _mask) _word := or(_newSelector, _word) mstore(add(_buf, 0x20), _word) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; library Helper { using SafeERC20 for IERC20; address internal constant ZERO_ADDRESS = address(0); address internal constant NATIVE_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; function _isNative(address token) internal pure returns (bool) { return (token == ZERO_ADDRESS || token == NATIVE_ADDRESS); } function _getBalance(address _token, address _account) internal view returns (uint256) { if (_isNative(_token)) { return _account.balance; } else { return IERC20(_token).balanceOf(_account); } } function _transfer(address _token, address _to, uint256 _amount) internal { if (_isNative(_token)) { Address.sendValue(payable(_to), _amount); } else { IERC20(_token).safeTransfer(_to, _amount); } } function _safeWithdraw(address _wToken, uint _value) internal returns (bool) { (bool success, bytes memory data) = _wToken.call(abi.encodeWithSelector(0x2e1a7d4d, _value)); return (success && (data.length == 0 || abi.decode(data, (bool)))); } function _fromBytes(bytes memory bys) internal pure returns (address addr) { assembly { addr := mload(add(bys, 20)) } } function _toBytes(address self) internal pure returns (bytes memory b) { b = abi.encodePacked(self); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "../interfaces/IMORC20.sol"; import "../interfaces/IMORC20Receiver.sol"; import "../executor/MapoExecutor.sol"; import "../lib/ExcessivelySafeCall.sol"; import "../lib/Helper.sol"; abstract contract MORC20Core is MapoExecutor, ERC165, IMORC20 { using ExcessivelySafeCall for address; using SafeERC20 for IERC20; using Address for address; bytes32 public constant INTERCHAIN_TRANSFER = keccak256("InterTransfer(bytes32,bytes)"); bytes32 public constant INTERCHAIN_TRANSFER_AND_CALL = keccak256("InterTransferAndCall(bytes32,bytes)"); bytes public constant NOT_CONTRACT_ADDRESS = "0x4e4f545f434f4e54524143545f41444452455353"; mapping(bytes32 => bool) public orderList; constructor(address _mosAddress) MapoExecutor(_mosAddress) {} function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IMORC20).interfaceId || super.supportsInterface(interfaceId); } function estimateFee( uint256 _toChain, uint256 _gasLimit ) external view virtual override returns (address feeToken, uint256 fee) { return _getMessageFee(_toChain, _gasLimit); } function interTransfer( address _fromAddress, uint256 _toChainId, bytes memory _toAddress, uint256 _fromAmount, uint256 _gasLimit ) external payable virtual override { _interTransfer(_fromAddress, _toChainId, _toAddress, _fromAmount, _gasLimit); } function interTransferAndCall( address _fromAddress, uint256 _toChainId, bytes memory _toAddress, uint256 _fromAmount, uint256 _gasLimit, bytes memory _refundAddress, bytes memory _messageData ) external payable virtual override { _interTransferAndCall( _fromAddress, _toChainId, _toAddress, _fromAmount, _gasLimit, _refundAddress, _messageData ); } function _interTransfer( address _fromAddress, uint256 _toChainId, bytes memory _toAddress, uint256 _fromAmount, uint256 _gasLimit ) internal virtual { (uint256 amount, uint256 decimals) = _destroyTokenFrom(_fromAddress, _toChainId, _toAddress, _fromAmount); require(amount > 0, "MORC20Core: amount too small"); bytes memory fromAddress = Helper._toBytes(_fromAddress); bytes memory prePayload = abi.encode(fromAddress, _toAddress, amount, decimals); bytes memory payload = abi.encode(INTERCHAIN_TRANSFER, prePayload); bytes32 orderId = _mosTransferOut(_toChainId, MESSAGE_TYPE_MESSAGE, payload, _gasLimit); emit InterTransfer(orderId, _fromAddress, _toChainId, _toAddress, _fromAmount); } function _interTransferAndCall( address _fromAddress, uint256 _toChainId, bytes memory _toAddress, uint256 _fromAmount, uint256 _gasLimit, bytes memory _refundAddress, bytes memory _messageData ) internal virtual { (uint256 amount, uint256 decimals) = _destroyTokenFrom(_fromAddress, _toChainId, _toAddress, _fromAmount); // amount returned should not have dust require(amount > 0, "MORC20Core: amount too small"); bytes memory fromAddress = Helper._toBytes(_fromAddress); bytes memory prePayload = abi.encode(fromAddress, _toAddress, amount, decimals, _refundAddress, _messageData); bytes memory payload = abi.encode(INTERCHAIN_TRANSFER_AND_CALL, prePayload); bytes32 orderId = _mosTransferOut(_toChainId, MESSAGE_TYPE_MESSAGE, payload, _gasLimit); emit InterTransferAndCall(orderId, _fromAddress, _toChainId, _toAddress, _fromAmount, prePayload); } function _interReceive(uint256 _fromChain, bytes32 _orderId, bytes memory _payload) internal virtual { (bytes memory fromBytes, bytes memory receiverBytes, uint256 amount, uint256 decimals) = abi.decode( _payload, (bytes, bytes, uint256, uint256) ); address receiverAddress = Helper._fromBytes(receiverBytes); _createTokenTo(receiverAddress, _fromChain, amount, decimals); emit InterReceive(_orderId, _fromChain, fromBytes, receiverAddress, amount); } function callOnMORC20Received( uint256 _fromChainId, bytes memory _fromAddress, uint256 _amount, address _receiverAddress, bytes32 _orderId, bytes calldata _message ) public virtual { require(_msgSender() == address(this), "MORC20Core: caller must be MORC20Core"); // send uint256 amount = _transferFrom(address(this), _receiverAddress, _amount); emit InterReceive(_orderId, _fromChainId, _fromAddress, _receiverAddress, amount); // call // todo: check the gas for call bool success = IMORC20Receiver(_receiverAddress).onMORC20Received{gas: gasleft()}( _fromChainId, _fromAddress, _amount, _orderId, _message ); require(success, "MORC20Core: callOnMORC20Received fail"); } function _interReceiveAndExecute(uint256 _fromChain, bytes32 _orderId, bytes memory _payload) internal virtual { ( bytes memory srcAddress, bytes memory receiverBytes, uint256 amount, uint256 decimals, bytes memory refundBytes, bytes memory messageData ) = abi.decode(_payload, (bytes, bytes, uint256, uint256, bytes, bytes)); address receiverAddress = Helper._fromBytes(receiverBytes); (uint256 amount_, ) = _createTokenTo(address(this), _fromChain, amount, decimals); if (!receiverAddress.isContract()) { _transferFrom(address(this), Helper._fromBytes(refundBytes), amount_); emit InterReceive(_orderId, _fromChain, srcAddress, Helper._fromBytes(refundBytes), amount_); emit InterReceiveAndExecute(_orderId, _fromChain, srcAddress, receiverAddress, false, NOT_CONTRACT_ADDRESS); return; } bytes memory callOnMORC20ReceivedSelector = abi.encodeWithSelector( this.callOnMORC20Received.selector, _fromChain, srcAddress, amount_, receiverAddress, _orderId, messageData ); (bool success, bytes memory reason) = address(this).excessivelySafeCall( gasleft(), 150, callOnMORC20ReceivedSelector ); if (success) { emit InterReceiveAndExecute(_orderId, _fromChain, srcAddress, receiverAddress, true, bytes("")); } else { _transferFrom(address(this), Helper._fromBytes(refundBytes), amount_); emit InterReceive(_orderId, _fromChain, srcAddress, Helper._fromBytes(refundBytes), amount_); emit InterReceiveAndExecute(_orderId, _fromChain, srcAddress, receiverAddress, false, reason); } } function _execute( uint256 _fromChain, uint256, bytes memory, bytes32 _orderId, bytes memory _message ) internal virtual override returns (bytes memory) { require(!orderList[_orderId], "MORC20Core: invalid orderId"); (bytes32 interType, bytes memory payload) = abi.decode(_message, (bytes32, bytes)); orderList[_orderId] = true; if (interType == INTERCHAIN_TRANSFER) { _interReceive(_fromChain, _orderId, payload); } else if (interType == INTERCHAIN_TRANSFER_AND_CALL) { _interReceiveAndExecute(_fromChain, _orderId, payload); } else { revert("MORC20Core: unknown message type"); } return payload; } // burn or lock omnichain token function _destroyTokenFrom( address _fromAddress, uint256 _toChainId, bytes memory _toAddress, uint256 _fromAmount ) internal virtual returns (uint256 amount, uint256 decimals); // mint or unlock omnichain token function _createTokenTo( address _receiverAddress, uint256 _fromChainId, uint256 _amount, uint256 _decimals ) internal virtual returns (uint256 amount, uint256 decimals); function _transferFrom(address _from, address _to, uint256 _amount) internal virtual returns (uint256); function currentChainSupply() public view virtual override returns (uint); function token() public view virtual override returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "./MORC20Core.sol"; contract MORC20Token is MORC20Core, ERC20 { uint256 public tokenDecimals; constructor( string memory _name, string memory _symbol, address _mosAddress ) ERC20(_name, _symbol) MORC20Core(_mosAddress) { tokenDecimals = uint256(decimals()); } function currentChainSupply() public view virtual override returns (uint) { return totalSupply(); } function token() public view virtual override returns (address) { return address(this); } function _destroyTokenFrom( address _fromAddress, uint256, bytes memory, uint256 _fromAmount ) internal virtual override returns (uint256 amount, uint256 decimals) { address spender = _msgSender(); if (_fromAddress != spender) { _spendAllowance(_fromAddress, spender, _fromAmount); } _burn(_fromAddress, _fromAmount); return (_fromAmount, tokenDecimals); } function _createTokenTo( address _receiverAddress, uint256, uint256 _fromAmount, uint256 _fromDecimals ) internal virtual override returns (uint256 amount, uint256 decimals) { if (tokenDecimals == _fromDecimals) { amount = _fromAmount; } else { amount = (_fromAmount * 10 ** tokenDecimals) / 10 ** _fromDecimals; } _mint(_receiverAddress, amount); return (amount, tokenDecimals); } function _transferFrom(address _from, address _to, uint256 _amount) internal virtual override returns (uint256) { address spender = _msgSender(); // if transfer from this contract, no need to check allowance if (_from != address(this) && _from != spender) { _spendAllowance(_from, spender, _amount); } _transfer(_from, _to, _amount); return _amount; } }
{ "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "london", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "metadata": { "useLiteralContent": true } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_mosAddress","type":"address"},{"internalType":"uint256","name":"_initialSupply","type":"uint256"},{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orderId","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"fromChain","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"fromAddress","type":"bytes"},{"indexed":false,"internalType":"address","name":"toAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"InterReceive","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orderId","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"fromchain","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"srcAddress","type":"bytes"},{"indexed":false,"internalType":"address","name":"toAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"result","type":"bool"},{"indexed":false,"internalType":"bytes","name":"reason","type":"bytes"}],"name":"InterReceiveAndExecute","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orderId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"fromAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"toChainId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"toAddress","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"fromAmount","type":"uint256"}],"name":"InterTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orderId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"fromAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"toChainId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"toAddress","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"fromAmount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"payLoad","type":"bytes"}],"name":"InterTransferAndCall","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"feeToken","type":"address"}],"name":"SetFeeToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"mos","type":"address"}],"name":"SetMosAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"toChainId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"toAddress","type":"bytes"}],"name":"SetTrustedAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INTERCHAIN_TRANSFER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INTERCHAIN_TRANSFER_AND_CALL","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MESSAGE_TYPE_CALL_DATA","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MESSAGE_TYPE_MESSAGE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NOT_CONTRACT_ADDRESS","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fromChainId","type":"uint256"},{"internalType":"bytes","name":"_fromAddress","type":"bytes"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_receiverAddress","type":"address"},{"internalType":"bytes32","name":"_orderId","type":"bytes32"},{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"callOnMORC20Received","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentChainSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_toChain","type":"uint256"},{"internalType":"uint256","name":"_gasLimit","type":"uint256"}],"name":"estimateFee","outputs":[{"internalType":"address","name":"feeToken","type":"address"},{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gasLimitMax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gasLimitMin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_remoteChainId","type":"uint256"}],"name":"getTrustedAddress","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fromAddress","type":"address"},{"internalType":"uint256","name":"_toChainId","type":"uint256"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256","name":"_fromAmount","type":"uint256"},{"internalType":"uint256","name":"_gasLimit","type":"uint256"}],"name":"interTransfer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_fromAddress","type":"address"},{"internalType":"uint256","name":"_toChainId","type":"uint256"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256","name":"_fromAmount","type":"uint256"},{"internalType":"uint256","name":"_gasLimit","type":"uint256"},{"internalType":"bytes","name":"_refundAddress","type":"bytes"},{"internalType":"bytes","name":"_messageData","type":"bytes"}],"name":"interTransferAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fromChain","type":"uint256"},{"internalType":"uint256","name":"_toChain","type":"uint256"},{"internalType":"bytes","name":"_fromAddress","type":"bytes"},{"internalType":"bytes32","name":"_orderId","type":"bytes32"},{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"mapoExecute","outputs":[{"internalType":"bytes","name":"newMessage","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mos","outputs":[{"internalType":"contract IMOSV3","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"orderList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"rescueFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeToken","type":"address"}],"name":"setFeeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_mos","type":"address"}],"name":"setMosAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_remoteChainIds","type":"uint256[]"},{"internalType":"bytes[]","name":"_remoteAddresses","type":"bytes[]"}],"name":"setTrustedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"trustedList","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101606040523480156200001257600080fd5b50604051620047473803806200474783398101604081905262000035916200048a565b8480604051806040016040528060018152602001603160f81b81525087878782828280620000726200006c6200020660201b60201c565b6200020a565b6001600160a01b038116620000d85760405162461bcd60e51b815260206004820152602160248201527f4d61706f4578656375746f723a20696e76616c6964206d6f73206164647265736044820152607360f81b60648201526084015b60405180910390fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055506008620001078382620005b1565b506009620001168282620005b1565b5062000123915050601290565b60ff16600a55506200013b9150839050600b6200025a565b610120526200014c81600c6200025a565b61014052815160208084019190912060e052815190820120610100524660a052620001da60e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c05250620001ef816200020a565b620001fb818362000293565b5050505050620006f9565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006020835110156200027a57620002728362000358565b90506200028d565b81620002878482620005b1565b5060ff90505b92915050565b6001600160a01b038216620002eb5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401620000cf565b8060076000828254620002ff91906200067d565b90915550506001600160a01b0382166000818152600560209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600080829050601f8151111562000386578260405163305a27a960e01b8152600401620000cf91906200069f565b80516200039382620006d4565b179392505050565b505050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620003d3578181015183820152602001620003b9565b50506000910152565b600082601f830112620003ee57600080fd5b81516001600160401b03808211156200040b576200040b620003a0565b604051601f8301601f19908116603f01168101908282118183101715620004365762000436620003a0565b816040528381528660208588010111156200045057600080fd5b62000463846020830160208901620003b6565b9695505050505050565b80516001600160a01b03811681146200048557600080fd5b919050565b600080600080600060a08688031215620004a357600080fd5b85516001600160401b0380821115620004bb57600080fd5b620004c989838a01620003dc565b96506020880151915080821115620004e057600080fd5b50620004ef88828901620003dc565b94505062000500604087016200046d565b92506060860151915062000517608087016200046d565b90509295509295909350565b600181811c908216806200053857607f821691505b6020821081036200055957634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039b57600081815260208120601f850160051c81016020861015620005885750805b601f850160051c820191505b81811015620005a95782815560010162000594565b505050505050565b81516001600160401b03811115620005cd57620005cd620003a0565b620005e581620005de845462000523565b846200055f565b602080601f8311600181146200061d5760008415620006045750858301515b600019600386901b1c1916600185901b178555620005a9565b600085815260208120601f198616915b828110156200064e578886015182559484019460019091019084016200062d565b50858210156200066d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808201808211156200028d57634e487b7160e01b600052601160045260246000fd5b6020815260008251806020840152620006c0816040850160208701620003b6565b601f01601f19169190910160400192915050565b80516020808301519190811015620005595760001960209190910360031b1b16919050565b60805160a05160c05160e051610100516101205161014051613ff3620007546000396000610d2701526000610cfc015260006119da015260006119b20152600061190d01526000611937015260006119610152613ff36000f3fe60806040526004361061025b5760003560e01c8063715018a611610144578063a457c2d7116100b6578063dd62ed3e1161007a578063dd62ed3e14610732578063ea093f3814610752578063f2fde38b14610765578063f32d49f714610785578063f4bf6a711461079b578063fc0c546a146107bb57600080fd5b8063a457c2d71461069b578063a9059cbb146106bb578063c697caec146106db578063d1dedf58146106fb578063d505accf1461071257600080fd5b806387d095b91161010857806387d095b9146105ec5780638da5cb5b146105ff578063950d4fcc1461061d57806395d89b4114610632578063994e919a14610647578063a2784c7a1461066757600080fd5b8063715018a61461055a57806378e3214f1461056f5780637c0ec54a1461058f5780637ecebe00146105a457806384b0196e146105c457600080fd5b806323b872dd116101dd5780633b97e856116101a15780633b97e8561461046a578063561cbfab14610480578063647846a5146104b457806368f3bc74146104d45780636af6400d146104f457806370a082311461052457600080fd5b806323b872dd146103d95780632b8b7b4b146103f9578063313ce567146104195780633644e51514610435578063395093511461044a57600080fd5b806315cce2241161022457806315cce2241461034e57806318160ddd14610370578063190f39401461038f5780631c1992e9146103af5780631e06f826146103c457600080fd5b8062e1d8d01461026057806301ffc9a7146102a457806306fdde03146102d4578063095ea7b3146102f65780631528dd7714610316575b600080fd5b34801561026c57600080fd5b5061028061027b3660046130b6565b6107ce565b604080516001600160a01b0390931683526020830191909152015b60405180910390f35b3480156102b057600080fd5b506102c46102bf3660046130d8565b6107e7565b604051901515815260200161029b565b3480156102e057600080fd5b506102e961081e565b60405161029b9190613159565b34801561030257600080fd5b506102c4610311366004613181565b6108b0565b34801561032257600080fd5b50600154610336906001600160a01b031681565b6040516001600160a01b03909116815260200161029b565b34801561035a57600080fd5b5061036e6103693660046131ad565b6108c8565b005b34801561037c57600080fd5b506007545b60405190815260200161029b565b34801561039b57600080fd5b5061036e6103aa3660046132ce565b610975565b3480156103bb57600080fd5b50610381610af1565b3480156103d057600080fd5b50610381600081565b3480156103e557600080fd5b506102c46103f4366004613369565b610b01565b34801561040557600080fd5b5061036e6104143660046131ad565b610b25565b34801561042557600080fd5b506040516012815260200161029b565b34801561044157600080fd5b50610381610bd7565b34801561045657600080fd5b506102c4610465366004613181565b610be1565b34801561047657600080fd5b50610381600a5481565b34801561048c57600080fd5b506103817f1de78eb8658305a581b2f1610c96707b0204d5cba6a782b313672045fa5a87c881565b3480156104c057600080fd5b50600254610336906001600160a01b031681565b3480156104e057600080fd5b506102e96104ef3660046133aa565b610c03565b34801561050057600080fd5b506102c461050f3660046133aa565b60046020526000908152604090205460ff1681565b34801561053057600080fd5b5061038161053f3660046131ad565b6001600160a01b031660009081526005602052604090205490565b34801561056657600080fd5b5061036e610ca5565b34801561057b57600080fd5b5061036e61058a366004613181565b610cb9565b34801561059b57600080fd5b50610381600181565b3480156105b057600080fd5b506103816105bf3660046131ad565b610cd0565b3480156105d057600080fd5b506105d9610cee565b60405161029b97969594939291906133c3565b61036e6105fa366004613459565b610d77565b34801561060b57600080fd5b506000546001600160a01b0316610336565b34801561062957600080fd5b506102e9610d8b565b34801561063e57600080fd5b506102e9610da7565b34801561065357600080fd5b506102e96106623660046134c3565b610db6565b34801561067357600080fd5b506103817f174904a4bed10a0a0bd36e5532ccc84114842489d9d4a7c8738d0eff93ccd57381565b3480156106a757600080fd5b506102c46106b6366004613181565b610fd4565b3480156106c757600080fd5b506102c46106d6366004613181565b61104f565b3480156106e757600080fd5b5061036e6106f6366004613573565b61105d565b34801561070757600080fd5b506103816298968081565b34801561071e57600080fd5b5061036e61072d3660046135de565b6111b5565b34801561073e57600080fd5b5061038161074d366004613655565b611319565b61036e61076036600461368e565b611344565b34801561077157600080fd5b5061036e6107803660046131ad565b61135c565b34801561079157600080fd5b5061038161520881565b3480156107a757600080fd5b506102e96107b63660046133aa565b6113d5565b3480156107c757600080fd5b5030610336565b6000806107db848461146f565b915091505b9250929050565b60006001600160e01b03198216634696da6960e11b148061081857506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606008805461082d90613745565b80601f016020809104026020016040519081016040528092919081815260200182805461085990613745565b80156108a65780601f1061087b576101008083540402835291602001916108a6565b820191906000526020600020905b81548152906001019060200180831161088957829003601f168201915b5050505050905090565b6000336108be81858561150b565b5060019392505050565b6108d061162f565b6001600160a01b03811661092b5760405162461bcd60e51b815260206004820152601f60248201527f4d61706f4578656375746f723a20696e76616c69642066656520746f6b656e0060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f0842bcbb92ca6d47ae89816778a843992dff9b876fad009865e1c5df73d46d1f90600090a250565b3330146109d25760405162461bcd60e51b815260206004820152602560248201527f4d4f52433230436f72653a2063616c6c6572206d757374206265204d4f52433260448201526430436f726560d81b6064820152608401610922565b60006109df308688611689565b90508784600080516020613f74833981519152898885604051610a0493929190613779565b60405180910390a36000856001600160a01b031663cb05b6f05a8b8b8b8a8a8a6040518863ffffffff1660e01b8152600401610a45969594939291906137d0565b60206040518083038160008887f1158015610a64573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610a899190613808565b905080610ae65760405162461bcd60e51b815260206004820152602560248201527f4d4f52433230436f72653a2063616c6c4f6e4d4f5243323052656365697665646044820152640819985a5b60da1b6064820152608401610922565b505050505050505050565b6000610afc60075490565b905090565b600033610b0f8582856116db565b610b1a858585611755565b506001949350505050565b610b2d61162f565b6001600160a01b038116610b8d5760405162461bcd60e51b815260206004820152602160248201527f4d61706f4578656375746f723a20696e76616c6964206d6f73206164647265736044820152607360f81b6064820152608401610922565b600180546001600160a01b0319166001600160a01b0383169081179091556040517f4dac21cd18f86f988c6cb57f54a5fc95e6c8e24ad536d4d13040797db555d82f90600090a250565b6000610afc611900565b6000336108be818585610bf48383611319565b610bfe9190613840565b61150b565b6000818152600360205260409020805460609190610c2090613745565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4c90613745565b8015610c995780601f10610c6e57610100808354040283529160200191610c99565b820191906000526020600020905b815481529060010190602001808311610c7c57829003601f168201915b50505050509050919050565b610cad61162f565b610cb76000611a2b565b565b610cc161162f565b610ccc823383611a7b565b5050565b6001600160a01b0381166000908152600d6020526040812054610818565b600060608082808083610d227f0000000000000000000000000000000000000000000000000000000000000000600b611aac565b610d4d7f0000000000000000000000000000000000000000000000000000000000000000600c611aac565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b610d848585858585611b57565b5050505050565b6040518060600160405280602a8152602001613f94602a913981565b60606009805461082d90613745565b6001546060906001600160a01b0316336001600160a01b031614610e1c5760405162461bcd60e51b815260206004820181905260248201527f4d61706f4578656375746f723a20696e76616c6964206d6f732063616c6c65726044820152606401610922565b60008881526003602052604081208054610e3590613745565b80601f0160208091040260200160405190810160405280929190818152602001828054610e6190613745565b8015610eae5780601f10610e8357610100808354040283529160200191610eae565b820191906000526020600020905b815481529060010190602001808311610e9157829003601f168201915b50505050509050805187879050148015610ec9575060008151115b8015610ef1575080516020820120604051610ee79089908990613853565b6040518091039020145b610f505760405162461bcd60e51b815260206004820152602a60248201527f4d61706f4578656375746f723a20696e76616c696420736f7572636520636861604482015269696e206164647265737360b01b6064820152608401610922565b610fc7898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a81528c935091508a908a9081908401838280828437600092019190915250611c9a92505050565b9998505050505050505050565b60003381610fe28286611319565b9050838110156110425760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610922565b610b1a828686840361150b565b6000336108be818585611755565b61106561162f565b8281146110c75760405162461bcd60e51b815260206004820152602a60248201527f4d61706f4578656375746f723a2061646472657373206f7220636861696e4964604482015269040dcdee840dac2e8c6d60b31b6064820152608401610922565b60005b83811015610d84578282828181106110e4576110e4613863565b90506020028101906110f69190613879565b6003600088888681811061110c5761110c613863565b905060200201358152602001908152602001600020918261112e92919061390d565b5084848281811061114157611141613863565b905060200201357f6e534b334194d22563fa33a8f94163835c7378f39c7770229441983cec7f82a784848481811061117b5761117b613863565b905060200281019061118d9190613879565b60405161119b9291906139cc565b60405180910390a2806111ad816139e0565b9150506110ca565b834211156112055760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610922565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886112348c611ded565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061128f82611e15565b9050600061129f82878787611e42565b9050896001600160a01b0316816001600160a01b0316146113025760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610922565b61130d8a8a8a61150b565b50505050505050505050565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205490565b61135387878787878787611e6c565b50505050505050565b61136461162f565b6001600160a01b0381166113c95760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610922565b6113d281611a2b565b50565b600360205260009081526040902080546113ee90613745565b80601f016020809104026020016040519081016040528092919081815260200182805461141a90613745565b80156114675780601f1061143c57610100808354040283529160200191611467565b820191906000526020600020905b81548152906001019060200180831161144a57829003601f168201915b505050505081565b600154600254604051634b7157ab60e11b8152600481018590526001600160a01b03918216602482015260448101849052600092839283929116906396e2af56906064016040805180830381865afa1580156114cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f391906139f9565b506002546001600160a01b0316969095509350505050565b6001600160a01b03831661156d5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610922565b6001600160a01b0382166115ce5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610922565b6001600160a01b0383811660008181526006602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6000546001600160a01b03163314610cb75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610922565b600033306001600160a01b038616148015906116b75750806001600160a01b0316856001600160a01b031614155b156116c7576116c78582856116db565b6116d2858585611755565b50909392505050565b60006116e78484611319565b9050600019811461174f57818110156117425760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610922565b61174f848484840361150b565b50505050565b6001600160a01b0383166117b95760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610922565b6001600160a01b03821661181b5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610922565b6001600160a01b038316600090815260056020526040902054818110156118935760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610922565b6001600160a01b0380851660008181526005602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906118f39086815260200190565b60405180910390a361174f565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561195957507f000000000000000000000000000000000000000000000000000000000000000046145b1561198357507f000000000000000000000000000000000000000000000000000000000000000090565b610afc604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611a8483611fb7565b15611a9857611a938282611ff0565b505050565b611a936001600160a01b0384168383612109565b606060ff8314611ac657611abf8361216c565b9050610818565b818054611ad290613745565b80601f0160208091040260200160405190810160405280929190818152602001828054611afe90613745565b8015611b4b5780601f10611b2057610100808354040283529160200191611b4b565b820191906000526020600020905b815481529060010190602001808311611b2e57829003601f168201915b50505050509050610818565b600080611b66878787876121ab565b9150915060008211611bba5760405162461bcd60e51b815260206004820152601c60248201527f4d4f52433230436f72653a20616d6f756e7420746f6f20736d616c6c000000006044820152606401610922565b6000611bc5886121e6565b9050600081878585604051602001611be09493929190613a1e565b604051602081830303815290604052905060007f1de78eb8658305a581b2f1610c96707b0204d5cba6a782b313672045fa5a87c882604051602001611c26929190613a57565b60405160208183030381529060405290506000611c468a6000848a61221c565b9050898b6001600160a01b0316827fe6292bde937d194a85f952b8bc8c86392c382249460fe6d13d860b78956162268c8c604051611c85929190613a70565b60405180910390a45050505050505050505050565b60008281526004602052604090205460609060ff1615611cfc5760405162461bcd60e51b815260206004820152601b60248201527f4d4f52433230436f72653a20696e76616c6964206f72646572496400000000006044820152606401610922565b60008083806020019051810190611d139190613ad7565b6000878152600460205260409020805460ff1916600117905590925090507fe21871479a7cfa5a7e4d0e9ef3698f84fdfb2a3459587d4cec98dfba05a578388201611d6857611d63888683612530565b611de2565b7f174904a4bed10a0a0bd36e5532ccc84114842489d9d4a7c8738d0eff93ccd5738203611d9a57611d638886836125a4565b60405162461bcd60e51b815260206004820181905260248201527f4d4f52433230436f72653a20756e6b6e6f776e206d65737361676520747970656044820152606401610922565b979650505050505050565b6001600160a01b0381166000908152600d602052604090208054600181018255905b50919050565b6000610818611e22611900565b8360405161190160f01b8152600281019290925260228201526042902090565b6000806000611e5387878787612810565b91509150611e60816128d1565b5090505b949350505050565b600080611e7b898989896121ab565b9150915060008211611ecf5760405162461bcd60e51b815260206004820152601c60248201527f4d4f52433230436f72653a20616d6f756e7420746f6f20736d616c6c000000006044820152606401610922565b6000611eda8a6121e6565b90506000818985858989604051602001611ef996959493929190613b1d565b604051602081830303815290604052905060007f174904a4bed10a0a0bd36e5532ccc84114842489d9d4a7c8738d0eff93ccd57382604051602001611f3f929190613a57565b60405160208183030381529060405290506000611f5f8c6000848c61221c565b90508b8d6001600160a01b0316827f0d11bdbb8fc1f694035f53a0a2073673b4b88caec2faae2b203ae1a97bed389c8e8e88604051611fa093929190613b76565b60405180910390a450505050505050505050505050565b60006001600160a01b038216158061081857506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1492915050565b804710156120405760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610922565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461208d576040519150601f19603f3d011682016040523d82523d6000602084013e612092565b606091505b5050905080611a935760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610922565b6040516001600160a01b038316602482015260448101829052611a9390849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612a1b565b6060600061217983612af0565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600080336001600160a01b03871681146121ca576121ca8782866116db565b6121d48785612b18565b5050600a548291505b94509492505050565b604051606082811b6bffffffffffffffffffffffff19166020830152906034016040516020818303038152906040529050919050565b6000848152600360205260408120805482919061223890613745565b80601f016020809104026020016040519081016040528092919081815260200182805461226490613745565b80156122b15780601f10612286576101008083540402835291602001916122b1565b820191906000526020600020905b81548152906001019060200180831161229457829003601f168201915b50505050509050600081511161231c5760405162461bcd60e51b815260206004820152602a60248201527f4d61706f4578656375746f723a20696e76616c69642072656d6f7465207472756044820152697374206164647265737360b01b6064820152608401610922565b6060856123575760006001838787600060405160200161234196959493929190613bc1565b60405160208183030381529060405290506123cf565b6001860361237c57600080838787600060405160200161234196959493929190613bc1565b60405162461bcd60e51b815260206004820152602260248201527f4d61706f4578656375746f723a20696e76616c6964206d657373616765207479604482015261706560f01b6064820152608401610922565b6000806123dc898761146f565b91509150600081116124305760405162461bcd60e51b815260206004820152601f60248201527f4d61706f4578656375746f723a20696e76616c6964206665652076616c7565006044820152606401610922565b6001600160a01b038216612493578034101561248e5760405162461bcd60e51b815260206004820152601960248201527f4d61706f4578656375746f723a20696e76616c696420666565000000000000006044820152606401610922565b6124b7565b61249f82333084612c4c565b6001546124b79083906001600160a01b031683612c84565b60015460405163a39ed3f960e01b81526001600160a01b039091169063a39ed3f99034906124ed908d9088908890600401613c2f565b60206040518083038185885af115801561250b573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610fc79190613c60565b6000806000808480602001905181019061254a9190613c79565b9350935093509350600061255f846014015190565b905061256d81898585612d99565b50508787600080516020613f7483398151915287848760405161259293929190613779565b60405180910390a35050505050505050565b600080600080600080868060200190518101906125c19190613cec565b95509550955095509550955060006125da866014015190565b905060006125ea308c8888612d99565b5090506001600160a01b0382163b6126ac576126113061260b866014015190565b83611689565b508a8a600080516020613f748339815191528a61262f886014015190565b8560405161263f93929190613779565b60405180910390a38a8a7f54c1958a9e21bd4f65a2a29edd6b693a607eba392d9d1d449ba96ed7894b54ff8a8560006040518060600160405280602a8152602001613f94602a91396040516126979493929190613daa565b60405180910390a35050505050505050505050565b600063190f394060e01b8c8a84868f896040516024016126d196959493929190613de6565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915290506000806127165a3090609686612df3565b915091508115612774578d8d7f54c1958a9e21bd4f65a2a29edd6b693a607eba392d9d1d449ba96ed7894b54ff8d886001604051806020016040528060008152506040516127679493929190613daa565b60405180910390a3612800565b61278930612783896014015190565b86611689565b508d8d600080516020613f748339815191528d6127a78b6014015190565b886040516127b793929190613779565b60405180910390a38d8d7f54c1958a9e21bd4f65a2a29edd6b693a607eba392d9d1d449ba96ed7894b54ff8d886000866040516127f79493929190613daa565b60405180910390a35b5050505050505050505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561284757506000905060036121dd565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561289b573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166128c4576000600192509250506121dd565b9660009650945050505050565b60008160048111156128e5576128e5613bab565b036128ed5750565b600181600481111561290157612901613bab565b0361294e5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610922565b600281600481111561296257612962613bab565b036129af5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610922565b60038160048111156129c3576129c3613bab565b036113d25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610922565b6000612a70826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612e7d9092919063ffffffff16565b9050805160001480612a91575080806020019051810190612a919190613808565b611a935760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610922565b600060ff8216601f81111561081857604051632cd44ac360e21b815260040160405180910390fd5b6001600160a01b038216612b785760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610922565b6001600160a01b03821660009081526005602052604090205481811015612bec5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610922565b6001600160a01b03831660008181526005602090815260408083208686039055600780548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6040516001600160a01b038085166024830152831660448201526064810182905261174f9085906323b872dd60e01b90608401612135565b801580612cfe5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015612cd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cfc9190613c60565b155b612d695760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610922565b6040516001600160a01b038316602482015260448101829052611a9390849063095ea7b360e01b90606401612135565b60008082600a5403612dad57839150612ddc565b612db883600a613f12565b600a8054612dc591613f12565b612dcf9086613f1e565b612dd99190613f35565b91505b612de68683612e8c565b50600a5494509492505050565b6000606060008060008661ffff166001600160401b03811115612e1857612e186131ca565b6040519080825280601f01601f191660200182016040528015612e42576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115612e64578692505b828152826000602083013e909890975095505050505050565b6060611e648484600085612f4d565b6001600160a01b038216612ee25760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610922565b8060076000828254612ef49190613840565b90915550506001600160a01b0382166000818152600560209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b606082471015612fae5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610922565b600080866001600160a01b03168587604051612fca9190613f57565b60006040518083038185875af1925050503d8060008114613007576040519150601f19603f3d011682016040523d82523d6000602084013e61300c565b606091505b5091509150611de28783838760608315613087578251600003613080576001600160a01b0385163b6130805760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610922565b5081611e64565b611e64838381511561309c5781518083602001fd5b8060405162461bcd60e51b81526004016109229190613159565b600080604083850312156130c957600080fd5b50508035926020909101359150565b6000602082840312156130ea57600080fd5b81356001600160e01b03198116811461310257600080fd5b9392505050565b60005b8381101561312457818101518382015260200161310c565b50506000910152565b60008151808452613145816020860160208601613109565b601f01601f19169290920160200192915050565b602081526000613102602083018461312d565b6001600160a01b03811681146113d257600080fd5b6000806040838503121561319457600080fd5b823561319f8161316c565b946020939093013593505050565b6000602082840312156131bf57600080fd5b81356131028161316c565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613208576132086131ca565b604052919050565b60006001600160401b03821115613229576132296131ca565b50601f01601f191660200190565b600082601f83011261324857600080fd5b813561325b61325682613210565b6131e0565b81815284602083860101111561327057600080fd5b816020850160208301376000918101602001919091529392505050565b60008083601f84011261329f57600080fd5b5081356001600160401b038111156132b657600080fd5b6020830191508360208285010111156107e057600080fd5b600080600080600080600060c0888a0312156132e957600080fd5b8735965060208801356001600160401b038082111561330757600080fd5b6133138b838c01613237565b975060408a0135965060608a0135915061332c8261316c565b9094506080890135935060a0890135908082111561334957600080fd5b506133568a828b0161328d565b989b979a50959850939692959293505050565b60008060006060848603121561337e57600080fd5b83356133898161316c565b925060208401356133998161316c565b929592945050506040919091013590565b6000602082840312156133bc57600080fd5b5035919050565b60ff60f81b881681526000602060e0818401526133e360e084018a61312d565b83810360408501526133f5818a61312d565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b818110156134475783518352928401929184019160010161342b565b50909c9b505050505050505050505050565b600080600080600060a0868803121561347157600080fd5b853561347c8161316c565b94506020860135935060408601356001600160401b0381111561349e57600080fd5b6134aa88828901613237565b9598949750949560608101359550608001359392505050565b600080600080600080600060a0888a0312156134de57600080fd5b873596506020880135955060408801356001600160401b038082111561350357600080fd5b61350f8b838c0161328d565b909750955060608a0135945060808a013591508082111561334957600080fd5b60008083601f84011261354157600080fd5b5081356001600160401b0381111561355857600080fd5b6020830191508360208260051b85010111156107e057600080fd5b6000806000806040858703121561358957600080fd5b84356001600160401b03808211156135a057600080fd5b6135ac8883890161352f565b909650945060208701359150808211156135c557600080fd5b506135d28782880161352f565b95989497509550505050565b600080600080600080600060e0888a0312156135f957600080fd5b87356136048161316c565b965060208801356136148161316c565b95506040880135945060608801359350608088013560ff8116811461363857600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561366857600080fd5b82356136738161316c565b915060208301356136838161316c565b809150509250929050565b600080600080600080600060e0888a0312156136a957600080fd5b87356136b48161316c565b96506020880135955060408801356001600160401b03808211156136d757600080fd5b6136e38b838c01613237565b965060608a0135955060808a0135945060a08a013591508082111561370757600080fd5b6137138b838c01613237565b935060c08a013591508082111561372957600080fd5b506137368a828b01613237565b91505092959891949750929550565b600181811c9082168061375957607f821691505b602082108103611e0f57634e487b7160e01b600052602260045260246000fd5b60608152600061378c606083018661312d565b6001600160a01b039490941660208301525060400152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b86815260a0602082015260006137e960a083018861312d565b8660408401528560608401528281036080840152610fc78185876137a7565b60006020828403121561381a57600080fd5b8151801515811461310257600080fd5b634e487b7160e01b600052601160045260246000fd5b808201808211156108185761081861382a565b8183823760009101908152919050565b634e487b7160e01b600052603260045260246000fd5b6000808335601e1984360301811261389057600080fd5b8301803591506001600160401b038211156138aa57600080fd5b6020019150368190038213156107e057600080fd5b601f821115611a9357600081815260208120601f850160051c810160208610156138e65750805b601f850160051c820191505b81811015613905578281556001016138f2565b505050505050565b6001600160401b03831115613924576139246131ca565b613938836139328354613745565b836138bf565b6000601f84116001811461396c57600085156139545750838201355b600019600387901b1c1916600186901b178355610d84565b600083815260209020601f19861690835b8281101561399d578685013582556020948501946001909201910161397d565b50868210156139ba5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b602081526000611e646020830184866137a7565b6000600182016139f2576139f261382a565b5060010190565b60008060408385031215613a0c57600080fd5b8251915060208301516136838161316c565b608081526000613a31608083018761312d565b8281036020840152613a43818761312d565b604084019590955250506060015292915050565b828152604060208201526000611e64604083018461312d565b604081526000613a83604083018561312d565b90508260208301529392505050565b600082601f830112613aa357600080fd5b8151613ab161325682613210565b818152846020838601011115613ac657600080fd5b611e64826020830160208701613109565b60008060408385031215613aea57600080fd5b8251915060208301516001600160401b03811115613b0757600080fd5b613b1385828601613a92565b9150509250929050565b60c081526000613b3060c083018961312d565b8281036020840152613b42818961312d565b90508660408401528560608401528281036080840152613b62818661312d565b905082810360a0840152610fc7818561312d565b606081526000613b89606083018661312d565b8460208401528281036040840152613ba1818561312d565b9695505050505050565b634e487b7160e01b600052602160045260246000fd5b8615158152600060028710613be657634e487b7160e01b600052602160045260246000fd5b86602083015260c06040830152613c0060c083018761312d565b8281036060840152613c12818761312d565b91505083608083015260ff831660a0830152979650505050505050565b838152606060208201526000613c48606083018561312d565b905060018060a01b0383166040830152949350505050565b600060208284031215613c7257600080fd5b5051919050565b60008060008060808587031215613c8f57600080fd5b84516001600160401b0380821115613ca657600080fd5b613cb288838901613a92565b95506020870151915080821115613cc857600080fd5b50613cd587828801613a92565b604087015160609097015195989097509350505050565b60008060008060008060c08789031215613d0557600080fd5b86516001600160401b0380821115613d1c57600080fd5b613d288a838b01613a92565b97506020890151915080821115613d3e57600080fd5b613d4a8a838b01613a92565b965060408901519550606089015194506080890151915080821115613d6e57600080fd5b613d7a8a838b01613a92565b935060a0890151915080821115613d9057600080fd5b50613d9d89828a01613a92565b9150509295509295509295565b608081526000613dbd608083018761312d565b6001600160a01b038616602084015284151560408401528281036060840152611de2818561312d565b86815260c060208201526000613dff60c083018861312d565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152610fc7818561312d565b600181815b80851115613e69578160001904821115613e4f57613e4f61382a565b80851615613e5c57918102915b93841c9390800290613e33565b509250929050565b600082613e8057506001610818565b81613e8d57506000610818565b8160018114613ea35760028114613ead57613ec9565b6001915050610818565b60ff841115613ebe57613ebe61382a565b50506001821b610818565b5060208310610133831016604e8410600b8410161715613eec575081810a610818565b613ef68383613e2e565b8060001904821115613f0a57613f0a61382a565b029392505050565b60006131028383613e71565b80820281158282048414176108185761081861382a565b600082613f5257634e487b7160e01b600052601260045260246000fd5b500490565b60008251613f69818460208701613109565b919091019291505056fecac681649d11d73aa22d1f83297c03f511c36a9c26f355bbc6446b1b65278ed4307834653466353435663433346634653534353234313433353435663431343434343532343535333533a2646970667358221220d5f54f3678a011ff4d56dc613b5a415636f45c23826c34dc6b8cd8107913887364736f6c6343000814003300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000008c3ccc219721b206da4a2070fd96e4911a48cb4f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038bcf8d2d48c084b661e3f2b3c514b4244b4d90000000000000000000000000000000000000000000000000000000000000000c4d41502050726f746f636f6c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044d41504f00000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x60806040526004361061025b5760003560e01c8063715018a611610144578063a457c2d7116100b6578063dd62ed3e1161007a578063dd62ed3e14610732578063ea093f3814610752578063f2fde38b14610765578063f32d49f714610785578063f4bf6a711461079b578063fc0c546a146107bb57600080fd5b8063a457c2d71461069b578063a9059cbb146106bb578063c697caec146106db578063d1dedf58146106fb578063d505accf1461071257600080fd5b806387d095b91161010857806387d095b9146105ec5780638da5cb5b146105ff578063950d4fcc1461061d57806395d89b4114610632578063994e919a14610647578063a2784c7a1461066757600080fd5b8063715018a61461055a57806378e3214f1461056f5780637c0ec54a1461058f5780637ecebe00146105a457806384b0196e146105c457600080fd5b806323b872dd116101dd5780633b97e856116101a15780633b97e8561461046a578063561cbfab14610480578063647846a5146104b457806368f3bc74146104d45780636af6400d146104f457806370a082311461052457600080fd5b806323b872dd146103d95780632b8b7b4b146103f9578063313ce567146104195780633644e51514610435578063395093511461044a57600080fd5b806315cce2241161022457806315cce2241461034e57806318160ddd14610370578063190f39401461038f5780631c1992e9146103af5780631e06f826146103c457600080fd5b8062e1d8d01461026057806301ffc9a7146102a457806306fdde03146102d4578063095ea7b3146102f65780631528dd7714610316575b600080fd5b34801561026c57600080fd5b5061028061027b3660046130b6565b6107ce565b604080516001600160a01b0390931683526020830191909152015b60405180910390f35b3480156102b057600080fd5b506102c46102bf3660046130d8565b6107e7565b604051901515815260200161029b565b3480156102e057600080fd5b506102e961081e565b60405161029b9190613159565b34801561030257600080fd5b506102c4610311366004613181565b6108b0565b34801561032257600080fd5b50600154610336906001600160a01b031681565b6040516001600160a01b03909116815260200161029b565b34801561035a57600080fd5b5061036e6103693660046131ad565b6108c8565b005b34801561037c57600080fd5b506007545b60405190815260200161029b565b34801561039b57600080fd5b5061036e6103aa3660046132ce565b610975565b3480156103bb57600080fd5b50610381610af1565b3480156103d057600080fd5b50610381600081565b3480156103e557600080fd5b506102c46103f4366004613369565b610b01565b34801561040557600080fd5b5061036e6104143660046131ad565b610b25565b34801561042557600080fd5b506040516012815260200161029b565b34801561044157600080fd5b50610381610bd7565b34801561045657600080fd5b506102c4610465366004613181565b610be1565b34801561047657600080fd5b50610381600a5481565b34801561048c57600080fd5b506103817f1de78eb8658305a581b2f1610c96707b0204d5cba6a782b313672045fa5a87c881565b3480156104c057600080fd5b50600254610336906001600160a01b031681565b3480156104e057600080fd5b506102e96104ef3660046133aa565b610c03565b34801561050057600080fd5b506102c461050f3660046133aa565b60046020526000908152604090205460ff1681565b34801561053057600080fd5b5061038161053f3660046131ad565b6001600160a01b031660009081526005602052604090205490565b34801561056657600080fd5b5061036e610ca5565b34801561057b57600080fd5b5061036e61058a366004613181565b610cb9565b34801561059b57600080fd5b50610381600181565b3480156105b057600080fd5b506103816105bf3660046131ad565b610cd0565b3480156105d057600080fd5b506105d9610cee565b60405161029b97969594939291906133c3565b61036e6105fa366004613459565b610d77565b34801561060b57600080fd5b506000546001600160a01b0316610336565b34801561062957600080fd5b506102e9610d8b565b34801561063e57600080fd5b506102e9610da7565b34801561065357600080fd5b506102e96106623660046134c3565b610db6565b34801561067357600080fd5b506103817f174904a4bed10a0a0bd36e5532ccc84114842489d9d4a7c8738d0eff93ccd57381565b3480156106a757600080fd5b506102c46106b6366004613181565b610fd4565b3480156106c757600080fd5b506102c46106d6366004613181565b61104f565b3480156106e757600080fd5b5061036e6106f6366004613573565b61105d565b34801561070757600080fd5b506103816298968081565b34801561071e57600080fd5b5061036e61072d3660046135de565b6111b5565b34801561073e57600080fd5b5061038161074d366004613655565b611319565b61036e61076036600461368e565b611344565b34801561077157600080fd5b5061036e6107803660046131ad565b61135c565b34801561079157600080fd5b5061038161520881565b3480156107a757600080fd5b506102e96107b63660046133aa565b6113d5565b3480156107c757600080fd5b5030610336565b6000806107db848461146f565b915091505b9250929050565b60006001600160e01b03198216634696da6960e11b148061081857506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606008805461082d90613745565b80601f016020809104026020016040519081016040528092919081815260200182805461085990613745565b80156108a65780601f1061087b576101008083540402835291602001916108a6565b820191906000526020600020905b81548152906001019060200180831161088957829003601f168201915b5050505050905090565b6000336108be81858561150b565b5060019392505050565b6108d061162f565b6001600160a01b03811661092b5760405162461bcd60e51b815260206004820152601f60248201527f4d61706f4578656375746f723a20696e76616c69642066656520746f6b656e0060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f0842bcbb92ca6d47ae89816778a843992dff9b876fad009865e1c5df73d46d1f90600090a250565b3330146109d25760405162461bcd60e51b815260206004820152602560248201527f4d4f52433230436f72653a2063616c6c6572206d757374206265204d4f52433260448201526430436f726560d81b6064820152608401610922565b60006109df308688611689565b90508784600080516020613f74833981519152898885604051610a0493929190613779565b60405180910390a36000856001600160a01b031663cb05b6f05a8b8b8b8a8a8a6040518863ffffffff1660e01b8152600401610a45969594939291906137d0565b60206040518083038160008887f1158015610a64573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610a899190613808565b905080610ae65760405162461bcd60e51b815260206004820152602560248201527f4d4f52433230436f72653a2063616c6c4f6e4d4f5243323052656365697665646044820152640819985a5b60da1b6064820152608401610922565b505050505050505050565b6000610afc60075490565b905090565b600033610b0f8582856116db565b610b1a858585611755565b506001949350505050565b610b2d61162f565b6001600160a01b038116610b8d5760405162461bcd60e51b815260206004820152602160248201527f4d61706f4578656375746f723a20696e76616c6964206d6f73206164647265736044820152607360f81b6064820152608401610922565b600180546001600160a01b0319166001600160a01b0383169081179091556040517f4dac21cd18f86f988c6cb57f54a5fc95e6c8e24ad536d4d13040797db555d82f90600090a250565b6000610afc611900565b6000336108be818585610bf48383611319565b610bfe9190613840565b61150b565b6000818152600360205260409020805460609190610c2090613745565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4c90613745565b8015610c995780601f10610c6e57610100808354040283529160200191610c99565b820191906000526020600020905b815481529060010190602001808311610c7c57829003601f168201915b50505050509050919050565b610cad61162f565b610cb76000611a2b565b565b610cc161162f565b610ccc823383611a7b565b5050565b6001600160a01b0381166000908152600d6020526040812054610818565b600060608082808083610d227f4d41502050726f746f636f6c000000000000000000000000000000000000000c600b611aac565b610d4d7f3100000000000000000000000000000000000000000000000000000000000001600c611aac565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b610d848585858585611b57565b5050505050565b6040518060600160405280602a8152602001613f94602a913981565b60606009805461082d90613745565b6001546060906001600160a01b0316336001600160a01b031614610e1c5760405162461bcd60e51b815260206004820181905260248201527f4d61706f4578656375746f723a20696e76616c6964206d6f732063616c6c65726044820152606401610922565b60008881526003602052604081208054610e3590613745565b80601f0160208091040260200160405190810160405280929190818152602001828054610e6190613745565b8015610eae5780601f10610e8357610100808354040283529160200191610eae565b820191906000526020600020905b815481529060010190602001808311610e9157829003601f168201915b50505050509050805187879050148015610ec9575060008151115b8015610ef1575080516020820120604051610ee79089908990613853565b6040518091039020145b610f505760405162461bcd60e51b815260206004820152602a60248201527f4d61706f4578656375746f723a20696e76616c696420736f7572636520636861604482015269696e206164647265737360b01b6064820152608401610922565b610fc7898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a81528c935091508a908a9081908401838280828437600092019190915250611c9a92505050565b9998505050505050505050565b60003381610fe28286611319565b9050838110156110425760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610922565b610b1a828686840361150b565b6000336108be818585611755565b61106561162f565b8281146110c75760405162461bcd60e51b815260206004820152602a60248201527f4d61706f4578656375746f723a2061646472657373206f7220636861696e4964604482015269040dcdee840dac2e8c6d60b31b6064820152608401610922565b60005b83811015610d84578282828181106110e4576110e4613863565b90506020028101906110f69190613879565b6003600088888681811061110c5761110c613863565b905060200201358152602001908152602001600020918261112e92919061390d565b5084848281811061114157611141613863565b905060200201357f6e534b334194d22563fa33a8f94163835c7378f39c7770229441983cec7f82a784848481811061117b5761117b613863565b905060200281019061118d9190613879565b60405161119b9291906139cc565b60405180910390a2806111ad816139e0565b9150506110ca565b834211156112055760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610922565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886112348c611ded565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061128f82611e15565b9050600061129f82878787611e42565b9050896001600160a01b0316816001600160a01b0316146113025760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610922565b61130d8a8a8a61150b565b50505050505050505050565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205490565b61135387878787878787611e6c565b50505050505050565b61136461162f565b6001600160a01b0381166113c95760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610922565b6113d281611a2b565b50565b600360205260009081526040902080546113ee90613745565b80601f016020809104026020016040519081016040528092919081815260200182805461141a90613745565b80156114675780601f1061143c57610100808354040283529160200191611467565b820191906000526020600020905b81548152906001019060200180831161144a57829003601f168201915b505050505081565b600154600254604051634b7157ab60e11b8152600481018590526001600160a01b03918216602482015260448101849052600092839283929116906396e2af56906064016040805180830381865afa1580156114cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f391906139f9565b506002546001600160a01b0316969095509350505050565b6001600160a01b03831661156d5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610922565b6001600160a01b0382166115ce5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610922565b6001600160a01b0383811660008181526006602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6000546001600160a01b03163314610cb75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610922565b600033306001600160a01b038616148015906116b75750806001600160a01b0316856001600160a01b031614155b156116c7576116c78582856116db565b6116d2858585611755565b50909392505050565b60006116e78484611319565b9050600019811461174f57818110156117425760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610922565b61174f848484840361150b565b50505050565b6001600160a01b0383166117b95760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610922565b6001600160a01b03821661181b5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610922565b6001600160a01b038316600090815260056020526040902054818110156118935760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610922565b6001600160a01b0380851660008181526005602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906118f39086815260200190565b60405180910390a361174f565b6000306001600160a01b037f00000000000000000000000066d79b8f60ec93bfce0b56f5ac14a2714e509a991614801561195957507f000000000000000000000000000000000000000000000000000000000000000146145b1561198357507ff1a6163fe94512e03bdbf1d9f8fdf9c3676f9fb4474f18bd8e496ddd9071926190565b610afc604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f473f7c10b56aad6a3afbd89ffff89f72cec6b014124850bf59110c150e6cd235918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611a8483611fb7565b15611a9857611a938282611ff0565b505050565b611a936001600160a01b0384168383612109565b606060ff8314611ac657611abf8361216c565b9050610818565b818054611ad290613745565b80601f0160208091040260200160405190810160405280929190818152602001828054611afe90613745565b8015611b4b5780601f10611b2057610100808354040283529160200191611b4b565b820191906000526020600020905b815481529060010190602001808311611b2e57829003601f168201915b50505050509050610818565b600080611b66878787876121ab565b9150915060008211611bba5760405162461bcd60e51b815260206004820152601c60248201527f4d4f52433230436f72653a20616d6f756e7420746f6f20736d616c6c000000006044820152606401610922565b6000611bc5886121e6565b9050600081878585604051602001611be09493929190613a1e565b604051602081830303815290604052905060007f1de78eb8658305a581b2f1610c96707b0204d5cba6a782b313672045fa5a87c882604051602001611c26929190613a57565b60405160208183030381529060405290506000611c468a6000848a61221c565b9050898b6001600160a01b0316827fe6292bde937d194a85f952b8bc8c86392c382249460fe6d13d860b78956162268c8c604051611c85929190613a70565b60405180910390a45050505050505050505050565b60008281526004602052604090205460609060ff1615611cfc5760405162461bcd60e51b815260206004820152601b60248201527f4d4f52433230436f72653a20696e76616c6964206f72646572496400000000006044820152606401610922565b60008083806020019051810190611d139190613ad7565b6000878152600460205260409020805460ff1916600117905590925090507fe21871479a7cfa5a7e4d0e9ef3698f84fdfb2a3459587d4cec98dfba05a578388201611d6857611d63888683612530565b611de2565b7f174904a4bed10a0a0bd36e5532ccc84114842489d9d4a7c8738d0eff93ccd5738203611d9a57611d638886836125a4565b60405162461bcd60e51b815260206004820181905260248201527f4d4f52433230436f72653a20756e6b6e6f776e206d65737361676520747970656044820152606401610922565b979650505050505050565b6001600160a01b0381166000908152600d602052604090208054600181018255905b50919050565b6000610818611e22611900565b8360405161190160f01b8152600281019290925260228201526042902090565b6000806000611e5387878787612810565b91509150611e60816128d1565b5090505b949350505050565b600080611e7b898989896121ab565b9150915060008211611ecf5760405162461bcd60e51b815260206004820152601c60248201527f4d4f52433230436f72653a20616d6f756e7420746f6f20736d616c6c000000006044820152606401610922565b6000611eda8a6121e6565b90506000818985858989604051602001611ef996959493929190613b1d565b604051602081830303815290604052905060007f174904a4bed10a0a0bd36e5532ccc84114842489d9d4a7c8738d0eff93ccd57382604051602001611f3f929190613a57565b60405160208183030381529060405290506000611f5f8c6000848c61221c565b90508b8d6001600160a01b0316827f0d11bdbb8fc1f694035f53a0a2073673b4b88caec2faae2b203ae1a97bed389c8e8e88604051611fa093929190613b76565b60405180910390a450505050505050505050505050565b60006001600160a01b038216158061081857506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1492915050565b804710156120405760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610922565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461208d576040519150601f19603f3d011682016040523d82523d6000602084013e612092565b606091505b5050905080611a935760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610922565b6040516001600160a01b038316602482015260448101829052611a9390849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612a1b565b6060600061217983612af0565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600080336001600160a01b03871681146121ca576121ca8782866116db565b6121d48785612b18565b5050600a548291505b94509492505050565b604051606082811b6bffffffffffffffffffffffff19166020830152906034016040516020818303038152906040529050919050565b6000848152600360205260408120805482919061223890613745565b80601f016020809104026020016040519081016040528092919081815260200182805461226490613745565b80156122b15780601f10612286576101008083540402835291602001916122b1565b820191906000526020600020905b81548152906001019060200180831161229457829003601f168201915b50505050509050600081511161231c5760405162461bcd60e51b815260206004820152602a60248201527f4d61706f4578656375746f723a20696e76616c69642072656d6f7465207472756044820152697374206164647265737360b01b6064820152608401610922565b6060856123575760006001838787600060405160200161234196959493929190613bc1565b60405160208183030381529060405290506123cf565b6001860361237c57600080838787600060405160200161234196959493929190613bc1565b60405162461bcd60e51b815260206004820152602260248201527f4d61706f4578656375746f723a20696e76616c6964206d657373616765207479604482015261706560f01b6064820152608401610922565b6000806123dc898761146f565b91509150600081116124305760405162461bcd60e51b815260206004820152601f60248201527f4d61706f4578656375746f723a20696e76616c6964206665652076616c7565006044820152606401610922565b6001600160a01b038216612493578034101561248e5760405162461bcd60e51b815260206004820152601960248201527f4d61706f4578656375746f723a20696e76616c696420666565000000000000006044820152606401610922565b6124b7565b61249f82333084612c4c565b6001546124b79083906001600160a01b031683612c84565b60015460405163a39ed3f960e01b81526001600160a01b039091169063a39ed3f99034906124ed908d9088908890600401613c2f565b60206040518083038185885af115801561250b573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610fc79190613c60565b6000806000808480602001905181019061254a9190613c79565b9350935093509350600061255f846014015190565b905061256d81898585612d99565b50508787600080516020613f7483398151915287848760405161259293929190613779565b60405180910390a35050505050505050565b600080600080600080868060200190518101906125c19190613cec565b95509550955095509550955060006125da866014015190565b905060006125ea308c8888612d99565b5090506001600160a01b0382163b6126ac576126113061260b866014015190565b83611689565b508a8a600080516020613f748339815191528a61262f886014015190565b8560405161263f93929190613779565b60405180910390a38a8a7f54c1958a9e21bd4f65a2a29edd6b693a607eba392d9d1d449ba96ed7894b54ff8a8560006040518060600160405280602a8152602001613f94602a91396040516126979493929190613daa565b60405180910390a35050505050505050505050565b600063190f394060e01b8c8a84868f896040516024016126d196959493929190613de6565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915290506000806127165a3090609686612df3565b915091508115612774578d8d7f54c1958a9e21bd4f65a2a29edd6b693a607eba392d9d1d449ba96ed7894b54ff8d886001604051806020016040528060008152506040516127679493929190613daa565b60405180910390a3612800565b61278930612783896014015190565b86611689565b508d8d600080516020613f748339815191528d6127a78b6014015190565b886040516127b793929190613779565b60405180910390a38d8d7f54c1958a9e21bd4f65a2a29edd6b693a607eba392d9d1d449ba96ed7894b54ff8d886000866040516127f79493929190613daa565b60405180910390a35b5050505050505050505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561284757506000905060036121dd565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561289b573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166128c4576000600192509250506121dd565b9660009650945050505050565b60008160048111156128e5576128e5613bab565b036128ed5750565b600181600481111561290157612901613bab565b0361294e5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610922565b600281600481111561296257612962613bab565b036129af5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610922565b60038160048111156129c3576129c3613bab565b036113d25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610922565b6000612a70826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612e7d9092919063ffffffff16565b9050805160001480612a91575080806020019051810190612a919190613808565b611a935760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610922565b600060ff8216601f81111561081857604051632cd44ac360e21b815260040160405180910390fd5b6001600160a01b038216612b785760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610922565b6001600160a01b03821660009081526005602052604090205481811015612bec5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610922565b6001600160a01b03831660008181526005602090815260408083208686039055600780548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6040516001600160a01b038085166024830152831660448201526064810182905261174f9085906323b872dd60e01b90608401612135565b801580612cfe5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015612cd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cfc9190613c60565b155b612d695760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610922565b6040516001600160a01b038316602482015260448101829052611a9390849063095ea7b360e01b90606401612135565b60008082600a5403612dad57839150612ddc565b612db883600a613f12565b600a8054612dc591613f12565b612dcf9086613f1e565b612dd99190613f35565b91505b612de68683612e8c565b50600a5494509492505050565b6000606060008060008661ffff166001600160401b03811115612e1857612e186131ca565b6040519080825280601f01601f191660200182016040528015612e42576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115612e64578692505b828152826000602083013e909890975095505050505050565b6060611e648484600085612f4d565b6001600160a01b038216612ee25760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610922565b8060076000828254612ef49190613840565b90915550506001600160a01b0382166000818152600560209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b606082471015612fae5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610922565b600080866001600160a01b03168587604051612fca9190613f57565b60006040518083038185875af1925050503d8060008114613007576040519150601f19603f3d011682016040523d82523d6000602084013e61300c565b606091505b5091509150611de28783838760608315613087578251600003613080576001600160a01b0385163b6130805760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610922565b5081611e64565b611e64838381511561309c5781518083602001fd5b8060405162461bcd60e51b81526004016109229190613159565b600080604083850312156130c957600080fd5b50508035926020909101359150565b6000602082840312156130ea57600080fd5b81356001600160e01b03198116811461310257600080fd5b9392505050565b60005b8381101561312457818101518382015260200161310c565b50506000910152565b60008151808452613145816020860160208601613109565b601f01601f19169290920160200192915050565b602081526000613102602083018461312d565b6001600160a01b03811681146113d257600080fd5b6000806040838503121561319457600080fd5b823561319f8161316c565b946020939093013593505050565b6000602082840312156131bf57600080fd5b81356131028161316c565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613208576132086131ca565b604052919050565b60006001600160401b03821115613229576132296131ca565b50601f01601f191660200190565b600082601f83011261324857600080fd5b813561325b61325682613210565b6131e0565b81815284602083860101111561327057600080fd5b816020850160208301376000918101602001919091529392505050565b60008083601f84011261329f57600080fd5b5081356001600160401b038111156132b657600080fd5b6020830191508360208285010111156107e057600080fd5b600080600080600080600060c0888a0312156132e957600080fd5b8735965060208801356001600160401b038082111561330757600080fd5b6133138b838c01613237565b975060408a0135965060608a0135915061332c8261316c565b9094506080890135935060a0890135908082111561334957600080fd5b506133568a828b0161328d565b989b979a50959850939692959293505050565b60008060006060848603121561337e57600080fd5b83356133898161316c565b925060208401356133998161316c565b929592945050506040919091013590565b6000602082840312156133bc57600080fd5b5035919050565b60ff60f81b881681526000602060e0818401526133e360e084018a61312d565b83810360408501526133f5818a61312d565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b818110156134475783518352928401929184019160010161342b565b50909c9b505050505050505050505050565b600080600080600060a0868803121561347157600080fd5b853561347c8161316c565b94506020860135935060408601356001600160401b0381111561349e57600080fd5b6134aa88828901613237565b9598949750949560608101359550608001359392505050565b600080600080600080600060a0888a0312156134de57600080fd5b873596506020880135955060408801356001600160401b038082111561350357600080fd5b61350f8b838c0161328d565b909750955060608a0135945060808a013591508082111561334957600080fd5b60008083601f84011261354157600080fd5b5081356001600160401b0381111561355857600080fd5b6020830191508360208260051b85010111156107e057600080fd5b6000806000806040858703121561358957600080fd5b84356001600160401b03808211156135a057600080fd5b6135ac8883890161352f565b909650945060208701359150808211156135c557600080fd5b506135d28782880161352f565b95989497509550505050565b600080600080600080600060e0888a0312156135f957600080fd5b87356136048161316c565b965060208801356136148161316c565b95506040880135945060608801359350608088013560ff8116811461363857600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561366857600080fd5b82356136738161316c565b915060208301356136838161316c565b809150509250929050565b600080600080600080600060e0888a0312156136a957600080fd5b87356136b48161316c565b96506020880135955060408801356001600160401b03808211156136d757600080fd5b6136e38b838c01613237565b965060608a0135955060808a0135945060a08a013591508082111561370757600080fd5b6137138b838c01613237565b935060c08a013591508082111561372957600080fd5b506137368a828b01613237565b91505092959891949750929550565b600181811c9082168061375957607f821691505b602082108103611e0f57634e487b7160e01b600052602260045260246000fd5b60608152600061378c606083018661312d565b6001600160a01b039490941660208301525060400152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b86815260a0602082015260006137e960a083018861312d565b8660408401528560608401528281036080840152610fc78185876137a7565b60006020828403121561381a57600080fd5b8151801515811461310257600080fd5b634e487b7160e01b600052601160045260246000fd5b808201808211156108185761081861382a565b8183823760009101908152919050565b634e487b7160e01b600052603260045260246000fd5b6000808335601e1984360301811261389057600080fd5b8301803591506001600160401b038211156138aa57600080fd5b6020019150368190038213156107e057600080fd5b601f821115611a9357600081815260208120601f850160051c810160208610156138e65750805b601f850160051c820191505b81811015613905578281556001016138f2565b505050505050565b6001600160401b03831115613924576139246131ca565b613938836139328354613745565b836138bf565b6000601f84116001811461396c57600085156139545750838201355b600019600387901b1c1916600186901b178355610d84565b600083815260209020601f19861690835b8281101561399d578685013582556020948501946001909201910161397d565b50868210156139ba5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b602081526000611e646020830184866137a7565b6000600182016139f2576139f261382a565b5060010190565b60008060408385031215613a0c57600080fd5b8251915060208301516136838161316c565b608081526000613a31608083018761312d565b8281036020840152613a43818761312d565b604084019590955250506060015292915050565b828152604060208201526000611e64604083018461312d565b604081526000613a83604083018561312d565b90508260208301529392505050565b600082601f830112613aa357600080fd5b8151613ab161325682613210565b818152846020838601011115613ac657600080fd5b611e64826020830160208701613109565b60008060408385031215613aea57600080fd5b8251915060208301516001600160401b03811115613b0757600080fd5b613b1385828601613a92565b9150509250929050565b60c081526000613b3060c083018961312d565b8281036020840152613b42818961312d565b90508660408401528560608401528281036080840152613b62818661312d565b905082810360a0840152610fc7818561312d565b606081526000613b89606083018661312d565b8460208401528281036040840152613ba1818561312d565b9695505050505050565b634e487b7160e01b600052602160045260246000fd5b8615158152600060028710613be657634e487b7160e01b600052602160045260246000fd5b86602083015260c06040830152613c0060c083018761312d565b8281036060840152613c12818761312d565b91505083608083015260ff831660a0830152979650505050505050565b838152606060208201526000613c48606083018561312d565b905060018060a01b0383166040830152949350505050565b600060208284031215613c7257600080fd5b5051919050565b60008060008060808587031215613c8f57600080fd5b84516001600160401b0380821115613ca657600080fd5b613cb288838901613a92565b95506020870151915080821115613cc857600080fd5b50613cd587828801613a92565b604087015160609097015195989097509350505050565b60008060008060008060c08789031215613d0557600080fd5b86516001600160401b0380821115613d1c57600080fd5b613d288a838b01613a92565b97506020890151915080821115613d3e57600080fd5b613d4a8a838b01613a92565b965060408901519550606089015194506080890151915080821115613d6e57600080fd5b613d7a8a838b01613a92565b935060a0890151915080821115613d9057600080fd5b50613d9d89828a01613a92565b9150509295509295509295565b608081526000613dbd608083018761312d565b6001600160a01b038616602084015284151560408401528281036060840152611de2818561312d565b86815260c060208201526000613dff60c083018861312d565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152610fc7818561312d565b600181815b80851115613e69578160001904821115613e4f57613e4f61382a565b80851615613e5c57918102915b93841c9390800290613e33565b509250929050565b600082613e8057506001610818565b81613e8d57506000610818565b8160018114613ea35760028114613ead57613ec9565b6001915050610818565b60ff841115613ebe57613ebe61382a565b50506001821b610818565b5060208310610133831016604e8410600b8410161715613eec575081810a610818565b613ef68383613e2e565b8060001904821115613f0a57613f0a61382a565b029392505050565b60006131028383613e71565b80820281158282048414176108185761081861382a565b600082613f5257634e487b7160e01b600052601260045260246000fd5b500490565b60008251613f69818460208701613109565b919091019291505056fecac681649d11d73aa22d1f83297c03f511c36a9c26f355bbc6446b1b65278ed4307834653466353435663433346634653534353234313433353435663431343434343532343535333533a2646970667358221220d5f54f3678a011ff4d56dc613b5a415636f45c23826c34dc6b8cd8107913887364736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000008c3ccc219721b206da4a2070fd96e4911a48cb4f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038bcf8d2d48c084b661e3f2b3c514b4244b4d90000000000000000000000000000000000000000000000000000000000000000c4d41502050726f746f636f6c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044d41504f00000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _name (string): MAP Protocol
Arg [1] : _symbol (string): MAPO
Arg [2] : _mosAddress (address): 0x8C3cCc219721B206DA4A2070fD96E4911a48CB4f
Arg [3] : _initialSupply (uint256): 0
Arg [4] : _owner (address): 0x038BCF8d2d48C084B661E3f2B3c514b4244B4D90
-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [2] : 0000000000000000000000008c3ccc219721b206da4a2070fd96e4911a48cb4f
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : 000000000000000000000000038bcf8d2d48c084b661e3f2b3c514b4244b4d90
Arg [5] : 000000000000000000000000000000000000000000000000000000000000000c
Arg [6] : 4d41502050726f746f636f6c0000000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [8] : 4d41504f00000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
167:368:25:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1169:210:33;;;;;;;;;;-1:-1:-1;1169:210:33;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;459:32:35;;;441:51;;523:2;508:18;;501:34;;;;414:18;1169:210:33;;;;;;;;951:212;;;;;;;;;;-1:-1:-1;951:212:33;;;;;:::i;:::-;;:::i;:::-;;;1002:14:35;;995:22;977:41;;965:2;950:18;951:212:33;837:187:35;2158:98:5;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;4444:197::-;;;;;;;;;;-1:-1:-1;4444:197:5;;;;;:::i;:::-;;:::i;605:17:26:-;;;;;;;;;;-1:-1:-1;605:17:26;;;;-1:-1:-1;;;;;605:17:26;;;;;;-1:-1:-1;;;;;2419:32:35;;;2401:51;;2389:2;2374:18;605:17:26;2241:217:35;4172:210:26;;;;;;;;;;-1:-1:-1;4172:210:26;;;;;:::i;:::-;;:::i;:::-;;3255:106:5;;;;;;;;;;-1:-1:-1;3342:12:5;;3255:106;;;2861:25:35;;;2849:2;2834:18;3255:106:5;2715:177:35;4521:862:33;;;;;;;;;;-1:-1:-1;4521:862:33;;;;;:::i;:::-;;:::i;436:111:34:-;;;;;;;;;;;;;:::i;392:48:26:-;;;;;;;;;;;;439:1;392:48;;5203:256:5;;;;;;;;;;-1:-1:-1;5203:256:5;;;;;:::i;:::-;;:::i;4388:199:26:-;;;;;;;;;;-1:-1:-1;4388:199:26;;;;;:::i;:::-;;:::i;3104:91:5:-;;;;;;;;;;-1:-1:-1;3104:91:5;;3186:2;5897:36:35;;5885:2;5870:18;3104:91:5;5755:184:35;2836:113:9;;;;;;;;;;;;;:::i;5854:234:5:-;;;;;;;;;;-1:-1:-1;5854:234:5;;;;;:::i;:::-;;:::i;190:28:34:-;;;;;;;;;;;;;;;;538:87:33;;;;;;;;;;;;584:41;538:87;;628:23:26;;;;;;;;;;-1:-1:-1;628:23:26;;;;-1:-1:-1;;;;;628:23:26;;;3544:139;;;;;;;;;;-1:-1:-1;3544:139:26;;;;;:::i;:::-;;:::i;836:41:33:-;;;;;;;;;;-1:-1:-1;836:41:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;3419:125:5;;;;;;;;;;-1:-1:-1;3419:125:5;;;;;:::i;:::-;-1:-1:-1;;;;;3519:18:5;3493:7;3519:18;;;:9;:18;;;;;;;3419:125;1824:101:2;;;;;;;;;;;;;:::i;4593:135:26:-;;;;;;;;;;-1:-1:-1;4593:135:26;;;;;:::i;:::-;;:::i;446:50::-;;;;;;;;;;;;495:1;446:50;;2603:126:9;;;;;;;;;;-1:-1:-1;2603:126:9;;;;;:::i;:::-;;:::i;5021:633:20:-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;1385:303:33:-;;;;;;:::i;:::-;;:::i;1201:85:2:-;;;;;;;;;;-1:-1:-1;1247:7:2;1273:6;-1:-1:-1;;;;;1273:6:2;1201:85;;740:89:33;;;;;;;;;;;;;:::i;2369:102:5:-;;;;;;;;;;;;;:::i;1039:744:26:-;;;;;;;;;;-1:-1:-1;1039:744:26;;;;;:::i;:::-;;:::i;631:103:33:-;;;;;;;;;;;;686:48;631:103;;6575:427:5;;;;;;;;;;-1:-1:-1;6575:427:5;;;;;:::i;:::-;;:::i;3740:189::-;;;;;;;;;;-1:-1:-1;3740:189:5;;;;;:::i;:::-;;:::i;3689:477:26:-;;;;;;;;;;-1:-1:-1;3689:477:26;;;;;:::i;:::-;;:::i;552:46::-;;;;;;;;;;;;590:8;552:46;;1923:626:9;;;;;;;;;;-1:-1:-1;1923:626:9;;;;;:::i;:::-;;:::i;3987:149:5:-;;;;;;;;;;-1:-1:-1;3987:149:5;;;;;:::i;:::-;;:::i;1694:513:33:-;;;;;;:::i;:::-;;:::i;2074:198:2:-;;;;;;;;;;-1:-1:-1;2074:198:2;;;;;:::i;:::-;;:::i;503:43:26:-;;;;;;;;;;;;541:5;503:43;;657:44;;;;;;;;;;-1:-1:-1;657:44:26;;;;;:::i;:::-;;:::i;553:101:34:-;;;;;;;;;;-1:-1:-1;642:4:34;553:101;;1169:210:33;1289:16;1307:11;1337:35;1352:8;1362:9;1337:14;:35::i;:::-;1330:42;;;;1169:210;;;;;;:::o;951:212::-;1053:4;-1:-1:-1;;;;;;1076:40:33;;-1:-1:-1;;;1076:40:33;;:80;;-1:-1:-1;;;;;;;;;;937:40:21;;;1120:36:33;1069:87;951:212;-1:-1:-1;;951:212:33:o;2158:98:5:-;2212:13;2244:5;2237:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2158:98;:::o;4444:197::-;4527:4;734:10:14;4581:32:5;734:10:14;4597:7:5;4606:6;4581:8;:32::i;:::-;-1:-1:-1;4630:4:5;;4444:197;-1:-1:-1;;;4444:197:5:o;4172:210:26:-;1094:13:2;:11;:13::i;:::-;-1:-1:-1;;;;;4249:23:26;::::1;4241:67;;;::::0;-1:-1:-1;;;4241:67:26;;13845:2:35;4241:67:26::1;::::0;::::1;13827:21:35::0;13884:2;13864:18;;;13857:30;13923:33;13903:18;;;13896:61;13974:18;;4241:67:26::1;;;;;;;;;4318:8;:20:::0;;-1:-1:-1;;;;;;4318:20:26::1;-1:-1:-1::0;;;;;4318:20:26;::::1;::::0;;::::1;::::0;;;4353:22:::1;::::0;::::1;::::0;-1:-1:-1;;4353:22:26::1;4172:210:::0;:::o;4521:862:33:-;734:10:14;4797:4:33;4773:29;4765:79;;;;-1:-1:-1;;;4765:79:33;;14205:2:35;4765:79:33;;;14187:21:35;14244:2;14224:18;;;14217:30;14283:34;14263:18;;;14256:62;-1:-1:-1;;;14334:18:35;;;14327:35;14379:19;;4765:79:33;14003:401:35;4765:79:33;4871:14;4888:55;4910:4;4917:16;4935:7;4888:13;:55::i;:::-;4871:72;;4981:12;4971:8;-1:-1:-1;;;;;;;;;;;4995:12:33;5009:16;5027:6;4958:76;;;;;;;;:::i;:::-;;;;;;;;5101:12;5132:16;-1:-1:-1;;;;;5116:50:33;;5172:9;5196:12;5222;5248:7;5269:8;5291;;5116:193;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5101:208;;5327:7;5319:57;;;;-1:-1:-1;;;5319:57:33;;16181:2:35;5319:57:33;;;16163:21:35;16220:2;16200:18;;;16193:30;16259:34;16239:18;;;16232:62;-1:-1:-1;;;16310:18:35;;;16303:35;16355:19;;5319:57:33;15979:401:35;5319:57:33;4755:628;;4521:862;;;;;;;:::o;436:111:34:-;504:4;527:13;3342:12:5;;;3255:106;527:13:34;520:20;;436:111;:::o;5203:256:5:-;5300:4;734:10:14;5356:38:5;5372:4;734:10:14;5387:6:5;5356:15;:38::i;:::-;5404:27;5414:4;5420:2;5424:6;5404:9;:27::i;:::-;-1:-1:-1;5448:4:5;;5203:256;-1:-1:-1;;;;5203:256:5:o;4388:199:26:-;1094:13:2;:11;:13::i;:::-;-1:-1:-1;;;;;4462:18:26;::::1;4454:64;;;::::0;-1:-1:-1;;;4454:64:26;;16587:2:35;4454:64:26::1;::::0;::::1;16569:21:35::0;16626:2;16606:18;;;16599:30;16665:34;16645:18;;;16638:62;-1:-1:-1;;;16716:18:35;;;16709:31;16757:19;;4454:64:26::1;16385:397:35::0;4454:64:26::1;4528:3;:18:::0;;-1:-1:-1;;;;;;4528:18:26::1;-1:-1:-1::0;;;;;4528:18:26;::::1;::::0;;::::1;::::0;;;4561:19:::1;::::0;::::1;::::0;-1:-1:-1;;4561:19:26::1;4388:199:::0;:::o;2836:113:9:-;2896:7;2922:20;:18;:20::i;5854:234:5:-;5942:4;734:10:14;5996:64:5;734:10:14;6012:7:5;6049:10;6021:25;734:10:14;6012:7:5;6021:9;:25::i;:::-;:38;;;;:::i;:::-;5996:8;:64::i;3544:139:26:-;3649:27;;;;:11;:27;;;;;3642:34;;3618:12;;3649:27;3642:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3544:139;;;:::o;1824:101:2:-;1094:13;:11;:13::i;:::-;1888:30:::1;1915:1;1888:18;:30::i;:::-;1824:101::o:0;4593:135:26:-;1094:13:2;:11;:13::i;:::-;4676:45:26::1;4693:6;4701:10;4713:7;4676:16;:45::i;:::-;4593:135:::0;;:::o;2603:126:9:-;-1:-1:-1;;;;;2698:14:9;;2672:7;2698:14;;;:7;:14;;;;;918::15;2698:24:9;827:112:15;5021:633:20;5136:13;5163:18;;5136:13;;;5163:18;5427:41;:5;5454:13;5427:26;:41::i;:::-;5482:47;:8;5512:16;5482:29;:47::i;:::-;5621:16;;;5605:1;5621:16;;;;;;;;;-1:-1:-1;;;5376:271:20;;;-1:-1:-1;5376:271:20;;-1:-1:-1;5543:13:20;;-1:-1:-1;5578:4:20;;-1:-1:-1;5605:1:20;-1:-1:-1;5621:16:20;-1:-1:-1;5376:271:20;-1:-1:-1;5021:633:20:o;1385:303:33:-;1605:76;1620:12;1634:10;1646;1658:11;1671:9;1605:14;:76::i;:::-;1385:303;;;;;:::o;740:89::-;;;;;;;;;;;;;;;;;;;:::o;2369:102:5:-;2425:13;2457:7;2450:14;;;;;:::i;1039:744:26:-;1318:3;;1251:23;;-1:-1:-1;;;;;1318:3:26;734:10:14;-1:-1:-1;;;;;1294:28:26;;1286:73;;;;-1:-1:-1;;;1286:73:26;;17251:2:35;1286:73:26;;;17233:21:35;;;17270:18;;;17263:30;17329:34;17309:18;;;17302:62;17381:18;;1286:73:26;17049:356:35;1286:73:26;1370:28;1401:23;;;:11;:23;;;;;1370:54;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1479:15;:22;1456:12;;:19;;:45;:91;;;;;1546:1;1521:15;:22;:26;1456:91;:164;;;;-1:-1:-1;1594:26:26;;;;;;1567:23;;;;1577:12;;;;1567:23;:::i;:::-;;;;;;;;:53;1456:164;1435:253;;;;-1:-1:-1;;;1435:253:26;;17888:2:35;1435:253:26;;;17870:21:35;17927:2;17907:18;;;17900:30;17966:34;17946:18;;;17939:62;-1:-1:-1;;;18017:18:35;;;18010:40;18067:19;;1435:253:26;17686:406:35;1435:253:26;1712:64;1721:10;1733:8;1743:12;;1712:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1712:64:26;;;;;;;;;;;;;;;;;;;;;;1757:8;;-1:-1:-1;1712:64:26;-1:-1:-1;1767:8:26;;;;;;1712:64;;1767:8;;;;1712:64;;;;;;;;;-1:-1:-1;1712:8:26;;-1:-1:-1;;;1712:64:26:i;:::-;1699:77;1039:744;-1:-1:-1;;;;;;;;;1039:744:26:o;6575:427:5:-;6668:4;734:10:14;6668:4:5;6749:25;734:10:14;6766:7:5;6749:9;:25::i;:::-;6722:52;;6812:15;6792:16;:35;;6784:85;;;;-1:-1:-1;;;6784:85:5;;18299:2:35;6784:85:5;;;18281:21:35;18338:2;18318:18;;;18311:30;18377:34;18357:18;;;18350:62;-1:-1:-1;;;18428:18:35;;;18421:35;18473:19;;6784:85:5;18097:401:35;6784:85:5;6903:60;6912:5;6919:7;6947:15;6928:16;:34;6903:8;:60::i;3740:189::-;3819:4;734:10:14;3873:28:5;734:10:14;3890:2:5;3894:6;3873:9;:28::i;3689:477:26:-;1094:13:2;:11;:13::i;:::-;3846:49:26;;::::1;3838:104;;;::::0;-1:-1:-1;;;3838:104:26;;18705:2:35;3838:104:26::1;::::0;::::1;18687:21:35::0;18744:2;18724:18;;;18717:30;18783:34;18763:18;;;18756:62;-1:-1:-1;;;18834:18:35;;;18827:40;18884:19;;3838:104:26::1;18503:406:35::0;3838:104:26::1;3957:9;3952:208;3972:26:::0;;::::1;3952:208;;;4053:16;;4070:1;4053:19;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;4019:11;:31;4031:15;;4047:1;4031:18;;;;;;;:::i;:::-;;;;;;;4019:31;;;;;;;;;;;:53;;;;;;;:::i;:::-;;4109:15;;4125:1;4109:18;;;;;;;:::i;:::-;;;;;;;4091:58;4129:16;;4146:1;4129:19;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;4091:58;;;;;;;:::i;:::-;;;;;;;;4000:3:::0;::::1;::::0;::::1;:::i;:::-;;;;3952:208;;1923:626:9::0;2158:8;2139:15;:27;;2131:69;;;;-1:-1:-1;;;2131:69:9;;22215:2:35;2131:69:9;;;22197:21:35;22254:2;22234:18;;;22227:30;22293:31;22273:18;;;22266:59;22342:18;;2131:69:9;22013:353:35;2131:69:9;2211:18;1125:95;2271:5;2278:7;2287:5;2294:16;2304:5;2294:9;:16::i;:::-;2242:79;;;;;;22658:25:35;;;;-1:-1:-1;;;;;22757:15:35;;;22737:18;;;22730:43;22809:15;;;;22789:18;;;22782:43;22841:18;;;22834:34;22884:19;;;22877:35;22928:19;;;22921:35;;;22630:19;;2242:79:9;;;;;;;;;;;;2232:90;;;;;;2211:111;;2333:12;2348:28;2365:10;2348:16;:28::i;:::-;2333:43;;2387:14;2404:28;2418:4;2424:1;2427;2430;2404:13;:28::i;:::-;2387:45;;2460:5;-1:-1:-1;;;;;2450:15:9;:6;-1:-1:-1;;;;;2450:15:9;;2442:58;;;;-1:-1:-1;;;2442:58:9;;23169:2:35;2442:58:9;;;23151:21:35;23208:2;23188:18;;;23181:30;23247:32;23227:18;;;23220:60;23297:18;;2442:58:9;22967:354:35;2442:58:9;2511:31;2520:5;2527:7;2536:5;2511:8;:31::i;:::-;2121:428;;;1923:626;;;;;;;:::o;3987:149:5:-;-1:-1:-1;;;;;4102:18:5;;;4076:7;4102:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;3987:149::o;1694:513:33:-;1993:207;2028:12;2054:10;2078;2102:11;2127:9;2150:14;2178:12;1993:21;:207::i;:::-;1694:513;;;;;;;:::o;2074:198:2:-;1094:13;:11;:13::i;:::-;-1:-1:-1;;;;;2162:22:2;::::1;2154:73;;;::::0;-1:-1:-1;;;2154:73:2;;23528:2:35;2154:73:2::1;::::0;::::1;23510:21:35::0;23567:2;23547:18;;;23540:30;23606:34;23586:18;;;23579:62;-1:-1:-1;;;23657:18:35;;;23650:36;23703:19;;2154:73:2::1;23326:402:35::0;2154:73:2::1;2237:28;2256:8;2237:18;:28::i;:::-;2074:198:::0;:::o;657:44:26:-;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;3307:231::-;3450:3;;3478:8;;3450:48;;-1:-1:-1;;;3450:48:26;;;;;23935:25:35;;;-1:-1:-1;;;;;3478:8:26;;;23976:18:35;;;23969:60;24045:18;;;24038:34;;;3391:13:26;;;;;;3450:3;;;:17;;23908:18:35;;3450:48:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;3517:8:26;;-1:-1:-1;;;;;3517:8:26;;3432:66;;-1:-1:-1;3307:231:26;-1:-1:-1;;;;3307:231:26:o;10457:340:5:-;-1:-1:-1;;;;;10558:19:5;;10550:68;;;;-1:-1:-1;;;10550:68:5;;24602:2:35;10550:68:5;;;24584:21:35;24641:2;24621:18;;;24614:30;24680:34;24660:18;;;24653:62;-1:-1:-1;;;24731:18:35;;;24724:34;24775:19;;10550:68:5;24400:400:35;10550:68:5;-1:-1:-1;;;;;10636:21:5;;10628:68;;;;-1:-1:-1;;;10628:68:5;;25007:2:35;10628:68:5;;;24989:21:35;25046:2;25026:18;;;25019:30;25085:34;25065:18;;;25058:62;-1:-1:-1;;;25136:18:35;;;25129:32;25178:19;;10628:68:5;24805:398:35;10628:68:5;-1:-1:-1;;;;;10707:18:5;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;10758:32;;2861:25:35;;;10758:32:5;;2834:18:35;10758:32:5;;;;;;;10457:340;;;:::o;1359:130:2:-;1247:7;1273:6;-1:-1:-1;;;;;1273:6:2;734:10:14;1422:23:2;1414:68;;;;-1:-1:-1;;;1414:68:2;;25410:2:35;1414:68:2;;;25392:21:35;;;25429:18;;;25422:30;25488:34;25468:18;;;25461:62;25540:18;;1414:68:2;25208:356:35;1608:415:34;1711:7;734:10:14;1861:4:34;-1:-1:-1;;;;;1844:22:34;;;;;;:42;;;1879:7;-1:-1:-1;;;;;1870:16:34;:5;-1:-1:-1;;;;;1870:16:34;;;1844:42;1840:113;;;1902:40;1918:5;1925:7;1934;1902:15;:40::i;:::-;1962:30;1972:5;1979:3;1984:7;1962:9;:30::i;:::-;-1:-1:-1;2009:7:34;;1608:415;-1:-1:-1;;;1608:415:34:o;11078:411:5:-;11178:24;11205:25;11215:5;11222:7;11205:9;:25::i;:::-;11178:52;;-1:-1:-1;;11244:16:5;:37;11240:243;;11325:6;11305:16;:26;;11297:68;;;;-1:-1:-1;;;11297:68:5;;25771:2:35;11297:68:5;;;25753:21:35;25810:2;25790:18;;;25783:30;25849:31;25829:18;;;25822:59;25898:18;;11297:68:5;25569:353:35;11297:68:5;11407:51;11416:5;11423:7;11451:6;11432:16;:25;11407:8;:51::i;:::-;11168:321;11078:411;;;:::o;7456:788::-;-1:-1:-1;;;;;7552:18:5;;7544:68;;;;-1:-1:-1;;;7544:68:5;;26129:2:35;7544:68:5;;;26111:21:35;26168:2;26148:18;;;26141:30;26207:34;26187:18;;;26180:62;-1:-1:-1;;;26258:18:35;;;26251:35;26303:19;;7544:68:5;25927:401:35;7544:68:5;-1:-1:-1;;;;;7630:16:5;;7622:64;;;;-1:-1:-1;;;7622:64:5;;26535:2:35;7622:64:5;;;26517:21:35;26574:2;26554:18;;;26547:30;26613:34;26593:18;;;26586:62;-1:-1:-1;;;26664:18:35;;;26657:33;26707:19;;7622:64:5;26333:399:35;7622:64:5;-1:-1:-1;;;;;7768:15:5;;7746:19;7768:15;;;:9;:15;;;;;;7801:21;;;;7793:72;;;;-1:-1:-1;;;7793:72:5;;26939:2:35;7793:72:5;;;26921:21:35;26978:2;26958:18;;;26951:30;27017:34;26997:18;;;26990:62;-1:-1:-1;;;27068:18:35;;;27061:36;27114:19;;7793:72:5;26737:402:35;7793:72:5;-1:-1:-1;;;;;7899:15:5;;;;;;;:9;:15;;;;;;7917:20;;;7899:38;;8114:13;;;;;;;;;;:23;;;;;;8163:26;;;;;;7931:6;2861:25:35;;2849:2;2834:18;;2715:177;8163:26:5;;;;;;;;8200:37;780:250:32;3695:262:20;3748:7;3779:4;-1:-1:-1;;;;;3788:11:20;3771:28;;:63;;;;;3820:14;3803:13;:31;3771:63;3767:184;;;-1:-1:-1;3857:22:20;;3695:262::o;3767:184::-;3917:23;4054:81;;;1929:95;4054:81;;;31747:25:35;4077:11:20;31788:18:35;;;31781:34;;;;4090:14:20;31831:18:35;;;31824:34;4106:13:20;31874:18:35;;;31867:34;4129:4:20;31917:19:35;;;31910:61;4018:7:20;;31719:19:35;;4054:81:20;;;;;;;;;;;;4044:92;;;;;;4037:99;;3963:180;;2426:187:2;2499:16;2518:6;;-1:-1:-1;;;;;2534:17:2;;;-1:-1:-1;;;;;;2534:17:2;;;;;;2566:40;;2518:6;;;;;;;2566:40;;2499:16;2566:40;2489:124;2426:187;:::o;780:250:32:-;868:17;878:6;868:9;:17::i;:::-;864:160;;;901:40;927:3;933:7;901:17;:40::i;:::-;780:250;;;:::o;864:160::-;972:41;-1:-1:-1;;;;;972:27:32;;1000:3;1005:7;972:27;:41::i;3367:268:16:-;3461:13;1371:66;3490:47;;3486:143;;3560:15;3569:5;3560:8;:15::i;:::-;3553:22;;;;3486:143;3613:5;3606:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2213:797:33;2418:14;2434:16;2454:68;2472:12;2486:10;2498;2510:11;2454:17;:68::i;:::-;2417:105;;;;2550:1;2541:6;:10;2533:51;;;;-1:-1:-1;;;2533:51:33;;27346:2:35;2533:51:33;;;27328:21:35;27385:2;27365:18;;;27358:30;27424;27404:18;;;27397:58;27472:18;;2533:51:33;27144:352:35;2533:51:33;2595:24;2622:29;2638:12;2622:15;:29::i;:::-;2595:56;;2661:23;2698:11;2711:10;2723:6;2731:8;2687:53;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;2661:79;;2750:20;584:41;2805:10;2773:43;;;;;;;;;:::i;:::-;;;;;;;;;;;;;2750:66;;2827:15;2845:69;2861:10;439:1:26;2895:7:33;2904:9;2845:15;:69::i;:::-;2827:87;;2967:10;2953:12;-1:-1:-1;;;;;2930:73:33;2944:7;2930:73;2979:10;2991:11;2930:73;;;;;;;:::i;:::-;;;;;;;;2407:603;;;;;;2213:797;;;;;:::o;7271:751::-;7487:19;;;;:9;:19;;;;;;7454:12;;7487:19;;7486:20;7478:60;;;;-1:-1:-1;;;7478:60:33;;28819:2:35;7478:60:33;;;28801:21:35;28858:2;28838:18;;;28831:30;28897:29;28877:18;;;28870:57;28944:18;;7478:60:33;28617:351:35;7478:60:33;7550:17;7569:20;7604:8;7593:38;;;;;;;;;;;;:::i;:::-;7642:19;;;;:9;:19;;;;;:26;;-1:-1:-1;;7642:26:33;7664:4;7642:26;;;7549:82;;-1:-1:-1;7549:82:33;-1:-1:-1;7683:32:33;;;7679:312;;7731:44;7745:10;7757:8;7767:7;7731:13;:44::i;:::-;7679:312;;;686:48;7796:9;:41;7792:199;;7853:54;7877:10;7889:8;7899:7;7853:23;:54::i;7792:199::-;7938:42;;-1:-1:-1;;;7938:42:33;;30022:2:35;7938:42:33;;;30004:21:35;;;30041:18;;;30034:30;30100:34;30080:18;;;30073:62;30152:18;;7938:42:33;29820:356:35;7792:199:33;8008:7;7271:751;-1:-1:-1;;;;;;;7271:751:33:o;3080:203:9:-;-1:-1:-1;;;;;3200:14:9;;3140:15;3200:14;;;:7;:14;;;;;918::15;;1050:1;1032:19;;;;918:14;3259:17:9;3157:126;3080:203;;;:::o;4768:165:20:-;4845:7;4871:55;4893:20;:18;:20::i;:::-;4915:10;8536:4:19;8530:11;-1:-1:-1;;;8554:23:19;;8606:4;8597:14;;8590:39;;;;8658:4;8649:14;;8642:34;8712:4;8697:20;;;8336:397;6598:232;6683:7;6703:17;6722:18;6744:25;6755:4;6761:1;6764;6767;6744:10;:25::i;:::-;6702:67;;;;6779:18;6791:5;6779:11;:18::i;:::-;-1:-1:-1;6814:9:19;-1:-1:-1;6598:232:19;;;;;;;:::o;3016:973:33:-;3300:14;3316:16;3336:68;3354:12;3368:10;3380;3392:11;3336:17;:68::i;:::-;3299:105;;;;3471:1;3462:6;:10;3454:51;;;;-1:-1:-1;;;3454:51:33;;27346:2:35;3454:51:33;;;27328:21:35;27385:2;27365:18;;;27358:30;27424;27404:18;;;27397:58;27472:18;;3454:51:33;27144:352:35;3454:51:33;3516:24;3543:29;3559:12;3543:15;:29::i;:::-;3516:56;;3582:23;3619:11;3632:10;3644:6;3652:8;3662:14;3678:12;3608:83;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;3582:109;;3701:20;686:48;3765:10;3724:52;;;;;;;;;:::i;:::-;;;;;;;;;;;;;3701:75;;3787:15;3805:69;3821:10;439:1:26;3855:7:33;3864:9;3805:15;:69::i;:::-;3787:87;;3934:10;3920:12;-1:-1:-1;;;;;3890:92:33;3911:7;3890:92;3946:10;3958:11;3971:10;3890:92;;;;;;;;:::i;:::-;;;;;;;;3289:700;;;;;;3016:973;;;;;;;:::o;385:137:32:-;442:4;-1:-1:-1;;;;;466:21:32;;;;:48;;-1:-1:-1;;;;;;491:23:32;;336:42;491:23;458:57;385:137;-1:-1:-1;;385:137:32:o;2647:312:13:-;2761:6;2736:21;:31;;2728:73;;;;-1:-1:-1;;;2728:73:13;;32184:2:35;2728:73:13;;;32166:21:35;32223:2;32203:18;;;32196:30;32262:31;32242:18;;;32235:59;32311:18;;2728:73:13;31982:353:35;2728:73:13;2813:12;2831:9;-1:-1:-1;;;;;2831:14:13;2853:6;2831:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2812:52;;;2882:7;2874:78;;;;-1:-1:-1;;;2874:78:13;;32752:2:35;2874:78:13;;;32734:21:35;32791:2;32771:18;;;32764:30;32830:34;32810:18;;;32803:62;32901:28;32881:18;;;32874:56;32947:19;;2874:78:13;32550:422:35;941:175:12;1050:58;;-1:-1:-1;;;;;459:32:35;;1050:58:12;;;441:51:35;508:18;;;501:34;;;1023:86:12;;1043:5;;-1:-1:-1;;;1073:23:12;414:18:35;;1050:58:12;;;;-1:-1:-1;;1050:58:12;;;;;;;;;;;;;;-1:-1:-1;;;;;1050:58:12;-1:-1:-1;;;;;;1050:58:12;;;;;;;;;;1023:19;:86::i;2059:405:16:-;2118:13;2143:11;2157:16;2168:4;2157:10;:16::i;:::-;2281:14;;;2292:2;2281:14;;;;;;;;;2143:30;;-1:-1:-1;2261:17:16;;2281:14;;;;;;;;;-1:-1:-1;;;2371:16:16;;;-1:-1:-1;2416:4:16;2407:14;;2400:28;;;;-1:-1:-1;2371:16:16;2059:405::o;660:449:34:-;826:14;;734:10:14;-1:-1:-1;;;;;914:23:34;;;;910:105;;953:51;969:12;983:7;992:11;953:15;:51::i;:::-;1024:32;1030:12;1044:11;1024:5;:32::i;:::-;-1:-1:-1;;1088:13:34;;1075:11;;-1:-1:-1;660:449:34;;;;;;;;:::o;1461:114:32:-;1546:22;;1516:14;33122:15:35;;;-1:-1:-1;;33118:53:35;1546:22:32;;;33106:66:35;1516:14:32;33188:12:35;;1546:22:32;;;;;;;;;;;;1542:26;;1461:114;;;:::o;2005:1296:26:-;2171:7;2215:21;;;:11;:21;;;;;2190:46;;2171:7;;2215:21;2190:46;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2273:1;2254:9;:16;:20;2246:75;;;;-1:-1:-1;;;2246:75:26;;33413:2:35;2246:75:26;;;33395:21:35;33452:2;33432:18;;;33425:30;33491:34;33471:18;;;33464:62;-1:-1:-1;;;33542:18:35;;;33535:40;33592:19;;2246:75:26;33211:406:35;2246:75:26;2332:29;2375:7;2371:414;;2452:5;2459:26;2487:9;2498:8;2508:9;2519:1;2441:80;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;2422:99;;2371:414;;;495:1;2542:7;:33;2538:247;;2621:5;2628:27;2657:9;2668:8;2678:9;2689:1;2610:81;;;;;;;;;;;;;:::i;2538:247::-;2722:52;;-1:-1:-1;;;2722:52:26;;34819:2:35;2722:52:26;;;34801:21:35;34858:2;34838:18;;;34831:30;34897:34;34877:18;;;34870:62;-1:-1:-1;;;34948:18:35;;;34941:32;34990:19;;2722:52:26;34617:398:35;2722:52:26;2796:13;2811:11;2826:35;2841:8;2851:9;2826:14;:35::i;:::-;2795:66;;;;2885:1;2879:3;:7;2871:51;;;;-1:-1:-1;;;2871:51:26;;35222:2:35;2871:51:26;;;35204:21:35;35261:2;35241:18;;;35234:30;35300:33;35280:18;;;35273:61;35351:18;;2871:51:26;35020:355:35;2871:51:26;-1:-1:-1;;;;;2936:19:26;;2932:277;;2992:3;2979:9;:16;;2971:54;;;;-1:-1:-1;;;2971:54:26;;35582:2:35;2971:54:26;;;35564:21:35;35621:2;35601:18;;;35594:30;35660:27;35640:18;;;35633:55;35705:18;;2971:54:26;35380:349:35;2971:54:26;2932:277;;;3056:73;3090:5;3098:10;3118:4;3125:3;3056:26;:73::i;:::-;3188:3;;3143:55;;3172:5;;-1:-1:-1;;;;;3188:3:26;3194;3143:21;:55::i;:::-;3226:3;;:68;;-1:-1:-1;;;3226:68:26;;-1:-1:-1;;;;;3226:3:26;;;;:15;;3249:9;;3226:68;;3260:8;;3270:16;;3288:5;;3226:68;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;3995:520:33:-;4107:22;4131:26;4159:14;4175:16;4219:8;4195:88;;;;;;;;;;;;:::i;:::-;4106:177;;;;;;;;4293:23;4319:32;4337:13;1435:2:32;1426:12;1420:19;;1304:151;4319:32:33;4293:58;;4361:61;4376:15;4393:10;4405:6;4413:8;4361:14;:61::i;:::-;;;4461:10;4451:8;-1:-1:-1;;;;;;;;;;;4473:9:33;4484:15;4501:6;4438:70;;;;;;;;:::i;:::-;;;;;;;;4096:419;;;;;3995:520;;;:::o;5389:1876::-;5524:23;5561:26;5601:14;5629:16;5659:24;5697;5745:8;5734:68;;;;;;;;;;;;:::i;:::-;5510:292;;;;;;;;;;;;5813:23;5839:32;5857:13;1435:2:32;1426:12;1420:19;;1304:151;5839:32:33;5813:58;;5882:15;5903:59;5926:4;5933:10;5945:6;5953:8;5903:14;:59::i;:::-;-1:-1:-1;5881:81:33;-1:-1:-1;;;;;;5978:26:33;;1702:19:13;5973:376:33;;6022:69;6044:4;6051:30;6069:11;1435:2:32;1426:12;1420:19;;1304:151;6051:30:33;6083:7;6022:13;:69::i;:::-;;6133:10;6123:8;-1:-1:-1;;;;;;;;;;;6145:10:33;6157:30;6175:11;1435:2:32;1426:12;1420:19;;1304:151;6157:30:33;6189:7;6110:87;;;;;;;;:::i;:::-;;;;;;;;6249:10;6239:8;6216:102;6261:10;6273:15;6290:5;6297:20;;;;;;;;;;;;;;;;;6216:102;;;;;;;;;:::i;:::-;;;;;;;;6332:7;;;;;;;;5389:1876;;;:::o;5973:376::-;6359:41;6439:34;;;6487:10;6511;6535:7;6556:15;6585:8;6607:11;6403:225;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;6403:225:33;;;;;;;;;;;;;;-1:-1:-1;;;;;6403:225:33;-1:-1:-1;;;;;;6403:225:33;;;;;;;;;;;-1:-1:-1;;;6677:125:33;6724:9;6685:4;;6747:3;6764:28;6677:33;:125::i;:::-;6639:163;;;;6817:7;6813:446;;;6878:10;6868:8;6845:90;6890:10;6902:15;6919:4;6925:9;;;;;;;;;;;;6845:90;;;;;;;;;:::i;:::-;;;;;;;;6813:446;;;6966:69;6988:4;6995:30;7013:11;1435:2:32;1426:12;1420:19;;1304:151;6995:30:33;7027:7;6966:13;:69::i;:::-;;7077:10;7067:8;-1:-1:-1;;;;;;;;;;;7089:10:33;7101:30;7119:11;1435:2:32;1426:12;1420:19;;1304:151;7101:30:33;7133:7;7054:87;;;;;;;;:::i;:::-;;;;;;;;7193:10;7183:8;7160:88;7205:10;7217:15;7234:5;7241:6;7160:88;;;;;;;;;:::i;:::-;;;;;;;;6813:446;5500:1765;;;;;;;;;;;5389:1876;;;:::o;5009:1456:19:-;5097:7;;6021:66;6008:79;;6004:161;;;-1:-1:-1;6119:1:19;;-1:-1:-1;6123:30:19;6103:51;;6004:161;6276:24;;;6259:14;6276:24;;;;;;;;;39581:25:35;;;39654:4;39642:17;;39622:18;;;39615:45;;;;39676:18;;;39669:34;;;39719:18;;;39712:34;;;6276:24:19;;39553:19:35;;6276:24:19;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6276:24:19;;-1:-1:-1;;6276:24:19;;;-1:-1:-1;;;;;;;6314:20:19;;6310:101;;6366:1;6370:29;6350:50;;;;;;;6310:101;6429:6;6437:20;;-1:-1:-1;5009:1456:19;-1:-1:-1;;;;;5009:1456:19:o;570:511::-;647:20;638:5;:29;;;;;;;;:::i;:::-;;634:441;;570:511;:::o;634:441::-;743:29;734:5;:38;;;;;;;;:::i;:::-;;730:345;;788:34;;-1:-1:-1;;;788:34:19;;39959:2:35;788:34:19;;;39941:21:35;39998:2;39978:18;;;39971:30;40037:26;40017:18;;;40010:54;40081:18;;788:34:19;39757:348:35;730:345:19;852:35;843:5;:44;;;;;;;;:::i;:::-;;839:236;;903:41;;-1:-1:-1;;;903:41:19;;40312:2:35;903:41:19;;;40294:21:35;40351:2;40331:18;;;40324:30;40390:33;40370:18;;;40363:61;40441:18;;903:41:19;40110:355:35;839:236:19;974:30;965:5;:39;;;;;;;;:::i;:::-;;961:114;;1020:44;;-1:-1:-1;;;1020:44:19;;40672:2:35;1020:44:19;;;40654:21:35;40711:2;40691:18;;;40684:30;40750:34;40730:18;;;40723:62;-1:-1:-1;;;40801:18:35;;;40794:32;40843:19;;1020:44:19;40470:398:35;5196:642:12;5615:23;5641:69;5669:4;5641:69;;;;;;;;;;;;;;;;;5649:5;-1:-1:-1;;;;;5641:27:12;;;:69;;;;;:::i;:::-;5615:95;;5728:10;:17;5749:1;5728:22;:56;;;;5765:10;5754:30;;;;;;;;;;;;:::i;:::-;5720:111;;;;-1:-1:-1;;;5720:111:12;;41075:2:35;5720:111:12;;;41057:21:35;41114:2;41094:18;;;41087:30;41153:34;41133:18;;;41126:62;-1:-1:-1;;;41204:18:35;;;41197:40;41254:19;;5720:111:12;40873:406:35;2536:245:16;2597:7;2669:4;2633:40;;2696:2;2687:11;;2683:69;;;2721:20;;-1:-1:-1;;;2721:20:16;;;;;;;;;;;9375:659:5;-1:-1:-1;;;;;9458:21:5;;9450:67;;;;-1:-1:-1;;;9450:67:5;;41486:2:35;9450:67:5;;;41468:21:35;41525:2;41505:18;;;41498:30;41564:34;41544:18;;;41537:62;-1:-1:-1;;;41615:18:35;;;41608:31;41656:19;;9450:67:5;41284:397:35;9450:67:5;-1:-1:-1;;;;;9613:18:5;;9588:22;9613:18;;;:9;:18;;;;;;9649:24;;;;9641:71;;;;-1:-1:-1;;;9641:71:5;;41888:2:35;9641:71:5;;;41870:21:35;41927:2;41907:18;;;41900:30;41966:34;41946:18;;;41939:62;-1:-1:-1;;;42017:18:35;;;42010:32;42059:19;;9641:71:5;41686:398:35;9641:71:5;-1:-1:-1;;;;;9746:18:5;;;;;;:9;:18;;;;;;;;9767:23;;;9746:44;;9883:12;:22;;;;;;;9931:37;2861:25:35;;;9746:18:5;;;9931:37;;2834:18:35;9931:37:5;;;;;;;780:250:32;;;:::o;1355:203:12:-;1482:68;;-1:-1:-1;;;;;42347:15:35;;;1482:68:12;;;42329:34:35;42399:15;;42379:18;;;42372:43;42431:18;;;42424:34;;;1455:96:12;;1475:5;;-1:-1:-1;;;1505:27:12;42264:18:35;;1482:68:12;42089:375:35;1818:573:12;2143:10;;;2142:62;;-1:-1:-1;2159:39:12;;-1:-1:-1;;;2159:39:12;;2183:4;2159:39;;;42681:34:35;-1:-1:-1;;;;;42751:15:35;;;42731:18;;;42724:43;2159:15:12;;;;;42616:18:35;;2159:39:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;2142:62;2121:163;;;;-1:-1:-1;;;2121:163:12;;43169:2:35;2121:163:12;;;43151:21:35;43208:2;43188:18;;;43181:30;43247:34;43227:18;;;43220:62;-1:-1:-1;;;43298:18:35;;;43291:52;43360:19;;2121:163:12;42967:418:35;2121:163:12;2321:62;;-1:-1:-1;;;;;459:32:35;;2321:62:12;;;441:51:35;508:18;;;501:34;;;2294:90:12;;2314:5;;-1:-1:-1;;;2344:22:12;414:18:35;;2321:62:12;267:274:35;1115:487:34;1291:14;1307:16;1356:13;1339;;:30;1335:178;;1394:11;1385:20;;1335:178;;;1483:19;1489:13;1483:2;:19;:::i;:::-;1466:13;;;1460:19;;;:::i;:::-;1446:33;;:11;:33;:::i;:::-;1445:57;;;;:::i;:::-;1436:66;;1335:178;1523:31;1529:16;1547:6;1523:5;:31::i;:::-;-1:-1:-1;1581:13:34;;1115:487;;;;;;;:::o;1100:1280:31:-;1257:4;1263:12;1323:15;1348:13;1371:24;1408:8;1398:19;;-1:-1:-1;;;;;1398:19:31;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1398:19:31;;1371:46;;1914:1;1885;1848:9;1842:16;1810:4;1799:9;1795:20;1761:1;1723:7;1694:4;1672:267;1660:279;;2006:16;1995:27;;2050:8;2041:7;2038:21;2035:76;;;2089:8;2078:19;;2035:76;2196:7;2183:11;2176:28;2316:7;2313:1;2306:4;2293:11;2289:22;2274:50;2351:8;;;;-1:-1:-1;1100:1280:31;-1:-1:-1;;;;;;1100:1280:31:o;4108:223:13:-;4241:12;4272:52;4294:6;4302:4;4308:1;4311:12;4272:21;:52::i;8520:535:5:-;-1:-1:-1;;;;;8603:21:5;;8595:65;;;;-1:-1:-1;;;8595:65:5;;45361:2:35;8595:65:5;;;45343:21:35;45400:2;45380:18;;;45373:30;45439:33;45419:18;;;45412:61;45490:18;;8595:65:5;45159:355:35;8595:65:5;8747:6;8731:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;8899:18:5;;;;;;:9;:18;;;;;;;;:28;;;;;;8952:37;2861:25:35;;;8952:37:5;;2834:18:35;8952:37:5;;;;;;;4593:135:26;;:::o;5165:446:13:-;5330:12;5387:5;5362:21;:30;;5354:81;;;;-1:-1:-1;;;5354:81:13;;45721:2:35;5354:81:13;;;45703:21:35;45760:2;45740:18;;;45733:30;45799:34;45779:18;;;45772:62;-1:-1:-1;;;45850:18:35;;;45843:36;45896:19;;5354:81:13;45519:402:35;5354:81:13;5446:12;5460:23;5487:6;-1:-1:-1;;;;;5487:11:13;5506:5;5513:4;5487:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5445:73;;;;5535:69;5562:6;5570:7;5579:10;5591:12;7851;7879:7;7875:418;;;7906:10;:17;7927:1;7906:22;7902:286;;-1:-1:-1;;;;;1702:19:13;;;8113:60;;;;-1:-1:-1;;;8113:60:13;;46420:2:35;8113:60:13;;;46402:21:35;46459:2;46439:18;;;46432:30;46498:31;46478:18;;;46471:59;46547:18;;8113:60:13;46218:353:35;8113:60:13;-1:-1:-1;8208:10:13;8201:17;;7875:418;8249:33;8257:10;8269:12;8980:17;;:21;8976:379;;9208:10;9202:17;9264:15;9251:10;9247:2;9243:19;9236:44;8976:379;9331:12;9324:20;;-1:-1:-1;;;9324:20:13;;;;;;;;:::i;14:248:35:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:35;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:35:o;546:286::-;604:6;657:2;645:9;636:7;632:23;628:32;625:52;;;673:1;670;663:12;625:52;699:23;;-1:-1:-1;;;;;;751:32:35;;741:43;;731:71;;798:1;795;788:12;731:71;821:5;546:286;-1:-1:-1;;;546:286:35:o;1029:250::-;1114:1;1124:113;1138:6;1135:1;1132:13;1124:113;;;1214:11;;;1208:18;1195:11;;;1188:39;1160:2;1153:10;1124:113;;;-1:-1:-1;;1271:1:35;1253:16;;1246:27;1029:250::o;1284:271::-;1326:3;1364:5;1358:12;1391:6;1386:3;1379:19;1407:76;1476:6;1469:4;1464:3;1460:14;1453:4;1446:5;1442:16;1407:76;:::i;:::-;1537:2;1516:15;-1:-1:-1;;1512:29:35;1503:39;;;;1544:4;1499:50;;1284:271;-1:-1:-1;;1284:271:35:o;1560:220::-;1709:2;1698:9;1691:21;1672:4;1729:45;1770:2;1759:9;1755:18;1747:6;1729:45;:::i;1785:131::-;-1:-1:-1;;;;;1860:31:35;;1850:42;;1840:70;;1906:1;1903;1896:12;1921:315;1989:6;1997;2050:2;2038:9;2029:7;2025:23;2021:32;2018:52;;;2066:1;2063;2056:12;2018:52;2105:9;2092:23;2124:31;2149:5;2124:31;:::i;:::-;2174:5;2226:2;2211:18;;;;2198:32;;-1:-1:-1;;;1921:315:35:o;2463:247::-;2522:6;2575:2;2563:9;2554:7;2550:23;2546:32;2543:52;;;2591:1;2588;2581:12;2543:52;2630:9;2617:23;2649:31;2674:5;2649:31;:::i;2897:127::-;2958:10;2953:3;2949:20;2946:1;2939:31;2989:4;2986:1;2979:15;3013:4;3010:1;3003:15;3029:275;3100:2;3094:9;3165:2;3146:13;;-1:-1:-1;;3142:27:35;3130:40;;-1:-1:-1;;;;;3185:34:35;;3221:22;;;3182:62;3179:88;;;3247:18;;:::i;:::-;3283:2;3276:22;3029:275;;-1:-1:-1;3029:275:35:o;3309:186::-;3357:4;-1:-1:-1;;;;;3382:6:35;3379:30;3376:56;;;3412:18;;:::i;:::-;-1:-1:-1;3478:2:35;3457:15;-1:-1:-1;;3453:29:35;3484:4;3449:40;;3309:186::o;3500:462::-;3542:5;3595:3;3588:4;3580:6;3576:17;3572:27;3562:55;;3613:1;3610;3603:12;3562:55;3649:6;3636:20;3680:48;3696:31;3724:2;3696:31;:::i;:::-;3680:48;:::i;:::-;3753:2;3744:7;3737:19;3799:3;3792:4;3787:2;3779:6;3775:15;3771:26;3768:35;3765:55;;;3816:1;3813;3806:12;3765:55;3881:2;3874:4;3866:6;3862:17;3855:4;3846:7;3842:18;3829:55;3929:1;3904:16;;;3922:4;3900:27;3893:38;;;;3908:7;3500:462;-1:-1:-1;;;3500:462:35:o;3967:347::-;4018:8;4028:6;4082:3;4075:4;4067:6;4063:17;4059:27;4049:55;;4100:1;4097;4090:12;4049:55;-1:-1:-1;4123:20:35;;-1:-1:-1;;;;;4155:30:35;;4152:50;;;4198:1;4195;4188:12;4152:50;4235:4;4227:6;4223:17;4211:29;;4287:3;4280:4;4271:6;4263;4259:19;4255:30;4252:39;4249:59;;;4304:1;4301;4294:12;4319:970;4443:6;4451;4459;4467;4475;4483;4491;4544:3;4532:9;4523:7;4519:23;4515:33;4512:53;;;4561:1;4558;4551:12;4512:53;4597:9;4584:23;4574:33;;4658:2;4647:9;4643:18;4630:32;-1:-1:-1;;;;;4722:2:35;4714:6;4711:14;4708:34;;;4738:1;4735;4728:12;4708:34;4761:49;4802:7;4793:6;4782:9;4778:22;4761:49;:::i;:::-;4751:59;;4857:2;4846:9;4842:18;4829:32;4819:42;;4911:2;4900:9;4896:18;4883:32;4870:45;;4924:31;4949:5;4924:31;:::i;:::-;4974:5;;-1:-1:-1;5026:3:35;5011:19;;4998:33;;-1:-1:-1;5084:3:35;5069:19;;5056:33;;5101:16;;;5098:36;;;5130:1;5127;5120:12;5098:36;;5169:60;5221:7;5210:8;5199:9;5195:24;5169:60;:::i;:::-;4319:970;;;;-1:-1:-1;4319:970:35;;-1:-1:-1;4319:970:35;;;;5143:86;;-1:-1:-1;;;4319:970:35:o;5294:456::-;5371:6;5379;5387;5440:2;5428:9;5419:7;5415:23;5411:32;5408:52;;;5456:1;5453;5446:12;5408:52;5495:9;5482:23;5514:31;5539:5;5514:31;:::i;:::-;5564:5;-1:-1:-1;5621:2:35;5606:18;;5593:32;5634:33;5593:32;5634:33;:::i;:::-;5294:456;;5686:7;;-1:-1:-1;;;5740:2:35;5725:18;;;;5712:32;;5294:456::o;6334:180::-;6393:6;6446:2;6434:9;6425:7;6421:23;6417:32;6414:52;;;6462:1;6459;6452:12;6414:52;-1:-1:-1;6485:23:35;;6334:180;-1:-1:-1;6334:180:35:o;6927:1259::-;7333:3;7328;7324:13;7316:6;7312:26;7301:9;7294:45;7275:4;7358:2;7396:3;7391:2;7380:9;7376:18;7369:31;7423:46;7464:3;7453:9;7449:19;7441:6;7423:46;:::i;:::-;7517:9;7509:6;7505:22;7500:2;7489:9;7485:18;7478:50;7551:33;7577:6;7569;7551:33;:::i;:::-;7615:2;7600:18;;7593:34;;;-1:-1:-1;;;;;7664:32:35;;7658:3;7643:19;;7636:61;7684:3;7713:19;;7706:35;;;7778:22;;;7772:3;7757:19;;7750:51;7850:13;;7872:22;;;7948:15;;;;-1:-1:-1;7910:15:35;;;;-1:-1:-1;7991:169:35;8005:6;8002:1;7999:13;7991:169;;;8066:13;;8054:26;;8135:15;;;;8100:12;;;;8027:1;8020:9;7991:169;;;-1:-1:-1;8177:3:35;;6927:1259;-1:-1:-1;;;;;;;;;;;;6927:1259:35:o;8191:661::-;8295:6;8303;8311;8319;8327;8380:3;8368:9;8359:7;8355:23;8351:33;8348:53;;;8397:1;8394;8387:12;8348:53;8436:9;8423:23;8455:31;8480:5;8455:31;:::i;:::-;8505:5;-1:-1:-1;8557:2:35;8542:18;;8529:32;;-1:-1:-1;8612:2:35;8597:18;;8584:32;-1:-1:-1;;;;;8628:30:35;;8625:50;;;8671:1;8668;8661:12;8625:50;8694:49;8735:7;8726:6;8715:9;8711:22;8694:49;:::i;:::-;8191:661;;;;-1:-1:-1;8684:59:35;;8790:2;8775:18;;8762:32;;-1:-1:-1;8841:3:35;8826:19;8813:33;;8191:661;-1:-1:-1;;;8191:661:35:o;8857:923::-;8974:6;8982;8990;8998;9006;9014;9022;9075:3;9063:9;9054:7;9050:23;9046:33;9043:53;;;9092:1;9089;9082:12;9043:53;9128:9;9115:23;9105:33;;9185:2;9174:9;9170:18;9157:32;9147:42;;9240:2;9229:9;9225:18;9212:32;-1:-1:-1;;;;;9304:2:35;9296:6;9293:14;9290:34;;;9320:1;9317;9310:12;9290:34;9359:58;9409:7;9400:6;9389:9;9385:22;9359:58;:::i;:::-;9436:8;;-1:-1:-1;9333:84:35;-1:-1:-1;9518:2:35;9503:18;;9490:32;;-1:-1:-1;9575:3:35;9560:19;;9547:33;;-1:-1:-1;9592:16:35;;;9589:36;;;9621:1;9618;9611:12;9785:367;9848:8;9858:6;9912:3;9905:4;9897:6;9893:17;9889:27;9879:55;;9930:1;9927;9920:12;9879:55;-1:-1:-1;9953:20:35;;-1:-1:-1;;;;;9985:30:35;;9982:50;;;10028:1;10025;10018:12;9982:50;10065:4;10057:6;10053:17;10041:29;;10125:3;10118:4;10108:6;10105:1;10101:14;10093:6;10089:27;10085:38;10082:47;10079:67;;;10142:1;10139;10132:12;10157:784;10290:6;10298;10306;10314;10367:2;10355:9;10346:7;10342:23;10338:32;10335:52;;;10383:1;10380;10373:12;10335:52;10423:9;10410:23;-1:-1:-1;;;;;10493:2:35;10485:6;10482:14;10479:34;;;10509:1;10506;10499:12;10479:34;10548:70;10610:7;10601:6;10590:9;10586:22;10548:70;:::i;:::-;10637:8;;-1:-1:-1;10522:96:35;-1:-1:-1;10725:2:35;10710:18;;10697:32;;-1:-1:-1;10741:16:35;;;10738:36;;;10770:1;10767;10760:12;10738:36;;10809:72;10873:7;10862:8;10851:9;10847:24;10809:72;:::i;:::-;10157:784;;;;-1:-1:-1;10900:8:35;-1:-1:-1;;;;10157:784:35:o;10946:829::-;11057:6;11065;11073;11081;11089;11097;11105;11158:3;11146:9;11137:7;11133:23;11129:33;11126:53;;;11175:1;11172;11165:12;11126:53;11214:9;11201:23;11233:31;11258:5;11233:31;:::i;:::-;11283:5;-1:-1:-1;11340:2:35;11325:18;;11312:32;11353:33;11312:32;11353:33;:::i;:::-;11405:7;-1:-1:-1;11459:2:35;11444:18;;11431:32;;-1:-1:-1;11510:2:35;11495:18;;11482:32;;-1:-1:-1;11566:3:35;11551:19;;11538:33;11615:4;11602:18;;11590:31;;11580:59;;11635:1;11632;11625:12;11580:59;10946:829;;;;-1:-1:-1;10946:829:35;;;;11658:7;11712:3;11697:19;;11684:33;;-1:-1:-1;11764:3:35;11749:19;;;11736:33;;10946:829;-1:-1:-1;;10946:829:35:o;11780:388::-;11848:6;11856;11909:2;11897:9;11888:7;11884:23;11880:32;11877:52;;;11925:1;11922;11915:12;11877:52;11964:9;11951:23;11983:31;12008:5;11983:31;:::i;:::-;12033:5;-1:-1:-1;12090:2:35;12075:18;;12062:32;12103:33;12062:32;12103:33;:::i;:::-;12155:7;12145:17;;;11780:388;;;;;:::o;12173:1080::-;12313:6;12321;12329;12337;12345;12353;12361;12414:3;12402:9;12393:7;12389:23;12385:33;12382:53;;;12431:1;12428;12421:12;12382:53;12470:9;12457:23;12489:31;12514:5;12489:31;:::i;:::-;12539:5;-1:-1:-1;12591:2:35;12576:18;;12563:32;;-1:-1:-1;12646:2:35;12631:18;;12618:32;-1:-1:-1;;;;;12699:14:35;;;12696:34;;;12726:1;12723;12716:12;12696:34;12749:49;12790:7;12781:6;12770:9;12766:22;12749:49;:::i;:::-;12739:59;;12845:2;12834:9;12830:18;12817:32;12807:42;;12896:3;12885:9;12881:19;12868:33;12858:43;;12954:3;12943:9;12939:19;12926:33;12910:49;;12984:2;12974:8;12971:16;12968:36;;;13000:1;12997;12990:12;12968:36;13023:51;13066:7;13055:8;13044:9;13040:24;13023:51;:::i;:::-;13013:61;;13127:3;13116:9;13112:19;13099:33;13083:49;;13157:2;13147:8;13144:16;13141:36;;;13173:1;13170;13163:12;13141:36;;13196:51;13239:7;13228:8;13217:9;13213:24;13196:51;:::i;:::-;13186:61;;;12173:1080;;;;;;;;;;:::o;13258:380::-;13337:1;13333:12;;;;13380;;;13401:61;;13455:4;13447:6;13443:17;13433:27;;13401:61;13508:2;13500:6;13497:14;13477:18;13474:38;13471:161;;13554:10;13549:3;13545:20;13542:1;13535:31;13589:4;13586:1;13579:15;13617:4;13614:1;13607:15;14409:386;14612:2;14601:9;14594:21;14575:4;14632:45;14673:2;14662:9;14658:18;14650:6;14632:45;:::i;:::-;-1:-1:-1;;;;;14713:32:35;;;;14708:2;14693:18;;14686:60;-1:-1:-1;14777:2:35;14762:18;14755:34;14624:53;14409:386;-1:-1:-1;14409:386:35:o;14800:266::-;14888:6;14883:3;14876:19;14940:6;14933:5;14926:4;14921:3;14917:14;14904:43;-1:-1:-1;14992:1:35;14967:16;;;14985:4;14963:27;;;14956:38;;;;15048:2;15027:15;;;-1:-1:-1;;15023:29:35;15014:39;;;15010:50;;14800:266::o;15071:621::-;15358:6;15347:9;15340:25;15401:3;15396:2;15385:9;15381:18;15374:31;15321:4;15428:46;15469:3;15458:9;15454:19;15446:6;15428:46;:::i;:::-;15510:6;15505:2;15494:9;15490:18;15483:34;15553:6;15548:2;15537:9;15533:18;15526:34;15609:9;15601:6;15597:22;15591:3;15580:9;15576:19;15569:51;15637:49;15679:6;15671;15663;15637:49;:::i;15697:277::-;15764:6;15817:2;15805:9;15796:7;15792:23;15788:32;15785:52;;;15833:1;15830;15823:12;15785:52;15865:9;15859:16;15918:5;15911:13;15904:21;15897:5;15894:32;15884:60;;15940:1;15937;15930:12;16787:127;16848:10;16843:3;16839:20;16836:1;16829:31;16879:4;16876:1;16869:15;16903:4;16900:1;16893:15;16919:125;16984:9;;;17005:10;;;17002:36;;;17018:18;;:::i;17410:271::-;17593:6;17585;17580:3;17567:33;17549:3;17619:16;;17644:13;;;17619:16;17410:271;-1:-1:-1;17410:271:35:o;18914:127::-;18975:10;18970:3;18966:20;18963:1;18956:31;19006:4;19003:1;18996:15;19030:4;19027:1;19020:15;19046:521;19123:4;19129:6;19189:11;19176:25;19283:2;19279:7;19268:8;19252:14;19248:29;19244:43;19224:18;19220:68;19210:96;;19302:1;19299;19292:12;19210:96;19329:33;;19381:20;;;-1:-1:-1;;;;;;19413:30:35;;19410:50;;;19456:1;19453;19446:12;19410:50;19489:4;19477:17;;-1:-1:-1;19520:14:35;19516:27;;;19506:38;;19503:58;;;19557:1;19554;19547:12;19697:544;19798:2;19793:3;19790:11;19787:448;;;19834:1;19859:5;19855:2;19848:17;19904:4;19900:2;19890:19;19974:2;19962:10;19958:19;19955:1;19951:27;19945:4;19941:38;20010:4;19998:10;19995:20;19992:47;;;-1:-1:-1;20033:4:35;19992:47;20088:2;20083:3;20079:12;20076:1;20072:20;20066:4;20062:31;20052:41;;20143:82;20161:2;20154:5;20151:13;20143:82;;;20206:17;;;20187:1;20176:13;20143:82;;;20147:3;;;19697:544;;;:::o;20417:1202::-;-1:-1:-1;;;;;20534:3:35;20531:27;20528:53;;;20561:18;;:::i;:::-;20590:93;20679:3;20639:38;20671:4;20665:11;20639:38;:::i;:::-;20633:4;20590:93;:::i;:::-;20709:1;20734:2;20729:3;20726:11;20751:1;20746:615;;;;21405:1;21422:3;21419:93;;;-1:-1:-1;21478:19:35;;;21465:33;21419:93;-1:-1:-1;;20374:1:35;20370:11;;;20366:24;20362:29;20352:40;20398:1;20394:11;;;20349:57;21525:78;;20719:894;;20746:615;19644:1;19637:14;;;19681:4;19668:18;;-1:-1:-1;;20782:17:35;;;20882:9;20904:229;20918:7;20915:1;20912:14;20904:229;;;21007:19;;;20994:33;20979:49;;21114:4;21099:20;;;;21067:1;21055:14;;;;20934:12;20904:229;;;20908:3;21161;21152:7;21149:16;21146:159;;;21285:1;21281:6;21275:3;21269;21266:1;21262:11;21258:21;21254:34;21250:39;21237:9;21232:3;21228:19;21215:33;21211:79;21203:6;21196:95;21146:159;;;21348:1;21342:3;21339:1;21335:11;21331:19;21325:4;21318:33;20719:894;;20417:1202;;;:::o;21624:244::-;21781:2;21770:9;21763:21;21744:4;21801:61;21858:2;21847:9;21843:18;21835:6;21827;21801:61;:::i;21873:135::-;21912:3;21933:17;;;21930:43;;21953:18;;:::i;:::-;-1:-1:-1;22000:1:35;21989:13;;21873:135::o;24083:312::-;24162:6;24170;24223:2;24211:9;24202:7;24198:23;24194:32;24191:52;;;24239:1;24236;24229:12;24191:52;24268:9;24262:16;24252:26;;24321:2;24310:9;24306:18;24300:25;24334:31;24359:5;24334:31;:::i;27501:523::-;27750:3;27739:9;27732:22;27713:4;27777:46;27818:3;27807:9;27803:19;27795:6;27777:46;:::i;:::-;27871:9;27863:6;27859:22;27854:2;27843:9;27839:18;27832:50;27899:33;27925:6;27917;27899:33;:::i;:::-;27963:2;27948:18;;27941:34;;;;-1:-1:-1;;28006:2:35;27991:18;27984:34;27891:41;27501:523;-1:-1:-1;;27501:523:35:o;28029:289::-;28204:6;28193:9;28186:25;28247:2;28242;28231:9;28227:18;28220:30;28167:4;28267:45;28308:2;28297:9;28293:18;28285:6;28267:45;:::i;28323:289::-;28498:2;28487:9;28480:21;28461:4;28518:45;28559:2;28548:9;28544:18;28536:6;28518:45;:::i;:::-;28510:53;;28599:6;28594:2;28583:9;28579:18;28572:34;28323:289;;;;;:::o;28973:441::-;29026:5;29079:3;29072:4;29064:6;29060:17;29056:27;29046:55;;29097:1;29094;29087:12;29046:55;29126:6;29120:13;29157:48;29173:31;29201:2;29173:31;:::i;29157:48::-;29230:2;29221:7;29214:19;29276:3;29269:4;29264:2;29256:6;29252:15;29248:26;29245:35;29242:55;;;29293:1;29290;29283:12;29242:55;29306:77;29380:2;29373:4;29364:7;29360:18;29353:4;29345:6;29341:17;29306:77;:::i;29419:396::-;29507:6;29515;29568:2;29556:9;29547:7;29543:23;29539:32;29536:52;;;29584:1;29581;29574:12;29536:52;29613:9;29607:16;29597:26;;29667:2;29656:9;29652:18;29646:25;-1:-1:-1;;;;;29686:6:35;29683:30;29680:50;;;29726:1;29723;29716:12;29680:50;29749:60;29801:7;29792:6;29781:9;29777:22;29749:60;:::i;:::-;29739:70;;;29419:396;;;;;:::o;30181:847::-;30522:3;30511:9;30504:22;30485:4;30549:46;30590:3;30579:9;30575:19;30567:6;30549:46;:::i;:::-;30643:9;30635:6;30631:22;30626:2;30615:9;30611:18;30604:50;30677:33;30703:6;30695;30677:33;:::i;:::-;30663:47;;30746:6;30741:2;30730:9;30726:18;30719:34;30789:6;30784:2;30773:9;30769:18;30762:34;30845:9;30837:6;30833:22;30827:3;30816:9;30812:19;30805:51;30879:33;30905:6;30897;30879:33;:::i;:::-;30865:47;;30961:9;30953:6;30949:22;30943:3;30932:9;30928:19;30921:51;30989:33;31015:6;31007;30989:33;:::i;31033:450::-;31254:2;31243:9;31236:21;31217:4;31280:45;31321:2;31310:9;31306:18;31298:6;31280:45;:::i;:::-;31361:6;31356:2;31345:9;31341:18;31334:34;31416:9;31408:6;31404:22;31399:2;31388:9;31384:18;31377:50;31444:33;31470:6;31462;31444:33;:::i;:::-;31436:41;31033:450;-1:-1:-1;;;;;;31033:450:35:o;33622:127::-;33683:10;33678:3;33674:20;33671:1;33664:31;33714:4;33711:1;33704:15;33738:4;33735:1;33728:15;33754:858;34084:6;34077:14;34070:22;34059:9;34052:41;34033:4;34123:1;34115:6;34112:13;34102:144;;34168:10;34163:3;34159:20;34156:1;34149:31;34203:4;34200:1;34193:15;34231:4;34228:1;34221:15;34102:144;34282:6;34277:2;34266:9;34262:18;34255:34;34325:3;34320:2;34309:9;34305:18;34298:31;34352:46;34393:3;34382:9;34378:19;34370:6;34352:46;:::i;:::-;34446:9;34438:6;34434:22;34429:2;34418:9;34414:18;34407:50;34474:33;34500:6;34492;34474:33;:::i;:::-;34466:41;;;34544:6;34538:3;34527:9;34523:19;34516:35;34600:4;34592:6;34588:17;34582:3;34571:9;34567:19;34560:46;33754:858;;;;;;;;;:::o;35734:386::-;35937:6;35926:9;35919:25;35980:2;35975;35964:9;35960:18;35953:30;35900:4;36000:45;36041:2;36030:9;36026:18;36018:6;36000:45;:::i;:::-;35992:53;;36110:1;36106;36101:3;36097:11;36093:19;36085:6;36081:32;36076:2;36065:9;36061:18;36054:60;35734:386;;;;;;:::o;36125:184::-;36195:6;36248:2;36236:9;36227:7;36223:23;36219:32;36216:52;;;36264:1;36261;36254:12;36216:52;-1:-1:-1;36287:16:35;;36125:184;-1:-1:-1;36125:184:35:o;36314:681::-;36429:6;36437;36445;36453;36506:3;36494:9;36485:7;36481:23;36477:33;36474:53;;;36523:1;36520;36513:12;36474:53;36556:9;36550:16;-1:-1:-1;;;;;36626:2:35;36618:6;36615:14;36612:34;;;36642:1;36639;36632:12;36612:34;36665:60;36717:7;36708:6;36697:9;36693:22;36665:60;:::i;:::-;36655:70;;36771:2;36760:9;36756:18;36750:25;36734:41;;36800:2;36790:8;36787:16;36784:36;;;36816:1;36813;36806:12;36784:36;;36839:62;36893:7;36882:8;36871:9;36867:24;36839:62;:::i;:::-;36941:2;36926:18;;36920:25;36985:2;36970:18;;;36964:25;36314:681;;36829:72;;-1:-1:-1;36314:681:35;-1:-1:-1;;;;36314:681:35:o;37000:1087::-;37151:6;37159;37167;37175;37183;37191;37244:3;37232:9;37223:7;37219:23;37215:33;37212:53;;;37261:1;37258;37251:12;37212:53;37294:9;37288:16;-1:-1:-1;;;;;37364:2:35;37356:6;37353:14;37350:34;;;37380:1;37377;37370:12;37350:34;37403:60;37455:7;37446:6;37435:9;37431:22;37403:60;:::i;:::-;37393:70;;37509:2;37498:9;37494:18;37488:25;37472:41;;37538:2;37528:8;37525:16;37522:36;;;37554:1;37551;37544:12;37522:36;37577:62;37631:7;37620:8;37609:9;37605:24;37577:62;:::i;:::-;37567:72;;37679:2;37668:9;37664:18;37658:25;37648:35;;37723:2;37712:9;37708:18;37702:25;37692:35;;37773:3;37762:9;37758:19;37752:26;37736:42;;37803:2;37793:8;37790:16;37787:36;;;37819:1;37816;37809:12;37787:36;37842:62;37896:7;37885:8;37874:9;37870:24;37842:62;:::i;:::-;37832:72;;37950:3;37939:9;37935:19;37929:26;37913:42;;37980:2;37970:8;37967:16;37964:36;;;37996:1;37993;37986:12;37964:36;;38019:62;38073:7;38062:8;38051:9;38047:24;38019:62;:::i;:::-;38009:72;;;37000:1087;;;;;;;;:::o;38092:559::-;38335:3;38324:9;38317:22;38298:4;38362:46;38403:3;38392:9;38388:19;38380:6;38362:46;:::i;:::-;-1:-1:-1;;;;;38444:32:35;;38439:2;38424:18;;38417:60;38520:14;;38513:22;38508:2;38493:18;;38486:50;38572:22;;;38567:2;38552:18;;38545:50;38612:33;38576:6;38630;38612:33;:::i;38656:693::-;38961:6;38950:9;38943:25;39004:3;38999:2;38988:9;38984:18;38977:31;38924:4;39031:46;39072:3;39061:9;39057:19;39049:6;39031:46;:::i;:::-;39108:2;39093:18;;39086:34;;;-1:-1:-1;;;;;39156:32:35;;39151:2;39136:18;;39129:60;39220:3;39205:19;;39198:35;;;39270:22;;;39176:3;39249:19;;39242:51;39310:33;39274:6;39328;39310:33;:::i;43390:422::-;43479:1;43522:5;43479:1;43536:270;43557:7;43547:8;43544:21;43536:270;;;43616:4;43612:1;43608:6;43604:17;43598:4;43595:27;43592:53;;;43625:18;;:::i;:::-;43675:7;43665:8;43661:22;43658:55;;;43695:16;;;;43658:55;43774:22;;;;43734:15;;;;43536:270;;;43540:3;43390:422;;;;;:::o;43817:806::-;43866:5;43896:8;43886:80;;-1:-1:-1;43937:1:35;43951:5;;43886:80;43985:4;43975:76;;-1:-1:-1;44022:1:35;44036:5;;43975:76;44067:4;44085:1;44080:59;;;;44153:1;44148:130;;;;44060:218;;44080:59;44110:1;44101:10;;44124:5;;;44148:130;44185:3;44175:8;44172:17;44169:43;;;44192:18;;:::i;:::-;-1:-1:-1;;44248:1:35;44234:16;;44263:5;;44060:218;;44362:2;44352:8;44349:16;44343:3;44337:4;44334:13;44330:36;44324:2;44314:8;44311:16;44306:2;44300:4;44297:12;44293:35;44290:77;44287:159;;;-1:-1:-1;44399:19:35;;;44431:5;;44287:159;44478:34;44503:8;44497:4;44478:34;:::i;:::-;44548:6;44544:1;44540:6;44536:19;44527:7;44524:32;44521:58;;;44559:18;;:::i;:::-;44597:20;;43817:806;-1:-1:-1;;;43817:806:35:o;44628:131::-;44688:5;44717:36;44744:8;44738:4;44717:36;:::i;44764:168::-;44837:9;;;44868;;44885:15;;;44879:22;;44865:37;44855:71;;44906:18;;:::i;44937:217::-;44977:1;45003;44993:132;;45047:10;45042:3;45038:20;45035:1;45028:31;45082:4;45079:1;45072:15;45110:4;45107:1;45100:15;44993:132;-1:-1:-1;45139:9:35;;44937:217::o;45926:287::-;46055:3;46093:6;46087:13;46109:66;46168:6;46163:3;46156:4;46148:6;46144:17;46109:66;:::i;:::-;46191:16;;;;;45926:287;-1:-1:-1;;45926:287:35:o
Swarm Source
ipfs://d5f54f3678a011ff4d56dc613b5a415636f45c23826c34dc6b8cd81079138873
Loading...
Loading
Loading...
Loading
OVERVIEW
Map Protocol is A #Bitcoin L2 for peer-to-peer interoperability, built on ZK & light clients.Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.