Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Sponsored
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x61010060 | 24710424 | 716 days ago | IN | 0 ETH | 0.001179238744 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
107317810 | 411 days ago | 0 ETH | ||||
107317810 | 411 days ago | 0 ETH | ||||
107317810 | 411 days ago | 0 ETH | ||||
107317810 | 411 days ago | 0 ETH | ||||
107317810 | 411 days ago | 0 ETH | ||||
107317810 | 411 days ago | 0 ETH | ||||
107317810 | 411 days ago | 0 ETH | ||||
107317810 | 411 days ago | 0 ETH | ||||
107317810 | 411 days ago | 0 ETH | ||||
107317810 | 411 days ago | 0 ETH | ||||
107317810 | 411 days ago | 0 ETH | ||||
107317810 | 411 days ago | 0 ETH | ||||
107317722 | 411 days ago | 0 ETH | ||||
107317722 | 411 days ago | 0 ETH | ||||
107189115 | 414 days ago | 0 ETH | ||||
107189115 | 414 days ago | 0 ETH | ||||
107189115 | 414 days ago | 0 ETH | ||||
107189115 | 414 days ago | 0 ETH | ||||
107185728 | 414 days ago | 0 ETH | ||||
107185728 | 414 days ago | 0 ETH | ||||
107185728 | 414 days ago | 0 ETH | ||||
107185728 | 414 days ago | 0 ETH | ||||
107006498 | 418 days ago | 0 ETH | ||||
107006498 | 418 days ago | 0 ETH | ||||
106831779 | 423 days ago | 0 ETH |
Loading...
Loading
Contract Name:
LyraOptionMarketWrapperContractGuardRollups
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 20 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // dHEDGE DAO - https://dhedge.org // // Copyright (c) 2021 dHEDGE DAO // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; pragma abicoder v2; import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./LyraOptionMarketWrapperContractGuard.sol"; import "../../interfaces/IERC20Extended.sol"; import "../../utils/TxDataUtils.sol"; import "../../utils/tracker/DhedgeNftTrackerStorage.sol"; import "../../interfaces/guards/ITxTrackingGuard.sol"; import "../../interfaces/IPoolLogic.sol"; import "../../interfaces/IPoolManagerLogic.sol"; import "../../interfaces/IHasSupportedAsset.sol"; import "../../interfaces/lyra/IOptionMarket.sol"; import "../../interfaces/lyra/IOptionMarketViewer.sol"; import "../../interfaces/lyra/IOptionMarketWrapper.sol"; import "../../interfaces/lyra/ISynthetixAdapter.sol"; import "../../interfaces/lyra/IShortCollateral.sol"; import "../../interfaces/synthetix/IAddressResolver.sol"; /// @title Transaction guard for Lyra OptionMarketWrapper (rollups) /// here we support the rollup functions mentioned in https://github.com/lyra-finance/lyra-protocol/blob/master/contracts/periphery/Wrapper/OptionMarketWrapper.sol contract LyraOptionMarketWrapperContractGuardRollups is LyraOptionMarketWrapperContractGuard { using SafeMathUpgradeable for uint256; constructor( address _marketWrapper, address _marketViewer, address _nftTracker, uint256 _maxPositionCount ) LyraOptionMarketWrapperContractGuard(_marketWrapper, _marketViewer, _nftTracker, _maxPositionCount) // solhint-disable-next-line no-empty-blocks { } /// @notice Transaction guard for OptionMarketWrapper - used for Toros /// @dev It supports close/open/forceClose position /// @param _poolManagerLogic the pool manager logic /// @param data the transaction data /// @return txType the transaction type of a given transaction data. /// @return isPublic if the transaction is public or private function txGuard( address _poolManagerLogic, address to, bytes calldata data ) public override returns (uint16 txType, bool isPublic) { IHasSupportedAsset poolManagerLogicAssets = IHasSupportedAsset(_poolManagerLogic); require(poolManagerLogicAssets.isSupportedAsset(to), "lyra not enabled"); settleExpiredAndFilterActivePositions(IPoolManagerLogic(_poolManagerLogic).poolLogic()); bytes4 method = getMethod(data); if ( method == IOptionMarketWrapper.openLong.selector || method == IOptionMarketWrapper.addLong.selector || method == IOptionMarketWrapper.openShort.selector || method == IOptionMarketWrapper.addShort.selector ) { uint256 params = abi.decode(getParams(data), (uint256)); (IOptionMarketWrapper.OptionPositionParams memory optionPositionParams, ) = _getOptionParam(method, params); _checkSupportedAsset( poolManagerLogicAssets, optionPositionParams.optionType, address(optionPositionParams.optionMarket) ); txType = 26; settleExpiredAndFilterActivePositions(IPoolManagerLogic(_poolManagerLogic).poolLogic()); } else if ( method == IOptionMarketWrapper.reduceLong.selector || method == IOptionMarketWrapper.closeLong.selector || method == IOptionMarketWrapper.reduceShort.selector || method == IOptionMarketWrapper.closeShort.selector ) { uint256 params = abi.decode(getParams(data), (uint256)); (IOptionMarketWrapper.OptionPositionParams memory optionPositionParams, bool isForceClose) = _getOptionParam( method, params ); _checkSupportedAsset( poolManagerLogicAssets, optionPositionParams.optionType, address(optionPositionParams.optionMarket) ); txType = (isForceClose) ? 28 : 27; settleExpiredAndFilterActivePositions(IPoolManagerLogic(_poolManagerLogic).poolLogic()); } else { (txType, isPublic) = super.txGuard(_poolManagerLogic, to, data); } return (txType, isPublic); } /// @notice This function is called after execution transaction (used to track transactions) /// @dev It supports close/open/forceClose position /// @param _poolManagerLogic the pool manager logic /// @param data the transaction data function afterTxGuard( address _poolManagerLogic, address to, bytes calldata data ) public override { address poolLogic = IPoolManagerLogic(_poolManagerLogic).poolLogic(); require(msg.sender == poolLogic, "not pool logic"); bytes4 method = getMethod(data); if ( method == IOptionMarketWrapper.openLong.selector || method == IOptionMarketWrapper.addLong.selector || method == IOptionMarketWrapper.reduceLong.selector || method == IOptionMarketWrapper.closeLong.selector || method == IOptionMarketWrapper.openShort.selector || method == IOptionMarketWrapper.addShort.selector || method == IOptionMarketWrapper.reduceShort.selector || method == IOptionMarketWrapper.closeShort.selector ) { uint256 params = abi.decode(getParams(data), (uint256)); (IOptionMarketWrapper.OptionPositionParams memory optionPositionParams, ) = _getOptionParam(method, params); afterTxGuardHandle(poolLogic, address(optionPositionParams.optionMarket), optionPositionParams.positionId); } else { super.afterTxGuard(_poolManagerLogic, to, data); } } function _getOptionParam(bytes4 method, uint256 params) internal view returns (IOptionMarketWrapper.OptionPositionParams memory optionPositionParams, bool isForceClose) { if (method == IOptionMarketWrapper.openLong.selector) { address inputAsset = _getOptionInputAsset(params); optionPositionParams = IOptionMarketWrapper.OptionPositionParams({ optionMarket: IOptionMarket(_getOptionMarket(params)), strikeId: _parseUint32(params >> 32), positionId: 0, iterations: _parseUint8(params >> 24), currentCollateral: 0, setCollateralTo: 0, optionType: uint8(params >> 16) > 0 ? IOptionMarket.OptionType.LONG_CALL : IOptionMarket.OptionType.LONG_PUT, amount: _parseUint64Amount(params >> 128), minCost: 0, maxCost: _parseUint32Amount(params >> 64), inputAmount: _convertDecimal(_parseUint32(params >> 96), inputAsset), inputAsset: IERC20(inputAsset) }); } else if (method == IOptionMarketWrapper.addLong.selector) { address optionMarket = _getOptionMarket(params); address inputAsset = _getOptionInputAsset(params); IOptionMarketWrapper.OptionMarketContracts memory c = IOptionMarketWrapper(marketWrapper).marketContracts( IOptionMarket(optionMarket) ); IOptionToken.OptionPosition memory position = c.optionToken.positions(uint256(uint32(params >> 24))); optionPositionParams = IOptionMarketWrapper.OptionPositionParams({ optionMarket: IOptionMarket(optionMarket), strikeId: position.strikeId, positionId: position.positionId, iterations: _parseUint8(params >> 16), currentCollateral: 0, setCollateralTo: 0, optionType: position.optionType, amount: _parseUint64Amount(params >> 120), minCost: 0, maxCost: _parseUint32Amount(params >> 56), inputAmount: _convertDecimal(_parseUint32(params >> 88), inputAsset), inputAsset: IERC20(inputAsset) }); } else if (method == IOptionMarketWrapper.reduceLong.selector) { address optionMarket = _getOptionMarket(params); address inputAsset = _getOptionInputAsset(params); IOptionMarketWrapper.OptionMarketContracts memory c = IOptionMarketWrapper(marketWrapper).marketContracts( IOptionMarket(optionMarket) ); IOptionToken.OptionPosition memory position = c.optionToken.positions(uint256(uint32(params >> 32))); optionPositionParams = IOptionMarketWrapper.OptionPositionParams({ optionMarket: IOptionMarket(optionMarket), strikeId: position.strikeId, positionId: position.positionId, iterations: _parseUint8(params >> 16), currentCollateral: 0, setCollateralTo: 0, optionType: position.optionType, amount: _parseUint64Amount(params >> 96), minCost: _parseUint32Amount(params >> 160), maxCost: type(uint256).max, inputAmount: _convertDecimal(_parseUint32(params >> 64), inputAsset), inputAsset: IERC20(inputAsset) }); isForceClose = (uint8(params >> 24) > 0); } else if (method == IOptionMarketWrapper.closeLong.selector) { address optionMarket = _getOptionMarket(params); address inputAsset = _getOptionInputAsset(params); IOptionMarketWrapper.OptionMarketContracts memory c = IOptionMarketWrapper(marketWrapper).marketContracts( IOptionMarket(optionMarket) ); IOptionToken.OptionPosition memory position = c.optionToken.positions(uint256(uint32(params >> 32))); optionPositionParams = IOptionMarketWrapper.OptionPositionParams({ optionMarket: IOptionMarket(optionMarket), strikeId: position.strikeId, positionId: position.positionId, iterations: _parseUint8(params >> 16), currentCollateral: 0, setCollateralTo: 0, optionType: position.optionType, amount: position.amount, minCost: _parseUint32Amount(params >> 96), maxCost: type(uint256).max, inputAmount: _convertDecimal(_parseUint32(params >> 64), inputAsset), inputAsset: IERC20(inputAsset) }); isForceClose = (uint8(params >> 24) > 0); } else if (method == IOptionMarketWrapper.openShort.selector) { address inputAsset = _getOptionInputAsset(params); optionPositionParams = IOptionMarketWrapper.OptionPositionParams({ optionMarket: IOptionMarket(_getOptionMarket(params)), strikeId: uint256(uint32(params >> 32)), positionId: 0, iterations: _parseUint8(params >> 24), currentCollateral: 0, setCollateralTo: _parseUint64Amount(params >> 192), optionType: IOptionMarket.OptionType(uint8(params >> 16)), amount: _parseUint64Amount(params >> 128), minCost: _parseUint32Amount(params >> 64), maxCost: type(uint256).max, inputAmount: _convertDecimal(_parseUint32(params >> 96), inputAsset), inputAsset: IERC20(inputAsset) }); } else if (method == IOptionMarketWrapper.addShort.selector) { address optionMarket = _getOptionMarket(params); address inputAsset = _getOptionInputAsset(params); IOptionMarketWrapper.OptionMarketContracts memory c = IOptionMarketWrapper(marketWrapper).marketContracts( IOptionMarket(optionMarket) ); IOptionToken.OptionPosition memory position = c.optionToken.positions(uint256(uint32(params >> 24))); optionPositionParams = IOptionMarketWrapper.OptionPositionParams({ optionMarket: IOptionMarket(optionMarket), strikeId: position.strikeId, positionId: position.positionId, iterations: _parseUint8(params >> 16), setCollateralTo: _parseUint64Amount(params >> 184), currentCollateral: position.collateral, optionType: position.optionType, amount: _parseUint64Amount(params >> 120), minCost: _parseUint32Amount(params >> 88), maxCost: type(uint256).max, inputAmount: _convertDecimal(_parseUint32(params >> 56), inputAsset), inputAsset: IERC20(inputAsset) }); } else if (method == IOptionMarketWrapper.reduceShort.selector) { address optionMarket = _getOptionMarket(params); address inputAsset = _getOptionInputAsset(params); IOptionMarketWrapper.OptionMarketContracts memory c = IOptionMarketWrapper(marketWrapper).marketContracts( IOptionMarket(optionMarket) ); IOptionToken.OptionPosition memory position = c.optionToken.positions(uint256(uint32(params >> 32))); optionPositionParams = IOptionMarketWrapper.OptionPositionParams({ optionMarket: IOptionMarket(optionMarket), strikeId: position.strikeId, positionId: position.positionId, iterations: _parseUint8(params >> 16), setCollateralTo: _parseUint64Amount(params >> 196), currentCollateral: position.collateral, optionType: position.optionType, amount: _parseUint64Amount(params >> 128), minCost: 0, maxCost: _parseUint32Amount(params >> 96), inputAmount: _convertDecimal(_parseUint32(params >> 64), inputAsset), inputAsset: IERC20(inputAsset) }); isForceClose = (uint8(params >> 24) > 0); } else if (method == IOptionMarketWrapper.closeShort.selector) { address optionMarket = _getOptionMarket(params); address inputAsset = _getOptionInputAsset(params); IOptionMarketWrapper.OptionMarketContracts memory c = IOptionMarketWrapper(marketWrapper).marketContracts( IOptionMarket(optionMarket) ); IOptionToken.OptionPosition memory position = c.optionToken.positions(uint256(uint32(params >> 32))); optionPositionParams = IOptionMarketWrapper.OptionPositionParams({ optionMarket: IOptionMarket(optionMarket), strikeId: position.strikeId, positionId: position.positionId, iterations: _parseUint8(params >> 16), currentCollateral: position.collateral, setCollateralTo: 0, optionType: position.optionType, amount: position.amount, minCost: 0, maxCost: _parseUint32Amount(params >> 96), inputAmount: _convertDecimal(_parseUint32(params >> 64), inputAsset), inputAsset: IERC20(inputAsset) }); isForceClose = (uint8(params >> 24) > 0); } else { revert("invalid method"); } } function _parseUint8(uint256 inp) internal pure returns (uint256) { return uint256(uint8(inp)); } function _parseUint32Amount(uint256 inp) internal pure returns (uint256) { return _parseUint32(inp) * 1e16; } function _parseUint32(uint256 inp) internal pure returns (uint256) { return uint256(uint32(inp)); } function _parseUint64Amount(uint256 inp) internal pure returns (uint256) { return uint256(uint64(inp)) * 1e10; } function _convertDecimal(uint256 amount, address inputAsset) internal view returns (uint256 newAmount) { newAmount = amount * (10**(IERC20Extended(inputAsset).decimals() - 2)); } function _getOptionMarket(uint256 params) internal view returns (address) { return IOptionMarketWrapper(marketWrapper).idToMarket(uint8(params)); } function _getOptionInputAsset(uint256 params) internal view returns (address) { return IOptionMarketWrapper(marketWrapper).idToERC(uint8(params >> 8)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @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 SafeMathUpgradeable { /** * @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) { 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) { 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) { // 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) { 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) { 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) { 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) { require(b <= a, "SafeMath: subtraction overflow"); 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) { 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, reverting 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) { require(b > 0, "SafeMath: division by zero"); 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) { require(b > 0, "SafeMath: modulo by zero"); 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) { 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. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * 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) { 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) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, 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); }
// __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // dHEDGE DAO - https://dhedge.org // // Copyright (c) 2021 dHEDGE DAO // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; pragma abicoder v2; import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "../../utils/TxDataUtils.sol"; import "../../utils/tracker/DhedgeNftTrackerStorage.sol"; import "../../interfaces/guards/ITxTrackingGuard.sol"; import "../../interfaces/IPoolLogic.sol"; import "../../interfaces/IPoolManagerLogic.sol"; import "../../interfaces/IHasSupportedAsset.sol"; import "../../interfaces/lyra/IOptionMarket.sol"; import "../../interfaces/lyra/IOptionMarketViewer.sol"; import "../../interfaces/lyra/IOptionMarketWrapper.sol"; import "../../interfaces/lyra/ISynthetixAdapter.sol"; import "../../interfaces/lyra/IShortCollateral.sol"; import "../../interfaces/synthetix/IAddressResolver.sol"; /// @title Transaction guard for Lyra OptionMarketWrapper contract LyraOptionMarketWrapperContractGuard is TxDataUtils, ITxTrackingGuard { using SafeMathUpgradeable for uint256; bytes32 public constant NFT_TYPE = keccak256("LYRA_NFT_TYPE"); address public immutable marketWrapper; IOptionMarketViewer public immutable marketViewer; address public immutable nftTracker; uint256 public immutable maxPositionCount; struct OptionPosition { address optionMarket; uint256 positionId; } bool public override isTxTrackingGuard = true; constructor( address _marketWrapper, address _marketViewer, address _nftTracker, uint256 _maxPositionCount ) { marketWrapper = _marketWrapper; marketViewer = IOptionMarketViewer(_marketViewer); nftTracker = _nftTracker; maxPositionCount = _maxPositionCount; } function getOptionPositions(address poolLogic) public view returns (OptionPosition[] memory optionPositions) { bytes[] memory data = DhedgeNftTrackerStorage(nftTracker).getAllData(NFT_TYPE, poolLogic); optionPositions = new OptionPosition[](data.length); for (uint256 i = 0; i < data.length; i++) { optionPositions[i] = abi.decode(data[i], (OptionPosition)); } } /// @notice Transaction guard for OptionMarketWrapper - used for Toros /// @dev It supports close/open/forceClose position /// @param _poolManagerLogic the pool manager logic /// @param data the transaction data /// @return txType the transaction type of a given transaction data. /// @return isPublic if the transaction is public or private function txGuard( address _poolManagerLogic, address to, bytes calldata data ) public virtual override returns ( uint16 txType, bool // isPublic ) { IHasSupportedAsset poolManagerLogicAssets = IHasSupportedAsset(_poolManagerLogic); require(poolManagerLogicAssets.isSupportedAsset(to), "lyra not enabled"); settleExpiredAndFilterActivePositions(IPoolManagerLogic(_poolManagerLogic).poolLogic()); bytes4 method = getMethod(data); if (method == IOptionMarketWrapper.openPosition.selector) { IOptionMarketWrapper.OptionPositionParams memory params = abi.decode( getParams(data), (IOptionMarketWrapper.OptionPositionParams) ); _checkSupportedAsset(poolManagerLogicAssets, params.optionType, address(params.optionMarket)); txType = 26; settleExpiredAndFilterActivePositions(IPoolManagerLogic(_poolManagerLogic).poolLogic()); } else if (method == IOptionMarketWrapper.closePosition.selector) { IOptionMarketWrapper.OptionPositionParams memory params = abi.decode( getParams(data), (IOptionMarketWrapper.OptionPositionParams) ); _checkSupportedAsset(poolManagerLogicAssets, params.optionType, address(params.optionMarket)); txType = 27; settleExpiredAndFilterActivePositions(IPoolManagerLogic(_poolManagerLogic).poolLogic()); } else if (method == IOptionMarketWrapper.forceClosePosition.selector) { IOptionMarketWrapper.OptionPositionParams memory params = abi.decode( getParams(data), (IOptionMarketWrapper.OptionPositionParams) ); _checkSupportedAsset(poolManagerLogicAssets, params.optionType, address(params.optionMarket)); txType = 28; settleExpiredAndFilterActivePositions(IPoolManagerLogic(_poolManagerLogic).poolLogic()); } return (txType, false); } function _checkSupportedAsset( IHasSupportedAsset poolManagerLogic, IOptionMarket.OptionType optionType, address optionMarket ) internal view { IOptionMarketViewer.OptionMarketAddresses memory optionMarketAddresses = marketViewer.marketAddresses(optionMarket); // if short-call-base option type, check base asset if (optionType == IOptionMarket.OptionType.SHORT_CALL_BASE) { require(poolManagerLogic.isSupportedAsset(address(optionMarketAddresses.baseAsset)), "unsupported base asset"); } else { // otherwise, check quote asset require(poolManagerLogic.isSupportedAsset(address(optionMarketAddresses.quoteAsset)), "unsupported quote asset"); } } /// @notice This function is called after execution transaction (used to track transactions) /// @dev It supports close/open/forceClose position /// @param _poolManagerLogic the pool manager logic /// @param data the transaction data function afterTxGuard( address _poolManagerLogic, address, // to bytes calldata data ) public virtual override { address poolLogic = IPoolManagerLogic(_poolManagerLogic).poolLogic(); require(msg.sender == poolLogic, "not pool logic"); IOptionMarketWrapper.OptionPositionParams memory params = abi.decode( getParams(data), (IOptionMarketWrapper.OptionPositionParams) ); afterTxGuardHandle(poolLogic, address(params.optionMarket), params.positionId); } function afterTxGuardHandle( address poolLogic, address optionMarket, uint256 positionId ) internal { IOptionMarketViewer.OptionMarketAddresses memory optionMarketAddresses = marketViewer.marketAddresses(optionMarket); // If the manager is not specifying a positionId it means he must be creating a new position // We use the optionMakets "nextId" to determine the last Id created and store that for the pool // "nextId" starts from 1 so the positionId starts from 1. if (positionId == 0) { // New position created, We use the nextId sub 1 as this code runs after the creation of the option. DhedgeNftTrackerStorage(nftTracker).addData( marketWrapper, NFT_TYPE, poolLogic, abi.encode( OptionPosition({ optionMarket: optionMarket, positionId: IOptionToken(optionMarketAddresses.optionToken).nextId().sub(1) }) ) ); require( DhedgeNftTrackerStorage(nftTracker).getDataCount(NFT_TYPE, poolLogic) <= maxPositionCount, "exceed maximum position count" ); // If the manager is specifying a positionId it must mean he is trying to make changes to an existing one // We detect if it is closed and remove it from storage } else { IOptionToken.PositionState positionState = IOptionToken(optionMarketAddresses.optionToken).getPositionState( positionId ); // find option position from nft tracker OptionPosition[] memory optionPositions = getOptionPositions(poolLogic); uint256 i; for (i = 0; i < optionPositions.length; i++) { if (optionPositions[i].optionMarket == optionMarket && optionPositions[i].positionId == positionId) { break; } } require(i < optionPositions.length, "position is not in track"); if (positionState != IOptionToken.PositionState.ACTIVE) { // If the position is not active remove it from nft tracker DhedgeNftTrackerStorage(nftTracker).removeData(marketWrapper, NFT_TYPE, poolLogic, i); } } } function removeClosedPosition( address poolLogic, address optionMarket, uint256 positionId ) external { OptionPosition[] memory optionPositions = getOptionPositions(poolLogic); // We need to find which array index is the position we want to delete for (uint256 i = 0; i < optionPositions.length; i++) { if (optionPositions[i].optionMarket == optionMarket && optionPositions[i].positionId == positionId) { IOptionMarketViewer.OptionMarketAddresses memory optionMarketAddresses = marketViewer.marketAddresses( optionMarket ); // Once we find it we check to make sure the postion is not active require( IOptionToken(optionMarketAddresses.optionToken).getPositionState(positionId) != IOptionToken.PositionState.ACTIVE, "not closed position" ); DhedgeNftTrackerStorage(nftTracker).removeData(marketWrapper, NFT_TYPE, poolLogic, i); break; } } } function settleExpiredAndFilterActivePositions(address poolLogic) public { IHasSupportedAsset poolManagerLogicAssets = IHasSupportedAsset(IPoolLogic(poolLogic).poolManagerLogic()); OptionPosition[] memory optionPositions = getOptionPositions(poolLogic); // 1. we filter active option positions // 2. we settle expired option positions // 3. we removed expired/inactive option positions from nft tracker for (uint256 i = optionPositions.length; i > 0; i--) { uint256 index = i - 1; IOptionMarketViewer.OptionMarketAddresses memory optionMarketAddresses = marketViewer.marketAddresses( optionPositions[index].optionMarket ); IOptionToken.OptionPosition memory position = IOptionToken(optionMarketAddresses.optionToken).positions( optionPositions[index].positionId ); if (position.state == IOptionToken.PositionState.ACTIVE) { (, uint256 priceAtExpiry, ) = IOptionMarket(optionPositions[index].optionMarket).getSettlementParameters( position.strikeId ); if (priceAtExpiry == 0) { continue; } // settlement will return base or quote asset back to the pool // we check if quote/base asset is supported for option position type _checkSupportedAsset(poolManagerLogicAssets, position.optionType, optionPositions[index].optionMarket); uint256[] memory positionsToSettle = new uint256[](1); positionsToSettle[0] = optionPositions[index].positionId; IShortCollateral(optionMarketAddresses.shortCollateral).settleOptions(positionsToSettle); } DhedgeNftTrackerStorage(nftTracker).removeData(marketWrapper, NFT_TYPE, poolLogic, index); } } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; // With aditional optional views interface IERC20Extended { // ERC20 Optional Views function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); // Views function totalSupply() external view returns (uint256); function balanceOf(address owner) external view returns (uint256); function scaledBalanceOf(address user) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); // Mutative functions function transfer(address to, uint256 value) external returns (bool); function approve(address spender, uint256 value) external returns (bool); function transferFrom( address from, address to, uint256 value ) external returns (bool); // Events event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); }
// __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // dHEDGE DAO - https://dhedge.org // // Copyright (c) 2021 dHEDGE DAO // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // // SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; import "@uniswap/v3-periphery/contracts/libraries/BytesLib.sol"; contract TxDataUtils { using BytesLib for bytes; using SafeMathUpgradeable for uint256; function getMethod(bytes memory data) public pure returns (bytes4) { return read4left(data, 0); } function getParams(bytes memory data) public pure returns (bytes memory) { return data.slice(4, data.length - 4); } function getInput(bytes memory data, uint8 inputNum) public pure returns (bytes32) { return read32(data, 32 * inputNum + 4, 32); } function getBytes( bytes memory data, uint8 inputNum, uint256 offset ) public pure returns (bytes memory) { require(offset < 20, "invalid offset"); // offset is in byte32 slots, not bytes offset = offset * 32; // convert offset to bytes uint256 bytesLenPos = uint256(read32(data, 32 * inputNum + 4 + offset, 32)); uint256 bytesLen = uint256(read32(data, bytesLenPos + 4 + offset, 32)); return data.slice(bytesLenPos + 4 + offset + 32, bytesLen); } function getArrayLast(bytes memory data, uint8 inputNum) public pure returns (bytes32) { bytes32 arrayPos = read32(data, 32 * inputNum + 4, 32); bytes32 arrayLen = read32(data, uint256(arrayPos) + 4, 32); require(arrayLen > 0, "input is not array"); return read32(data, uint256(arrayPos) + 4 + (uint256(arrayLen) * 32), 32); } function getArrayLength(bytes memory data, uint8 inputNum) public pure returns (uint256) { bytes32 arrayPos = read32(data, 32 * inputNum + 4, 32); return uint256(read32(data, uint256(arrayPos) + 4, 32)); } function getArrayIndex( bytes memory data, uint8 inputNum, uint8 arrayIndex ) public pure returns (bytes32) { bytes32 arrayPos = read32(data, 32 * inputNum + 4, 32); bytes32 arrayLen = read32(data, uint256(arrayPos) + 4, 32); require(arrayLen > 0, "input is not array"); require(uint256(arrayLen) > arrayIndex, "invalid array position"); return read32(data, uint256(arrayPos) + 4 + ((1 + uint256(arrayIndex)) * 32), 32); } function read4left(bytes memory data, uint256 offset) public pure returns (bytes4 o) { require(data.length >= offset + 4, "Reading bytes out of bounds"); assembly { o := mload(add(data, add(32, offset))) } } function read32( bytes memory data, uint256 offset, uint256 length ) public pure returns (bytes32 o) { require(data.length >= offset + length, "Reading bytes out of bounds"); assembly { o := mload(add(data, add(32, offset))) let lb := sub(32, length) if lb { o := div(o, exp(2, mul(lb, 8))) } } } function convert32toAddress(bytes32 data) public pure returns (address o) { return address(uint160(uint256(data))); } function sliceUint(bytes memory data, uint256 start) internal pure returns (uint256) { require(data.length >= start + 32, "slicing out of range"); uint256 x; assembly { x := mload(add(data, add(0x20, start))) } return x; } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma experimental ABIEncoderV2; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "../../interfaces/IHasGuardInfo.sol"; contract DhedgeNftTrackerStorage is OwnableUpgradeable { address public poolFactory; // dhedge pool factory mapping(bytes32 => mapping(address => bytes[])) internal _nftTrackData; // keccak of NFT_TYPE -> poolAddress -> data[] // solhint-disable-next-line no-empty-blocks function initialize(address _poolFactory) external initializer { __Ownable_init(); poolFactory = _poolFactory; } /// @notice implementations should not be left unintialized // solhint-disable-next-line no-empty-blocks function implInitializer() external initializer {} modifier checkContractGuard(address _guardedContract) { require(IHasGuardInfo(poolFactory).getContractGuard(_guardedContract) == msg.sender, "not correct contract guard"); _; } /** * @notice record new NFT data * @dev only called by authorized guard * @param _nftType keccak of NFT_TYPE * @param _pool the poolLogic address * @param _data the nft track data to be recorded in storage */ function addData( address _guardedContract, bytes32 _nftType, address _pool, bytes memory _data ) external checkContractGuard(_guardedContract) { _nftTrackData[_nftType][_pool].push(_data); } /** * @notice delete NFT data * @dev only called by authorized guard * @param _nftType keccak of NFT_TYPE * @param _pool the poolLogic address * @param _index the nft track data index to be removed from storage */ function removeData( address _guardedContract, bytes32 _nftType, address _pool, uint256 _index ) external checkContractGuard(_guardedContract) { uint256 length = _nftTrackData[_nftType][_pool].length; require(_index < length, "invalid index"); _nftTrackData[_nftType][_pool][_index] = _nftTrackData[_nftType][_pool][length - 1]; _nftTrackData[_nftType][_pool].pop(); } /** * @notice returns tracked nft by index * @param _nftType keccak of NFT_TYPE * @param _pool the poolLogic address * @param _index the index of nft track data * @return data the nft track data of given NFT_TYPE & poolLogic & index */ function getData( bytes32 _nftType, address _pool, uint256 _index ) external view returns (bytes memory) { return _nftTrackData[_nftType][_pool][_index]; } /** * @notice returns all tracked nfts by NFT_TYPE & poolLogic * @param _nftType keccak of NFT_TYPE * @param _pool the poolLogic address * @return data all tracked nfts of given NFT_TYPE & poolLogic */ function getAllData(bytes32 _nftType, address _pool) external view returns (bytes[] memory) { return _nftTrackData[_nftType][_pool]; } /** * @notice returns all tracked nfts by NFT_TYPE & poolLogic * @param _nftType keccak of NFT_TYPE * @param _pool the poolLogic address * @return count all tracked nfts count of given NFT_TYPE & poolLogic */ function getDataCount(bytes32 _nftType, address _pool) external view returns (uint256) { return _nftTrackData[_nftType][_pool].length; } }
// // __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // dHEDGE DAO - https://dhedge.org // // Copyright (c) 2021 dHEDGE DAO // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // // SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "./IGuard.sol"; interface ITxTrackingGuard is IGuard { function isTxTrackingGuard() external view returns (bool); function afterTxGuard( address poolManagerLogic, address to, bytes calldata data ) external; }
// // __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // dHEDGE DAO - https://dhedge.org // // Copyright (c) 2021 dHEDGE DAO // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // // SPDX-License-Identifier: MIT pragma solidity 0.7.6; interface IPoolLogic { function factory() external view returns (address); function poolManagerLogic() external view returns (address); function setPoolManagerLogic(address _poolManagerLogic) external returns (bool); function availableManagerFee() external view returns (uint256 fee); function tokenPrice() external view returns (uint256 price); function tokenPriceWithoutManagerFee() external view returns (uint256 price); function deposit(address _asset, uint256 _amount) external returns (uint256 liquidityMinted); function depositFor( address _recipient, address _asset, uint256 _amount ) external returns (uint256 liquidityMinted); function depositForWithCustomCooldown( address _recipient, address _asset, uint256 _amount, uint256 _cooldown ) external returns (uint256 liquidityMinted); function withdraw(uint256 _fundTokenAmount) external; function transfer(address to, uint256 value) external returns (bool); function balanceOf(address owner) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom( address from, address to, uint256 value ) external returns (bool); }
// // __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // dHEDGE DAO - https://dhedge.org // // Copyright (c) 2021 dHEDGE DAO // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // // SPDX-License-Identifier: MIT pragma solidity 0.7.6; interface IPoolManagerLogic { function poolLogic() external view returns (address); function isDepositAsset(address asset) external view returns (bool); function validateAsset(address asset) external view returns (bool); function assetValue(address asset) external view returns (uint256); function assetValue(address asset, uint256 amount) external view returns (uint256); function assetBalance(address asset) external view returns (uint256 balance); function factory() external view returns (address); function setPoolLogic(address fundAddress) external returns (bool); function totalFundValue() external view returns (uint256); function isMemberAllowed(address member) external view returns (bool); function getFee() external view returns ( uint256, uint256, uint256 ); }
// // __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // dHEDGE DAO - https://dhedge.org // // Copyright (c) 2021 dHEDGE DAO // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // // SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma experimental ABIEncoderV2; interface IHasSupportedAsset { struct Asset { address asset; bool isDeposit; } function getSupportedAssets() external view returns (Asset[] memory); function isSupportedAsset(address asset) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma experimental ABIEncoderV2; interface IOptionMarket { enum TradeDirection { OPEN, CLOSE, LIQUIDATE } enum OptionType { LONG_CALL, LONG_PUT, SHORT_CALL_BASE, SHORT_CALL_QUOTE, SHORT_PUT_QUOTE } struct Strike { // strike listing identifier uint256 id; // strike price uint256 strikePrice; // volatility component specific to the strike listing (boardIv * skew = vol of strike) uint256 skew; // total user long call exposure uint256 longCall; // total user short call (base collateral) exposure uint256 shortCallBase; // total user short call (quote collateral) exposure uint256 shortCallQuote; // total user long put exposure uint256 longPut; // total user short put (quote collateral) exposure uint256 shortPut; // id of board to which strike belongs uint256 boardId; } function getStrike(uint256 strikeId) external view returns (Strike memory); function getStrikeAndExpiry(uint256 strikeId) external view returns (uint256 strikePrice, uint256 expiry); function getSettlementParameters(uint256 strikeId) external view returns ( uint256 strikePrice, uint256 priceAtExpiry, uint256 strikeToBaseReturned ); }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./IOptionToken.sol"; import "./IOptionMarket.sol"; import "./IOptionGreekCache.sol"; interface IOptionMarketViewer { struct MarketOptionPositions { address market; IOptionToken.OptionPosition[] positions; } struct OptionMarketAddresses { address liquidityPool; address liquidityTokens; IOptionGreekCache greekCache; IOptionMarket optionMarket; address optionMarketPricer; IOptionToken optionToken; address shortCollateral; address poolHedger; IERC20 quoteAsset; IERC20 baseAsset; } function synthetixAdapter() external view returns (address); function getOwnerPositions(address owner) external view returns (IOptionToken.OptionPosition[] memory); function getMarketAddresses() external view returns (OptionMarketAddresses[] memory); function marketAddresses(address market) external view returns (OptionMarketAddresses memory); }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma experimental ABIEncoderV2; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./IOptionMarket.sol"; import "./IOptionToken.sol"; interface IOptionMarketWrapper { struct OptionMarketContracts { IERC20 quoteAsset; IERC20 baseAsset; IOptionToken optionToken; } struct OptionPositionParams { IOptionMarket optionMarket; uint256 strikeId; // The id of the relevant OptionListing uint256 positionId; uint256 iterations; uint256 setCollateralTo; uint256 currentCollateral; IOptionMarket.OptionType optionType; // Is the trade a long/short & call/put? uint256 amount; // The amount the user has requested to close uint256 minCost; // Min amount for the cost of the trade uint256 maxCost; // Max amount for the cost of the trade uint256 inputAmount; // Amount of stable coins the user can use IERC20 inputAsset; // Address of coin user wants to open with } struct ReturnDetails { address market; uint256 positionId; address owner; uint256 amount; uint256 totalCost; uint256 totalFee; int256 swapFee; address token; } function openPosition(OptionPositionParams memory params) external returns (ReturnDetails memory returnDetails); function closePosition(OptionPositionParams memory params) external returns (ReturnDetails memory returnDetails); function forceClosePosition(OptionPositionParams memory params) external returns (ReturnDetails memory returnDetails); function marketContracts(IOptionMarket market) external view returns (OptionMarketContracts memory); function idToMarket(uint8 id) external view returns (address optionMarket); function idToERC(uint8 id) external view returns (address token); function openLong(uint256 params) external returns (uint256 totalCost); function addLong(uint256 params) external returns (uint256 totalCost); function reduceLong(uint256 params) external returns (uint256 totalReceived); function closeLong(uint256 params) external returns (uint256 totalReceived); function openShort(uint256 params) external returns (uint256 totalReceived); function addShort(uint256 params) external returns (uint256 totalReceived); function reduceShort(uint256 params) external returns (uint256 totalCost); function closeShort(uint256 params) external returns (uint256 totalCost); }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./IOptionMarket.sol"; interface ISynthetixAdapter { function addressResolver() external view returns (address); function quoteKey(address) external view returns (bytes32); function baseKey(address) external view returns (bytes32); function getSpotPriceForMarket(address) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; interface IShortCollateral { function settleOptions(uint256[] memory positionIds) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; interface IAddressResolver { function getAddress(bytes32 name) external view returns (address); }
// SPDX-License-Identifier: GPL-2.0-or-later /* * @title Solidity Bytes Arrays Utils * @author Gonçalo Sá <[email protected]> * * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity. * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage. */ pragma solidity >=0.5.0 <0.8.0; library BytesLib { function slice( bytes memory _bytes, uint256 _start, uint256 _length ) internal pure returns (bytes memory) { require(_length + 31 >= _length, 'slice_overflow'); require(_start + _length >= _start, 'slice_overflow'); require(_bytes.length >= _start + _length, 'slice_outOfBounds'); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) { require(_start + 20 >= _start, 'toAddress_overflow'); require(_bytes.length >= _start + 20, 'toAddress_outOfBounds'); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint24(bytes memory _bytes, uint256 _start) internal pure returns (uint24) { require(_start + 3 >= _start, 'toUint24_overflow'); require(_bytes.length >= _start + 3, 'toUint24_outOfBounds'); uint24 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x3), _start)) } return tempUint; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal initializer { __Context_init_unchained(); __Ownable_init_unchained(); } function __Ownable_init_unchained() internal initializer { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } uint256[49] private __gap; }
// // __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // dHEDGE DAO - https://dhedge.org // // Copyright (c) 2021 dHEDGE DAO // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // // SPDX-License-Identifier: MIT pragma solidity 0.7.6; interface IHasGuardInfo { // Get guard function getContractGuard(address extContract) external view returns (address); // Get asset guard function getAssetGuard(address extContract) external view returns (address); // Get mapped addresses from Governance function getAddress(bytes32 name) external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../proxy/Initializable.sol"; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // solhint-disable-next-line compiler-version pragma solidity >=0.4.24 <0.8.0; import "../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || _isConstructor() || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /// @dev Returns true if and only if the function is running in the constructor function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// // __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // dHEDGE DAO - https://dhedge.org // // Copyright (c) 2021 dHEDGE DAO // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // // SPDX-License-Identifier: MIT pragma solidity 0.7.6; interface IGuard { event ExchangeFrom(address fundAddress, address sourceAsset, uint256 sourceAmount, address dstAsset, uint256 time); event ExchangeTo(address fundAddress, address sourceAsset, address dstAsset, uint256 dstAmount, uint256 time); function txGuard( address poolManagerLogic, address to, bytes calldata data ) external returns (uint16 txType, bool isPublic); }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import "@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol"; import "./IOptionMarket.sol"; interface IOptionToken is IERC721Enumerable { enum PositionState { EMPTY, ACTIVE, CLOSED, LIQUIDATED, SETTLED, MERGED } enum PositionUpdatedType { OPENED, ADJUSTED, CLOSED, SPLIT_FROM, SPLIT_INTO, MERGED, MERGED_INTO, SETTLED, LIQUIDATED, TRANSFER } struct OptionPosition { uint256 positionId; uint256 strikeId; IOptionMarket.OptionType optionType; uint256 amount; uint256 collateral; PositionState state; } struct PositionWithOwner { uint256 positionId; uint256 strikeId; IOptionMarket.OptionType optionType; uint256 amount; uint256 collateral; PositionState state; address owner; } function nextId() external view returns (uint256); function getOwnerPositions(address target) external view returns (OptionPosition[] memory); function positions(uint256 positionId) external view returns (OptionPosition memory); function getPositionState(uint256 positionId) external view returns (PositionState); function getPositionWithOwner(uint256 positionId) external view returns (PositionWithOwner memory); }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import "./IOptionMarket.sol"; interface IOptionGreekCache { function isGlobalCacheStale(uint256 spotPrice) external view returns (bool); function isBoardCacheStale(uint256 boardId) external view returns (bool); function updateBoardCachedGreeks(uint256 boardId) external; function getMinCollateral( IOptionMarket.OptionType optionType, uint256 strikePrice, uint256 expiry, uint256 spotPrice, uint256 amount ) external view returns (uint256 minCollateral); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "./IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "../../introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
{ "optimizer": { "enabled": true, "runs": 20 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_marketWrapper","type":"address"},{"internalType":"address","name":"_marketViewer","type":"address"},{"internalType":"address","name":"_nftTracker","type":"address"},{"internalType":"uint256","name":"_maxPositionCount","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"fundAddress","type":"address"},{"indexed":false,"internalType":"address","name":"sourceAsset","type":"address"},{"indexed":false,"internalType":"uint256","name":"sourceAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"dstAsset","type":"address"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"ExchangeFrom","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"fundAddress","type":"address"},{"indexed":false,"internalType":"address","name":"sourceAsset","type":"address"},{"indexed":false,"internalType":"address","name":"dstAsset","type":"address"},{"indexed":false,"internalType":"uint256","name":"dstAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"ExchangeTo","type":"event"},{"inputs":[],"name":"NFT_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_poolManagerLogic","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"afterTxGuard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"data","type":"bytes32"}],"name":"convert32toAddress","outputs":[{"internalType":"address","name":"o","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint8","name":"inputNum","type":"uint8"},{"internalType":"uint8","name":"arrayIndex","type":"uint8"}],"name":"getArrayIndex","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint8","name":"inputNum","type":"uint8"}],"name":"getArrayLast","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint8","name":"inputNum","type":"uint8"}],"name":"getArrayLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint8","name":"inputNum","type":"uint8"},{"internalType":"uint256","name":"offset","type":"uint256"}],"name":"getBytes","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint8","name":"inputNum","type":"uint8"}],"name":"getInput","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"getMethod","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"poolLogic","type":"address"}],"name":"getOptionPositions","outputs":[{"components":[{"internalType":"address","name":"optionMarket","type":"address"},{"internalType":"uint256","name":"positionId","type":"uint256"}],"internalType":"struct LyraOptionMarketWrapperContractGuard.OptionPosition[]","name":"optionPositions","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"getParams","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"isTxTrackingGuard","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketViewer","outputs":[{"internalType":"contract IOptionMarketViewer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketWrapper","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPositionCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nftTracker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"offset","type":"uint256"},{"internalType":"uint256","name":"length","type":"uint256"}],"name":"read32","outputs":[{"internalType":"bytes32","name":"o","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"offset","type":"uint256"}],"name":"read4left","outputs":[{"internalType":"bytes4","name":"o","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"poolLogic","type":"address"},{"internalType":"address","name":"optionMarket","type":"address"},{"internalType":"uint256","name":"positionId","type":"uint256"}],"name":"removeClosedPosition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"poolLogic","type":"address"}],"name":"settleExpiredAndFilterActivePositions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_poolManagerLogic","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"txGuard","outputs":[{"internalType":"uint16","name":"txType","type":"uint16"},{"internalType":"bool","name":"isPublic","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101006040526000805460ff191660011790553480156200001f57600080fd5b5060405162003fe038038062003fe0833981016040819052620000429162000089565b6001600160601b0319606094851b811660805292841b831660a052921b1660c05260e052620000da565b80516001600160a01b03811681146200008457600080fd5b919050565b600080600080608085870312156200009f578384fd5b620000aa856200006c565b9350620000ba602086016200006c565b9250620000ca604086016200006c565b6060959095015193969295505050565b60805160601c60a05160601c60c05160601c60e051613e546200018c6000398061054b5280612c545250806104995280610b7e5280610c40528061105b5280612add5280612c7f5280612e7b5250806103465280610877528061129e52806116985280612a4e5250806104c65280610bab52806112c252806119ba5280611bdd5280611e0852806120ce52806122dd52806124eb5280612b0c5280612ea8528061304052806130e35250613e546000f3fe608060405234801561001057600080fd5b50600436106101075760003560e01c80630561e1a11461010c57806307caac391461012157806309ff5c7d1461013f5780631053f952146101525780631eba307714610172578063293d80631461019257806341dc16c3146101b257806343054c12146101c55780634349be80146101d857806352dac656146101e05780636179309d146101e8578063689015131461020957806375d144751461021c5780637bf981191461023c57806382f86acc14610251578063998546e314610264578063c3c6279f14610277578063db896b571461028a578063e4e6ea581461029d578063ef38bf01146102a5578063f66c9dd2146102ad575b600080fd5b61011f61011a36600461340a565b6102c0565b005b610129610549565b6040516101369190613b7c565b60405180910390f35b61012961014d366004613613565b61056d565b610165610160366004613662565b610600565b6040516101369190613bb1565b61018561018036600461353c565b610698565b6040516101369190613a6f565b6101a56101a0366004613586565b61069f565b6040516101369190613b9c565b6101296101c03660046136a8565b610701565b61011f6101d3366004613346565b6107df565b610129610c2c565b610185610c3e565b6101fb6101f636600461337e565b610c62565b604051610136929190613d43565b610165610217366004613554565b61103a565b61022f61022a366004613346565b611055565b6040516101369190613ae0565b6102446111b8565b6040516101369190613b71565b61012961025f366004613613565b6111c1565b610129610272366004613613565b6111df565b6101a5610285366004613554565b611210565b6101296102983660046135c8565b61121d565b61018561129c565b6101856112c0565b61011f6102bb36600461337e565b6112e4565b60006102cb84611055565b905060005b815181101561054257836001600160a01b03168282815181106102ef57fe5b6020026020010151600001516001600160a01b031614801561032757508282828151811061031957fe5b602002602001015160200151145b1561053a5760405163c71b7e5360e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c71b7e539061037b908890600401613a6f565b6101406040518083038186803b15801561039457600080fd5b505afa1580156103a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103cc9190613723565b905060018160a001516001600160a01b031663eb29dc5e866040518263ffffffff1660e01b81526004016104009190613b7c565b60206040518083038186803b15801561041857600080fd5b505afa15801561042c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104509190613709565b600581111561045b57fe5b14156104825760405162461bcd60e51b815260040161047990613c77565b60405180910390fd5b604051636631173960e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cc622e7290610502907f000000000000000000000000000000000000000000000000000000000000000090600080516020613dff833981519152908b908890600401613ab6565b600060405180830381600087803b15801561051c57600080fd5b505af1158015610530573d6000803e3d6000fd5b5050505050610542565b6001016102d0565b5050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600080610585848460200260040160ff16602061121d565b905060006105988560048401602061121d565b9050806105e1576040805162461bcd60e51b8152602060048201526012602482015271696e707574206973206e6f7420617272617960701b604482015290519081900360640190fd5b6105f585602080840285016004019061121d565b925050505b92915050565b606060148210610648576040805162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a59081bd9999cd95d60921b604482015290519081900360640190fd5b816020029150600061066785848660200260040160ff1601602061121d565b9050600061067c86858401600401602061121d565b905061068e866024848701018361152d565b9695505050505050565b805b919050565b600081600401835110156106f8576040805162461bcd60e51b815260206004820152601b60248201527a52656164696e67206279746573206f7574206f6620626f756e647360281b604482015290519081900360640190fd5b50016020015190565b600080610719858560200260040160ff16602061121d565b9050600061072c8660048401602061121d565b905080610775576040805162461bcd60e51b8152602060048201526012602482015271696e707574206973206e6f7420617272617960701b604482015290519081900360640190fd5b60ff841681116107c5576040805162461bcd60e51b815260206004820152601660248201527534b73b30b634b21030b93930bc903837b9b4ba34b7b760511b604482015290519081900360640190fd5b61068e866020600160ff881601810285016004019061121d565b6000816001600160a01b0316631e50a4a66040518163ffffffff1660e01b815260040160206040518083038186803b15801561081a57600080fd5b505afa15801561082e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108529190613362565b9050600061085f83611055565b80519091505b8015610c2657600060018203905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c71b7e538584815181106108b057fe5b6020026020010151600001516040518263ffffffff1660e01b81526004016108d89190613a6f565b6101406040518083038186803b1580156108f157600080fd5b505afa158015610905573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109299190613723565b905060008160a001516001600160a01b03166399fbab8886858151811061094c57fe5b6020026020010151602001516040518263ffffffff1660e01b81526004016109749190613b7c565b60c06040518083038186803b15801561098c57600080fd5b505afa1580156109a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c4919061394d565b905060018160a0015160058111156109d857fe5b1415610b675760008584815181106109ec57fe5b6020026020010151600001516001600160a01b0316631fdb6cbd83602001516040518263ffffffff1660e01b8152600401610a279190613b7c565b60606040518083038186803b158015610a3f57600080fd5b505afa158015610a53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7791906139e2565b5091505080610a895750505050610c1d565b610aaf878360400151888781518110610a9e57fe5b60200260200101516000015161167e565b60408051600180825281830190925260009160208083019080368337019050509050868581518110610add57fe5b60200260200101516020015181600081518110610af657fe5b6020026020010181815250508360c001516001600160a01b031663bc0d6c57826040518263ffffffff1660e01b8152600401610b329190613b2d565b600060405180830381600087803b158015610b4c57600080fd5b505af1158015610b60573d6000803e3d6000fd5b5050505050505b604051636631173960e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cc622e7290610be7907f000000000000000000000000000000000000000000000000000000000000000090600080516020613dff833981519152908c908990600401613ab6565b600060405180830381600087803b158015610c0157600080fd5b505af1158015610c15573d6000803e3d6000fd5b505050505050505b60001901610865565b50505050565b600080516020613dff83398151915281565b7f000000000000000000000000000000000000000000000000000000000000000081565b604051634df48c7360e11b8152600090819086906001600160a01b03821690639be918e690610c95908990600401613a6f565b60206040518083038186803b158015610cad57600080fd5b505afa158015610cc1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce5919061351c565b610d015760405162461bcd60e51b815260040161047990613bf5565b610d75876001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b158015610d3d57600080fd5b505afa158015610d51573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d39190613362565b6000610db686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061121092505050565b90506001600160e01b031981166309f0390960e41b1480610de757506001600160e01b031981166313020d7760e11b145b80610e0257506001600160e01b03198116637683971160e11b145b80610e1d57506001600160e01b0319811663883ec2f760e01b145b15610ee1576000610e6387878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061103a92505050565b806020019051810190610e7691906139ca565b90506000610e848383611873565b509050610e9a848260c00151836000015161167e565b601a9550610eda8a6001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b158015610d3d57600080fd5b505061102f565b6001600160e01b03198116630c4a5b4960e21b1480610f1057506001600160e01b0319811663128b191760e01b145b80610f2b57506001600160e01b031981166390ac6a1160e01b145b80610f4657506001600160e01b0319811663dee2a1a160e01b145b1561101d576000610f8c87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061103a92505050565b806020019051810190610f9f91906139ca565b9050600080610fae8484611873565b91509150610fc5858360c00151846000015161167e565b80610fd157601b610fd4565b601c5b60ff1696506110158b6001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b158015610d3d57600080fd5b50505061102f565b611029888888886126b9565b90945092505b505094509492505050565b60606105fa6004808451038461152d9092919063ffffffff16565b606060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663adee6197600080516020613dff833981519152856040518363ffffffff1660e01b81526004016110b5929190613b85565b60006040518083038186803b1580156110cd57600080fd5b505afa1580156110e1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611109919081019061344a565b905080516001600160401b038111801561112257600080fd5b5060405190808252806020026020018201604052801561115c57816020015b611149613237565b8152602001906001900390816111415790505b50915060005b81518110156111b15781818151811061117757fe5b602002602001015180602001905181019061119291906138fd565b83828151811061119e57fe5b6020908102919091010152600101611162565b5050919050565b60005460ff1681565b60006111d8838360200260040160ff16602061121d565b9392505050565b6000806111f7848460200260040160ff16602061121d565b90506112088460048301602061121d565b949350505050565b60006105fa82600061069f565b600081830184511015611275576040805162461bcd60e51b815260206004820152601b60248201527a52656164696e67206279746573206f7574206f6620626f756e647360281b604482015290519081900360640190fd5b826020018401519050816020038015611294576008810260020a820491505b509392505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000846001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b15801561131f57600080fd5b505afa158015611333573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113579190613362565b9050336001600160a01b038216146113815760405162461bcd60e51b815260040161047990613d0d565b60006113c284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061121092505050565b90506001600160e01b031981166309f0390960e41b14806113f357506001600160e01b031981166313020d7760e11b145b8061140e57506001600160e01b03198116630c4a5b4960e21b145b8061142957506001600160e01b0319811663128b191760e01b145b8061144457506001600160e01b03198116637683971160e11b145b8061145f57506001600160e01b0319811663883ec2f760e01b145b8061147a57506001600160e01b031981166390ac6a1160e01b145b8061149557506001600160e01b0319811663dee2a1a160e01b145b156115195760006114db85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061103a92505050565b8060200190518101906114ee91906139ca565b905060006114fc8383611873565b5090506115128482600001518360400151612a34565b5050611525565b61152586868686612f20565b505050505050565b60608182601f011015611578576040805162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b604482015290519081900360640190fd5b8282840110156115c0576040805162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b604482015290519081900360640190fd5b8183018451101561160c576040805162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b604482015290519081900360640190fd5b60608215801561162b5760405191506000825260208201604052611675565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561166457805183526020928301920161164c565b5050858452601f01601f1916604052505b50949350505050565b60405163c71b7e5360e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c71b7e53906116cd908590600401613a6f565b6101406040518083038186803b1580156116e657600080fd5b505afa1580156116fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171e9190613723565b9050600283600481111561172e57fe5b14156117d657610120810151604051634df48c7360e11b81526001600160a01b03861691639be918e6916117659190600401613a6f565b60206040518083038186803b15801561177d57600080fd5b505afa158015611791573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b5919061351c565b6117d15760405162461bcd60e51b815260040161047990613c1f565b610c26565b610100810151604051634df48c7360e11b81526001600160a01b03861691639be918e6916118079190600401613a6f565b60206040518083038186803b15801561181f57600080fd5b505afa158015611833573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611857919061351c565b610c265760405162461bcd60e51b815260040161047990613bc4565b61187b61324e565b60006001600160e01b031984166309f0390960e41b14156119835760006118a184613026565b90506040518061018001604052806118b8866130c9565b6001600160a01b031681526020016118d3602087901c613118565b8152602001600081526020016118ec601887901c613121565b815260200160008152602001600081526020016000601087901c60ff1611611915576001611918565b60005b600481111561192357fe5b8152602001611935608087901c613127565b81526020016000815260200161194e604087901c61313a565b8152602001611969611963606088901c613118565b84613154565b8152602001826001600160a01b03168152509250506126b2565b6001600160e01b031984166313020d7760e11b1415611ba65760006119a7846130c9565b905060006119b485613026565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166373ccbf67846040518263ffffffff1660e01b8152600401611a049190613a6f565b60606040518083038186803b158015611a1c57600080fd5b505afa158015611a30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a5491906137ee565b9050600081604001516001600160a01b03166399fbab88601889901c63ffffffff166040518263ffffffff1660e01b8152600401611a929190613b7c565b60c06040518083038186803b158015611aaa57600080fd5b505afa158015611abe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae2919061394d565b9050604051806101800160405280856001600160a01b031681526020018260200151815260200182600001518152602001611b2060108a901c613121565b8152602001600081526020016000815260200182604001516004811115611b4357fe5b8152602001611b5560788a901c613127565b815260200160008152602001611b6e60388a901c61313a565b8152602001611b89611b8360588b901c613118565b86613154565b8152602001846001600160a01b03168152509550505050506126b2565b6001600160e01b03198416630c4a5b4960e21b1415611dd1576000611bca846130c9565b90506000611bd785613026565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166373ccbf67846040518263ffffffff1660e01b8152600401611c279190613a6f565b60606040518083038186803b158015611c3f57600080fd5b505afa158015611c53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7791906137ee565b9050600081604001516001600160a01b03166399fbab88602089901c63ffffffff166040518263ffffffff1660e01b8152600401611cb59190613b7c565b60c06040518083038186803b158015611ccd57600080fd5b505afa158015611ce1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d05919061394d565b9050604051806101800160405280856001600160a01b031681526020018260200151815260200182600001518152602001611d4360108a901c613121565b8152602001600081526020016000815260200182604001516004811115611d6657fe5b8152602001611d7860608a901c613127565b8152602001611d8a60a08a901c61313a565b81526020016000198152602001611da7611b8360408b901c613118565b8152602001846001600160a01b031681525095506000601888901c60ff16119450505050506126b2565b6001600160e01b0319841663128b191760e01b1415611fad576000611df5846130c9565b90506000611e0285613026565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166373ccbf67846040518263ffffffff1660e01b8152600401611e529190613a6f565b60606040518083038186803b158015611e6a57600080fd5b505afa158015611e7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea291906137ee565b9050600081604001516001600160a01b03166399fbab88602089901c63ffffffff166040518263ffffffff1660e01b8152600401611ee09190613b7c565b60c06040518083038186803b158015611ef857600080fd5b505afa158015611f0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f30919061394d565b9050604051806101800160405280856001600160a01b031681526020018260200151815260200182600001518152602001611f6e60108a901c613121565b8152602001600081526020016000815260200182604001516004811115611f9157fe5b815260200182606001518152602001611d8a60608a901c61313a565b6001600160e01b03198416637683971160e11b1415612097576000611fd184613026565b9050604051806101800160405280611fe8866130c9565b6001600160a01b03168152602001602086901c63ffffffff1681526020016000815260200161201a601887901c613121565b815260200161202c60c087901c613127565b815260200160008152602001601086901c60ff16600481111561204b57fe5b600481111561205657fe5b8152602001612068608087901c613127565b815260200161207a604087901c61313a565b81526020016000198152602001611969611963606088901c613118565b6001600160e01b0319841663883ec2f760e01b14156122a65760006120bb846130c9565b905060006120c885613026565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166373ccbf67846040518263ffffffff1660e01b81526004016121189190613a6f565b60606040518083038186803b15801561213057600080fd5b505afa158015612144573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216891906137ee565b9050600081604001516001600160a01b03166399fbab88601889901c63ffffffff166040518263ffffffff1660e01b81526004016121a69190613b7c565b60c06040518083038186803b1580156121be57600080fd5b505afa1580156121d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f6919061394d565b9050604051806101800160405280856001600160a01b03168152602001826020015181526020018260000151815260200161223460108a901c613121565b815260200161224660b88a901c613127565b8152602001826080015181526020018260400151600481111561226557fe5b815260200161227760788a901c613127565b815260200161228960588a901c61313a565b81526020016000198152602001611b89611b8360388b901c613118565b6001600160e01b031984166390ac6a1160e01b14156124b45760006122ca846130c9565b905060006122d785613026565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166373ccbf67846040518263ffffffff1660e01b81526004016123279190613a6f565b60606040518083038186803b15801561233f57600080fd5b505afa158015612353573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061237791906137ee565b9050600081604001516001600160a01b03166399fbab88602089901c63ffffffff166040518263ffffffff1660e01b81526004016123b59190613b7c565b60c06040518083038186803b1580156123cd57600080fd5b505afa1580156123e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612405919061394d565b9050604051806101800160405280856001600160a01b03168152602001826020015181526020018260000151815260200161244360108a901c613121565b815260200161245560c48a901c613127565b8152602001826080015181526020018260400151600481111561247457fe5b815260200161248660808a901c613127565b81526020016000815260200161249f60608a901c61313a565b8152602001611da7611b8360408b901c613118565b6001600160e01b0319841663dee2a1a160e01b141561269a5760006124d8846130c9565b905060006124e585613026565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166373ccbf67846040518263ffffffff1660e01b81526004016125359190613a6f565b60606040518083038186803b15801561254d57600080fd5b505afa158015612561573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258591906137ee565b9050600081604001516001600160a01b03166399fbab88602089901c63ffffffff166040518263ffffffff1660e01b81526004016125c39190613b7c565b60c06040518083038186803b1580156125db57600080fd5b505afa1580156125ef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612613919061394d565b9050604051806101800160405280856001600160a01b03168152602001826020015181526020018260000151815260200161265160108a901c613121565b815260200160008152602001826080015181526020018260400151600481111561267757fe5b8152602001826060015181526020016000815260200161249f60608a901c61313a565b60405162461bcd60e51b815260040161047990613c4f565b9250929050565b604051634df48c7360e11b8152600090819086906001600160a01b03821690639be918e6906126ec908990600401613a6f565b60206040518083038186803b15801561270457600080fd5b505afa158015612718573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061273c919061351c565b6127585760405162461bcd60e51b815260040161047990613bf5565b612794876001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b158015610d3d57600080fd5b60006127d586868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061121092505050565b90506001600160e01b03198116638bc3696960e01b141561289f57600061283187878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061103a92505050565b8060200190518101906128449190613858565b9050612859838260c00151836000015161167e565b601a9450612899896001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b158015610d3d57600080fd5b50612a25565b6001600160e01b0319811663b738a96b60e01b14156129615760006128f987878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061103a92505050565b80602001905181019061290c9190613858565b9050612921838260c00151836000015161167e565b601b9450612899896001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b158015610d3d57600080fd5b6001600160e01b031981166305766e3d60e11b1415612a255760006129bb87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061103a92505050565b8060200190518101906129ce9190613858565b90506129e3838260c00151836000015161167e565b601c9450612a23896001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b158015610d3d57600080fd5b505b50600091505094509492505050565b60405163c71b7e5360e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c71b7e5390612a83908690600401613a6f565b6101406040518083038186803b158015612a9c57600080fd5b505afa158015612ab0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ad49190613723565b905081612d33577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166354d8c4ba7f0000000000000000000000000000000000000000000000000000000000000000600080516020613dff833981519152876040518060400160405280896001600160a01b03168152602001612bd560018960a001516001600160a01b03166361b8ce8c6040518163ffffffff1660e01b815260040160206040518083038186803b158015612b9757600080fd5b505afa158015612bab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bcf91906139ca565b906131da565b9052604051612be79190602001613d35565b6040516020818303038152906040526040518563ffffffff1660e01b8152600401612c159493929190613a83565b600060405180830381600087803b158015612c2f57600080fd5b505af1158015612c43573d6000803e3d6000fd5b5050604051632ac14da160e21b81527f000000000000000000000000000000000000000000000000000000000000000092506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016915063ab05368490612cc590600080516020613dff833981519152908990600401613b85565b60206040518083038186803b158015612cdd57600080fd5b505afa158015612cf1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d1591906139ca565b11156117d15760405162461bcd60e51b815260040161047990613cd6565b60a0810151604051637594ee2f60e11b81526000916001600160a01b03169063eb29dc5e90612d66908690600401613b7c565b60206040518083038186803b158015612d7e57600080fd5b505afa158015612d92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612db69190613709565b90506000612dc386611055565b905060005b8151811015612e3157856001600160a01b0316828281518110612de757fe5b6020026020010151600001516001600160a01b0316148015612e1f575084828281518110612e1157fe5b602002602001015160200151145b15612e2957612e31565b600101612dc8565b81518110612e515760405162461bcd60e51b815260040161047990613ca4565b6001836005811115612e5f57fe5b14612f1757604051636631173960e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cc622e7290612ee4907f000000000000000000000000000000000000000000000000000000000000000090600080516020613dff833981519152908c908790600401613ab6565b600060405180830381600087803b158015612efe57600080fd5b505af1158015612f12573d6000803e3d6000fd5b505050505b50505050505050565b6000846001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b158015612f5b57600080fd5b505afa158015612f6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f939190613362565b9050336001600160a01b03821614612fbd5760405162461bcd60e51b815260040161047990613d0d565b6000612ffe84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061103a92505050565b8060200190518101906130119190613858565b90506115258282600001518360400151612a34565b60405163ecf6578360e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ecf657839061307990600886901c90600401613d59565b60206040518083038186803b15801561309157600080fd5b505afa1580156130a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105fa9190613362565b60405163c346745160e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c346745190613079908590600401613d59565b63ffffffff1690565b60ff1690565b6001600160401b03166402540be4000290565b600061314582613118565b662386f26fc100000292915050565b60006002826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561319157600080fd5b505afa1580156131a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c99190613a0f565b0360ff16600a0a8302905092915050565b600082821115613231576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b604080518082019091526000808252602082015290565b60405180610180016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081526020016000600481111561329a57fe5b81526020016000815260200160008152602001600081526020016000815260200160006001600160a01b031681525090565b805161069a81613dd7565b600082601f8301126132e7578081fd5b81356132fa6132f582613d8a565b613d67565b81815284602083860101111561330e578283fd5b816020850160208301379081016020019190915292915050565b80516005811061069a57600080fd5b80516006811061069a57600080fd5b600060208284031215613357578081fd5b81356111d881613dd7565b600060208284031215613373578081fd5b81516111d881613dd7565b60008060008060608587031215613393578283fd5b843561339e81613dd7565b935060208501356133ae81613dd7565b925060408501356001600160401b03808211156133c9578384fd5b818701915087601f8301126133dc578384fd5b8135818111156133ea578485fd5b8860208285010111156133fb578485fd5b95989497505060200194505050565b60008060006060848603121561341e578081fd5b833561342981613dd7565b9250602084013561343981613dd7565b929592945050506040919091013590565b6000602080838503121561345c578182fd5b82516001600160401b0380821115613472578384fd5b818501915085601f830112613485578384fd5b81518181111561349157fe5b61349e8485830201613d67565b8181528481019250838501865b8381101561350e57815186018a603f8201126134c5578889fd5b8781015160406134d76132f583613d8a565b8281528d828486010111156134ea578b8cfd5b6134f9838c8301848701613dab565b885250505093860193908601906001016134ab565b509098975050505050505050565b60006020828403121561352d578081fd5b815180151581146111d8578182fd5b60006020828403121561354d578081fd5b5035919050565b600060208284031215613565578081fd5b81356001600160401b0381111561357a578182fd5b611208848285016132d7565b60008060408385031215613598578182fd5b82356001600160401b038111156135ad578283fd5b6135b9858286016132d7565b95602094909401359450505050565b6000806000606084860312156135dc578081fd5b83356001600160401b038111156135f1578182fd5b6135fd868287016132d7565b9660208601359650604090950135949350505050565b60008060408385031215613625578182fd5b82356001600160401b0381111561363a578283fd5b613646858286016132d7565b925050602083013561365781613def565b809150509250929050565b600080600060608486031215613676578081fd5b83356001600160401b0381111561368b578182fd5b613697868287016132d7565b935050602084013561343981613def565b6000806000606084860312156136bc578081fd5b83356001600160401b038111156136d1578182fd5b6136dd868287016132d7565b93505060208401356136ee81613def565b915060408401356136fe81613def565b809150509250925092565b60006020828403121561371a578081fd5b6111d882613337565b6000610140808385031215613736578182fd5b61373f81613d67565b905061374a836132cc565b8152613758602084016132cc565b6020820152613769604084016132cc565b604082015261377a606084016132cc565b606082015261378b608084016132cc565b608082015261379c60a084016132cc565b60a08201526137ad60c084016132cc565b60c08201526137be60e084016132cc565b60e08201526101006137d18185016132cc565b908201526101206137e38482016132cc565b908201529392505050565b6000606082840312156137ff578081fd5b604051606081018181106001600160401b038211171561381b57fe5b604052825161382981613dd7565b8152602083015161383981613dd7565b6020820152604083015161384c81613dd7565b60408201529392505050565b600061018080838503121561386b578182fd5b61387481613d67565b905061387f836132cc565b81526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a08201526138bf60c08401613328565b60c082015260e083810151908201526101008084015190820152610120808401519082015261014080840151908201526101606137e38185016132cc565b60006040828403121561390e578081fd5b604051604081018181106001600160401b038211171561392a57fe5b604052825161393881613dd7565b81526020928301519281019290925250919050565b600060c0828403121561395e578081fd5b60405160c081018181106001600160401b038211171561397a57fe5b8060405250825181526020830151602082015261399960408401613328565b604082015260608301516060820152608083015160808201526139be60a08401613337565b60a08201529392505050565b6000602082840312156139db578081fd5b5051919050565b6000806000606084860312156139f6578081fd5b8351925060208401519150604084015190509250925092565b600060208284031215613a20578081fd5b81516111d881613def565b60008151808452613a43816020860160208601613dab565b601f01601f19169290920160200192915050565b80516001600160a01b03168252602090810151910152565b6001600160a01b0391909116815260200190565b6001600160a01b038581168252602082018590528316604082015260806060820181905260009061068e90830184613a2b565b6001600160a01b039485168152602081019390935292166040820152606081019190915260800190565b602080825282518282018190526000919060409081850190868401855b82811015613b2057613b10848351613a57565b9284019290850190600101613afd565b5091979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613b6557835183529284019291840191600101613b49565b50909695505050505050565b901515815260200190565b90815260200190565b9182526001600160a01b0316602082015260400190565b6001600160e01b031991909116815260200190565b6000602082526111d86020830184613a2b565b6020808252601790820152761d5b9cdd5c1c1bdc9d1959081c5d5bdd1948185cdcd95d604a1b604082015260600190565b60208082526010908201526f1b1e5c98481b9bdd08195b98589b195960821b604082015260600190565b6020808252601690820152751d5b9cdd5c1c1bdc9d19590818985cd948185cdcd95d60521b604082015260600190565b6020808252600e908201526d1a5b9d985b1a59081b595d1a1bd960921b604082015260600190565b6020808252601390820152723737ba1031b637b9b2b2103837b9b4ba34b7b760691b604082015260600190565b602080825260189082015277706f736974696f6e206973206e6f7420696e20747261636b60401b604082015260600190565b6020808252601d908201527f657863656564206d6178696d756d20706f736974696f6e20636f756e74000000604082015260600190565b6020808252600e908201526d6e6f7420706f6f6c206c6f67696360901b604082015260600190565b604081016105fa8284613a57565b61ffff9290921682521515602082015260400190565b60ff91909116815260200190565b6040518181016001600160401b0381118282101715613d8257fe5b604052919050565b60006001600160401b03821115613d9d57fe5b50601f01601f191660200190565b60005b83811015613dc6578181015183820152602001613dae565b83811115610c265750506000910152565b6001600160a01b0381168114613dec57600080fd5b50565b60ff81168114613dec57600080fdfe9bb8215865837737a430a2ed3e9c04cabdb00a3a0eb47bf3b216ebc38d14a326a2646970667358221220c8f164429155a469b2711477d872d68ad0eb4645a4d4b447601499e5d3af101b64736f6c63430007060033000000000000000000000000cce7819d65f348c64b7beb205ba367b3fe33763b000000000000000000000000eaf788ad8abd9c98ba05f6802a62b8dbc673d76b000000000000000000000000d0d2eb0f55f626ac8ed144f9fe824e416f7e743d0000000000000000000000000000000000000000000000000000000000000002
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101075760003560e01c80630561e1a11461010c57806307caac391461012157806309ff5c7d1461013f5780631053f952146101525780631eba307714610172578063293d80631461019257806341dc16c3146101b257806343054c12146101c55780634349be80146101d857806352dac656146101e05780636179309d146101e8578063689015131461020957806375d144751461021c5780637bf981191461023c57806382f86acc14610251578063998546e314610264578063c3c6279f14610277578063db896b571461028a578063e4e6ea581461029d578063ef38bf01146102a5578063f66c9dd2146102ad575b600080fd5b61011f61011a36600461340a565b6102c0565b005b610129610549565b6040516101369190613b7c565b60405180910390f35b61012961014d366004613613565b61056d565b610165610160366004613662565b610600565b6040516101369190613bb1565b61018561018036600461353c565b610698565b6040516101369190613a6f565b6101a56101a0366004613586565b61069f565b6040516101369190613b9c565b6101296101c03660046136a8565b610701565b61011f6101d3366004613346565b6107df565b610129610c2c565b610185610c3e565b6101fb6101f636600461337e565b610c62565b604051610136929190613d43565b610165610217366004613554565b61103a565b61022f61022a366004613346565b611055565b6040516101369190613ae0565b6102446111b8565b6040516101369190613b71565b61012961025f366004613613565b6111c1565b610129610272366004613613565b6111df565b6101a5610285366004613554565b611210565b6101296102983660046135c8565b61121d565b61018561129c565b6101856112c0565b61011f6102bb36600461337e565b6112e4565b60006102cb84611055565b905060005b815181101561054257836001600160a01b03168282815181106102ef57fe5b6020026020010151600001516001600160a01b031614801561032757508282828151811061031957fe5b602002602001015160200151145b1561053a5760405163c71b7e5360e01b81526000906001600160a01b037f000000000000000000000000eaf788ad8abd9c98ba05f6802a62b8dbc673d76b169063c71b7e539061037b908890600401613a6f565b6101406040518083038186803b15801561039457600080fd5b505afa1580156103a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103cc9190613723565b905060018160a001516001600160a01b031663eb29dc5e866040518263ffffffff1660e01b81526004016104009190613b7c565b60206040518083038186803b15801561041857600080fd5b505afa15801561042c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104509190613709565b600581111561045b57fe5b14156104825760405162461bcd60e51b815260040161047990613c77565b60405180910390fd5b604051636631173960e11b81526001600160a01b037f000000000000000000000000d0d2eb0f55f626ac8ed144f9fe824e416f7e743d169063cc622e7290610502907f000000000000000000000000cce7819d65f348c64b7beb205ba367b3fe33763b90600080516020613dff833981519152908b908890600401613ab6565b600060405180830381600087803b15801561051c57600080fd5b505af1158015610530573d6000803e3d6000fd5b5050505050610542565b6001016102d0565b5050505050565b7f000000000000000000000000000000000000000000000000000000000000000281565b600080610585848460200260040160ff16602061121d565b905060006105988560048401602061121d565b9050806105e1576040805162461bcd60e51b8152602060048201526012602482015271696e707574206973206e6f7420617272617960701b604482015290519081900360640190fd5b6105f585602080840285016004019061121d565b925050505b92915050565b606060148210610648576040805162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a59081bd9999cd95d60921b604482015290519081900360640190fd5b816020029150600061066785848660200260040160ff1601602061121d565b9050600061067c86858401600401602061121d565b905061068e866024848701018361152d565b9695505050505050565b805b919050565b600081600401835110156106f8576040805162461bcd60e51b815260206004820152601b60248201527a52656164696e67206279746573206f7574206f6620626f756e647360281b604482015290519081900360640190fd5b50016020015190565b600080610719858560200260040160ff16602061121d565b9050600061072c8660048401602061121d565b905080610775576040805162461bcd60e51b8152602060048201526012602482015271696e707574206973206e6f7420617272617960701b604482015290519081900360640190fd5b60ff841681116107c5576040805162461bcd60e51b815260206004820152601660248201527534b73b30b634b21030b93930bc903837b9b4ba34b7b760511b604482015290519081900360640190fd5b61068e866020600160ff881601810285016004019061121d565b6000816001600160a01b0316631e50a4a66040518163ffffffff1660e01b815260040160206040518083038186803b15801561081a57600080fd5b505afa15801561082e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108529190613362565b9050600061085f83611055565b80519091505b8015610c2657600060018203905060007f000000000000000000000000eaf788ad8abd9c98ba05f6802a62b8dbc673d76b6001600160a01b031663c71b7e538584815181106108b057fe5b6020026020010151600001516040518263ffffffff1660e01b81526004016108d89190613a6f565b6101406040518083038186803b1580156108f157600080fd5b505afa158015610905573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109299190613723565b905060008160a001516001600160a01b03166399fbab8886858151811061094c57fe5b6020026020010151602001516040518263ffffffff1660e01b81526004016109749190613b7c565b60c06040518083038186803b15801561098c57600080fd5b505afa1580156109a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c4919061394d565b905060018160a0015160058111156109d857fe5b1415610b675760008584815181106109ec57fe5b6020026020010151600001516001600160a01b0316631fdb6cbd83602001516040518263ffffffff1660e01b8152600401610a279190613b7c565b60606040518083038186803b158015610a3f57600080fd5b505afa158015610a53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7791906139e2565b5091505080610a895750505050610c1d565b610aaf878360400151888781518110610a9e57fe5b60200260200101516000015161167e565b60408051600180825281830190925260009160208083019080368337019050509050868581518110610add57fe5b60200260200101516020015181600081518110610af657fe5b6020026020010181815250508360c001516001600160a01b031663bc0d6c57826040518263ffffffff1660e01b8152600401610b329190613b2d565b600060405180830381600087803b158015610b4c57600080fd5b505af1158015610b60573d6000803e3d6000fd5b5050505050505b604051636631173960e11b81526001600160a01b037f000000000000000000000000d0d2eb0f55f626ac8ed144f9fe824e416f7e743d169063cc622e7290610be7907f000000000000000000000000cce7819d65f348c64b7beb205ba367b3fe33763b90600080516020613dff833981519152908c908990600401613ab6565b600060405180830381600087803b158015610c0157600080fd5b505af1158015610c15573d6000803e3d6000fd5b505050505050505b60001901610865565b50505050565b600080516020613dff83398151915281565b7f000000000000000000000000d0d2eb0f55f626ac8ed144f9fe824e416f7e743d81565b604051634df48c7360e11b8152600090819086906001600160a01b03821690639be918e690610c95908990600401613a6f565b60206040518083038186803b158015610cad57600080fd5b505afa158015610cc1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce5919061351c565b610d015760405162461bcd60e51b815260040161047990613bf5565b610d75876001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b158015610d3d57600080fd5b505afa158015610d51573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d39190613362565b6000610db686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061121092505050565b90506001600160e01b031981166309f0390960e41b1480610de757506001600160e01b031981166313020d7760e11b145b80610e0257506001600160e01b03198116637683971160e11b145b80610e1d57506001600160e01b0319811663883ec2f760e01b145b15610ee1576000610e6387878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061103a92505050565b806020019051810190610e7691906139ca565b90506000610e848383611873565b509050610e9a848260c00151836000015161167e565b601a9550610eda8a6001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b158015610d3d57600080fd5b505061102f565b6001600160e01b03198116630c4a5b4960e21b1480610f1057506001600160e01b0319811663128b191760e01b145b80610f2b57506001600160e01b031981166390ac6a1160e01b145b80610f4657506001600160e01b0319811663dee2a1a160e01b145b1561101d576000610f8c87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061103a92505050565b806020019051810190610f9f91906139ca565b9050600080610fae8484611873565b91509150610fc5858360c00151846000015161167e565b80610fd157601b610fd4565b601c5b60ff1696506110158b6001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b158015610d3d57600080fd5b50505061102f565b611029888888886126b9565b90945092505b505094509492505050565b60606105fa6004808451038461152d9092919063ffffffff16565b606060007f000000000000000000000000d0d2eb0f55f626ac8ed144f9fe824e416f7e743d6001600160a01b031663adee6197600080516020613dff833981519152856040518363ffffffff1660e01b81526004016110b5929190613b85565b60006040518083038186803b1580156110cd57600080fd5b505afa1580156110e1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611109919081019061344a565b905080516001600160401b038111801561112257600080fd5b5060405190808252806020026020018201604052801561115c57816020015b611149613237565b8152602001906001900390816111415790505b50915060005b81518110156111b15781818151811061117757fe5b602002602001015180602001905181019061119291906138fd565b83828151811061119e57fe5b6020908102919091010152600101611162565b5050919050565b60005460ff1681565b60006111d8838360200260040160ff16602061121d565b9392505050565b6000806111f7848460200260040160ff16602061121d565b90506112088460048301602061121d565b949350505050565b60006105fa82600061069f565b600081830184511015611275576040805162461bcd60e51b815260206004820152601b60248201527a52656164696e67206279746573206f7574206f6620626f756e647360281b604482015290519081900360640190fd5b826020018401519050816020038015611294576008810260020a820491505b509392505050565b7f000000000000000000000000eaf788ad8abd9c98ba05f6802a62b8dbc673d76b81565b7f000000000000000000000000cce7819d65f348c64b7beb205ba367b3fe33763b81565b6000846001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b15801561131f57600080fd5b505afa158015611333573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113579190613362565b9050336001600160a01b038216146113815760405162461bcd60e51b815260040161047990613d0d565b60006113c284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061121092505050565b90506001600160e01b031981166309f0390960e41b14806113f357506001600160e01b031981166313020d7760e11b145b8061140e57506001600160e01b03198116630c4a5b4960e21b145b8061142957506001600160e01b0319811663128b191760e01b145b8061144457506001600160e01b03198116637683971160e11b145b8061145f57506001600160e01b0319811663883ec2f760e01b145b8061147a57506001600160e01b031981166390ac6a1160e01b145b8061149557506001600160e01b0319811663dee2a1a160e01b145b156115195760006114db85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061103a92505050565b8060200190518101906114ee91906139ca565b905060006114fc8383611873565b5090506115128482600001518360400151612a34565b5050611525565b61152586868686612f20565b505050505050565b60608182601f011015611578576040805162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b604482015290519081900360640190fd5b8282840110156115c0576040805162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b604482015290519081900360640190fd5b8183018451101561160c576040805162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b604482015290519081900360640190fd5b60608215801561162b5760405191506000825260208201604052611675565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561166457805183526020928301920161164c565b5050858452601f01601f1916604052505b50949350505050565b60405163c71b7e5360e01b81526000906001600160a01b037f000000000000000000000000eaf788ad8abd9c98ba05f6802a62b8dbc673d76b169063c71b7e53906116cd908590600401613a6f565b6101406040518083038186803b1580156116e657600080fd5b505afa1580156116fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171e9190613723565b9050600283600481111561172e57fe5b14156117d657610120810151604051634df48c7360e11b81526001600160a01b03861691639be918e6916117659190600401613a6f565b60206040518083038186803b15801561177d57600080fd5b505afa158015611791573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b5919061351c565b6117d15760405162461bcd60e51b815260040161047990613c1f565b610c26565b610100810151604051634df48c7360e11b81526001600160a01b03861691639be918e6916118079190600401613a6f565b60206040518083038186803b15801561181f57600080fd5b505afa158015611833573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611857919061351c565b610c265760405162461bcd60e51b815260040161047990613bc4565b61187b61324e565b60006001600160e01b031984166309f0390960e41b14156119835760006118a184613026565b90506040518061018001604052806118b8866130c9565b6001600160a01b031681526020016118d3602087901c613118565b8152602001600081526020016118ec601887901c613121565b815260200160008152602001600081526020016000601087901c60ff1611611915576001611918565b60005b600481111561192357fe5b8152602001611935608087901c613127565b81526020016000815260200161194e604087901c61313a565b8152602001611969611963606088901c613118565b84613154565b8152602001826001600160a01b03168152509250506126b2565b6001600160e01b031984166313020d7760e11b1415611ba65760006119a7846130c9565b905060006119b485613026565b905060007f000000000000000000000000cce7819d65f348c64b7beb205ba367b3fe33763b6001600160a01b03166373ccbf67846040518263ffffffff1660e01b8152600401611a049190613a6f565b60606040518083038186803b158015611a1c57600080fd5b505afa158015611a30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a5491906137ee565b9050600081604001516001600160a01b03166399fbab88601889901c63ffffffff166040518263ffffffff1660e01b8152600401611a929190613b7c565b60c06040518083038186803b158015611aaa57600080fd5b505afa158015611abe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae2919061394d565b9050604051806101800160405280856001600160a01b031681526020018260200151815260200182600001518152602001611b2060108a901c613121565b8152602001600081526020016000815260200182604001516004811115611b4357fe5b8152602001611b5560788a901c613127565b815260200160008152602001611b6e60388a901c61313a565b8152602001611b89611b8360588b901c613118565b86613154565b8152602001846001600160a01b03168152509550505050506126b2565b6001600160e01b03198416630c4a5b4960e21b1415611dd1576000611bca846130c9565b90506000611bd785613026565b905060007f000000000000000000000000cce7819d65f348c64b7beb205ba367b3fe33763b6001600160a01b03166373ccbf67846040518263ffffffff1660e01b8152600401611c279190613a6f565b60606040518083038186803b158015611c3f57600080fd5b505afa158015611c53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7791906137ee565b9050600081604001516001600160a01b03166399fbab88602089901c63ffffffff166040518263ffffffff1660e01b8152600401611cb59190613b7c565b60c06040518083038186803b158015611ccd57600080fd5b505afa158015611ce1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d05919061394d565b9050604051806101800160405280856001600160a01b031681526020018260200151815260200182600001518152602001611d4360108a901c613121565b8152602001600081526020016000815260200182604001516004811115611d6657fe5b8152602001611d7860608a901c613127565b8152602001611d8a60a08a901c61313a565b81526020016000198152602001611da7611b8360408b901c613118565b8152602001846001600160a01b031681525095506000601888901c60ff16119450505050506126b2565b6001600160e01b0319841663128b191760e01b1415611fad576000611df5846130c9565b90506000611e0285613026565b905060007f000000000000000000000000cce7819d65f348c64b7beb205ba367b3fe33763b6001600160a01b03166373ccbf67846040518263ffffffff1660e01b8152600401611e529190613a6f565b60606040518083038186803b158015611e6a57600080fd5b505afa158015611e7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea291906137ee565b9050600081604001516001600160a01b03166399fbab88602089901c63ffffffff166040518263ffffffff1660e01b8152600401611ee09190613b7c565b60c06040518083038186803b158015611ef857600080fd5b505afa158015611f0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f30919061394d565b9050604051806101800160405280856001600160a01b031681526020018260200151815260200182600001518152602001611f6e60108a901c613121565b8152602001600081526020016000815260200182604001516004811115611f9157fe5b815260200182606001518152602001611d8a60608a901c61313a565b6001600160e01b03198416637683971160e11b1415612097576000611fd184613026565b9050604051806101800160405280611fe8866130c9565b6001600160a01b03168152602001602086901c63ffffffff1681526020016000815260200161201a601887901c613121565b815260200161202c60c087901c613127565b815260200160008152602001601086901c60ff16600481111561204b57fe5b600481111561205657fe5b8152602001612068608087901c613127565b815260200161207a604087901c61313a565b81526020016000198152602001611969611963606088901c613118565b6001600160e01b0319841663883ec2f760e01b14156122a65760006120bb846130c9565b905060006120c885613026565b905060007f000000000000000000000000cce7819d65f348c64b7beb205ba367b3fe33763b6001600160a01b03166373ccbf67846040518263ffffffff1660e01b81526004016121189190613a6f565b60606040518083038186803b15801561213057600080fd5b505afa158015612144573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216891906137ee565b9050600081604001516001600160a01b03166399fbab88601889901c63ffffffff166040518263ffffffff1660e01b81526004016121a69190613b7c565b60c06040518083038186803b1580156121be57600080fd5b505afa1580156121d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f6919061394d565b9050604051806101800160405280856001600160a01b03168152602001826020015181526020018260000151815260200161223460108a901c613121565b815260200161224660b88a901c613127565b8152602001826080015181526020018260400151600481111561226557fe5b815260200161227760788a901c613127565b815260200161228960588a901c61313a565b81526020016000198152602001611b89611b8360388b901c613118565b6001600160e01b031984166390ac6a1160e01b14156124b45760006122ca846130c9565b905060006122d785613026565b905060007f000000000000000000000000cce7819d65f348c64b7beb205ba367b3fe33763b6001600160a01b03166373ccbf67846040518263ffffffff1660e01b81526004016123279190613a6f565b60606040518083038186803b15801561233f57600080fd5b505afa158015612353573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061237791906137ee565b9050600081604001516001600160a01b03166399fbab88602089901c63ffffffff166040518263ffffffff1660e01b81526004016123b59190613b7c565b60c06040518083038186803b1580156123cd57600080fd5b505afa1580156123e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612405919061394d565b9050604051806101800160405280856001600160a01b03168152602001826020015181526020018260000151815260200161244360108a901c613121565b815260200161245560c48a901c613127565b8152602001826080015181526020018260400151600481111561247457fe5b815260200161248660808a901c613127565b81526020016000815260200161249f60608a901c61313a565b8152602001611da7611b8360408b901c613118565b6001600160e01b0319841663dee2a1a160e01b141561269a5760006124d8846130c9565b905060006124e585613026565b905060007f000000000000000000000000cce7819d65f348c64b7beb205ba367b3fe33763b6001600160a01b03166373ccbf67846040518263ffffffff1660e01b81526004016125359190613a6f565b60606040518083038186803b15801561254d57600080fd5b505afa158015612561573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258591906137ee565b9050600081604001516001600160a01b03166399fbab88602089901c63ffffffff166040518263ffffffff1660e01b81526004016125c39190613b7c565b60c06040518083038186803b1580156125db57600080fd5b505afa1580156125ef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612613919061394d565b9050604051806101800160405280856001600160a01b03168152602001826020015181526020018260000151815260200161265160108a901c613121565b815260200160008152602001826080015181526020018260400151600481111561267757fe5b8152602001826060015181526020016000815260200161249f60608a901c61313a565b60405162461bcd60e51b815260040161047990613c4f565b9250929050565b604051634df48c7360e11b8152600090819086906001600160a01b03821690639be918e6906126ec908990600401613a6f565b60206040518083038186803b15801561270457600080fd5b505afa158015612718573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061273c919061351c565b6127585760405162461bcd60e51b815260040161047990613bf5565b612794876001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b158015610d3d57600080fd5b60006127d586868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061121092505050565b90506001600160e01b03198116638bc3696960e01b141561289f57600061283187878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061103a92505050565b8060200190518101906128449190613858565b9050612859838260c00151836000015161167e565b601a9450612899896001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b158015610d3d57600080fd5b50612a25565b6001600160e01b0319811663b738a96b60e01b14156129615760006128f987878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061103a92505050565b80602001905181019061290c9190613858565b9050612921838260c00151836000015161167e565b601b9450612899896001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b158015610d3d57600080fd5b6001600160e01b031981166305766e3d60e11b1415612a255760006129bb87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061103a92505050565b8060200190518101906129ce9190613858565b90506129e3838260c00151836000015161167e565b601c9450612a23896001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b158015610d3d57600080fd5b505b50600091505094509492505050565b60405163c71b7e5360e01b81526000906001600160a01b037f000000000000000000000000eaf788ad8abd9c98ba05f6802a62b8dbc673d76b169063c71b7e5390612a83908690600401613a6f565b6101406040518083038186803b158015612a9c57600080fd5b505afa158015612ab0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ad49190613723565b905081612d33577f000000000000000000000000d0d2eb0f55f626ac8ed144f9fe824e416f7e743d6001600160a01b03166354d8c4ba7f000000000000000000000000cce7819d65f348c64b7beb205ba367b3fe33763b600080516020613dff833981519152876040518060400160405280896001600160a01b03168152602001612bd560018960a001516001600160a01b03166361b8ce8c6040518163ffffffff1660e01b815260040160206040518083038186803b158015612b9757600080fd5b505afa158015612bab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bcf91906139ca565b906131da565b9052604051612be79190602001613d35565b6040516020818303038152906040526040518563ffffffff1660e01b8152600401612c159493929190613a83565b600060405180830381600087803b158015612c2f57600080fd5b505af1158015612c43573d6000803e3d6000fd5b5050604051632ac14da160e21b81527f000000000000000000000000000000000000000000000000000000000000000292506001600160a01b037f000000000000000000000000d0d2eb0f55f626ac8ed144f9fe824e416f7e743d16915063ab05368490612cc590600080516020613dff833981519152908990600401613b85565b60206040518083038186803b158015612cdd57600080fd5b505afa158015612cf1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d1591906139ca565b11156117d15760405162461bcd60e51b815260040161047990613cd6565b60a0810151604051637594ee2f60e11b81526000916001600160a01b03169063eb29dc5e90612d66908690600401613b7c565b60206040518083038186803b158015612d7e57600080fd5b505afa158015612d92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612db69190613709565b90506000612dc386611055565b905060005b8151811015612e3157856001600160a01b0316828281518110612de757fe5b6020026020010151600001516001600160a01b0316148015612e1f575084828281518110612e1157fe5b602002602001015160200151145b15612e2957612e31565b600101612dc8565b81518110612e515760405162461bcd60e51b815260040161047990613ca4565b6001836005811115612e5f57fe5b14612f1757604051636631173960e11b81526001600160a01b037f000000000000000000000000d0d2eb0f55f626ac8ed144f9fe824e416f7e743d169063cc622e7290612ee4907f000000000000000000000000cce7819d65f348c64b7beb205ba367b3fe33763b90600080516020613dff833981519152908c908790600401613ab6565b600060405180830381600087803b158015612efe57600080fd5b505af1158015612f12573d6000803e3d6000fd5b505050505b50505050505050565b6000846001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b158015612f5b57600080fd5b505afa158015612f6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f939190613362565b9050336001600160a01b03821614612fbd5760405162461bcd60e51b815260040161047990613d0d565b6000612ffe84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061103a92505050565b8060200190518101906130119190613858565b90506115258282600001518360400151612a34565b60405163ecf6578360e01b81526000906001600160a01b037f000000000000000000000000cce7819d65f348c64b7beb205ba367b3fe33763b169063ecf657839061307990600886901c90600401613d59565b60206040518083038186803b15801561309157600080fd5b505afa1580156130a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105fa9190613362565b60405163c346745160e01b81526000906001600160a01b037f000000000000000000000000cce7819d65f348c64b7beb205ba367b3fe33763b169063c346745190613079908590600401613d59565b63ffffffff1690565b60ff1690565b6001600160401b03166402540be4000290565b600061314582613118565b662386f26fc100000292915050565b60006002826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561319157600080fd5b505afa1580156131a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c99190613a0f565b0360ff16600a0a8302905092915050565b600082821115613231576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b604080518082019091526000808252602082015290565b60405180610180016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081526020016000600481111561329a57fe5b81526020016000815260200160008152602001600081526020016000815260200160006001600160a01b031681525090565b805161069a81613dd7565b600082601f8301126132e7578081fd5b81356132fa6132f582613d8a565b613d67565b81815284602083860101111561330e578283fd5b816020850160208301379081016020019190915292915050565b80516005811061069a57600080fd5b80516006811061069a57600080fd5b600060208284031215613357578081fd5b81356111d881613dd7565b600060208284031215613373578081fd5b81516111d881613dd7565b60008060008060608587031215613393578283fd5b843561339e81613dd7565b935060208501356133ae81613dd7565b925060408501356001600160401b03808211156133c9578384fd5b818701915087601f8301126133dc578384fd5b8135818111156133ea578485fd5b8860208285010111156133fb578485fd5b95989497505060200194505050565b60008060006060848603121561341e578081fd5b833561342981613dd7565b9250602084013561343981613dd7565b929592945050506040919091013590565b6000602080838503121561345c578182fd5b82516001600160401b0380821115613472578384fd5b818501915085601f830112613485578384fd5b81518181111561349157fe5b61349e8485830201613d67565b8181528481019250838501865b8381101561350e57815186018a603f8201126134c5578889fd5b8781015160406134d76132f583613d8a565b8281528d828486010111156134ea578b8cfd5b6134f9838c8301848701613dab565b885250505093860193908601906001016134ab565b509098975050505050505050565b60006020828403121561352d578081fd5b815180151581146111d8578182fd5b60006020828403121561354d578081fd5b5035919050565b600060208284031215613565578081fd5b81356001600160401b0381111561357a578182fd5b611208848285016132d7565b60008060408385031215613598578182fd5b82356001600160401b038111156135ad578283fd5b6135b9858286016132d7565b95602094909401359450505050565b6000806000606084860312156135dc578081fd5b83356001600160401b038111156135f1578182fd5b6135fd868287016132d7565b9660208601359650604090950135949350505050565b60008060408385031215613625578182fd5b82356001600160401b0381111561363a578283fd5b613646858286016132d7565b925050602083013561365781613def565b809150509250929050565b600080600060608486031215613676578081fd5b83356001600160401b0381111561368b578182fd5b613697868287016132d7565b935050602084013561343981613def565b6000806000606084860312156136bc578081fd5b83356001600160401b038111156136d1578182fd5b6136dd868287016132d7565b93505060208401356136ee81613def565b915060408401356136fe81613def565b809150509250925092565b60006020828403121561371a578081fd5b6111d882613337565b6000610140808385031215613736578182fd5b61373f81613d67565b905061374a836132cc565b8152613758602084016132cc565b6020820152613769604084016132cc565b604082015261377a606084016132cc565b606082015261378b608084016132cc565b608082015261379c60a084016132cc565b60a08201526137ad60c084016132cc565b60c08201526137be60e084016132cc565b60e08201526101006137d18185016132cc565b908201526101206137e38482016132cc565b908201529392505050565b6000606082840312156137ff578081fd5b604051606081018181106001600160401b038211171561381b57fe5b604052825161382981613dd7565b8152602083015161383981613dd7565b6020820152604083015161384c81613dd7565b60408201529392505050565b600061018080838503121561386b578182fd5b61387481613d67565b905061387f836132cc565b81526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a08201526138bf60c08401613328565b60c082015260e083810151908201526101008084015190820152610120808401519082015261014080840151908201526101606137e38185016132cc565b60006040828403121561390e578081fd5b604051604081018181106001600160401b038211171561392a57fe5b604052825161393881613dd7565b81526020928301519281019290925250919050565b600060c0828403121561395e578081fd5b60405160c081018181106001600160401b038211171561397a57fe5b8060405250825181526020830151602082015261399960408401613328565b604082015260608301516060820152608083015160808201526139be60a08401613337565b60a08201529392505050565b6000602082840312156139db578081fd5b5051919050565b6000806000606084860312156139f6578081fd5b8351925060208401519150604084015190509250925092565b600060208284031215613a20578081fd5b81516111d881613def565b60008151808452613a43816020860160208601613dab565b601f01601f19169290920160200192915050565b80516001600160a01b03168252602090810151910152565b6001600160a01b0391909116815260200190565b6001600160a01b038581168252602082018590528316604082015260806060820181905260009061068e90830184613a2b565b6001600160a01b039485168152602081019390935292166040820152606081019190915260800190565b602080825282518282018190526000919060409081850190868401855b82811015613b2057613b10848351613a57565b9284019290850190600101613afd565b5091979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613b6557835183529284019291840191600101613b49565b50909695505050505050565b901515815260200190565b90815260200190565b9182526001600160a01b0316602082015260400190565b6001600160e01b031991909116815260200190565b6000602082526111d86020830184613a2b565b6020808252601790820152761d5b9cdd5c1c1bdc9d1959081c5d5bdd1948185cdcd95d604a1b604082015260600190565b60208082526010908201526f1b1e5c98481b9bdd08195b98589b195960821b604082015260600190565b6020808252601690820152751d5b9cdd5c1c1bdc9d19590818985cd948185cdcd95d60521b604082015260600190565b6020808252600e908201526d1a5b9d985b1a59081b595d1a1bd960921b604082015260600190565b6020808252601390820152723737ba1031b637b9b2b2103837b9b4ba34b7b760691b604082015260600190565b602080825260189082015277706f736974696f6e206973206e6f7420696e20747261636b60401b604082015260600190565b6020808252601d908201527f657863656564206d6178696d756d20706f736974696f6e20636f756e74000000604082015260600190565b6020808252600e908201526d6e6f7420706f6f6c206c6f67696360901b604082015260600190565b604081016105fa8284613a57565b61ffff9290921682521515602082015260400190565b60ff91909116815260200190565b6040518181016001600160401b0381118282101715613d8257fe5b604052919050565b60006001600160401b03821115613d9d57fe5b50601f01601f191660200190565b60005b83811015613dc6578181015183820152602001613dae565b83811115610c265750506000910152565b6001600160a01b0381168114613dec57600080fd5b50565b60ff81168114613dec57600080fdfe9bb8215865837737a430a2ed3e9c04cabdb00a3a0eb47bf3b216ebc38d14a326a2646970667358221220c8f164429155a469b2711477d872d68ad0eb4645a4d4b447601499e5d3af101b64736f6c63430007060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000cce7819d65f348c64b7beb205ba367b3fe33763b000000000000000000000000eaf788ad8abd9c98ba05f6802a62b8dbc673d76b000000000000000000000000d0d2eb0f55f626ac8ed144f9fe824e416f7e743d0000000000000000000000000000000000000000000000000000000000000002
-----Decoded View---------------
Arg [0] : _marketWrapper (address): 0xCCE7819d65f348c64B7Beb205BA367b3fE33763B
Arg [1] : _marketViewer (address): 0xEAf788AD8abd9C98bA05F6802a62B8DbC673D76B
Arg [2] : _nftTracker (address): 0xd0D2eB0F55F626Ac8ed144f9fE824e416F7e743D
Arg [3] : _maxPositionCount (uint256): 2
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000cce7819d65f348c64b7beb205ba367b3fe33763b
Arg [1] : 000000000000000000000000eaf788ad8abd9c98ba05f6802a62b8dbc673d76b
Arg [2] : 000000000000000000000000d0d2eb0f55f626ac8ed144f9fe824e416f7e743d
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000002
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.