Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
20311665 | 194 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
CallPolicy
Compiler Version
v0.8.24+commit.e11b9ed9
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity ^0.8.0; import "kernel/sdk/moduleBase/PolicyBase.sol"; import "kernel/utils/ExecLib.sol"; import {IERC7579Account} from "kernel/interfaces/IERC7579Account.sol"; struct Permission { CallType callType; // calltype can be CALLTYPE_SINGLE/CALLTYPE_DELEGATECALL address target; bytes4 selector; uint256 valueLimit; ParamRule[] rules; } struct ParamRule { ParamCondition condition; uint64 offset; bytes32[] params; } enum ParamCondition { EQUAL, GREATER_THAN, LESS_THAN, GREATER_THAN_OR_EQUAL, LESS_THAN_OR_EQUAL, NOT_EQUAL, ONE_OF } enum Status { NA, Live, Deprecated } contract CallPolicy is PolicyBase { error InvalidCallType(); error InvalidCallData(); error CallViolatesParamRule(); error CallViolatesValueRule(); mapping(address => uint256) public usedIds; mapping(bytes32 id => mapping(address => Status)) public status; mapping(bytes32 id => mapping(bytes32 permissionHash => mapping(address => bytes))) public encodedPermissions; function isInitialized(address wallet) external view override returns (bool) { return usedIds[wallet] > 0; } function checkUserOpPolicy(bytes32 id, PackedUserOperation calldata userOp) external payable override returns (uint256) { require(bytes4(userOp.callData[0:4]) == IERC7579Account.execute.selector); ExecMode mode = ExecMode.wrap(bytes32(userOp.callData[4:36])); (CallType callType, ExecType execType,,) = ExecLib.decode(mode); bytes calldata executionCallData = userOp.callData; // Cache calldata here assembly { executionCallData.offset := add(add(executionCallData.offset, 0x24), calldataload(add(executionCallData.offset, 0x24))) executionCallData.length := calldataload(sub(executionCallData.offset, 0x20)) } if (callType == CALLTYPE_SINGLE) { (address target, uint256 value, bytes calldata callData) = ExecLib.decodeSingle(executionCallData); bool permissionPass = _checkPermission(msg.sender, id, CALLTYPE_SINGLE, target, callData, value); if (!permissionPass) { revert CallViolatesParamRule(); } } else if (callType == CALLTYPE_BATCH) { Execution[] calldata exec = ExecLib.decodeBatch(executionCallData); for (uint256 i = 0; i < exec.length; i++) { bool permissionPass = _checkPermission(msg.sender, id, CALLTYPE_SINGLE, exec[i].target, exec[i].callData, exec[i].value); if (!permissionPass) { revert CallViolatesParamRule(); } } } else if (callType == CALLTYPE_DELEGATECALL) { (address target, uint256 value, bytes calldata callData) = ExecLib.decodeSingle(executionCallData); bool permissionPass = _checkPermission(msg.sender, id, CALLTYPE_DELEGATECALL, target, callData, value); if (!permissionPass) { revert CallViolatesParamRule(); } } else { revert InvalidCallType(); } } function _checkPermission( address wallet, bytes32 id, CallType callType, address target, bytes calldata data, uint256 value ) internal returns (bool) { bytes4 _data = data.length == 0 ? bytes4(0x0) : bytes4(data[0:4]); bytes32 permissionHash = keccak256(abi.encodePacked(callType, target, _data)); bytes memory encodedPermission = encodedPermissions[id][permissionHash][wallet]; // try to find the permission with zero address which means ANY target address // e.g. allow to call `approve` function of `ANY` ERC20 token contracts if (encodedPermission.length == 0) { bytes32 permissionHashWithZeroAddress = keccak256(abi.encodePacked(callType, address(0), _data)); encodedPermission = encodedPermissions[id][permissionHashWithZeroAddress][wallet]; } // if still no permission found, then the call is not allowed if (encodedPermission.length == 0) { revert InvalidCallData(); } (uint256 allowedValue, ParamRule[] memory rules) = abi.decode(encodedPermission, (uint256, ParamRule[])); if (value > allowedValue) { revert CallViolatesValueRule(); } for (uint256 i = 0; i < rules.length; i++) { ParamRule memory rule = rules[i]; bytes32 param = bytes32(data[4 + rule.offset:4 + rule.offset + 32]); // only ONE_OF condition can have multiple params if (rule.condition == ParamCondition.EQUAL && param != rule.params[0]) { return false; } else if (rule.condition == ParamCondition.GREATER_THAN && param <= rule.params[0]) { return false; } else if (rule.condition == ParamCondition.LESS_THAN && param >= rule.params[0]) { return false; } else if (rule.condition == ParamCondition.GREATER_THAN_OR_EQUAL && param < rule.params[0]) { return false; } else if (rule.condition == ParamCondition.LESS_THAN_OR_EQUAL && param > rule.params[0]) { return false; } else if (rule.condition == ParamCondition.NOT_EQUAL && param == rule.params[0]) { return false; } else if (rule.condition == ParamCondition.ONE_OF) { bool oneOfStatus = false; for (uint256 j = 0; j < rule.params.length; j++) { if (param == rule.params[j]) { oneOfStatus = true; break; } } if (!oneOfStatus) { return false; } } } return true; } function checkSignaturePolicy(bytes32 id, address sender, bytes32 hash, bytes calldata sig) external view override returns (uint256) { require(status[id][msg.sender] == Status.Live); return 0; } function _parsePermission(bytes calldata _sig) internal pure returns (Permission[] calldata permissions) { assembly { permissions.offset := add(add(_sig.offset, 32), calldataload(_sig.offset)) permissions.length := calldataload(sub(permissions.offset, 32)) } } function _policyOninstall(bytes32 id, bytes calldata _data) internal override { require(status[id][msg.sender] == Status.NA); Permission[] calldata permissions = _parsePermission(_data); for (uint256 i = 0; i < permissions.length; i++) { // check if the permissionHash is unique bytes32 permissionHash = keccak256(abi.encodePacked(permissions[i].callType, permissions[i].target, permissions[i].selector)); require(encodedPermissions[id][permissionHash][msg.sender].length == 0, "duplicate permissionHash"); // check if the params length is correct for (uint256 j = 0; j < permissions[i].rules.length; j++) { if (permissions[i].rules[j].condition != ParamCondition.ONE_OF) { require(permissions[i].rules[j].params.length == 1, "only OneOf condition can have multiple params"); } } encodedPermissions[id][permissionHash][msg.sender] = abi.encode(permissions[i].valueLimit, permissions[i].rules); } status[id][msg.sender] = Status.Live; usedIds[msg.sender]++; } function _policyOnUninstall(bytes32 id, bytes calldata _data) internal override { require(status[id][msg.sender] == Status.Live); //delete encodedPermissions[id][msg.sender]; status[id][msg.sender] = Status.Deprecated; usedIds[msg.sender]--; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IPolicy} from "../../interfaces/IERC7579Modules.sol"; import {PackedUserOperation} from "../../interfaces/PackedUserOperation.sol"; abstract contract PolicyBase is IPolicy { function onInstall(bytes calldata data) external payable { bytes32 id = bytes32(data[0:32]); bytes calldata _data = data[32:]; _policyOninstall(id, _data); } function onUninstall(bytes calldata data) external payable { bytes32 id = bytes32(data[0:32]); bytes calldata _data = data[32:]; _policyOnUninstall(id, _data); } function isModuleType(uint256 id) external pure returns (bool) { return id == 5; } function isInitialized(address) external view virtual returns (bool); // TODO : not sure if this is the right way to do it function checkUserOpPolicy(bytes32 id, PackedUserOperation calldata userOp) external payable virtual returns (uint256); function checkSignaturePolicy(bytes32 id, address sender, bytes32 hash, bytes calldata sig) external view virtual returns (uint256); function _policyOninstall(bytes32 id, bytes calldata _data) internal virtual; function _policyOnUninstall(bytes32 id, bytes calldata _data) internal virtual; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.23; import {ExecMode, CallType, ExecType, ExecModeSelector, ExecModePayload} from "../types/Types.sol"; import { CALLTYPE_SINGLE, CALLTYPE_BATCH, EXECTYPE_DEFAULT, EXEC_MODE_DEFAULT, EXECTYPE_TRY, CALLTYPE_DELEGATECALL } from "../types/Constants.sol"; import {Execution} from "../types/Structs.sol"; /** * @dev ExecLib is a helper library for execution */ library ExecLib { error ExecutionFailed(); event TryExecuteUnsuccessful(uint256 batchExecutionindex, bytes result); function execute(ExecMode execMode, bytes calldata executionCalldata) internal returns (bytes[] memory returnData) { (CallType callType, ExecType execType,,) = decode(execMode); // check if calltype is batch or single if (callType == CALLTYPE_BATCH) { // destructure executionCallData according to batched exec Execution[] calldata executions = decodeBatch(executionCalldata); // check if execType is revert or try if (execType == EXECTYPE_DEFAULT) returnData = execute(executions); else if (execType == EXECTYPE_TRY) returnData = tryExecute(executions); else revert("Unsupported"); } else if (callType == CALLTYPE_SINGLE) { // destructure executionCallData according to single exec (address target, uint256 value, bytes calldata callData) = decodeSingle(executionCalldata); returnData = new bytes[](1); bool success; // check if execType is revert or try if (execType == EXECTYPE_DEFAULT) { returnData[0] = execute(target, value, callData); } else if (execType == EXECTYPE_TRY) { (success, returnData[0]) = tryExecute(target, value, callData); if (!success) emit TryExecuteUnsuccessful(0, returnData[0]); } else { revert("Unsupported"); } } else if (callType == CALLTYPE_DELEGATECALL) { address delegate = address(bytes20(executionCalldata[0:20])); bytes calldata callData = executionCalldata[20:]; executeDelegatecall(delegate, callData); } else { revert("Unsupported"); } } function execute(Execution[] calldata executions) internal returns (bytes[] memory result) { uint256 length = executions.length; result = new bytes[](length); for (uint256 i; i < length; i++) { Execution calldata _exec = executions[i]; result[i] = execute(_exec.target, _exec.value, _exec.callData); } } function tryExecute(Execution[] calldata executions) internal returns (bytes[] memory result) { uint256 length = executions.length; result = new bytes[](length); for (uint256 i; i < length; i++) { Execution calldata _exec = executions[i]; bool success; (success, result[i]) = tryExecute(_exec.target, _exec.value, _exec.callData); if (!success) emit TryExecuteUnsuccessful(i, result[i]); } } function execute(address target, uint256 value, bytes calldata callData) internal returns (bytes memory result) { /// @solidity memory-safe-assembly assembly { result := mload(0x40) calldatacopy(result, callData.offset, callData.length) if iszero(call(gas(), target, value, result, callData.length, codesize(), 0x00)) { // Bubble up the revert if the call reverts. returndatacopy(result, 0x00, returndatasize()) revert(result, returndatasize()) } mstore(result, returndatasize()) // Store the length. let o := add(result, 0x20) returndatacopy(o, 0x00, returndatasize()) // Copy the returndata. mstore(0x40, add(o, returndatasize())) // Allocate the memory. } } function tryExecute(address target, uint256 value, bytes calldata callData) internal returns (bool success, bytes memory result) { /// @solidity memory-safe-assembly assembly { result := mload(0x40) calldatacopy(result, callData.offset, callData.length) success := call(gas(), target, value, result, callData.length, codesize(), 0x00) mstore(result, returndatasize()) // Store the length. let o := add(result, 0x20) returndatacopy(o, 0x00, returndatasize()) // Copy the returndata. mstore(0x40, add(o, returndatasize())) // Allocate the memory. } } /// @dev Execute a delegatecall with `delegate` on this account. function executeDelegatecall(address delegate, bytes calldata callData) internal returns (bool success, bytes memory result) { /// @solidity memory-safe-assembly assembly { result := mload(0x40) calldatacopy(result, callData.offset, callData.length) // Forwards the `data` to `delegate` via delegatecall. success := delegatecall(gas(), delegate, result, callData.length, codesize(), 0x00) mstore(result, returndatasize()) // Store the length. let o := add(result, 0x20) returndatacopy(o, 0x00, returndatasize()) // Copy the returndata. mstore(0x40, add(o, returndatasize())) // Allocate the memory. } } function decode(ExecMode mode) internal pure returns (CallType _calltype, ExecType _execType, ExecModeSelector _modeSelector, ExecModePayload _modePayload) { assembly { _calltype := mode _execType := shl(8, mode) _modeSelector := shl(48, mode) _modePayload := shl(80, mode) } } function encode(CallType callType, ExecType execType, ExecModeSelector mode, ExecModePayload payload) internal pure returns (ExecMode) { return ExecMode.wrap( bytes32(abi.encodePacked(callType, execType, bytes4(0), ExecModeSelector.unwrap(mode), payload)) ); } function encodeSimpleBatch() internal pure returns (ExecMode mode) { mode = encode(CALLTYPE_BATCH, EXECTYPE_DEFAULT, EXEC_MODE_DEFAULT, ExecModePayload.wrap(0x00)); } function encodeSimpleSingle() internal pure returns (ExecMode mode) { mode = encode(CALLTYPE_SINGLE, EXECTYPE_DEFAULT, EXEC_MODE_DEFAULT, ExecModePayload.wrap(0x00)); } function getCallType(ExecMode mode) internal pure returns (CallType calltype) { assembly { calltype := mode } } function decodeBatch(bytes calldata callData) internal pure returns (Execution[] calldata executionBatch) { /* * Batch Call Calldata Layout * Offset (in bytes) | Length (in bytes) | Contents * 0x0 | 0x4 | bytes4 function selector * 0x4 | - | abi.encode(IERC7579Execution.Execution[]) */ // solhint-disable-next-line no-inline-assembly assembly ("memory-safe") { let dataPointer := add(callData.offset, calldataload(callData.offset)) // Extract the ERC7579 Executions executionBatch.offset := add(dataPointer, 32) executionBatch.length := calldataload(dataPointer) } } function encodeBatch(Execution[] memory executions) internal pure returns (bytes memory callData) { callData = abi.encode(executions); } function decodeSingle(bytes calldata executionCalldata) internal pure returns (address target, uint256 value, bytes calldata callData) { target = address(bytes20(executionCalldata[0:20])); value = uint256(bytes32(executionCalldata[20:52])); callData = executionCalldata[52:]; } function encodeSingle(address target, uint256 value, bytes memory callData) internal pure returns (bytes memory userOpCalldata) { userOpCalldata = abi.encodePacked(target, value, callData); } function doFallback2771Static(address fallbackHandler) internal view returns (bool success, bytes memory result) { assembly { function allocate(length) -> pos { pos := mload(0x40) mstore(0x40, add(pos, length)) } let calldataPtr := allocate(calldatasize()) calldatacopy(calldataPtr, 0, calldatasize()) // The msg.sender address is shifted to the left by 12 bytes to remove the padding // Then the address without padding is stored right after the calldata let senderPtr := allocate(20) mstore(senderPtr, shl(96, caller())) // Add 20 bytes for the address appended add the end success := staticcall(gas(), fallbackHandler, calldataPtr, add(calldatasize(), 20), 0, 0) result := mload(0x40) mstore(result, returndatasize()) // Store the length. let o := add(result, 0x20) returndatacopy(o, 0x00, returndatasize()) // Copy the returndata. mstore(0x40, add(o, returndatasize())) // Allocate the memory. } } function doFallback2771Call(address target) internal returns (bool success, bytes memory result) { assembly { function allocate(length) -> pos { pos := mload(0x40) mstore(0x40, add(pos, length)) } let calldataPtr := allocate(calldatasize()) calldatacopy(calldataPtr, 0, calldatasize()) // The msg.sender address is shifted to the left by 12 bytes to remove the padding // Then the address without padding is stored right after the calldata let senderPtr := allocate(20) mstore(senderPtr, shl(96, caller())) // Add 20 bytes for the address appended add the end success := call(gas(), target, 0, calldataPtr, add(calldatasize(), 20), 0, 0) result := mload(0x40) mstore(result, returndatasize()) // Store the length. let o := add(result, 0x20) returndatacopy(o, 0x00, returndatasize()) // Copy the returndata. mstore(0x40, add(o, returndatasize())) // Allocate the memory. } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; import {CallType, ExecType, ExecMode} from "../utils/ExecLib.sol"; import {PackedUserOperation} from "./PackedUserOperation.sol"; struct Execution { address target; uint256 value; bytes callData; } interface IERC7579Account { event ModuleInstalled(uint256 moduleTypeId, address module); event ModuleUninstalled(uint256 moduleTypeId, address module); /** * @dev Executes a transaction on behalf of the account. * This function is intended to be called by ERC-4337 EntryPoint.sol * @dev Ensure adequate authorization control: i.e. onlyEntryPointOrSelf * * @dev MSA MUST implement this function signature. * If a mode is requested that is not supported by the Account, it MUST revert * @param mode The encoded execution mode of the transaction. See ModeLib.sol for details * @param executionCalldata The encoded execution call data */ function execute(ExecMode mode, bytes calldata executionCalldata) external payable; /** * @dev Executes a transaction on behalf of the account. * This function is intended to be called by Executor Modules * @dev Ensure adequate authorization control: i.e. onlyExecutorModule * * @dev MSA MUST implement this function signature. * If a mode is requested that is not supported by the Account, it MUST revert * @param mode The encoded execution mode of the transaction. See ModeLib.sol for details * @param executionCalldata The encoded execution call data */ function executeFromExecutor(ExecMode mode, bytes calldata executionCalldata) external payable returns (bytes[] memory returnData); /** * @dev ERC-1271 isValidSignature * This function is intended to be used to validate a smart account signature * and may forward the call to a validator module * * @param hash The hash of the data that is signed * @param data The data that is signed */ function isValidSignature(bytes32 hash, bytes calldata data) external view returns (bytes4); /** * @dev installs a Module of a certain type on the smart account * @dev Implement Authorization control of your chosing * @param moduleTypeId the module type ID according the ERC-7579 spec * @param module the module address * @param initData arbitrary data that may be required on the module during `onInstall` * initialization. */ function installModule(uint256 moduleTypeId, address module, bytes calldata initData) external payable; /** * @dev uninstalls a Module of a certain type on the smart account * @dev Implement Authorization control of your chosing * @param moduleTypeId the module type ID according the ERC-7579 spec * @param module the module address * @param deInitData arbitrary data that may be required on the module during `onUninstall` * de-initialization. */ function uninstallModule(uint256 moduleTypeId, address module, bytes calldata deInitData) external payable; /** * Function to check if the account supports a certain CallType or ExecType (see ModeLib.sol) * @param encodedMode the encoded mode */ function supportsExecutionMode(ExecMode encodedMode) external view returns (bool); /** * Function to check if the account supports installation of a certain module type Id * @param moduleTypeId the module type ID according the ERC-7579 spec */ function supportsModule(uint256 moduleTypeId) external view returns (bool); /** * Function to check if the account has a certain module installed * @param moduleTypeId the module type ID according the ERC-7579 spec * Note: keep in mind that some contracts can be multiple module types at the same time. It * thus may be necessary to query multiple module types * @param module the module address * @param additionalContext additional context data that the smart account may interpret to * identifiy conditions under which the module is installed. * usually this is not necessary, but for some special hooks that * are stored in mappings, this param might be needed */ function isModuleInstalled(uint256 moduleTypeId, address module, bytes calldata additionalContext) external view returns (bool); /** * @dev Returns the account id of the smart account * @return accountImplementationId the account id of the smart account * the accountId should be structured like so: * "vendorname.accountname.semver" */ function accountId() external view returns (string memory accountImplementationId); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; import {PackedUserOperation} from "./PackedUserOperation.sol"; interface IModule { error AlreadyInitialized(address smartAccount); error NotInitialized(address smartAccount); /** * @dev This function is called by the smart account during installation of the module * @param data arbitrary data that may be required on the module during `onInstall` * initialization * * MUST revert on error (i.e. if module is already enabled) */ function onInstall(bytes calldata data) external payable; /** * @dev This function is called by the smart account during uninstallation of the module * @param data arbitrary data that may be required on the module during `onUninstall` * de-initialization * * MUST revert on error */ function onUninstall(bytes calldata data) external payable; /** * @dev Returns boolean value if module is a certain type * @param moduleTypeId the module type ID according the ERC-7579 spec * * MUST return true if the module is of the given type and false otherwise */ function isModuleType(uint256 moduleTypeId) external view returns (bool); /** * @dev Returns if the module was already initialized for a provided smartaccount */ function isInitialized(address smartAccount) external view returns (bool); } interface IValidator is IModule { error InvalidTargetAddress(address target); /** * @dev Validates a transaction on behalf of the account. * This function is intended to be called by the MSA during the ERC-4337 validaton phase * Note: solely relying on bytes32 hash and signature is not suffcient for some * validation implementations (i.e. SessionKeys often need access to userOp.calldata) * @param userOp The user operation to be validated. The userOp MUST NOT contain any metadata. * The MSA MUST clean up the userOp before sending it to the validator. * @param userOpHash The hash of the user operation to be validated * @return return value according to ERC-4337 */ function validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash) external payable returns (uint256); /** * Validator can be used for ERC-1271 validation */ function isValidSignatureWithSender(address sender, bytes32 hash, bytes calldata data) external view returns (bytes4); } interface IExecutor is IModule {} interface IHook is IModule { /** * @dev Called by the smart account before execution * @param msgSender the address that called the smart account * @param value the value that was sent to the smart account * @param msgData the data that was sent to the smart account * * MAY return arbitrary data in the `hookData` return value */ function preCheck(address msgSender, uint256 value, bytes calldata msgData) external payable returns (bytes memory hookData); /** * @dev Called by the smart account after execution * @param hookData the data that was returned by the `preCheck` function * @param executionSuccess whether the execution(s) was (were) successful * @param executionReturn the return/revert data of the execution(s) * * MAY validate the `hookData` to validate transaction context of the `preCheck` function */ function postCheck(bytes calldata hookData, bool executionSuccess, bytes calldata executionReturn) external payable; } interface IFallback is IModule {} interface IPolicy is IModule { function checkUserOpPolicy(bytes32 id, PackedUserOperation calldata userOp) external payable returns (uint256); function checkSignaturePolicy(bytes32 id, address sender, bytes32 hash, bytes calldata sig) external view returns (uint256); } interface ISigner is IModule { function checkUserOpSignature(bytes32 id, PackedUserOperation calldata userOp, bytes32 userOpHash) external payable returns (uint256); function checkSignature(bytes32 id, address sender, bytes32 hash, bytes calldata sig) external view returns (bytes4); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.5; /** * 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 accountGasLimits - Packed gas limits for validateUserOp and gas limit passed to the callData method call. * @param preVerificationGas - Gas not calculated by the handleOps method, but added to the gas paid. * Covers batch overhead. * @param gasFees - packed gas fields maxFeePerGas and maxPriorityFeePerGas - Same as EIP-1559 gas parameter. * @param paymasterAndData - If set, this field holds the paymaster address, verification gas limit, postOp gas limit and paymaster-specific extra 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 PackedUserOperation { address sender; uint256 nonce; bytes initCode; bytes callData; bytes32 accountGasLimits; uint256 preVerificationGas; bytes32 gasFees; //maxPriorityFee and maxFeePerGas; bytes paymasterAndData; bytes signature; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.23; // Custom type for improved developer experience type ExecMode is bytes32; type CallType is bytes1; type ExecType is bytes1; type ExecModeSelector is bytes4; type ExecModePayload is bytes22; using {eqModeSelector as ==} for ExecModeSelector global; using {eqCallType as ==} for CallType global; using {notEqCallType as !=} for CallType global; using {eqExecType as ==} for ExecType global; function eqCallType(CallType a, CallType b) pure returns (bool) { return CallType.unwrap(a) == CallType.unwrap(b); } function notEqCallType(CallType a, CallType b) pure returns (bool) { return CallType.unwrap(a) != CallType.unwrap(b); } function eqExecType(ExecType a, ExecType b) pure returns (bool) { return ExecType.unwrap(a) == ExecType.unwrap(b); } function eqModeSelector(ExecModeSelector a, ExecModeSelector b) pure returns (bool) { return ExecModeSelector.unwrap(a) == ExecModeSelector.unwrap(b); } type ValidationMode is bytes1; type ValidationId is bytes21; type ValidationType is bytes1; type PermissionId is bytes4; type PolicyData is bytes22; // 2bytes for flag on skip, 20 bytes for validator address type PassFlag is bytes2; using {vModeEqual as ==} for ValidationMode global; using {vTypeEqual as ==} for ValidationType global; using {vIdentifierEqual as ==} for ValidationId global; using {vModeNotEqual as !=} for ValidationMode global; using {vTypeNotEqual as !=} for ValidationType global; using {vIdentifierNotEqual as !=} for ValidationId global; // nonce = uint192(key) + nonce // key = mode + (vtype + validationDataWithoutType) + 2bytes parallelNonceKey // key = 0x00 + 0x00 + 0x000 .. 00 + 0x0000 // key = 0x00 + 0x01 + 0x1234...ff + 0x0000 // key = 0x00 + 0x02 + ( ) + 0x000 function vModeEqual(ValidationMode a, ValidationMode b) pure returns (bool) { return ValidationMode.unwrap(a) == ValidationMode.unwrap(b); } function vModeNotEqual(ValidationMode a, ValidationMode b) pure returns (bool) { return ValidationMode.unwrap(a) != ValidationMode.unwrap(b); } function vTypeEqual(ValidationType a, ValidationType b) pure returns (bool) { return ValidationType.unwrap(a) == ValidationType.unwrap(b); } function vTypeNotEqual(ValidationType a, ValidationType b) pure returns (bool) { return ValidationType.unwrap(a) != ValidationType.unwrap(b); } function vIdentifierEqual(ValidationId a, ValidationId b) pure returns (bool) { return ValidationId.unwrap(a) == ValidationId.unwrap(b); } function vIdentifierNotEqual(ValidationId a, ValidationId b) pure returns (bool) { return ValidationId.unwrap(a) != ValidationId.unwrap(b); } type ValidationData is uint256; type ValidAfter is uint48; type ValidUntil is uint48; function getValidationResult(ValidationData validationData) pure returns (address result) { assembly { result := validationData } } function packValidationData(ValidAfter validAfter, ValidUntil validUntil) pure returns (uint256) { return uint256(ValidAfter.unwrap(validAfter)) << 208 | uint256(ValidUntil.unwrap(validUntil)) << 160; } function parseValidationData(uint256 validationData) pure returns (ValidAfter validAfter, ValidUntil validUntil, address result) { assembly { result := validationData validUntil := and(shr(160, validationData), 0xffffffffffff) switch iszero(validUntil) case 1 { validUntil := 0xffffffffffff } validAfter := shr(208, validationData) } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {CallType, ExecType, ExecModeSelector} from "./Types.sol"; import {PassFlag, ValidationMode, ValidationType} from "./Types.sol"; import {ValidationData} from "./Types.sol"; // --- ERC7579 calltypes --- // Default CallType CallType constant CALLTYPE_SINGLE = CallType.wrap(0x00); // Batched CallType CallType constant CALLTYPE_BATCH = CallType.wrap(0x01); CallType constant CALLTYPE_STATIC = CallType.wrap(0xFE); // @dev Implementing delegatecall is OPTIONAL! // implement delegatecall with extreme care. CallType constant CALLTYPE_DELEGATECALL = CallType.wrap(0xFF); // --- ERC7579 exectypes --- // @dev default behavior is to revert on failure // To allow very simple accounts to use mode encoding, the default behavior is to revert on failure // Since this is value 0x00, no additional encoding is required for simple accounts ExecType constant EXECTYPE_DEFAULT = ExecType.wrap(0x00); // @dev account may elect to change execution behavior. For example "try exec" / "allow fail" ExecType constant EXECTYPE_TRY = ExecType.wrap(0x01); // --- ERC7579 mode selector --- ExecModeSelector constant EXEC_MODE_DEFAULT = ExecModeSelector.wrap(bytes4(0x00000000)); // --- Kernel permission skip flags --- PassFlag constant SKIP_USEROP = PassFlag.wrap(0x0001); PassFlag constant SKIP_SIGNATURE = PassFlag.wrap(0x0002); // --- Kernel validation modes --- ValidationMode constant VALIDATION_MODE_DEFAULT = ValidationMode.wrap(0x00); ValidationMode constant VALIDATION_MODE_ENABLE = ValidationMode.wrap(0x01); ValidationMode constant VALIDATION_MODE_INSTALL = ValidationMode.wrap(0x02); // --- Kernel validation types --- ValidationType constant VALIDATION_TYPE_ROOT = ValidationType.wrap(0x00); ValidationType constant VALIDATION_TYPE_VALIDATOR = ValidationType.wrap(0x01); ValidationType constant VALIDATION_TYPE_PERMISSION = ValidationType.wrap(0x02); // --- storage slots --- // bytes32(uint256(keccak256('kernel.v3.selector')) - 1) bytes32 constant SELECTOR_MANAGER_STORAGE_SLOT = 0x7c341349a4360fdd5d5bc07e69f325dc6aaea3eb018b3e0ea7e53cc0bb0d6f3b; // bytes32(uint256(keccak256('kernel.v3.executor')) - 1) bytes32 constant EXECUTOR_MANAGER_STORAGE_SLOT = 0x1bbee3173dbdc223633258c9f337a0fff8115f206d302bea0ed3eac003b68b86; // bytes32(uint256(keccak256('kernel.v3.hook')) - 1) bytes32 constant HOOK_MANAGER_STORAGE_SLOT = 0x4605d5f70bb605094b2e761eccdc27bed9a362d8612792676bf3fb9b12832ffc; // bytes32(uint256(keccak256('kernel.v3.validation')) - 1) bytes32 constant VALIDATION_MANAGER_STORAGE_SLOT = 0x7bcaa2ced2a71450ed5a9a1b4848e8e5206dbc3f06011e595f7f55428cc6f84f; bytes32 constant ERC1967_IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; // --- Kernel validation nonce incremental size limit --- uint32 constant MAX_NONCE_INCREMENT_SIZE = 10; // -- EIP712 type hash --- bytes32 constant ENABLE_TYPE_HASH = 0xb17ab1224aca0d4255ef8161acaf2ac121b8faa32a4b2258c912cc5f8308c505; bytes32 constant KERNEL_WRAPPER_TYPE_HASH = 0x1547321c374afde8a591d972a084b071c594c275e36724931ff96c25f2999c83; // --- ERC constants --- // ERC4337 constants uint256 constant SIG_VALIDATION_FAILED_UINT = 1; uint256 constant SIG_VALIDATION_SUCCESS_UINT = 0; ValidationData constant SIG_VALIDATION_FAILED = ValidationData.wrap(SIG_VALIDATION_FAILED_UINT); // ERC-1271 constants bytes4 constant ERC1271_MAGICVALUE = 0x1626ba7e; bytes4 constant ERC1271_INVALID = 0xffffffff; uint256 constant MODULE_TYPE_VALIDATOR = 1; uint256 constant MODULE_TYPE_EXECUTOR = 2; uint256 constant MODULE_TYPE_FALLBACK = 3; uint256 constant MODULE_TYPE_HOOK = 4; uint256 constant MODULE_TYPE_POLICY = 5; uint256 constant MODULE_TYPE_SIGNER = 6;
// SPDX-License-Identifier: MIT pragma solidity ^0.8.23; struct Execution { address target; uint256 value; bytes callData; }
{ "remappings": [ "ds-test/=lib/kernel_v3/lib/forge-std/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "kernel/=lib/kernel_v3/src/", "solady/=lib/kernel_v3/lib/solady/src/", "ExcessivelySafeCall/=lib/kernel_v3/lib/ExcessivelySafeCall/src/", "kernel_v3/=lib/kernel_v3/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "none", "appendCBOR": false }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": true, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"smartAccount","type":"address"}],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"CallViolatesParamRule","type":"error"},{"inputs":[],"name":"CallViolatesValueRule","type":"error"},{"inputs":[],"name":"InvalidCallData","type":"error"},{"inputs":[],"name":"InvalidCallType","type":"error"},{"inputs":[{"internalType":"address","name":"smartAccount","type":"address"}],"name":"NotInitialized","type":"error"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"sig","type":"bytes"}],"name":"checkSignaturePolicy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"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":"bytes32","name":"accountGasLimits","type":"bytes32"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"bytes32","name":"gasFees","type":"bytes32"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct PackedUserOperation","name":"userOp","type":"tuple"}],"name":"checkUserOpPolicy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"bytes32","name":"permissionHash","type":"bytes32"},{"internalType":"address","name":"","type":"address"}],"name":"encodedPermissions","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"isInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"isModuleType","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onInstall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onUninstall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"address","name":"","type":"address"}],"name":"status","outputs":[{"internalType":"enum Status","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"usedIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6080806040523461001657611cd9908161001c8239f35b600080fdfe608080604052600436101561001357600080fd5b60003560e01c908163244d6cb214610a2357508063309bfb76146109ad5780636d61fe70146104505780637129edce146102a25780638a91b0e3146101f5578063d60b347f146101b9578063d8ed2b3c1461014f578063ecd059611461012f5763ffbb39f81461008257600080fd5b3461012a57606036600319011261012a576044356001600160a01b0381169081900361012a57600435600052602090600282526040600020602435600052825260406000209060005281526100da6040600020610b43565b604051828193825282519081818401526000935b828510610111575050604092506000838284010152601f80199101168101030190f35b84810182015186860160400152938101938593506100ee565b600080fd5b3461012a57602036600319011261012a5760206040516005600435148152f35b3461012a57604036600319011261012a57610168610a6f565b600435600052600160205260406000209060018060a01b031660005260205260ff6040600020541660405160038210156101a3576020918152f35b634e487b7160e01b600052602160045260246000fd5b3461012a57602036600319011261012a576001600160a01b036101da610a59565b16600052600060205260206040600020541515604051908152f35b60208060031936011261012a576004356001600160401b03811161012a57610221903690600401610a85565b821161012a5735908160005260018152604060002033600052815260ff6040600020541660038110156101a35760010361012a5760009182526001815260408220338352815260408220600260ff198254161790555260406000208054801561028c57600019019055005b634e487b7160e01b600052601160045260246000fd5b60031960403682011261012a57600435906024356001600160401b03811161012a576101208160040192823603011261012a57606401906102e38282610c1d565b60041161012a57631651a3ad60e01b90356001600160e01b0319160161012a5761030d8282610c1d565b60249391931161012a5761032091610c1d565b5060248101350160248101906004808201359360ff60f81b918291013516801560001461038557505050610362929161035891610cf2565b92909193336117de565b15610373575b602060405160008152f35b60405163016754b960e61b8152600490fd5b919391600160f81b81036104085750505035016024604482019101359160005b8381106103b55750505050610368565b6103fb6103cb6103c6838787610c4f565b610c87565b6103e36103d9848888610c4f565b6040810190610c1d565b9060206103f1868a8a610c4f565b01359286336112d6565b15610373576001016103a5565b919493500361043e576104289261041e91610cf2565b9290919333610d82565b6103685760405163016754b960e61b8152600490fd5b6040516339d2eb5560e01b8152600490fd5b602036600319011261012a576004356001600160401b03811161012a5761047b903690600401610a85565b60201161012a578035600052600160205260406000203360005260205260ff6040600020541660038110156101a35761012a576000602082013582015b6020810135821061050557823560005260016020526040600020336000526020526040600020600160ff19825416179055600060205260406000208054600019811461028c576001019055005b61051782602083013560408401610c9b565b3560ff60f81b811680910361012a57610542602061053c858286013560408701610c9b565b01610c87565b6040610555856020860135838701610c9b565b013563ffffffff60e01b811680910361012a5760405191602083019384526bffffffffffffffffffffffff199060601b16602183015260358201526019815261059d81610b07565b519020833560005260026020526040600020816000526020526040600020336000526020526105d0604060002054610ab2565b6109685760005b6105f66105ec85602086013560408701610c9b565b6080810190610cbd565b90508110156106c35761061e816106186105ec87602088013560408901610c9b565b90610c4f565b35600781101561012a57600603610638575b6001016105d7565b6001610660610656836106186105ec8960208a013560408b01610c9b565b6040810190610cbd565b905003156106305760405162461bcd60e51b815260206004820152602d60248201527f6f6e6c79204f6e654f6620636f6e646974696f6e2063616e2068617665206d7560448201526c6c7469706c6520706172616d7360981b6064820152608490fd5b50929160606106da82602085013560408601610c9b565b0135936106f26105ec83602086013560408701610c9b565b958660405197889260608401906020850152604080850152526080820160808260051b8401019380926000915b81831061088e57505050505061073d9103601f198101875286610b22565b83356000526002602052604060002090600052602052604060002033600052602052604060002084516001600160401b0381116108785761077e8254610ab2565b601f8111610834575b506020601f82116001146107ca57819060019596976000926107bf575b5050600019600383901b1c191690841b1790555b01906104b8565b0151905087806107a4565b601f198216968360005260206000209760005b81811061081c5750916001969798918488959410610803575b505050811b0190556107b8565b015160001960f88460031b161c191690558780806107f6565b92986020600181928c8601518155019a0193016107dd565b826000526020600020601f830160051c810160208410610871575b601f830160051c82018110610865575050610787565b6000815560010161084f565b508061084f565b634e487b7160e01b600052604160045260246000fd5b909192939450607f198b87030184528435605e198236030181121561012a57600782820135101561012a5780820180358852602001356001600160401b038116810361012a576001600160401b03166020880152601e1982820136030160408383010135121561012a578101604081013501956001600160401b0387351161012a57863560051b3603602088011361012a5760606040820181905287359082018190526001600160fb1b031061012a5760208060806001938f9a803560051b848201848401373560051b010198970195019301919061071f565b60405162461bcd60e51b815260206004820152601860248201527f6475706c6963617465207065726d697373696f6e4861736800000000000000006044820152606490fd5b3461012a57608036600319011261012a576109c6610a6f565b506064356001600160401b03811161012a576109e6903690600401610a85565b5050600435600052600160205260406000203360005260205260ff6040600020541660038110156101a35760010361012a57602060405160008152f35b3461012a57602036600319011261012a576020906001600160a01b03610a47610a59565b16600052600082526040600020548152f35b600435906001600160a01b038216820361012a57565b602435906001600160a01b038216820361012a57565b9181601f8401121561012a578235916001600160401b03831161012a576020838186019501011161012a57565b90600182811c92168015610ae2575b6020831014610acc57565b634e487b7160e01b600052602260045260246000fd5b91607f1691610ac1565b606081019081106001600160401b0382111761087857604052565b604081019081106001600160401b0382111761087857604052565b90601f801991011681019081106001600160401b0382111761087857604052565b90604051918260008254610b5681610ab2565b90818452602094600191600181169081600014610bc65750600114610b87575b505050610b8592500383610b22565b565b600090815285812095935091905b818310610bae575050610b859350820101388080610b76565b85548884018501529485019487945091830191610b95565b92505050610b8594925060ff191682840152151560051b820101388080610b76565b9093929384831161012a57841161012a578101920390565b359060208110610c0e575090565b6000199060200360031b1b1690565b903590601e198136030182121561012a57018035906001600160401b03821161012a5760200191813603831361012a57565b9190811015610c715760051b81013590605e198136030182121561012a570190565b634e487b7160e01b600052603260045260246000fd5b356001600160a01b038116810361012a5790565b9190811015610c715760051b81013590609e198136030182121561012a570190565b903590601e198136030182121561012a57018035906001600160401b03821161012a57602001918160051b3603831361012a57565b908060141161012a57813560601c928160341161012a57601483013592603401916033190190565b6001600160401b0381116108785760051b60200190565b805115610c715760200190565b8051821015610c715760209160051b010190565b906001600160401b0380921660040191821161028c57565b9060206001600160401b038093160191821161028c57565b91949293929190836112bc576000955b6040516001600160f81b03196020820181815260609390931b6001600160601b03191660218301526001600160e01b03199098166035820181905260198252979190610ddd81610b07565b51902082600052600260205260406000209060005260205260406000209260018060a01b03169283600052602052610e186040600020610b43565b96875115611257575b5050505083511561124557835184019060408583031261012a576020850151916040860151906001600160401b03821161012a5760208101603f83890101121561012a5760208288010151610e7581610d1a565b97610e83604051998a610b22565b81895260208901936020840160408460051b83850101011161012a57604081830101945b60408460051b8385010101861061114d575050505050501161113b5760005b835181101561113257610ed98185610d3e565b51610f1d610f17602083016001600160401b0380610f0d610f0882610f0081875116610d52565b955116610d52565b610d6a565b1691168688610be8565b90610c00565b815190600791828110156101a357158061111b575b15610f435750505050505050600090565b825191808310156101a357600180931480611104575b15610f6b575050505050505050600090565b8351818110156101a357600214806110ed575b15610f90575050505050505050600090565b8351818110156101a357600314806110d7575b15610fb5575050505050505050600090565b8351818110156101a3576004809114806110c1575b15610fdd57505050505050505050600090565b8451828110156110ac5760051480611096575b1561100357505050505050505050600090565b8451918210156110815750600614611021575b505050600101610ec6565b60009260400183835b611049575b505050501561104057388080611016565b50505050600090565b8151805182101561107b578161105e91610d3e565b51831461106d5783018361102a565b50505090503880808061102f565b5061102f565b602190634e487b7160e01b6000525260246000fd5b506110a46040860151610d31565b518314610ff0565b602182634e487b7160e01b6000525260246000fd5b506110cf6040860151610d31565b518311610fca565b506110e56040850151610d31565b518210610fa3565b506110fb6040850151610d31565b51821015610f7e565b506111126040850151610d31565b51821115610f59565b506111296040840151610d31565b51811415610f32565b50505050600190565b604051631ed604b560e21b8152600490fd5b85516001600160401b03811161012a57838301016060818703601f19011261012a576040519061117c82610aec565b6040810151600781101561012a57825260608101516001600160401b038116810361012a57602083015260808101516001600160401b03811161012a5760208801605f82840101121561012a5760408183010151906111da82610d1a565b926111e86040519485610b22565b828452602084019160208b0160608560051b83850101011161012a57606081830101925b60608560051b838501010184106112355750505050506040820152815260209586019501610ea7565b835181526020938401930161120c565b604051631c49f4d160e01b8152600490fd5b90919293965060405190602082019283526000602183015260358201526019815261128181610b07565b5190209060005260026020526040600020906000526020526040600020906000526020526112b26040600020610b43565b9238808080610e21565b8360041161012a5784356001600160e01b03191695610d92565b929392906000846117c057506000925b60405160006020820190815260609290921b6001600160601b03191660218201526001600160e01b03198516603582015261132e81603981015b03601f198101835282610b22565b51902081600052600260205260406000209060005260205260406000209160018060a01b031691826000526020526113696040600020610b43565b92835115611755575b50505080511561124557805181019360408286031261012a576020820151916040810151906001600160401b03821161012a5760208701603f83830101121561012a57602082820101516113c581610d1a565b976113d3604051998a610b22565b81895260208901906020810160408460051b87870101011161012a57604085850101915b60408460051b87870101018310611632575050505050501161113b5760005b8351811015611132576114298185610d3e565b51611450610f17602083016001600160401b0380610f0d610f0882610f0081875116610d52565b815190600791828110156101a357158061161b575b156114765750505050505050600090565b825191808310156101a357600180931480611604575b1561149e575050505050505050600090565b8351818110156101a357600214806115ed575b156114c3575050505050505050600090565b8351818110156101a357600314806115d7575b156114e8575050505050505050600090565b8351818110156101a3576004809114806115c1575b1561151057505050505050505050600090565b8451828110156110ac57600514806115ab575b1561153657505050505050505050600090565b8451918210156110815750600614611554575b505050600101611416565b60009260400183835b611573575b505050501561104057388080611549565b815180518210156115a5578161158891610d3e565b5183146115975783018361155d565b505050905038808080611562565b50611562565b506115b96040860151610d31565b518314611523565b506115cf6040860151610d31565b5183116114fd565b506115e56040850151610d31565b5182106114d6565b506115fb6040850151610d31565b518210156114b1565b506116126040850151610d31565b5182111561148c565b506116296040840151610d31565b51811415611465565b82516001600160401b03811161012a57606086880182018403601f19011261012a576040519061166182610aec565b604081898901010151600781101561012a5782526060818989010101516001600160401b038116810361012a576020830152608081898901010151906001600160401b03821161012a5760208501605f83838c8c01010101121561012a57604082828b8b0101010151906116d482610d1a565b926116e26040519485610b22565b82845260208401918b60608c848460208d01948960051b9301010101011161012a578b928b60608484878401010101915b60608760051b8686898601010101018310611745575050505050604084019290925250508152602092830192016113f7565b8251815260209283019201611713565b909192506040516020810191600083526000602183015263ffffffff60e01b1660358201526019815261178781610b07565b5190209060005260026020526040600020906000526020526040600020906000526020526117b86040600020610b43565b388080611372565b846004116117db575084356001600160e01b031916926112e6565b80fd5b92939290600084611cbe57506000925b60405160006020820190815260609290921b6001600160601b03191660218201526001600160e01b03198516603582015261182c8160398101611320565b51902081600052600260205260406000209060005260205260406000209160018060a01b031691826000526020526118676040600020610b43565b92835115611c53575b50505080511561124557805181019360408286031261012a576020820151916040810151906001600160401b03821161012a5760208701603f83830101121561012a57602082820101516118c381610d1a565b976118d1604051998a610b22565b81895260208901906020810160408460051b87870101011161012a57604085850101915b60408460051b87870101018310611b30575050505050501161113b5760005b8351811015611132576119278185610d3e565b5161194e610f17602083016001600160401b0380610f0d610f0882610f0081875116610d52565b815190600791828110156101a3571580611b19575b156119745750505050505050600090565b825191808310156101a357600180931480611b02575b1561199c575050505050505050600090565b8351818110156101a35760021480611aeb575b156119c1575050505050505050600090565b8351818110156101a35760031480611ad5575b156119e6575050505050505050600090565b8351818110156101a357600480911480611abf575b15611a0e57505050505050505050600090565b8451828110156110ac5760051480611aa9575b15611a3457505050505050505050600090565b8451918210156110815750600614611a52575b505050600101611914565b60009260400183835b611a71575b505050501561104057388080611a47565b81518051821015611aa35781611a8691610d3e565b518314611a9557830183611a5b565b505050905038808080611a60565b50611a60565b50611ab76040860151610d31565b518314611a21565b50611acd6040860151610d31565b5183116119fb565b50611ae36040850151610d31565b5182106119d4565b50611af96040850151610d31565b518210156119af565b50611b106040850151610d31565b5182111561198a565b50611b276040840151610d31565b51811415611963565b82516001600160401b03811161012a57606086880182018403601f19011261012a5760405190611b5f82610aec565b604081898901010151600781101561012a5782526060818989010101516001600160401b038116810361012a576020830152608081898901010151906001600160401b03821161012a5760208501605f83838c8c01010101121561012a57604082828b8b010101015190611bd282610d1a565b92611be06040519485610b22565b82845260208401918b60608c848460208d01948960051b9301010101011161012a578b928b60608484878401010101915b60608760051b8686898601010101018310611c43575050505050604084019290925250508152602092830192016118f5565b8251815260209283019201611c11565b909192506040516020810191600083526000602183015263ffffffff60e01b16603582015260198152611c8581610b07565b519020906000526002602052604060002090600052602052604060002090600052602052611cb66040600020610b43565b388080611870565b846004116117db575084356001600160e01b031916926117ee56
Deployed Bytecode
0x608080604052600436101561001357600080fd5b60003560e01c908163244d6cb214610a2357508063309bfb76146109ad5780636d61fe70146104505780637129edce146102a25780638a91b0e3146101f5578063d60b347f146101b9578063d8ed2b3c1461014f578063ecd059611461012f5763ffbb39f81461008257600080fd5b3461012a57606036600319011261012a576044356001600160a01b0381169081900361012a57600435600052602090600282526040600020602435600052825260406000209060005281526100da6040600020610b43565b604051828193825282519081818401526000935b828510610111575050604092506000838284010152601f80199101168101030190f35b84810182015186860160400152938101938593506100ee565b600080fd5b3461012a57602036600319011261012a5760206040516005600435148152f35b3461012a57604036600319011261012a57610168610a6f565b600435600052600160205260406000209060018060a01b031660005260205260ff6040600020541660405160038210156101a3576020918152f35b634e487b7160e01b600052602160045260246000fd5b3461012a57602036600319011261012a576001600160a01b036101da610a59565b16600052600060205260206040600020541515604051908152f35b60208060031936011261012a576004356001600160401b03811161012a57610221903690600401610a85565b821161012a5735908160005260018152604060002033600052815260ff6040600020541660038110156101a35760010361012a5760009182526001815260408220338352815260408220600260ff198254161790555260406000208054801561028c57600019019055005b634e487b7160e01b600052601160045260246000fd5b60031960403682011261012a57600435906024356001600160401b03811161012a576101208160040192823603011261012a57606401906102e38282610c1d565b60041161012a57631651a3ad60e01b90356001600160e01b0319160161012a5761030d8282610c1d565b60249391931161012a5761032091610c1d565b5060248101350160248101906004808201359360ff60f81b918291013516801560001461038557505050610362929161035891610cf2565b92909193336117de565b15610373575b602060405160008152f35b60405163016754b960e61b8152600490fd5b919391600160f81b81036104085750505035016024604482019101359160005b8381106103b55750505050610368565b6103fb6103cb6103c6838787610c4f565b610c87565b6103e36103d9848888610c4f565b6040810190610c1d565b9060206103f1868a8a610c4f565b01359286336112d6565b15610373576001016103a5565b919493500361043e576104289261041e91610cf2565b9290919333610d82565b6103685760405163016754b960e61b8152600490fd5b6040516339d2eb5560e01b8152600490fd5b602036600319011261012a576004356001600160401b03811161012a5761047b903690600401610a85565b60201161012a578035600052600160205260406000203360005260205260ff6040600020541660038110156101a35761012a576000602082013582015b6020810135821061050557823560005260016020526040600020336000526020526040600020600160ff19825416179055600060205260406000208054600019811461028c576001019055005b61051782602083013560408401610c9b565b3560ff60f81b811680910361012a57610542602061053c858286013560408701610c9b565b01610c87565b6040610555856020860135838701610c9b565b013563ffffffff60e01b811680910361012a5760405191602083019384526bffffffffffffffffffffffff199060601b16602183015260358201526019815261059d81610b07565b519020833560005260026020526040600020816000526020526040600020336000526020526105d0604060002054610ab2565b6109685760005b6105f66105ec85602086013560408701610c9b565b6080810190610cbd565b90508110156106c35761061e816106186105ec87602088013560408901610c9b565b90610c4f565b35600781101561012a57600603610638575b6001016105d7565b6001610660610656836106186105ec8960208a013560408b01610c9b565b6040810190610cbd565b905003156106305760405162461bcd60e51b815260206004820152602d60248201527f6f6e6c79204f6e654f6620636f6e646974696f6e2063616e2068617665206d7560448201526c6c7469706c6520706172616d7360981b6064820152608490fd5b50929160606106da82602085013560408601610c9b565b0135936106f26105ec83602086013560408701610c9b565b958660405197889260608401906020850152604080850152526080820160808260051b8401019380926000915b81831061088e57505050505061073d9103601f198101875286610b22565b83356000526002602052604060002090600052602052604060002033600052602052604060002084516001600160401b0381116108785761077e8254610ab2565b601f8111610834575b506020601f82116001146107ca57819060019596976000926107bf575b5050600019600383901b1c191690841b1790555b01906104b8565b0151905087806107a4565b601f198216968360005260206000209760005b81811061081c5750916001969798918488959410610803575b505050811b0190556107b8565b015160001960f88460031b161c191690558780806107f6565b92986020600181928c8601518155019a0193016107dd565b826000526020600020601f830160051c810160208410610871575b601f830160051c82018110610865575050610787565b6000815560010161084f565b508061084f565b634e487b7160e01b600052604160045260246000fd5b909192939450607f198b87030184528435605e198236030181121561012a57600782820135101561012a5780820180358852602001356001600160401b038116810361012a576001600160401b03166020880152601e1982820136030160408383010135121561012a578101604081013501956001600160401b0387351161012a57863560051b3603602088011361012a5760606040820181905287359082018190526001600160fb1b031061012a5760208060806001938f9a803560051b848201848401373560051b010198970195019301919061071f565b60405162461bcd60e51b815260206004820152601860248201527f6475706c6963617465207065726d697373696f6e4861736800000000000000006044820152606490fd5b3461012a57608036600319011261012a576109c6610a6f565b506064356001600160401b03811161012a576109e6903690600401610a85565b5050600435600052600160205260406000203360005260205260ff6040600020541660038110156101a35760010361012a57602060405160008152f35b3461012a57602036600319011261012a576020906001600160a01b03610a47610a59565b16600052600082526040600020548152f35b600435906001600160a01b038216820361012a57565b602435906001600160a01b038216820361012a57565b9181601f8401121561012a578235916001600160401b03831161012a576020838186019501011161012a57565b90600182811c92168015610ae2575b6020831014610acc57565b634e487b7160e01b600052602260045260246000fd5b91607f1691610ac1565b606081019081106001600160401b0382111761087857604052565b604081019081106001600160401b0382111761087857604052565b90601f801991011681019081106001600160401b0382111761087857604052565b90604051918260008254610b5681610ab2565b90818452602094600191600181169081600014610bc65750600114610b87575b505050610b8592500383610b22565b565b600090815285812095935091905b818310610bae575050610b859350820101388080610b76565b85548884018501529485019487945091830191610b95565b92505050610b8594925060ff191682840152151560051b820101388080610b76565b9093929384831161012a57841161012a578101920390565b359060208110610c0e575090565b6000199060200360031b1b1690565b903590601e198136030182121561012a57018035906001600160401b03821161012a5760200191813603831361012a57565b9190811015610c715760051b81013590605e198136030182121561012a570190565b634e487b7160e01b600052603260045260246000fd5b356001600160a01b038116810361012a5790565b9190811015610c715760051b81013590609e198136030182121561012a570190565b903590601e198136030182121561012a57018035906001600160401b03821161012a57602001918160051b3603831361012a57565b908060141161012a57813560601c928160341161012a57601483013592603401916033190190565b6001600160401b0381116108785760051b60200190565b805115610c715760200190565b8051821015610c715760209160051b010190565b906001600160401b0380921660040191821161028c57565b9060206001600160401b038093160191821161028c57565b91949293929190836112bc576000955b6040516001600160f81b03196020820181815260609390931b6001600160601b03191660218301526001600160e01b03199098166035820181905260198252979190610ddd81610b07565b51902082600052600260205260406000209060005260205260406000209260018060a01b03169283600052602052610e186040600020610b43565b96875115611257575b5050505083511561124557835184019060408583031261012a576020850151916040860151906001600160401b03821161012a5760208101603f83890101121561012a5760208288010151610e7581610d1a565b97610e83604051998a610b22565b81895260208901936020840160408460051b83850101011161012a57604081830101945b60408460051b8385010101861061114d575050505050501161113b5760005b835181101561113257610ed98185610d3e565b51610f1d610f17602083016001600160401b0380610f0d610f0882610f0081875116610d52565b955116610d52565b610d6a565b1691168688610be8565b90610c00565b815190600791828110156101a357158061111b575b15610f435750505050505050600090565b825191808310156101a357600180931480611104575b15610f6b575050505050505050600090565b8351818110156101a357600214806110ed575b15610f90575050505050505050600090565b8351818110156101a357600314806110d7575b15610fb5575050505050505050600090565b8351818110156101a3576004809114806110c1575b15610fdd57505050505050505050600090565b8451828110156110ac5760051480611096575b1561100357505050505050505050600090565b8451918210156110815750600614611021575b505050600101610ec6565b60009260400183835b611049575b505050501561104057388080611016565b50505050600090565b8151805182101561107b578161105e91610d3e565b51831461106d5783018361102a565b50505090503880808061102f565b5061102f565b602190634e487b7160e01b6000525260246000fd5b506110a46040860151610d31565b518314610ff0565b602182634e487b7160e01b6000525260246000fd5b506110cf6040860151610d31565b518311610fca565b506110e56040850151610d31565b518210610fa3565b506110fb6040850151610d31565b51821015610f7e565b506111126040850151610d31565b51821115610f59565b506111296040840151610d31565b51811415610f32565b50505050600190565b604051631ed604b560e21b8152600490fd5b85516001600160401b03811161012a57838301016060818703601f19011261012a576040519061117c82610aec565b6040810151600781101561012a57825260608101516001600160401b038116810361012a57602083015260808101516001600160401b03811161012a5760208801605f82840101121561012a5760408183010151906111da82610d1a565b926111e86040519485610b22565b828452602084019160208b0160608560051b83850101011161012a57606081830101925b60608560051b838501010184106112355750505050506040820152815260209586019501610ea7565b835181526020938401930161120c565b604051631c49f4d160e01b8152600490fd5b90919293965060405190602082019283526000602183015260358201526019815261128181610b07565b5190209060005260026020526040600020906000526020526040600020906000526020526112b26040600020610b43565b9238808080610e21565b8360041161012a5784356001600160e01b03191695610d92565b929392906000846117c057506000925b60405160006020820190815260609290921b6001600160601b03191660218201526001600160e01b03198516603582015261132e81603981015b03601f198101835282610b22565b51902081600052600260205260406000209060005260205260406000209160018060a01b031691826000526020526113696040600020610b43565b92835115611755575b50505080511561124557805181019360408286031261012a576020820151916040810151906001600160401b03821161012a5760208701603f83830101121561012a57602082820101516113c581610d1a565b976113d3604051998a610b22565b81895260208901906020810160408460051b87870101011161012a57604085850101915b60408460051b87870101018310611632575050505050501161113b5760005b8351811015611132576114298185610d3e565b51611450610f17602083016001600160401b0380610f0d610f0882610f0081875116610d52565b815190600791828110156101a357158061161b575b156114765750505050505050600090565b825191808310156101a357600180931480611604575b1561149e575050505050505050600090565b8351818110156101a357600214806115ed575b156114c3575050505050505050600090565b8351818110156101a357600314806115d7575b156114e8575050505050505050600090565b8351818110156101a3576004809114806115c1575b1561151057505050505050505050600090565b8451828110156110ac57600514806115ab575b1561153657505050505050505050600090565b8451918210156110815750600614611554575b505050600101611416565b60009260400183835b611573575b505050501561104057388080611549565b815180518210156115a5578161158891610d3e565b5183146115975783018361155d565b505050905038808080611562565b50611562565b506115b96040860151610d31565b518314611523565b506115cf6040860151610d31565b5183116114fd565b506115e56040850151610d31565b5182106114d6565b506115fb6040850151610d31565b518210156114b1565b506116126040850151610d31565b5182111561148c565b506116296040840151610d31565b51811415611465565b82516001600160401b03811161012a57606086880182018403601f19011261012a576040519061166182610aec565b604081898901010151600781101561012a5782526060818989010101516001600160401b038116810361012a576020830152608081898901010151906001600160401b03821161012a5760208501605f83838c8c01010101121561012a57604082828b8b0101010151906116d482610d1a565b926116e26040519485610b22565b82845260208401918b60608c848460208d01948960051b9301010101011161012a578b928b60608484878401010101915b60608760051b8686898601010101018310611745575050505050604084019290925250508152602092830192016113f7565b8251815260209283019201611713565b909192506040516020810191600083526000602183015263ffffffff60e01b1660358201526019815261178781610b07565b5190209060005260026020526040600020906000526020526040600020906000526020526117b86040600020610b43565b388080611372565b846004116117db575084356001600160e01b031916926112e6565b80fd5b92939290600084611cbe57506000925b60405160006020820190815260609290921b6001600160601b03191660218201526001600160e01b03198516603582015261182c8160398101611320565b51902081600052600260205260406000209060005260205260406000209160018060a01b031691826000526020526118676040600020610b43565b92835115611c53575b50505080511561124557805181019360408286031261012a576020820151916040810151906001600160401b03821161012a5760208701603f83830101121561012a57602082820101516118c381610d1a565b976118d1604051998a610b22565b81895260208901906020810160408460051b87870101011161012a57604085850101915b60408460051b87870101018310611b30575050505050501161113b5760005b8351811015611132576119278185610d3e565b5161194e610f17602083016001600160401b0380610f0d610f0882610f0081875116610d52565b815190600791828110156101a3571580611b19575b156119745750505050505050600090565b825191808310156101a357600180931480611b02575b1561199c575050505050505050600090565b8351818110156101a35760021480611aeb575b156119c1575050505050505050600090565b8351818110156101a35760031480611ad5575b156119e6575050505050505050600090565b8351818110156101a357600480911480611abf575b15611a0e57505050505050505050600090565b8451828110156110ac5760051480611aa9575b15611a3457505050505050505050600090565b8451918210156110815750600614611a52575b505050600101611914565b60009260400183835b611a71575b505050501561104057388080611a47565b81518051821015611aa35781611a8691610d3e565b518314611a9557830183611a5b565b505050905038808080611a60565b50611a60565b50611ab76040860151610d31565b518314611a21565b50611acd6040860151610d31565b5183116119fb565b50611ae36040850151610d31565b5182106119d4565b50611af96040850151610d31565b518210156119af565b50611b106040850151610d31565b5182111561198a565b50611b276040840151610d31565b51811415611963565b82516001600160401b03811161012a57606086880182018403601f19011261012a5760405190611b5f82610aec565b604081898901010151600781101561012a5782526060818989010101516001600160401b038116810361012a576020830152608081898901010151906001600160401b03821161012a5760208501605f83838c8c01010101121561012a57604082828b8b010101015190611bd282610d1a565b92611be06040519485610b22565b82845260208401918b60608c848460208d01948960051b9301010101011161012a578b928b60608484878401010101915b60608760051b8686898601010101018310611c43575050505050604084019290925250508152602092830192016118f5565b8251815260209283019201611c11565b909192506040516020810191600083526000602183015263ffffffff60e01b16603582015260198152611c8581610b07565b519020906000526002602052604060002090600052602052604060002090600052602052611cb66040600020610b43565b388080611870565b846004116117db575084356001600160e01b031916926117ee56
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.