Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- WitnetPriceFeed
- Optimization enabled
- true
- Compiler version
- v0.7.6+commit.7338295f
- Optimization runs
- 200
- EVM Version
- istanbul
- Verified at
- 2023-04-19T17:06:52.152844Z
Constructor Arguments
000000000000000000000000d39d4d972c7e166856c4eb29e54d3548b4597f534c80cf2e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000015180
Arg [0] (address) : 0xd39d4d972c7e166856c4eb29e54d3548b4597f53
Arg [1] (bytes4) : 4c80cf2e
Arg [2] (uint256) : 6
Arg [3] (uint256) : 86400
Contract source code
// Sources flattened with hardhat v2.14.0 https://hardhat.org // File contracts/dependencies/openzeppelin/contracts/SafeMath.sol // SPDX-License-Identifier: agpl-3.0, MIT pragma solidity 0.7.6; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @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) { uint256 c = a + b; require(c >= a, 'SafeMath: addition overflow'); return c; } /** * @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 sub(a, b, 'SafeMath: subtraction overflow'); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @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) { // 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; } /** * @dev Returns the integer division of two unsigned integers. Reverts 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) internal pure returns (uint256) { return div(a, b, 'SafeMath: division by zero'); } /** * @dev Returns the integer division of two unsigned integers. Reverts 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) { // Solidity only automatically asserts when dividing by 0 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; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts 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 mod(a, b, 'SafeMath: modulo by zero'); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message 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, string memory errorMessage ) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File contracts/interfaces/IERC2362.sol pragma solidity 0.7.6; interface IERC2362 { /** * @dev Exposed function pertaining to EIP standards * @param _id bytes32 ID of the query * @return int,uint,uint returns the value, timestamp, and status code of query */ function valueFor(bytes32 _id) external view returns(int256,uint256,uint256); } // File contracts/interfaces/IPriceFeed.sol pragma solidity 0.7.6; interface IPriceFeed { // --- Function --- function fetchPrice() external view returns (uint256); function updatePrice() external returns (uint256); } // File contracts/misc/WitnetPriceFeed.sol pragma solidity 0.7.6; /* * The WitnetPriceFeed uses Witnet as primary oracle. */ contract WitnetPriceFeed is IPriceFeed { using SafeMath for uint256; uint256 public constant DECIMAL_PRECISION = 1e18; IERC2362 public oracle; bytes4 public erc2362id; uint256 public decimals; // Use to convert a price answer to an 18-digit precision uint uint256 public constant TARGET_DIGITS = 18; // Maximum time period allowed since Witnet's latest round data timestamp, beyond which Witnet is considered frozen. // For stablecoins we recommend 90000, as Witnet updates once per day when there is no significant price movement // For volatile assets we recommend 14400 (4 hours) uint256 public immutable TIMEOUT; // Maximum deviation allowed between two consecutive Witnet oracle prices. 18-digit precision. uint256 public constant MAX_PRICE_DEVIATION_FROM_PREVIOUS_ROUND = 5e17; // 50% /* * The maximum relative price difference between two oracle responses allowed in order for the PriceFeed * to return to using the Witnet oracle. 18-digit precision. */ uint256 public constant MAX_PRICE_DIFFERENCE_BETWEEN_ORACLES = 5e16; // 5% // The last good price seen from an oracle by Liquity uint256 public lastGoodPrice; struct OracleResponse { uint256 answer; uint256 timestamp; bool success; } enum Status { oracleWorking, oracleUntrusted } // The current status of the PricFeed, which determines the conditions for the next price fetch attempt Status public status; event LastGoodPriceUpdated(uint256 _lastGoodPrice); event PriceFeedStatusChanged(Status newStatus); // --- Dependency setters --- constructor(IERC2362 _oracle, bytes4 _erc2362id, uint256 _decimals, uint256 _timeout) { oracle = _oracle; erc2362id = _erc2362id; decimals = _decimals; TIMEOUT = _timeout; // Explicitly set initial system status status = Status.oracleWorking; // Get an initial price from Witnet to serve as first reference for lastGoodPrice OracleResponse memory response = _getCurrentResponse(); require( !_oracleIsBroken(response) && block.timestamp.sub(response.timestamp) < _timeout, 'PriceFeed: Witnet must be working and current' ); lastGoodPrice = _scalePriceByDigits(uint256(response.answer), decimals); } // --- Functions --- /* * fetchPrice(): * Returns the latest price obtained from the Oracle. Called by Liquity functions that require a current price. * * Also callable by anyone externally. * * Non-view function - it stores the last good price seen by Liquity. * * Uses a main oracle (Witnet). If it fails, * it uses the last good price seen by Liquity. * */ function fetchPrice() external view override returns (uint256) { (, uint256 price) = _fetchPrice(); return price; } function updatePrice() external override returns (uint256) { (Status newStatus, uint256 price) = _fetchPrice(); lastGoodPrice = price; if (status != newStatus) { status = newStatus; emit PriceFeedStatusChanged(newStatus); } return price; } function _fetchPrice() internal view returns (Status, uint256) { // Get current and previous price data from Witnet, and current price data from Band OracleResponse memory response = _getCurrentResponse(); // --- CASE 1: System fetched last price from Witnet --- if (status == Status.oracleWorking) { // If Witnet is broken or frozen if (_oracleIsBroken(response) || _oracleIsFrozen(response)) { // If Witnet is broken, switch to Band and return current Band price return (Status.oracleUntrusted, lastGoodPrice); } // If Witnet is working, return Witnet current price (no status change) return (Status.oracleWorking, response.answer); } // --- CASE 2: Witnet oracle is untrusted at the last price fetch --- if (status == Status.oracleUntrusted) { if (_oracleIsBroken(response) || _oracleIsFrozen(response)) { return (Status.oracleUntrusted, lastGoodPrice); } return (Status.oracleWorking, response.answer); } } // --- Helper functions --- /* Witnet is considered broken if its current or previous round data is in any way bad. We check the previous round * for two reasons: * * 1) It is necessary data for the price deviation check in case 1, * and * 2) Witnet is the PriceFeed's preferred primary oracle - having two consecutive valid round responses adds * peace of mind when using or returning to Witnet. */ function _oracleIsBroken(OracleResponse memory _response) internal view returns (bool) { // Check for response call reverted if (!_response.success) { return true; } // Check for an invalid timeStamp that is 0, or in the future if (_response.timestamp == 0 || _response.timestamp > block.timestamp) { return true; } // Check for non-positive price (original value returned from Witnet is int256) if (int256(_response.answer) <= 0) { return true; } return false; } function _oracleIsFrozen(OracleResponse memory _response) internal view returns (bool) { return block.timestamp.sub(_response.timestamp) > TIMEOUT; } function _scalePriceByDigits(uint256 _price, uint256 _digits) internal pure returns (uint256) { /* * Convert the price returned by the Witnet oracle to an 18-digit decimal for use by Liquity. * At date of Liquity launch, Witnet uses an 8-digit price, but we also handle the possibility of * future changes. */ uint256 price; if (_digits >= TARGET_DIGITS) { // Scale the returned price value down to Liquity's target precision price = _price.div(10**(_digits - TARGET_DIGITS)); } else if (_digits < TARGET_DIGITS) { // Scale the returned price value up to Liquity's target precision price = _price.mul(10**(TARGET_DIGITS - _digits)); } return price; } // --- Oracle response wrapper functions --- function _getCurrentResponse() internal view returns (OracleResponse memory response) { // Secondly, try to get latest price data: try oracle.valueFor(erc2362id) returns ( int256 lastPrice, uint256 lastTimestamp, uint256 /* latestUpdateStatus */ ) { // If call to Witnet succeeds, return the response and success = true response.answer = _scalePriceByDigits(uint256(lastPrice), decimals); response.timestamp = lastTimestamp; response.success = true; return response; } catch { // If call to Witnet aggregator reverts, return a zero response with success = false return response; } } }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_oracle","internalType":"contract IERC2362"},{"type":"bytes4","name":"_erc2362id","internalType":"bytes4"},{"type":"uint256","name":"_decimals","internalType":"uint256"},{"type":"uint256","name":"_timeout","internalType":"uint256"}]},{"type":"event","name":"LastGoodPriceUpdated","inputs":[{"type":"uint256","name":"_lastGoodPrice","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"PriceFeedStatusChanged","inputs":[{"type":"uint8","name":"newStatus","internalType":"enum WitnetPriceFeed.Status","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"DECIMAL_PRECISION","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_PRICE_DEVIATION_FROM_PREVIOUS_ROUND","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_PRICE_DIFFERENCE_BETWEEN_ORACLES","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"TARGET_DIGITS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"TIMEOUT","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes4","name":"","internalType":"bytes4"}],"name":"erc2362id","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"fetchPrice","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastGoodPrice","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC2362"}],"name":"oracle","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"enum WitnetPriceFeed.Status"}],"name":"status","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"updatePrice","inputs":[]}]
Contract Creation Code
0x60a06040523480156200001157600080fd5b5060405162000c8038038062000c80833981810160405260808110156200003757600080fd5b50805160208201516040830151606090930151600080546001600160a01b0319166001600160a01b0385161763ffffffff60a01b1916600160a01b60e085901c02178155600185905560808290526003805460ff19169055929391926200009d62000131565b9050620000aa8162000203565b158015620000d4575081620000d28260200151426200025860201b620002b71790919060201c565b105b620001115760405162461bcd60e51b815260040180806020018281038252602d81526020018062000c32602d913960400191505060405180910390fd5b8051600154620001229190620002ab565b60025550620004e09350505050565b6200013b620004bd565b6000546040805163f78eea8360e01b81526001600160e01b0319600160a01b840460e01b16600482015290516001600160a01b039092169163f78eea8391602480820192606092909190829003018186803b1580156200019a57600080fd5b505afa925050508015620001d057506040513d6060811015620001bc57600080fd5b508051602082015160409092015190919060015b620001db5762000200565b620001ef83600154620002ab60201b60201c565b845250602083015250600160408201525b90565b60008160400151620002185750600162000253565b602082015115806200022d5750428260200151115b156200023c5750600162000253565b81516000126200024f5750600162000253565b5060005b919050565b6000620002a283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506200031160201b60201c565b90505b92915050565b60008060128310620002df57620002d760128403600a0a85620003ac60201b620003021790919060201c565b9050620002a2565b6012831015620002a2576200030983601203600a0a85620003f660201b620003441790919060201c565b949350505050565b60008184841115620003a45760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015620003685781810151838201526020016200034e565b50505050905090810190601f168015620003965780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000620002a283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506200045460201b60201c565b6000826200040757506000620002a5565b828202828482816200041557fe5b0414620002a25760405162461bcd60e51b815260040180806020018281038252602181526020018062000c5f6021913960400191505060405180910390fd5b60008183620004a65760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315620003685781810151838201526020016200034e565b506000838581620004b357fe5b0495945050505050565b604051806060016040528060008152602001600081526020016000151581525090565b6080516107326200050060003980610295528061063652506107326000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c806358a6aa881161007157806358a6aa881461011c578063673a7e28146101245780637dc0d1d01461012c578063a20baee614610150578063efac30df14610158578063f56f48f21461017d576100b4565b80630490be83146100b95780630fdb11cf146100d35780631be5c92f146100db578063200d2ed2146100e3578063313ce5671461010c57806345079cb414610114575b600080fd5b6100c1610185565b60408051918252519081900360200190f35b6100c161018b565b6100c161019e565b6100eb6101a3565b604051808260018111156100fb57fe5b815260200191505060405180910390f35b6100c16101ac565b6100c16101b2565b6100c16101bd565b6100c16101c9565b610134610268565b604080516001600160a01b039092168252519081900360200190f35b6100c1610277565b610160610283565b604080516001600160e01b03199092168252519081900360200190f35b6100c1610293565b60025481565b60008061019661039d565b925050505b90565b601281565b60035460ff1681565b60015481565b66b1a2bc2ec5000081565b6706f05b59d3b2000081565b60008060006101d661039d565b600281905590925090508160018111156101ec57fe5b60035460ff1660018111156101fd57fe5b14610262576003805483919060ff19166001838181111561021a57fe5b02179055507f5c57579a8214fe4f710c1c56fa829f045b9fa6d225a744225a30c32188064d4e826040518082600181111561025157fe5b815260200191505060405180910390a15b91505090565b6000546001600160a01b031681565b670de0b6b3a764000081565b600054600160a01b900460e01b81565b7f000000000000000000000000000000000000000000000000000000000000000081565b60006102f983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610424565b90505b92915050565b60006102f983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506104bb565b600082610353575060006102fc565b8282028284828161036057fe5b04146102f95760405162461bcd60e51b81526004018080602001828103825260218152602001806106dc6021913960400191505060405180910390fd5b60008060006103aa610520565b9050600060035460ff1660018111156103bf57fe5b14156103fc576103ce816105e4565b806103dd57506103dd81610632565b156103f057505060025460019150610420565b51600092509050610420565b600160035460ff16600181111561040f57fe5b141561041e576103ce816105e4565b505b9091565b600081848411156104b35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610478578181015183820152602001610460565b50505050905090810190601f1680156104a55780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000818361050a5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610478578181015183820152602001610460565b50600083858161051657fe5b0495945050505050565b6105286106b8565b6000546040805163f78eea8360e01b81526001600160e01b0319600160a01b840460e01b16600482015290516001600160a01b039092169163f78eea8391602480820192606092909190829003018186803b15801561058657600080fd5b505afa9250505080156105ba57506040513d60608110156105a657600080fd5b508051602082015160409092015190919060015b6105c35761019b565b6105cf83600154610673565b8452506020830152506001604082015261019b565b600081604001516105f75750600161062d565b6020820151158061060b5750428260200151115b156106185750600161062d565b81516000126106295750600161062d565b5060005b919050565b60007f000000000000000000000000000000000000000000000000000000000000000061066c8360200151426102b790919063ffffffff16565b1192915050565b600080601283106106965761068f846011198501600a0a610302565b90506102f9565b60128310156102f9576106b0846012859003600a0a610344565b949350505050565b60405180606001604052806000815260200160008152602001600015158152509056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a26469706673582212209f9e53197789bb5bf625443e882176c9432d8e333af100d9d0db9cc5bf71395364736f6c634300070600335072696365466565643a205769746e6574206d75737420626520776f726b696e6720616e642063757272656e74536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77000000000000000000000000d39d4d972c7e166856c4eb29e54d3548b4597f534c80cf2e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000015180
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106100b45760003560e01c806358a6aa881161007157806358a6aa881461011c578063673a7e28146101245780637dc0d1d01461012c578063a20baee614610150578063efac30df14610158578063f56f48f21461017d576100b4565b80630490be83146100b95780630fdb11cf146100d35780631be5c92f146100db578063200d2ed2146100e3578063313ce5671461010c57806345079cb414610114575b600080fd5b6100c1610185565b60408051918252519081900360200190f35b6100c161018b565b6100c161019e565b6100eb6101a3565b604051808260018111156100fb57fe5b815260200191505060405180910390f35b6100c16101ac565b6100c16101b2565b6100c16101bd565b6100c16101c9565b610134610268565b604080516001600160a01b039092168252519081900360200190f35b6100c1610277565b610160610283565b604080516001600160e01b03199092168252519081900360200190f35b6100c1610293565b60025481565b60008061019661039d565b925050505b90565b601281565b60035460ff1681565b60015481565b66b1a2bc2ec5000081565b6706f05b59d3b2000081565b60008060006101d661039d565b600281905590925090508160018111156101ec57fe5b60035460ff1660018111156101fd57fe5b14610262576003805483919060ff19166001838181111561021a57fe5b02179055507f5c57579a8214fe4f710c1c56fa829f045b9fa6d225a744225a30c32188064d4e826040518082600181111561025157fe5b815260200191505060405180910390a15b91505090565b6000546001600160a01b031681565b670de0b6b3a764000081565b600054600160a01b900460e01b81565b7f000000000000000000000000000000000000000000000000000000000001518081565b60006102f983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610424565b90505b92915050565b60006102f983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506104bb565b600082610353575060006102fc565b8282028284828161036057fe5b04146102f95760405162461bcd60e51b81526004018080602001828103825260218152602001806106dc6021913960400191505060405180910390fd5b60008060006103aa610520565b9050600060035460ff1660018111156103bf57fe5b14156103fc576103ce816105e4565b806103dd57506103dd81610632565b156103f057505060025460019150610420565b51600092509050610420565b600160035460ff16600181111561040f57fe5b141561041e576103ce816105e4565b505b9091565b600081848411156104b35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610478578181015183820152602001610460565b50505050905090810190601f1680156104a55780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000818361050a5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610478578181015183820152602001610460565b50600083858161051657fe5b0495945050505050565b6105286106b8565b6000546040805163f78eea8360e01b81526001600160e01b0319600160a01b840460e01b16600482015290516001600160a01b039092169163f78eea8391602480820192606092909190829003018186803b15801561058657600080fd5b505afa9250505080156105ba57506040513d60608110156105a657600080fd5b508051602082015160409092015190919060015b6105c35761019b565b6105cf83600154610673565b8452506020830152506001604082015261019b565b600081604001516105f75750600161062d565b6020820151158061060b5750428260200151115b156106185750600161062d565b81516000126106295750600161062d565b5060005b919050565b60007f000000000000000000000000000000000000000000000000000000000001518061066c8360200151426102b790919063ffffffff16565b1192915050565b600080601283106106965761068f846011198501600a0a610302565b90506102f9565b60128310156102f9576106b0846012859003600a0a610344565b949350505050565b60405180606001604052806000815260200160008152602001600015158152509056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a26469706673582212209f9e53197789bb5bf625443e882176c9432d8e333af100d9d0db9cc5bf71395364736f6c63430007060033