Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Initialize | 18568864 | 233 days ago | IN | 0 ETH | 0.00257263 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
17720267 | 352 days ago | Contract Creation | 0 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
SmartAccount
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.12; import "../interfaces/IStorage.sol"; import "./base/SignatureManager.sol"; import "./base/ModuleManager.sol"; import "./base/OwnerManager.sol"; import "./base/FallbackManager.sol"; import "./base/GuardManager.sol"; import "./common/EtherPaymentFallback.sol"; import "./common/Singleton.sol"; import "./common/SignatureDecoder.sol"; import "./common/SecuredTokenTransfer.sol"; contract SmartAccount is EtherPaymentFallback, Singleton, ModuleManager, OwnerManager, SignatureDecoder, SecuredTokenTransfer, FallbackManager, GuardManager, SignatureManager { address public immutable EntryPoint; address public immutable FallbackHandler; constructor( address _EntryPoint, address _FallbackHandler, string memory _name, string memory _version ) SignatureManager(_name, _version) { EntryPoint = _EntryPoint; FallbackHandler = _FallbackHandler; } modifier onlyEntryPoint() { require(msg.sender == EntryPoint, "Not from entrypoint"); _; } function Initialize(address _owner) external { require(getOwner() == address(0), "account: have set up"); initializeOwners(_owner); initializeFallbackHandler(FallbackHandler); initializeModules(); } function validateUserOp( UserOperation calldata userOp, bytes32 userOpHash, address aggregatorAddress, uint256 missingAccountFunds ) public override onlyEntryPoint returns (uint256 deadline) { deadline = super.validateUserOp( userOp, userOpHash, aggregatorAddress, missingAccountFunds ); } function validateUserOpWithoutSig( UserOperation calldata userOp, bytes32 userOpHash, address aggregatorAddress, uint256 missingAccountFunds ) public override onlyEntryPoint returns (uint256 deadline) { deadline = super.validateUserOpWithoutSig( userOp, userOpHash, aggregatorAddress, missingAccountFunds ); } function execTransactionFromEntrypoint( address to, uint256 value, bytes calldata data ) public onlyEntryPoint { executeWithGuard(to, value, data); } function execTransactionFromEntrypointBatch( ExecuteParams[] calldata _params ) external onlyEntryPoint { executeWithGuardBatch(_params); } function execTransactionFromEntrypointBatchRevertOnFail( ExecuteParams[] calldata _params ) external onlyEntryPoint { execTransactionBatchRevertOnFail(_params); } function execTransactionFromModule( address to, uint256 value, bytes calldata data, Enum.Operation operation ) public override { IStorage(EntryPoint).validateModuleWhitelist(msg.sender); if (operation == Enum.Operation.Call) { ModuleManager.execTransactionFromModule(to, value, data, operation); } else { address originalFallbackHandler = getFallbackHandler(); setFallbackHandler(msg.sender, true); ModuleManager.execTransactionFromModule(to, value, data, operation); setFallbackHandler(originalFallbackHandler, false); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; import "../library/UserOperation.sol"; interface IAccount { /** * Validate user's signature and nonce * the entryPoint will make the call to the recipient only if this validation call returns successfully. * signature failure should be reported by returning SIG_VALIDATION_FAILED (1). * This allows making a "simulation call" without a valid signature * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure. * * @dev Must validate caller is the entryPoint. * Must validate the signature and nonce * @param userOp the operation that is about to be executed. * @param userOpHash hash of the user's request data. can be used as the basis for signature. * @param aggregator the aggregator used to validate the signature. NULL for non-aggregated signature accounts. * @param missingAccountFunds missing funds on the account's deposit in the entrypoint. * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call. * The excess is left as a deposit in the entrypoint, for future calls. * can be withdrawn anytime using "entryPoint.withdrawTo()" * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero. * @return deadline the last block timestamp this operation is valid, or zero if it is valid indefinitely. * signature failure is returned as SIG_VALIDATION_FAILED value (1) * Note that the validation code cannot use block.timestamp (or block.number) directly. */ function validateUserOp( UserOperation calldata userOp, bytes32 userOpHash, address aggregator, uint256 missingAccountFunds ) external returns (uint256 deadline); function validateUserOpWithoutSig( UserOperation calldata userOp, bytes32 userOpHash, address aggregator, uint256 missingAccountFunds ) external returns (uint256 deadline); }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.12; contract ISignatureValidatorConstants { // bytes4(keccak256("isValidSignature(bytes,bytes)") bytes4 internal constant EIP1271_MAGIC_VALUE = 0x20c13b0b; } abstract contract ISignatureValidator is ISignatureValidatorConstants { /** * @dev Should return whether the signature provided is valid for the provided data * @param _data Arbitrary length data signed on the behalf of address(this) * @param _signature Signature byte array associated with _data * * MUST return the bytes4 magic value 0x20c13b0b when function passes. * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5) * MUST allow external calls */ function isValidSignature( bytes memory _data, bytes memory _signature ) public view virtual returns (bytes4); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; interface IStorage { struct bundlerInformation { address bundler; uint256 registeTime; } event UnrestrictedWalletSet(bool allowed); event UnrestrictedBundlerSet(bool allowed); event UnrestrictedModuleSet(bool allowed); event WalletFactoryWhitelistSet(address walletProxyFactory); event BundlerWhitelistSet(address indexed bundler, bool allowed); event ModuleWhitelistSet(address indexed module, bool allowed); function officialBundlerWhiteList( address bundler ) external view returns (bool); function moduleWhiteList(address module) external view returns (bool); function setUnrestrictedWallet(bool allowed) external; function setUnrestrictedBundler(bool allowed) external; function setUnrestrictedModule(bool allowed) external; function setBundlerOfficialWhitelist( address bundler, bool allowed ) external; function setWalletProxyFactoryWhitelist(address walletFactory) external; function setModuleWhitelist(address module, bool allowed) external; function validateModuleWhitelist(address module) external; function validateWalletWhitelist(address sender) external view; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; /* solhint-disable no-inline-assembly */ /** * User Operation struct * @param sender the sender account of this request * @param nonce unique value the sender uses to verify it is not a replay. * @param initCode if set, the account contract will be created by this constructor * @param callData the method call to execute on this account. * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead. * @param maxFeePerGas same as EIP-1559 gas parameter * @param maxPriorityFeePerGas same as EIP-1559 gas parameter * @param paymasterAndData if set, this field hold the paymaster address and "paymaster-specific-data". the paymaster will pay for the transaction instead of the sender * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID. */ struct UserOperation { address sender; uint256 nonce; bytes initCode; bytes callData; uint256 callGasLimit; uint256 verificationGasLimit; uint256 preVerificationGas; uint256 maxFeePerGas; uint256 maxPriorityFeePerGas; bytes paymasterAndData; bytes signature; } library UserOperationLib { function getSender( UserOperation calldata userOp ) internal pure returns (address) { address data; //read sender from userOp, which is first userOp member (saves 800 gas...) assembly { data := calldataload(userOp) } return address(uint160(data)); } //relayer/block builder might submit the TX with higher priorityFee, but the user should not // pay above what he signed for. function gasPrice( UserOperation calldata userOp ) internal view returns (uint256) { unchecked { uint256 maxFeePerGas = userOp.maxFeePerGas; uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas; if (maxFeePerGas == maxPriorityFeePerGas) { //legacy mode (for networks that don't support basefee opcode) return maxFeePerGas; } return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee); } } function pack( UserOperation calldata userOp ) internal pure returns (bytes memory ret) { address sender = getSender(userOp); uint256 nonce = userOp.nonce; bytes32 hashInitCode = calldataKeccak(userOp.initCode); bytes32 hashCallData = calldataKeccak(userOp.callData); uint256 callGasLimit = userOp.callGasLimit; uint256 verificationGasLimit = userOp.verificationGasLimit; uint256 preVerificationGas = userOp.preVerificationGas; uint256 maxFeePerGas = userOp.maxFeePerGas; uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas; bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData); return abi.encode( sender, nonce, hashInitCode, hashCallData, callGasLimit, verificationGasLimit, preVerificationGas, maxFeePerGas, maxPriorityFeePerGas, hashPaymasterAndData ); } function calldataKeccak( bytes calldata data ) internal pure returns (bytes32 ret) { assembly { let mem := mload(0x40) let len := data.length calldatacopy(mem, data.offset, len) ret := keccak256(mem, len) } } function hash( UserOperation calldata userOp ) internal pure returns (bytes32) { return keccak256(pack(userOp)); } function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.12; import "../common/Enum.sol"; /// @title Executor - A contract that can execute transactions contract Executor { struct ExecuteParams { bool allowFailed; address to; uint256 value; bytes data; bytes nestedCalls; // ExecuteParams encoded as bytes } event HandleSuccessExternalCalls(); event HandleFailedExternalCalls(bytes revertReason); function execute( ExecuteParams memory params, Enum.Operation operation, uint256 txGas ) internal returns (bool success) { bytes memory result; if (operation == Enum.Operation.DelegateCall) { // solhint-disable-next-line no-inline-assembly (success, result) = params.to.delegatecall{gas: txGas}(params.data); } else { // solhint-disable-next-line no-inline-assembly (success, result) = payable(params.to).call{ gas: txGas, value: params.value }(params.data); } if (!success) { if (!params.allowFailed) { assembly { revert(add(result, 32), mload(result)) } } } } }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.12; import "../common/SelfAuthorized.sol"; /// @title Fallback Manager - A contract that manages fallback calls made to this contract contract FallbackManager is SelfAuthorized { event ChangedFallbackHandler(address handler); // keccak256("fallback_manager.handler.address") bytes32 internal constant FALLBACK_HANDLER_STORAGE_SLOT = 0x6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5; function getFallbackHandler() public view returns (address fallbackHandler) { bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT; // solhint-disable-next-line no-inline-assembly assembly { let encoded := sload(slot) fallbackHandler := shr(96, encoded) } } /// @dev Allows to add a contract to handle fallback calls. /// Only fallback calls without value and with data will be forwarded. /// This can only be done via a Safe transaction. /// @param handler contract to handle fallbacks calls. function setFallbackHandler(address handler) external authorized { setFallbackHandler(handler, false); emit ChangedFallbackHandler(handler); } function setFallbackHandler(address handler, bool delegate) internal { bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT; // solhint-disable-next-line no-inline-assembly assembly { let encoded := or(shl(96, handler), delegate) sstore(slot, encoded) } } function initializeFallbackHandler(address handler) internal { bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT; // solhint-disable-next-line no-inline-assembly assembly { let encoded := shl(96, handler) sstore(slot, encoded) } } // solhint-disable-next-line payable-fallback,no-complex-fallback fallback() external { assembly { // Load handler and delegate flag from storage let encoded := sload(FALLBACK_HANDLER_STORAGE_SLOT) let handler := shr(96, encoded) let delegate := and(encoded, 1) // Copy calldata to memory calldatacopy(0, 0, calldatasize()) // If delegate flag is set, delegate the call to the handler switch delegate case 0 { mstore(calldatasize(), shl(96, caller())) let success := call( gas(), handler, 0, 0, add(calldatasize(), 20), 0, 0 ) returndatacopy(0, 0, returndatasize()) if iszero(success) { revert(0, returndatasize()) } return(0, returndatasize()) } case 1 { let result := delegatecall( gas(), handler, 0, calldatasize(), 0, 0 ) returndatacopy(0, 0, returndatasize()) switch result case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } } }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.12; import "../common/Enum.sol"; import "../common/SelfAuthorized.sol"; import "./Executor.sol"; interface Guard { function checkTransaction( address to, uint256 value, bytes memory data, Enum.Operation operation ) external; function checkAfterExecution(bool success) external; } /// @title Fallback Manager - A contract that manages fallback calls made to this contract contract GuardManager is SelfAuthorized, Executor { event ChangedGuard(address guard); // keccak256("guard_manager.guard.address") bytes32 internal constant GUARD_STORAGE_SLOT = 0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8; function getGuard() public view returns (address guard) { bytes32 slot = GUARD_STORAGE_SLOT; // solhint-disable-next-line no-inline-assembly assembly { guard := sload(slot) } } function setGuard(address guard) external authorized { bytes32 slot = GUARD_STORAGE_SLOT; // solhint-disable-next-line no-inline-assembly assembly { sstore(slot, guard) } emit ChangedGuard(guard); } // execute from this contract function execTransactionBatch( bytes memory executeParamBytes ) external authorized { executeWithGuardBatch(abi.decode(executeParamBytes, (ExecuteParams[]))); } function execTransactionRevertOnFail( bytes memory executeParamBytes ) external authorized { execTransactionBatchRevertOnFail( abi.decode(executeParamBytes, (ExecuteParams[])) ); } function executeWithGuard( address to, uint256 value, bytes calldata data ) internal { address guard = getGuard(); if (guard != address(0)) { Guard(guard).checkTransaction(to, value, data, Enum.Operation.Call); Guard(guard).checkAfterExecution( execute( ExecuteParams(false, to, value, data, ""), Enum.Operation.Call, gasleft() ) ); } else { execute( ExecuteParams(false, to, value, data, ""), Enum.Operation.Call, gasleft() ); } } function execTransactionBatchRevertOnFail( ExecuteParams[] memory _params ) internal { address guard = getGuard(); uint256 length = _params.length; if (guard == address(0)) { for (uint256 i = 0; i < length; ) { ExecuteParams memory param = _params[i]; execute(param, Enum.Operation.Call, gasleft()); if (param.nestedCalls.length > 0) { try this.execTransactionRevertOnFail(param.nestedCalls) {} catch (bytes memory returnData) { revert(string(returnData)); } } unchecked { ++i; } } } else { for (uint256 i = 0; i < length; ) { ExecuteParams memory param = _params[i]; Guard(guard).checkTransaction( param.to, param.value, param.data, Enum.Operation.Call ); Guard(guard).checkAfterExecution( execute(param, Enum.Operation.Call, gasleft()) ); if (param.nestedCalls.length > 0) { try this.execTransactionRevertOnFail(param.nestedCalls) {} catch (bytes memory returnData) { revert(string(returnData)); } } unchecked { ++i; } } } } function executeWithGuardBatch(ExecuteParams[] memory _params) internal { address guard = getGuard(); uint256 length = _params.length; if (guard == address(0)) { for (uint256 i = 0; i < length; ) { ExecuteParams memory param = _params[i]; bool success = execute(param, Enum.Operation.Call, gasleft()); if (success) { emit HandleSuccessExternalCalls(); } if (param.nestedCalls.length > 0) { try this.execTransactionBatch(param.nestedCalls) {} catch ( bytes memory returnData ) { emit HandleFailedExternalCalls(returnData); } } unchecked { ++i; } } } else { for (uint256 i = 0; i < length; ) { ExecuteParams memory param = _params[i]; Guard(guard).checkTransaction( param.to, param.value, param.data, Enum.Operation.Call ); bool success = execute(param, Enum.Operation.Call, gasleft()); if (success) { emit HandleSuccessExternalCalls(); } Guard(guard).checkAfterExecution(success); if (param.nestedCalls.length > 0) { try this.execTransactionBatch(param.nestedCalls) {} catch ( bytes memory returnData ) { emit HandleFailedExternalCalls(returnData); } } unchecked { ++i; } } } } }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.12; import "../common/Enum.sol"; import "../common/SelfAuthorized.sol"; import "./Executor.sol"; /// @title Module Manager - A contract that manages modules that can execute transactions via this contract contract ModuleManager is SelfAuthorized, Executor { event EnabledModule(address module); event DisabledModule(address module); event ExecutionFromModuleSuccess(address module); event ExecutionFromModuleFailure(address module); address internal constant SENTINEL_MODULES = address(0x1); mapping(address => address) internal modules; function initializeModules() internal { modules[SENTINEL_MODULES] = SENTINEL_MODULES; } function enableModule(address module) public authorized { // Module address cannot be null or sentinel. require(module != address(0) && module != SENTINEL_MODULES, "GS101"); // Module cannot be added twice. require(modules[module] == address(0), "GS102"); modules[module] = modules[SENTINEL_MODULES]; modules[SENTINEL_MODULES] = module; emit EnabledModule(module); } /// @dev Allows to remove a module from the whitelist. /// This can only be done via a Safe transaction. /// @notice Disables the module `module` for the Safe. /// @param prevModule Module that pointed to the module to be removed in the linked list /// @param module Module to be removed. function disableModule( address prevModule, address module ) public authorized { // Validate module address and check that it corresponds to module index. require(module != address(0) && module != SENTINEL_MODULES, "GS101"); require(modules[prevModule] == module, "GS103"); modules[prevModule] = modules[module]; modules[module] = address(0); emit DisabledModule(module); } /// @dev Returns if an module is enabled /// @return True if the module is enabled function isModuleEnabled(address module) public view returns (bool) { return SENTINEL_MODULES != module && modules[module] != address(0); } /// @dev Allows a Module to execute a Safe transaction without any further confirmations. /// @param to Destination address of module transaction. /// @param value Ether value of module transaction. /// @param data Data payload of module transaction. /// @param operation Operation type of module transaction. function execTransactionFromModule( address to, uint256 value, bytes calldata data, Enum.Operation operation ) public virtual { // Only whitelisted modules are allowed. require(modules[msg.sender] != address(0), "GS104"); // Execute transaction without further confirmations. if ( execute( ExecuteParams(false, to, value, data, ""), operation, gasleft() ) ) emit ExecutionFromModuleSuccess(msg.sender); else emit ExecutionFromModuleFailure(msg.sender); } /// @dev Allows a Module to execute a Safe transaction without any further confirmations and return data /// @param to Destination address of module transaction. /// @param value Ether value of module transaction. /// @param data Data payload of module transaction. /// @param operation Operation type of module transaction. function execTransactionFromModuleReturnData( address to, uint256 value, bytes calldata data, Enum.Operation operation ) public returns (bytes memory returnData) { execTransactionFromModule(to, value, data, operation); // solhint-disable-next-line no-inline-assembly assembly { // Load free memory location let ptr := mload(0x40) // We allocate memory for the return data by setting the free memory location to // current free memory location + data size + 32 bytes for data size value mstore(0x40, add(ptr, add(returndatasize(), 0x20))) // Store the size mstore(ptr, returndatasize()) // Store the data returndatacopy(add(ptr, 0x20), 0, returndatasize()) // Point the return data to the correct memory location returnData := ptr } } }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.12; contract OwnerManager { event AAOwnerSet(address owner); address internal owner; uint256 public nonce; modifier onlyOwner() { require(isOwner(msg.sender), "not call by owner"); _; } function initializeOwners(address _owner) internal { owner = _owner; emit AAOwnerSet(_owner); } function isOwner(address _owner) public view returns (bool) { return owner == _owner; } function getOwner() public view returns (address) { return owner; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "../../interfaces/ISignatureValidator.sol"; import "../../interfaces/IAccount.sol"; import "../common/Enum.sol"; import "../common/SignatureDecoder.sol"; import "./OwnerManager.sol"; contract SignatureManager is IAccount, ISignatureValidatorConstants, Enum, OwnerManager, SignatureDecoder { using UserOperationLib for UserOperation; uint256 internal constant NONCE_VALIDATION_FAILED = 2; bytes32 internal immutable HASH_NAME; bytes32 internal immutable HASH_VERSION; bytes32 internal immutable TYPE_HASH; address internal immutable ADDRESS_THIS; bytes32 internal immutable EIP712_ORDER_STRUCT_SCHEMA_HASH; uint256 internal constant SIG_VALIDATION_FAILED = 1; struct SignMessage { address sender; uint256 nonce; bytes initCode; bytes callData; uint256 callGasLimit; uint256 verificationGasLimit; uint256 preVerificationGas; uint256 maxFeePerGas; uint256 maxPriorityFeePerGas; bytes paymasterAndData; address EntryPoint; uint256 sigTime; } /* solhint-enable var-name-mixedcase */ constructor(string memory name, string memory version) { HASH_NAME = keccak256(bytes(name)); HASH_VERSION = keccak256(bytes(version)); TYPE_HASH = keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ); ADDRESS_THIS = address(this); EIP712_ORDER_STRUCT_SCHEMA_HASH = keccak256( abi.encodePacked( "SignMessage(", "address sender,", "uint256 nonce,", "bytes initCode,", "bytes callData,", "uint256 callGasLimit,", "uint256 verificationGasLimit,", "uint256 preVerificationGas,", "uint256 maxFeePerGas,", "uint256 maxPriorityFeePerGas,", "bytes paymasterAndData,", "address EntryPoint,", "uint256 sigTime", ")" ) ); } function getUOPHash( SignatureType sigType, address EntryPoint, UserOperation calldata userOp ) public view returns (bytes32) { return keccak256( abi.encode( sigType == SignatureType.EIP712Type ? EIP712_ORDER_STRUCT_SCHEMA_HASH : bytes32(block.chainid), userOp.getSender(), userOp.nonce, keccak256(userOp.initCode), keccak256(userOp.callData), userOp.callGasLimit, userOp.verificationGasLimit, userOp.preVerificationGas, userOp.maxFeePerGas, userOp.maxPriorityFeePerGas, keccak256(userOp.paymasterAndData), EntryPoint, uint256(bytes32(userOp.signature[1:33])) ) ); } function getUOPSignedHash( SignatureType sigType, address EntryPoint, UserOperation calldata userOp ) public view returns (bytes32) { return sigType == SignatureType.EIP712Type ? ECDSA.toTypedDataHash( keccak256( abi.encode( TYPE_HASH, HASH_NAME, HASH_VERSION, block.chainid, ADDRESS_THIS ) ), keccak256( abi.encode( EIP712_ORDER_STRUCT_SCHEMA_HASH, userOp.getSender(), userOp.nonce, keccak256(userOp.initCode), keccak256(userOp.callData), userOp.callGasLimit, userOp.verificationGasLimit, userOp.preVerificationGas, userOp.maxFeePerGas, userOp.maxPriorityFeePerGas, keccak256(userOp.paymasterAndData), EntryPoint, uint256(bytes32(userOp.signature[1:33])) ) ) ) : ECDSA.toEthSignedMessageHash( keccak256( abi.encode( bytes32(block.chainid), userOp.getSender(), userOp.nonce, keccak256(userOp.initCode), keccak256(userOp.callData), userOp.callGasLimit, userOp.verificationGasLimit, userOp.preVerificationGas, userOp.maxFeePerGas, userOp.maxPriorityFeePerGas, keccak256(userOp.paymasterAndData), EntryPoint, uint256(bytes32(userOp.signature[1:33])) ) ) ); } function validateUserOp( UserOperation calldata userOp, bytes32, address, uint256 missingAccountFunds ) public virtual returns (uint256) { if (missingAccountFunds != 0) { payable(msg.sender).call{ value: missingAccountFunds, gas: type(uint256).max }(""); } unchecked { if (userOp.nonce != nonce++) { return NONCE_VALIDATION_FAILED; } } if ( ECDSA.recover( getUOPSignedHash( SignatureType(uint8(bytes1(userOp.signature[0:1]))), msg.sender, userOp ), userOp.signature[33:] ) != owner ) { return SIG_VALIDATION_FAILED; } else { return uint256(bytes32(userOp.signature[1:33])); } } function validateUserOpWithoutSig( UserOperation calldata userOp, bytes32, address, uint256 missingAccountFunds ) public virtual returns (uint256) { if (missingAccountFunds != 0) { payable(msg.sender).call{ value: missingAccountFunds, gas: type(uint256).max }(""); } unchecked { if (userOp.nonce != nonce++) { return NONCE_VALIDATION_FAILED; } } if ( ECDSA.recover( getUOPSignedHash( SignatureType(uint8(bytes1(userOp.signature[0:1]))), msg.sender, userOp ), userOp.signature[33:] ) != owner ) { return uint256(bytes32(userOp.signature[1:33])); } else { return uint256(bytes32(userOp.signature[1:33])); } } function isValidSignature( bytes32 _hash, bytes calldata _signature ) external view returns (bytes4) { if (isOwner(ECDSA.recover(_hash, _signature))) { return 0x1626ba7e; } else { return 0xffffffff; } } }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.12; /// @title Enum - Collection of enums contract Enum { enum Operation { Call, DelegateCall } enum SignatureType { EIP712Type, EIP191Type } }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.12; /// @title EtherPaymentFallback - A contract that has a fallback to accept ether payments /// @author Richard Meissner - <[email protected]> contract EtherPaymentFallback { event SafeReceived(address indexed sender, uint256 value); /// @dev Fallback function accepts Ether transactions. receive() external payable { emit SafeReceived(msg.sender, msg.value); } }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.12; /// @title SecuredTokenTransfer - Secure token transfer /// @author Richard Meissner - <[email protected]> contract SecuredTokenTransfer { /// @dev Transfers a token and returns if it was a success /// @param token Token that should be transferred /// @param receiver Receiver to whom the token should be transferred /// @param amount The amount of tokens that should be transferred function transferToken( address token, address receiver, uint256 amount ) internal returns (bool transferred) { // 0xa9059cbb - keccack("transfer(address,uint256)") bytes memory data = abi.encodeWithSelector( 0xa9059cbb, receiver, amount ); // solhint-disable-next-line no-inline-assembly assembly { // We write the return value to scratch space. // See https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html#layout-in-memory let success := call( sub(gas(), 10000), token, 0, add(data, 0x20), mload(data), 0, 0x20 ) switch returndatasize() case 0 { transferred := success } case 0x20 { transferred := iszero(or(iszero(success), iszero(mload(0)))) } default { transferred := 0 } } } }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.12; import "../common/SelfAuthorized.sol"; /// @title SelfAuthorized - authorizes current contract to perform actions /// @author Richard Meissner - <[email protected]> contract SelfAuthorized { function requireSelfCall() private view { require(msg.sender == address(this), "GS031"); } modifier authorized() { // This is a function call as it minimized the bytecode size requireSelfCall(); _; } }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.12; /// @title SignatureDecoder - Decodes signatures that a encoded as bytes /// @author Richard Meissner - <[email protected]> contract SignatureDecoder { /// @dev divides bytes signature into `uint8 v, bytes32 r, bytes32 s`. /// @notice Make sure to peform a bounds check for @param pos, to avoid out of bounds access on @param signatures /// @param pos which signature to read. A prior bounds check of this parameter should be performed, to avoid out of bounds access /// @param signatures concatenated rsv signatures function signatureSplit( bytes memory signatures, uint256 pos ) internal pure returns (uint8 v, bytes32 r, bytes32 s) { // The signature format is a compact form of: // {bytes32 r}{bytes32 s}{uint8 v} // Compact means, uint8 is not padded to 32 bytes. // solhint-disable-next-line no-inline-assembly assembly { let signaturePos := mul(0x41, pos) r := mload(add(signatures, add(signaturePos, 0x20))) s := mload(add(signatures, add(signaturePos, 0x40))) // Here we are loading the last 32 bytes, including 31 bytes // of 's'. There is no 'mload8' to do this. // // 'byte' is not working due to the Solidity parser, so lets // use the second best option, 'and' v := and(mload(add(signatures, add(signaturePos, 0x41))), 0xff) } } }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.12; import "./SelfAuthorized.sol"; /// @title Singleton - Base for singleton contracts (should always be first super contract) /// This contract is tightly coupled to our proxy contract contract Singleton is SelfAuthorized { event ImplementUpdated(address indexed implement); address internal singleton; function updateImplement(address implement) external authorized { singleton = implement; emit ImplementUpdated(implement); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_EntryPoint","type":"address"},{"internalType":"address","name":"_FallbackHandler","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_version","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"}],"name":"AAOwnerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"handler","type":"address"}],"name":"ChangedFallbackHandler","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"ChangedGuard","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"module","type":"address"}],"name":"DisabledModule","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"module","type":"address"}],"name":"EnabledModule","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"module","type":"address"}],"name":"ExecutionFromModuleFailure","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"module","type":"address"}],"name":"ExecutionFromModuleSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"revertReason","type":"bytes"}],"name":"HandleFailedExternalCalls","type":"event"},{"anonymous":false,"inputs":[],"name":"HandleSuccessExternalCalls","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implement","type":"address"}],"name":"ImplementUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"SafeReceived","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[],"name":"EntryPoint","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FallbackHandler","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"Initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"prevModule","type":"address"},{"internalType":"address","name":"module","type":"address"}],"name":"disableModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"module","type":"address"}],"name":"enableModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"executeParamBytes","type":"bytes"}],"name":"execTransactionBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"execTransactionFromEntrypoint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bool","name":"allowFailed","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"nestedCalls","type":"bytes"}],"internalType":"struct Executor.ExecuteParams[]","name":"_params","type":"tuple[]"}],"name":"execTransactionFromEntrypointBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bool","name":"allowFailed","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"nestedCalls","type":"bytes"}],"internalType":"struct Executor.ExecuteParams[]","name":"_params","type":"tuple[]"}],"name":"execTransactionFromEntrypointBatchRevertOnFail","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"enum Enum.Operation","name":"operation","type":"uint8"}],"name":"execTransactionFromModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"enum Enum.Operation","name":"operation","type":"uint8"}],"name":"execTransactionFromModuleReturnData","outputs":[{"internalType":"bytes","name":"returnData","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"executeParamBytes","type":"bytes"}],"name":"execTransactionRevertOnFail","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getFallbackHandler","outputs":[{"internalType":"address","name":"fallbackHandler","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGuard","outputs":[{"internalType":"address","name":"guard","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum Enum.SignatureType","name":"sigType","type":"uint8"},{"internalType":"address","name":"EntryPoint","type":"address"},{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"uint256","name":"callGasLimit","type":"uint256"},{"internalType":"uint256","name":"verificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct UserOperation","name":"userOp","type":"tuple"}],"name":"getUOPHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum Enum.SignatureType","name":"sigType","type":"uint8"},{"internalType":"address","name":"EntryPoint","type":"address"},{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"uint256","name":"callGasLimit","type":"uint256"},{"internalType":"uint256","name":"verificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct UserOperation","name":"userOp","type":"tuple"}],"name":"getUOPSignedHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"module","type":"address"}],"name":"isModuleEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"handler","type":"address"}],"name":"setFallbackHandler","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guard","type":"address"}],"name":"setGuard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"implement","type":"address"}],"name":"updateImplement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"uint256","name":"callGasLimit","type":"uint256"},{"internalType":"uint256","name":"verificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct UserOperation","name":"userOp","type":"tuple"},{"internalType":"bytes32","name":"userOpHash","type":"bytes32"},{"internalType":"address","name":"aggregatorAddress","type":"address"},{"internalType":"uint256","name":"missingAccountFunds","type":"uint256"}],"name":"validateUserOp","outputs":[{"internalType":"uint256","name":"deadline","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"uint256","name":"callGasLimit","type":"uint256"},{"internalType":"uint256","name":"verificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct UserOperation","name":"userOp","type":"tuple"},{"internalType":"bytes32","name":"userOpHash","type":"bytes32"},{"internalType":"address","name":"aggregatorAddress","type":"address"},{"internalType":"uint256","name":"missingAccountFunds","type":"uint256"}],"name":"validateUserOpWithoutSig","outputs":[{"internalType":"uint256","name":"deadline","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6101606040523480156200001257600080fd5b50604051620030f0380380620030f0833981016040819052620000359162000341565b815160208084019190912060805281518183012060a0527f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60c0523060e052604051839183916200022591016b0a6d2cedc9acae6e6c2ceca560a31b81526e1859191c995cdcc81cd95b99195c8b608a1b600c8201526d1d5a5b9d0c8d4d881b9bdb98d94b60921b601b8201526e189e5d195cc81a5b9a5d10dbd9194b608a1b60298201526e189e5d195cc818d85b1b11185d184b608a1b60388201527f75696e743235362063616c6c4761734c696d69742c000000000000000000000060478201527f75696e7432353620766572696669636174696f6e4761734c696d69742c000000605c8201527f75696e7432353620707265566572696669636174696f6e4761732c000000000060798201527f75696e74323536206d61784665655065724761732c000000000000000000000060948201527f75696e74323536206d61785072696f726974794665655065724761732c00000060a98201527f6279746573207061796d6173746572416e64446174612c00000000000000000060c68201527f6164647265737320456e747279506f696e742c0000000000000000000000000060dd8201526e75696e743235362073696754696d6560881b60f0820152602960f81b60ff8201526101000190565b60408051601f198184030181529190528051602090910120610100525050506001600160a01b0392831661012052501661014052620003d1565b80516001600160a01b03811681146200027757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620002a457600080fd5b81516001600160401b0380821115620002c157620002c16200027c565b604051601f8301601f19908116603f01168101908282118183101715620002ec57620002ec6200027c565b816040528381526020925086838588010111156200030957600080fd5b600091505b838210156200032d57858201830151818301840152908201906200030e565b600093810190920192909252949350505050565b600080600080608085870312156200035857600080fd5b62000363856200025f565b935062000373602086016200025f565b60408601519093506001600160401b03808211156200039157600080fd5b6200039f8883890162000292565b93506060870151915080821115620003b657600080fd5b50620003c58782880162000292565b91505092959194509250565b60805160a05160c05160e051610100516101205161014051612c8c62000464600039600081816103ae01526107e40152600081816102aa0152818161067501528181610be101528181610f8801528181610fdc0152818161103601526110d7015260008181610a800152610d2901526000610a3c015260006109ba01526000610a08015260006109e00152612c8c6000f3fe6080604052600436106101855760003560e01c80636b34af62116100d1578063affed0e01161008a578063c910638911610064578063c910638914610596578063e009cfde146105b8578063e19a9dd9146105d8578063f08a0323146105f8576101c1565b8063affed0e014610540578063bfceb0e714610556578063bfefafc614610576576101c1565b80636b34af621461047d57806370641a221461049d57806383aa7c9e146104bd578063856dfd99146104dd578063893d20e814610502578063ae93dfbc14610520576101c1565b806336b145351161013e578063468721a711610118578063468721a7146103f05780635229073f14610410578063583d554b1461043d578063610b59251461045d576101c1565b806336b145351461037c5780633b97c0a21461039c5780633e728f84146103d0576101c1565b806306c4bacc146102455780630825d1fc1461026557806314cf557d146102985780631626ba7e146102e45780632d9ad53d1461031d5780632f54bf6e1461034d576101c1565b366101c15760405134815233907f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d9060200160405180910390a2005b3480156101cd57600080fd5b50600080516020612c3783398151915254600181169060601c36600080378180156101fc576001811461022457005b3360601b365260008060143601600080865af13d6000803e8061021e573d6000fd5b503d6000f35b600080366000855af43d6000803e80801561023e573d6000f35b3d6000fd5b005b34801561025157600080fd5b50610243610260366004612279565b610618565b34801561027157600080fd5b506102856102803660046122af565b610668565b6040519081526020015b60405180910390f35b3480156102a457600080fd5b506102cc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161028f565b3480156102f057600080fd5b506103046102ff366004612350565b6106d0565b6040516001600160e01b0319909116815260200161028f565b34801561032957600080fd5b5061033d610338366004612279565b61073a565b604051901515815260200161028f565b34801561035957600080fd5b5061033d610368366004612279565b6002546001600160a01b0390811691161490565b34801561038857600080fd5b50610243610397366004612279565b610775565b3480156103a857600080fd5b506102cc7f000000000000000000000000000000000000000000000000000000000000000081565b3480156103dc57600080fd5b506102856103eb3660046123a8565b61085e565b3480156103fc57600080fd5b5061024361040b366004612409565b610bcc565b34801561041c57600080fd5b5061043061042b366004612409565b610cd7565b60405161028f91906124cc565b34801561044957600080fd5b506102856104583660046123a8565b610d07565b34801561046957600080fd5b50610243610478366004612279565b610e39565b34801561048957600080fd5b506102856104983660046122af565b610f7b565b3480156104a957600080fd5b506102436104b83660046124df565b610fd1565b3480156104c957600080fd5b506102436104d836600461253a565b61102b565b3480156104e957600080fd5b50600080516020612c378339815191525460601c6102cc565b34801561050e57600080fd5b506002546001600160a01b03166102cc565b34801561052c57600080fd5b5061024361053b366004612699565b611089565b34801561054c57600080fd5b5061028560035481565b34801561056257600080fd5b50610243610571366004612699565b6110ad565b34801561058257600080fd5b5061024361059136600461253a565b6110cc565b3480156105a257600080fd5b50600080516020612c17833981519152546102cc565b3480156105c457600080fd5b506102436105d33660046126cd565b611121565b3480156105e457600080fd5b506102436105f3366004612279565b611250565b34801561060457600080fd5b50610243610613366004612279565b6112a3565b6106206112f9565b600080546001600160a01b0319166001600160a01b038316908117825560405190917fef0d964da7bed19ca04a94b064e2d9bf4dd0ec695ffa9b18ed34c756889b330b91a250565b6000336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106bb5760405162461bcd60e51b81526004016106b290612706565b60405180910390fd5b6106c785858585611332565b95945050505050565b60006107156103688585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061148a92505050565b156107285750630b135d3f60e11b610733565b506001600160e01b03195b9392505050565b600060016001600160a01b0383161480159061076f57506001600160a01b038281166000908152600160205260409020541615155b92915050565b60006107896002546001600160a01b031690565b6001600160a01b0316146107d65760405162461bcd60e51b815260206004820152601460248201527306163636f756e743a2068617665207365742075760641b60448201526064016106b2565b6107df816114ae565b6108187f000000000000000000000000000000000000000000000000000000000000000060601b600080516020612c3783398151915255565b61085b6001600081905260208190527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f80546001600160a01b0319169091179055565b50565b60008084600181111561087357610873612733565b146109b4576109af46833560208501356108906040870187612749565b60405161089e92919061278f565b6040519081900390206108b46060880188612749565b6040516108c292919061278f565b604051908190039020608088013560a089013560c08a013560e08b01356101008c01356108f36101208e018e612749565b60405161090192919061278f565b60405180910390208e8e80610140019061091b9190612749565b61092a9160219160019161279f565b610933916127c9565b60405161094f9d9c9b9a999897969594939291906020016127e7565b60408051601f1981840301815282825280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000084830152603c8085019190915282518085039091018152605c909301909152815191012090565b610bc4565b604080517f000000000000000000000000000000000000000000000000000000000000000060208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660a0820152610bc49060c001604051602081830303815290604052805190602001207f0000000000000000000000000000000000000000000000000000000000000000610aa7853590565b6020860135610ab96040880188612749565b604051610ac792919061278f565b604051908190039020610add6060890189612749565b604051610aeb92919061278f565b604051908190039020608089013560a08a013560c08b013560e08c01356101008d0135610b1c6101208f018f612749565b604051610b2a92919061278f565b60405180910390208f8f806101400190610b449190612749565b610b539160219160019161279f565b610b5c916127c9565b604051610b789d9c9b9a999897969594939291906020016127e7565b60408051601f19818403018152828252805160209182012061190160f01b8483015260228401949094526042808401949094528151808403909401845260629092019052815191012090565b949350505050565b604051630930492360e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690630930492390602401600060405180830381600087803b158015610c2d57600080fd5b505af1158015610c41573d6000803e3d6000fd5b5060009250610c4e915050565b816001811115610c6057610c60612733565b03610c7757610c7285858585856114fc565b610cd0565b6000610c92600080516020612c378339815191525460601c90565b3360601b600117600080516020612c37833981519152559050610cb886868686866114fc565b606081901b600080516020612c37833981519152555b505b5050505050565b6060610ce68686868686610bcc565b60405160203d0181016040523d81523d6000602083013e9695505050505050565b600080846001811115610d1c57610d1c612733565b14610d275746610d49565b7f00000000000000000000000000000000000000000000000000000000000000005b82356020840135610d5d6040860186612749565b604051610d6b92919061278f565b604051908190039020610d816060870187612749565b604051610d8f92919061278f565b604051908190039020608087013560a088013560c089013560e08a01356101008b0135610dc06101208d018d612749565b604051610dce92919061278f565b6040519081900390208d610de66101408f018f612749565b610df59160219160019161279f565b610dfe916127c9565b604051610e1a9d9c9b9a999897969594939291906020016127e7565b6040516020818303038152906040528051906020012090509392505050565b610e416112f9565b6001600160a01b03811615801590610e6357506001600160a01b038116600114155b610e975760405162461bcd60e51b8152602060048201526005602482015264475331303160d81b60448201526064016106b2565b6001600160a01b038181166000908152600160205260409020541615610ee75760405162461bcd60e51b815260206004820152600560248201526423a998981960d91b60448201526064016106b2565b600160208181527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f80546001600160a01b03858116600081815260408082208054949095166001600160a01b031994851617909455959095528254168417909155519182527fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844091015b60405180910390a150565b6000336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610fc55760405162461bcd60e51b81526004016106b290612706565b6106c78585858561163e565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146110195760405162461bcd60e51b81526004016106b290612706565b611025848484846116ed565b50505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146110735760405162461bcd60e51b81526004016106b290612706565b6110856110808284612880565b6118e3565b5050565b6110916112f9565b61085b818060200190518101906110a891906129c2565b611c54565b6110b56112f9565b61085b8180602001905181019061108091906129c2565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146111145760405162461bcd60e51b81526004016106b290612706565b6110856110a88284612880565b6111296112f9565b6001600160a01b0381161580159061114b57506001600160a01b038116600114155b61117f5760405162461bcd60e51b8152602060048201526005602482015264475331303160d81b60448201526064016106b2565b6001600160a01b038281166000908152600160205260409020548116908216146111d35760405162461bcd60e51b8152602060048201526005602482015264475331303360d81b60448201526064016106b2565b6001600160a01b038181166000818152600160209081526040808320805488871685528285208054919097166001600160a01b03199182161790965592849052825490941690915591519081527faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427691015b60405180910390a15050565b6112586112f9565b600080516020612c178339815191528181556040516001600160a01b03831681527f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa290602001611244565b6112ab6112f9565b606081901b600080516020612c37833981519152556040516001600160a01b03821681527f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b090602001610f70565b3330146113305760405162461bcd60e51b8152602060048201526005602482015264475330333160d81b60448201526064016106b2565b565b600081156113885760405133906000199084906000818181858888f193505050503d806000811461137f576040519150601f19603f3d011682016040523d82523d6000602084013e611384565b606091505b5050505b60038054600181019091556020860135146113a557506002610bc4565b6002546001600160a01b031661144e6113f86113c5610140890189612749565b6113d49160019160009161279f565b6113dd91612b03565b60f81c60018111156113f1576113f1612733565b338961085e565b611406610140890189612749565b61141491602190829061279f565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061148a92505050565b6001600160a01b03161461146457506001610bc4565b611472610140860186612749565b6114819160219160019161279f565b6106c7916127c9565b60008060006114998585611f04565b915091506114a681611f49565b509392505050565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f9ac05916ca838710da05c0dcb6ae31d326eeb2be76a734f9c9ca713ee2a28af090602001610f70565b336000908152600160205260409020546001600160a01b03166115495760405162461bcd60e51b815260206004820152600560248201526411d4cc4c0d60da1b60448201526064016106b2565b6115c76040518060a00160405280600015158152602001876001600160a01b0316815260200186815260200185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093855250506040805160208181019092529283529092015250825a612093565b15611604576040513381527f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb89060200160405180910390a1610cd0565b6040513381527facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd3759060200160405180910390a15050505050565b600081156116945760405133906000199084906000818181858888f193505050503d806000811461168b576040519150601f19603f3d011682016040523d82523d6000602084013e611690565b606091505b5050505b60038054600181019091556020860135146116b157506002610bc4565b6002546001600160a01b03166116d16113f86113c5610140890189612749565b6001600160a01b03161461146457611472610140860186612749565b6000611705600080516020612c178339815191525490565b90506001600160a01b038116156118635760405163c5caf0cd60e01b81526001600160a01b0382169063c5caf0cd9061174b908890889088908890600090600401612b55565b600060405180830381600087803b15801561176557600080fd5b505af1158015611779573d6000803e3d6000fd5b50505050806001600160a01b03166330adc7da61180c6040518060a00160405280600015158152602001896001600160a01b0316815260200188815260200187878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250938552505060408051602081810190925283815293019290925290505a612093565b6040518263ffffffff1660e01b815260040161182c911515815260200190565b600060405180830381600087803b15801561184657600080fd5b505af115801561185a573d6000803e3d6000fd5b50505050610cd0565b610cce6040518060a00160405280600015158152602001876001600160a01b0316815260200186815260200185858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250938552505060408051602081810190925283815293019290925290505a612093565b60006118fb600080516020612c178339815191525490565b82519091506001600160a01b038216611a4b5760005b8181101561102557600084828151811061192d5761192d612bae565b6020026020010151905060006119458260005a612093565b90508015611977576040517fc097c092d69b13be4f5c2d2dcbf6eae66db75cd0e53233be524a1f410bc0deb790600090a15b60808201515115611a4157608082015160405163bfceb0e760e01b8152309163bfceb0e7916119a991906004016124cc565b600060405180830381600087803b1580156119c357600080fd5b505af19250505080156119d4575060015b611a41573d808015611a02576040519150601f19603f3d011682016040523d82523d6000602084013e611a07565b606091505b507fe968f91e027886fe8437e0c77b159f7b2bf0f88cf967bc8c1ca3c4f5c294057981604051611a3791906124cc565b60405180910390a1505b5050600101611911565b60005b81811015611025576000848281518110611a6a57611a6a612bae565b60200260200101519050836001600160a01b031663c5caf0cd82602001518360400151846060015160006040518563ffffffff1660e01b8152600401611ab39493929190612bc4565b600060405180830381600087803b158015611acd57600080fd5b505af1158015611ae1573d6000803e3d6000fd5b505050506000611af38260005a612093565b90508015611b25576040517fc097c092d69b13be4f5c2d2dcbf6eae66db75cd0e53233be524a1f410bc0deb790600090a15b604051631856e3ed60e11b815281151560048201526001600160a01b038616906330adc7da90602401600060405180830381600087803b158015611b6857600080fd5b505af1158015611b7c573d6000803e3d6000fd5b5050505060808201515115611c4a57608082015160405163bfceb0e760e01b8152309163bfceb0e791611bb291906004016124cc565b600060405180830381600087803b158015611bcc57600080fd5b505af1925050508015611bdd575060015b611c4a573d808015611c0b576040519150601f19603f3d011682016040523d82523d6000602084013e611c10565b606091505b507fe968f91e027886fe8437e0c77b159f7b2bf0f88cf967bc8c1ca3c4f5c294057981604051611c4091906124cc565b60405180910390a1505b5050600101611a4e565b6000611c6c600080516020612c178339815191525490565b82519091506001600160a01b038216611d695760005b81811015611025576000848281518110611c9e57611c9e612bae565b60200260200101519050611cb48160005a612093565b5060808101515115611d60576080810151604051632ba4f7ef60e21b8152309163ae93dfbc91611ce791906004016124cc565b600060405180830381600087803b158015611d0157600080fd5b505af1925050508015611d12575060015b611d60573d808015611d40576040519150601f19603f3d011682016040523d82523d6000602084013e611d45565b606091505b508060405162461bcd60e51b81526004016106b291906124cc565b50600101611c82565b60005b81811015611025576000848281518110611d8857611d88612bae565b60200260200101519050836001600160a01b031663c5caf0cd82602001518360400151846060015160006040518563ffffffff1660e01b8152600401611dd19493929190612bc4565b600060405180830381600087803b158015611deb57600080fd5b505af1158015611dff573d6000803e3d6000fd5b50505050836001600160a01b03166330adc7da611e1e8360005a612093565b6040518263ffffffff1660e01b8152600401611e3e911515815260200190565b600060405180830381600087803b158015611e5857600080fd5b505af1158015611e6c573d6000803e3d6000fd5b5050505060808101515115611efb576080810151604051632ba4f7ef60e21b8152309163ae93dfbc91611ea291906004016124cc565b600060405180830381600087803b158015611ebc57600080fd5b505af1925050508015611ecd575060015b611efb573d808015611d40576040519150601f19603f3d011682016040523d82523d6000602084013e611d45565b50600101611d6c565b6000808251604103611f3a5760208301516040840151606085015160001a611f2e878285856121a0565b94509450505050611f42565b506000905060025b9250929050565b6000816004811115611f5d57611f5d612733565b03611f655750565b6001816004811115611f7957611f79612733565b03611fc65760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016106b2565b6002816004811115611fda57611fda612733565b036120275760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016106b2565b600381600481111561203b5761203b612733565b0361085b5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016106b2565b6000606060018460018111156120ab576120ab612733565b0361211d5784602001516001600160a01b03168386606001516040516120d19190612bfa565b6000604051808303818686f4925050503d806000811461210d576040519150601f19603f3d011682016040523d82523d6000602084013e612112565b606091505b50909250905061218d565b84602001516001600160a01b031683866040015187606001516040516121439190612bfa565b600060405180830381858888f193505050503d8060008114612181576040519150601f19603f3d011682016040523d82523d6000602084013e612186565b606091505b5090925090505b816114a65784516114a657805160208201fd5b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156121d7575060009050600361225b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561222b573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166122545760006001925092505061225b565b9150600090505b94509492505050565b6001600160a01b038116811461085b57600080fd5b60006020828403121561228b57600080fd5b813561073381612264565b600061016082840312156122a957600080fd5b50919050565b600080600080608085870312156122c557600080fd5b84356001600160401b038111156122db57600080fd5b6122e787828801612296565b9450506020850135925060408501356122ff81612264565b9396929550929360600135925050565b60008083601f84011261232157600080fd5b5081356001600160401b0381111561233857600080fd5b602083019150836020828501011115611f4257600080fd5b60008060006040848603121561236557600080fd5b8335925060208401356001600160401b0381111561238257600080fd5b61238e8682870161230f565b9497909650939450505050565b6002811061085b57600080fd5b6000806000606084860312156123bd57600080fd5b83356123c88161239b565b925060208401356123d881612264565b915060408401356001600160401b038111156123f357600080fd5b6123ff86828701612296565b9150509250925092565b60008060008060006080868803121561242157600080fd5b853561242c81612264565b94506020860135935060408601356001600160401b0381111561244e57600080fd5b61245a8882890161230f565b909450925050606086013561246e8161239b565b809150509295509295909350565b60005b8381101561249757818101518382015260200161247f565b50506000910152565b600081518084526124b881602086016020860161247c565b601f01601f19169290920160200192915050565b60208152600061073360208301846124a0565b600080600080606085870312156124f557600080fd5b843561250081612264565b93506020850135925060408501356001600160401b0381111561252257600080fd5b61252e8782880161230f565b95989497509550505050565b6000806020838503121561254d57600080fd5b82356001600160401b038082111561256457600080fd5b818501915085601f83011261257857600080fd5b81358181111561258757600080fd5b8660208260051b850101111561259c57600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b03811182821017156125e6576125e66125ae565b60405290565b604051601f8201601f191681016001600160401b0381118282101715612614576126146125ae565b604052919050565b60006001600160401b03821115612635576126356125ae565b50601f01601f191660200190565b600082601f83011261265457600080fd5b81356126676126628261261c565b6125ec565b81815284602083860101111561267c57600080fd5b816020850160208301376000918101602001919091529392505050565b6000602082840312156126ab57600080fd5b81356001600160401b038111156126c157600080fd5b610bc484828501612643565b600080604083850312156126e057600080fd5b82356126eb81612264565b915060208301356126fb81612264565b809150509250929050565b602080825260139082015272139bdd08199c9bdb48195b9d1c9e5c1bda5b9d606a1b604082015260600190565b634e487b7160e01b600052602160045260246000fd5b6000808335601e1984360301811261276057600080fd5b8301803591506001600160401b0382111561277a57600080fd5b602001915036819003821315611f4257600080fd5b8183823760009101908152919050565b600080858511156127af57600080fd5b838611156127bc57600080fd5b5050820193919092039150565b8035602083101561076f57600019602084900360031b1b1692915050565b9c8d526001600160a01b039b8c1660208e015260408d019a909a5260608c019890985260808b019690965260a08a019490945260c089019290925260e08801526101008701526101208601526101408501529091166101608301526101808201526101a00190565b60006001600160401b03821115612868576128686125ae565b5060051b60200190565b801515811461085b57600080fd5b600061288e6126628461284f565b80848252602080830192508560051b8501368111156128ac57600080fd5b855b818110156129715780356001600160401b03808211156128ce5760008081fd5b818901915060a082360312156128e45760008081fd5b6128ec6125c4565b82356128f781612872565b81528286013561290681612264565b8187015260408381013590820152606080840135838111156129285760008081fd5b61293436828701612643565b8284015250506080808401358381111561294e5760008081fd5b61295a36828701612643565b9183019190915250875250509382019382016128ae565b50919695505050505050565b600082601f83011261298e57600080fd5b815161299c6126628261261c565b8181528460208386010111156129b157600080fd5b610bc482602083016020870161247c565b600060208083850312156129d557600080fd5b82516001600160401b03808211156129ec57600080fd5b818501915085601f830112612a0057600080fd5b8151612a0e6126628261284f565b81815260059190911b83018401908481019088831115612a2d57600080fd5b8585015b83811015612af657805185811115612a4857600080fd5b860160a0818c03601f19011215612a5f5760008081fd5b612a676125c4565b88820151612a7481612872565b8152604082810151612a8581612264565b808b8401525060608084015182840152608091508184015189811115612aab5760008081fd5b612ab98f8d8388010161297d565b82850152505060a083015188811115612ad25760008081fd5b612ae08e8c8387010161297d565b9183019190915250845250918601918601612a31565b5098975050505050505050565b6001600160f81b03198135818116916001851015612b2b5780818660010360031b1b83161692505b505092915050565b60028110612b5157634e487b7160e01b600052602160045260246000fd5b9052565b6001600160a01b0386168152602081018590526080604082018190528101839052828460a0830137600060a08483010152600060a0601f19601f8601168301019050612ba46060830184612b33565b9695505050505050565b634e487b7160e01b600052603260045260246000fd5b60018060a01b0385168152836020820152608060408201526000612beb60808301856124a0565b90506106c76060830184612b33565b60008251612c0c81846020870161247c565b919091019291505056fe4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c86c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5a2646970667358221220d3767a748d99fbca60f841cb91c3a10f2b65f92107c95f93883f0ff200f50cb064736f6c63430008110033000000000000000000000000dc5319815cdaac2d113f7f275bc893ed7d9ca469000000000000000000000000c9b02677ebfa3f4da43ebefc6fc38e11148b664d000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000253410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005312e302e30000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106101855760003560e01c80636b34af62116100d1578063affed0e01161008a578063c910638911610064578063c910638914610596578063e009cfde146105b8578063e19a9dd9146105d8578063f08a0323146105f8576101c1565b8063affed0e014610540578063bfceb0e714610556578063bfefafc614610576576101c1565b80636b34af621461047d57806370641a221461049d57806383aa7c9e146104bd578063856dfd99146104dd578063893d20e814610502578063ae93dfbc14610520576101c1565b806336b145351161013e578063468721a711610118578063468721a7146103f05780635229073f14610410578063583d554b1461043d578063610b59251461045d576101c1565b806336b145351461037c5780633b97c0a21461039c5780633e728f84146103d0576101c1565b806306c4bacc146102455780630825d1fc1461026557806314cf557d146102985780631626ba7e146102e45780632d9ad53d1461031d5780632f54bf6e1461034d576101c1565b366101c15760405134815233907f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d9060200160405180910390a2005b3480156101cd57600080fd5b50600080516020612c3783398151915254600181169060601c36600080378180156101fc576001811461022457005b3360601b365260008060143601600080865af13d6000803e8061021e573d6000fd5b503d6000f35b600080366000855af43d6000803e80801561023e573d6000f35b3d6000fd5b005b34801561025157600080fd5b50610243610260366004612279565b610618565b34801561027157600080fd5b506102856102803660046122af565b610668565b6040519081526020015b60405180910390f35b3480156102a457600080fd5b506102cc7f000000000000000000000000dc5319815cdaac2d113f7f275bc893ed7d9ca46981565b6040516001600160a01b03909116815260200161028f565b3480156102f057600080fd5b506103046102ff366004612350565b6106d0565b6040516001600160e01b0319909116815260200161028f565b34801561032957600080fd5b5061033d610338366004612279565b61073a565b604051901515815260200161028f565b34801561035957600080fd5b5061033d610368366004612279565b6002546001600160a01b0390811691161490565b34801561038857600080fd5b50610243610397366004612279565b610775565b3480156103a857600080fd5b506102cc7f000000000000000000000000c9b02677ebfa3f4da43ebefc6fc38e11148b664d81565b3480156103dc57600080fd5b506102856103eb3660046123a8565b61085e565b3480156103fc57600080fd5b5061024361040b366004612409565b610bcc565b34801561041c57600080fd5b5061043061042b366004612409565b610cd7565b60405161028f91906124cc565b34801561044957600080fd5b506102856104583660046123a8565b610d07565b34801561046957600080fd5b50610243610478366004612279565b610e39565b34801561048957600080fd5b506102856104983660046122af565b610f7b565b3480156104a957600080fd5b506102436104b83660046124df565b610fd1565b3480156104c957600080fd5b506102436104d836600461253a565b61102b565b3480156104e957600080fd5b50600080516020612c378339815191525460601c6102cc565b34801561050e57600080fd5b506002546001600160a01b03166102cc565b34801561052c57600080fd5b5061024361053b366004612699565b611089565b34801561054c57600080fd5b5061028560035481565b34801561056257600080fd5b50610243610571366004612699565b6110ad565b34801561058257600080fd5b5061024361059136600461253a565b6110cc565b3480156105a257600080fd5b50600080516020612c17833981519152546102cc565b3480156105c457600080fd5b506102436105d33660046126cd565b611121565b3480156105e457600080fd5b506102436105f3366004612279565b611250565b34801561060457600080fd5b50610243610613366004612279565b6112a3565b6106206112f9565b600080546001600160a01b0319166001600160a01b038316908117825560405190917fef0d964da7bed19ca04a94b064e2d9bf4dd0ec695ffa9b18ed34c756889b330b91a250565b6000336001600160a01b037f000000000000000000000000dc5319815cdaac2d113f7f275bc893ed7d9ca46916146106bb5760405162461bcd60e51b81526004016106b290612706565b60405180910390fd5b6106c785858585611332565b95945050505050565b60006107156103688585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061148a92505050565b156107285750630b135d3f60e11b610733565b506001600160e01b03195b9392505050565b600060016001600160a01b0383161480159061076f57506001600160a01b038281166000908152600160205260409020541615155b92915050565b60006107896002546001600160a01b031690565b6001600160a01b0316146107d65760405162461bcd60e51b815260206004820152601460248201527306163636f756e743a2068617665207365742075760641b60448201526064016106b2565b6107df816114ae565b6108187f000000000000000000000000c9b02677ebfa3f4da43ebefc6fc38e11148b664d60601b600080516020612c3783398151915255565b61085b6001600081905260208190527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f80546001600160a01b0319169091179055565b50565b60008084600181111561087357610873612733565b146109b4576109af46833560208501356108906040870187612749565b60405161089e92919061278f565b6040519081900390206108b46060880188612749565b6040516108c292919061278f565b604051908190039020608088013560a089013560c08a013560e08b01356101008c01356108f36101208e018e612749565b60405161090192919061278f565b60405180910390208e8e80610140019061091b9190612749565b61092a9160219160019161279f565b610933916127c9565b60405161094f9d9c9b9a999897969594939291906020016127e7565b60408051601f1981840301815282825280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000084830152603c8085019190915282518085039091018152605c909301909152815191012090565b610bc4565b604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0c382912095e7706ed01a66755a50c713445aceaf5a9168954498b03dd381faa918101919091527f06c015bd22b4c69690933c1058878ebdfef31f9aaae40bbe86d8a09fe1b2972c60608201524660808201526001600160a01b037f0000000000000000000000003dbeb76d9d9444d7db9dcf3799e17acd247f8fac1660a0820152610bc49060c001604051602081830303815290604052805190602001207f7a4b0f35f3c0d8dcb98866e1af96ac3a41a9ff5cdbae7b831d0cd27b6faa4899610aa7853590565b6020860135610ab96040880188612749565b604051610ac792919061278f565b604051908190039020610add6060890189612749565b604051610aeb92919061278f565b604051908190039020608089013560a08a013560c08b013560e08c01356101008d0135610b1c6101208f018f612749565b604051610b2a92919061278f565b60405180910390208f8f806101400190610b449190612749565b610b539160219160019161279f565b610b5c916127c9565b604051610b789d9c9b9a999897969594939291906020016127e7565b60408051601f19818403018152828252805160209182012061190160f01b8483015260228401949094526042808401949094528151808403909401845260629092019052815191012090565b949350505050565b604051630930492360e01b81523360048201527f000000000000000000000000dc5319815cdaac2d113f7f275bc893ed7d9ca4696001600160a01b031690630930492390602401600060405180830381600087803b158015610c2d57600080fd5b505af1158015610c41573d6000803e3d6000fd5b5060009250610c4e915050565b816001811115610c6057610c60612733565b03610c7757610c7285858585856114fc565b610cd0565b6000610c92600080516020612c378339815191525460601c90565b3360601b600117600080516020612c37833981519152559050610cb886868686866114fc565b606081901b600080516020612c37833981519152555b505b5050505050565b6060610ce68686868686610bcc565b60405160203d0181016040523d81523d6000602083013e9695505050505050565b600080846001811115610d1c57610d1c612733565b14610d275746610d49565b7f7a4b0f35f3c0d8dcb98866e1af96ac3a41a9ff5cdbae7b831d0cd27b6faa48995b82356020840135610d5d6040860186612749565b604051610d6b92919061278f565b604051908190039020610d816060870187612749565b604051610d8f92919061278f565b604051908190039020608087013560a088013560c089013560e08a01356101008b0135610dc06101208d018d612749565b604051610dce92919061278f565b6040519081900390208d610de66101408f018f612749565b610df59160219160019161279f565b610dfe916127c9565b604051610e1a9d9c9b9a999897969594939291906020016127e7565b6040516020818303038152906040528051906020012090509392505050565b610e416112f9565b6001600160a01b03811615801590610e6357506001600160a01b038116600114155b610e975760405162461bcd60e51b8152602060048201526005602482015264475331303160d81b60448201526064016106b2565b6001600160a01b038181166000908152600160205260409020541615610ee75760405162461bcd60e51b815260206004820152600560248201526423a998981960d91b60448201526064016106b2565b600160208181527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f80546001600160a01b03858116600081815260408082208054949095166001600160a01b031994851617909455959095528254168417909155519182527fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844091015b60405180910390a150565b6000336001600160a01b037f000000000000000000000000dc5319815cdaac2d113f7f275bc893ed7d9ca4691614610fc55760405162461bcd60e51b81526004016106b290612706565b6106c78585858561163e565b336001600160a01b037f000000000000000000000000dc5319815cdaac2d113f7f275bc893ed7d9ca46916146110195760405162461bcd60e51b81526004016106b290612706565b611025848484846116ed565b50505050565b336001600160a01b037f000000000000000000000000dc5319815cdaac2d113f7f275bc893ed7d9ca46916146110735760405162461bcd60e51b81526004016106b290612706565b6110856110808284612880565b6118e3565b5050565b6110916112f9565b61085b818060200190518101906110a891906129c2565b611c54565b6110b56112f9565b61085b8180602001905181019061108091906129c2565b336001600160a01b037f000000000000000000000000dc5319815cdaac2d113f7f275bc893ed7d9ca46916146111145760405162461bcd60e51b81526004016106b290612706565b6110856110a88284612880565b6111296112f9565b6001600160a01b0381161580159061114b57506001600160a01b038116600114155b61117f5760405162461bcd60e51b8152602060048201526005602482015264475331303160d81b60448201526064016106b2565b6001600160a01b038281166000908152600160205260409020548116908216146111d35760405162461bcd60e51b8152602060048201526005602482015264475331303360d81b60448201526064016106b2565b6001600160a01b038181166000818152600160209081526040808320805488871685528285208054919097166001600160a01b03199182161790965592849052825490941690915591519081527faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427691015b60405180910390a15050565b6112586112f9565b600080516020612c178339815191528181556040516001600160a01b03831681527f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa290602001611244565b6112ab6112f9565b606081901b600080516020612c37833981519152556040516001600160a01b03821681527f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b090602001610f70565b3330146113305760405162461bcd60e51b8152602060048201526005602482015264475330333160d81b60448201526064016106b2565b565b600081156113885760405133906000199084906000818181858888f193505050503d806000811461137f576040519150601f19603f3d011682016040523d82523d6000602084013e611384565b606091505b5050505b60038054600181019091556020860135146113a557506002610bc4565b6002546001600160a01b031661144e6113f86113c5610140890189612749565b6113d49160019160009161279f565b6113dd91612b03565b60f81c60018111156113f1576113f1612733565b338961085e565b611406610140890189612749565b61141491602190829061279f565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061148a92505050565b6001600160a01b03161461146457506001610bc4565b611472610140860186612749565b6114819160219160019161279f565b6106c7916127c9565b60008060006114998585611f04565b915091506114a681611f49565b509392505050565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f9ac05916ca838710da05c0dcb6ae31d326eeb2be76a734f9c9ca713ee2a28af090602001610f70565b336000908152600160205260409020546001600160a01b03166115495760405162461bcd60e51b815260206004820152600560248201526411d4cc4c0d60da1b60448201526064016106b2565b6115c76040518060a00160405280600015158152602001876001600160a01b0316815260200186815260200185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093855250506040805160208181019092529283529092015250825a612093565b15611604576040513381527f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb89060200160405180910390a1610cd0565b6040513381527facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd3759060200160405180910390a15050505050565b600081156116945760405133906000199084906000818181858888f193505050503d806000811461168b576040519150601f19603f3d011682016040523d82523d6000602084013e611690565b606091505b5050505b60038054600181019091556020860135146116b157506002610bc4565b6002546001600160a01b03166116d16113f86113c5610140890189612749565b6001600160a01b03161461146457611472610140860186612749565b6000611705600080516020612c178339815191525490565b90506001600160a01b038116156118635760405163c5caf0cd60e01b81526001600160a01b0382169063c5caf0cd9061174b908890889088908890600090600401612b55565b600060405180830381600087803b15801561176557600080fd5b505af1158015611779573d6000803e3d6000fd5b50505050806001600160a01b03166330adc7da61180c6040518060a00160405280600015158152602001896001600160a01b0316815260200188815260200187878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250938552505060408051602081810190925283815293019290925290505a612093565b6040518263ffffffff1660e01b815260040161182c911515815260200190565b600060405180830381600087803b15801561184657600080fd5b505af115801561185a573d6000803e3d6000fd5b50505050610cd0565b610cce6040518060a00160405280600015158152602001876001600160a01b0316815260200186815260200185858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250938552505060408051602081810190925283815293019290925290505a612093565b60006118fb600080516020612c178339815191525490565b82519091506001600160a01b038216611a4b5760005b8181101561102557600084828151811061192d5761192d612bae565b6020026020010151905060006119458260005a612093565b90508015611977576040517fc097c092d69b13be4f5c2d2dcbf6eae66db75cd0e53233be524a1f410bc0deb790600090a15b60808201515115611a4157608082015160405163bfceb0e760e01b8152309163bfceb0e7916119a991906004016124cc565b600060405180830381600087803b1580156119c357600080fd5b505af19250505080156119d4575060015b611a41573d808015611a02576040519150601f19603f3d011682016040523d82523d6000602084013e611a07565b606091505b507fe968f91e027886fe8437e0c77b159f7b2bf0f88cf967bc8c1ca3c4f5c294057981604051611a3791906124cc565b60405180910390a1505b5050600101611911565b60005b81811015611025576000848281518110611a6a57611a6a612bae565b60200260200101519050836001600160a01b031663c5caf0cd82602001518360400151846060015160006040518563ffffffff1660e01b8152600401611ab39493929190612bc4565b600060405180830381600087803b158015611acd57600080fd5b505af1158015611ae1573d6000803e3d6000fd5b505050506000611af38260005a612093565b90508015611b25576040517fc097c092d69b13be4f5c2d2dcbf6eae66db75cd0e53233be524a1f410bc0deb790600090a15b604051631856e3ed60e11b815281151560048201526001600160a01b038616906330adc7da90602401600060405180830381600087803b158015611b6857600080fd5b505af1158015611b7c573d6000803e3d6000fd5b5050505060808201515115611c4a57608082015160405163bfceb0e760e01b8152309163bfceb0e791611bb291906004016124cc565b600060405180830381600087803b158015611bcc57600080fd5b505af1925050508015611bdd575060015b611c4a573d808015611c0b576040519150601f19603f3d011682016040523d82523d6000602084013e611c10565b606091505b507fe968f91e027886fe8437e0c77b159f7b2bf0f88cf967bc8c1ca3c4f5c294057981604051611c4091906124cc565b60405180910390a1505b5050600101611a4e565b6000611c6c600080516020612c178339815191525490565b82519091506001600160a01b038216611d695760005b81811015611025576000848281518110611c9e57611c9e612bae565b60200260200101519050611cb48160005a612093565b5060808101515115611d60576080810151604051632ba4f7ef60e21b8152309163ae93dfbc91611ce791906004016124cc565b600060405180830381600087803b158015611d0157600080fd5b505af1925050508015611d12575060015b611d60573d808015611d40576040519150601f19603f3d011682016040523d82523d6000602084013e611d45565b606091505b508060405162461bcd60e51b81526004016106b291906124cc565b50600101611c82565b60005b81811015611025576000848281518110611d8857611d88612bae565b60200260200101519050836001600160a01b031663c5caf0cd82602001518360400151846060015160006040518563ffffffff1660e01b8152600401611dd19493929190612bc4565b600060405180830381600087803b158015611deb57600080fd5b505af1158015611dff573d6000803e3d6000fd5b50505050836001600160a01b03166330adc7da611e1e8360005a612093565b6040518263ffffffff1660e01b8152600401611e3e911515815260200190565b600060405180830381600087803b158015611e5857600080fd5b505af1158015611e6c573d6000803e3d6000fd5b5050505060808101515115611efb576080810151604051632ba4f7ef60e21b8152309163ae93dfbc91611ea291906004016124cc565b600060405180830381600087803b158015611ebc57600080fd5b505af1925050508015611ecd575060015b611efb573d808015611d40576040519150601f19603f3d011682016040523d82523d6000602084013e611d45565b50600101611d6c565b6000808251604103611f3a5760208301516040840151606085015160001a611f2e878285856121a0565b94509450505050611f42565b506000905060025b9250929050565b6000816004811115611f5d57611f5d612733565b03611f655750565b6001816004811115611f7957611f79612733565b03611fc65760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016106b2565b6002816004811115611fda57611fda612733565b036120275760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016106b2565b600381600481111561203b5761203b612733565b0361085b5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016106b2565b6000606060018460018111156120ab576120ab612733565b0361211d5784602001516001600160a01b03168386606001516040516120d19190612bfa565b6000604051808303818686f4925050503d806000811461210d576040519150601f19603f3d011682016040523d82523d6000602084013e612112565b606091505b50909250905061218d565b84602001516001600160a01b031683866040015187606001516040516121439190612bfa565b600060405180830381858888f193505050503d8060008114612181576040519150601f19603f3d011682016040523d82523d6000602084013e612186565b606091505b5090925090505b816114a65784516114a657805160208201fd5b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156121d7575060009050600361225b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561222b573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166122545760006001925092505061225b565b9150600090505b94509492505050565b6001600160a01b038116811461085b57600080fd5b60006020828403121561228b57600080fd5b813561073381612264565b600061016082840312156122a957600080fd5b50919050565b600080600080608085870312156122c557600080fd5b84356001600160401b038111156122db57600080fd5b6122e787828801612296565b9450506020850135925060408501356122ff81612264565b9396929550929360600135925050565b60008083601f84011261232157600080fd5b5081356001600160401b0381111561233857600080fd5b602083019150836020828501011115611f4257600080fd5b60008060006040848603121561236557600080fd5b8335925060208401356001600160401b0381111561238257600080fd5b61238e8682870161230f565b9497909650939450505050565b6002811061085b57600080fd5b6000806000606084860312156123bd57600080fd5b83356123c88161239b565b925060208401356123d881612264565b915060408401356001600160401b038111156123f357600080fd5b6123ff86828701612296565b9150509250925092565b60008060008060006080868803121561242157600080fd5b853561242c81612264565b94506020860135935060408601356001600160401b0381111561244e57600080fd5b61245a8882890161230f565b909450925050606086013561246e8161239b565b809150509295509295909350565b60005b8381101561249757818101518382015260200161247f565b50506000910152565b600081518084526124b881602086016020860161247c565b601f01601f19169290920160200192915050565b60208152600061073360208301846124a0565b600080600080606085870312156124f557600080fd5b843561250081612264565b93506020850135925060408501356001600160401b0381111561252257600080fd5b61252e8782880161230f565b95989497509550505050565b6000806020838503121561254d57600080fd5b82356001600160401b038082111561256457600080fd5b818501915085601f83011261257857600080fd5b81358181111561258757600080fd5b8660208260051b850101111561259c57600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b03811182821017156125e6576125e66125ae565b60405290565b604051601f8201601f191681016001600160401b0381118282101715612614576126146125ae565b604052919050565b60006001600160401b03821115612635576126356125ae565b50601f01601f191660200190565b600082601f83011261265457600080fd5b81356126676126628261261c565b6125ec565b81815284602083860101111561267c57600080fd5b816020850160208301376000918101602001919091529392505050565b6000602082840312156126ab57600080fd5b81356001600160401b038111156126c157600080fd5b610bc484828501612643565b600080604083850312156126e057600080fd5b82356126eb81612264565b915060208301356126fb81612264565b809150509250929050565b602080825260139082015272139bdd08199c9bdb48195b9d1c9e5c1bda5b9d606a1b604082015260600190565b634e487b7160e01b600052602160045260246000fd5b6000808335601e1984360301811261276057600080fd5b8301803591506001600160401b0382111561277a57600080fd5b602001915036819003821315611f4257600080fd5b8183823760009101908152919050565b600080858511156127af57600080fd5b838611156127bc57600080fd5b5050820193919092039150565b8035602083101561076f57600019602084900360031b1b1692915050565b9c8d526001600160a01b039b8c1660208e015260408d019a909a5260608c019890985260808b019690965260a08a019490945260c089019290925260e08801526101008701526101208601526101408501529091166101608301526101808201526101a00190565b60006001600160401b03821115612868576128686125ae565b5060051b60200190565b801515811461085b57600080fd5b600061288e6126628461284f565b80848252602080830192508560051b8501368111156128ac57600080fd5b855b818110156129715780356001600160401b03808211156128ce5760008081fd5b818901915060a082360312156128e45760008081fd5b6128ec6125c4565b82356128f781612872565b81528286013561290681612264565b8187015260408381013590820152606080840135838111156129285760008081fd5b61293436828701612643565b8284015250506080808401358381111561294e5760008081fd5b61295a36828701612643565b9183019190915250875250509382019382016128ae565b50919695505050505050565b600082601f83011261298e57600080fd5b815161299c6126628261261c565b8181528460208386010111156129b157600080fd5b610bc482602083016020870161247c565b600060208083850312156129d557600080fd5b82516001600160401b03808211156129ec57600080fd5b818501915085601f830112612a0057600080fd5b8151612a0e6126628261284f565b81815260059190911b83018401908481019088831115612a2d57600080fd5b8585015b83811015612af657805185811115612a4857600080fd5b860160a0818c03601f19011215612a5f5760008081fd5b612a676125c4565b88820151612a7481612872565b8152604082810151612a8581612264565b808b8401525060608084015182840152608091508184015189811115612aab5760008081fd5b612ab98f8d8388010161297d565b82850152505060a083015188811115612ad25760008081fd5b612ae08e8c8387010161297d565b9183019190915250845250918601918601612a31565b5098975050505050505050565b6001600160f81b03198135818116916001851015612b2b5780818660010360031b1b83161692505b505092915050565b60028110612b5157634e487b7160e01b600052602160045260246000fd5b9052565b6001600160a01b0386168152602081018590526080604082018190528101839052828460a0830137600060a08483010152600060a0601f19601f8601168301019050612ba46060830184612b33565b9695505050505050565b634e487b7160e01b600052603260045260246000fd5b60018060a01b0385168152836020820152608060408201526000612beb60808301856124a0565b90506106c76060830184612b33565b60008251612c0c81846020870161247c565b919091019291505056fe4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c86c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5a2646970667358221220d3767a748d99fbca60f841cb91c3a10f2b65f92107c95f93883f0ff200f50cb064736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000dc5319815cdaac2d113f7f275bc893ed7d9ca469000000000000000000000000c9b02677ebfa3f4da43ebefc6fc38e11148b664d000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000253410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005312e302e30000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _EntryPoint (address): 0xdc5319815CdAaC2d113f7F275bc893ed7D9cA469
Arg [1] : _FallbackHandler (address): 0xc9b02677ebFa3f4dA43EBEfC6fc38e11148b664D
Arg [2] : _name (string): SA
Arg [3] : _version (string): 1.0.0
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 000000000000000000000000dc5319815cdaac2d113f7f275bc893ed7d9ca469
Arg [1] : 000000000000000000000000c9b02677ebfa3f4da43ebefc6fc38e11148b664d
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [5] : 5341000000000000000000000000000000000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [7] : 312e302e30000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.