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
|
|||||
---|---|---|---|---|---|---|---|---|---|
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
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 Source Code Verified (Exact Match)
Contract Name:
OperationExecutor
Compiler Version
v0.8.15+commit.e14f2714
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.15; import { ServiceRegistry } from "./ServiceRegistry.sol"; import { OperationStorage } from "./OperationStorage.sol"; import { OperationsRegistry } from "./OperationsRegistry.sol"; import { DSProxy } from "../libs/DS/DSProxy.sol"; import { ActionAddress } from "../libs/ActionAddress.sol"; import { TakeFlashloan } from "../actions/common/TakeFlashloan.sol"; import { Executable } from "../actions/common/Executable.sol"; import { IERC3156FlashBorrower } from "../interfaces/flashloan/IERC3156FlashBorrower.sol"; import { IERC3156FlashLender } from "../interfaces/flashloan/IERC3156FlashLender.sol"; import { SafeERC20, IERC20 } from "../libs/SafeERC20.sol"; import { SafeMath } from "../libs/SafeMath.sol"; import { FlashloanData, Call } from "./types/Common.sol"; import { OPERATION_STORAGE, OPERATIONS_REGISTRY, OPERATION_EXECUTOR } from "./constants/Common.sol"; import { FLASH_MINT_MODULE } from "./constants/Maker.sol"; /** * @title Operation Executor * @notice Is responsible for executing sequences of Actions (Operations) */ contract OperationExecutor is IERC3156FlashBorrower { using ActionAddress for address; using SafeERC20 for IERC20; using SafeMath for uint256; ServiceRegistry public immutable registry; /** * @dev Emitted once an Operation has completed execution * @param name The address initiating the deposit * @param calls An array of Action calls the operation must execute **/ event Operation(string name, Call[] calls); constructor(ServiceRegistry _registry) { registry = _registry; } /** * @notice Executes an operation * @dev * There are operations stored in the OperationsRegistry which guarantee the order of execution of actions for a given Operation. * There is a possibility to execute an arrays of calls that don't form an official operation. * * Operation storage is cleared before and after an operation is executed. * * To avoid re-entrancy attack, there is a lock implemented on OpStorage. * A standard reentrancy modifier is not sufficient because the second call via the onFlashloan handler * calls aggregateCallback via DSProxy once again but this breaks the special modifier _ behaviour * and the modifier cannot return the execution flow to the original function. * This is why re-entrancy defence is immplemented here using an external storage contract via the lock/unlock functions * @param calls An array of Action calls the operation must execute * @param operationName The name of the Operation being executed */ function executeOp(Call[] memory calls, string calldata operationName) public payable { OperationStorage opStorage = OperationStorage(registry.getRegisteredService(OPERATION_STORAGE)); opStorage.lock(); OperationsRegistry opRegistry = OperationsRegistry( registry.getRegisteredService(OPERATIONS_REGISTRY) ); opStorage.clearStorage(); opStorage.setOperationActions(opRegistry.getOperation(operationName)); aggregate(calls); opStorage.clearStorage(); opStorage.unlock(); emit Operation(operationName, calls); } function aggregate(Call[] memory calls) internal { OperationStorage opStorage = OperationStorage(registry.getRegisteredService(OPERATION_STORAGE)); bool hasActionsToVerify = opStorage.hasActionsToVerify(); for (uint256 current = 0; current < calls.length; current++) { if (hasActionsToVerify) { opStorage.verifyAction(calls[current].targetHash); } address target = registry.getServiceAddress(calls[current].targetHash); target.execute(calls[current].callData); } } /** * @notice Not to be called directly * @dev Is called by the Operation Executor via a user's proxy to execute Actions nested in the FlashloanAction * @param calls An array of Action calls the operation must execute */ function callbackAggregate(Call[] memory calls) external { require( msg.sender == registry.getRegisteredService(OPERATION_EXECUTOR), "OpExecutor: Caller forbidden" ); aggregate(calls); } /** * @notice Not to be called directly. * @dev Callback handler for use by a flashloan lender contract. * If the dsProxyFlashloan flag is supplied we reestablish the calling context as the user's proxy (at time of writing DSProxy). Although stored values will * We set the initiator on Operation Storage such that calls originating from other contracts EG Oasis Automation Bot (see https://github.com/OasisDEX/automation-smartcontracts) * The initiator address will be used to store values against the original msg.sender. * This protects against the Operation Storage values being polluted by malicious code from untrusted 3rd party contracts. * @param initiator Is the address of the contract that initiated the flashloan (EG Operation Executor) * @param asset The address of the asset being flash loaned * @param amount The size of the flash loan * @param fee The Fee charged for the loan * @param data Any calldata sent to the contract for execution later in the callback */ function onFlashLoan( address initiator, address asset, uint256 amount, uint256 fee, bytes calldata data ) external override returns (bytes32) { address lender = registry.getRegisteredService(FLASH_MINT_MODULE); require(msg.sender == lender, "Untrusted flashloan lender"); FlashloanData memory flData = abi.decode(data, (FlashloanData)); require(IERC20(asset).balanceOf(address(this)) >= flData.amount, "Flashloan inconsistency"); if (flData.dsProxyFlashloan) { IERC20(asset).safeTransfer(initiator, flData.amount); DSProxy(payable(initiator)).execute( address(this), abi.encodeWithSelector(this.callbackAggregate.selector, flData.calls) ); } else { OperationStorage opStorage = OperationStorage( registry.getRegisteredService(OPERATION_STORAGE) ); opStorage.setInitiator(initiator); aggregate(flData.calls); } uint256 paybackAmount = amount.add(fee); require( IERC20(asset).balanceOf(address(this)) >= paybackAmount, "Insufficient funds for payback" ); IERC20(asset).safeApprove(lender, paybackAmount); return keccak256("ERC3156FlashBorrower.onFlashLoan"); } }
//SPDX-License-Identifier: Unlicense pragma solidity >=0.8.1; /** * @title Service Registry * @notice Stores addresses of deployed contracts */ contract ServiceRegistry { uint256 public constant MAX_DELAY = 30 days; mapping(bytes32 => uint256) public lastExecuted; mapping(bytes32 => address) private namedService; address public owner; uint256 public requiredDelay; modifier validateInput(uint256 len) { require(msg.data.length == len, "registry/illegal-padding"); _; } modifier delayedExecution() { bytes32 operationHash = keccak256(msg.data); uint256 reqDelay = requiredDelay; /* solhint-disable not-rely-on-time */ if (lastExecuted[operationHash] == 0 && reqDelay > 0) { // not called before, scheduled for execution lastExecuted[operationHash] = block.timestamp; emit ChangeScheduled(operationHash, block.timestamp + reqDelay, msg.data); } else { require(block.timestamp - reqDelay > lastExecuted[operationHash], "registry/delay-too-small"); emit ChangeApplied(operationHash, block.timestamp, msg.data); _; lastExecuted[operationHash] = 0; } /* solhint-enable not-rely-on-time */ } modifier onlyOwner() { require(msg.sender == owner, "registry/only-owner"); _; } constructor(uint256 initialDelay) { require(initialDelay <= MAX_DELAY, "registry/invalid-delay"); requiredDelay = initialDelay; owner = msg.sender; } /** * @param newOwner Transfers ownership of the registry to a new address */ function transferOwnership(address newOwner) external onlyOwner validateInput(36) delayedExecution { owner = newOwner; } /** * @param newDelay Updates the required delay before an change can be confirmed with a follow up t/x */ function changeRequiredDelay(uint256 newDelay) external onlyOwner validateInput(36) delayedExecution { require(newDelay <= MAX_DELAY, "registry/invalid-delay"); requiredDelay = newDelay; } /** * @param name Hashes the supplied name * @return Returns the hash of the name */ function getServiceNameHash(string memory name) external pure returns (bytes32) { return keccak256(abi.encodePacked(name)); } /** * @param serviceNameHash The hashed name * @param serviceAddress The address stored for a given name */ function addNamedService(bytes32 serviceNameHash, address serviceAddress) external onlyOwner validateInput(68) delayedExecution { require(namedService[serviceNameHash] == address(0), "registry/service-override"); namedService[serviceNameHash] = serviceAddress; } /** * @param serviceNameHash The hashed name * @param serviceAddress The address to update for a given name */ function updateNamedService(bytes32 serviceNameHash, address serviceAddress) external onlyOwner validateInput(68) delayedExecution { require(namedService[serviceNameHash] != address(0), "registry/service-does-not-exist"); namedService[serviceNameHash] = serviceAddress; } /** * @param serviceNameHash The hashed service name to remove */ function removeNamedService(bytes32 serviceNameHash) external onlyOwner validateInput(36) { require(namedService[serviceNameHash] != address(0), "registry/service-does-not-exist"); namedService[serviceNameHash] = address(0); emit NamedServiceRemoved(serviceNameHash); } /** * @param serviceName Get a service address by its name */ function getRegisteredService(string memory serviceName) external view returns (address) { return namedService[keccak256(abi.encodePacked(serviceName))]; } /** * @param serviceNameHash Get a service address by the hash of its name */ function getServiceAddress(bytes32 serviceNameHash) external view returns (address) { return namedService[serviceNameHash]; } /** * @dev Voids any submitted changes that are yet to be confirmed by a follow-up transaction * @param scheduledExecution Clear any scheduled changes */ function clearScheduledExecution(bytes32 scheduledExecution) external onlyOwner validateInput(36) { require(lastExecuted[scheduledExecution] > 0, "registry/execution-not-scheduled"); lastExecuted[scheduledExecution] = 0; emit ChangeCancelled(scheduledExecution); } event ChangeScheduled(bytes32 dataHash, uint256 scheduledFor, bytes data); event ChangeApplied(bytes32 dataHash, uint256 appliedAt, bytes data); event ChangeCancelled(bytes32 dataHash); event NamedServiceRemoved(bytes32 nameHash); }
pragma solidity ^0.8.15; import { ServiceRegistry } from "./ServiceRegistry.sol"; /** * @title Operation Storage * @notice Stores the return values from Actions during an Operation's execution * @dev valuesHolders is an array of t/x initiators (msg.sender) who have pushed values to Operation Storage * returnValues is a mapping between a msg.sender and an array of Action return values generated by that senders transaction */ contract OperationStorage { uint8 internal action = 0; bytes32[] public actions; mapping(address => bytes32[]) public returnValues; address[] public valuesHolders; bool private locked; address private whoLocked; address public initiator; address immutable operationExecutorAddress; ServiceRegistry internal immutable registry; constructor(ServiceRegistry _registry, address _operationExecutorAddress) { registry = _registry; operationExecutorAddress = _operationExecutorAddress; } /** * @dev Locks storage to protect against re-entrancy attacks.@author */ function lock() external { locked = true; whoLocked = msg.sender; } /** * @dev Only the original locker can unlock the contract at the end of the transaction */ function unlock() external { require(whoLocked == msg.sender, "Only the locker can unlock"); require(locked, "Not locked"); locked = false; whoLocked = address(0); } /** * @dev Sets the initiator of the original call * Is used by Automation Bot branch in the onFlashloan callback in Operation Executor * Ensures that third party calls to Operation Storage do not maliciously override values in Operation Storage * @param _initiator Sets the initiator to Operation Executor contract when storing return values from flashloan nested Action */ function setInitiator(address _initiator) external { require(msg.sender == operationExecutorAddress); initiator = _initiator; } /** * @param _actions Stores the Actions currently being executed for a given Operation */ function setOperationActions(bytes32[] memory _actions) external { actions = _actions; } /** * @param actionHash Checks the current action has against the expected action hash */ function verifyAction(bytes32 actionHash) external { require(actions[action] == actionHash, "incorrect-action"); registry.getServiceAddress(actionHash); action++; } /** * @dev Custom operations have no Actions stored in Operation Registry * @return Returns true / false depending on whether the Operation has any actions to verify the Operation against */ function hasActionsToVerify() external view returns (bool) { return actions.length > 0; } /** * @param value Pushes a bytes32 to end of the returnValues array */ function push(bytes32 value) external { address who = msg.sender; if (who == operationExecutorAddress) { who = initiator; } if (returnValues[who].length == 0) { valuesHolders.push(who); } returnValues[who].push(value); } /** * @dev Values are stored against an address (who) * This ensures that malicious actors looking to push values to Operation Storage mid transaction cannot overwrite values * @param index The index of the desired value * @param who The msg.sender address responsible for storing values */ function at(uint256 index, address who) external view returns (bytes32) { if (who == operationExecutorAddress) { who = initiator; } return returnValues[who][index]; } /** * @param who The msg.sender address responsible for storing values * @return The length of return values stored against a given msg.sender address */ function len(address who) external view returns (uint256) { if (who == operationExecutorAddress) { who = initiator; } return returnValues[who].length; } /** * @dev Clears storage in preparation for the next Operation */ function clearStorage() external { delete action; delete actions; for (uint256 i = 0; i < valuesHolders.length; i++) { delete returnValues[valuesHolders[i]]; } delete valuesHolders; } }
pragma solidity ^0.8.15; import { Operation } from "./types/Common.sol"; import { OPERATIONS_REGISTRY } from "./constants/Common.sol"; struct StoredOperation { bytes32[] actions; string name; } /** * @title Operation Registry * @notice Stores the Actions that constitute a given Operation */ contract OperationsRegistry { mapping(string => StoredOperation) private operations; address public owner; modifier onlyOwner() { require(msg.sender == owner, "only-owner"); _; } constructor() { owner = msg.sender; } /** * @notice Stores the Actions that constitute a given Operation * @param newOwner The address of the new owner of the Operations Registry */ function transferOwnership(address newOwner) public onlyOwner { owner = newOwner; } /** * @dev Emitted when a new operation is added or an existing operation is updated * @param name The Operation name **/ event OperationAdded(string name); /** * @notice Adds an Operation's Actions keyed to a an operation name * @param name The Operation name * @param actions An array the Actions the Operation consists of */ function addOperation(string memory name, bytes32[] memory actions) external onlyOwner { operations[name] = StoredOperation(actions, name); emit OperationAdded(name); } /** * @notice Gets an Operation from the Registry * @param name The name of the Operation * @return actions Returns an array of Actions */ function getOperation(string memory name) external view returns (bytes32[] memory actions) { if (keccak256(bytes(operations[name].name)) == keccak256(bytes(""))) { revert("Operation doesn't exist"); } actions = operations[name].actions; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.15; import "./DSAuth.sol"; import "./DSNote.sol"; abstract contract DSProxy is DSAuth, DSNote { DSProxyCache public cache; // global cache for contracts constructor(address _cacheAddr) { require(setCache(_cacheAddr), "Cache not set"); } // solhint-disable-next-line no-empty-blocks receive() external payable {} // use the proxy to execute calldata _data on contract _code function execute(bytes memory _code, bytes memory _data) public payable virtual returns (address target, bytes32 response); function execute(address _target, bytes memory _data) public payable virtual returns (bytes32 response); //set new cache function setCache(address _cacheAddr) public payable virtual returns (bool); } contract DSProxyCache { mapping(bytes32 => address) cache; function read(bytes memory _code) public view returns (address) { bytes32 hash = keccak256(_code); return cache[hash]; } function write(bytes memory _code) public returns (address target) { assembly { target := create(0, add(_code, 0x20), mload(_code)) switch iszero(extcodesize(target)) case 1 { // throw if contract failed to deploy revert(0, 0) } } bytes32 hash = keccak256(_code); cache[hash] = target; } }
pragma solidity ^0.8.15; import "./Address.sol"; import "../actions/common/Executable.sol"; library ActionAddress { using Address for address; function execute(address action, bytes memory callData) internal { require(isCallingAnExecutable(callData), "OpExecutor: illegal call"); action.functionDelegateCall(callData, "OpExecutor: low-level delegatecall failed"); } function isCallingAnExecutable(bytes memory callData) private pure returns (bool) { bytes4 executeSelector = convertBytesToBytes4( abi.encodeWithSelector(Executable.execute.selector) ); bytes4 selector = convertBytesToBytes4(callData); return selector == executeSelector; } function convertBytesToBytes4(bytes memory inBytes) private pure returns (bytes4 outBytes4) { if (inBytes.length == 0) { return 0x0; } assembly { outBytes4 := mload(add(inBytes, 32)) } } }
pragma solidity ^0.8.15; import { Executable } from "../common/Executable.sol"; import { ServiceRegistry } from "../../core/ServiceRegistry.sol"; import { IERC3156FlashBorrower } from "../../interfaces/flashloan/IERC3156FlashBorrower.sol"; import { IERC3156FlashLender } from "../../interfaces/flashloan/IERC3156FlashLender.sol"; import { FlashloanData } from "../../core/types/Common.sol"; import { OPERATION_EXECUTOR, DAI, TAKE_FLASH_LOAN_ACTION } from "../../core/constants/Common.sol"; import { FLASH_MINT_MODULE } from "../../core/constants/Maker.sol"; import { ProxyPermission } from "../../libs/DS/ProxyPermission.sol"; /** * @title TakeFlashloan Action contract * @notice Executes a sequence of Actions after flashloaning funds */ contract TakeFlashloan is Executable, ProxyPermission { ServiceRegistry internal immutable registry; address internal immutable dai; constructor(ServiceRegistry _registry, address _dai) { registry = _registry; dai = _dai; } /** * @dev When the Flashloan lender calls back the Operation Executor we may need to re-establish the calling context. * @dev The dsProxyFlashloan flag is used to give the Operation Executor temporary authority to call the execute method on a user's proxy * @param data Encoded calldata that conforms to the FlashloanData struct */ function execute(bytes calldata data, uint8[] memory) external payable override { FlashloanData memory flData = parseInputs(data); address operationExecutorAddress = registry.getRegisteredService(OPERATION_EXECUTOR); if (flData.dsProxyFlashloan) { givePermission(operationExecutorAddress); } IERC3156FlashLender(registry.getRegisteredService(FLASH_MINT_MODULE)).flashLoan( IERC3156FlashBorrower(operationExecutorAddress), dai, flData.amount, data ); if (flData.dsProxyFlashloan) { removePermission(operationExecutorAddress); } emit Action(TAKE_FLASH_LOAN_ACTION, bytes32(flData.amount)); } function parseInputs(bytes memory _callData) public pure returns (FlashloanData memory params) { return abi.decode(_callData, (FlashloanData)); } }
pragma solidity ^0.8.15; /** * @title Shared Action Executable interface * @notice Provides a common interface for an execute method to all Action */ interface Executable { function execute(bytes calldata data, uint8[] memory paramsMap) external payable; /** * @dev Emitted once an Action has completed execution * @param name The Action name * @param returned The bytes32 value returned by the Action **/ event Action(string name, bytes32 returned); }
// SPDX-License-Identifier: AGPL-3.0-or-later // Copyright (C) 2021 Dai Foundation // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <https://www.gnu.org/licenses/>. pragma solidity ^0.8.15; interface IERC3156FlashBorrower { /** * @dev Receive a flash loan. * @param initiator The initiator of the loan. * @param token The loan currency. * @param amount The amount of tokens lent. * @param fee The additional amount of tokens to repay. * @param data Arbitrary data structure, intended to contain user-defined parameters. * @return The keccak256 hash of "ERC3156FlashBorrower.onFlashLoan" */ function onFlashLoan( address initiator, address token, uint256 amount, uint256 fee, bytes calldata data ) external returns (bytes32); }
// SPDX-License-Identifier: AGPL-3.0-or-later // Copyright (C) 2021 Dai Foundation // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <https://www.gnu.org/licenses/>. pragma solidity ^0.8.15; import "./IERC3156FlashBorrower.sol"; interface IERC3156FlashLender { /** * @dev The amount of currency available to be lent. * @param token The loan currency. * @return The amount of `token` that can be borrowed. */ function maxFlashLoan(address token) external view returns (uint256); /** * @dev The fee to be charged for a given loan. * @param token The loan currency. * @param amount The amount of tokens lent. * @return The amount of `token` to be charged for the loan, on top of the returned principal. */ function flashFee(address token, uint256 amount) external view returns (uint256); /** * @dev Initiate a flash loan. * @param receiver The receiver of the tokens in the loan, and the receiver of the callback. * @param token The loan currency. * @param amount The amount of tokens lent. * @param data Arbitrary data structure, intended to contain user-defined parameters. */ function flashLoan( IERC3156FlashBorrower receiver, address token, uint256 amount, bytes calldata data ) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.1; import { IERC20 } from "../interfaces/tokens/IERC20.sol"; import { Address } from "./Address.sol"; import { SafeMath } from "./SafeMath.sol"; library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value) ); } /** * @dev Deprecated. This function has issues similar to the ones found in * {ERC20-approve}, and its usage is discouraged. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn( token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance) ); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender).sub( value, "SafeERC20: decreased allowance below zero" ); _callOptionalReturn( token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance) ); } function _callOptionalReturn(IERC20 token, bytes memory data) private { bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.15; library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } }
pragma solidity ^0.8.15; struct FlashloanData { uint256 amount; bool dsProxyFlashloan; Call[] calls; } struct PullTokenData { address asset; address from; uint256 amount; } struct SendTokenData { address asset; address to; uint256 amount; } struct SetApprovalData { address asset; address delegate; uint256 amount; } struct SwapData { address fromAsset; address toAsset; uint256 amount; uint256 receiveAtLeast; uint256 fee; bytes withData; bool collectFeeInFromToken; } struct Call { bytes32 targetHash; bytes callData; } struct Operation { uint8 currentAction; bytes32[] actions; } struct WrapEthData { uint256 amount; } struct UnwrapEthData { uint256 amount; } struct ReturnFundsData { address asset; }
pragma solidity ^0.8.15; string constant OPERATION_STORAGE = "OperationStorage"; string constant OPERATION_EXECUTOR = "OperationExecutor"; string constant OPERATIONS_REGISTRY = "OperationsRegistry"; string constant ONE_INCH_AGGREGATOR = "OneInchAggregator"; string constant WETH = "WETH"; string constant DAI = "DAI"; uint256 constant RAY = 10**27; bytes32 constant NULL = ""; string constant PULL_TOKEN_ACTION = "PullToken"; string constant SEND_TOKEN_ACTION = "SendToken"; string constant SET_APPROVAL_ACTION = "SetApproval"; string constant TAKE_FLASH_LOAN_ACTION = "TakeFlashloan"; string constant WRAP_ETH = "WrapEth"; string constant UNWRAP_ETH = "UnwrapEth"; string constant RETURN_FUNDS_ACTION = "ReturnFunds"; string constant UNISWAP_ROUTER = "UniswapRouter"; string constant SWAP = "Swap"; address constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
pragma solidity ^0.8.15; string constant FLASH_MINT_MODULE = "McdFlashMintModule"; string constant OPEN_VAULT_ACTION = "MakerOpenVault"; string constant DEPOSIT_ACTION = "MakerDeposit"; string constant GENERATE_ACTION = "MakerGenerate"; string constant PAYBACK_ACTION = "MakerPayback"; string constant WITHDRAW_ACTION = "MakerWithdraw"; string constant MCD_MANAGER = "McdManager"; string constant MCD_JUG = "McdJug"; string constant MCD_JOIN_DAI = "McdJoinDai"; string constant CDP_ALLOW = "MakerCdpAllow";
// SPDX-License-Identifier: MIT pragma solidity ^0.8.15; import "./DSAuthority.sol"; contract DSAuthEvents { event LogSetAuthority(address indexed authority); event LogSetOwner(address indexed owner); } contract DSAuth is DSAuthEvents { DSAuthority public authority; address public owner; constructor() { owner = msg.sender; emit LogSetOwner(msg.sender); } function setOwner(address owner_) public auth { owner = owner_; emit LogSetOwner(owner); } function setAuthority(DSAuthority authority_) public auth { authority = authority_; emit LogSetAuthority(address(authority)); } modifier auth() { require(isAuthorized(msg.sender, msg.sig), "Not authorized"); _; } function isAuthorized(address src, bytes4 sig) internal view returns (bool) { if (src == address(this)) { return true; } else if (src == owner) { return true; } else if (authority == DSAuthority(address(0))) { return false; } else { return authority.canCall(src, address(this), sig); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.15; contract DSNote { event LogNote( bytes4 indexed sig, address indexed guy, bytes32 indexed foo, bytes32 indexed bar, uint256 wad, bytes fax ) anonymous; modifier note() { bytes32 foo; bytes32 bar; assembly { foo := calldataload(4) bar := calldataload(36) } emit LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data); _; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.15; abstract contract DSAuthority { function canCall( address src, address dst, bytes4 sig ) public view virtual returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.1; library Address { function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue( address target, bytes memory data, uint256 weiValue, string memory errorMessage ) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); if (success) { return returndata; } if (returndata.length > 0) { assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } revert(errorMessage); } }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.15; import "./DSGuard.sol"; import "./DSAuth.sol"; contract ProxyPermission { address internal constant FACTORY_ADDRESS = 0x5a15566417e6C1c9546523066500bDDBc53F88C7; bytes4 public constant ALLOWED_METHOD_HASH = bytes4(keccak256("execute(address,bytes)")); function givePermission(address _contractAddr) public { address currAuthority = address(DSAuth(address(this)).authority()); DSGuard guard = DSGuard(currAuthority); if (currAuthority == address(0)) { guard = DSGuardFactory(FACTORY_ADDRESS).newGuard(); DSAuth(address(this)).setAuthority(DSAuthority(address(guard))); } if (!guard.canCall(_contractAddr, address(this), ALLOWED_METHOD_HASH)) { guard.permit(_contractAddr, address(this), ALLOWED_METHOD_HASH); } } function removePermission(address _contractAddr) public { address currAuthority = address(DSAuth(address(this)).authority()); if (currAuthority == address(0)) { return; } DSGuard guard = DSGuard(currAuthority); guard.forbid(_contractAddr, address(this), ALLOWED_METHOD_HASH); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.15; abstract contract DSGuard { function canCall( address src_, address dst_, bytes4 sig ) public view virtual returns (bool); function permit( bytes32 src, bytes32 dst, bytes32 sig ) public virtual; function forbid( bytes32 src, bytes32 dst, bytes32 sig ) public virtual; function permit( address src, address dst, bytes32 sig ) public virtual; function forbid( address src, address dst, bytes32 sig ) public virtual; } abstract contract DSGuardFactory { function newGuard() public virtual returns (DSGuard guard); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.15; interface IERC20 { function totalSupply() external view returns (uint256 supply); function balanceOf(address _owner) external view returns (uint256 balance); function transfer(address _to, uint256 _value) external returns (bool success); function transferFrom( address _from, address _to, uint256 _value ) external returns (bool success); function approve(address _spender, uint256 _value) external returns (bool success); function allowance(address _owner, address _spender) external view returns (uint256 remaining); function decimals() external view returns (uint256 digits); }
{ "optimizer": { "enabled": false, "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":"contract ServiceRegistry","name":"_registry","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"name","type":"string"},{"components":[{"internalType":"bytes32","name":"targetHash","type":"bytes32"},{"internalType":"bytes","name":"callData","type":"bytes"}],"indexed":false,"internalType":"struct Call[]","name":"calls","type":"tuple[]"}],"name":"Operation","type":"event"},{"inputs":[{"components":[{"internalType":"bytes32","name":"targetHash","type":"bytes32"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct Call[]","name":"calls","type":"tuple[]"}],"name":"callbackAggregate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"targetHash","type":"bytes32"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct Call[]","name":"calls","type":"tuple[]"},{"internalType":"string","name":"operationName","type":"string"}],"name":"executeOp","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"initiator","type":"address"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onFlashLoan","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"registry","outputs":[{"internalType":"contract ServiceRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b5060405162002baa38038062002baa8339818101604052810190620000379190620000f0565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505062000122565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000a48262000077565b9050919050565b6000620000b88262000097565b9050919050565b620000ca81620000ab565b8114620000d657600080fd5b50565b600081519050620000ea81620000bf565b92915050565b60006020828403121562000109576200010862000072565b5b60006200011984828501620000d9565b91505092915050565b608051612a3c6200016e6000396000818160f601528181610440015281816106b901528181610801015281816108270152818161095a01528181610d090152610eeb0152612a3c6000f3fe60806040526004361061003f5760003560e01c806323e30c8b146100445780634fa0b9ff146100815780637b103999146100aa578063c4a8b32f146100d5575b600080fd5b34801561005057600080fd5b5061006b60048036038101906100669190611763565b6100f1565b6040516100789190611816565b60405180910390f35b34801561008d57600080fd5b506100a860048036038101906100a39190611af5565b6106b7565b005b3480156100b657600080fd5b506100bf6107ff565b6040516100cc9190611b9d565b60405180910390f35b6100ef60048036038101906100ea9190611c0e565b610823565b005b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16630851f3bd6040518060400160405280601281526020017f4d6364466c6173684d696e744d6f64756c6500000000000000000000000000008152506040518263ffffffff1660e01b81526004016101829190611d12565b602060405180830381865afa15801561019f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c39190611d49565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610233576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161022a90611dc2565b60405180910390fd5b600084848101906102449190611e9a565b905080600001518873ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016102849190611ef2565b602060405180830381865afa1580156102a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c59190611f22565b1015610306576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102fd90611f9b565b60405180910390fd5b80602001511561043c5761033f8982600001518a73ffffffffffffffffffffffffffffffffffffffff16610c7f9092919063ffffffff16565b8873ffffffffffffffffffffffffffffffffffffffff16631cff79cd30634fa0b9ff60e01b8460400151604051602401610379919061211e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518363ffffffff1660e01b81526004016103f392919061218a565b6020604051808303816000875af1158015610412573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043691906121cf565b50610589565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16630851f3bd6040518060400160405280601081526020017f4f7065726174696f6e53746f72616765000000000000000000000000000000008152506040518263ffffffff1660e01b81526004016104cc9190611d12565b602060405180830381865afa1580156104e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050d9190611d49565b90508073ffffffffffffffffffffffffffffffffffffffff1663d59dfd618b6040518263ffffffff1660e01b81526004016105489190611ef2565b600060405180830381600087803b15801561056257600080fd5b505af1158015610576573d6000803e3d6000fd5b505050506105878260400151610d05565b505b600061059e878961100490919063ffffffff16565b9050808973ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105da9190611ef2565b602060405180830381865afa1580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190611f22565b101561065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161065390612248565b60405180910390fd5b61068783828b73ffffffffffffffffffffffffffffffffffffffff166110629092919063ffffffff16565b7f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd993505050509695505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16630851f3bd6040518060400160405280601181526020017f4f7065726174696f6e4578656375746f720000000000000000000000000000008152506040518263ffffffff1660e01b81526004016107459190611d12565b602060405180830381865afa158015610762573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107869190611d49565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107ea906122b4565b60405180910390fd5b6107fc81610d05565b50565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16630851f3bd6040518060400160405280601081526020017f4f7065726174696f6e53746f72616765000000000000000000000000000000008152506040518263ffffffff1660e01b81526004016108b39190611d12565b602060405180830381865afa1580156108d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f49190611d49565b90508073ffffffffffffffffffffffffffffffffffffffff1663f83d08ba6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561093e57600080fd5b505af1158015610952573d6000803e3d6000fd5b5050505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16630851f3bd6040518060400160405280601281526020017f4f7065726174696f6e73526567697374727900000000000000000000000000008152506040518263ffffffff1660e01b81526004016109e69190611d12565b602060405180830381865afa158015610a03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a279190611d49565b90508173ffffffffffffffffffffffffffffffffffffffff166369bd38a06040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610a7157600080fd5b505af1158015610a85573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff1663b082cbfc8273ffffffffffffffffffffffffffffffffffffffff16631fffb05c87876040518363ffffffff1660e01b8152600401610ae0929190612301565b600060405180830381865afa158015610afd573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610b2691906123e8565b6040518263ffffffff1660e01b8152600401610b4291906124e0565b600060405180830381600087803b158015610b5c57600080fd5b505af1158015610b70573d6000803e3d6000fd5b50505050610b7d85610d05565b8173ffffffffffffffffffffffffffffffffffffffff166369bd38a06040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610bc557600080fd5b505af1158015610bd9573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff1663a69df4b56040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610c2557600080fd5b505af1158015610c39573d6000803e3d6000fd5b505050507fcc558ab90a763767f0ca2c8bd53b5dcad35d2a3da3e5bd6e585b48ae8f4210ab848487604051610c7093929190612502565b60405180910390a15050505050565b610d008363a9059cbb60e01b8484604051602401610c9e92919061254a565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061116a565b505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16630851f3bd6040518060400160405280601081526020017f4f7065726174696f6e53746f72616765000000000000000000000000000000008152506040518263ffffffff1660e01b8152600401610d959190611d12565b602060405180830381865afa158015610db2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd69190611d49565b905060008173ffffffffffffffffffffffffffffffffffffffff16634b1824a46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e499190612588565b905060005b8351811015610ffe578115610ee7578273ffffffffffffffffffffffffffffffffffffffff16638abe863c858381518110610e8c57610e8b6125b5565b5b6020026020010151600001516040518263ffffffff1660e01b8152600401610eb49190611816565b600060405180830381600087803b158015610ece57600080fd5b505af1158015610ee2573d6000803e3d6000fd5b505050505b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663c2527b32868481518110610f3857610f376125b5565b5b6020026020010151600001516040518263ffffffff1660e01b8152600401610f609190611816565b602060405180830381865afa158015610f7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa19190611d49565b9050610fea858381518110610fb957610fb86125b5565b5b6020026020010151602001518273ffffffffffffffffffffffffffffffffffffffff1661123190919063ffffffff16565b508080610ff690612613565b915050610e4e565b50505050565b6000808284611013919061265b565b905083811015611058576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104f906126fd565b60405180910390fd5b8091505092915050565b6110e48363095ea7b360e01b846000604051602401611082929190612765565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061116a565b6111658363095ea7b360e01b848460405160240161110392919061254a565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061116a565b505050565b60006111cc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166112c19092919063ffffffff16565b905060008151111561122c57808060200190518101906111ec9190612588565b61122b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161122290612800565b60405180910390fd5b5b505050565b61123a816112d9565b611279576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112709061286c565b60405180910390fd5b6112bc816040518060600160405280602981526020016129de602991398473ffffffffffffffffffffffffffffffffffffffff166113a89092919063ffffffff16565b505050565b60606112d084846000856114c6565b90509392505050565b60008061134f6385e92d9860e01b604051602401604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506115e8565b9050600061135c846115e8565b9050817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161492505050919050565b60606113b38461160b565b6113f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113e9906128fe565b60405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168560405161141a919061295a565b600060405180830381855af49150503d8060008114611455576040519150601f19603f3d011682016040523d82523d6000602084013e61145a565b606091505b5091509150811561146f5780925050506114bf565b6000815111156114825780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114b69190611d12565b60405180910390fd5b9392505050565b60606114d18561160b565b611510576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611507906129bd565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611539919061295a565b60006040518083038185875af1925050503d8060008114611576576040519150601f19603f3d011682016040523d82523d6000602084013e61157b565b606091505b509150915081156115905780925050506115e0565b6000815111156115a35780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115d79190611d12565b60405180910390fd5b949350505050565b6000808251036115fe57600060e01b9050611606565b602082015190505b919050565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f915080821415801561164d57506000801b8214155b92505050919050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006116958261166a565b9050919050565b6116a58161168a565b81146116b057600080fd5b50565b6000813590506116c28161169c565b92915050565b6000819050919050565b6116db816116c8565b81146116e657600080fd5b50565b6000813590506116f8816116d2565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611723576117226116fe565b5b8235905067ffffffffffffffff8111156117405761173f611703565b5b60208301915083600182028301111561175c5761175b611708565b5b9250929050565b60008060008060008060a087890312156117805761177f611660565b5b600061178e89828a016116b3565b965050602061179f89828a016116b3565b95505060406117b089828a016116e9565b94505060606117c189828a016116e9565b935050608087013567ffffffffffffffff8111156117e2576117e1611665565b5b6117ee89828a0161170d565b92509250509295509295509295565b6000819050919050565b611810816117fd565b82525050565b600060208201905061182b6000830184611807565b92915050565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61187a82611831565b810181811067ffffffffffffffff8211171561189957611898611842565b5b80604052505050565b60006118ac611656565b90506118b88282611871565b919050565b600067ffffffffffffffff8211156118d8576118d7611842565b5b602082029050602081019050919050565b600080fd5b600080fd5b6118fc816117fd565b811461190757600080fd5b50565b600081359050611919816118f3565b92915050565b600080fd5b600067ffffffffffffffff82111561193f5761193e611842565b5b61194882611831565b9050602081019050919050565b82818337600083830152505050565b600061197761197284611924565b6118a2565b9050828152602081018484840111156119935761199261191f565b5b61199e848285611955565b509392505050565b600082601f8301126119bb576119ba6116fe565b5b81356119cb848260208601611964565b91505092915050565b6000604082840312156119ea576119e96118e9565b5b6119f460406118a2565b90506000611a048482850161190a565b600083015250602082013567ffffffffffffffff811115611a2857611a276118ee565b5b611a34848285016119a6565b60208301525092915050565b6000611a53611a4e846118bd565b6118a2565b90508083825260208201905060208402830185811115611a7657611a75611708565b5b835b81811015611abd57803567ffffffffffffffff811115611a9b57611a9a6116fe565b5b808601611aa889826119d4565b85526020850194505050602081019050611a78565b5050509392505050565b600082601f830112611adc57611adb6116fe565b5b8135611aec848260208601611a40565b91505092915050565b600060208284031215611b0b57611b0a611660565b5b600082013567ffffffffffffffff811115611b2957611b28611665565b5b611b3584828501611ac7565b91505092915050565b6000819050919050565b6000611b63611b5e611b598461166a565b611b3e565b61166a565b9050919050565b6000611b7582611b48565b9050919050565b6000611b8782611b6a565b9050919050565b611b9781611b7c565b82525050565b6000602082019050611bb26000830184611b8e565b92915050565b60008083601f840112611bce57611bcd6116fe565b5b8235905067ffffffffffffffff811115611beb57611bea611703565b5b602083019150836001820283011115611c0757611c06611708565b5b9250929050565b600080600060408486031215611c2757611c26611660565b5b600084013567ffffffffffffffff811115611c4557611c44611665565b5b611c5186828701611ac7565b935050602084013567ffffffffffffffff811115611c7257611c71611665565b5b611c7e86828701611bb8565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b60005b83811015611cc4578082015181840152602081019050611ca9565b83811115611cd3576000848401525b50505050565b6000611ce482611c8a565b611cee8185611c95565b9350611cfe818560208601611ca6565b611d0781611831565b840191505092915050565b60006020820190508181036000830152611d2c8184611cd9565b905092915050565b600081519050611d438161169c565b92915050565b600060208284031215611d5f57611d5e611660565b5b6000611d6d84828501611d34565b91505092915050565b7f556e7472757374656420666c6173686c6f616e206c656e646572000000000000600082015250565b6000611dac601a83611c95565b9150611db782611d76565b602082019050919050565b60006020820190508181036000830152611ddb81611d9f565b9050919050565b60008115159050919050565b611df781611de2565b8114611e0257600080fd5b50565b600081359050611e1481611dee565b92915050565b600060608284031215611e3057611e2f6118e9565b5b611e3a60606118a2565b90506000611e4a848285016116e9565b6000830152506020611e5e84828501611e05565b602083015250604082013567ffffffffffffffff811115611e8257611e816118ee565b5b611e8e84828501611ac7565b60408301525092915050565b600060208284031215611eb057611eaf611660565b5b600082013567ffffffffffffffff811115611ece57611ecd611665565b5b611eda84828501611e1a565b91505092915050565b611eec8161168a565b82525050565b6000602082019050611f076000830184611ee3565b92915050565b600081519050611f1c816116d2565b92915050565b600060208284031215611f3857611f37611660565b5b6000611f4684828501611f0d565b91505092915050565b7f466c6173686c6f616e20696e636f6e73697374656e6379000000000000000000600082015250565b6000611f85601783611c95565b9150611f9082611f4f565b602082019050919050565b60006020820190508181036000830152611fb481611f78565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611ff0816117fd565b82525050565b600081519050919050565b600082825260208201905092915050565b600061201d82611ff6565b6120278185612001565b9350612037818560208601611ca6565b61204081611831565b840191505092915050565b60006040830160008301516120636000860182611fe7565b506020830151848203602086015261207b8282612012565b9150508091505092915050565b6000612094838361204b565b905092915050565b6000602082019050919050565b60006120b482611fbb565b6120be8185611fc6565b9350836020820285016120d085611fd7565b8060005b8581101561210c57848403895281516120ed8582612088565b94506120f88361209c565b925060208a019950506001810190506120d4565b50829750879550505050505092915050565b6000602082019050818103600083015261213881846120a9565b905092915050565b600082825260208201905092915050565b600061215c82611ff6565b6121668185612140565b9350612176818560208601611ca6565b61217f81611831565b840191505092915050565b600060408201905061219f6000830185611ee3565b81810360208301526121b18184612151565b90509392505050565b6000815190506121c9816118f3565b92915050565b6000602082840312156121e5576121e4611660565b5b60006121f3848285016121ba565b91505092915050565b7f496e73756666696369656e742066756e647320666f72207061796261636b0000600082015250565b6000612232601e83611c95565b915061223d826121fc565b602082019050919050565b6000602082019050818103600083015261226181612225565b9050919050565b7f4f704578656375746f723a2043616c6c657220666f7262696464656e00000000600082015250565b600061229e601c83611c95565b91506122a982612268565b602082019050919050565b600060208201905081810360008301526122cd81612291565b9050919050565b60006122e08385611c95565b93506122ed838584611955565b6122f683611831565b840190509392505050565b6000602082019050818103600083015261231c8184866122d4565b90509392505050565b600067ffffffffffffffff8211156123405761233f611842565b5b602082029050602081019050919050565b600061236461235f84612325565b6118a2565b9050808382526020820190506020840283018581111561238757612386611708565b5b835b818110156123b0578061239c88826121ba565b845260208401935050602081019050612389565b5050509392505050565b600082601f8301126123cf576123ce6116fe565b5b81516123df848260208601612351565b91505092915050565b6000602082840312156123fe576123fd611660565b5b600082015167ffffffffffffffff81111561241c5761241b611665565b5b612428848285016123ba565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006124698383611fe7565b60208301905092915050565b6000602082019050919050565b600061248d82612431565b612497818561243c565b93506124a28361244d565b8060005b838110156124d35781516124ba888261245d565b97506124c583612475565b9250506001810190506124a6565b5085935050505092915050565b600060208201905081810360008301526124fa8184612482565b905092915050565b6000604082019050818103600083015261251d8185876122d4565b9050818103602083015261253181846120a9565b9050949350505050565b612544816116c8565b82525050565b600060408201905061255f6000830185611ee3565b61256c602083018461253b565b9392505050565b60008151905061258281611dee565b92915050565b60006020828403121561259e5761259d611660565b5b60006125ac84828501612573565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061261e826116c8565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036126505761264f6125e4565b5b600182019050919050565b6000612666826116c8565b9150612671836116c8565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156126a6576126a56125e4565b5b828201905092915050565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000600082015250565b60006126e7601b83611c95565b91506126f2826126b1565b602082019050919050565b60006020820190508181036000830152612716816126da565b9050919050565b6000819050919050565b600060ff82169050919050565b600061274f61274a6127458461271d565b611b3e565b612727565b9050919050565b61275f81612734565b82525050565b600060408201905061277a6000830185611ee3565b6127876020830184612756565b9392505050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b60006127ea602a83611c95565b91506127f58261278e565b604082019050919050565b60006020820190508181036000830152612819816127dd565b9050919050565b7f4f704578656375746f723a20696c6c6567616c2063616c6c0000000000000000600082015250565b6000612856601883611c95565b915061286182612820565b602082019050919050565b6000602082019050818103600083015261288581612849565b9050919050565b7f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60008201527f6e74726163740000000000000000000000000000000000000000000000000000602082015250565b60006128e8602683611c95565b91506128f38261288c565b604082019050919050565b60006020820190508181036000830152612917816128db565b9050919050565b600081905092915050565b600061293482611ff6565b61293e818561291e565b935061294e818560208601611ca6565b80840191505092915050565b60006129668284612929565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b60006129a7601d83611c95565b91506129b282612971565b602082019050919050565b600060208201905081810360008301526129d68161299a565b905091905056fe4f704578656375746f723a206c6f772d6c6576656c2064656c656761746563616c6c206661696c6564a2646970667358221220ed9d43a5b4a9bd69ea5ac17fb51616fa6fb15f22ca68403ac5d00789beb9090064736f6c634300080f00330000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada
Deployed Bytecode
0x60806040526004361061003f5760003560e01c806323e30c8b146100445780634fa0b9ff146100815780637b103999146100aa578063c4a8b32f146100d5575b600080fd5b34801561005057600080fd5b5061006b60048036038101906100669190611763565b6100f1565b6040516100789190611816565b60405180910390f35b34801561008d57600080fd5b506100a860048036038101906100a39190611af5565b6106b7565b005b3480156100b657600080fd5b506100bf6107ff565b6040516100cc9190611b9d565b60405180910390f35b6100ef60048036038101906100ea9190611c0e565b610823565b005b6000807f0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada73ffffffffffffffffffffffffffffffffffffffff16630851f3bd6040518060400160405280601281526020017f4d6364466c6173684d696e744d6f64756c6500000000000000000000000000008152506040518263ffffffff1660e01b81526004016101829190611d12565b602060405180830381865afa15801561019f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c39190611d49565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610233576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161022a90611dc2565b60405180910390fd5b600084848101906102449190611e9a565b905080600001518873ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016102849190611ef2565b602060405180830381865afa1580156102a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c59190611f22565b1015610306576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102fd90611f9b565b60405180910390fd5b80602001511561043c5761033f8982600001518a73ffffffffffffffffffffffffffffffffffffffff16610c7f9092919063ffffffff16565b8873ffffffffffffffffffffffffffffffffffffffff16631cff79cd30634fa0b9ff60e01b8460400151604051602401610379919061211e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518363ffffffff1660e01b81526004016103f392919061218a565b6020604051808303816000875af1158015610412573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043691906121cf565b50610589565b60007f0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada73ffffffffffffffffffffffffffffffffffffffff16630851f3bd6040518060400160405280601081526020017f4f7065726174696f6e53746f72616765000000000000000000000000000000008152506040518263ffffffff1660e01b81526004016104cc9190611d12565b602060405180830381865afa1580156104e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050d9190611d49565b90508073ffffffffffffffffffffffffffffffffffffffff1663d59dfd618b6040518263ffffffff1660e01b81526004016105489190611ef2565b600060405180830381600087803b15801561056257600080fd5b505af1158015610576573d6000803e3d6000fd5b505050506105878260400151610d05565b505b600061059e878961100490919063ffffffff16565b9050808973ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105da9190611ef2565b602060405180830381865afa1580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190611f22565b101561065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161065390612248565b60405180910390fd5b61068783828b73ffffffffffffffffffffffffffffffffffffffff166110629092919063ffffffff16565b7f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd993505050509695505050505050565b7f0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada73ffffffffffffffffffffffffffffffffffffffff16630851f3bd6040518060400160405280601181526020017f4f7065726174696f6e4578656375746f720000000000000000000000000000008152506040518263ffffffff1660e01b81526004016107459190611d12565b602060405180830381865afa158015610762573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107869190611d49565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107ea906122b4565b60405180910390fd5b6107fc81610d05565b50565b7f0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada81565b60007f0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada73ffffffffffffffffffffffffffffffffffffffff16630851f3bd6040518060400160405280601081526020017f4f7065726174696f6e53746f72616765000000000000000000000000000000008152506040518263ffffffff1660e01b81526004016108b39190611d12565b602060405180830381865afa1580156108d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f49190611d49565b90508073ffffffffffffffffffffffffffffffffffffffff1663f83d08ba6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561093e57600080fd5b505af1158015610952573d6000803e3d6000fd5b5050505060007f0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada73ffffffffffffffffffffffffffffffffffffffff16630851f3bd6040518060400160405280601281526020017f4f7065726174696f6e73526567697374727900000000000000000000000000008152506040518263ffffffff1660e01b81526004016109e69190611d12565b602060405180830381865afa158015610a03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a279190611d49565b90508173ffffffffffffffffffffffffffffffffffffffff166369bd38a06040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610a7157600080fd5b505af1158015610a85573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff1663b082cbfc8273ffffffffffffffffffffffffffffffffffffffff16631fffb05c87876040518363ffffffff1660e01b8152600401610ae0929190612301565b600060405180830381865afa158015610afd573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610b2691906123e8565b6040518263ffffffff1660e01b8152600401610b4291906124e0565b600060405180830381600087803b158015610b5c57600080fd5b505af1158015610b70573d6000803e3d6000fd5b50505050610b7d85610d05565b8173ffffffffffffffffffffffffffffffffffffffff166369bd38a06040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610bc557600080fd5b505af1158015610bd9573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff1663a69df4b56040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610c2557600080fd5b505af1158015610c39573d6000803e3d6000fd5b505050507fcc558ab90a763767f0ca2c8bd53b5dcad35d2a3da3e5bd6e585b48ae8f4210ab848487604051610c7093929190612502565b60405180910390a15050505050565b610d008363a9059cbb60e01b8484604051602401610c9e92919061254a565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061116a565b505050565b60007f0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada73ffffffffffffffffffffffffffffffffffffffff16630851f3bd6040518060400160405280601081526020017f4f7065726174696f6e53746f72616765000000000000000000000000000000008152506040518263ffffffff1660e01b8152600401610d959190611d12565b602060405180830381865afa158015610db2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd69190611d49565b905060008173ffffffffffffffffffffffffffffffffffffffff16634b1824a46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e499190612588565b905060005b8351811015610ffe578115610ee7578273ffffffffffffffffffffffffffffffffffffffff16638abe863c858381518110610e8c57610e8b6125b5565b5b6020026020010151600001516040518263ffffffff1660e01b8152600401610eb49190611816565b600060405180830381600087803b158015610ece57600080fd5b505af1158015610ee2573d6000803e3d6000fd5b505050505b60007f0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada73ffffffffffffffffffffffffffffffffffffffff1663c2527b32868481518110610f3857610f376125b5565b5b6020026020010151600001516040518263ffffffff1660e01b8152600401610f609190611816565b602060405180830381865afa158015610f7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa19190611d49565b9050610fea858381518110610fb957610fb86125b5565b5b6020026020010151602001518273ffffffffffffffffffffffffffffffffffffffff1661123190919063ffffffff16565b508080610ff690612613565b915050610e4e565b50505050565b6000808284611013919061265b565b905083811015611058576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104f906126fd565b60405180910390fd5b8091505092915050565b6110e48363095ea7b360e01b846000604051602401611082929190612765565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061116a565b6111658363095ea7b360e01b848460405160240161110392919061254a565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061116a565b505050565b60006111cc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166112c19092919063ffffffff16565b905060008151111561122c57808060200190518101906111ec9190612588565b61122b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161122290612800565b60405180910390fd5b5b505050565b61123a816112d9565b611279576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112709061286c565b60405180910390fd5b6112bc816040518060600160405280602981526020016129de602991398473ffffffffffffffffffffffffffffffffffffffff166113a89092919063ffffffff16565b505050565b60606112d084846000856114c6565b90509392505050565b60008061134f6385e92d9860e01b604051602401604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506115e8565b9050600061135c846115e8565b9050817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161492505050919050565b60606113b38461160b565b6113f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113e9906128fe565b60405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168560405161141a919061295a565b600060405180830381855af49150503d8060008114611455576040519150601f19603f3d011682016040523d82523d6000602084013e61145a565b606091505b5091509150811561146f5780925050506114bf565b6000815111156114825780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114b69190611d12565b60405180910390fd5b9392505050565b60606114d18561160b565b611510576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611507906129bd565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611539919061295a565b60006040518083038185875af1925050503d8060008114611576576040519150601f19603f3d011682016040523d82523d6000602084013e61157b565b606091505b509150915081156115905780925050506115e0565b6000815111156115a35780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115d79190611d12565b60405180910390fd5b949350505050565b6000808251036115fe57600060e01b9050611606565b602082015190505b919050565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f915080821415801561164d57506000801b8214155b92505050919050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006116958261166a565b9050919050565b6116a58161168a565b81146116b057600080fd5b50565b6000813590506116c28161169c565b92915050565b6000819050919050565b6116db816116c8565b81146116e657600080fd5b50565b6000813590506116f8816116d2565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611723576117226116fe565b5b8235905067ffffffffffffffff8111156117405761173f611703565b5b60208301915083600182028301111561175c5761175b611708565b5b9250929050565b60008060008060008060a087890312156117805761177f611660565b5b600061178e89828a016116b3565b965050602061179f89828a016116b3565b95505060406117b089828a016116e9565b94505060606117c189828a016116e9565b935050608087013567ffffffffffffffff8111156117e2576117e1611665565b5b6117ee89828a0161170d565b92509250509295509295509295565b6000819050919050565b611810816117fd565b82525050565b600060208201905061182b6000830184611807565b92915050565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61187a82611831565b810181811067ffffffffffffffff8211171561189957611898611842565b5b80604052505050565b60006118ac611656565b90506118b88282611871565b919050565b600067ffffffffffffffff8211156118d8576118d7611842565b5b602082029050602081019050919050565b600080fd5b600080fd5b6118fc816117fd565b811461190757600080fd5b50565b600081359050611919816118f3565b92915050565b600080fd5b600067ffffffffffffffff82111561193f5761193e611842565b5b61194882611831565b9050602081019050919050565b82818337600083830152505050565b600061197761197284611924565b6118a2565b9050828152602081018484840111156119935761199261191f565b5b61199e848285611955565b509392505050565b600082601f8301126119bb576119ba6116fe565b5b81356119cb848260208601611964565b91505092915050565b6000604082840312156119ea576119e96118e9565b5b6119f460406118a2565b90506000611a048482850161190a565b600083015250602082013567ffffffffffffffff811115611a2857611a276118ee565b5b611a34848285016119a6565b60208301525092915050565b6000611a53611a4e846118bd565b6118a2565b90508083825260208201905060208402830185811115611a7657611a75611708565b5b835b81811015611abd57803567ffffffffffffffff811115611a9b57611a9a6116fe565b5b808601611aa889826119d4565b85526020850194505050602081019050611a78565b5050509392505050565b600082601f830112611adc57611adb6116fe565b5b8135611aec848260208601611a40565b91505092915050565b600060208284031215611b0b57611b0a611660565b5b600082013567ffffffffffffffff811115611b2957611b28611665565b5b611b3584828501611ac7565b91505092915050565b6000819050919050565b6000611b63611b5e611b598461166a565b611b3e565b61166a565b9050919050565b6000611b7582611b48565b9050919050565b6000611b8782611b6a565b9050919050565b611b9781611b7c565b82525050565b6000602082019050611bb26000830184611b8e565b92915050565b60008083601f840112611bce57611bcd6116fe565b5b8235905067ffffffffffffffff811115611beb57611bea611703565b5b602083019150836001820283011115611c0757611c06611708565b5b9250929050565b600080600060408486031215611c2757611c26611660565b5b600084013567ffffffffffffffff811115611c4557611c44611665565b5b611c5186828701611ac7565b935050602084013567ffffffffffffffff811115611c7257611c71611665565b5b611c7e86828701611bb8565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b60005b83811015611cc4578082015181840152602081019050611ca9565b83811115611cd3576000848401525b50505050565b6000611ce482611c8a565b611cee8185611c95565b9350611cfe818560208601611ca6565b611d0781611831565b840191505092915050565b60006020820190508181036000830152611d2c8184611cd9565b905092915050565b600081519050611d438161169c565b92915050565b600060208284031215611d5f57611d5e611660565b5b6000611d6d84828501611d34565b91505092915050565b7f556e7472757374656420666c6173686c6f616e206c656e646572000000000000600082015250565b6000611dac601a83611c95565b9150611db782611d76565b602082019050919050565b60006020820190508181036000830152611ddb81611d9f565b9050919050565b60008115159050919050565b611df781611de2565b8114611e0257600080fd5b50565b600081359050611e1481611dee565b92915050565b600060608284031215611e3057611e2f6118e9565b5b611e3a60606118a2565b90506000611e4a848285016116e9565b6000830152506020611e5e84828501611e05565b602083015250604082013567ffffffffffffffff811115611e8257611e816118ee565b5b611e8e84828501611ac7565b60408301525092915050565b600060208284031215611eb057611eaf611660565b5b600082013567ffffffffffffffff811115611ece57611ecd611665565b5b611eda84828501611e1a565b91505092915050565b611eec8161168a565b82525050565b6000602082019050611f076000830184611ee3565b92915050565b600081519050611f1c816116d2565b92915050565b600060208284031215611f3857611f37611660565b5b6000611f4684828501611f0d565b91505092915050565b7f466c6173686c6f616e20696e636f6e73697374656e6379000000000000000000600082015250565b6000611f85601783611c95565b9150611f9082611f4f565b602082019050919050565b60006020820190508181036000830152611fb481611f78565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611ff0816117fd565b82525050565b600081519050919050565b600082825260208201905092915050565b600061201d82611ff6565b6120278185612001565b9350612037818560208601611ca6565b61204081611831565b840191505092915050565b60006040830160008301516120636000860182611fe7565b506020830151848203602086015261207b8282612012565b9150508091505092915050565b6000612094838361204b565b905092915050565b6000602082019050919050565b60006120b482611fbb565b6120be8185611fc6565b9350836020820285016120d085611fd7565b8060005b8581101561210c57848403895281516120ed8582612088565b94506120f88361209c565b925060208a019950506001810190506120d4565b50829750879550505050505092915050565b6000602082019050818103600083015261213881846120a9565b905092915050565b600082825260208201905092915050565b600061215c82611ff6565b6121668185612140565b9350612176818560208601611ca6565b61217f81611831565b840191505092915050565b600060408201905061219f6000830185611ee3565b81810360208301526121b18184612151565b90509392505050565b6000815190506121c9816118f3565b92915050565b6000602082840312156121e5576121e4611660565b5b60006121f3848285016121ba565b91505092915050565b7f496e73756666696369656e742066756e647320666f72207061796261636b0000600082015250565b6000612232601e83611c95565b915061223d826121fc565b602082019050919050565b6000602082019050818103600083015261226181612225565b9050919050565b7f4f704578656375746f723a2043616c6c657220666f7262696464656e00000000600082015250565b600061229e601c83611c95565b91506122a982612268565b602082019050919050565b600060208201905081810360008301526122cd81612291565b9050919050565b60006122e08385611c95565b93506122ed838584611955565b6122f683611831565b840190509392505050565b6000602082019050818103600083015261231c8184866122d4565b90509392505050565b600067ffffffffffffffff8211156123405761233f611842565b5b602082029050602081019050919050565b600061236461235f84612325565b6118a2565b9050808382526020820190506020840283018581111561238757612386611708565b5b835b818110156123b0578061239c88826121ba565b845260208401935050602081019050612389565b5050509392505050565b600082601f8301126123cf576123ce6116fe565b5b81516123df848260208601612351565b91505092915050565b6000602082840312156123fe576123fd611660565b5b600082015167ffffffffffffffff81111561241c5761241b611665565b5b612428848285016123ba565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006124698383611fe7565b60208301905092915050565b6000602082019050919050565b600061248d82612431565b612497818561243c565b93506124a28361244d565b8060005b838110156124d35781516124ba888261245d565b97506124c583612475565b9250506001810190506124a6565b5085935050505092915050565b600060208201905081810360008301526124fa8184612482565b905092915050565b6000604082019050818103600083015261251d8185876122d4565b9050818103602083015261253181846120a9565b9050949350505050565b612544816116c8565b82525050565b600060408201905061255f6000830185611ee3565b61256c602083018461253b565b9392505050565b60008151905061258281611dee565b92915050565b60006020828403121561259e5761259d611660565b5b60006125ac84828501612573565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061261e826116c8565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036126505761264f6125e4565b5b600182019050919050565b6000612666826116c8565b9150612671836116c8565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156126a6576126a56125e4565b5b828201905092915050565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000600082015250565b60006126e7601b83611c95565b91506126f2826126b1565b602082019050919050565b60006020820190508181036000830152612716816126da565b9050919050565b6000819050919050565b600060ff82169050919050565b600061274f61274a6127458461271d565b611b3e565b612727565b9050919050565b61275f81612734565b82525050565b600060408201905061277a6000830185611ee3565b6127876020830184612756565b9392505050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b60006127ea602a83611c95565b91506127f58261278e565b604082019050919050565b60006020820190508181036000830152612819816127dd565b9050919050565b7f4f704578656375746f723a20696c6c6567616c2063616c6c0000000000000000600082015250565b6000612856601883611c95565b915061286182612820565b602082019050919050565b6000602082019050818103600083015261288581612849565b9050919050565b7f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60008201527f6e74726163740000000000000000000000000000000000000000000000000000602082015250565b60006128e8602683611c95565b91506128f38261288c565b604082019050919050565b60006020820190508181036000830152612917816128db565b9050919050565b600081905092915050565b600061293482611ff6565b61293e818561291e565b935061294e818560208601611ca6565b80840191505092915050565b60006129668284612929565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b60006129a7601d83611c95565b91506129b282612971565b602082019050919050565b600060208201905081810360008301526129d68161299a565b905091905056fe4f704578656375746f723a206c6f772d6c6576656c2064656c656761746563616c6c206661696c6564a2646970667358221220ed9d43a5b4a9bd69ea5ac17fb51616fa6fb15f22ca68403ac5d00789beb9090064736f6c634300080f0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada
-----Decoded View---------------
Arg [0] : _registry (address): 0x9b4Ae7b164d195df9C4Da5d08Be88b2848b2EaDA
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
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.