Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 318 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Forward | 20665553 | 24 mins ago | IN | 0 ETH | 0.00100737 | ||||
Forward | 20642611 | 3 days ago | IN | 0 ETH | 0.00047776 | ||||
Forward | 20635627 | 4 days ago | IN | 0 ETH | 0.00058427 | ||||
Forward | 20613699 | 7 days ago | IN | 0 ETH | 0.00043003 | ||||
Forward | 20613436 | 7 days ago | IN | 0 ETH | 0.00104916 | ||||
Forward | 20612876 | 7 days ago | IN | 0 ETH | 0.00042459 | ||||
Forward | 20612050 | 7 days ago | IN | 0 ETH | 0.00073883 | ||||
Forward | 20549378 | 16 days ago | IN | 0 ETH | 0.00042539 | ||||
Forward | 20523681 | 19 days ago | IN | 0 ETH | 0.00014526 | ||||
Forward | 20523545 | 19 days ago | IN | 0 ETH | 0.00017997 | ||||
Forward | 20523069 | 19 days ago | IN | 0 ETH | 0.00014375 | ||||
Forward | 20471805 | 27 days ago | IN | 0 ETH | 0.00060335 | ||||
Forward | 20469811 | 27 days ago | IN | 0 ETH | 0.00076668 | ||||
Deposit | 20468373 | 27 days ago | IN | 0 ETH | 0.00085721 | ||||
Forward | 20413583 | 35 days ago | IN | 0 ETH | 0.00088048 | ||||
Forward | 20413322 | 35 days ago | IN | 0 ETH | 0.00079823 | ||||
Forward | 20411442 | 35 days ago | IN | 0 ETH | 0.00041316 | ||||
Forward | 20411430 | 35 days ago | IN | 0 ETH | 0.00057443 | ||||
Forward | 20395858 | 37 days ago | IN | 0 ETH | 0.0002367 | ||||
Forward | 20394726 | 37 days ago | IN | 0 ETH | 0.00060589 | ||||
Forward | 20392633 | 38 days ago | IN | 0 ETH | 0.00033907 | ||||
Forward | 20392622 | 38 days ago | IN | 0 ETH | 0.00031473 | ||||
Forward | 20392512 | 38 days ago | IN | 0 ETH | 0.00028125 | ||||
Forward | 20392009 | 38 days ago | IN | 0 ETH | 0.00055865 | ||||
Forward | 20391627 | 38 days ago | IN | 0 ETH | 0.00078616 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
BridgeEthEthereum
Compiler Version
v0.8.24+commit.e11b9ed9
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2024-02-15 */ // File: contracts/bridge/Bridgeable.sol /** * * ██████╗ ██████╗ ██████╗ █████╗ ██╗██╗ ███████╗ * ██╔════╝ ██╔═══██╗ ██╔══██╗██╔══██╗██║██║ ██╔════╝ * ██║ ███╗██║ ██║ ██████╔╝███████║██║██║ ███████╗ * ██║ ██║██║ ██║ ██╔══██╗██╔══██║██║██║ ╚════██║ * ╚██████╔╝╚██████╔╝ ██║ ██║██║ ██║██║███████╗███████║ * ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚══════╝╚══════╝ * * https://patorjk.com/software/taag/#p=display&f=ANSI%20Shadow&t=Go%20Rails * * author: 0f0crypto <[email protected]> * SPDX-License-Identifier: MIT */ pragma solidity ^0.8.20; interface Bridgeable { /** * @dev Receive a transfer with a signed authorization from the payer * @dev This has an additional check to ensure that the payee's address * matches the address of this contract to prevent front-running attacks. * * To value of the `to` parameter is the destination wallet on the bridged * chain. The provided (v,r,s) signature must be constructed for the `address(this)` * as the recipient. * * @param from Payer's address (Authorizer) * @param to Payee's address * @param value Amount to be transferred * @param validAfter The time after which this is valid (unix time) * @param validBefore The time before which this is valid (unix time) * @param nonce Unique nonce * @param v v of the signature * @param r r of the signature * @param s s of the signature */ function receiveWithAuthorization( address from, address to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Function to mint tokens * @param to The address that will receive the minted tokens. * @param amount The amount of tokens to mint. Must be less than or equal * to the minterAllowance of the caller. * @return A boolean that indicates if the operation was successful. */ function mint(address to, uint256 amount) external returns (bool); /** * @dev Function to burn tokens * @param amount uint256 the amount of tokens to be burned */ function burn(uint256 amount) external; /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer( address recipient, uint256 amount ) external returns (bool); } // File: @openzeppelin/contracts/interfaces/IERC5267.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol) pragma solidity ^0.8.20; 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 ); } // File: @openzeppelin/contracts/utils/StorageSlot.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.20; /** * @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(newImplementation.code.length > 0); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` */ 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 } } } // File: @openzeppelin/contracts/utils/ShortStrings.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/ShortStrings.sol) pragma solidity ^0.8.20; // | 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; } } } // File: @openzeppelin/contracts/utils/math/SignedMath.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.20; /** * @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); } } } // File: @openzeppelin/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol) pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Muldiv operation overflow. */ error MathOverflowedMulDiv(); enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an overflow flag. */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the 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 towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. return a / b; } // (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 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) 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. if (denominator <= prod1) { revert MathOverflowedMulDiv(); } /////////////////////////////////////////////// // 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. uint256 twos = denominator & (0 - denominator); 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 (unsignedRoundsUp(rounding) && 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 * towards zero. * * 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 + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * 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 + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * 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 + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * 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 + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol) pragma solidity ^0.8.20; /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @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), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(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) { uint256 localValue = value; 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] = HEX_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } 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 bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } } // File: @openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MessageHashUtils.sol) pragma solidity ^0.8.20; /** * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing. * * The library provides methods for generating a hash of a message that conforms to the * https://eips.ethereum.org/EIPS/eip-191[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712] * specifications. */ library MessageHashUtils { /** * @dev Returns the keccak256 digest of an EIP-191 signed data with version * `0x45` (`personal_sign` messages). * * The digest is calculated by prefixing a bytes32 `messageHash` with * `"\x19Ethereum Signed Message:\n32"` and hashing the result. It corresponds with the * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. * * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with * keccak256, although any bytes32 value can be safely used because the final digest will * be re-hashed. * * See {ECDSA-recover}. */ function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) { /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") // 32 is the bytes-length of messageHash mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20) } } /** * @dev Returns the keccak256 digest of an EIP-191 signed data with version * `0x45` (`personal_sign` messages). * * The digest is calculated by prefixing an arbitrary `message` with * `"\x19Ethereum Signed Message:\n" + len(message)` and hashing the result. It corresponds with the * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. * * See {ECDSA-recover}. */ function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) { return keccak256(bytes.concat("\x19Ethereum Signed Message:\n", bytes(Strings.toString(message.length)), message)); } /** * @dev Returns the keccak256 digest of an EIP-191 signed data with version * `0x00` (data with intended validator). * * The digest is calculated by prefixing an arbitrary `data` with `"\x19\x00"` and the intended * `validator` address. Then hashing the result. * * See {ECDSA-recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked(hex"19_00", validator, data)); } /** * @dev Returns the keccak256 digest of an EIP-712 typed data (EIP-191 version `0x01`). * * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with * `\x19\x01` and hashing the result. It corresponds to the hash signed by the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712. * * See {ECDSA-recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, hex"19_01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) digest := keccak256(ptr, 0x42) } } } // File: @openzeppelin/contracts/utils/cryptography/EIP712.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/EIP712.sol) pragma solidity ^0.8.20; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose * encoding is very generic and therefore its 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 order to * produce the hash of their typed data 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. * * @custom:oz-upgrades-unsafe-allow state-variable-immutable */ 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 MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev See {IERC-5267}. */ function eip712Domain() public view virtual returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ) { return ( hex"0f", // 01111 _EIP712Name(), _EIP712Version(), block.chainid, address(this), bytes32(0), new uint256[](0) ); } /** * @dev The name parameter for the EIP712 domain. * * NOTE: By default this function reads _name which is an immutable value. * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). */ // solhint-disable-next-line func-name-mixedcase function _EIP712Name() internal view returns (string memory) { return _name.toStringWithFallback(_nameFallback); } /** * @dev The version parameter for the EIP712 domain. * * NOTE: By default this function reads _version which is an immutable value. * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). */ // solhint-disable-next-line func-name-mixedcase function _EIP712Version() internal view returns (string memory) { return _version.toStringWithFallback(_versionFallback); } } // File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.20; /** * @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 } /** * @dev The signature derives the `address(0)`. */ error ECDSAInvalidSignature(); /** * @dev The signature has an invalid length. */ error ECDSAInvalidSignatureLength(uint256 length); /** * @dev The signature has an S value that is in the upper half order. */ error ECDSAInvalidSignatureS(bytes32 s); /** * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not * return address(0) without also returning an error description. Errors are documented using an enum (error type) * and a bytes32 providing additional information about the error. * * If no error is returned, then the address can be used for verification purposes. * * The `ecrecover` EVM precompile 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 {MessageHashUtils-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] */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) { 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, bytes32(signature.length)); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM precompile 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 {MessageHashUtils-toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature); _throwError(error, errorArg); 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] */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) { unchecked { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); // We do not check for an overflow here since the shift operation results in 0 or 1. 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. */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs); _throwError(error, errorArg); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError, bytes32) { // 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, s); } // 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, bytes32(0)); } return (signer, RecoverError.NoError, bytes32(0)); } /** * @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, bytes32 errorArg) = tryRecover(hash, v, r, s); _throwError(error, errorArg); return recovered; } /** * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided. */ function _throwError(RecoverError error, bytes32 errorArg) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert ECDSAInvalidSignature(); } else if (error == RecoverError.InvalidSignatureLength) { revert ECDSAInvalidSignatureLength(uint256(errorArg)); } else if (error == RecoverError.InvalidSignatureS) { revert ECDSAInvalidSignatureS(errorArg); } } } // File: @openzeppelin/contracts/interfaces/draft-IERC6093.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } } // File: @openzeppelin/contracts/utils/Pausable.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol) pragma solidity ^0.8.20; /** * @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 { bool private _paused; /** * @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); /** * @dev The operation failed because the contract is paused. */ error EnforcedPause(); /** * @dev The operation failed because the contract is not paused. */ error ExpectedPause(); /** * @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 { if (paused()) { revert EnforcedPause(); } } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { if (!paused()) { revert ExpectedPause(); } } /** * @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()); } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: @openzeppelin/contracts/access/Ownable2Step.sol // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol) pragma solidity ^0.8.20; /** * @dev Contract module which provides access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is specified at deployment time in the constructor for `Ownable`. This * can later be changed with {transferOwnership} and {acceptOwnership}. * * This module is used through inheritance. It will make available all functions * from parent (Ownable). */ abstract contract Ownable2Step is Ownable { address private _pendingOwner; event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); /** * @dev Returns the address of the pending owner. */ function pendingOwner() public view virtual returns (address) { return _pendingOwner; } /** * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual override onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual override { delete _pendingOwner; super._transferOwnership(newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() public virtual { address sender = _msgSender(); if (pendingOwner() != sender) { revert OwnableUnauthorizedAccount(sender); } _transferOwnership(sender); } } // File: contracts/bridge/FeesCollectable.sol /** * @dev Enables setting and collecting (token transfer) fees */ abstract contract FeesCollectable is Ownable2Step { uint128 public constant DECIMALS = 10 ** 6; uint128 private constant VALUE_1 = 1 * DECIMALS; uint128 private constant VALUE_1K = 1_000 * DECIMALS; uint128 private constant VALUE_5K = 5_000 * DECIMALS; uint128 private constant VALUE_10K = 10_000 * DECIMALS; uint128 private constant FEE_FRACTION = 100_000; enum FeeType { FREE, FLAT, PROGRESSIVE } struct Fees { uint128 min; // < 1k uint16 tier_1k; // <1k uint16 tier_5k; // 1k-5k uint16 tier_10k; // 5k-10k uint16 tier_max; // > 10k uint64 gap; // storage gap for upgrades } Fees public fees; FeeType public feeType; address public feesVault; /** * @dev calculate the transfer fee for the specified value * * @param value the value for which to calculate the fee */ function calculateFee(uint256 value) public view returns (uint256) { if (feeType == FeeType.FREE) { return 0; } if (feeType == FeeType.FLAT) { return fees.min; } uint256 fee = 0; // anything over 10k is "taxed" at the tier_max rate if (value > VALUE_10K) { fee += ((value - VALUE_10K) * fees.tier_max) / FEE_FRACTION; value = VALUE_10K; } // the amount between 5k and 10k is taxed at tier_10k rate if (value > VALUE_5K) { fee += ((value - VALUE_5K) * fees.tier_10k) / FEE_FRACTION; value = VALUE_5K; } // the amount between 1k and 5k is taxed at tier_5k rate if (value > VALUE_1K) { fee += ((value - VALUE_1K) * fees.tier_5k) / FEE_FRACTION; value = VALUE_1K; } // the amount between 0 and 1k is taxed at tier_1k rate fee += (value * fees.tier_1k) / FEE_FRACTION; // if the fee is smaller than the min fee, return the min fee if (fee < fees.min){ return fees.min; } return fee; } function setFees( uint128 min, uint16 tier_1k, uint16 tier_5k, uint16 tier_10k, uint16 tier_max ) public onlyOwner { fees = Fees(min, tier_1k, tier_5k, tier_10k, tier_max, 0); } function setFeeType(FeeType _value) public onlyOwner { feeType = _value; } function setFeesVault(address _vault) public onlyOwner { feesVault = _vault; } } // File: contracts/common/Blacklistable.sol /** * @dev Allows accounts to be blacklisted by a "blacklister" role */ abstract contract Blacklistable is Ownable2Step { mapping(address => bool) internal blacklisted; event Blacklisted(address indexed _account); event UnBlacklisted(address indexed _account); error BlacklistedAccount(address account); /** * @dev Reverts if the specified account is blacklisted * @param account The address to check */ modifier notBlacklisted(address account) { _checkBlacklist(account); _; } /** * @dev Reverts if the specified account is blacklisted */ function _checkBlacklist(address account) internal view virtual { if (blacklisted[account]) { revert BlacklistedAccount(account); } } /** * @dev Checks if the specified account is blacklisted * @param account The address to check */ function isBlacklisted(address account) external view returns (bool) { return blacklisted[account]; } /** * @dev Adds the specified account to blacklist * @param account The address to blacklist */ function blacklist(address account) external onlyOwner { blacklisted[account] = true; emit Blacklisted(account); } /** * @dev Removes the specified account from blacklist * @param account The address to remove from the blacklist */ function unBlacklist(address account) external onlyOwner { blacklisted[account] = false; emit UnBlacklisted(account); } } // File: contracts/bridge/Bridge.sol abstract contract Bridge is Blacklistable, FeesCollectable, IERC20Errors, EIP712, Pausable { /** * @dev The operation failed because the deposit signature is invalid (EIP-2612). */ error BridgeInvalidDepositSignature(address sender, address from); /** * @dev Emitted when the a bridge forward fails because the fees vault is the zero address. */ error BridgeInvalidFeesVault(address feesVault); /** * @dev Emitted when the a bridge forward fails due to fees being greater * than the transfer amount (value). */ error BridgeInvalidForwardAmount(address to, uint256 value, uint256 fee); /** * @dev The operation failed because the tx signer is invalid (EIP-2612). */ error BridgeInvalidSigner(address sender, address signer); /** * @dev The operation failed because the nonce has already been used by the specified user. */ error BridgeNonceAlreadyUsed(address from, bytes32 nonce); /** * @dev The operation failed because the authorization has expired / is not valid yet (EIP-3009). */ error BridgeExpiredAuthorization( uint256 validAfter, uint256 validBefore, uint256 timestamp ); /** * @dev Emitted when the a bridge deposit has been made */ event BridgeDeposit( address indexed from, address indexed to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, bytes depositSignature ); /** * @dev Emitted when the a bridge nonce has been used by the specified user */ event BridgeNonceUsed(address indexed from, bytes32 nonce); /** * @dev Emitted when the a bridge forward transaction has been made */ event BridgeForward(address indexed to, uint256 value, bytes32 nonce); // keccak256("Forward(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)") bytes32 public constant FORWARD_WITH_AUTHORIZATION_TYPEHASH = 0x4e28ed42d027eeb58993b424b784ad6ee35fa214e181855687ea18fabae63840; Bridgeable internal token; mapping(address => mapping(bytes32 => bool)) private _usedNonces; address internal _bridgeSigner; constructor( address bridgeSigner, address tokenAddress, address initialOwner ) Ownable(initialOwner) EIP712("USDC Bridge", "1") { _bridgeSigner = bridgeSigner; token = Bridgeable(tokenAddress); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function pause() public onlyOwner { _pause(); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function unpause() public onlyOwner { _unpause(); } function setSigner(address _signer) external onlyOwner { _bridgeSigner = _signer; } function signer() external view returns (address) { return _bridgeSigner; } /** * @dev Executes after deposit() is performed * @param value Amount to be transferred */ function _afterDeposit(uint256 value) internal virtual {} /** * @dev Execute a deposit with a signed authorization * @param from Payer's address (Authorizer) * @param to Payee's address * @param value Amount to be transferred * @param validAfter The time after which this is valid (unix time) * @param validBefore The time before which this is valid (unix time) * @param nonce Unique nonce * @param v v of the signature * @param r r of the signature * @param s s of the signature * @param depositSignature the deposit signature */ function deposit( address from, address to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, uint8 v, bytes32 r, bytes32 s, bytes memory depositSignature ) external whenNotPaused notBlacklisted(from) notBlacklisted(to) { _verifyDepositSignature( from, to, value, validAfter, validBefore, nonce, depositSignature ); token.receiveWithAuthorization( from, address(this), value, validAfter, validBefore, nonce, v, r, s ); emit BridgeDeposit( from, to, value, validAfter, validBefore, nonce, depositSignature ); _afterDeposit(value); } /** * @dev Mark a nonce as used * @param from Sender address * @param nonce Nonce of the desosit */ function markNonceAsUsed(address from, bytes32 nonce) external onlyOwner { _markNonceAsUsed(from, nonce); } /** * @dev Calculates the transfer fee and amount and prepares the forward transfer * @param to Payee's address * @param value Amount to be transferred * * @return amount The amount to be credited to the payee's * @return fee The transfer fee to be sent to the vault */ function _prepareForward( address to, uint256 value ) internal view returns (uint256, uint256) { uint256 fee = calculateFee(value); if (to == feesVault) { fee = 0; } if (feesVault == address(0)) { revert BridgeInvalidFeesVault(feesVault); } if (fee > value) { revert BridgeInvalidForwardAmount(to, value, fee); } return (value - fee, fee); } /** * @dev Mark a nonce as used * @param from Sender address * @param nonce Nonce of the desosit */ function _markNonceAsUsed(address from, bytes32 nonce) internal { _usedNonces[from][nonce] = true; emit BridgeNonceUsed(from, nonce); } /** * @dev Check that a nonce is unused * @param from Sender * @param nonce Nonce of the authorization */ function _requireUnusedNonce(address from, bytes32 nonce) internal view { if (_usedNonces[from][nonce]) { revert BridgeNonceAlreadyUsed(from, nonce); } } /** * @dev Check that authorization is valid * @param authorizer Authorizer's address * @param nonce Nonce of the authorization * @param validAfter The time after which this is valid (unix time) * @param validBefore The time before which this is valid (unix time) */ function _requireValidAuthorization( address authorizer, bytes32 nonce, uint256 validAfter, uint256 validBefore ) internal view { if (block.timestamp < validAfter) { revert BridgeExpiredAuthorization( validAfter, validBefore, block.timestamp ); } if (block.timestamp > validBefore) { revert BridgeExpiredAuthorization( validAfter, validBefore, block.timestamp ); } _requireUnusedNonce(authorizer, nonce); } /** * @dev Check that deposit signature is valid * @param from Payer's address (Authorizer) * @param to Payee's address * @param value Amount to be transferred * @param validAfter The time after which this is valid (unix time) * @param validBefore The time before which this is valid (unix time) * @param nonce Unique nonce * @param signature The deposit signature (EIP-2612) to check */ function _verifyDepositSignature( address from, address to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, bytes memory signature ) internal pure { bytes32 hash = keccak256( abi.encodePacked(from, to, value, validAfter, validBefore, nonce) ); bytes32 digest = keccak256( abi.encodePacked("\x19Ethereum Signed Message:\n32", hash) ); address sender = ECDSA.recover(digest, signature); if (sender != from) { revert BridgeInvalidDepositSignature(sender, from); } } /** * @param from Payer's address (Authorizer) * @param to Payee's address * @param value Amount to be transferred * @param validAfter The time after which this is valid (unix time) * @param validBefore The time before which this is valid (unix time) * @param nonce Unique nonce * @param v v of the signature * @param r r of the signature * @param s s of the signature */ function _verifyForwardSignature( address from, address to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, uint8 v, bytes32 r, bytes32 s ) internal view { bytes32 structHash = keccak256( abi.encode( FORWARD_WITH_AUTHORIZATION_TYPEHASH, from, to, value, validAfter, validBefore, nonce ) ); bytes32 hash = _hashTypedDataV4(structHash); address _signer = ECDSA.recover(hash, v, r, s); if (_signer != from) { revert BridgeInvalidSigner(_signer, from); } } } // File: contracts/bridge/BridgeEth.sol abstract contract BridgeEth is Bridge { constructor( address bridgeSigner, address tokenAddress, address initialOwner ) Bridge(bridgeSigner, tokenAddress, initialOwner) {} function forward( address from, address to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, uint8 v, bytes32 r, bytes32 s, bytes memory depositSignature ) external whenNotPaused notBlacklisted(from) notBlacklisted(to) { _requireValidAuthorization(from, nonce, validAfter, validBefore); _verifyDepositSignature( from, to, value, validAfter, validBefore, nonce, depositSignature ); _verifyForwardSignature( _bridgeSigner, to, value, validAfter, validBefore, nonce, v, r, s ); _requireUnusedNonce(to, nonce); _markNonceAsUsed(to, nonce); _collectFeeAndForward(to, value); emit BridgeForward(to, value, nonce); } function _collectFeeAndForward(address to, uint256 value) internal { (uint256 amount, uint256 fee) = _prepareForward(to, value); if (fee > 0) { token.transfer(feesVault, fee); } token.transfer(to, amount); } } contract BridgeEthSepolia is BridgeEth { constructor( address bridgeSigner, address tokenAddress, address initialOwner ) BridgeEth(bridgeSigner, tokenAddress, initialOwner) { setFeeType(FeeType.PROGRESSIVE); setFees(10_000_000, 6_500, 6_000, 5_500, 5_000); setFeesVault(0xe432dF1f0307ca9DCA73F98845a46Ce96Cbb0130); } } contract BridgeEthEthereum is BridgeEth { constructor( address bridgeSigner, address tokenAddress, address initialOwner ) BridgeEth(bridgeSigner, tokenAddress, initialOwner) { setFeeType(FeeType.PROGRESSIVE); setFees(10_000_000, 6_500, 6_000, 5_500, 5_000); setFeesVault(0x6278f3FefF7d4CDE58871Bf606f61e59aA825EEf); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"bridgeSigner","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"initialOwner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"BlacklistedAccount","type":"error"},{"inputs":[{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"BridgeExpiredAuthorization","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"from","type":"address"}],"name":"BridgeInvalidDepositSignature","type":"error"},{"inputs":[{"internalType":"address","name":"feesVault","type":"address"}],"name":"BridgeInvalidFeesVault","type":"error"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"BridgeInvalidForwardAmount","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"signer","type":"address"}],"name":"BridgeInvalidSigner","type":"error"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"BridgeNonceAlreadyUsed","type":"error"},{"inputs":[],"name":"ECDSAInvalidSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"ECDSAInvalidSignatureLength","type":"error"},{"inputs":[{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"ECDSAInvalidSignatureS","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_account","type":"address"}],"name":"Blacklisted","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"},{"indexed":false,"internalType":"uint256","name":"validAfter","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"validBefore","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"nonce","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"depositSignature","type":"bytes"}],"name":"BridgeDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"BridgeForward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"BridgeNonceUsed","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_account","type":"address"}],"name":"UnBlacklisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DECIMALS","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FORWARD_WITH_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"blacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"calculateFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"bytes","name":"depositSignature","type":"bytes"}],"name":"deposit","outputs":[],"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":[],"name":"feeType","outputs":[{"internalType":"enum FeesCollectable.FeeType","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fees","outputs":[{"internalType":"uint128","name":"min","type":"uint128"},{"internalType":"uint16","name":"tier_1k","type":"uint16"},{"internalType":"uint16","name":"tier_5k","type":"uint16"},{"internalType":"uint16","name":"tier_10k","type":"uint16"},{"internalType":"uint16","name":"tier_max","type":"uint16"},{"internalType":"uint64","name":"gap","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feesVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"bytes","name":"depositSignature","type":"bytes"}],"name":"forward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isBlacklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"markNonceAsUsed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum FeesCollectable.FeeType","name":"_value","type":"uint8"}],"name":"setFeeType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"min","type":"uint128"},{"internalType":"uint16","name":"tier_1k","type":"uint16"},{"internalType":"uint16","name":"tier_5k","type":"uint16"},{"internalType":"uint16","name":"tier_10k","type":"uint16"},{"internalType":"uint16","name":"tier_max","type":"uint16"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"setFeesVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"unBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
61016060405234801562000011575f80fd5b50604051620040c0380380620040c083398181016040528101906200003791906200082b565b8282828282826040518060400160405280600b81526020017f55534443204272696467650000000000000000000000000000000000000000008152506040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250825f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036200011d575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040162000114919062000895565b60405180910390fd5b6200012e81620002df60201b60201c565b50620001456005836200031760201b90919060201c565b6101208181525050620001636006826200031760201b90919060201c565b6101408181525050818051906020012060e08181525050808051906020012061010081815250504660a08181525050620001a26200036c60201b60201c565b608081815250503073ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff168152505050505f60075f6101000a81548160ff0219169083151502179055508260095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600760016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050505050620002916002620003c860201b60201c565b620002b16298968061196461177061157c6113886200040760201b60201c565b620002d6736278f3feff7d4cde58871bf606f61e59aa825eef6200056e60201b60201c565b50505062000df5565b60015f6101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556200031481620005c260201b60201c565b50565b5f6020835110156200033c5762000334836200068360201b60201c565b905062000366565b826200034e83620006ed60201b60201c565b5f0190816200035e919062000b14565b5060ff5f1b90505b92915050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60e051610100514630604051602001620003ad95949392919062000c23565b60405160208183030381529060405280519060200120905090565b620003d8620006f660201b60201c565b8060045f6101000a81548160ff02191690836002811115620003ff57620003fe62000c7e565b5b021790555050565b62000417620006f660201b60201c565b6040518060c00160405280866fffffffffffffffffffffffffffffffff1681526020018561ffff1681526020018461ffff1681526020018361ffff1681526020018261ffff1681526020015f67ffffffffffffffff1681525060035f820151815f015f6101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506020820151815f0160106101000a81548161ffff021916908361ffff1602179055506040820151815f0160126101000a81548161ffff021916908361ffff1602179055506060820151815f0160146101000a81548161ffff021916908361ffff1602179055506080820151815f0160166101000a81548161ffff021916908361ffff16021790555060a0820151815f0160186101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055509050505050505050565b6200057e620006f660201b60201c565b80600460016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f80829050601f81511115620006d257826040517f305a27a9000000000000000000000000000000000000000000000000000000008152600401620006c9919062000d35565b60405180910390fd5b805181620006e09062000d86565b5f1c175f1b915050919050565b5f819050919050565b620007066200079860201b60201c565b73ffffffffffffffffffffffffffffffffffffffff166200072c6200079f60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16146200079657620007586200079860201b60201c565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016200078d919062000895565b60405180910390fd5b565b5f33905090565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f620007f582620007ca565b9050919050565b6200080781620007e9565b811462000812575f80fd5b50565b5f815190506200082581620007fc565b92915050565b5f805f60608486031215620008455762000844620007c6565b5b5f620008548682870162000815565b9350506020620008678682870162000815565b92505060406200087a8682870162000815565b9150509250925092565b6200088f81620007e9565b82525050565b5f602082019050620008aa5f83018462000884565b92915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200092c57607f821691505b602082108103620009425762000941620008e7565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620009a67fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000969565b620009b2868362000969565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f620009fc620009f6620009f084620009ca565b620009d3565b620009ca565b9050919050565b5f819050919050565b62000a1783620009dc565b62000a2f62000a268262000a03565b84845462000975565b825550505050565b5f90565b62000a4562000a37565b62000a5281848462000a0c565b505050565b5b8181101562000a795762000a6d5f8262000a3b565b60018101905062000a58565b5050565b601f82111562000ac85762000a928162000948565b62000a9d846200095a565b8101602085101562000aad578190505b62000ac562000abc856200095a565b83018262000a57565b50505b505050565b5f82821c905092915050565b5f62000aea5f198460080262000acd565b1980831691505092915050565b5f62000b04838362000ad9565b9150826002028217905092915050565b62000b1f82620008b0565b67ffffffffffffffff81111562000b3b5762000b3a620008ba565b5b62000b47825462000914565b62000b5482828562000a7d565b5f60209050601f83116001811462000b8a575f841562000b75578287015190505b62000b81858262000af7565b86555062000bf0565b601f19841662000b9a8662000948565b5f5b8281101562000bc35784890151825560018201915060208501945060208101905062000b9c565b8683101562000be3578489015162000bdf601f89168262000ad9565b8355505b6001600288020188555050505b505050505050565b5f819050919050565b62000c0c8162000bf8565b82525050565b62000c1d81620009ca565b82525050565b5f60a08201905062000c385f83018862000c01565b62000c47602083018762000c01565b62000c56604083018662000c01565b62000c65606083018562000c12565b62000c74608083018462000884565b9695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f82825260208201905092915050565b5f5b8381101562000cda57808201518184015260208101905062000cbd565b5f8484015250505050565b5f601f19601f8301169050919050565b5f62000d0182620008b0565b62000d0d818562000cab565b935062000d1f81856020860162000cbb565b62000d2a8162000ce5565b840191505092915050565b5f6020820190508181035f83015262000d4f818462000cf5565b905092915050565b5f81519050919050565b5f819050602082019050919050565b5f62000d7d825162000bf8565b80915050919050565b5f62000d928262000d57565b8262000d9e8462000d61565b905062000dab8162000d70565b9250602082101562000dee5762000de97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080262000969565b831692505b5050919050565b60805160a05160c05160e05161010051610120516101405161327962000e475f395f61156301525f61152801525f61223301525f61221201525f611fc601525f61201c01525f61204501526132795ff3fe608060405234801561000f575f80fd5b506004361061018c575f3560e01c806384b0196e116100dc578063c717a86e11610095578063f2fde38b1161006f578063f2fde38b146103e1578063f9f92be4146103fd578063fb8dc17914610419578063fe575a87146104375761018c565b8063c717a86e14610387578063d6b880c4146103a5578063e30c3978146103c35761018c565b806384b0196e146102ba5780638da5cb5b146102de57806399a5d747146102fc5780639af1d35a1461032c5780639f8cfbe41461034f578063b0cd88661461036b5761018c565b80633f4ba83a116101495780636c19e783116101235780636c19e78314610280578063715018a61461029c57806379ba5097146102a65780638456cb59146102b05761018c565b80633f4ba83a1461023c57806340094141146102465780635c975abb146102625761018c565b80631a895266146101905780631cbecd41146101ac578063238ac933146101c8578063266bbb6a146101e657806329eb1592146102025780632e0f26251461021e575b5f80fd5b6101aa60048036038101906101a591906122ee565b610467565b005b6101c660048036038101906101c191906122ee565b610509565b005b6101d0610555565b6040516101dd9190612328565b60405180910390f35b61020060048036038101906101fb91906123bd565b61057d565b005b61021c60048036038101906102179190612457565b6106dc565b005b610226610710565b6040516102339190612491565b60405180910390f35b610244610717565b005b610260600480360381019061025b9190612682565b610729565b005b61026a610870565b6040516102779190612791565b60405180910390f35b61029a600480360381019061029591906122ee565b610885565b005b6102a46108d0565b005b6102ae6108e3565b005b6102b8610971565b005b6102c2610983565b6040516102d59796959493929190612933565b60405180910390f35b6102e6610a28565b6040516102f39190612328565b60405180910390f35b610316600480360381019061031191906129b5565b610a4f565b60405161032391906129e0565b60405180910390f35b610334610e35565b60405161034696959493929190612a2a565b60405180910390f35b61036960048036038101906103649190612a89565b610ec0565b005b61038560048036038101906103809190612682565b610ed6565b005b61038f610fbb565b60405161039c9190612328565b60405180910390f35b6103ad610fe1565b6040516103ba9190612ac7565b60405180910390f35b6103cb611007565b6040516103d89190612328565b60405180910390f35b6103fb60048036038101906103f691906122ee565b61102f565b005b610417600480360381019061041291906122ee565b6110db565b005b61042161117e565b60405161042e9190612b53565b60405180910390f35b610451600480360381019061044c91906122ee565b611190565b60405161045e9190612791565b60405180910390f35b61046f6111e2565b5f60025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f117e3210bb9aa7d9baff172026820255c6f6c30ba8999d1c2fd88e2848137c4e60405160405180910390a250565b6105116111e2565b80600460016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6105856111e2565b6040518060c00160405280866fffffffffffffffffffffffffffffffff1681526020018561ffff1681526020018461ffff1681526020018361ffff1681526020018261ffff1681526020015f67ffffffffffffffff1681525060035f820151815f015f6101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506020820151815f0160106101000a81548161ffff021916908361ffff1602179055506040820151815f0160126101000a81548161ffff021916908361ffff1602179055506060820151815f0160146101000a81548161ffff021916908361ffff1602179055506080820151815f0160166101000a81548161ffff021916908361ffff16021790555060a0820151815f0160186101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055509050505050505050565b6106e46111e2565b8060045f6101000a81548160ff0219169083600281111561070857610707612ae0565b5b021790555050565b620f424081565b61071f6111e2565b610727611269565b565b6107316112ca565b8961073b8161130b565b896107458161130b565b6107548c8c8c8c8c8c8961139a565b600760019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef55bec68d308d8d8d8d8d8d8d6040518a63ffffffff1660e01b81526004016107bf99989796959493929190612b7b565b5f604051808303815f87803b1580156107d6575f80fd5b505af11580156107e8573d5f803e3d5ffd5b505050508a73ffffffffffffffffffffffffffffffffffffffff168c73ffffffffffffffffffffffffffffffffffffffff167f9fc75a639b7b689c31f060ef03c521cb7907ff88cc094bef18fbb039288584648c8c8c8c89604051610851959493929190612c58565b60405180910390a36108628a611483565b505050505050505050505050565b5f60075f9054906101000a900460ff16905090565b61088d6111e2565b8060095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6108d86111e2565b6108e15f611486565b565b5f6108ec6114b6565b90508073ffffffffffffffffffffffffffffffffffffffff1661090d611007565b73ffffffffffffffffffffffffffffffffffffffff161461096557806040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161095c9190612328565b60405180910390fd5b61096e81611486565b50565b6109796111e2565b6109816114bd565b565b5f6060805f805f606061099461151f565b61099c61155a565b46305f801b5f67ffffffffffffffff8111156109bb576109ba61255e565b5b6040519080825280602002602001820160405280156109e95781602001602082028036833780820191505090505b507f0f00000000000000000000000000000000000000000000000000000000000000959493929190965096509650965096509650965090919293949596565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f806002811115610a6357610a62612ae0565b5b60045f9054906101000a900460ff166002811115610a8457610a83612ae0565b5b03610a91575f9050610e30565b60016002811115610aa557610aa4612ae0565b5b60045f9054906101000a900460ff166002811115610ac657610ac5612ae0565b5b03610b045760035f015f9054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff169050610e30565b5f620f4240612710610b169190612cdd565b6fffffffffffffffffffffffffffffffff16831115610bd157620186a06fffffffffffffffffffffffffffffffff1660035f0160169054906101000a900461ffff1661ffff16620f4240612710610b6d9190612cdd565b6fffffffffffffffffffffffffffffffff1685610b8a9190612d19565b610b949190612d4c565b610b9e9190612dba565b81610ba99190612dea565b9050620f4240612710610bbc9190612cdd565b6fffffffffffffffffffffffffffffffff1692505b620f4240611388610be29190612cdd565b6fffffffffffffffffffffffffffffffff16831115610c9d57620186a06fffffffffffffffffffffffffffffffff1660035f0160149054906101000a900461ffff1661ffff16620f4240611388610c399190612cdd565b6fffffffffffffffffffffffffffffffff1685610c569190612d19565b610c609190612d4c565b610c6a9190612dba565b81610c759190612dea565b9050620f4240611388610c889190612cdd565b6fffffffffffffffffffffffffffffffff1692505b620f42406103e8610cae9190612cdd565b6fffffffffffffffffffffffffffffffff16831115610d6957620186a06fffffffffffffffffffffffffffffffff1660035f0160129054906101000a900461ffff1661ffff16620f42406103e8610d059190612cdd565b6fffffffffffffffffffffffffffffffff1685610d229190612d19565b610d2c9190612d4c565b610d369190612dba565b81610d419190612dea565b9050620f42406103e8610d549190612cdd565b6fffffffffffffffffffffffffffffffff1692505b620186a06fffffffffffffffffffffffffffffffff1660035f0160109054906101000a900461ffff1661ffff1684610da19190612d4c565b610dab9190612dba565b81610db69190612dea565b905060035f015f9054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16811015610e2b5760035f015f9054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16915050610e30565b809150505b919050565b6003805f015f9054906101000a90046fffffffffffffffffffffffffffffffff1690805f0160109054906101000a900461ffff1690805f0160129054906101000a900461ffff1690805f0160149054906101000a900461ffff1690805f0160169054906101000a900461ffff1690805f0160189054906101000a900467ffffffffffffffff16905086565b610ec86111e2565b610ed28282611595565b5050565b610ede6112ca565b89610ee88161130b565b89610ef28161130b565b610efe8c888b8b61164b565b610f0d8c8c8c8c8c8c8961139a565b610f3f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff168c8c8c8c8c8c8c8c6116ed565b610f498b886117e0565b610f538b88611595565b610f5d8b8b611881565b8a73ffffffffffffffffffffffffffffffffffffffff167f70d7ab06c601bfbc6d266f8a85337783d85e67832224829ea01ac93d2c0701668b89604051610fa5929190612e1d565b60405180910390a2505050505050505050505050565b600460019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f4e28ed42d027eeb58993b424b784ad6ee35fa214e181855687ea18fabae638405f1b81565b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6110376111e2565b8060015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16611096610a28565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6110e36111e2565b600160025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167fffa4e6181777692565cf28528fc88fd1516ea86b56da075235fa575af6a4b85560405160405180910390a250565b60045f9054906101000a900460ff1681565b5f60025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff169050919050565b6111ea6114b6565b73ffffffffffffffffffffffffffffffffffffffff16611208610a28565b73ffffffffffffffffffffffffffffffffffffffff16146112675761122b6114b6565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161125e9190612328565b60405180910390fd5b565b6112716119fe565b5f60075f6101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6112b36114b6565b6040516112c09190612328565b60405180910390a1565b6112d2610870565b15611309576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60025f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff161561139757806040517fe137861c00000000000000000000000000000000000000000000000000000000815260040161138e9190612328565b60405180910390fd5b50565b5f8787878787876040516020016113b696959493929190612ec9565b6040516020818303038152906040528051906020012090505f816040516020016113e09190612f8c565b6040516020818303038152906040528051906020012090505f6114038285611a3e565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461147757808a6040517f18852ffc00000000000000000000000000000000000000000000000000000000815260040161146e929190612fb1565b60405180910390fd5b50505050505050505050565b50565b60015f6101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556114b381611a68565b50565b5f33905090565b6114c56112ca565b600160075f6101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586115086114b6565b6040516115159190612328565b60405180910390a1565b606061155560057f0000000000000000000000000000000000000000000000000000000000000000611b2990919063ffffffff16565b905090565b606061159060067f0000000000000000000000000000000000000000000000000000000000000000611b2990919063ffffffff16565b905090565b600160085f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff167f911165de2ecddb09236f75d07c747493df144e504e4e25fdbbfad4feaed518f18260405161163f9190612ac7565b60405180910390a25050565b81421015611694578181426040517fb2fa54b100000000000000000000000000000000000000000000000000000000815260040161168b93929190612fd8565b60405180910390fd5b804211156116dd578181426040517fb2fa54b10000000000000000000000000000000000000000000000000000000081526004016116d493929190612fd8565b60405180910390fd5b6116e784846117e0565b50505050565b5f7f4e28ed42d027eeb58993b424b784ad6ee35fa214e181855687ea18fabae638405f1b8a8a8a8a8a8a60405160200161172d979695949392919061300d565b6040516020818303038152906040528051906020012090505f61174f82611bd6565b90505f61175e82878787611bef565b90508b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146117d257808c6040517fdccb3d5e0000000000000000000000000000000000000000000000000000000081526004016117c9929190612fb1565b60405180910390fd5b505050505050505050505050565b60085f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8281526020019081526020015f205f9054906101000a900460ff161561187d5781816040517fb4fbc49d00000000000000000000000000000000000000000000000000000000815260040161187492919061307a565b60405180910390fd5b5050565b5f8061188d8484611c1d565b915091505f81111561195a57600760019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600460019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b81526004016119189291906130a1565b6020604051808303815f875af1158015611934573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061195891906130f2565b505b600760019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85846040518363ffffffff1660e01b81526004016119b79291906130a1565b6020604051808303815f875af11580156119d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119f791906130f2565b5050505050565b611a06610870565b611a3c576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f805f80611a4c8686611d9a565b925092509250611a5c8282611def565b82935050505092915050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b606060ff5f1b8314611b4557611b3e83611f51565b9050611bd0565b818054611b519061314a565b80601f0160208091040260200160405190810160405280929190818152602001828054611b7d9061314a565b8015611bc85780601f10611b9f57610100808354040283529160200191611bc8565b820191905f5260205f20905b815481529060010190602001808311611bab57829003601f168201915b505050505090505b92915050565b5f611be8611be2611fc3565b83612079565b9050919050565b5f805f80611bff888888886120b9565b925092509250611c0f8282611def565b829350505050949350505050565b5f805f611c2984610a4f565b9050600460019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611c84575f90505b5f73ffffffffffffffffffffffffffffffffffffffff16600460019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603611d3857600460019054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fe38152de000000000000000000000000000000000000000000000000000000008152600401611d2f9190612328565b60405180910390fd5b83811115611d81578484826040517f5038661e000000000000000000000000000000000000000000000000000000008152600401611d789392919061317a565b60405180910390fd5b8084611d8d9190612d19565b8192509250509250929050565b5f805f6041845103611dda575f805f602087015192506040870151915060608701515f1a9050611dcc888285856120b9565b955095509550505050611de8565b5f600285515f1b9250925092505b9250925092565b5f6003811115611e0257611e01612ae0565b5b826003811115611e1557611e14612ae0565b5b0315611f4d5760016003811115611e2f57611e2e612ae0565b5b826003811115611e4257611e41612ae0565b5b03611e79576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026003811115611e8d57611e8c612ae0565b5b826003811115611ea057611e9f612ae0565b5b03611ee457805f1c6040517ffce698f7000000000000000000000000000000000000000000000000000000008152600401611edb91906129e0565b60405180910390fd5b600380811115611ef757611ef6612ae0565b5b826003811115611f0a57611f09612ae0565b5b03611f4c57806040517fd78bce0c000000000000000000000000000000000000000000000000000000008152600401611f439190612ac7565b60405180910390fd5b5b5050565b60605f611f5d836121a0565b90505f602067ffffffffffffffff811115611f7b57611f7a61255e565b5b6040519080825280601f01601f191660200182016040528015611fad5781602001600182028036833780820191505090505b5090508181528360208201528092505050919050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614801561203e57507f000000000000000000000000000000000000000000000000000000000000000046145b1561206b577f00000000000000000000000000000000000000000000000000000000000000009050612076565b6120736121ee565b90505b90565b5f6040517f190100000000000000000000000000000000000000000000000000000000000081528360028201528260228201526042812091505092915050565b5f805f7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0845f1c11156120f5575f600385925092509250612196565b5f6001888888886040515f815260200160405260405161211894939291906131af565b6020604051602081039080840390855afa158015612138573d5f803e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612189575f60015f801b93509350935050612196565b805f805f1b935093509350505b9450945094915050565b5f8060ff835f1c169050601f8111156121e5576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80915050919050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000046306040516020016122689594939291906131f2565b60405160208183030381529060405280519060200120905090565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6122bd82612294565b9050919050565b6122cd816122b3565b81146122d7575f80fd5b50565b5f813590506122e8816122c4565b92915050565b5f602082840312156123035761230261228c565b5b5f612310848285016122da565b91505092915050565b612322816122b3565b82525050565b5f60208201905061233b5f830184612319565b92915050565b5f6fffffffffffffffffffffffffffffffff82169050919050565b61236581612341565b811461236f575f80fd5b50565b5f813590506123808161235c565b92915050565b5f61ffff82169050919050565b61239c81612386565b81146123a6575f80fd5b50565b5f813590506123b781612393565b92915050565b5f805f805f60a086880312156123d6576123d561228c565b5b5f6123e388828901612372565b95505060206123f4888289016123a9565b9450506040612405888289016123a9565b9350506060612416888289016123a9565b9250506080612427888289016123a9565b9150509295509295909350565b60038110612440575f80fd5b50565b5f8135905061245181612434565b92915050565b5f6020828403121561246c5761246b61228c565b5b5f61247984828501612443565b91505092915050565b61248b81612341565b82525050565b5f6020820190506124a45f830184612482565b92915050565b5f819050919050565b6124bc816124aa565b81146124c6575f80fd5b50565b5f813590506124d7816124b3565b92915050565b5f819050919050565b6124ef816124dd565b81146124f9575f80fd5b50565b5f8135905061250a816124e6565b92915050565b5f60ff82169050919050565b61252581612510565b811461252f575f80fd5b50565b5f813590506125408161251c565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6125948261254e565b810181811067ffffffffffffffff821117156125b3576125b261255e565b5b80604052505050565b5f6125c5612283565b90506125d1828261258b565b919050565b5f67ffffffffffffffff8211156125f0576125ef61255e565b5b6125f98261254e565b9050602081019050919050565b828183375f83830152505050565b5f612626612621846125d6565b6125bc565b9050828152602081018484840111156126425761264161254a565b5b61264d848285612606565b509392505050565b5f82601f83011261266957612668612546565b5b8135612679848260208601612614565b91505092915050565b5f805f805f805f805f806101408b8d0312156126a1576126a061228c565b5b5f6126ae8d828e016122da565b9a505060206126bf8d828e016122da565b99505060406126d08d828e016124c9565b98505060606126e18d828e016124c9565b97505060806126f28d828e016124c9565b96505060a06127038d828e016124fc565b95505060c06127148d828e01612532565b94505060e06127258d828e016124fc565b9350506101006127378d828e016124fc565b9250506101208b013567ffffffffffffffff81111561275957612758612290565b5b6127658d828e01612655565b9150509295989b9194979a5092959850565b5f8115159050919050565b61278b81612777565b82525050565b5f6020820190506127a45f830184612782565b92915050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6127de816127aa565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561281b578082015181840152602081019050612800565b5f8484015250505050565b5f612830826127e4565b61283a81856127ee565b935061284a8185602086016127fe565b6128538161254e565b840191505092915050565b612867816124aa565b82525050565b612876816124dd565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6128ae816124aa565b82525050565b5f6128bf83836128a5565b60208301905092915050565b5f602082019050919050565b5f6128e18261287c565b6128eb8185612886565b93506128f683612896565b805f5b8381101561292657815161290d88826128b4565b9750612918836128cb565b9250506001810190506128f9565b5085935050505092915050565b5f60e0820190506129465f83018a6127d5565b81810360208301526129588189612826565b9050818103604083015261296c8188612826565b905061297b606083018761285e565b6129886080830186612319565b61299560a083018561286d565b81810360c08301526129a781846128d7565b905098975050505050505050565b5f602082840312156129ca576129c961228c565b5b5f6129d7848285016124c9565b91505092915050565b5f6020820190506129f35f83018461285e565b92915050565b612a0281612386565b82525050565b5f67ffffffffffffffff82169050919050565b612a2481612a08565b82525050565b5f60c082019050612a3d5f830189612482565b612a4a60208301886129f9565b612a5760408301876129f9565b612a6460608301866129f9565b612a7160808301856129f9565b612a7e60a0830184612a1b565b979650505050505050565b5f8060408385031215612a9f57612a9e61228c565b5b5f612aac858286016122da565b9250506020612abd858286016124fc565b9150509250929050565b5f602082019050612ada5f83018461286d565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60038110612b1e57612b1d612ae0565b5b50565b5f819050612b2e82612b0d565b919050565b5f612b3d82612b21565b9050919050565b612b4d81612b33565b82525050565b5f602082019050612b665f830184612b44565b92915050565b612b7581612510565b82525050565b5f61012082019050612b8f5f83018c612319565b612b9c602083018b612319565b612ba9604083018a61285e565b612bb6606083018961285e565b612bc3608083018861285e565b612bd060a083018761286d565b612bdd60c0830186612b6c565b612bea60e083018561286d565b612bf861010083018461286d565b9a9950505050505050505050565b5f81519050919050565b5f82825260208201905092915050565b5f612c2a82612c06565b612c348185612c10565b9350612c448185602086016127fe565b612c4d8161254e565b840191505092915050565b5f60a082019050612c6b5f83018861285e565b612c78602083018761285e565b612c85604083018661285e565b612c92606083018561286d565b8181036080830152612ca48184612c20565b90509695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612ce782612341565b9150612cf283612341565b9250828202612d0081612341565b9150808214612d1257612d11612cb0565b5b5092915050565b5f612d23826124aa565b9150612d2e836124aa565b9250828203905081811115612d4657612d45612cb0565b5b92915050565b5f612d56826124aa565b9150612d61836124aa565b9250828202612d6f816124aa565b91508282048414831517612d8657612d85612cb0565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f612dc4826124aa565b9150612dcf836124aa565b925082612ddf57612dde612d8d565b5b828204905092915050565b5f612df4826124aa565b9150612dff836124aa565b9250828201905080821115612e1757612e16612cb0565b5b92915050565b5f604082019050612e305f83018561285e565b612e3d602083018461286d565b9392505050565b5f8160601b9050919050565b5f612e5a82612e44565b9050919050565b5f612e6b82612e50565b9050919050565b612e83612e7e826122b3565b612e61565b82525050565b5f819050919050565b612ea3612e9e826124aa565b612e89565b82525050565b5f819050919050565b612ec3612ebe826124dd565b612ea9565b82525050565b5f612ed48289612e72565b601482019150612ee48288612e72565b601482019150612ef48287612e92565b602082019150612f048286612e92565b602082019150612f148285612e92565b602082019150612f248284612eb2565b602082019150819050979650505050505050565b5f81905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000005f82015250565b5f612f76601c83612f38565b9150612f8182612f42565b601c82019050919050565b5f612f9682612f6a565b9150612fa28284612eb2565b60208201915081905092915050565b5f604082019050612fc45f830185612319565b612fd16020830184612319565b9392505050565b5f606082019050612feb5f83018661285e565b612ff8602083018561285e565b613005604083018461285e565b949350505050565b5f60e0820190506130205f83018a61286d565b61302d6020830189612319565b61303a6040830188612319565b613047606083018761285e565b613054608083018661285e565b61306160a083018561285e565b61306e60c083018461286d565b98975050505050505050565b5f60408201905061308d5f830185612319565b61309a602083018461286d565b9392505050565b5f6040820190506130b45f830185612319565b6130c1602083018461285e565b9392505050565b6130d181612777565b81146130db575f80fd5b50565b5f815190506130ec816130c8565b92915050565b5f602082840312156131075761310661228c565b5b5f613114848285016130de565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061316157607f821691505b6020821081036131745761317361311d565b5b50919050565b5f60608201905061318d5f830186612319565b61319a602083018561285e565b6131a7604083018461285e565b949350505050565b5f6080820190506131c25f83018761286d565b6131cf6020830186612b6c565b6131dc604083018561286d565b6131e9606083018461286d565b95945050505050565b5f60a0820190506132055f83018861286d565b613212602083018761286d565b61321f604083018661286d565b61322c606083018561285e565b6132396080830184612319565b969550505050505056fea2646970667358221220bd0dabbbc2d72a0e86a73812a9d8680d73fc16c1979d81bf5439e90a4879d2d664736f6c634300081800330000000000000000000000006278b07059f7688a944742e6bd1fbc8e2cd35ae8000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006278a5a4e6ca72c502a307d8752f8648c5095232
Deployed Bytecode
0x608060405234801561000f575f80fd5b506004361061018c575f3560e01c806384b0196e116100dc578063c717a86e11610095578063f2fde38b1161006f578063f2fde38b146103e1578063f9f92be4146103fd578063fb8dc17914610419578063fe575a87146104375761018c565b8063c717a86e14610387578063d6b880c4146103a5578063e30c3978146103c35761018c565b806384b0196e146102ba5780638da5cb5b146102de57806399a5d747146102fc5780639af1d35a1461032c5780639f8cfbe41461034f578063b0cd88661461036b5761018c565b80633f4ba83a116101495780636c19e783116101235780636c19e78314610280578063715018a61461029c57806379ba5097146102a65780638456cb59146102b05761018c565b80633f4ba83a1461023c57806340094141146102465780635c975abb146102625761018c565b80631a895266146101905780631cbecd41146101ac578063238ac933146101c8578063266bbb6a146101e657806329eb1592146102025780632e0f26251461021e575b5f80fd5b6101aa60048036038101906101a591906122ee565b610467565b005b6101c660048036038101906101c191906122ee565b610509565b005b6101d0610555565b6040516101dd9190612328565b60405180910390f35b61020060048036038101906101fb91906123bd565b61057d565b005b61021c60048036038101906102179190612457565b6106dc565b005b610226610710565b6040516102339190612491565b60405180910390f35b610244610717565b005b610260600480360381019061025b9190612682565b610729565b005b61026a610870565b6040516102779190612791565b60405180910390f35b61029a600480360381019061029591906122ee565b610885565b005b6102a46108d0565b005b6102ae6108e3565b005b6102b8610971565b005b6102c2610983565b6040516102d59796959493929190612933565b60405180910390f35b6102e6610a28565b6040516102f39190612328565b60405180910390f35b610316600480360381019061031191906129b5565b610a4f565b60405161032391906129e0565b60405180910390f35b610334610e35565b60405161034696959493929190612a2a565b60405180910390f35b61036960048036038101906103649190612a89565b610ec0565b005b61038560048036038101906103809190612682565b610ed6565b005b61038f610fbb565b60405161039c9190612328565b60405180910390f35b6103ad610fe1565b6040516103ba9190612ac7565b60405180910390f35b6103cb611007565b6040516103d89190612328565b60405180910390f35b6103fb60048036038101906103f691906122ee565b61102f565b005b610417600480360381019061041291906122ee565b6110db565b005b61042161117e565b60405161042e9190612b53565b60405180910390f35b610451600480360381019061044c91906122ee565b611190565b60405161045e9190612791565b60405180910390f35b61046f6111e2565b5f60025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f117e3210bb9aa7d9baff172026820255c6f6c30ba8999d1c2fd88e2848137c4e60405160405180910390a250565b6105116111e2565b80600460016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6105856111e2565b6040518060c00160405280866fffffffffffffffffffffffffffffffff1681526020018561ffff1681526020018461ffff1681526020018361ffff1681526020018261ffff1681526020015f67ffffffffffffffff1681525060035f820151815f015f6101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506020820151815f0160106101000a81548161ffff021916908361ffff1602179055506040820151815f0160126101000a81548161ffff021916908361ffff1602179055506060820151815f0160146101000a81548161ffff021916908361ffff1602179055506080820151815f0160166101000a81548161ffff021916908361ffff16021790555060a0820151815f0160186101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055509050505050505050565b6106e46111e2565b8060045f6101000a81548160ff0219169083600281111561070857610707612ae0565b5b021790555050565b620f424081565b61071f6111e2565b610727611269565b565b6107316112ca565b8961073b8161130b565b896107458161130b565b6107548c8c8c8c8c8c8961139a565b600760019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef55bec68d308d8d8d8d8d8d8d6040518a63ffffffff1660e01b81526004016107bf99989796959493929190612b7b565b5f604051808303815f87803b1580156107d6575f80fd5b505af11580156107e8573d5f803e3d5ffd5b505050508a73ffffffffffffffffffffffffffffffffffffffff168c73ffffffffffffffffffffffffffffffffffffffff167f9fc75a639b7b689c31f060ef03c521cb7907ff88cc094bef18fbb039288584648c8c8c8c89604051610851959493929190612c58565b60405180910390a36108628a611483565b505050505050505050505050565b5f60075f9054906101000a900460ff16905090565b61088d6111e2565b8060095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6108d86111e2565b6108e15f611486565b565b5f6108ec6114b6565b90508073ffffffffffffffffffffffffffffffffffffffff1661090d611007565b73ffffffffffffffffffffffffffffffffffffffff161461096557806040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161095c9190612328565b60405180910390fd5b61096e81611486565b50565b6109796111e2565b6109816114bd565b565b5f6060805f805f606061099461151f565b61099c61155a565b46305f801b5f67ffffffffffffffff8111156109bb576109ba61255e565b5b6040519080825280602002602001820160405280156109e95781602001602082028036833780820191505090505b507f0f00000000000000000000000000000000000000000000000000000000000000959493929190965096509650965096509650965090919293949596565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f806002811115610a6357610a62612ae0565b5b60045f9054906101000a900460ff166002811115610a8457610a83612ae0565b5b03610a91575f9050610e30565b60016002811115610aa557610aa4612ae0565b5b60045f9054906101000a900460ff166002811115610ac657610ac5612ae0565b5b03610b045760035f015f9054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff169050610e30565b5f620f4240612710610b169190612cdd565b6fffffffffffffffffffffffffffffffff16831115610bd157620186a06fffffffffffffffffffffffffffffffff1660035f0160169054906101000a900461ffff1661ffff16620f4240612710610b6d9190612cdd565b6fffffffffffffffffffffffffffffffff1685610b8a9190612d19565b610b949190612d4c565b610b9e9190612dba565b81610ba99190612dea565b9050620f4240612710610bbc9190612cdd565b6fffffffffffffffffffffffffffffffff1692505b620f4240611388610be29190612cdd565b6fffffffffffffffffffffffffffffffff16831115610c9d57620186a06fffffffffffffffffffffffffffffffff1660035f0160149054906101000a900461ffff1661ffff16620f4240611388610c399190612cdd565b6fffffffffffffffffffffffffffffffff1685610c569190612d19565b610c609190612d4c565b610c6a9190612dba565b81610c759190612dea565b9050620f4240611388610c889190612cdd565b6fffffffffffffffffffffffffffffffff1692505b620f42406103e8610cae9190612cdd565b6fffffffffffffffffffffffffffffffff16831115610d6957620186a06fffffffffffffffffffffffffffffffff1660035f0160129054906101000a900461ffff1661ffff16620f42406103e8610d059190612cdd565b6fffffffffffffffffffffffffffffffff1685610d229190612d19565b610d2c9190612d4c565b610d369190612dba565b81610d419190612dea565b9050620f42406103e8610d549190612cdd565b6fffffffffffffffffffffffffffffffff1692505b620186a06fffffffffffffffffffffffffffffffff1660035f0160109054906101000a900461ffff1661ffff1684610da19190612d4c565b610dab9190612dba565b81610db69190612dea565b905060035f015f9054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16811015610e2b5760035f015f9054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16915050610e30565b809150505b919050565b6003805f015f9054906101000a90046fffffffffffffffffffffffffffffffff1690805f0160109054906101000a900461ffff1690805f0160129054906101000a900461ffff1690805f0160149054906101000a900461ffff1690805f0160169054906101000a900461ffff1690805f0160189054906101000a900467ffffffffffffffff16905086565b610ec86111e2565b610ed28282611595565b5050565b610ede6112ca565b89610ee88161130b565b89610ef28161130b565b610efe8c888b8b61164b565b610f0d8c8c8c8c8c8c8961139a565b610f3f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff168c8c8c8c8c8c8c8c6116ed565b610f498b886117e0565b610f538b88611595565b610f5d8b8b611881565b8a73ffffffffffffffffffffffffffffffffffffffff167f70d7ab06c601bfbc6d266f8a85337783d85e67832224829ea01ac93d2c0701668b89604051610fa5929190612e1d565b60405180910390a2505050505050505050505050565b600460019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f4e28ed42d027eeb58993b424b784ad6ee35fa214e181855687ea18fabae638405f1b81565b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6110376111e2565b8060015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16611096610a28565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6110e36111e2565b600160025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167fffa4e6181777692565cf28528fc88fd1516ea86b56da075235fa575af6a4b85560405160405180910390a250565b60045f9054906101000a900460ff1681565b5f60025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff169050919050565b6111ea6114b6565b73ffffffffffffffffffffffffffffffffffffffff16611208610a28565b73ffffffffffffffffffffffffffffffffffffffff16146112675761122b6114b6565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161125e9190612328565b60405180910390fd5b565b6112716119fe565b5f60075f6101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6112b36114b6565b6040516112c09190612328565b60405180910390a1565b6112d2610870565b15611309576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60025f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff161561139757806040517fe137861c00000000000000000000000000000000000000000000000000000000815260040161138e9190612328565b60405180910390fd5b50565b5f8787878787876040516020016113b696959493929190612ec9565b6040516020818303038152906040528051906020012090505f816040516020016113e09190612f8c565b6040516020818303038152906040528051906020012090505f6114038285611a3e565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461147757808a6040517f18852ffc00000000000000000000000000000000000000000000000000000000815260040161146e929190612fb1565b60405180910390fd5b50505050505050505050565b50565b60015f6101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556114b381611a68565b50565b5f33905090565b6114c56112ca565b600160075f6101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586115086114b6565b6040516115159190612328565b60405180910390a1565b606061155560057f555344432042726964676500000000000000000000000000000000000000000b611b2990919063ffffffff16565b905090565b606061159060067f3100000000000000000000000000000000000000000000000000000000000001611b2990919063ffffffff16565b905090565b600160085f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff167f911165de2ecddb09236f75d07c747493df144e504e4e25fdbbfad4feaed518f18260405161163f9190612ac7565b60405180910390a25050565b81421015611694578181426040517fb2fa54b100000000000000000000000000000000000000000000000000000000815260040161168b93929190612fd8565b60405180910390fd5b804211156116dd578181426040517fb2fa54b10000000000000000000000000000000000000000000000000000000081526004016116d493929190612fd8565b60405180910390fd5b6116e784846117e0565b50505050565b5f7f4e28ed42d027eeb58993b424b784ad6ee35fa214e181855687ea18fabae638405f1b8a8a8a8a8a8a60405160200161172d979695949392919061300d565b6040516020818303038152906040528051906020012090505f61174f82611bd6565b90505f61175e82878787611bef565b90508b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146117d257808c6040517fdccb3d5e0000000000000000000000000000000000000000000000000000000081526004016117c9929190612fb1565b60405180910390fd5b505050505050505050505050565b60085f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8281526020019081526020015f205f9054906101000a900460ff161561187d5781816040517fb4fbc49d00000000000000000000000000000000000000000000000000000000815260040161187492919061307a565b60405180910390fd5b5050565b5f8061188d8484611c1d565b915091505f81111561195a57600760019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600460019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b81526004016119189291906130a1565b6020604051808303815f875af1158015611934573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061195891906130f2565b505b600760019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85846040518363ffffffff1660e01b81526004016119b79291906130a1565b6020604051808303815f875af11580156119d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119f791906130f2565b5050505050565b611a06610870565b611a3c576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f805f80611a4c8686611d9a565b925092509250611a5c8282611def565b82935050505092915050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b606060ff5f1b8314611b4557611b3e83611f51565b9050611bd0565b818054611b519061314a565b80601f0160208091040260200160405190810160405280929190818152602001828054611b7d9061314a565b8015611bc85780601f10611b9f57610100808354040283529160200191611bc8565b820191905f5260205f20905b815481529060010190602001808311611bab57829003601f168201915b505050505090505b92915050565b5f611be8611be2611fc3565b83612079565b9050919050565b5f805f80611bff888888886120b9565b925092509250611c0f8282611def565b829350505050949350505050565b5f805f611c2984610a4f565b9050600460019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611c84575f90505b5f73ffffffffffffffffffffffffffffffffffffffff16600460019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603611d3857600460019054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fe38152de000000000000000000000000000000000000000000000000000000008152600401611d2f9190612328565b60405180910390fd5b83811115611d81578484826040517f5038661e000000000000000000000000000000000000000000000000000000008152600401611d789392919061317a565b60405180910390fd5b8084611d8d9190612d19565b8192509250509250929050565b5f805f6041845103611dda575f805f602087015192506040870151915060608701515f1a9050611dcc888285856120b9565b955095509550505050611de8565b5f600285515f1b9250925092505b9250925092565b5f6003811115611e0257611e01612ae0565b5b826003811115611e1557611e14612ae0565b5b0315611f4d5760016003811115611e2f57611e2e612ae0565b5b826003811115611e4257611e41612ae0565b5b03611e79576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026003811115611e8d57611e8c612ae0565b5b826003811115611ea057611e9f612ae0565b5b03611ee457805f1c6040517ffce698f7000000000000000000000000000000000000000000000000000000008152600401611edb91906129e0565b60405180910390fd5b600380811115611ef757611ef6612ae0565b5b826003811115611f0a57611f09612ae0565b5b03611f4c57806040517fd78bce0c000000000000000000000000000000000000000000000000000000008152600401611f439190612ac7565b60405180910390fd5b5b5050565b60605f611f5d836121a0565b90505f602067ffffffffffffffff811115611f7b57611f7a61255e565b5b6040519080825280601f01601f191660200182016040528015611fad5781602001600182028036833780820191505090505b5090508181528360208201528092505050919050565b5f7f0000000000000000000000002add4242b7eb8aa167ee374f706b8db28258c70873ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614801561203e57507f000000000000000000000000000000000000000000000000000000000000000146145b1561206b577fa679f710213c5836d7ed9db5ae4707ff4aaeb442e7187294dc01faa65e5e7b889050612076565b6120736121ee565b90505b90565b5f6040517f190100000000000000000000000000000000000000000000000000000000000081528360028201528260228201526042812091505092915050565b5f805f7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0845f1c11156120f5575f600385925092509250612196565b5f6001888888886040515f815260200160405260405161211894939291906131af565b6020604051602081039080840390855afa158015612138573d5f803e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612189575f60015f801b93509350935050612196565b805f805f1b935093509350505b9450945094915050565b5f8060ff835f1c169050601f8111156121e5576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80915050919050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7fef64f01db6529bb747f96e9a34d66d0792b528e0dd9afa2b18560ca4ecfa25307fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc646306040516020016122689594939291906131f2565b60405160208183030381529060405280519060200120905090565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6122bd82612294565b9050919050565b6122cd816122b3565b81146122d7575f80fd5b50565b5f813590506122e8816122c4565b92915050565b5f602082840312156123035761230261228c565b5b5f612310848285016122da565b91505092915050565b612322816122b3565b82525050565b5f60208201905061233b5f830184612319565b92915050565b5f6fffffffffffffffffffffffffffffffff82169050919050565b61236581612341565b811461236f575f80fd5b50565b5f813590506123808161235c565b92915050565b5f61ffff82169050919050565b61239c81612386565b81146123a6575f80fd5b50565b5f813590506123b781612393565b92915050565b5f805f805f60a086880312156123d6576123d561228c565b5b5f6123e388828901612372565b95505060206123f4888289016123a9565b9450506040612405888289016123a9565b9350506060612416888289016123a9565b9250506080612427888289016123a9565b9150509295509295909350565b60038110612440575f80fd5b50565b5f8135905061245181612434565b92915050565b5f6020828403121561246c5761246b61228c565b5b5f61247984828501612443565b91505092915050565b61248b81612341565b82525050565b5f6020820190506124a45f830184612482565b92915050565b5f819050919050565b6124bc816124aa565b81146124c6575f80fd5b50565b5f813590506124d7816124b3565b92915050565b5f819050919050565b6124ef816124dd565b81146124f9575f80fd5b50565b5f8135905061250a816124e6565b92915050565b5f60ff82169050919050565b61252581612510565b811461252f575f80fd5b50565b5f813590506125408161251c565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6125948261254e565b810181811067ffffffffffffffff821117156125b3576125b261255e565b5b80604052505050565b5f6125c5612283565b90506125d1828261258b565b919050565b5f67ffffffffffffffff8211156125f0576125ef61255e565b5b6125f98261254e565b9050602081019050919050565b828183375f83830152505050565b5f612626612621846125d6565b6125bc565b9050828152602081018484840111156126425761264161254a565b5b61264d848285612606565b509392505050565b5f82601f83011261266957612668612546565b5b8135612679848260208601612614565b91505092915050565b5f805f805f805f805f806101408b8d0312156126a1576126a061228c565b5b5f6126ae8d828e016122da565b9a505060206126bf8d828e016122da565b99505060406126d08d828e016124c9565b98505060606126e18d828e016124c9565b97505060806126f28d828e016124c9565b96505060a06127038d828e016124fc565b95505060c06127148d828e01612532565b94505060e06127258d828e016124fc565b9350506101006127378d828e016124fc565b9250506101208b013567ffffffffffffffff81111561275957612758612290565b5b6127658d828e01612655565b9150509295989b9194979a5092959850565b5f8115159050919050565b61278b81612777565b82525050565b5f6020820190506127a45f830184612782565b92915050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6127de816127aa565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561281b578082015181840152602081019050612800565b5f8484015250505050565b5f612830826127e4565b61283a81856127ee565b935061284a8185602086016127fe565b6128538161254e565b840191505092915050565b612867816124aa565b82525050565b612876816124dd565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6128ae816124aa565b82525050565b5f6128bf83836128a5565b60208301905092915050565b5f602082019050919050565b5f6128e18261287c565b6128eb8185612886565b93506128f683612896565b805f5b8381101561292657815161290d88826128b4565b9750612918836128cb565b9250506001810190506128f9565b5085935050505092915050565b5f60e0820190506129465f83018a6127d5565b81810360208301526129588189612826565b9050818103604083015261296c8188612826565b905061297b606083018761285e565b6129886080830186612319565b61299560a083018561286d565b81810360c08301526129a781846128d7565b905098975050505050505050565b5f602082840312156129ca576129c961228c565b5b5f6129d7848285016124c9565b91505092915050565b5f6020820190506129f35f83018461285e565b92915050565b612a0281612386565b82525050565b5f67ffffffffffffffff82169050919050565b612a2481612a08565b82525050565b5f60c082019050612a3d5f830189612482565b612a4a60208301886129f9565b612a5760408301876129f9565b612a6460608301866129f9565b612a7160808301856129f9565b612a7e60a0830184612a1b565b979650505050505050565b5f8060408385031215612a9f57612a9e61228c565b5b5f612aac858286016122da565b9250506020612abd858286016124fc565b9150509250929050565b5f602082019050612ada5f83018461286d565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60038110612b1e57612b1d612ae0565b5b50565b5f819050612b2e82612b0d565b919050565b5f612b3d82612b21565b9050919050565b612b4d81612b33565b82525050565b5f602082019050612b665f830184612b44565b92915050565b612b7581612510565b82525050565b5f61012082019050612b8f5f83018c612319565b612b9c602083018b612319565b612ba9604083018a61285e565b612bb6606083018961285e565b612bc3608083018861285e565b612bd060a083018761286d565b612bdd60c0830186612b6c565b612bea60e083018561286d565b612bf861010083018461286d565b9a9950505050505050505050565b5f81519050919050565b5f82825260208201905092915050565b5f612c2a82612c06565b612c348185612c10565b9350612c448185602086016127fe565b612c4d8161254e565b840191505092915050565b5f60a082019050612c6b5f83018861285e565b612c78602083018761285e565b612c85604083018661285e565b612c92606083018561286d565b8181036080830152612ca48184612c20565b90509695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612ce782612341565b9150612cf283612341565b9250828202612d0081612341565b9150808214612d1257612d11612cb0565b5b5092915050565b5f612d23826124aa565b9150612d2e836124aa565b9250828203905081811115612d4657612d45612cb0565b5b92915050565b5f612d56826124aa565b9150612d61836124aa565b9250828202612d6f816124aa565b91508282048414831517612d8657612d85612cb0565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f612dc4826124aa565b9150612dcf836124aa565b925082612ddf57612dde612d8d565b5b828204905092915050565b5f612df4826124aa565b9150612dff836124aa565b9250828201905080821115612e1757612e16612cb0565b5b92915050565b5f604082019050612e305f83018561285e565b612e3d602083018461286d565b9392505050565b5f8160601b9050919050565b5f612e5a82612e44565b9050919050565b5f612e6b82612e50565b9050919050565b612e83612e7e826122b3565b612e61565b82525050565b5f819050919050565b612ea3612e9e826124aa565b612e89565b82525050565b5f819050919050565b612ec3612ebe826124dd565b612ea9565b82525050565b5f612ed48289612e72565b601482019150612ee48288612e72565b601482019150612ef48287612e92565b602082019150612f048286612e92565b602082019150612f148285612e92565b602082019150612f248284612eb2565b602082019150819050979650505050505050565b5f81905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000005f82015250565b5f612f76601c83612f38565b9150612f8182612f42565b601c82019050919050565b5f612f9682612f6a565b9150612fa28284612eb2565b60208201915081905092915050565b5f604082019050612fc45f830185612319565b612fd16020830184612319565b9392505050565b5f606082019050612feb5f83018661285e565b612ff8602083018561285e565b613005604083018461285e565b949350505050565b5f60e0820190506130205f83018a61286d565b61302d6020830189612319565b61303a6040830188612319565b613047606083018761285e565b613054608083018661285e565b61306160a083018561285e565b61306e60c083018461286d565b98975050505050505050565b5f60408201905061308d5f830185612319565b61309a602083018461286d565b9392505050565b5f6040820190506130b45f830185612319565b6130c1602083018461285e565b9392505050565b6130d181612777565b81146130db575f80fd5b50565b5f815190506130ec816130c8565b92915050565b5f602082840312156131075761310661228c565b5b5f613114848285016130de565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061316157607f821691505b6020821081036131745761317361311d565b5b50919050565b5f60608201905061318d5f830186612319565b61319a602083018561285e565b6131a7604083018461285e565b949350505050565b5f6080820190506131c25f83018761286d565b6131cf6020830186612b6c565b6131dc604083018561286d565b6131e9606083018461286d565b95945050505050565b5f60a0820190506132055f83018861286d565b613212602083018761286d565b61321f604083018661286d565b61322c606083018561285e565b6132396080830184612319565b969550505050505056fea2646970667358221220bd0dabbbc2d72a0e86a73812a9d8680d73fc16c1979d81bf5439e90a4879d2d664736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006278b07059f7688a944742e6bd1fbc8e2cd35ae8000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006278a5a4e6ca72c502a307d8752f8648c5095232
-----Decoded View---------------
Arg [0] : bridgeSigner (address): 0x6278b07059F7688A944742e6Bd1fbC8E2cD35Ae8
Arg [1] : tokenAddress (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [2] : initialOwner (address): 0x6278A5a4E6ca72c502a307D8752F8648c5095232
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000006278b07059f7688a944742e6bd1fbc8e2cd35ae8
Arg [1] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [2] : 0000000000000000000000006278a5a4e6ca72c502a307d8752f8648c5095232
Deployed Bytecode Sourcemap
83670:389:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71196:142;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;69578:92;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74503:89;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69233:241;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;69482:88;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67138:42;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74325:65;;;:::i;:::-;;75456:1014;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60707:86;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74398:97;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64080:103;;;:::i;:::-;;66717:235;;;:::i;:::-;;74123:61;;;:::i;:::-;;41604:580;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;63405:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68037:1188;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67798:16;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;;;;;;;;76624:121;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81982:1020;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67850:24;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73440:137;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65805:101;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66105:181;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70911:137;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67821:22;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70669:115;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71196:142;63291:13;:11;:13::i;:::-;71287:5:::1;71264:11;:20;71276:7;71264:20;;;;;;;;;;;;;;;;:28;;;;;;;;;;;;;;;;;;71322:7;71308:22;;;;;;;;;;;;71196:142:::0;:::o;69578:92::-;63291:13;:11;:13::i;:::-;69656:6:::1;69644:9;;:18;;;;;;;;;;;;;;;;;;69578:92:::0;:::o;74503:89::-;74544:7;74571:13;;;;;;;;;;;74564:20;;74503:89;:::o;69233:241::-;63291:13;:11;:13::i;:::-;69416:50:::1;;;;;;;;69421:3;69416:50;;;;;;69426:7;69416:50;;;;;;69435:7;69416:50;;;;;;69444:8;69416:50;;;;;;69454:8;69416:50;;;;;;69464:1;69416:50;;;;::::0;69409:4:::1;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69233:241:::0;;;;;:::o;69482:88::-;63291:13;:11;:13::i;:::-;69556:6:::1;69546:7;;:16;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;69482:88:::0;:::o;67138:42::-;67173:7;67138:42;:::o;74325:65::-;63291:13;:11;:13::i;:::-;74372:10:::1;:8;:10::i;:::-;74325:65::o:0;75456:1014::-;60312:19;:17;:19::i;:::-;75767:4:::1;70239:24;70255:7;70239:15;:24::i;:::-;75788:2:::2;70239:24;70255:7;70239:15;:24::i;:::-;75803:192:::3;75841:4;75860:2;75877:5;75897:10;75922:11;75948:5;75968:16;75803:23;:192::i;:::-;76006:5;;;;;;;;;;;:30;;;76051:4;76078;76098:5;76118:10;76143:11;76169:5;76189:1;76205;76221;76006:227;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;76296:2;76249:182;;76277:4;76249:182;;;76313:5;76333:10;76358:11;76384:5;76404:16;76249:182;;;;;;;;;;:::i;:::-;;;;;;;;76442:20;76456:5;76442:13;:20::i;:::-;70274:1:::2;60342::::1;75456:1014:::0;;;;;;;;;;:::o;60707:86::-;60754:4;60778:7;;;;;;;;;;;60771:14;;60707:86;:::o;74398:97::-;63291:13;:11;:13::i;:::-;74480:7:::1;74464:13;;:23;;;;;;;;;;;;;;;;;;74398:97:::0;:::o;64080:103::-;63291:13;:11;:13::i;:::-;64145:30:::1;64172:1;64145:18;:30::i;:::-;64080:103::o:0;66717:235::-;66770:14;66787:12;:10;:12::i;:::-;66770:29;;66832:6;66814:24;;:14;:12;:14::i;:::-;:24;;;66810:98;;66889:6;66862:34;;;;;;;;;;;:::i;:::-;;;;;;;;66810:98;66918:26;66937:6;66918:18;:26::i;:::-;66759:193;66717:235::o;74123:61::-;63291:13;:11;:13::i;:::-;74168:8:::1;:6;:8::i;:::-;74123:61::o:0;41604:580::-;41707:13;41735:18;41768:21;41804:15;41834:25;41874:12;41901:27;42009:13;:11;:13::i;:::-;42037:16;:14;:16::i;:::-;42068:13;42104:4;42132:1;42124:10;;42163:1;42149:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41956:220;;;;;;;;;;;;;;;;;;;;;41604:580;;;;;;;:::o;63405:87::-;63451:7;63478:6;;;;;;;;;;;63471:13;;63405:87;:::o;68037:1188::-;68095:7;68130:12;68119:23;;;;;;;;:::i;:::-;;:7;;;;;;;;;;;:23;;;;;;;;:::i;:::-;;;68115:64;;68166:1;68159:8;;;;68115:64;68204:12;68193:23;;;;;;;;:::i;:::-;;:7;;;;;;;;;;;:23;;;;;;;;:::i;:::-;;;68189:71;;68240:4;:8;;;;;;;;;;;;68233:15;;;;;;68189:71;68272:11;67173:7;67396:6;:17;;;;:::i;:::-;68366;;:5;:17;68362:141;;;67460:7;68407:52;;68430:4;:13;;;;;;;;;;;;68408:35;;67173:7;67396:6;:17;;;;:::i;:::-;68409;;:5;:17;;;;:::i;:::-;68408:35;;;;:::i;:::-;68407:52;;;;:::i;:::-;68400:59;;;;;:::i;:::-;;;67173:7;67396:6;:17;;;;:::i;:::-;68474;;;;68362:141;67173:7;67336:5;:16;;;;:::i;:::-;68585;;:5;:16;68581:138;;;67460:7;68625:51;;68647:4;:13;;;;;;;;;;;;68626:34;;67173:7;67336:5;:16;;;;:::i;:::-;68627;;:5;:16;;;;:::i;:::-;68626:34;;;;:::i;:::-;68625:51;;;;:::i;:::-;68618:58;;;;;:::i;:::-;;;67173:7;67336:5;:16;;;;:::i;:::-;68691;;;;68581:138;67173:7;67277:5;:16;;;;:::i;:::-;68799;;:5;:16;68795:137;;;67460:7;68839:50;;68861:4;:12;;;;;;;;;;;;68840:33;;67173:7;67277:5;:16;;;;:::i;:::-;68841;;:5;:16;;;;:::i;:::-;68840:33;;;;:::i;:::-;68839:50;;;;:::i;:::-;68832:57;;;;;:::i;:::-;;;67173:7;67277:5;:16;;;;:::i;:::-;68904;;;;68795:137;67460:7;69014:37;;69023:4;:12;;;;;;;;;;;;69015:20;;:5;:20;;;;:::i;:::-;69014:37;;;;:::i;:::-;69007:44;;;;;:::i;:::-;;;69145:4;:8;;;;;;;;;;;;69139:14;;:3;:14;69135:60;;;69174:4;:8;;;;;;;;;;;;69167:15;;;;;;;69135:60;69214:3;69207:10;;;68037:1188;;;;:::o;67798:16::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;76624:121::-;63291:13;:11;:13::i;:::-;76708:29:::1;76725:4;76731:5;76708:16;:29::i;:::-;76624:121:::0;;:::o;81982:1020::-;60312:19;:17;:19::i;:::-;82293:4:::1;70239:24;70255:7;70239:15;:24::i;:::-;82314:2:::2;70239:24;70255:7;70239:15;:24::i;:::-;82329:64:::3;82356:4;82362:5;82369:10;82381:11;82329:26;:64::i;:::-;82404:192;82442:4;82461:2;82478:5;82498:10;82523:11;82549:5;82569:16;82404:23;:192::i;:::-;82607:218;82645:13;;;;;;;;;;;82673:2;82690:5;82710:10;82735:11;82761:5;82781:1;82797;82813;82607:23;:218::i;:::-;82836:30;82856:2;82860:5;82836:19;:30::i;:::-;82877:27;82894:2;82898:5;82877:16;:27::i;:::-;82915:32;82937:2;82941:5;82915:21;:32::i;:::-;82977:2;82963:31;;;82981:5;82988;82963:31;;;;;;;:::i;:::-;;;;;;;;70274:1:::2;60342::::1;81982:1020:::0;;;;;;;;;;:::o;67850:24::-;;;;;;;;;;;;;:::o;73440:137::-;73511:66;73440:137;;;:::o;65805:101::-;65858:7;65885:13;;;;;;;;;;;65878:20;;65805:101;:::o;66105:181::-;63291:13;:11;:13::i;:::-;66211:8:::1;66195:13;;:24;;;;;;;;;;;;;;;;;;66269:8;66235:43;;66260:7;:5;:7::i;:::-;66235:43;;;;;;;;;;;;66105:181:::0;:::o;70911:137::-;63291:13;:11;:13::i;:::-;71000:4:::1;70977:11;:20;70989:7;70977:20;;;;;;;;;;;;;;;;:27;;;;;;;;;;;;;;;;;;71032:7;71020:20;;;;;;;;;;;;70911:137:::0;:::o;67821:22::-;;;;;;;;;;;;;:::o;70669:115::-;70732:4;70756:11;:20;70768:7;70756:20;;;;;;;;;;;;;;;;;;;;;;;;;70749:27;;70669:115;;;:::o;63570:166::-;63641:12;:10;:12::i;:::-;63630:23;;:7;:5;:7::i;:::-;:23;;;63626:103;;63704:12;:10;:12::i;:::-;63677:40;;;;;;;;;;;:::i;:::-;;;;;;;;63626:103;63570:166::o;61608:120::-;60571:16;:14;:16::i;:::-;61677:5:::1;61667:7;;:15;;;;;;;;;;;;;;;;;;61698:22;61707:12;:10;:12::i;:::-;61698:22;;;;;;:::i;:::-;;;;;;;;61608:120::o:0;60866:132::-;60932:8;:6;:8::i;:::-;60928:63;;;60964:15;;;;;;;;;;;;;;60928:63;60866:132::o;70370:169::-;70449:11;:20;70461:7;70449:20;;;;;;;;;;;;;;;;;;;;;;;;;70445:87;;;70512:7;70493:27;;;;;;;;;;;:::i;:::-;;;;;;;;70445:87;70370:169;:::o;79750:662::-;79999:12;80055:4;80061:2;80065:5;80072:10;80084:11;80097:5;80038:65;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;80014:100;;;;;;79999:115;;80125:14;80219:4;80166:58;;;;;;;;:::i;:::-;;;;;;;;;;;;;80142:93;;;;;;80125:110;;80248:14;80265:32;80279:6;80287:9;80265:13;:32::i;:::-;80248:49;;80322:4;80312:14;;:6;:14;;;80308:97;;80380:6;80388:4;80350:43;;;;;;;;;;;;:::i;:::-;;;;;;;;80308:97;79988:424;;;79750:662;;;;;;;:::o;74727:57::-;;:::o;66476:156::-;66566:13;;66559:20;;;;;;;;;;;66590:34;66615:8;66590:24;:34::i;:::-;66476:156;:::o;58486:98::-;58539:7;58566:10;58559:17;;58486:98;:::o;61349:118::-;60312:19;:17;:19::i;:::-;61419:4:::1;61409:7;;:14;;;;;;;;;;;;;;;;;;61439:20;61446:12;:10;:12::i;:::-;61439:20;;;;;;:::i;:::-;;;;;;;;61349:118::o:0;42513:128::-;42559:13;42592:41;42619:13;42592:5;:26;;:41;;;;:::i;:::-;42585:48;;42513:128;:::o;42976:137::-;43025:13;43058:47;43088:16;43058:8;:29;;:47;;;;:::i;:::-;43051:54;;42976:137;:::o;77760:158::-;77862:4;77835:11;:17;77847:4;77835:17;;;;;;;;;;;;;;;:24;77853:5;77835:24;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;77898:4;77882:28;;;77904:5;77882:28;;;;;;:::i;:::-;;;;;;;;77760:158;;:::o;78599:651::-;78801:10;78783:15;:28;78779:202;;;78880:10;78909:11;78939:15;78835:134;;;;;;;;;;;;;:::i;:::-;;;;;;;;78779:202;79013:11;78995:15;:29;78991:203;;;79093:10;79122:11;79152:15;79048:134;;;;;;;;;;;;;:::i;:::-;;;;;;;;78991:203;79204:38;79224:10;79236:5;79204:19;:38::i;:::-;78599:651;;;;:::o;80934:782::-;81208:18;73511:66;81282:35;;81336:4;81359:2;81380:5;81404:10;81433:11;81463:5;81253:230;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;81229:265;;;;;;81208:286;;81507:12;81522:28;81539:10;81522:16;:28::i;:::-;81507:43;;81563:15;81581:28;81595:4;81601:1;81604;81607;81581:13;:28::i;:::-;81563:46;;81635:4;81624:15;;:7;:15;;;81620:89;;81683:7;81692:4;81663:34;;;;;;;;;;;;:::i;:::-;;;;;;;;81620:89;81197:519;;;80934:782;;;;;;;;;:::o;78078:189::-;78165:11;:17;78177:4;78165:17;;;;;;;;;;;;;;;:24;78183:5;78165:24;;;;;;;;;;;;;;;;;;;;;78161:99;;;78236:4;78242:5;78213:35;;;;;;;;;;;;:::i;:::-;;;;;;;;78161:99;78078:189;;:::o;83010:261::-;83089:14;83105:11;83120:26;83136:2;83140:5;83120:15;:26::i;:::-;83088:58;;;;83167:1;83161:3;:7;83157:70;;;83185:5;;;;;;;;;;;:14;;;83200:9;;;;;;;;;;;83211:3;83185:30;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;83157:70;83237:5;;;;;;;;;;;:14;;;83252:2;83256:6;83237:26;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;83077:194;;83010:261;;:::o;61075:130::-;61139:8;:6;:8::i;:::-;61134:64;;61171:15;;;;;;;;;;;;;;61134:64;61075:130::o;46944:259::-;47022:7;47043:17;47062:18;47082:16;47102:27;47113:4;47119:9;47102:10;:27::i;:::-;47042:87;;;;;;47140:28;47152:5;47159:8;47140:11;:28::i;:::-;47186:9;47179:16;;;;;46944:259;;;;:::o;64718:191::-;64792:16;64811:6;;;;;;;;;;;64792:25;;64837:8;64828:6;;:17;;;;;;;;;;;;;;;;;;64892:8;64861:40;;64882:8;64861:40;;;;;;;;;;;;64781:128;64718:191;:::o;11659:273::-;11753:13;9605:66;11812:17;;11802:5;11783:46;11779:146;;11853:15;11862:5;11853:8;:15::i;:::-;11846:22;;;;11779:146;11908:5;11901:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11659:273;;;;;:::o;41370:178::-;41447:7;41474:66;41507:20;:18;:20::i;:::-;41529:10;41474:32;:66::i;:::-;41467:73;;41370:178;;;:::o;50110:264::-;50195:7;50216:17;50235:18;50255:16;50275:25;50286:4;50292:1;50295;50298;50275:10;:25::i;:::-;50215:85;;;;;;50311:28;50323:5;50330:8;50311:11;:28::i;:::-;50357:9;50350:16;;;;;50110:264;;;;;;:::o;77122:484::-;77222:7;77231;77251:11;77265:19;77278:5;77265:12;:19::i;:::-;77251:33;;77305:9;;;;;;;;;;;77299:15;;:2;:15;;;77295:55;;77337:1;77331:7;;77295:55;77387:1;77366:23;;:9;;;;;;;;;;;:23;;;77362:96;;77436:9;;;;;;;;;;;77413:33;;;;;;;;;;;:::i;:::-;;;;;;;;77362:96;77478:5;77472:3;:11;77468:93;;;77534:2;77538:5;77545:3;77507:42;;;;;;;;;;;;;:::i;:::-;;;;;;;;77468:93;77589:3;77581:5;:11;;;;:::i;:::-;77594:3;77573:25;;;;;77122:484;;;;;:::o;45338:783::-;45419:7;45428:12;45442:7;45486:2;45466:9;:16;:22;45462:652;;45505:9;45529;45553:7;45810:4;45799:9;45795:20;45789:27;45784:32;;45860:4;45849:9;45845:20;45839:27;45834:32;;45918:4;45907:9;45903:20;45897:27;45894:1;45889:36;45884:41;;45961:25;45972:4;45978:1;45981;45984;45961:10;:25::i;:::-;45954:32;;;;;;;;;;;45462:652;46035:1;46039:35;46084:9;:16;46076:25;;46019:83;;;;;;45338:783;;;;;;:::o;50512:542::-;50608:20;50599:29;;;;;;;;:::i;:::-;;:5;:29;;;;;;;;:::i;:::-;;;50595:452;50645:7;50595:452;50706:29;50697:38;;;;;;;;:::i;:::-;;:5;:38;;;;;;;;:::i;:::-;;;50693:354;;50759:23;;;;;;;;;;;;;;50693:354;50813:35;50804:44;;;;;;;;:::i;:::-;;:5;:44;;;;;;;;:::i;:::-;;;50800:247;;50908:8;50900:17;;50872:46;;;;;;;;;;;:::i;:::-;;;;;;;;50800:247;50949:30;50940:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;50936:111;;51026:8;51003:32;;;;;;;;;;;:::i;:::-;;;;;;;;50936:111;50512:542;;;:::o;10314:415::-;10373:13;10399:11;10413:16;10424:4;10413:10;:16::i;:::-;10399:30;;10519:17;10550:2;10539:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10519:34;;10644:3;10639;10632:16;10685:4;10678;10673:3;10669:14;10662:28;10718:3;10711:10;;;;10314:415;;;:::o;40271:268::-;40324:7;40365:11;40348:28;;40356:4;40348:28;;;:63;;;;;40397:14;40380:13;:31;40348:63;40344:188;;;40435:22;40428:29;;;;40344:188;40497:23;:21;:23::i;:::-;40490:30;;40271:268;;:::o;36070:410::-;36163:14;36275:4;36269:11;36306:10;36301:3;36294:23;36354:15;36347:4;36342:3;36338:14;36331:39;36407:10;36400:4;36395:3;36391:14;36384:34;36457:4;36452:3;36442:20;36432:30;;36243:230;36070:410;;;;:::o;48415:1556::-;48546:7;48555:12;48569:7;49489:66;49484:1;49476:10;;:79;49472:166;;;49588:1;49592:30;49624:1;49572:54;;;;;;;;49472:166;49735:14;49752:24;49762:4;49768:1;49771;49774;49752:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49735:41;;49809:1;49791:20;;:6;:20;;;49787:115;;49844:1;49848:29;49887:1;49879:10;;49828:62;;;;;;;;;49787:115;49922:6;49930:20;49960:1;49952:10;;49914:49;;;;;;;48415:1556;;;;;;;;;:::o;10806:251::-;10867:7;10887:14;10940:4;10931;10904:33;;:40;10887:57;;10968:2;10959:6;:11;10955:71;;;10994:20;;;;;;;;;;;;;;10955:71;11043:6;11036:13;;;10806:251;;;:::o;40547:181::-;40602:7;38463:95;40661:11;40674:14;40690:13;40713:4;40639:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;40629:91;;;;;;40622:98;;40547:181;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:126;371:7;411:42;404:5;400:54;389:65;;334:126;;;:::o;466:96::-;503:7;532:24;550:5;532:24;:::i;:::-;521:35;;466:96;;;:::o;568:122::-;641:24;659:5;641:24;:::i;:::-;634:5;631:35;621:63;;680:1;677;670:12;621:63;568:122;:::o;696:139::-;742:5;780:6;767:20;758:29;;796:33;823:5;796:33;:::i;:::-;696:139;;;;:::o;841:329::-;900:6;949:2;937:9;928:7;924:23;920:32;917:119;;;955:79;;:::i;:::-;917:119;1075:1;1100:53;1145:7;1136:6;1125:9;1121:22;1100:53;:::i;:::-;1090:63;;1046:117;841:329;;;;:::o;1176:118::-;1263:24;1281:5;1263:24;:::i;:::-;1258:3;1251:37;1176:118;;:::o;1300:222::-;1393:4;1431:2;1420:9;1416:18;1408:26;;1444:71;1512:1;1501:9;1497:17;1488:6;1444:71;:::i;:::-;1300:222;;;;:::o;1528:118::-;1565:7;1605:34;1598:5;1594:46;1583:57;;1528:118;;;:::o;1652:122::-;1725:24;1743:5;1725:24;:::i;:::-;1718:5;1715:35;1705:63;;1764:1;1761;1754:12;1705:63;1652:122;:::o;1780:139::-;1826:5;1864:6;1851:20;1842:29;;1880:33;1907:5;1880:33;:::i;:::-;1780:139;;;;:::o;1925:89::-;1961:7;2001:6;1994:5;1990:18;1979:29;;1925:89;;;:::o;2020:120::-;2092:23;2109:5;2092:23;:::i;:::-;2085:5;2082:34;2072:62;;2130:1;2127;2120:12;2072:62;2020:120;:::o;2146:137::-;2191:5;2229:6;2216:20;2207:29;;2245:32;2271:5;2245:32;:::i;:::-;2146:137;;;;:::o;2289:903::-;2380:6;2388;2396;2404;2412;2461:3;2449:9;2440:7;2436:23;2432:33;2429:120;;;2468:79;;:::i;:::-;2429:120;2588:1;2613:53;2658:7;2649:6;2638:9;2634:22;2613:53;:::i;:::-;2603:63;;2559:117;2715:2;2741:52;2785:7;2776:6;2765:9;2761:22;2741:52;:::i;:::-;2731:62;;2686:117;2842:2;2868:52;2912:7;2903:6;2892:9;2888:22;2868:52;:::i;:::-;2858:62;;2813:117;2969:2;2995:52;3039:7;3030:6;3019:9;3015:22;2995:52;:::i;:::-;2985:62;;2940:117;3096:3;3123:52;3167:7;3158:6;3147:9;3143:22;3123:52;:::i;:::-;3113:62;;3067:118;2289:903;;;;;;;;:::o;3198:111::-;3283:1;3276:5;3273:12;3263:40;;3299:1;3296;3289:12;3263:40;3198:111;:::o;3315:163::-;3373:5;3411:6;3398:20;3389:29;;3427:45;3466:5;3427:45;:::i;:::-;3315:163;;;;:::o;3484:353::-;3555:6;3604:2;3592:9;3583:7;3579:23;3575:32;3572:119;;;3610:79;;:::i;:::-;3572:119;3730:1;3755:65;3812:7;3803:6;3792:9;3788:22;3755:65;:::i;:::-;3745:75;;3701:129;3484:353;;;;:::o;3843:118::-;3930:24;3948:5;3930:24;:::i;:::-;3925:3;3918:37;3843:118;;:::o;3967:222::-;4060:4;4098:2;4087:9;4083:18;4075:26;;4111:71;4179:1;4168:9;4164:17;4155:6;4111:71;:::i;:::-;3967:222;;;;:::o;4195:77::-;4232:7;4261:5;4250:16;;4195:77;;;:::o;4278:122::-;4351:24;4369:5;4351:24;:::i;:::-;4344:5;4341:35;4331:63;;4390:1;4387;4380:12;4331:63;4278:122;:::o;4406:139::-;4452:5;4490:6;4477:20;4468:29;;4506:33;4533:5;4506:33;:::i;:::-;4406:139;;;;:::o;4551:77::-;4588:7;4617:5;4606:16;;4551:77;;;:::o;4634:122::-;4707:24;4725:5;4707:24;:::i;:::-;4700:5;4697:35;4687:63;;4746:1;4743;4736:12;4687:63;4634:122;:::o;4762:139::-;4808:5;4846:6;4833:20;4824:29;;4862:33;4889:5;4862:33;:::i;:::-;4762:139;;;;:::o;4907:86::-;4942:7;4982:4;4975:5;4971:16;4960:27;;4907:86;;;:::o;4999:118::-;5070:22;5086:5;5070:22;:::i;:::-;5063:5;5060:33;5050:61;;5107:1;5104;5097:12;5050:61;4999:118;:::o;5123:135::-;5167:5;5205:6;5192:20;5183:29;;5221:31;5246:5;5221:31;:::i;:::-;5123:135;;;;:::o;5264:117::-;5373:1;5370;5363:12;5387:117;5496:1;5493;5486:12;5510:102;5551:6;5602:2;5598:7;5593:2;5586:5;5582:14;5578:28;5568:38;;5510:102;;;:::o;5618:180::-;5666:77;5663:1;5656:88;5763:4;5760:1;5753:15;5787:4;5784:1;5777:15;5804:281;5887:27;5909:4;5887:27;:::i;:::-;5879:6;5875:40;6017:6;6005:10;6002:22;5981:18;5969:10;5966:34;5963:62;5960:88;;;6028:18;;:::i;:::-;5960:88;6068:10;6064:2;6057:22;5847:238;5804:281;;:::o;6091:129::-;6125:6;6152:20;;:::i;:::-;6142:30;;6181:33;6209:4;6201:6;6181:33;:::i;:::-;6091:129;;;:::o;6226:307::-;6287:4;6377:18;6369:6;6366:30;6363:56;;;6399:18;;:::i;:::-;6363:56;6437:29;6459:6;6437:29;:::i;:::-;6429:37;;6521:4;6515;6511:15;6503:23;;6226:307;;;:::o;6539:146::-;6636:6;6631:3;6626;6613:30;6677:1;6668:6;6663:3;6659:16;6652:27;6539:146;;;:::o;6691:423::-;6768:5;6793:65;6809:48;6850:6;6809:48;:::i;:::-;6793:65;:::i;:::-;6784:74;;6881:6;6874:5;6867:21;6919:4;6912:5;6908:16;6957:3;6948:6;6943:3;6939:16;6936:25;6933:112;;;6964:79;;:::i;:::-;6933:112;7054:54;7101:6;7096:3;7091;7054:54;:::i;:::-;6774:340;6691:423;;;;;:::o;7133:338::-;7188:5;7237:3;7230:4;7222:6;7218:17;7214:27;7204:122;;7245:79;;:::i;:::-;7204:122;7362:6;7349:20;7387:78;7461:3;7453:6;7446:4;7438:6;7434:17;7387:78;:::i;:::-;7378:87;;7194:277;7133:338;;;;:::o;7477:1815::-;7624:6;7632;7640;7648;7656;7664;7672;7680;7688;7696;7745:3;7733:9;7724:7;7720:23;7716:33;7713:120;;;7752:79;;:::i;:::-;7713:120;7872:1;7897:53;7942:7;7933:6;7922:9;7918:22;7897:53;:::i;:::-;7887:63;;7843:117;7999:2;8025:53;8070:7;8061:6;8050:9;8046:22;8025:53;:::i;:::-;8015:63;;7970:118;8127:2;8153:53;8198:7;8189:6;8178:9;8174:22;8153:53;:::i;:::-;8143:63;;8098:118;8255:2;8281:53;8326:7;8317:6;8306:9;8302:22;8281:53;:::i;:::-;8271:63;;8226:118;8383:3;8410:53;8455:7;8446:6;8435:9;8431:22;8410:53;:::i;:::-;8400:63;;8354:119;8512:3;8539:53;8584:7;8575:6;8564:9;8560:22;8539:53;:::i;:::-;8529:63;;8483:119;8641:3;8668:51;8711:7;8702:6;8691:9;8687:22;8668:51;:::i;:::-;8658:61;;8612:117;8768:3;8795:53;8840:7;8831:6;8820:9;8816:22;8795:53;:::i;:::-;8785:63;;8739:119;8897:3;8924:53;8969:7;8960:6;8949:9;8945:22;8924:53;:::i;:::-;8914:63;;8868:119;9054:3;9043:9;9039:19;9026:33;9086:18;9078:6;9075:30;9072:117;;;9108:79;;:::i;:::-;9072:117;9213:62;9267:7;9258:6;9247:9;9243:22;9213:62;:::i;:::-;9203:72;;8997:288;7477:1815;;;;;;;;;;;;;:::o;9298:90::-;9332:7;9375:5;9368:13;9361:21;9350:32;;9298:90;;;:::o;9394:109::-;9475:21;9490:5;9475:21;:::i;:::-;9470:3;9463:34;9394:109;;:::o;9509:210::-;9596:4;9634:2;9623:9;9619:18;9611:26;;9647:65;9709:1;9698:9;9694:17;9685:6;9647:65;:::i;:::-;9509:210;;;;:::o;9725:149::-;9761:7;9801:66;9794:5;9790:78;9779:89;;9725:149;;;:::o;9880:115::-;9965:23;9982:5;9965:23;:::i;:::-;9960:3;9953:36;9880:115;;:::o;10001:99::-;10053:6;10087:5;10081:12;10071:22;;10001:99;;;:::o;10106:169::-;10190:11;10224:6;10219:3;10212:19;10264:4;10259:3;10255:14;10240:29;;10106:169;;;;:::o;10281:246::-;10362:1;10372:113;10386:6;10383:1;10380:13;10372:113;;;10471:1;10466:3;10462:11;10456:18;10452:1;10447:3;10443:11;10436:39;10408:2;10405:1;10401:10;10396:15;;10372:113;;;10519:1;10510:6;10505:3;10501:16;10494:27;10343:184;10281:246;;;:::o;10533:377::-;10621:3;10649:39;10682:5;10649:39;:::i;:::-;10704:71;10768:6;10763:3;10704:71;:::i;:::-;10697:78;;10784:65;10842:6;10837:3;10830:4;10823:5;10819:16;10784:65;:::i;:::-;10874:29;10896:6;10874:29;:::i;:::-;10869:3;10865:39;10858:46;;10625:285;10533:377;;;;:::o;10916:118::-;11003:24;11021:5;11003:24;:::i;:::-;10998:3;10991:37;10916:118;;:::o;11040:::-;11127:24;11145:5;11127:24;:::i;:::-;11122:3;11115:37;11040:118;;:::o;11164:114::-;11231:6;11265:5;11259:12;11249:22;;11164:114;;;:::o;11284:184::-;11383:11;11417:6;11412:3;11405:19;11457:4;11452:3;11448:14;11433:29;;11284:184;;;;:::o;11474:132::-;11541:4;11564:3;11556:11;;11594:4;11589:3;11585:14;11577:22;;11474:132;;;:::o;11612:108::-;11689:24;11707:5;11689:24;:::i;:::-;11684:3;11677:37;11612:108;;:::o;11726:179::-;11795:10;11816:46;11858:3;11850:6;11816:46;:::i;:::-;11894:4;11889:3;11885:14;11871:28;;11726:179;;;;:::o;11911:113::-;11981:4;12013;12008:3;12004:14;11996:22;;11911:113;;;:::o;12060:732::-;12179:3;12208:54;12256:5;12208:54;:::i;:::-;12278:86;12357:6;12352:3;12278:86;:::i;:::-;12271:93;;12388:56;12438:5;12388:56;:::i;:::-;12467:7;12498:1;12483:284;12508:6;12505:1;12502:13;12483:284;;;12584:6;12578:13;12611:63;12670:3;12655:13;12611:63;:::i;:::-;12604:70;;12697:60;12750:6;12697:60;:::i;:::-;12687:70;;12543:224;12530:1;12527;12523:9;12518:14;;12483:284;;;12487:14;12783:3;12776:10;;12184:608;;;12060:732;;;;:::o;12798:1215::-;13147:4;13185:3;13174:9;13170:19;13162:27;;13199:69;13265:1;13254:9;13250:17;13241:6;13199:69;:::i;:::-;13315:9;13309:4;13305:20;13300:2;13289:9;13285:18;13278:48;13343:78;13416:4;13407:6;13343:78;:::i;:::-;13335:86;;13468:9;13462:4;13458:20;13453:2;13442:9;13438:18;13431:48;13496:78;13569:4;13560:6;13496:78;:::i;:::-;13488:86;;13584:72;13652:2;13641:9;13637:18;13628:6;13584:72;:::i;:::-;13666:73;13734:3;13723:9;13719:19;13710:6;13666:73;:::i;:::-;13749;13817:3;13806:9;13802:19;13793:6;13749:73;:::i;:::-;13870:9;13864:4;13860:20;13854:3;13843:9;13839:19;13832:49;13898:108;14001:4;13992:6;13898:108;:::i;:::-;13890:116;;12798:1215;;;;;;;;;;:::o;14019:329::-;14078:6;14127:2;14115:9;14106:7;14102:23;14098:32;14095:119;;;14133:79;;:::i;:::-;14095:119;14253:1;14278:53;14323:7;14314:6;14303:9;14299:22;14278:53;:::i;:::-;14268:63;;14224:117;14019:329;;;;:::o;14354:222::-;14447:4;14485:2;14474:9;14470:18;14462:26;;14498:71;14566:1;14555:9;14551:17;14542:6;14498:71;:::i;:::-;14354:222;;;;:::o;14582:115::-;14667:23;14684:5;14667:23;:::i;:::-;14662:3;14655:36;14582:115;;:::o;14703:101::-;14739:7;14779:18;14772:5;14768:30;14757:41;;14703:101;;;:::o;14810:115::-;14895:23;14912:5;14895:23;:::i;:::-;14890:3;14883:36;14810:115;;:::o;14931:755::-;15154:4;15192:3;15181:9;15177:19;15169:27;;15206:71;15274:1;15263:9;15259:17;15250:6;15206:71;:::i;:::-;15287:70;15353:2;15342:9;15338:18;15329:6;15287:70;:::i;:::-;15367;15433:2;15422:9;15418:18;15409:6;15367:70;:::i;:::-;15447;15513:2;15502:9;15498:18;15489:6;15447:70;:::i;:::-;15527:71;15593:3;15582:9;15578:19;15569:6;15527:71;:::i;:::-;15608;15674:3;15663:9;15659:19;15650:6;15608:71;:::i;:::-;14931:755;;;;;;;;;:::o;15692:474::-;15760:6;15768;15817:2;15805:9;15796:7;15792:23;15788:32;15785:119;;;15823:79;;:::i;:::-;15785:119;15943:1;15968:53;16013:7;16004:6;15993:9;15989:22;15968:53;:::i;:::-;15958:63;;15914:117;16070:2;16096:53;16141:7;16132:6;16121:9;16117:22;16096:53;:::i;:::-;16086:63;;16041:118;15692:474;;;;;:::o;16172:222::-;16265:4;16303:2;16292:9;16288:18;16280:26;;16316:71;16384:1;16373:9;16369:17;16360:6;16316:71;:::i;:::-;16172:222;;;;:::o;16400:180::-;16448:77;16445:1;16438:88;16545:4;16542:1;16535:15;16569:4;16566:1;16559:15;16586:117;16671:1;16664:5;16661:12;16651:46;;16677:18;;:::i;:::-;16651:46;16586:117;:::o;16709:135::-;16758:7;16787:5;16776:16;;16793:45;16832:5;16793:45;:::i;:::-;16709:135;;;:::o;16850:::-;16910:9;16943:36;16973:5;16943:36;:::i;:::-;16930:49;;16850:135;;;:::o;16991:151::-;17088:47;17129:5;17088:47;:::i;:::-;17083:3;17076:60;16991:151;;:::o;17148:242::-;17251:4;17289:2;17278:9;17274:18;17266:26;;17302:81;17380:1;17369:9;17365:17;17356:6;17302:81;:::i;:::-;17148:242;;;;:::o;17396:112::-;17479:22;17495:5;17479:22;:::i;:::-;17474:3;17467:35;17396:112;;:::o;17514:1100::-;17827:4;17865:3;17854:9;17850:19;17842:27;;17879:71;17947:1;17936:9;17932:17;17923:6;17879:71;:::i;:::-;17960:72;18028:2;18017:9;18013:18;18004:6;17960:72;:::i;:::-;18042;18110:2;18099:9;18095:18;18086:6;18042:72;:::i;:::-;18124;18192:2;18181:9;18177:18;18168:6;18124:72;:::i;:::-;18206:73;18274:3;18263:9;18259:19;18250:6;18206:73;:::i;:::-;18289;18357:3;18346:9;18342:19;18333:6;18289:73;:::i;:::-;18372:69;18436:3;18425:9;18421:19;18412:6;18372:69;:::i;:::-;18451:73;18519:3;18508:9;18504:19;18495:6;18451:73;:::i;:::-;18534;18602:3;18591:9;18587:19;18578:6;18534:73;:::i;:::-;17514:1100;;;;;;;;;;;;:::o;18620:98::-;18671:6;18705:5;18699:12;18689:22;;18620:98;;;:::o;18724:168::-;18807:11;18841:6;18836:3;18829:19;18881:4;18876:3;18872:14;18857:29;;18724:168;;;;:::o;18898:373::-;18984:3;19012:38;19044:5;19012:38;:::i;:::-;19066:70;19129:6;19124:3;19066:70;:::i;:::-;19059:77;;19145:65;19203:6;19198:3;19191:4;19184:5;19180:16;19145:65;:::i;:::-;19235:29;19257:6;19235:29;:::i;:::-;19230:3;19226:39;19219:46;;18988:283;18898:373;;;;:::o;19277:751::-;19500:4;19538:3;19527:9;19523:19;19515:27;;19552:71;19620:1;19609:9;19605:17;19596:6;19552:71;:::i;:::-;19633:72;19701:2;19690:9;19686:18;19677:6;19633:72;:::i;:::-;19715;19783:2;19772:9;19768:18;19759:6;19715:72;:::i;:::-;19797;19865:2;19854:9;19850:18;19841:6;19797:72;:::i;:::-;19917:9;19911:4;19907:20;19901:3;19890:9;19886:19;19879:49;19945:76;20016:4;20007:6;19945:76;:::i;:::-;19937:84;;19277:751;;;;;;;;:::o;20034:180::-;20082:77;20079:1;20072:88;20179:4;20176:1;20169:15;20203:4;20200:1;20193:15;20220:279;20260:7;20283:20;20301:1;20283:20;:::i;:::-;20278:25;;20317:20;20335:1;20317:20;:::i;:::-;20312:25;;20372:1;20369;20365:9;20394:30;20412:11;20394:30;:::i;:::-;20383:41;;20456:11;20447:7;20444:24;20434:58;;20472:18;;:::i;:::-;20434:58;20268:231;20220:279;;;;:::o;20505:194::-;20545:4;20565:20;20583:1;20565:20;:::i;:::-;20560:25;;20599:20;20617:1;20599:20;:::i;:::-;20594:25;;20643:1;20640;20636:9;20628:17;;20667:1;20661:4;20658:11;20655:37;;;20672:18;;:::i;:::-;20655:37;20505:194;;;;:::o;20705:410::-;20745:7;20768:20;20786:1;20768:20;:::i;:::-;20763:25;;20802:20;20820:1;20802:20;:::i;:::-;20797:25;;20857:1;20854;20850:9;20879:30;20897:11;20879:30;:::i;:::-;20868:41;;21058:1;21049:7;21045:15;21042:1;21039:22;21019:1;21012:9;20992:83;20969:139;;21088:18;;:::i;:::-;20969:139;20753:362;20705:410;;;;:::o;21121:180::-;21169:77;21166:1;21159:88;21266:4;21263:1;21256:15;21290:4;21287:1;21280:15;21307:185;21347:1;21364:20;21382:1;21364:20;:::i;:::-;21359:25;;21398:20;21416:1;21398:20;:::i;:::-;21393:25;;21437:1;21427:35;;21442:18;;:::i;:::-;21427:35;21484:1;21481;21477:9;21472:14;;21307:185;;;;:::o;21498:191::-;21538:3;21557:20;21575:1;21557:20;:::i;:::-;21552:25;;21591:20;21609:1;21591:20;:::i;:::-;21586:25;;21634:1;21631;21627:9;21620:16;;21655:3;21652:1;21649:10;21646:36;;;21662:18;;:::i;:::-;21646:36;21498:191;;;;:::o;21695:332::-;21816:4;21854:2;21843:9;21839:18;21831:26;;21867:71;21935:1;21924:9;21920:17;21911:6;21867:71;:::i;:::-;21948:72;22016:2;22005:9;22001:18;21992:6;21948:72;:::i;:::-;21695:332;;;;;:::o;22033:94::-;22066:8;22114:5;22110:2;22106:14;22085:35;;22033:94;;;:::o;22133:::-;22172:7;22201:20;22215:5;22201:20;:::i;:::-;22190:31;;22133:94;;;:::o;22233:100::-;22272:7;22301:26;22321:5;22301:26;:::i;:::-;22290:37;;22233:100;;;:::o;22339:157::-;22444:45;22464:24;22482:5;22464:24;:::i;:::-;22444:45;:::i;:::-;22439:3;22432:58;22339:157;;:::o;22502:79::-;22541:7;22570:5;22559:16;;22502:79;;;:::o;22587:157::-;22692:45;22712:24;22730:5;22712:24;:::i;:::-;22692:45;:::i;:::-;22687:3;22680:58;22587:157;;:::o;22750:79::-;22789:7;22818:5;22807:16;;22750:79;;;:::o;22835:157::-;22940:45;22960:24;22978:5;22960:24;:::i;:::-;22940:45;:::i;:::-;22935:3;22928:58;22835:157;;:::o;22998:961::-;23250:3;23265:75;23336:3;23327:6;23265:75;:::i;:::-;23365:2;23360:3;23356:12;23349:19;;23378:75;23449:3;23440:6;23378:75;:::i;:::-;23478:2;23473:3;23469:12;23462:19;;23491:75;23562:3;23553:6;23491:75;:::i;:::-;23591:2;23586:3;23582:12;23575:19;;23604:75;23675:3;23666:6;23604:75;:::i;:::-;23704:2;23699:3;23695:12;23688:19;;23717:75;23788:3;23779:6;23717:75;:::i;:::-;23817:2;23812:3;23808:12;23801:19;;23830:75;23901:3;23892:6;23830:75;:::i;:::-;23930:2;23925:3;23921:12;23914:19;;23950:3;23943:10;;22998:961;;;;;;;;;:::o;23965:148::-;24067:11;24104:3;24089:18;;23965:148;;;;:::o;24119:214::-;24259:66;24255:1;24247:6;24243:14;24236:90;24119:214;:::o;24339:402::-;24499:3;24520:85;24602:2;24597:3;24520:85;:::i;:::-;24513:92;;24614:93;24703:3;24614:93;:::i;:::-;24732:2;24727:3;24723:12;24716:19;;24339:402;;;:::o;24747:522::-;24960:3;24982:148;25126:3;24982:148;:::i;:::-;24975:155;;25140:75;25211:3;25202:6;25140:75;:::i;:::-;25240:2;25235:3;25231:12;25224:19;;25260:3;25253:10;;24747:522;;;;:::o;25275:332::-;25396:4;25434:2;25423:9;25419:18;25411:26;;25447:71;25515:1;25504:9;25500:17;25491:6;25447:71;:::i;:::-;25528:72;25596:2;25585:9;25581:18;25572:6;25528:72;:::i;:::-;25275:332;;;;;:::o;25613:442::-;25762:4;25800:2;25789:9;25785:18;25777:26;;25813:71;25881:1;25870:9;25866:17;25857:6;25813:71;:::i;:::-;25894:72;25962:2;25951:9;25947:18;25938:6;25894:72;:::i;:::-;25976;26044:2;26033:9;26029:18;26020:6;25976:72;:::i;:::-;25613:442;;;;;;:::o;26061:886::-;26322:4;26360:3;26349:9;26345:19;26337:27;;26374:71;26442:1;26431:9;26427:17;26418:6;26374:71;:::i;:::-;26455:72;26523:2;26512:9;26508:18;26499:6;26455:72;:::i;:::-;26537;26605:2;26594:9;26590:18;26581:6;26537:72;:::i;:::-;26619;26687:2;26676:9;26672:18;26663:6;26619:72;:::i;:::-;26701:73;26769:3;26758:9;26754:19;26745:6;26701:73;:::i;:::-;26784;26852:3;26841:9;26837:19;26828:6;26784:73;:::i;:::-;26867;26935:3;26924:9;26920:19;26911:6;26867:73;:::i;:::-;26061:886;;;;;;;;;;:::o;26953:332::-;27074:4;27112:2;27101:9;27097:18;27089:26;;27125:71;27193:1;27182:9;27178:17;27169:6;27125:71;:::i;:::-;27206:72;27274:2;27263:9;27259:18;27250:6;27206:72;:::i;:::-;26953:332;;;;;:::o;27291:::-;27412:4;27450:2;27439:9;27435:18;27427:26;;27463:71;27531:1;27520:9;27516:17;27507:6;27463:71;:::i;:::-;27544:72;27612:2;27601:9;27597:18;27588:6;27544:72;:::i;:::-;27291:332;;;;;:::o;27629:116::-;27699:21;27714:5;27699:21;:::i;:::-;27692:5;27689:32;27679:60;;27735:1;27732;27725:12;27679:60;27629:116;:::o;27751:137::-;27805:5;27836:6;27830:13;27821:22;;27852:30;27876:5;27852:30;:::i;:::-;27751:137;;;;:::o;27894:345::-;27961:6;28010:2;27998:9;27989:7;27985:23;27981:32;27978:119;;;28016:79;;:::i;:::-;27978:119;28136:1;28161:61;28214:7;28205:6;28194:9;28190:22;28161:61;:::i;:::-;28151:71;;28107:125;27894:345;;;;:::o;28245:180::-;28293:77;28290:1;28283:88;28390:4;28387:1;28380:15;28414:4;28411:1;28404:15;28431:320;28475:6;28512:1;28506:4;28502:12;28492:22;;28559:1;28553:4;28549:12;28580:18;28570:81;;28636:4;28628:6;28624:17;28614:27;;28570:81;28698:2;28690:6;28687:14;28667:18;28664:38;28661:84;;28717:18;;:::i;:::-;28661:84;28482:269;28431:320;;;:::o;28757:442::-;28906:4;28944:2;28933:9;28929:18;28921:26;;28957:71;29025:1;29014:9;29010:17;29001:6;28957:71;:::i;:::-;29038:72;29106:2;29095:9;29091:18;29082:6;29038:72;:::i;:::-;29120;29188:2;29177:9;29173:18;29164:6;29120:72;:::i;:::-;28757:442;;;;;;:::o;29205:545::-;29378:4;29416:3;29405:9;29401:19;29393:27;;29430:71;29498:1;29487:9;29483:17;29474:6;29430:71;:::i;:::-;29511:68;29575:2;29564:9;29560:18;29551:6;29511:68;:::i;:::-;29589:72;29657:2;29646:9;29642:18;29633:6;29589:72;:::i;:::-;29671;29739:2;29728:9;29724:18;29715:6;29671:72;:::i;:::-;29205:545;;;;;;;:::o;29756:664::-;29961:4;29999:3;29988:9;29984:19;29976:27;;30013:71;30081:1;30070:9;30066:17;30057:6;30013:71;:::i;:::-;30094:72;30162:2;30151:9;30147:18;30138:6;30094:72;:::i;:::-;30176;30244:2;30233:9;30229:18;30220:6;30176:72;:::i;:::-;30258;30326:2;30315:9;30311:18;30302:6;30258:72;:::i;:::-;30340:73;30408:3;30397:9;30393:19;30384:6;30340:73;:::i;:::-;29756:664;;;;;;;;:::o
Swarm Source
ipfs://bd0dabbbc2d72a0e86a73812a9d8680d73fc16c1979d81bf5439e90a4879d2d6
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $0.999801 | 7,418.6648 | $7,417.19 |
Loading...
Loading
[ 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.