Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60a06040 | 15477899 | 809 days ago | IN | 0 ETH | 0.01797779 |
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 Name:
BasicBuyCommand
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
Yes with 1000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0-or-later /// BasicBuyCommand.sol // Copyright (C) 2021-2021 Oazo Apps Limited // 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.0; import { SafeMath } from "@openzeppelin/contracts/utils/math/SafeMath.sol"; import { ManagerLike } from "../interfaces/ManagerLike.sol"; import { MPALike } from "../interfaces/MPALike.sol"; import { SpotterLike } from "../interfaces/SpotterLike.sol"; import { RatioUtils } from "../libs/RatioUtils.sol"; import { ServiceRegistry } from "../ServiceRegistry.sol"; import { McdView } from "../McdView.sol"; import { BaseMPACommand } from "./BaseMPACommand.sol"; contract BasicBuyCommand is BaseMPACommand { using SafeMath for uint256; using RatioUtils for uint256; struct BasicBuyTriggerData { uint256 cdpId; uint16 triggerType; uint256 execCollRatio; uint256 targetCollRatio; uint256 maxBuyPrice; bool continuous; uint64 deviation; uint32 maxBaseFeeInGwei; } constructor(ServiceRegistry _serviceRegistry) BaseMPACommand(_serviceRegistry) {} function decode(bytes memory triggerData) public pure returns (BasicBuyTriggerData memory) { return abi.decode(triggerData, (BasicBuyTriggerData)); } function isTriggerDataValid(uint256 _cdpId, bytes memory triggerData) external view returns (bool) { BasicBuyTriggerData memory trigger = decode(triggerData); ManagerLike manager = ManagerLike(serviceRegistry.getRegisteredService(CDP_MANAGER_KEY)); bytes32 ilk = manager.ilks(trigger.cdpId); SpotterLike spot = SpotterLike(serviceRegistry.getRegisteredService(MCD_SPOT_KEY)); (, uint256 liquidationRatio) = spot.ilks(ilk); (uint256 lowerTarget, uint256 upperTarget) = trigger.targetCollRatio.bounds( trigger.deviation ); return _cdpId == trigger.cdpId && trigger.triggerType == 3 && trigger.execCollRatio > upperTarget && lowerTarget.ray() > liquidationRatio && deviationIsValid(trigger.deviation); } function isExecutionLegal(uint256 cdpId, bytes memory triggerData) external view returns (bool) { BasicBuyTriggerData memory trigger = decode(triggerData); ( , uint256 nextCollRatio, uint256 currPrice, uint256 nextPrice, bytes32 ilk ) = getVaultAndMarketInfo(cdpId); SpotterLike spot = SpotterLike(serviceRegistry.getRegisteredService(MCD_SPOT_KEY)); (, uint256 liquidationRatio) = spot.ilks(ilk); return nextCollRatio >= trigger.execCollRatio.wad() && nextPrice <= trigger.maxBuyPrice && trigger.targetCollRatio.wad().mul(currPrice).div(nextPrice) > liquidationRatio.rayToWad() && baseFeeIsValid(trigger.maxBaseFeeInGwei); } function execute( bytes calldata executionData, uint256 cdpId, bytes memory triggerData ) external { BasicBuyTriggerData memory trigger = decode(triggerData); validateTriggerType(trigger.triggerType, 3); validateSelector(MPALike.increaseMultiple.selector, executionData); executeMPAMethod(executionData); if (trigger.continuous) { recreateTrigger(cdpId, trigger.triggerType, triggerData); } } function isExecutionCorrect(uint256 cdpId, bytes memory triggerData) external view returns (bool) { BasicBuyTriggerData memory trigger = decode(triggerData); McdView mcdView = McdView(serviceRegistry.getRegisteredService(MCD_VIEW_KEY)); uint256 nextCollRatio = mcdView.getRatio(cdpId, true); (uint256 lowerTarget, uint256 upperTarget) = trigger.targetCollRatio.bounds( trigger.deviation ); return nextCollRatio <= upperTarget.wad() && nextCollRatio >= lowerTarget.wad(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol) pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; interface ManagerLike { function cdpCan( address owner, uint256 cdpId, address allowedAddr ) external view returns (uint256); function vat() external view returns (address); function ilks(uint256) external view returns (bytes32); function owns(uint256) external view returns (address); function urns(uint256) external view returns (address); function cdpAllow( uint256 cdp, address usr, uint256 ok ) external; function frob( uint256, int256, int256 ) external; function flux( uint256, address, uint256 ) external; function move( uint256, address, uint256 ) external; function exit( address, uint256, address, uint256 ) external; }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; interface MPALike { struct CdpData { address gemJoin; address payable fundsReceiver; uint256 cdpId; bytes32 ilk; uint256 requiredDebt; uint256 borrowCollateral; uint256 withdrawCollateral; uint256 withdrawDai; uint256 depositDai; uint256 depositCollateral; bool skipFL; string methodName; } struct AddressRegistry { address jug; address manager; address multiplyProxyActions; address lender; address exchange; } struct ExchangeData { address fromTokenAddress; address toTokenAddress; uint256 fromTokenAmount; uint256 toTokenAmount; uint256 minToTokenAmount; address exchangeAddress; bytes _exchangeCalldata; } function increaseMultiple( ExchangeData calldata exchangeData, CdpData memory cdpData, AddressRegistry calldata addressRegistry ) external; function decreaseMultiple( ExchangeData calldata exchangeData, CdpData memory cdpData, AddressRegistry calldata addressRegistry ) external; function closeVaultExitCollateral( ExchangeData calldata exchangeData, CdpData memory cdpData, AddressRegistry calldata addressRegistry ) external; function closeVaultExitDai( ExchangeData calldata exchangeData, CdpData memory cdpData, AddressRegistry calldata addressRegistry ) external; }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; interface IPipInterface { function read() external returns (bytes32); } interface SpotterLike { function ilks(bytes32) external view returns (IPipInterface pip, uint256 mat); function par() external view returns (uint256); }
// SPDX-License-Identifier: AGPL-3.0-or-later /// BasicBuyCommand.sol // Copyright (C) 2021-2021 Oazo Apps Limited // 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.0; import { SafeMath } from "@openzeppelin/contracts/utils/math/SafeMath.sol"; library RatioUtils { using SafeMath for uint256; uint256 public constant RATIO = 10**4; uint256 public constant WAD = 10**18; uint256 public constant RAY = 10**27; uint256 public constant RAD = 10**45; // convert base units to ratio function toRatio(uint256 units) internal pure returns (uint256) { return units.mul(RATIO); } function wad(uint256 ratio) internal pure returns (uint256) { return ratio.mul(WAD).div(RATIO); } function ray(uint256 ratio) internal pure returns (uint256) { return ratio.mul(RAY).div(RATIO); } function bounds(uint256 ratio, uint64 deviation) internal pure returns (uint256 lower, uint256 upper) { uint256 offset = ratio.mul(deviation).div(RATIO); return (ratio.sub(offset), ratio.add(offset)); } function rayToWad(uint256 _ray) internal pure returns (uint256 _wad) { _wad = _ray.mul(WAD).div(RAY); } function wadToRay(uint256 _wad) internal pure returns (uint256 _ray) { _ray = _wad.mul(RAY).div(WAD); } function radToWad(uint256 _rad) internal pure returns (uint256 _wad) { _wad = _rad.mul(WAD).div(RAD); } function wadToRad(uint256 _wad) internal pure returns (uint256 _rad) { _rad = _wad.mul(RAD).div(WAD); } }
// SPDX-License-Identifier: AGPL-3.0-or-later /// ServiceRegistry.sol // Copyright (C) 2021-2021 Oazo Apps Limited // 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.0; 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; } function transferOwnership(address newOwner) external onlyOwner validateInput(36) delayedExecution { owner = newOwner; } function changeRequiredDelay(uint256 newDelay) external onlyOwner validateInput(36) delayedExecution { require(newDelay <= MAX_DELAY, "registry/invalid-delay"); requiredDelay = newDelay; } function getServiceNameHash(string memory name) external pure returns (bytes32) { return keccak256(abi.encodePacked(name)); } function addNamedService(bytes32 serviceNameHash, address serviceAddress) external onlyOwner validateInput(68) delayedExecution { require(namedService[serviceNameHash] == address(0), "registry/service-override"); namedService[serviceNameHash] = serviceAddress; } function updateNamedService(bytes32 serviceNameHash, address serviceAddress) external onlyOwner validateInput(68) delayedExecution { require(namedService[serviceNameHash] != address(0), "registry/service-does-not-exist"); namedService[serviceNameHash] = serviceAddress; } 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); } function getRegisteredService(string memory serviceName) external view returns (address) { return namedService[keccak256(abi.encodePacked(serviceName))]; } function getServiceAddress(bytes32 serviceNameHash) external view returns (address) { return namedService[serviceNameHash]; } 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); }
// SPDX-License-Identifier: AGPL-3.0-or-later /// McdView.sol // Copyright (C) 2021-2021 Oazo Apps Limited // 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.0; import "./interfaces/ManagerLike.sol"; import "./interfaces/ICommand.sol"; import "./interfaces/BotLike.sol"; import "./ServiceRegistry.sol"; import "./interfaces/SpotterLike.sol"; import "./interfaces/VatLike.sol"; import "./interfaces/OsmMomLike.sol"; import "./interfaces/OsmLike.sol"; import "./external/DSMath.sol"; /// @title Getter contract for Vault info from Maker protocol contract McdView is DSMath { ManagerLike public manager; VatLike public vat; SpotterLike public spotter; OsmMomLike public osmMom; address public owner; mapping(address => bool) public whitelisted; constructor( address _vat, address _manager, address _spotter, address _mom, address _owner ) { manager = ManagerLike(_manager); vat = VatLike(_vat); spotter = SpotterLike(_spotter); osmMom = OsmMomLike(_mom); owner = _owner; } function approve(address _allowedReader, bool isApproved) external { require(msg.sender == owner, "mcd-view/not-authorised"); whitelisted[_allowedReader] = isApproved; } /// @notice Gets Vault info (collateral, debt) /// @param vaultId Id of the Vault function getVaultInfo(uint256 vaultId) public view returns (uint256, uint256) { address urn = manager.urns(vaultId); bytes32 ilk = manager.ilks(vaultId); (uint256 collateral, uint256 debt) = vat.urns(ilk, urn); (, uint256 rate, , , ) = vat.ilks(ilk); return (collateral, rmul(debt, rate)); } /// @notice Gets a price of the asset /// @param ilk Ilk of the Vault function getPrice(bytes32 ilk) public view returns (uint256) { (, uint256 mat) = spotter.ilks(ilk); (, , uint256 spot, , ) = vat.ilks(ilk); return div(rmul(rmul(spot, spotter.par()), mat), 10**9); } /// @notice Gets oracle next price of the asset /// @param ilk Ilk of the Vault function getNextPrice(bytes32 ilk) public view returns (uint256) { require(whitelisted[msg.sender], "mcd-view/not-whitelisted"); OsmLike osm = OsmLike(osmMom.osms(ilk)); (bytes32 val, bool status) = osm.peep(); require(status, "mcd-view/osm-price-error"); return uint256(val); } /// @notice Gets Vaults ratio /// @param vaultId Id of the Vault function getRatio(uint256 vaultId, bool useNextPrice) public view returns (uint256) { bytes32 ilk = manager.ilks(vaultId); uint256 price = useNextPrice ? getNextPrice(ilk) : getPrice(ilk); (uint256 collateral, uint256 debt) = getVaultInfo(vaultId); if (debt == 0) return 0; return wdiv(wmul(collateral, price), debt); } }
// SPDX-License-Identifier: AGPL-3.0-or-later /// BaseMPACommand.sol // Copyright (C) 2021-2021 Oazo Apps Limited // 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.0; import { RatioUtils } from "../libs/RatioUtils.sol"; import { ICommand } from "../interfaces/ICommand.sol"; import { ManagerLike } from "../interfaces/ManagerLike.sol"; import { ServiceRegistry } from "../ServiceRegistry.sol"; import { McdView } from "../McdView.sol"; import { AutomationBot } from "../AutomationBot.sol"; abstract contract BaseMPACommand is ICommand { using RatioUtils for uint256; string public constant MCD_VIEW_KEY = "MCD_VIEW"; string public constant CDP_MANAGER_KEY = "CDP_MANAGER"; string public constant MPA_KEY = "MULTIPLY_PROXY_ACTIONS"; string public constant MCD_SPOT_KEY = "MCD_SPOT"; string public constant MCD_VAT_KEY = "MCD_VAT"; string private constant AUTOMATION_BOT_KEY = "AUTOMATION_BOT"; uint256 public constant MIN_ALLOWED_DEVIATION = 50; ServiceRegistry public immutable serviceRegistry; constructor(ServiceRegistry _serviceRegistry) { serviceRegistry = _serviceRegistry; } function getVaultAndMarketInfo(uint256 cdpId) public view returns ( uint256 collRatio, uint256 nextCollRatio, uint256 currPrice, uint256 nextPrice, bytes32 ilk ) { ManagerLike manager = ManagerLike(serviceRegistry.getRegisteredService(CDP_MANAGER_KEY)); ilk = manager.ilks(cdpId); McdView mcdView = McdView(serviceRegistry.getRegisteredService(MCD_VIEW_KEY)); collRatio = mcdView.getRatio(cdpId, false); nextCollRatio = mcdView.getRatio(cdpId, true); currPrice = mcdView.getPrice(ilk); nextPrice = mcdView.getNextPrice(ilk); } function getVaultDebt(uint256 cdpId) internal view returns (uint256) { McdView mcdView = McdView(serviceRegistry.getRegisteredService(MCD_VIEW_KEY)); (, uint256 debt) = mcdView.getVaultInfo(cdpId); return debt; } function baseFeeIsValid(uint256 maxAcceptableBaseFeeInGwei) public view returns (bool) { return block.basefee <= maxAcceptableBaseFeeInGwei * (10**9); } function deviationIsValid(uint256 deviation) public pure returns (bool) { return deviation >= MIN_ALLOWED_DEVIATION; } function validateTriggerType(uint16 triggerType, uint16 expectedTriggerType) public pure { require(triggerType == expectedTriggerType, "base-mpa-command/type-not-supported"); } function validateSelector(bytes4 expectedSelector, bytes memory executionData) public pure { bytes4 selector = abi.decode(executionData, (bytes4)); require(selector == expectedSelector, "base-mpa-command/invalid-selector"); } function executeMPAMethod(bytes memory executionData) internal { (bool status, bytes memory reason) = serviceRegistry .getRegisteredService(MPA_KEY) .delegatecall(executionData); require(status, string(reason)); } function recreateTrigger( uint256 cdpId, uint16 triggerType, bytes memory triggerData ) internal virtual { address automationBot = serviceRegistry.getRegisteredService(AUTOMATION_BOT_KEY); (bool status, ) = (automationBot).delegatecall( abi.encodeWithSelector( AutomationBot(msg.sender).addTrigger.selector, cdpId, triggerType, 0, triggerData ) ); require(status, "base-mpa-command/trigger-recreation-failed"); } }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; interface ICommand { function isTriggerDataValid(uint256 _cdpId, bytes memory triggerData) external view returns (bool); function isExecutionCorrect(uint256 cdpId, bytes memory triggerData) external view returns (bool); function isExecutionLegal(uint256 cdpId, bytes memory triggerData) external view returns (bool); function execute( bytes calldata executionData, uint256 cdpId, bytes memory triggerData ) external; }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; interface BotLike { function addRecord( uint256 cdpId, uint256 triggerType, uint256 replacedTriggerId, bytes memory triggerData ) external; function removeRecord( // This function should be executed allways in a context of AutomationBot address not DsProxy, //msg.sender should be dsProxy uint256 cdpId, uint256 triggerId ) external; function execute( bytes calldata executionData, uint256 cdpId, bytes calldata triggerData, address commandAddress, uint256 triggerId, uint256 daiCoverage ) external; }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; interface VatLike { function urns(bytes32, address) external view returns (uint256 ink, uint256 art); function ilks(bytes32) external view returns ( uint256 art, // Total Normalised Debt [wad] uint256 rate, // Accumulated Rates [ray] uint256 spot, // Price with Safety Margin [ray] uint256 line, // Debt Ceiling [rad] uint256 dust // Urn Debt Floor [rad] ); function gem(bytes32, address) external view returns (uint256); // [wad] function can(address, address) external view returns (uint256); function dai(address) external view returns (uint256); function frob( bytes32, address, address, address, int256, int256 ) external; function hope(address) external; function move( address, address, uint256 ) external; function fork( bytes32, address, address, int256, int256 ) external; }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; interface OsmMomLike { function osms(bytes32) external view returns (address); }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; interface OsmLike { function peep() external view returns (bytes32, bool); function bud(address) external view returns (uint256); function kiss(address a) external; }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; contract DSMath { function add(uint256 x, uint256 y) internal pure returns (uint256 z) { require((z = x + y) >= x, ""); } function sub(uint256 x, uint256 y) internal pure returns (uint256 z) { require((z = x - y) <= x, ""); } function mul(uint256 x, uint256 y) internal pure returns (uint256 z) { require(y == 0 || (z = x * y) / y == x, ""); } function div(uint256 x, uint256 y) internal pure returns (uint256 z) { return x / y; } function min(uint256 x, uint256 y) internal pure returns (uint256 z) { return x <= y ? x : y; } function max(uint256 x, uint256 y) internal pure returns (uint256 z) { return x >= y ? x : y; } function imin(int256 x, int256 y) internal pure returns (int256 z) { return x <= y ? x : y; } function imax(int256 x, int256 y) internal pure returns (int256 z) { return x >= y ? x : y; } uint256 internal constant WAD = 10**18; uint256 internal constant RAY = 10**27; function wmul(uint256 x, uint256 y) internal pure returns (uint256 z) { z = add(mul(x, y), WAD / 2) / WAD; } function rmul(uint256 x, uint256 y) internal pure returns (uint256 z) { z = add(mul(x, y), RAY / 2) / RAY; } function wdiv(uint256 x, uint256 y) internal pure returns (uint256 z) { z = add(mul(x, WAD), y / 2) / y; } function rdiv(uint256 x, uint256 y) internal pure returns (uint256 z) { z = add(mul(x, RAY), y / 2) / y; } // This famous algorithm is called "exponentiation by squaring" // and calculates x^n with x as fixed-point and n as regular unsigned. // // It's O(log n), instead of O(n) for naive repeated multiplication. // // These facts are why it works: // // If n is even, then x^n = (x^2)^(n/2). // If n is odd, then x^n = x * x^(n-1), // and applying the equation for even x gives // x^n = x * (x^2)^((n-1) / 2). // // Also, EVM division is flooring and // floor[(n-1) / 2] = floor[n / 2]. // function rpow(uint256 x, uint256 n) internal pure returns (uint256 z) { z = n % 2 != 0 ? x : RAY; for (n /= 2; n != 0; n /= 2) { x = rmul(x, x); if (n % 2 != 0) { z = rmul(z, x); } } } }
// SPDX-License-Identifier: AGPL-3.0-or-later /// AutomationBot.sol // Copyright (C) 2021-2021 Oazo Apps Limited // 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.0; import "./interfaces/ManagerLike.sol"; import "./interfaces/ICommand.sol"; import "./interfaces/BotLike.sol"; import "./ServiceRegistry.sol"; import "./McdUtils.sol"; contract AutomationBot { struct TriggerRecord { bytes32 triggerHash; uint256 cdpId; } string private constant CDP_MANAGER_KEY = "CDP_MANAGER"; string private constant AUTOMATION_BOT_KEY = "AUTOMATION_BOT"; string private constant AUTOMATION_EXECUTOR_KEY = "AUTOMATION_EXECUTOR"; string private constant MCD_UTILS_KEY = "MCD_UTILS"; mapping(uint256 => TriggerRecord) public activeTriggers; uint256 public triggersCounter = 0; ServiceRegistry public immutable serviceRegistry; address public immutable self; constructor(ServiceRegistry _serviceRegistry) { serviceRegistry = _serviceRegistry; self = address(this); } modifier auth(address caller) { require( serviceRegistry.getRegisteredService(AUTOMATION_EXECUTOR_KEY) == caller, "bot/not-executor" ); _; } modifier onlyDelegate() { require(address(this) != self, "bot/only-delegate"); _; } // works correctly in any context function validatePermissions( uint256 cdpId, address operator, ManagerLike manager ) private view { require(isCdpOwner(cdpId, operator, manager), "bot/no-permissions"); } // works correctly in any context function isCdpAllowed( uint256 cdpId, address operator, ManagerLike manager ) public view returns (bool) { address cdpOwner = manager.owns(cdpId); return (manager.cdpCan(cdpOwner, cdpId, operator) == 1) || (operator == cdpOwner); } // works correctly in any context function isCdpOwner( uint256 cdpId, address operator, ManagerLike manager ) private view returns (bool) { return (operator == manager.owns(cdpId)); } // works correctly in any context function getCommandAddress(uint256 triggerType) public view returns (address) { bytes32 commandHash = keccak256(abi.encode("Command", triggerType)); address commandAddress = serviceRegistry.getServiceAddress(commandHash); return commandAddress; } // works correctly in any context function getTriggersHash( uint256 cdpId, bytes memory triggerData, address commandAddress ) private view returns (bytes32) { bytes32 triggersHash = keccak256( abi.encodePacked(cdpId, triggerData, serviceRegistry, commandAddress) ); return triggersHash; } // works correctly in context of Automation Bot function checkTriggersExistenceAndCorrectness( uint256 cdpId, uint256 triggerId, address commandAddress, bytes memory triggerData ) private view { bytes32 triggersHash = activeTriggers[triggerId].triggerHash; require( triggersHash != bytes32(0) && triggersHash == getTriggersHash(cdpId, triggerData, commandAddress), "bot/invalid-trigger" ); } function checkTriggersExistenceAndCorrectness(uint256 cdpId, uint256 triggerId) private view { require(activeTriggers[triggerId].cdpId == cdpId, "bot/invalid-trigger"); } // works correctly in context of automationBot function addRecord( // This function should be executed allways in a context of AutomationBot address not DsProxy, // msg.sender should be dsProxy uint256 cdpId, uint256 triggerType, uint256 replacedTriggerId, bytes memory triggerData ) external { ManagerLike manager = ManagerLike(serviceRegistry.getRegisteredService(CDP_MANAGER_KEY)); address commandAddress = getCommandAddress(triggerType); require( ICommand(commandAddress).isTriggerDataValid(cdpId, triggerData), "bot/invalid-trigger-data" ); require(isCdpAllowed(cdpId, msg.sender, manager), "bot/no-permissions"); triggersCounter = triggersCounter + 1; activeTriggers[triggersCounter] = TriggerRecord( getTriggersHash(cdpId, triggerData, commandAddress), cdpId ); if (replacedTriggerId != 0) { require( activeTriggers[replacedTriggerId].cdpId == cdpId, "bot/trigger-removal-illegal" ); activeTriggers[replacedTriggerId] = TriggerRecord(0, 0); emit TriggerRemoved(cdpId, replacedTriggerId); } emit TriggerAdded(triggersCounter, commandAddress, cdpId, triggerData); } // works correctly in context of automationBot function removeRecord( // This function should be executed allways in a context of AutomationBot address not DsProxy, // msg.sender should be dsProxy uint256 cdpId, uint256 triggerId ) external { address managerAddress = serviceRegistry.getRegisteredService(CDP_MANAGER_KEY); require(isCdpAllowed(cdpId, msg.sender, ManagerLike(managerAddress)), "bot/no-permissions"); // validatePermissions(cdpId, msg.sender, ManagerLike(managerAddress)); checkTriggersExistenceAndCorrectness(cdpId, triggerId); activeTriggers[triggerId] = TriggerRecord(0, 0); emit TriggerRemoved(cdpId, triggerId); } //works correctly in context of dsProxy function addTrigger( uint256 cdpId, uint256 triggerType, uint256 replacedTriggerId, bytes memory triggerData ) external onlyDelegate { // TODO: consider adding isCdpAllow add flag in tx payload, make sense from extensibility perspective ManagerLike manager = ManagerLike(serviceRegistry.getRegisteredService(CDP_MANAGER_KEY)); address automationBot = serviceRegistry.getRegisteredService(AUTOMATION_BOT_KEY); BotLike(automationBot).addRecord(cdpId, triggerType, replacedTriggerId, triggerData); if (!isCdpAllowed(cdpId, automationBot, manager)) { manager.cdpAllow(cdpId, automationBot, 1); emit ApprovalGranted(cdpId, automationBot); } } //works correctly in context of dsProxy // TODO: removeAllowance parameter of this method moves responsibility to decide on this to frontend. // In case of a bug on frontend allowance might be revoked by setting this parameter to `true` // despite there still be some active triggers which will be disables by this call. // One of the solutions is to add counter of active triggers and revoke allowance only if last trigger is being deleted function removeTrigger( uint256 cdpId, uint256 triggerId, bool removeAllowance ) external onlyDelegate { address managerAddress = serviceRegistry.getRegisteredService(CDP_MANAGER_KEY); ManagerLike manager = ManagerLike(managerAddress); address automationBot = serviceRegistry.getRegisteredService(AUTOMATION_BOT_KEY); BotLike(automationBot).removeRecord(cdpId, triggerId); if (removeAllowance) { manager.cdpAllow(cdpId, automationBot, 0); emit ApprovalRemoved(cdpId, automationBot); } emit TriggerRemoved(cdpId, triggerId); } //works correctly in context of dsProxy function removeApproval(ServiceRegistry _serviceRegistry, uint256 cdpId) external onlyDelegate { address approvedEntity = changeApprovalStatus(_serviceRegistry, cdpId, 0); emit ApprovalRemoved(cdpId, approvedEntity); } //works correctly in context of dsProxy function grantApproval(ServiceRegistry _serviceRegistry, uint256 cdpId) external onlyDelegate { address approvedEntity = changeApprovalStatus(_serviceRegistry, cdpId, 1); emit ApprovalGranted(cdpId, approvedEntity); } //works correctly in context of dsProxy function changeApprovalStatus( ServiceRegistry _serviceRegistry, uint256 cdpId, uint256 status ) private returns (address) { address managerAddress = _serviceRegistry.getRegisteredService(CDP_MANAGER_KEY); ManagerLike manager = ManagerLike(managerAddress); address automationBot = _serviceRegistry.getRegisteredService(AUTOMATION_BOT_KEY); require( isCdpAllowed(cdpId, automationBot, manager) != (status == 1), "bot/approval-unchanged" ); validatePermissions(cdpId, address(this), manager); manager.cdpAllow(cdpId, automationBot, status); return automationBot; } function drawDaiFromVault( uint256 cdpId, ManagerLike manager, uint256 daiCoverage ) internal { address utilsAddress = serviceRegistry.getRegisteredService(MCD_UTILS_KEY); McdUtils utils = McdUtils(utilsAddress); manager.cdpAllow(cdpId, utilsAddress, 1); utils.drawDebt(daiCoverage, cdpId, manager, msg.sender); manager.cdpAllow(cdpId, utilsAddress, 0); } //works correctly in context of automationBot function execute( bytes calldata executionData, uint256 cdpId, bytes calldata triggerData, address commandAddress, uint256 triggerId, uint256 daiCoverage ) external auth(msg.sender) { checkTriggersExistenceAndCorrectness(cdpId, triggerId, commandAddress, triggerData); ManagerLike manager = ManagerLike(serviceRegistry.getRegisteredService(CDP_MANAGER_KEY)); drawDaiFromVault(cdpId, manager, daiCoverage); ICommand command = ICommand(commandAddress); require(command.isExecutionLegal(cdpId, triggerData), "bot/trigger-execution-illegal"); manager.cdpAllow(cdpId, commandAddress, 1); command.execute(executionData, cdpId, triggerData); activeTriggers[triggerId] = TriggerRecord(0, 0); manager.cdpAllow(cdpId, commandAddress, 0); require(command.isExecutionCorrect(cdpId, triggerData), "bot/trigger-execution-wrong"); emit TriggerExecuted(triggerId, cdpId, executionData); } event ApprovalRemoved(uint256 indexed cdpId, address approvedEntity); event ApprovalGranted(uint256 indexed cdpId, address approvedEntity); event TriggerRemoved(uint256 indexed cdpId, uint256 indexed triggerId); event TriggerAdded( uint256 indexed triggerId, address indexed commandAddress, uint256 indexed cdpId, bytes triggerData ); event TriggerExecuted(uint256 indexed triggerId, uint256 indexed cdpId, bytes executionData); }
// SPDX-License-Identifier: AGPL-3.0-or-later /// McdUtils.sol // Copyright (C) 2021-2021 Oazo Apps Limited // 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.0; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./external/DSMath.sol"; import "./interfaces/ManagerLike.sol"; import "./interfaces/ICommand.sol"; import "./interfaces/Mcd.sol"; import "./interfaces/BotLike.sol"; import "./ServiceRegistry.sol"; /// @title Getter contract for Vault info from Maker protocol contract McdUtils is DSMath { address public immutable serviceRegistry; IERC20 private immutable DAI; address private immutable daiJoin; address public immutable jug; constructor( address _serviceRegistry, IERC20 _dai, address _daiJoin, address _jug ) { serviceRegistry = _serviceRegistry; DAI = _dai; daiJoin = _daiJoin; jug = _jug; } function toInt256(uint256 x) internal pure returns (int256 y) { y = int256(x); require(y >= 0, "int256-overflow"); } function _getDrawDart( address vat, address urn, bytes32 ilk, uint256 wad ) internal returns (int256 dart) { // Updates stability fee rate uint256 rate = IJug(jug).drip(ilk); // Gets DAI balance of the urn in the vat uint256 dai = IVat(vat).dai(urn); // If there was already enough DAI in the vat balance, just exits it without adding more debt if (dai < mul(wad, RAY)) { // Calculates the needed dart so together with the existing dai in the vat is enough to exit wad amount of DAI tokens dart = toInt256(sub(mul(wad, RAY), dai) / rate); // This is neeeded due lack of precision. It might need to sum an extra dart wei (for the given DAI wad amount) dart = mul(uint256(dart), rate) < mul(wad, RAY) ? dart + 1 : dart; } } function drawDebt( uint256 borrowedDai, uint256 cdpId, ManagerLike manager, address sendTo ) external { address urn = manager.urns(cdpId); address vat = manager.vat(); manager.frob(cdpId, 0, _getDrawDart(vat, urn, manager.ilks(cdpId), borrowedDai)); manager.move(cdpId, address(this), mul(borrowedDai, RAY)); if (IVat(vat).can(address(this), daiJoin) == 0) { IVat(vat).hope(daiJoin); } IJoin(daiJoin).exit(sendTo, borrowedDai); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; abstract contract IVat { struct Urn { uint256 ink; // Locked Collateral [wad] uint256 art; // Normalised Debt [wad] } struct Ilk { uint256 Art; // Total Normalised Debt [wad] uint256 rate; // Accumulated Rates [ray] uint256 spot; // Price with Safety Margin [ray] uint256 line; // Debt Ceiling [rad] uint256 dust; // Urn Debt Floor [rad] } mapping(bytes32 => mapping(address => Urn)) public urns; mapping(bytes32 => Ilk) public ilks; mapping(bytes32 => mapping(address => uint256)) public gem; // [wad] function can(address, address) public view virtual returns (uint256); function dai(address) public view virtual returns (uint256); function frob( bytes32, address, address, address, int256, int256 ) public virtual; function hope(address) public virtual; function move( address, address, uint256 ) public virtual; function fork( bytes32, address, address, int256, int256 ) public virtual; } abstract contract IGem { function dec() public virtual returns (uint256); function gem() public virtual returns (IGem); function join(address, uint256) public payable virtual; function exit(address, uint256) public virtual; function approve(address, uint256) public virtual; function transfer(address, uint256) public virtual returns (bool); function transferFrom( address, address, uint256 ) public virtual returns (bool); function deposit() public payable virtual; function withdraw(uint256) public virtual; function allowance(address, address) public virtual returns (uint256); } abstract contract IJoin { bytes32 public ilk; function dec() public view virtual returns (uint256); function gem() public view virtual returns (IGem); function join(address, uint256) public payable virtual; function exit(address, uint256) public virtual; } abstract contract IDaiJoin { function vat() public virtual returns (IVat); function dai() public virtual returns (IGem); function join(address, uint256) public payable virtual; function exit(address, uint256) public virtual; } abstract contract IJug { struct Ilk { uint256 duty; uint256 rho; } mapping(bytes32 => Ilk) public ilks; function drip(bytes32) public virtual returns (uint256); }
{ "optimizer": { "enabled": true, "runs": 1000 }, "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":"_serviceRegistry","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CDP_MANAGER_KEY","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MCD_SPOT_KEY","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MCD_VAT_KEY","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MCD_VIEW_KEY","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_ALLOWED_DEVIATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MPA_KEY","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxAcceptableBaseFeeInGwei","type":"uint256"}],"name":"baseFeeIsValid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"triggerData","type":"bytes"}],"name":"decode","outputs":[{"components":[{"internalType":"uint256","name":"cdpId","type":"uint256"},{"internalType":"uint16","name":"triggerType","type":"uint16"},{"internalType":"uint256","name":"execCollRatio","type":"uint256"},{"internalType":"uint256","name":"targetCollRatio","type":"uint256"},{"internalType":"uint256","name":"maxBuyPrice","type":"uint256"},{"internalType":"bool","name":"continuous","type":"bool"},{"internalType":"uint64","name":"deviation","type":"uint64"},{"internalType":"uint32","name":"maxBaseFeeInGwei","type":"uint32"}],"internalType":"struct BasicBuyCommand.BasicBuyTriggerData","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"deviation","type":"uint256"}],"name":"deviationIsValid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"executionData","type":"bytes"},{"internalType":"uint256","name":"cdpId","type":"uint256"},{"internalType":"bytes","name":"triggerData","type":"bytes"}],"name":"execute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"cdpId","type":"uint256"}],"name":"getVaultAndMarketInfo","outputs":[{"internalType":"uint256","name":"collRatio","type":"uint256"},{"internalType":"uint256","name":"nextCollRatio","type":"uint256"},{"internalType":"uint256","name":"currPrice","type":"uint256"},{"internalType":"uint256","name":"nextPrice","type":"uint256"},{"internalType":"bytes32","name":"ilk","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"cdpId","type":"uint256"},{"internalType":"bytes","name":"triggerData","type":"bytes"}],"name":"isExecutionCorrect","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"cdpId","type":"uint256"},{"internalType":"bytes","name":"triggerData","type":"bytes"}],"name":"isExecutionLegal","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cdpId","type":"uint256"},{"internalType":"bytes","name":"triggerData","type":"bytes"}],"name":"isTriggerDataValid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"serviceRegistry","outputs":[{"internalType":"contract ServiceRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"expectedSelector","type":"bytes4"},{"internalType":"bytes","name":"executionData","type":"bytes"}],"name":"validateSelector","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint16","name":"triggerType","type":"uint16"},{"internalType":"uint16","name":"expectedTriggerType","type":"uint16"}],"name":"validateTriggerType","outputs":[],"stateMutability":"pure","type":"function"}]
Contract Creation Code
60a060405234801561001057600080fd5b50604051611aaf380380611aaf83398101604081905261002f91610040565b6001600160a01b0316608052610070565b60006020828403121561005257600080fd5b81516001600160a01b038116811461006957600080fd5b9392505050565b6080516119ec6100c3600039600081816102e9015281816104f0015281816106550152818161090a01528181610a2b01528181610c1901528181610d6d0152818161108601526111c901526119ec6000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c80639306f6be116100b2578063c4b73fda11610081578063cbcf252a11610066578063cbcf252a146102e4578063d05e47fb14610323578063e5c5e9a31461035e57600080fd5b8063c4b73fda14610281578063c63fa8a4146102bd57600080fd5b80639306f6be146101f6578063938018771461020b5780639561557b1461021e578063a8438a581461024557600080fd5b80634f873e44116100ee5780634f873e44146101865780635b7f7ea81461019957806364ae63a5146101d05780637827a9b0146101e357600080fd5b80630441d02a1461012057806311449b61146101355780632fddf37e146101505780633c946ca314610173575b600080fd5b61013361012e3660046114ff565b6103e8565b005b61013d603281565b6040519081526020015b60405180910390f35b61016361015e36600461159d565b6104aa565b6040519015158152602001610147565b61016361018136600461159d565b61062b565b610133610194366004611615565b6107ec565b6101c36040518060400160405280600b81526020016a21a2282fa6a0a720a3a2a960a91b81525081565b60405161014791906116a7565b6101636101de3660046116ba565b6108a8565b6101636101f136600461159d565b6108c1565b6101636102043660046116ba565b6032111590565b6101336102193660046116e3565b610b8d565b6101c3604051806040016040528060088152602001674d43445f5649455760c01b81525081565b6101c36040518060400160405280600781526020017f4d43445f5641540000000000000000000000000000000000000000000000000081525081565b6101c36040518060400160405280601681526020017f4d554c5449504c595f50524f58595f414354494f4e530000000000000000000081525081565b6101c3604051806040016040528060088152602001671350d117d4d413d560c21b81525081565b61030b7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610147565b6103366103313660046116ba565b610c0e565b604080519586526020860194909452928401919091526060830152608082015260a001610147565b61037161036c36600461171c565b610fdf565b60405161014791906000610100820190508251825261ffff602084015116602083015260408301516040830152606083015160608301526080830151608083015260a0830151151560a083015267ffffffffffffffff60c08401511660c083015263ffffffff60e08401511660e083015292915050565b60006103f382610fdf565b905061040481602001516003610b8d565b61044b634a9b4e0c60e01b86868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506107ec92505050565b61048a85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061103892505050565b8060a00151156104a3576104a38382602001518461117d565b5050505050565b6000806104b683610fdf565b60408051808201825260088152674d43445f5649455760c01b60208201529051630851f3bd60e01b81529192506000916001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691630851f3bd9161052491906004016116a7565b602060405180830381865afa158015610541573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610565919061176e565b604051632f792afb60e21b815260048101879052600160248201529091506000906001600160a01b0383169063bde4abec90604401602060405180830381865afa1580156105b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105db919061178b565b90506000806105fb8560c00151866060015161138d90919063ffffffff16565b91509150610608816113cd565b831115801561061f575061061b826113cd565b8310155b98975050505050505050565b60008061063783610fdf565b905060008060008061064888610c0e565b94509450945094505060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630851f3bd604051806040016040528060088152602001671350d117d4d413d560c21b8152506040518263ffffffff1660e01b81526004016106bf91906116a7565b602060405180830381865afa1580156106dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610700919061176e565b604051636cb1c69b60e11b8152600481018490529091506000906001600160a01b0383169063d9638d36906024016040805180830381865afa15801561074a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076e91906117a4565b91505061077e87604001516113cd565b8610158015610791575086608001518411155b80156107c457506107a1816113e7565b6107c2856107bc886107b68c606001516113cd565b90611407565b9061141a565b115b80156107de57506107de8760e0015163ffffffff166108a8565b9a9950505050505050505050565b60008180602001905181019061080291906117d2565b90507fffffffff00000000000000000000000000000000000000000000000000000000808216908416146108a35760405162461bcd60e51b815260206004820152602160248201527f626173652d6d70612d636f6d6d616e642f696e76616c69642d73656c6563746f60448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b505050565b60006108b882633b9aca00611805565b48111592915050565b6000806108cd83610fdf565b604080518082018252600b81526a21a2282fa6a0a720a3a2a960a91b60208201529051630851f3bd60e01b81529192506000916001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691630851f3bd9161093e91906004016116a7565b602060405180830381865afa15801561095b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097f919061176e565b8251604051632c2cb9fd60e01b815260048101919091529091506000906001600160a01b03831690632c2cb9fd90602401602060405180830381865afa1580156109cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f1919061178b565b60408051808201825260088152671350d117d4d413d560c21b60208201529051630851f3bd60e01b81529192506000916001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691630851f3bd91610a5f91906004016116a7565b602060405180830381865afa158015610a7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa0919061176e565b604051636cb1c69b60e11b8152600481018490529091506000906001600160a01b0383169063d9638d36906024016040805180830381865afa158015610aea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0e91906117a4565b915050600080610b2f8760c00151886060015161138d90919063ffffffff16565b885191935091508a148015610b4c5750866020015161ffff166003145b8015610b5b5750808760400151115b8015610b6e575082610b6c83611426565b115b80156107de575060c087015167ffffffffffffffff16603211156107de565b8061ffff168261ffff1614610c0a5760405162461bcd60e51b815260206004820152602360248201527f626173652d6d70612d636f6d6d616e642f747970652d6e6f742d737570706f7260448201527f7465640000000000000000000000000000000000000000000000000000000000606482015260840161089a565b5050565b6000806000806000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630851f3bd6040518060400160405280600b81526020016a21a2282fa6a0a720a3a2a960a91b8152506040518263ffffffff1660e01b8152600401610c8691906116a7565b602060405180830381865afa158015610ca3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc7919061176e565b604051632c2cb9fd60e01b8152600481018990529091506001600160a01b03821690632c2cb9fd90602401602060405180830381865afa158015610d0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d33919061178b565b60408051808201825260088152674d43445f5649455760c01b60208201529051630851f3bd60e01b81529193506000916001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691630851f3bd91610da191906004016116a7565b602060405180830381865afa158015610dbe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de2919061176e565b604051632f792afb60e21b8152600481018a9052600060248201529091506001600160a01b0382169063bde4abec90604401602060405180830381865afa158015610e31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e55919061178b565b604051632f792afb60e21b8152600481018a9052600160248201529097506001600160a01b0382169063bde4abec90604401602060405180830381865afa158015610ea4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec8919061178b565b6040517f31d98b3f000000000000000000000000000000000000000000000000000000008152600481018590529096506001600160a01b038216906331d98b3f90602401602060405180830381865afa158015610f29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4d919061178b565b6040517f0ee95ecf000000000000000000000000000000000000000000000000000000008152600481018590529095506001600160a01b03821690630ee95ecf90602401602060405180830381865afa158015610fae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd2919061178b565b9350505091939590929450565b604080516101008101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e0820152825190916110329184018101908401611865565b92915050565b604080518082018252601681527f4d554c5449504c595f50524f58595f414354494f4e530000000000000000000060208201529051630851f3bd60e01b815260009182916001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691630851f3bd916110ba91906004016116a7565b602060405180830381865afa1580156110d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110fb919061176e565b6001600160a01b0316836040516111129190611913565b600060405180830381855af49150503d806000811461114d576040519150601f19603f3d011682016040523d82523d6000602084013e611152565b606091505b50915091508181906111775760405162461bcd60e51b815260040161089a91906116a7565b50505050565b604080518082018252600e81527f4155544f4d4154494f4e5f424f5400000000000000000000000000000000000060208201529051630851f3bd60e01b81526000916001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691630851f3bd916111fc916004016116a7565b602060405180830381865afa158015611219573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123d919061176e565b90506000816001600160a01b03166311386ede60e01b868660008760405160240161126b949392919061192f565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516112d69190611913565b600060405180830381855af49150503d8060008114611311576040519150601f19603f3d011682016040523d82523d6000602084013e611316565b606091505b50509050806104a35760405162461bcd60e51b815260206004820152602a60248201527f626173652d6d70612d636f6d6d616e642f747269676765722d7265637265617460448201527f696f6e2d6661696c656400000000000000000000000000000000000000000000606482015260840161089a565b600080806113ab6127106107bc8767ffffffffffffffff8816611407565b90506113b78582611444565b6113c18683611450565b92509250509250929050565b60006110326127106107bc84670de0b6b3a7640000611407565b60006110326b033b2e3c9fd0803ce80000006107bc84670de0b6b3a76400005b60006114138284611805565b9392505050565b60006114138284611965565b60006110326127106107bc846b033b2e3c9fd0803ce8000000611407565b60006114138284611987565b6000611413828461199e565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261148357600080fd5b813567ffffffffffffffff8082111561149e5761149e61145c565b604051601f8301601f19908116603f011681019082821181831017156114c6576114c661145c565b816040528381528660208588010111156114df57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806060858703121561151557600080fd5b843567ffffffffffffffff8082111561152d57600080fd5b818701915087601f83011261154157600080fd5b81358181111561155057600080fd5b88602082850101111561156257600080fd5b6020928301965094509086013592506040860135908082111561158457600080fd5b5061159187828801611472565b91505092959194509250565b600080604083850312156115b057600080fd5b82359150602083013567ffffffffffffffff8111156115ce57600080fd5b6115da85828601611472565b9150509250929050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461161257600080fd5b50565b6000806040838503121561162857600080fd5b8235611633816115e4565b9150602083013567ffffffffffffffff8111156115ce57600080fd5b60005b8381101561166a578181015183820152602001611652565b838111156111775750506000910152565b6000815180845261169381602086016020860161164f565b601f01601f19169290920160200192915050565b602081526000611413602083018461167b565b6000602082840312156116cc57600080fd5b5035919050565b61ffff8116811461161257600080fd5b600080604083850312156116f657600080fd5b8235611701816116d3565b91506020830135611711816116d3565b809150509250929050565b60006020828403121561172e57600080fd5b813567ffffffffffffffff81111561174557600080fd5b61175184828501611472565b949350505050565b6001600160a01b038116811461161257600080fd5b60006020828403121561178057600080fd5b815161141381611759565b60006020828403121561179d57600080fd5b5051919050565b600080604083850312156117b757600080fd5b82516117c281611759565b6020939093015192949293505050565b6000602082840312156117e457600080fd5b8151611413816115e4565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561181f5761181f6117ef565b500290565b8051801515811461183457600080fd5b919050565b805167ffffffffffffffff8116811461183457600080fd5b805163ffffffff8116811461183457600080fd5b600061010080838503121561187957600080fd5b6040519081019067ffffffffffffffff8211818310171561189c5761189c61145c565b8160405283518152602084015191506118b4826116d3565b8160208201526040840151604082015260608401516060820152608084015160808201526118e460a08501611824565b60a08201526118f560c08501611839565b60c082015261190660e08501611851565b60e0820152949350505050565b6000825161192581846020870161164f565b9190910192915050565b84815261ffff8416602082015260ff8316604082015260806060820152600061195b608083018461167b565b9695505050505050565b60008261198257634e487b7160e01b600052601260045260246000fd5b500490565b600082821015611999576119996117ef565b500390565b600082198211156119b1576119b16117ef565b50019056fea2646970667358221220b74985902a46adce69c90992b2a1bc0779360e349de13c03f7c938713b9bb88064736f6c634300080d00330000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061011b5760003560e01c80639306f6be116100b2578063c4b73fda11610081578063cbcf252a11610066578063cbcf252a146102e4578063d05e47fb14610323578063e5c5e9a31461035e57600080fd5b8063c4b73fda14610281578063c63fa8a4146102bd57600080fd5b80639306f6be146101f6578063938018771461020b5780639561557b1461021e578063a8438a581461024557600080fd5b80634f873e44116100ee5780634f873e44146101865780635b7f7ea81461019957806364ae63a5146101d05780637827a9b0146101e357600080fd5b80630441d02a1461012057806311449b61146101355780632fddf37e146101505780633c946ca314610173575b600080fd5b61013361012e3660046114ff565b6103e8565b005b61013d603281565b6040519081526020015b60405180910390f35b61016361015e36600461159d565b6104aa565b6040519015158152602001610147565b61016361018136600461159d565b61062b565b610133610194366004611615565b6107ec565b6101c36040518060400160405280600b81526020016a21a2282fa6a0a720a3a2a960a91b81525081565b60405161014791906116a7565b6101636101de3660046116ba565b6108a8565b6101636101f136600461159d565b6108c1565b6101636102043660046116ba565b6032111590565b6101336102193660046116e3565b610b8d565b6101c3604051806040016040528060088152602001674d43445f5649455760c01b81525081565b6101c36040518060400160405280600781526020017f4d43445f5641540000000000000000000000000000000000000000000000000081525081565b6101c36040518060400160405280601681526020017f4d554c5449504c595f50524f58595f414354494f4e530000000000000000000081525081565b6101c3604051806040016040528060088152602001671350d117d4d413d560c21b81525081565b61030b7f0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada81565b6040516001600160a01b039091168152602001610147565b6103366103313660046116ba565b610c0e565b604080519586526020860194909452928401919091526060830152608082015260a001610147565b61037161036c36600461171c565b610fdf565b60405161014791906000610100820190508251825261ffff602084015116602083015260408301516040830152606083015160608301526080830151608083015260a0830151151560a083015267ffffffffffffffff60c08401511660c083015263ffffffff60e08401511660e083015292915050565b60006103f382610fdf565b905061040481602001516003610b8d565b61044b634a9b4e0c60e01b86868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506107ec92505050565b61048a85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061103892505050565b8060a00151156104a3576104a38382602001518461117d565b5050505050565b6000806104b683610fdf565b60408051808201825260088152674d43445f5649455760c01b60208201529051630851f3bd60e01b81529192506000916001600160a01b037f0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada1691630851f3bd9161052491906004016116a7565b602060405180830381865afa158015610541573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610565919061176e565b604051632f792afb60e21b815260048101879052600160248201529091506000906001600160a01b0383169063bde4abec90604401602060405180830381865afa1580156105b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105db919061178b565b90506000806105fb8560c00151866060015161138d90919063ffffffff16565b91509150610608816113cd565b831115801561061f575061061b826113cd565b8310155b98975050505050505050565b60008061063783610fdf565b905060008060008061064888610c0e565b94509450945094505060007f0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada6001600160a01b0316630851f3bd604051806040016040528060088152602001671350d117d4d413d560c21b8152506040518263ffffffff1660e01b81526004016106bf91906116a7565b602060405180830381865afa1580156106dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610700919061176e565b604051636cb1c69b60e11b8152600481018490529091506000906001600160a01b0383169063d9638d36906024016040805180830381865afa15801561074a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076e91906117a4565b91505061077e87604001516113cd565b8610158015610791575086608001518411155b80156107c457506107a1816113e7565b6107c2856107bc886107b68c606001516113cd565b90611407565b9061141a565b115b80156107de57506107de8760e0015163ffffffff166108a8565b9a9950505050505050505050565b60008180602001905181019061080291906117d2565b90507fffffffff00000000000000000000000000000000000000000000000000000000808216908416146108a35760405162461bcd60e51b815260206004820152602160248201527f626173652d6d70612d636f6d6d616e642f696e76616c69642d73656c6563746f60448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b505050565b60006108b882633b9aca00611805565b48111592915050565b6000806108cd83610fdf565b604080518082018252600b81526a21a2282fa6a0a720a3a2a960a91b60208201529051630851f3bd60e01b81529192506000916001600160a01b037f0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada1691630851f3bd9161093e91906004016116a7565b602060405180830381865afa15801561095b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097f919061176e565b8251604051632c2cb9fd60e01b815260048101919091529091506000906001600160a01b03831690632c2cb9fd90602401602060405180830381865afa1580156109cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f1919061178b565b60408051808201825260088152671350d117d4d413d560c21b60208201529051630851f3bd60e01b81529192506000916001600160a01b037f0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada1691630851f3bd91610a5f91906004016116a7565b602060405180830381865afa158015610a7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa0919061176e565b604051636cb1c69b60e11b8152600481018490529091506000906001600160a01b0383169063d9638d36906024016040805180830381865afa158015610aea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0e91906117a4565b915050600080610b2f8760c00151886060015161138d90919063ffffffff16565b885191935091508a148015610b4c5750866020015161ffff166003145b8015610b5b5750808760400151115b8015610b6e575082610b6c83611426565b115b80156107de575060c087015167ffffffffffffffff16603211156107de565b8061ffff168261ffff1614610c0a5760405162461bcd60e51b815260206004820152602360248201527f626173652d6d70612d636f6d6d616e642f747970652d6e6f742d737570706f7260448201527f7465640000000000000000000000000000000000000000000000000000000000606482015260840161089a565b5050565b6000806000806000807f0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada6001600160a01b0316630851f3bd6040518060400160405280600b81526020016a21a2282fa6a0a720a3a2a960a91b8152506040518263ffffffff1660e01b8152600401610c8691906116a7565b602060405180830381865afa158015610ca3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc7919061176e565b604051632c2cb9fd60e01b8152600481018990529091506001600160a01b03821690632c2cb9fd90602401602060405180830381865afa158015610d0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d33919061178b565b60408051808201825260088152674d43445f5649455760c01b60208201529051630851f3bd60e01b81529193506000916001600160a01b037f0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada1691630851f3bd91610da191906004016116a7565b602060405180830381865afa158015610dbe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de2919061176e565b604051632f792afb60e21b8152600481018a9052600060248201529091506001600160a01b0382169063bde4abec90604401602060405180830381865afa158015610e31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e55919061178b565b604051632f792afb60e21b8152600481018a9052600160248201529097506001600160a01b0382169063bde4abec90604401602060405180830381865afa158015610ea4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec8919061178b565b6040517f31d98b3f000000000000000000000000000000000000000000000000000000008152600481018590529096506001600160a01b038216906331d98b3f90602401602060405180830381865afa158015610f29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4d919061178b565b6040517f0ee95ecf000000000000000000000000000000000000000000000000000000008152600481018590529095506001600160a01b03821690630ee95ecf90602401602060405180830381865afa158015610fae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd2919061178b565b9350505091939590929450565b604080516101008101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e0820152825190916110329184018101908401611865565b92915050565b604080518082018252601681527f4d554c5449504c595f50524f58595f414354494f4e530000000000000000000060208201529051630851f3bd60e01b815260009182916001600160a01b037f0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada1691630851f3bd916110ba91906004016116a7565b602060405180830381865afa1580156110d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110fb919061176e565b6001600160a01b0316836040516111129190611913565b600060405180830381855af49150503d806000811461114d576040519150601f19603f3d011682016040523d82523d6000602084013e611152565b606091505b50915091508181906111775760405162461bcd60e51b815260040161089a91906116a7565b50505050565b604080518082018252600e81527f4155544f4d4154494f4e5f424f5400000000000000000000000000000000000060208201529051630851f3bd60e01b81526000916001600160a01b037f0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada1691630851f3bd916111fc916004016116a7565b602060405180830381865afa158015611219573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123d919061176e565b90506000816001600160a01b03166311386ede60e01b868660008760405160240161126b949392919061192f565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516112d69190611913565b600060405180830381855af49150503d8060008114611311576040519150601f19603f3d011682016040523d82523d6000602084013e611316565b606091505b50509050806104a35760405162461bcd60e51b815260206004820152602a60248201527f626173652d6d70612d636f6d6d616e642f747269676765722d7265637265617460448201527f696f6e2d6661696c656400000000000000000000000000000000000000000000606482015260840161089a565b600080806113ab6127106107bc8767ffffffffffffffff8816611407565b90506113b78582611444565b6113c18683611450565b92509250509250929050565b60006110326127106107bc84670de0b6b3a7640000611407565b60006110326b033b2e3c9fd0803ce80000006107bc84670de0b6b3a76400005b60006114138284611805565b9392505050565b60006114138284611965565b60006110326127106107bc846b033b2e3c9fd0803ce8000000611407565b60006114138284611987565b6000611413828461199e565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261148357600080fd5b813567ffffffffffffffff8082111561149e5761149e61145c565b604051601f8301601f19908116603f011681019082821181831017156114c6576114c661145c565b816040528381528660208588010111156114df57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806060858703121561151557600080fd5b843567ffffffffffffffff8082111561152d57600080fd5b818701915087601f83011261154157600080fd5b81358181111561155057600080fd5b88602082850101111561156257600080fd5b6020928301965094509086013592506040860135908082111561158457600080fd5b5061159187828801611472565b91505092959194509250565b600080604083850312156115b057600080fd5b82359150602083013567ffffffffffffffff8111156115ce57600080fd5b6115da85828601611472565b9150509250929050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461161257600080fd5b50565b6000806040838503121561162857600080fd5b8235611633816115e4565b9150602083013567ffffffffffffffff8111156115ce57600080fd5b60005b8381101561166a578181015183820152602001611652565b838111156111775750506000910152565b6000815180845261169381602086016020860161164f565b601f01601f19169290920160200192915050565b602081526000611413602083018461167b565b6000602082840312156116cc57600080fd5b5035919050565b61ffff8116811461161257600080fd5b600080604083850312156116f657600080fd5b8235611701816116d3565b91506020830135611711816116d3565b809150509250929050565b60006020828403121561172e57600080fd5b813567ffffffffffffffff81111561174557600080fd5b61175184828501611472565b949350505050565b6001600160a01b038116811461161257600080fd5b60006020828403121561178057600080fd5b815161141381611759565b60006020828403121561179d57600080fd5b5051919050565b600080604083850312156117b757600080fd5b82516117c281611759565b6020939093015192949293505050565b6000602082840312156117e457600080fd5b8151611413816115e4565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561181f5761181f6117ef565b500290565b8051801515811461183457600080fd5b919050565b805167ffffffffffffffff8116811461183457600080fd5b805163ffffffff8116811461183457600080fd5b600061010080838503121561187957600080fd5b6040519081019067ffffffffffffffff8211818310171561189c5761189c61145c565b8160405283518152602084015191506118b4826116d3565b8160208201526040840151604082015260608401516060820152608084015160808201526118e460a08501611824565b60a08201526118f560c08501611839565b60c082015261190660e08501611851565b60e0820152949350505050565b6000825161192581846020870161164f565b9190910192915050565b84815261ffff8416602082015260ff8316604082015260806060820152600061195b608083018461167b565b9695505050505050565b60008261198257634e487b7160e01b600052601260045260246000fd5b500490565b600082821015611999576119996117ef565b500390565b600082198211156119b1576119b16117ef565b50019056fea2646970667358221220b74985902a46adce69c90992b2a1bc0779360e349de13c03f7c938713b9bb88064736f6c634300080d0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada
-----Decoded View---------------
Arg [0] : _serviceRegistry (address): 0x9b4Ae7b164d195df9C4Da5d08Be88b2848b2EaDA
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000009b4ae7b164d195df9c4da5d08be88b2848b2eada
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.