Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Sponsored
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
107557632 | 439 days ago | 0 ETH | ||||
107557632 | 439 days ago | 0 ETH | ||||
107557632 | 439 days ago | 0 ETH | ||||
107557632 | 439 days ago | 0 ETH | ||||
107557632 | 439 days ago | 0 ETH | ||||
107557632 | 439 days ago | 0 ETH | ||||
107557632 | 439 days ago | 0 ETH | ||||
107557632 | 439 days ago | 0 ETH | ||||
107557632 | 439 days ago | 0 ETH | ||||
107557632 | 439 days ago | 0 ETH | ||||
107557632 | 439 days ago | 0 ETH | ||||
107557632 | 439 days ago | 0 ETH | ||||
107557632 | 439 days ago | 0 ETH | ||||
107557632 | 439 days ago | 0 ETH | ||||
107557632 | 439 days ago | 0 ETH | ||||
107557579 | 439 days ago | 0 ETH | ||||
107557579 | 439 days ago | 0 ETH | ||||
107557579 | 439 days ago | 0 ETH | ||||
107557579 | 439 days ago | 0 ETH | ||||
107557579 | 439 days ago | 0 ETH | ||||
107557579 | 439 days ago | 0 ETH | ||||
107557579 | 439 days ago | 0 ETH | ||||
107557579 | 439 days ago | 0 ETH | ||||
107557579 | 439 days ago | 0 ETH | ||||
107557577 | 439 days ago | 0 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
PoolFactory
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 experimental ABIEncoderV2; import "./PoolLogic.sol"; import "./upgradability/ProxyFactory.sol"; import "./interfaces/IAssetHandler.sol"; import "./interfaces/IHasDaoInfo.sol"; import "./interfaces/IHasFeeInfo.sol"; import "./interfaces/IHasAssetInfo.sol"; import "./interfaces/IPoolLogic.sol"; import "./interfaces/IHasGuardInfo.sol"; import "./interfaces/IHasPausable.sol"; import "./interfaces/IHasSupportedAsset.sol"; import "./interfaces/IGovernance.sol"; import "./interfaces/IManaged.sol"; import "./utils/AddressHelper.sol"; import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; /// @title Pool Factory /// @dev A Factory to spawn pools contract PoolFactory is PausableUpgradeable, ProxyFactory, IHasDaoInfo, IHasFeeInfo, IHasAssetInfo, IHasGuardInfo, IHasPausable { using SafeMathUpgradeable for uint256; using AddressHelper for address; struct PoolPausedInfo { address pool; bool paused; } event FundCreated( address fundAddress, bool isPoolPrivate, string fundName, string managerName, address manager, uint256 time, uint256 performanceFeeNumerator, uint256 managerFeeNumerator, uint256 managerFeeDenominator ); event PoolEvent(address poolAddress); event PoolManagerEvent(address poolManagerAddress); event DAOAddressSet(address daoAddress); event GovernanceAddressSet(address governanceAddress); event DaoFeeSet(uint256 numerator, uint256 denominator); event ExitFeeSet(uint256 numerator, uint256 denominator); event ExitCooldownSet(uint256 cooldown); event MaximumSupportedAssetCountSet(uint256 count); event LogUpgrade(address indexed manager, address indexed pool); event SetPoolManagerFee(uint256 numerator, uint256 denominator); event SetMaximumFee( uint256 performanceFeeNumerator, uint256 managerFeeNumerator, uint256 entryFeeNumerator, uint256 denominator ); event SetMaximumPerformanceFeeNumeratorChange(uint256 amount); event SetAssetHandler(address assetHandler); event SetPoolStorageVersion(uint256 poolStorageVersion); event SetPerformanceFeeNumeratorChangeDelay(uint256 delay); address[] public deployedFunds; address public override daoAddress; address public governanceAddress; address internal _assetHandler; uint256 internal _daoFeeNumerator; uint256 internal _daoFeeDenominator; mapping(address => bool) public isPool; // solhint-disable-next-line var-name-mixedcase uint256 private maximumPerformanceFeeNumerator; // solhint-disable-next-line var-name-mixedcase uint256 private _MANAGER_FEE_DENOMINATOR; uint256 internal _exitCooldown; uint256 internal _maximumSupportedAssetCount; mapping(address => uint256) public poolVersion; uint256 public poolStorageVersion; uint256 public override maximumPerformanceFeeNumeratorChange; uint256 public override performanceFeeNumeratorChangeDelay; // Added after initial deployment address public poolPerformanceAddress; // not used now uint256 private _exitFeeNumerator; uint256 private _exitFeeDenominator; // allows to perform pool deposit with lockup cooldown passed as param mapping(address => bool) public customCooldownWhitelist; uint256 private maximumManagerFeeNumerator; // A list of addresses that can receive tokens that are still under a lockup mapping(address => bool) public receiverWhitelist; uint256 private maximumEntryFeeNumerator; mapping(address => bool) public override pausedPools; /// @notice Initialize the factory /// @param _poolLogic The pool logic address /// @param _managerLogic The manager logic address /// @param assetHandler The address of the asset handler /// @param _daoAddress The address of the DAO /// @param _governanceAddress The address of the governance contract function initialize( address _poolLogic, address _managerLogic, address assetHandler, address _daoAddress, address _governanceAddress ) external initializer { __ProxyFactory_init(_poolLogic, _managerLogic); __Pausable_init(); _setAssetHandler(assetHandler); _setDAOAddress(_daoAddress); _setGovernanceAddress(_governanceAddress); _setMaximumFee(5000, 300, 100, 10000); // 50% manager fee, 3% streaming fee, 1% entry fee _setDaoFee(10, 100); // 10% _setExitFee(5, 1000); // 0.5% _setExitCooldown(1 days); setPerformanceFeeNumeratorChangeDelay(4 weeks); setMaximumPerformanceFeeNumeratorChange(1000); _setMaximumSupportedAssetCount(10); _setPoolStorageVersion(230); // V2.3.0; } modifier onlyPool() { require(isPool[msg.sender] == true, "only pools"); _; } modifier onlyPoolManager() { require(isPool[IPoolManagerLogic(msg.sender).poolLogic()] == true, "only managers"); _; } /// @notice implementations should not be left unintialized // solhint-disable-next-line no-empty-blocks function implInitializer() external initializer {} /// @notice Function to create a new fund /// @param _privatePool A boolean indicating whether the fund is private or not /// @param _manager A manager address /// @param _managerName The name of the manager /// @param _fundName The name of the fund /// @param _fundSymbol The symbol of the fund /// @param _performanceFeeNumerator The numerator of the manager fee /// @param _supportedAssets An array of supported assets /// @return fund Address of the fund function createFund( bool _privatePool, address _manager, string memory _managerName, string memory _fundName, string memory _fundSymbol, uint256 _performanceFeeNumerator, uint256 _managerFeeNumerator, IHasSupportedAsset.Asset[] memory _supportedAssets ) external returns (address fund) { require(!paused(), "contracts paused"); bytes memory poolLogicData = abi.encodeWithSignature( "initialize(address,bool,string,string)", address(this), _privatePool, _fundName, _fundSymbol ); fund = deploy(poolLogicData, 2); bytes memory managerLogicData = abi.encodeWithSignature( "initialize(address,address,string,address,uint256,uint256,(address,bool)[])", address(this), _manager, _managerName, fund, _performanceFeeNumerator, _managerFeeNumerator, _supportedAssets ); address managerLogic = deploy(managerLogicData, 1); // Ignore return value as want it to continue regardless IPoolLogic(fund).setPoolManagerLogic(managerLogic); deployedFunds.push(fund); isPool[fund] = true; poolVersion[fund] = poolStorageVersion; emit FundCreated( fund, _privatePool, _fundName, _managerName, _manager, block.timestamp, _performanceFeeNumerator, _managerFeeNumerator, _MANAGER_FEE_DENOMINATOR ); } /// @notice Add an address to the whitelist /// @dev allows address to perform pool deposit with custom lockup cooldown /// @param _extAddress The address to add to whitelist function addCustomCooldownWhitelist(address _extAddress) external onlyOwner { customCooldownWhitelist[_extAddress] = true; } /// @notice Remove an address from the whitelist /// @dev allows address to perform pool deposit with custom lockup cooldown /// @param _extAddress The address to remove from whitelist function removeCustomCooldownWhitelist(address _extAddress) external onlyOwner { customCooldownWhitelist[_extAddress] = false; } /// @notice Add an address to the whitelist /// @dev allows address to receive tokens that are under lockup /// @param _extAddress The address to add to whitelist function addReceiverWhitelist(address _extAddress) external onlyOwner { receiverWhitelist[_extAddress] = true; } /// @notice Remove an address from the whitelist /// @dev disallows address to receive tokens that are under lockup /// @param _extAddress The address to remove from whitelist function removeReceiverWhitelist(address _extAddress) external onlyOwner { receiverWhitelist[_extAddress] = false; } // DAO info (Uber Pool) /// @notice Set the DAO address /// @param _daoAddress The address of the DAO function setDAOAddress(address _daoAddress) external onlyOwner { _setDAOAddress(_daoAddress); } /// @notice Set the DAO address internal call /// @param _daoAddress The address of the DAO function _setDAOAddress(address _daoAddress) internal { require(_daoAddress != address(0), "Invalid daoAddress"); daoAddress = _daoAddress; emit DAOAddressSet(_daoAddress); } // Governance info /// @notice Set the governance address /// @param _governanceAddress The address of the governance contract function setGovernanceAddress(address _governanceAddress) external onlyOwner { _setGovernanceAddress(_governanceAddress); } /// @notice Set the governance address internal call /// @param _governanceAddress The address of the governance contract function _setGovernanceAddress(address _governanceAddress) internal { require(_governanceAddress != address(0), "Invalid governanceAddress"); governanceAddress = _governanceAddress; emit GovernanceAddressSet(_governanceAddress); } /// @notice Set the DAO fee /// @param numerator The numerator of the DAO fee /// @param denominator The denominator of the DAO fee function setDaoFee(uint256 numerator, uint256 denominator) external onlyOwner { _setDaoFee(numerator, denominator); } /// @notice Set the DAO fee internal call /// @param numerator The numerator of the DAO fee /// @param denominator The denominator of the DAO fee function _setDaoFee(uint256 numerator, uint256 denominator) internal { require(numerator <= denominator, "invalid fraction"); _daoFeeNumerator = numerator; _daoFeeDenominator = denominator; emit DaoFeeSet(numerator, denominator); } /// @notice Get the DAO fee /// @return The numerator of the DAO fee /// @return The denominator of the DAO fee function getDaoFee() external view override returns (uint256, uint256) { return (_daoFeeNumerator, _daoFeeDenominator); } /// @notice Set the Exit fee /// @param numerator The numerator of the Exit fee /// @param denominator The denominator of the Exit fee function setExitFee(uint256 numerator, uint256 denominator) external onlyOwner { _setExitFee(numerator, denominator); } /// @notice Set the Exit fee internal call /// @param numerator The numerator of the Exit fee /// @param denominator The denominator of the Exit fee function _setExitFee(uint256 numerator, uint256 denominator) internal { require(numerator <= denominator, "invalid fraction"); _exitFeeNumerator = numerator; _exitFeeDenominator = denominator; emit ExitFeeSet(numerator, denominator); } /// @notice Get the Exit fee /// @return The numerator of the Exit fee /// @return The denominator of the Exit fee function getExitFee() external view override returns (uint256, uint256) { return (_exitFeeNumerator, _exitFeeDenominator); } // Manager fees /// @notice Get the maximum manager fee /// @return The maximum manager fee numerator /// @return The maximum entry fee numerator /// @return The maximum manager fee denominator function getMaximumFee() external view override returns ( uint256, uint256, uint256, uint256 ) { return ( maximumPerformanceFeeNumerator, maximumManagerFeeNumerator, maximumEntryFeeNumerator, _MANAGER_FEE_DENOMINATOR ); } /// @notice Set the maximum manager fee /// @param performanceFeeNumerator The numerator of the maximum manager fee /// @param managerFeeNumerator The numerator of the maximum streaming fee function setMaximumFee( uint256 performanceFeeNumerator, uint256 managerFeeNumerator, uint256 entryFeeNumerator ) external onlyOwner { _setMaximumFee(performanceFeeNumerator, managerFeeNumerator, entryFeeNumerator, _MANAGER_FEE_DENOMINATOR); } /// @notice Set the maximum manager fee internal call /// @param performanceFeeNumerator The numerator of the maximum manager fee /// @param managerFeeNumerator The numerator of the maximum streaming fee /// @param denominator The denominator of the maximum manager fee function _setMaximumFee( uint256 performanceFeeNumerator, uint256 managerFeeNumerator, uint256 entryFeeNumerator, uint256 denominator ) internal { require( performanceFeeNumerator <= denominator && managerFeeNumerator <= denominator && entryFeeNumerator <= denominator, "invalid fraction" ); maximumPerformanceFeeNumerator = performanceFeeNumerator; maximumManagerFeeNumerator = managerFeeNumerator; _MANAGER_FEE_DENOMINATOR = denominator; maximumEntryFeeNumerator = entryFeeNumerator; emit SetMaximumFee(performanceFeeNumerator, managerFeeNumerator, entryFeeNumerator, denominator); } /// @notice Set maximum manager fee numberator change /// @param amount The amount for the maximum manager fee numerator change function setMaximumPerformanceFeeNumeratorChange(uint256 amount) public onlyOwner { maximumPerformanceFeeNumeratorChange = amount; emit SetMaximumPerformanceFeeNumeratorChange(amount); } /// @notice Set manager fee numberator change delay /// @param delay The delay in seconds for the manager fee numerator change function setPerformanceFeeNumeratorChangeDelay(uint256 delay) public onlyOwner { performanceFeeNumeratorChangeDelay = delay; emit SetPerformanceFeeNumeratorChangeDelay(delay); } /// @notice Set exit cool down time (in seconds) /// @param cooldown The cool down time in seconds function setExitCooldown(uint256 cooldown) external onlyOwner { _setExitCooldown(cooldown); } /// @notice Set exit cool down time (in seconds) internal call /// @param cooldown The cool down time in seconds function _setExitCooldown(uint256 cooldown) internal { _exitCooldown = cooldown; emit ExitCooldownSet(cooldown); } /// @notice Get the exit cool down time (in seconds) /// @return The exit cool down time in seconds function getExitCooldown() external view override returns (uint256) { return _exitCooldown; } // Asset Info /// @notice Set maximum supported asset count /// @param count The maximum supported asset count function setMaximumSupportedAssetCount(uint256 count) external onlyOwner { _setMaximumSupportedAssetCount(count); } /// @notice Set maximum supported asset count internal call /// @param count The maximum supported asset count function _setMaximumSupportedAssetCount(uint256 count) internal { _maximumSupportedAssetCount = count; emit MaximumSupportedAssetCountSet(count); } /// @notice Get maximum supported asset count /// @return The maximum supported asset count function getMaximumSupportedAssetCount() external view virtual override returns (uint256) { return _maximumSupportedAssetCount; } /// @notice Return boolean if the asset is supported /// @return True if it's valid asset, false otherwise function isValidAsset(address asset) public view override returns (bool) { return IAssetHandler(_assetHandler).priceAggregators(asset) != address(0); } /// @notice Return the latest price of a given asset /// @param asset The address of the asset /// @return price The latest price of a given asset function getAssetPrice(address asset) external view override returns (uint256 price) { price = IAssetHandler(_assetHandler).getUSDPrice(asset); } /// @notice Return type of the asset /// @param asset The address of the asset /// @return assetType The type of the asset function getAssetType(address asset) external view override returns (uint16 assetType) { assetType = IAssetHandler(_assetHandler).assetTypes(asset); } /// @notice Return the address of the asset handler /// @return Address of the asset handler function getAssetHandler() external view returns (address) { return _assetHandler; } /// @notice Set the asset handler address /// @param assetHandler The address of the asset handler function setAssetHandler(address assetHandler) external onlyOwner { _setAssetHandler(assetHandler); } /// @notice Set the asset handler address internal call /// @param assetHandler The address of the asset handler function _setAssetHandler(address assetHandler) internal { require(assetHandler != address(0), "Invalid assetHandler"); _assetHandler = assetHandler; emit SetAssetHandler(assetHandler); } // Upgrade /// @notice Set the pool storage version /// @param _poolStorageVersion The pool storage version function setPoolStorageVersion(uint256 _poolStorageVersion) external onlyOwner { _setPoolStorageVersion(_poolStorageVersion); } /// @notice Set the pool storage version internal call /// @param _poolStorageVersion The pool storage version function _setPoolStorageVersion(uint256 _poolStorageVersion) internal { require(_poolStorageVersion > poolStorageVersion, "version needs to be higher"); poolStorageVersion = _poolStorageVersion; emit SetPoolStorageVersion(_poolStorageVersion); } /** * @notice Backdoor function * @param pool Address of the target. * @param data Calldata for the target address. * @param targetVersion set target version after call */ function _upgradePool( address pool, bytes calldata data, uint256 targetVersion ) internal { require(pool != address(0), "target-invalid"); require(data.length > 0, "data-invalid"); require(poolVersion[pool] < targetVersion, "already upgraded"); pool.tryAssemblyDelegateCall(data); emit LogUpgrade(msg.sender, pool); poolVersion[pool] = targetVersion; } /// @notice Upgrade pools in batch /// @param startIndex The start index of the pool upgrade /// @param endIndex The end index of the pool upgrade /// @param targetVersion The target version of the pool upgrade /// @param data The calldata for the target address function upgradePoolBatch( uint256 startIndex, uint256 endIndex, uint256 targetVersion, bytes calldata data ) external onlyOwner { require(startIndex <= endIndex && endIndex < deployedFunds.length, "invalid bounds"); for (uint256 i = startIndex; i <= endIndex; i++) { address pool = deployedFunds[i]; if (pool == address(0)) continue; if (poolVersion[pool] >= targetVersion) continue; _upgradePool(pool, data, targetVersion); } } /// @notice Upgrade pools in batch with array of data /// @param startIndex The start index of the pool upgrade /// @param endIndex The end index of the pool upgrade /// @param targetVersion The target version of the pool upgrade /// @param data Array of calldata for the target address function upgradePoolBatch( uint256 startIndex, uint256 endIndex, uint256 targetVersion, bytes[] calldata data ) external onlyOwner { require(startIndex <= endIndex && endIndex < deployedFunds.length, "invalid bounds"); require(data.length == endIndex.sub(startIndex).add(1), "data not metch index"); for (uint256 i = startIndex; i <= endIndex; i++) { address pool = deployedFunds[i]; if (pool == address(0)) continue; if (poolVersion[pool] >= targetVersion) continue; _upgradePool(pool, data[i.sub(startIndex)], targetVersion); } } /// @notice call the pause the contract function pause() external onlyOwner { _pause(); } /// @notice call the unpause the contract function unpause() external onlyOwner { _unpause(); } /// @notice Return the pause status /// @return The pause status function isPaused() external view override returns (bool) { return paused(); } /// @notice Set the pause status of the pool /// @param pools The array of pool paused info /// @dev This function is used to pause/unpause the pool /// @dev The pool can be paused/unpaused by the owner only function setPoolsPaused(PoolPausedInfo[] calldata pools) external onlyOwner { uint256 poolsLength = pools.length; for (uint256 i = 0; i < poolsLength; i++) { PoolPausedInfo memory poolInfo = pools[i]; require(isPool[poolInfo.pool], "invalid pool"); pausedPools[poolInfo.pool] = poolInfo.paused; } } // Transaction Guards /// @notice Get address of the contract guard /// @param extContract The address of the external contract /// @return guard Return the address of the transaction guard function getContractGuard(address extContract) external view override returns (address guard) { guard = IGovernance(governanceAddress).contractGuards(extContract); } /// @notice Get address of the asset guard /// @param extAsset The address of the external asset /// @return guard Address of the asset guard function getAssetGuard(address extAsset) public view override returns (address guard) { if (isValidAsset(extAsset)) { uint16 assetType = IAssetHandler(_assetHandler).assetTypes(extAsset); guard = IGovernance(governanceAddress).assetGuards(assetType); } } /// @notice Get address from the Governance contract /// @param name The name of the address /// @return destination The destination address function getAddress(bytes32 name) public view override returns (address destination) { destination = IGovernance(governanceAddress).nameToDestination(name); require(destination != address(0), "governance: invalid name"); } /// @notice Return full array of deployed funds /// @return Full array of deployed funds function getDeployedFunds() external view returns (address[] memory) { return deployedFunds; } /** * @notice Returns all invested pools by a given user * @param user the user address * @return investedPools All invested pools by a given user */ function getInvestedPools(address user) external view returns (address[] memory investedPools) { uint256 length = deployedFunds.length; investedPools = new address[](length); uint256 index = 0; for (uint256 i = 0; i < length; i++) { if (IERC20Upgradeable(deployedFunds[i]).balanceOf(user) > 0) { investedPools[index] = deployedFunds[i]; index++; } } uint256 reduceLength = length.sub(index); assembly { mstore(investedPools, sub(mload(investedPools), reduceLength)) } } /** * @notice Returns all managed pools by a given manager * @param manager The manager address * @return managedPools All managed pools by a given manager */ function getManagedPools(address manager) external view returns (address[] memory managedPools) { uint256 length = deployedFunds.length; managedPools = new address[](length); uint256 index = 0; for (uint256 i = 0; i < length; i++) { address poolManagerLogic = IPoolLogic(deployedFunds[i]).poolManagerLogic(); if (IManaged(poolManagerLogic).manager() == manager) { managedPools[index] = deployedFunds[i]; index++; } } uint256 reduceLength = length.sub(index); assembly { mstore(managedPools, sub(mload(managedPools), reduceLength)) } } /// @notice Allows us to just listen to the PoolFactory for all pool events function emitPoolEvent() external onlyPool { emit PoolEvent(msg.sender); } /// @notice Allows us to just listen to the PoolFactory for all poolManager events function emitPoolManagerEvent() external onlyPoolManager { emit PoolManagerEvent(msg.sender); } // The Factory is not safe to be inherited by other contracts // uint256[47] private __gap; }
// 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; }
// 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 // 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; import "../../utils/ContextUpgradeable.sol"; import "./IERC20Upgradeable.sol"; import "../../math/SafeMathUpgradeable.sol"; import "../../proxy/Initializable.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable { using SafeMathUpgradeable for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for {name} and {symbol}, initializes {decimals} with * a default value of 18. * * To select a different value for {decimals}, use {_setupDecimals}. * * All three of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name_, string memory symbol_) internal initializer { __Context_init_unchained(); __ERC20_init_unchained(name_, symbol_); } function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer { _name = name_; _symbol = symbol_; _decimals = 18; } /** * @dev Returns the name of the token. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is * called. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual returns (uint8) { return _decimals; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `to` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Sets {decimals} to a value other than the default one of 18. * * WARNING: This function should only be called from the constructor. Most * applications that interact with token contracts will not expect * {decimals} to ever change, and may work incorrectly if it does. */ function _setupDecimals(uint8 decimals_) internal virtual { _decimals = decimals_; } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be to transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } uint256[44] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @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); }
// 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); } } } }
// 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 pragma solidity ^0.7.0; import "./ContextUpgradeable.sol"; import "../proxy/Initializable.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal initializer { __Context_init_unchained(); __Pausable_init_unchained(); } function __Pausable_init_unchained() internal initializer { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "../proxy/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal initializer { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal initializer { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } 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; pragma experimental ABIEncoderV2; import "./IAssetGuard.sol"; interface IAaveLendingPoolAssetGuard { function flashloanProcessing( address pool, uint256 portion, address[] memory repayAssets, uint256[] memory repayAmounts, uint256[] memory premiums, uint256[] memory interestRateModes ) external view returns (IAssetGuard.MultiTransaction[] memory transactions); function aaveLendingPool() external view returns (address); }
// // __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // 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; import "../IHasSupportedAsset.sol"; interface IAssetGuard { struct MultiTransaction { address to; bytes txData; } function withdrawProcessing( address pool, address asset, uint256 withdrawPortion, address to ) external returns ( address, uint256, MultiTransaction[] memory transactions ); function getBalance(address pool, address asset) external view returns (uint256 balance); function getDecimals(address asset) external view returns (uint256 decimals); function removeAssetCheck(address poolLogic, address asset) external view; }
// // __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // 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); // TODO: eventually update `txType` to be of enum type as per ITransactionTypes }
// // __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // 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; }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma experimental ABIEncoderV2; interface IAssetHandler { event AddedAsset(address asset, uint16 assetType, address aggregator); event RemovedAsset(address asset); struct Asset { address asset; uint16 assetType; address aggregator; } function addAsset( address asset, uint16 assetType, address aggregator ) external; function addAssets(Asset[] memory assets) external; function removeAsset(address asset) external; function priceAggregators(address asset) external view returns (address); function assetTypes(address asset) external view returns (uint16); function getUSDPrice(address asset) external view returns (uint256); }
// 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); }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; interface IGovernance { function contractGuards(address target) external view returns (address guard); function assetGuards(uint16 assetType) external view returns (address guard); function nameToDestination(bytes32 name) external view returns (address); }
// // __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // 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 IHasAssetInfo { function isValidAsset(address asset) external view returns (bool); function getAssetPrice(address asset) external view returns (uint256); function getAssetType(address asset) external view returns (uint16); function getMaximumSupportedAssetCount() external view returns (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; interface IHasDaoInfo { function getDaoFee() external view returns (uint256, uint256); function daoAddress() external view returns (address); }
// // __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // 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 IHasFeeInfo { // Manager fee function getMaximumFee() external view returns ( uint256, uint256, uint256, uint256 ); function maximumPerformanceFeeNumeratorChange() external view returns (uint256); function performanceFeeNumeratorChangeDelay() external view returns (uint256); function getExitFee() external view returns (uint256, uint256); function getExitCooldown() external view returns (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; 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); }
// // __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // 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 IHasOwnable { function owner() external view returns (address); }
// // __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // 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 IHasPausable { function isPaused() external view returns (bool); function pausedPools(address pool) external view 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; 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); }
// // __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // 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 IManaged { function manager() external view returns (address); function trader() external view returns (address); function managerName() external view returns (string memory); }
// // __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // 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 IPoolFactory { function governanceAddress() external view returns (address); function isPool(address pool) external view returns (bool); function customCooldownWhitelist(address from) external view returns (bool); function receiverWhitelist(address to) external view returns (bool); function emitPoolEvent() external; function emitPoolManagerEvent() 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 mintManagerFee() external; 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 symbol() external view returns (string memory); function transferFrom( address from, address to, uint256 value ) external returns (bool); function getExitRemainingCooldown(address sender) external view returns (uint256 remaining); }
// // __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // 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, uint256 ); function minDepositUSD() external view returns (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: BUSL-1.1 pragma solidity 0.7.6; pragma experimental ABIEncoderV2; import "./interfaces/IERC20Extended.sol"; import "./interfaces/IHasDaoInfo.sol"; import "./interfaces/IHasFeeInfo.sol"; import "./interfaces/IHasGuardInfo.sol"; import "./interfaces/IPoolFactory.sol"; import "./interfaces/IHasAssetInfo.sol"; import "./interfaces/IHasPausable.sol"; import "./interfaces/IPoolManagerLogic.sol"; import "./interfaces/IHasSupportedAsset.sol"; import "./interfaces/IHasOwnable.sol"; import "./interfaces/IHasDaoInfo.sol"; import "./interfaces/IManaged.sol"; import "./interfaces/guards/IGuard.sol"; import "./interfaces/guards/ITxTrackingGuard.sol"; import "./interfaces/guards/IAssetGuard.sol"; import "./interfaces/guards/IAaveLendingPoolAssetGuard.sol"; import "./interfaces/IGovernance.sol"; import "./utils/AddressHelper.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol"; /// @notice Logic implementation for pool contract PoolLogic is ERC20Upgradeable, ReentrancyGuardUpgradeable { using SafeMathUpgradeable for uint256; using AddressHelper for address; struct FundSummary { string name; uint256 totalSupply; uint256 totalFundValue; address manager; string managerName; uint256 creationTime; bool privatePool; uint256 performanceFeeNumerator; uint256 managerFeeNumerator; uint256 managerFeeDenominator; uint256 exitFeeNumerator; uint256 exitFeeDenominator; uint256 entryFeeNumerator; } struct TxToExecute { address to; bytes data; } event Deposit( address fundAddress, address investor, address assetDeposited, uint256 amountDeposited, uint256 valueDeposited, uint256 fundTokensReceived, uint256 totalInvestorFundTokens, uint256 fundValue, uint256 totalSupply, uint256 time ); struct WithdrawnAsset { address asset; uint256 amount; bool externalWithdrawProcessed; } event Withdrawal( address fundAddress, address investor, uint256 valueWithdrawn, uint256 fundTokensWithdrawn, uint256 totalInvestorFundTokens, uint256 fundValue, uint256 totalSupply, WithdrawnAsset[] withdrawnAssets, uint256 time ); event TransactionExecuted(address pool, address manager, uint16 transactionType, uint256 time); event PoolPrivacyUpdated(bool isPoolPrivate); event ManagerFeeMinted( address pool, address manager, uint256 available, uint256 daoFee, uint256 managerFee, uint256 tokenPriceAtLastFeeMint ); event PoolManagerLogicSet(address poolManagerLogic, address from); bool public privatePool; address public creator; uint256 public creationTime; address public factory; // Manager fees uint256 public tokenPriceAtLastFeeMint; mapping(address => uint256) public lastDeposit; address public poolManagerLogic; mapping(address => uint256) public lastWhitelistTransfer; uint256 public lastFeeMintTime; mapping(address => uint256) public lastExitCooldown; modifier onlyAllowed(address _recipient) { require(_recipient == manager() || !privatePool || isMemberAllowed(_recipient), "only members allowed"); _; } modifier onlyManager() { require(msg.sender == manager(), "only manager"); _; } modifier whenNotFactoryPaused() { require(!IHasPausable(factory).isPaused(), "contracts paused"); _; } modifier whitelistedForCustomCooldown() { require(IPoolFactory(factory).customCooldownWhitelist(msg.sender), "only whitelisted sender"); _; } modifier whenNotPaused() { require(!IHasPausable(factory).pausedPools(address(this)), "pool is paused"); _; } /// @notice Initialize the pool /// @param _factory address of the factory /// @param _privatePool true if the pool is private, false otherwise /// @param _fundName name of the fund /// @param _fundSymbol symbol of the fund function initialize( address _factory, bool _privatePool, string memory _fundName, string memory _fundSymbol ) external initializer { require(_factory != address(0), "Invalid factory"); __ERC20_init(_fundName, _fundSymbol); __ReentrancyGuard_init(); factory = _factory; _setPoolPrivacy(_privatePool); creator = msg.sender; creationTime = block.timestamp; lastFeeMintTime = block.timestamp; tokenPriceAtLastFeeMint = 10**18; } /// @notice Before token transfer hook /// @param from address of the token owner /// @param to address of the token receiver /// @param amount amount of tokens to transfer function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual override { super._beforeTokenTransfer(from, to, amount); // Minting if (from == address(0)) { return; } if (IPoolFactory(factory).receiverWhitelist(to) == true) { return; } require(getExitRemainingCooldown(from) == 0, "cooldown active"); } /// @notice Set the pool privacy /// @param _privatePool true if the pool is private, false otherwise function setPoolPrivate(bool _privatePool) external onlyManager { require(privatePool != _privatePool, "flag must be different"); _setPoolPrivacy(_privatePool); emitFactoryEvent(); } /// @notice Set the pool privacy internal call /// @param _privacy true if the pool is private, false otherwise function _setPoolPrivacy(bool _privacy) internal { privatePool = _privacy; emit PoolPrivacyUpdated(_privacy); } /// @notice Deposit funds into the pool /// @param _asset Address of the token /// @param _amount Amount of tokens to deposit /// @return liquidityMinted Amount of liquidity minted function deposit(address _asset, uint256 _amount) external returns (uint256 liquidityMinted) { return _depositFor(msg.sender, _asset, _amount, IHasFeeInfo(factory).getExitCooldown()); } function depositFor( address _recipient, address _asset, uint256 _amount ) external returns (uint256 liquidityMinted) { return _depositFor(_recipient, _asset, _amount, IHasFeeInfo(factory).getExitCooldown()); } function depositForWithCustomCooldown( address _recipient, address _asset, uint256 _amount, uint256 _cooldown ) external whitelistedForCustomCooldown returns (uint256 liquidityMinted) { require(_cooldown >= 5 minutes, "cooldown must exceed 5 mins"); require(_cooldown <= IHasFeeInfo(factory).getExitCooldown(), "cant exceed default cooldown"); return _depositFor(_recipient, _asset, _amount, _cooldown); } function _depositFor( address _recipient, address _asset, uint256 _amount, uint256 _cooldown ) private onlyAllowed(_recipient) whenNotFactoryPaused whenNotPaused returns (uint256 liquidityMinted) { require(IPoolManagerLogic(poolManagerLogic).isDepositAsset(_asset), "invalid deposit asset"); uint256 fundValue = _mintManagerFee(); uint256 totalSupplyBefore = totalSupply(); _asset.tryAssemblyCall( abi.encodeWithSelector(IERC20Upgradeable.transferFrom.selector, msg.sender, address(this), _amount) ); uint256 usdAmount = IPoolManagerLogic(poolManagerLogic).assetValue(_asset, _amount); // Scoping to avoid stack too deep errors. { (, , uint256 entryFeeNumerator, uint256 denominator) = IPoolManagerLogic(poolManagerLogic).getFee(); if (totalSupplyBefore > 0) { // Accounting for entry fee while calculating liquidity to be minted. liquidityMinted = usdAmount.mul(totalSupplyBefore).mul(denominator.sub(entryFeeNumerator)).div(fundValue).div( denominator ); } else { // This is equivalent to doing liquidityMinted = liquidityMinted * (1 - entryFeeNumerator/denominator). liquidityMinted = usdAmount.mul(denominator.sub(entryFeeNumerator)).div(denominator); } } // Note: We are making it impossible for someone to mint liquidity < 100_000. // This is so that we can mitigate the inflation attack. require(liquidityMinted >= 100_000, "invalid liquidityMinted"); lastExitCooldown[_recipient] = calculateCooldown( balanceOf(_recipient), liquidityMinted, _cooldown, lastExitCooldown[_recipient], lastDeposit[_recipient], block.timestamp ); lastDeposit[_recipient] = block.timestamp; _mint(_recipient, liquidityMinted); uint256 balance = balanceOf(_recipient); uint256 fundValueAfter = fundValue.add(usdAmount); uint256 totalSupplyAfter = totalSupplyBefore.add(liquidityMinted); require( balance.mul(_tokenPrice(fundValueAfter, totalSupplyAfter)).div(10**18) >= IPoolManagerLogic(poolManagerLogic).minDepositUSD(), "must meet minimum deposit" ); emit Deposit( address(this), _recipient, _asset, _amount, usdAmount, liquidityMinted, balance, fundValueAfter, totalSupplyAfter, block.timestamp ); emitFactoryEvent(); } function withdraw(uint256 _fundTokenAmount) external { withdrawTo(msg.sender, _fundTokenAmount); } /// @notice Withdraw assets based on the fund token amount /// @param _fundTokenAmount the fund token amount function withdrawTo(address _recipient, uint256 _fundTokenAmount) public virtual nonReentrant whenNotFactoryPaused whenNotPaused { require(lastDeposit[msg.sender] < block.timestamp, "can withdraw shortly"); require(balanceOf(msg.sender) >= _fundTokenAmount, "insufficient balance"); // Scoping to avoid "stack-too-deep" errors. { // Calculating how much pool token supply will be left after withdrawal and // whether or not this satisfies the min supply (100_000) check. // If the user is redeeming all the shares then this check passes. // Otherwise, they might have to reduce the amount to be withdrawn. uint256 supplyAfter = totalSupply().sub(_fundTokenAmount); require(supplyAfter >= 100_000 || supplyAfter == 0, "below supply threshold"); } // calculate the exit fee uint256 fundValue = _mintManagerFee(); // calculate the proportion uint256 portion = _fundTokenAmount.mul(10**18).div(totalSupply()); // first return funded tokens _burn(msg.sender, _fundTokenAmount); // TODO: Combining into one line to fix stack too deep, // need to refactor some variables into struct in order to have more variables IHasSupportedAsset.Asset[] memory _supportedAssets = IHasSupportedAsset(poolManagerLogic).getSupportedAssets(); WithdrawnAsset[] memory withdrawnAssets = new WithdrawnAsset[](_supportedAssets.length); uint16 index = 0; for (uint256 i = 0; i < _supportedAssets.length; i++) { (address asset, uint256 portionOfAssetBalance, bool externalWithdrawProcessed) = _withdrawProcessing( _supportedAssets[i].asset, _recipient, portion ); if (portionOfAssetBalance > 0) { require(asset != address(0), "requires asset to withdraw"); // Ignoring return value for transfer as want to transfer no matter what happened asset.tryAssemblyCall( abi.encodeWithSelector(IERC20Upgradeable.transfer.selector, _recipient, portionOfAssetBalance) ); } if (externalWithdrawProcessed || portionOfAssetBalance > 0) { withdrawnAssets[index] = WithdrawnAsset({ asset: asset, amount: portionOfAssetBalance, externalWithdrawProcessed: externalWithdrawProcessed }); index++; } } // Reduce length for withdrawnAssets to remove the empty items uint256 reduceLength = _supportedAssets.length.sub(index); assembly { mstore(withdrawnAssets, sub(mload(withdrawnAssets), reduceLength)) } uint256 valueWithdrawn = portion.mul(fundValue).div(10**18); emit Withdrawal( address(this), msg.sender, valueWithdrawn, _fundTokenAmount, balanceOf(msg.sender), fundValue.sub(valueWithdrawn), totalSupply(), withdrawnAssets, block.timestamp ); emitFactoryEvent(); } /// @notice Perform any additional processing on withdrawal of asset /// @dev Checks for staked tokens and withdraws them to the investor account /// @param asset Asset for withdrawal processing /// @param to Investor account to send withdrawed tokens to /// @param portion Portion of investor withdrawal of the total dHedge pool /// @return withdrawAsset Asset to be withdrawed /// @return withdrawBalance Asset balance amount to be withdrawed /// @return externalWithdrawProcessed A boolean for success or fail transaction function _withdrawProcessing( address asset, address to, uint256 portion ) internal returns ( address, // withdrawAsset uint256, // withdrawBalance bool externalWithdrawProcessed ) { // Withdraw any external tokens (eg. staked tokens in other contracts) address guard = IHasGuardInfo(factory).getAssetGuard(asset); require(guard != address(0), "invalid guard"); (address withdrawAsset, uint256 withdrawBalance, IAssetGuard.MultiTransaction[] memory transactions) = IAssetGuard( guard ).withdrawProcessing(address(this), asset, portion, to); uint256 txCount = transactions.length; if (txCount > 0) { uint256 assetBalanceBefore; if (withdrawAsset != address(0)) { assetBalanceBefore = IERC20Upgradeable(withdrawAsset).balanceOf(address(this)); } for (uint256 i = 0; i < txCount; i++) { externalWithdrawProcessed = transactions[i].to.tryAssemblyCall(transactions[i].txData); } if (withdrawAsset != address(0)) { // get any balance increase after withdraw processing and add it to the withdraw balance uint256 assetBalanceAfter = IERC20Upgradeable(withdrawAsset).balanceOf(address(this)); withdrawBalance = withdrawBalance.add(assetBalanceAfter.sub(assetBalanceBefore)); } } return (withdrawAsset, withdrawBalance, externalWithdrawProcessed); } /// @notice Private function to let pool talk to other protocol /// @dev execute transaction for the pool /// @param to The destination address for pool to talk to /// @param data The data that going to send in the transaction /// @return success A boolean for success or fail transaction function _execTransaction(address to, bytes memory data) private nonReentrant whenNotFactoryPaused returns (bool success) { require(to != address(0), "non-zero address is required"); address contractGuard = IHasGuardInfo(factory).getContractGuard(to); address assetGuard; address guard; uint16 txType; bool isPublic; if (contractGuard != address(0)) { guard = contractGuard; (txType, isPublic) = IGuard(contractGuard).txGuard(poolManagerLogic, to, data); } // invalid contract guard call, try asset guard if (txType == 0) { // no contract guard configured, get asset guard assetGuard = IHasGuardInfo(factory).getAssetGuard(to); if (assetGuard == address(0)) { // If there is no contractGuard and no assetGuard then use the ERC20Guard for the transaction, // which will only allow a valid approve transaction address governanceAddress = IPoolFactory(factory).governanceAddress(); assetGuard = IGovernance(governanceAddress).assetGuards(0); // get ERC20Guard (assetType 0) } else { // if asset is configured, ensure that it's enabled in the pool require(IHasSupportedAsset(poolManagerLogic).isSupportedAsset(to), "asset not enabled in pool"); } guard = assetGuard; (txType, isPublic) = IGuard(assetGuard).txGuard(poolManagerLogic, to, data); } require(txType > 0, "invalid transaction"); // solhint-disable-next-line reason-string require(isPublic || msg.sender == manager() || msg.sender == trader(), "only manager or trader or public function"); success = to.tryAssemblyCall(data); // call afterTxGuard to track transactions // to make it compatible with previous version, we use low-level call before calling afterTxGuard() function // the low level call will return `false` if its execution reverts // solhint-disable-next-line avoid-low-level-calls (bool hasFunction, bytes memory returnData) = guard.call(abi.encodeWithSignature("isTxTrackingGuard()")); if (hasFunction && abi.decode(returnData, (bool))) { ITxTrackingGuard(guard).afterTxGuard(poolManagerLogic, to, data); } emit TransactionExecuted(address(this), manager(), txType, block.timestamp); emitFactoryEvent(); } /// @notice Exposed function to let pool talk to other protocol /// @dev Execute single transaction for the pool /// @param to The destination address for pool to talk to /// @param data The data that going to send in the transaction /// @return success A boolean for success or fail transaction function execTransaction(address to, bytes calldata data) external returns (bool success) { return _execTransaction(to, data); } /// @notice Exposed function to let pool talk to other protocol /// @dev Execute multiple transactions for the pool /// @param txs Array of structs, each consisting of address and data /// @return success A boolean indicating if all transactions succeeded function execTransactions(TxToExecute[] calldata txs) external returns (bool success) { require(txs.length > 0, "no transactions to execute"); for (uint256 i = 0; i < txs.length; i++) { bool result = _execTransaction(txs[i].to, txs[i].data); require(result, "transaction failure"); } return true; } /// @notice Get fund summary of the pool /// @return Fund summary of the pool function getFundSummary() external view returns (FundSummary memory) { ( uint256 performanceFeeNumerator, uint256 managerFeeNumerator, uint256 entryFeeNumerator, uint256 managerFeeDenominator ) = IPoolManagerLogic(poolManagerLogic).getFee(); (uint256 exitFeeNumerator, uint256 exitFeeDenominator) = IHasFeeInfo(factory).getExitFee(); return FundSummary( name(), totalSupply(), IPoolManagerLogic(poolManagerLogic).totalFundValue(), manager(), managerName(), creationTime, privatePool, performanceFeeNumerator, managerFeeNumerator, managerFeeDenominator, exitFeeNumerator, exitFeeDenominator, entryFeeNumerator ); } /// @notice Get price of the asset adjusted for any unminted manager fees /// @param price A price of the asset function tokenPrice() external view returns (uint256 price) { (uint256 managerFee, uint256 fundValue) = availableManagerFeeAndTotalFundValue(); uint256 tokenSupply = totalSupply().add(managerFee); price = _tokenPrice(fundValue, tokenSupply); } function tokenPriceWithoutManagerFee() external view returns (uint256 price) { uint256 fundValue = IPoolManagerLogic(poolManagerLogic).totalFundValue(); uint256 tokenSupply = totalSupply(); price = _tokenPrice(fundValue, tokenSupply); } /// @notice Get price of the asset internal call /// @param _fundValue The total fund value of the pool /// @param _tokenSupply The total token supply of the pool /// @return price A price of the asset function _tokenPrice(uint256 _fundValue, uint256 _tokenSupply) internal pure returns (uint256 price) { if (_tokenSupply == 0 || _fundValue == 0) return 0; price = _fundValue.mul(10**18).div(_tokenSupply); } /// @notice Get available manager fee of the pool /// @return fee available manager fee of the pool function availableManagerFee() public view returns (uint256 fee) { (fee, ) = availableManagerFeeAndTotalFundValue(); } /// @notice Get available manager fee of the pool and totalFundValue /// @return fee available manager fee of the pool function availableManagerFeeAndTotalFundValue() public view returns (uint256 fee, uint256 fundValue) { fundValue = IPoolManagerLogic(poolManagerLogic).totalFundValue(); uint256 tokenSupply = totalSupply(); (uint256 performanceFeeNumerator, uint256 managerFeeNumerator, , uint256 managerFeeDenominator) = IPoolManagerLogic( poolManagerLogic ).getFee(); fee = _availableManagerFee( fundValue, tokenSupply, performanceFeeNumerator, managerFeeNumerator, managerFeeDenominator ); } /// @notice Get available manager fee of the pool internal call /// @param _fundValue The total fund value of the pool /// @param _tokenSupply The total token supply of the pool /// @param _performanceFeeNumerator The manager fee numerator /// @param _managerFeeNumerator The streaming fee numerator /// @param _feeDenominator The fee denominator /// @return available manager fee of the pool function _availableManagerFee( uint256 _fundValue, uint256 _tokenSupply, uint256 _performanceFeeNumerator, uint256 _managerFeeNumerator, uint256 _feeDenominator ) internal view returns (uint256 available) { if (_tokenSupply == 0 || _fundValue == 0) return 0; uint256 currentTokenPrice = _fundValue.mul(10**18).div(_tokenSupply); if (currentTokenPrice > tokenPriceAtLastFeeMint) { available = currentTokenPrice .sub(tokenPriceAtLastFeeMint) .mul(_tokenSupply) .mul(_performanceFeeNumerator) .div(_feeDenominator) .div(currentTokenPrice); } // this timestamp for old pools would be zero at the first time if (lastFeeMintTime != 0) { uint256 timeChange = block.timestamp.sub(lastFeeMintTime); uint256 streamingFee = _tokenSupply.mul(timeChange).mul(_managerFeeNumerator).div(_feeDenominator).div(365 days); available = available.add(streamingFee); } } /// @notice Mint the manager fee of the pool function mintManagerFee() external whenNotFactoryPaused whenNotPaused { _mintManagerFee(); } /// @notice Get mint manager fee of the pool internal call /// @return fundValue The total fund value of the pool function _mintManagerFee() internal returns (uint256 fundValue) { fundValue = IPoolManagerLogic(poolManagerLogic).totalFundValue(); uint256 tokenSupply = totalSupply(); (uint256 performanceFeeNumerator, uint256 managerFeeNumerator, , uint256 managerFeeDenominator) = IPoolManagerLogic( poolManagerLogic ).getFee(); uint256 available = _availableManagerFee( fundValue, tokenSupply, performanceFeeNumerator, managerFeeNumerator, managerFeeDenominator ); address daoAddress = IHasDaoInfo(factory).daoAddress(); uint256 daoFeeNumerator; uint256 daoFeeDenominator; (daoFeeNumerator, daoFeeDenominator) = IHasDaoInfo(factory).getDaoFee(); uint256 daoFee = available.mul(daoFeeNumerator).div(daoFeeDenominator); uint256 managerFee = available.sub(daoFee); if (daoFee > 0) _mint(daoAddress, daoFee); if (managerFee > 0) _mint(manager(), managerFee); uint256 currentTokenPrice = _tokenPrice(fundValue, tokenSupply); if (tokenPriceAtLastFeeMint < currentTokenPrice) { tokenPriceAtLastFeeMint = currentTokenPrice; } lastFeeMintTime = block.timestamp; emit ManagerFeeMinted(address(this), manager(), available, daoFee, managerFee, tokenPriceAtLastFeeMint); emitFactoryEvent(); } /// @notice Calculate lockup cooldown applied to the investor after pool deposit /// @param currentBalance Investor's current pool tokens balance /// @param liquidityMinted Liquidity to be minted to investor after pool deposit /// @param newCooldown New cooldown lockup time /// @param lastCooldown Last cooldown lockup time applied to investor /// @param lastDepositTime Timestamp when last pool deposit happened /// @param blockTimestamp Timestamp of a block /// @return cooldown New lockup cooldown to be applied to investor address function calculateCooldown( uint256 currentBalance, uint256 liquidityMinted, uint256 newCooldown, uint256 lastCooldown, uint256 lastDepositTime, uint256 blockTimestamp ) public pure returns (uint256 cooldown) { // Get timestamp when current cooldown ends uint256 cooldownEndsAt = lastDepositTime.add(lastCooldown); // Current exit remaining cooldown uint256 remainingCooldown = cooldownEndsAt < blockTimestamp ? 0 : cooldownEndsAt.sub(blockTimestamp); // If it's first deposit with zero liquidity, no cooldown should be applied if (currentBalance == 0 && liquidityMinted == 0) { cooldown = 0; // If it's first deposit, new cooldown should be applied } else if (currentBalance == 0) { cooldown = newCooldown; // If zero liquidity or new cooldown reduces remaining cooldown, apply remaining } else if (liquidityMinted == 0 || newCooldown < remainingCooldown) { cooldown = remainingCooldown; // For the rest cases calculate cooldown based on current balance and liquidity minted } else { // If the user already owns liquidity, the additional lockup should be in proportion to their existing liquidity. // Calculated as newCooldown * liquidityMinted / currentBalance uint256 additionalCooldown = newCooldown.mul(liquidityMinted).div(currentBalance); // Aggregate additional and remaining cooldowns uint256 aggregatedCooldown = additionalCooldown.add(remainingCooldown); // Resulting value is capped at new cooldown time (shouldn't be bigger) and falls back to one second in case of zero cooldown = aggregatedCooldown > newCooldown ? newCooldown : aggregatedCooldown != 0 ? aggregatedCooldown : 1; } } /// @notice Get exit remaining time of the pool /// @return remaining The remaining exit time of the pool function getExitRemainingCooldown(address sender) public view returns (uint256 remaining) { uint256 cooldownFinished = lastDeposit[sender].add(lastExitCooldown[sender]); if (cooldownFinished < block.timestamp) return 0; remaining = cooldownFinished.sub(block.timestamp); } /// @notice Set address for pool manager logic function setPoolManagerLogic(address _poolManagerLogic) external returns (bool) { require(_poolManagerLogic != address(0), "Invalid poolManagerLogic address"); require( msg.sender == address(factory) || msg.sender == IHasOwnable(factory).owner(), "only owner or factory allowed" ); poolManagerLogic = _poolManagerLogic; emit PoolManagerLogicSet(_poolManagerLogic, msg.sender); return true; } /// @notice Get address of the manager /// @return _manager The address of the manager function manager() internal view returns (address _manager) { _manager = IManaged(poolManagerLogic).manager(); } /// @notice Get address of the trader /// @return _trader The address of the trader function trader() internal view returns (address _trader) { _trader = IManaged(poolManagerLogic).trader(); } /// @notice Get name of the manager /// @return _managerName The name of the manager function managerName() public view returns (string memory _managerName) { _managerName = IManaged(poolManagerLogic).managerName(); } /// @notice Return boolean if the address is a member of the list /// @param member The address of the member /// @return True if the address is a member of the list, false otherwise function isMemberAllowed(address member) public view returns (bool) { return IPoolManagerLogic(poolManagerLogic).isMemberAllowed(member); } /// @notice execute function of aave flash loan /// @dev This function is called after your contract has received the flash loaned amount /// @param assets the loaned assets /// @param amounts the loaned amounts per each asset /// @param premiums the additional owed amount per each asset /// @param originator the origin caller address of the flash loan /// @param params Variadic packed params to pass to the receiver as extra information function executeOperation( address[] memory assets, uint256[] memory amounts, uint256[] memory premiums, address originator, bytes memory params ) external returns (bool success) { require(originator == address(this), "only pool flash loan origin"); address aaveLendingPoolAssetGuard = IHasGuardInfo(factory).getAssetGuard(msg.sender); require( aaveLendingPoolAssetGuard != address(0) && msg.sender == IAaveLendingPoolAssetGuard(aaveLendingPoolAssetGuard).aaveLendingPool(), "invalid lending pool" ); (uint256[] memory interestRateModes, uint256 portion) = abi.decode(params, (uint256[], uint256)); address weth = IHasGuardInfo(factory).getAddress("weth"); uint256 wethBalanceBefore = IERC20Upgradeable(weth).balanceOf(address(this)); IAssetGuard.MultiTransaction[] memory transactions = IAaveLendingPoolAssetGuard(aaveLendingPoolAssetGuard) .flashloanProcessing(address(this), portion, assets, amounts, premiums, interestRateModes); for (uint256 i = 0; i < transactions.length; i++) { success = transactions[i].to.tryAssemblyCall(transactions[i].txData); } // Liquidation of collateral not enough to pay off debt, flashloan repayment stealing pool's weth require( wethBalanceBefore == 0 || wethBalanceBefore <= IERC20Upgradeable(weth).balanceOf(address(this)), "too high slippage" ); } /// @notice Emits an event through the factory, so we can just listen to the factory offchain function emitFactoryEvent() internal { IPoolFactory(factory).emitPoolEvent(); } uint256[47] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; /** * Utility library of inline functions on addresses * * Source https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/v2.1.3/contracts/utils/Address.sol * This contract is copied here and renamed from the original to avoid clashes in the compiled artifacts * when the user imports a zos-lib contract (that transitively causes this contract to be compiled and added to the * build/artifacts folder) as well as the vanilla Address implementation from an openzeppelin version. */ library OpenZeppelinUpgradesAddress { /** * @notice Returns whether the target address is a contract * @dev This function will return false if invoked during the constructor of a contract, * as the code is not actually created until after the constructor finishes. * @param account address of the account to check * @return whether the target address is a contract */ function isContract(address account) internal view returns (bool) { uint256 size; // XXX Currently there is no better way to check if there is a contract in an address // than to check the size of the code at that address. // See https://ethereum.stackexchange.com/a/14016/36603 // for more details about how this works. // TODO Check this again before the Serenity release, because all addresses will be // contracts then. assembly { size := extcodesize(account) } return size > 0; } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "./Proxy.sol"; import "./Address.sol"; import "./HasLogic.sol"; /** * @title BaseUpgradeabilityProxy * @dev This contract implements a proxy that allows to change the * implementation address to which it will delegate. * Such a change is called an implementation upgrade. */ contract BaseUpgradeabilityProxy is Proxy { /** * @dev Emitted when the implementation is upgraded. * @param implementation Address of the new implementation. */ event Upgraded(address indexed implementation); /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Storing type of the proxy, 1 for managerLogic, 2 for pool. */ bytes32 internal constant PROXY_TYPE = 0x1000000000000000000000000000000000000000000000000000000000000000; /** * @notice Returns the current implementation. * @return impl Address of the current implementation */ function _implementation() internal view override returns (address) { address factory; bytes32 slot = IMPLEMENTATION_SLOT; assembly { factory := sload(slot) } // Begin custom modification if (factory == address(0x0)) return address(0x0); // If factory not initialized return empty return HasLogic(factory).getLogic(_proxyType()); } /// @notice Return the proxy type. /// @return proxyType Return type of the proxy. function _proxyType() internal view returns (uint8 proxyType) { bytes32 slot = PROXY_TYPE; assembly { proxyType := sload(slot) } } /** * @notice Upgrades the proxy to a new implementation. * @param newImplementation Address of the new implementation. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @notice Sets the implementation address of the proxy. * @param newImplementation Address of the new implementation. */ function _setImplementation(address newImplementation) internal { require(OpenZeppelinUpgradesAddress.isContract(newImplementation), "Cannot set implementation to EOA"); bytes32 slot = IMPLEMENTATION_SLOT; assembly { sstore(slot, newImplementation) } } /** * @notice Sets type of the proxy. * @param proxyType Type of the proxy. */ function _setProxyType(uint8 proxyType) internal { bytes32 slot = PROXY_TYPE; assembly { sstore(slot, proxyType) } } }
// // __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // 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 HasLogic { function getLogic(uint8 _proxyType) external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "./BaseUpgradeabilityProxy.sol"; import "../utils/AddressHelper.sol"; /** * @title InitializableUpgradeabilityProxy * @dev Extends BaseUpgradeabilityProxy with an initializer for initializing * implementation and init data. */ contract InitializableUpgradeabilityProxy is BaseUpgradeabilityProxy { using AddressHelper for address; /** * @dev Contract initializer. * @param _factory Address of the factory containing the implementation. * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. */ function initialize( address _factory, bytes memory _data, uint8 _proxyType ) public payable { require(_implementation() == address(0), "Impl not zero"); assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1)); _setImplementation(_factory); _setProxyType(_proxyType); if (_data.length > 0) { _implementation().tryAssemblyDelegateCall(_data); } } }
// // __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // 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; /** * @title Proxy * @dev Implements delegation of calls to other contracts, with proper * forwarding of return values and bubbling of failures. * It defines a fallback function that delegates all calls to the address * returned by the abstract _implementation() internal function. */ abstract contract Proxy { /** * @notice Fallback function. * Implemented entirely in `_fallback`. */ fallback() external payable { _fallback(); } /** * @notice Receive function. * Implemented entirely in `_fallback`. */ receive() external payable { _fallback(); } /** * @return The Address of the implementation. */ function _implementation() internal view virtual returns (address); /** * @notice Delegates execution to an implementation contract. * This is a low level function that doesn't return to its internal call site. * It will return to the external caller whatever the implementation returns. * @param implementation Address to delegate. */ function _delegate(address implementation) internal { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) // Copy the returned data. // Warning: OVM: Using RETURNDATASIZE or RETURNDATACOPY in user asm isn't guaranteed to work returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @notice Function that is run as the first thing in the fallback function. * Can be redefined in derived contracts to add functionality. * Redefinitions must call super._willFallback(). */ // solhint-disable-next-line no-empty-blocks function _willFallback() internal virtual {} /** * @notice fallback implementation. * Extracted to enable manual triggering. */ function _fallback() internal { _willFallback(); _delegate(_implementation()); } }
// // __ __ __ ________ _______ ______ ________ // / |/ | / |/ |/ \ / \ / | // ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/ // / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__ // /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ | // $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/ // $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____ // $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ | // $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/ // // 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 "./InitializableUpgradeabilityProxy.sol"; import "./HasLogic.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; /// @notice This contract is used to deploy the proxy contract. contract ProxyFactory is OwnableUpgradeable, HasLogic { event ProxyCreated(address proxy); address private poolLogic; address private poolManagerLogic; /// @notice initialise poolLogic and poolManagerLogic /// @param _poolLogic address of the pool logic /// @param _poolManagerLogic address of the pool manager logic // solhint-disable-next-line func-name-mixedcase function __ProxyFactory_init(address _poolLogic, address _poolManagerLogic) internal { __Ownable_init(); require(_poolLogic != address(0), "Invalid poolLogic"); require(_poolManagerLogic != address(0), "Invalid poolManagerLogic"); poolLogic = _poolLogic; poolManagerLogic = _poolManagerLogic; } /// @notice Setting logic address for both poolLogic and poolManagerLogic /// @param _poolLogic address of the pool logic /// @param _poolManagerLogic address of the pool manager logic function setLogic(address _poolLogic, address _poolManagerLogic) public onlyOwner { require(_poolLogic != address(0), "Invalid poolLogic"); require(_poolManagerLogic != address(0), "Invalid poolManagerLogic"); poolLogic = _poolLogic; poolManagerLogic = _poolManagerLogic; } /// @notice Return logic address of the pool or the pool manager logic function getLogic(uint8 _proxyType) public view override returns (address) { if (_proxyType == 1) { return poolManagerLogic; } else { return poolLogic; } } /// @notice Deploy proxy contract external call function deploy(bytes memory _data, uint8 _proxyType) public returns (address) { return _deployProxy(_data, _proxyType); } /// @notice Deploy and initialize proxy contract internal call function _deployProxy(bytes memory _data, uint8 _proxyType) internal returns (address) { InitializableUpgradeabilityProxy proxy = _createProxy(); emit ProxyCreated(address(proxy)); proxy.initialize(address(this), _data, _proxyType); return address(proxy); } /// @notice Deploy proxy contract function _createProxy() internal returns (InitializableUpgradeabilityProxy) { address payable addr; bytes memory code = type(InitializableUpgradeabilityProxy).creationCode; assembly { addr := create(0, add(code, 0x20), mload(code)) if iszero(extcodesize(addr)) { revert(0, 0) } } return InitializableUpgradeabilityProxy(addr); } uint256[50] 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 // import "./BytesLib.sol"; pragma solidity 0.7.6; /** * @title A library for Address utils. */ library AddressHelper { /** * @notice try a contract call via assembly * @param to the contract address * @param data the call data * @return success if the contract call is successful or not */ function tryAssemblyCall(address to, bytes memory data) internal returns (bool success) { assembly { success := call(gas(), to, 0, add(data, 0x20), mload(data), 0, 0) switch iszero(success) case 1 { let size := returndatasize() returndatacopy(0x00, 0x00, size) revert(0x00, size) } } } /** * @notice try a contract delegatecall via assembly * @param to the contract address * @param data the call data * @return success if the contract call is successful or not */ function tryAssemblyDelegateCall(address to, bytes memory data) internal returns (bool success) { assembly { success := delegatecall(gas(), to, add(data, 0x20), mload(data), 0, 0) switch iszero(success) case 1 { let size := returndatasize() returndatacopy(0x00, 0x00, size) revert(0x00, size) } } } // /** // * @notice try a contract call // * @param to the contract address // * @param data the call data // * @return success if the contract call is successful or not // */ // function tryCall(address to, bytes memory data) internal returns (bool) { // (bool success, bytes memory res) = to.call(data); // // Get the revert message of the call and revert with it if the call failed // require(success, _getRevertMsg(res)); // return success; // } // /** // * @dev Get the revert message from a call // * @notice This is needed in order to get the human-readable revert message from a call // * @param response Response of the call // * @return Revert message string // */ // function _getRevertMsg(bytes memory response) internal pure returns (string memory) { // // If the response length is less than 68, then the transaction failed silently (without a revert message) // if (response.length < 68) return "Transaction reverted silently"; // bytes memory revertData = response.slice(4, response.length - 4); // Remove the selector which is the first 4 bytes // return abi.decode(revertData, (string)); // All that remains is the revert string // } }
{ "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "optimizer": { "enabled": true, "runs": 20 }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"daoAddress","type":"address"}],"name":"DAOAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"numerator","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"DaoFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"cooldown","type":"uint256"}],"name":"ExitCooldownSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"numerator","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ExitFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"fundAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"isPoolPrivate","type":"bool"},{"indexed":false,"internalType":"string","name":"fundName","type":"string"},{"indexed":false,"internalType":"string","name":"managerName","type":"string"},{"indexed":false,"internalType":"address","name":"manager","type":"address"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"performanceFeeNumerator","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"managerFeeNumerator","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"managerFeeDenominator","type":"uint256"}],"name":"FundCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"governanceAddress","type":"address"}],"name":"GovernanceAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"manager","type":"address"},{"indexed":true,"internalType":"address","name":"pool","type":"address"}],"name":"LogUpgrade","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"count","type":"uint256"}],"name":"MaximumSupportedAssetCountSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"poolAddress","type":"address"}],"name":"PoolEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"poolManagerAddress","type":"address"}],"name":"PoolManagerEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"proxy","type":"address"}],"name":"ProxyCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"assetHandler","type":"address"}],"name":"SetAssetHandler","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"performanceFeeNumerator","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"managerFeeNumerator","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"entryFeeNumerator","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"SetMaximumFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SetMaximumPerformanceFeeNumeratorChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"delay","type":"uint256"}],"name":"SetPerformanceFeeNumeratorChangeDelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"numerator","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"SetPoolManagerFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"poolStorageVersion","type":"uint256"}],"name":"SetPoolStorageVersion","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"address","name":"_extAddress","type":"address"}],"name":"addCustomCooldownWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_extAddress","type":"address"}],"name":"addReceiverWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_privatePool","type":"bool"},{"internalType":"address","name":"_manager","type":"address"},{"internalType":"string","name":"_managerName","type":"string"},{"internalType":"string","name":"_fundName","type":"string"},{"internalType":"string","name":"_fundSymbol","type":"string"},{"internalType":"uint256","name":"_performanceFeeNumerator","type":"uint256"},{"internalType":"uint256","name":"_managerFeeNumerator","type":"uint256"},{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"bool","name":"isDeposit","type":"bool"}],"internalType":"struct IHasSupportedAsset.Asset[]","name":"_supportedAssets","type":"tuple[]"}],"name":"createFund","outputs":[{"internalType":"address","name":"fund","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"customCooldownWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"daoAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"uint8","name":"_proxyType","type":"uint8"}],"name":"deploy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"deployedFunds","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emitPoolEvent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emitPoolManagerEvent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"name","type":"bytes32"}],"name":"getAddress","outputs":[{"internalType":"address","name":"destination","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"extAsset","type":"address"}],"name":"getAssetGuard","outputs":[{"internalType":"address","name":"guard","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAssetHandler","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getAssetPrice","outputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getAssetType","outputs":[{"internalType":"uint16","name":"assetType","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"extContract","type":"address"}],"name":"getContractGuard","outputs":[{"internalType":"address","name":"guard","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDaoFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDeployedFunds","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExitCooldown","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExitFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getInvestedPools","outputs":[{"internalType":"address[]","name":"investedPools","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_proxyType","type":"uint8"}],"name":"getLogic","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"manager","type":"address"}],"name":"getManagedPools","outputs":[{"internalType":"address[]","name":"managedPools","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaximumFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaximumSupportedAssetCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governanceAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implInitializer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_poolLogic","type":"address"},{"internalType":"address","name":"_managerLogic","type":"address"},{"internalType":"address","name":"assetHandler","type":"address"},{"internalType":"address","name":"_daoAddress","type":"address"},{"internalType":"address","name":"_governanceAddress","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isPool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"isValidAsset","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maximumPerformanceFeeNumeratorChange","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"pausedPools","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"performanceFeeNumeratorChangeDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolPerformanceAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolStorageVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"poolVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"receiverWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_extAddress","type":"address"}],"name":"removeCustomCooldownWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_extAddress","type":"address"}],"name":"removeReceiverWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"assetHandler","type":"address"}],"name":"setAssetHandler","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_daoAddress","type":"address"}],"name":"setDAOAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"setDaoFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"cooldown","type":"uint256"}],"name":"setExitCooldown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"setExitFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_governanceAddress","type":"address"}],"name":"setGovernanceAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_poolLogic","type":"address"},{"internalType":"address","name":"_poolManagerLogic","type":"address"}],"name":"setLogic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"performanceFeeNumerator","type":"uint256"},{"internalType":"uint256","name":"managerFeeNumerator","type":"uint256"},{"internalType":"uint256","name":"entryFeeNumerator","type":"uint256"}],"name":"setMaximumFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setMaximumPerformanceFeeNumeratorChange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"name":"setMaximumSupportedAssetCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"delay","type":"uint256"}],"name":"setPerformanceFeeNumeratorChangeDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolStorageVersion","type":"uint256"}],"name":"setPoolStorageVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"bool","name":"paused","type":"bool"}],"internalType":"struct PoolFactory.PoolPausedInfo[]","name":"pools","type":"tuple[]"}],"name":"setPoolsPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"endIndex","type":"uint256"},{"internalType":"uint256","name":"targetVersion","type":"uint256"},{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"upgradePoolBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"endIndex","type":"uint256"},{"internalType":"uint256","name":"targetVersion","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradePoolBatch","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50613e05806100206000396000f3fe608060405234801561001057600080fd5b50600436106102c45760003560e01c806389da8ad71161017957806389da8ad7146104c55780638da5cb5b146104d8578063965afa89146104e05780639a068bd6146104f35780639b313686146105065780639cada6e4146105195780639f49b60e1461052f578063aa12ae4d14610542578063aa7d664e1461054a578063af8902151461055d578063b187bd2614610565578063b3596f071461056d578063b8ff28ac14610580578063bdcede0c14610593578063c8f88a80146105a6578063cb6f3bbc146105b9578063cc435bf3146105c1578063cdf04c07146105d4578063cfc16254146105e7578063d77268e6146105fa578063dbf5974d14610602578063e0cb599614610615578063e5ac13a914610628578063eb849a041461063b578063ecb0116a1461064e578063ecef89d514610656578063eec16c4414610669578063eed0ff461461067c578063f2fde38b1461068f578063fcc08cbc146106a2576102c4565b8063032c49ed146102c957806307120115146102f257806308d7ce02146102fc57806309ed4893146103145780630ddefe14146103295780630f6559c41461033c5780631459457a146103515780632131c68c1461036457806321f8a7211461036c57806325c4121b1461037f5780632927233b146103875780633f4ba83a146103a75780633f7f5c72146103af5780634501b088146103b757806345812ca5146103bf5780634da0be1d146103d25780634f8419b9146103f257806354d8a5bd146104055780635556ee551461040d5780635a97284b146104205780635b16ebb7146104335780635c975abb146104465780635fbf37a31461044e578063715018a614610461578063771d1baf14610469578063795053d31461047c5780637b7d612b14610484578063808ae5fb146104975780638456cb59146104aa578063878f4778146104b2575b600080fd5b6102dc6102d7366004612fcd565b6106b5565b6040516102e991906138d5565b60405180910390f35b6102fa61073c565b005b6103046107de565b6040516102e994939291906138f2565b61031c6107f0565b6040516102e9919061348d565b6102fa610337366004612fcd565b6107ff565b610344610885565b6040516102e99190613646565b6102fa61035f36600461303d565b61088b565b61031c6109c2565b61031c61037a366004613214565b6109d1565b6102fa610a88565b61039a610395366004612fcd565b610af5565b6040516102e9919061363b565b6102fa610b0a565b6102fa610b76565b610344610c58565b61031c6103cd36600461322c565b610c5e565b6103e56103e0366004612fcd565b610c71565b6040516102e991906135ee565b61031c610400366004612fcd565b610ddd565b6103e5610e5e565b61034461041b366004612fcd565b610ec0565b6102fa61042e366004612fcd565b610ed2565b61039a610441366004612fcd565b610f55565b61039a610f6a565b6102fa61045c366004613214565b610f73565b6102fa611015565b6102fa6104773660046132df565b6110af565b61031c61111f565b6102fa610492366004613214565b61112e565b6102fa6104a5366004613005565b6111c5565b6102fa6112fa565b6102fa6104c036600461332b565b611364565b6102fa6104d3366004612fcd565b6114c0565b61031c611543565b6102fa6104ee366004612fcd565b611552565b61031c610501366004613214565b6115bd565b6102fa6105143660046130ad565b6115e7565b6105216116f1565b6040516102e99291906138e4565b6102fa61053d3660046132df565b6116fb565b610344611767565b6102fa610558366004613214565b61176d565b61031c6117d8565b61039a6117e7565b61034461057b366004612fcd565b6117f6565b61031c61058e366004613138565b611877565b6102fa6105a1366004612fcd565b611ad5565b6102fa6105b4366004613300565b611b5b565b610344611bd0565b61039a6105cf366004612fcd565b611bd6565b61039a6105e2366004612fcd565b611c6c565b6102fa6105f5366004612fcd565b611c81565b610344611cec565b6102fa6106103660046133b4565b611cf2565b61039a610623366004612fcd565b611df6565b6102fa610636366004612fcd565b611e0b565b6103e5610649366004612fcd565b611e76565b610521612046565b61031c610664366004613428565b612050565b6102fa610677366004613214565b612082565b6102fa61068a366004613214565b6120ed565b6102fa61069d366004612fcd565b612158565b61031c6106b0366004612fcd565b612249565b60ce5460405163b02e786f60e01b81526000916001600160a01b03169063b02e786f906106e690859060040161348d565b60206040518083038186803b1580156106fe57600080fd5b505afa158015610712573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073691906132a5565b92915050565b600054610100900460ff1680610755575061075561235a565b80610763575060005460ff16155b61079e5760405162461bcd60e51b815260040180806020018281038252602e815260200180613d62602e913960400191505060405180910390fd5b600054610100900460ff161580156107c9576000805460ff1961ff0019909116610100171660011790555b80156107db576000805461ff00191690555b50565b60d25460de5460e05460d35490919293565b60ce546001600160a01b031690565b61080761236b565b6001600160a01b0316610818611543565b6001600160a01b031614610861576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6001600160a01b0316600090815260df60205260409020805460ff19166001179055565b60d75481565b600054610100900460ff16806108a457506108a461235a565b806108b2575060005460ff16155b6108ed5760405162461bcd60e51b815260040180806020018281038252602e815260200180613d62602e913960400191505060405180910390fd5b600054610100900460ff16158015610918576000805460ff1961ff0019909116610100171660011790555b610922868661236f565b61092a612377565b61093384612414565b61093c83612485565b610945826124f6565b61095861138861012c6064612710612567565b610964600a60646125f7565b61097160056103e861265f565b61097d620151806126bb565b6109896224ea0061112e565b6109946103e8610f73565b61099e600a6126f0565b6109a860e6612725565b80156109ba576000805461ff00191690555b505050505050565b60cc546001600160a01b031681565b60cd5460405163c2a9ffb160e01b81526000916001600160a01b03169063c2a9ffb190610a02908590600401613646565b60206040518083038186803b158015610a1a57600080fd5b505afa158015610a2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a529190612fe9565b90506001600160a01b038116610a835760405162461bcd60e51b8152600401610a7a90613851565b60405180910390fd5b919050565b33600090815260d1602052604090205460ff161515600114610abc5760405162461bcd60e51b8152600401610a7a906137a2565b7fdbd4d7b818d776167ae42054b0831aa269b1eb3ea73bd2e7ef6091f2879b183733604051610aeb919061348d565b60405180910390a1565b60dd6020526000908152604090205460ff1681565b610b1261236b565b6001600160a01b0316610b23611543565b6001600160a01b031614610b6c576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b610b7461277b565b565b60d16000336001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b158015610bb357600080fd5b505afa158015610bc7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610beb9190612fe9565b6001600160a01b0316815260208101919091526040016000205460ff161515600114610c295760405162461bcd60e51b8152600401610a7a906136a1565b7f686c28f13f997a49532b3373c8e5b4a6e22e6b06b66d06487a8241a599717f4933604051610aeb919061348d565b60d45490565b6000610c6a838361281b565b9392505050565b60cb54606090806001600160401b0381118015610c8d57600080fd5b50604051908082528060200260200182016040528015610cb7578160200160208202803683370190505b5091506000805b82811015610dc257600060cb8281548110610cd557fe5b6000918252602090912001546040516370a0823160e01b81526001600160a01b03909116906370a0823190610d0e90899060040161348d565b60206040518083038186803b158015610d2657600080fd5b505afa158015610d3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5e91906132c7565b1115610dba5760cb8181548110610d7157fe5b9060005260206000200160009054906101000a90046001600160a01b0316848381518110610d9b57fe5b6001600160a01b03909216602092830291909101909101526001909101905b600101610cbe565b506000610dcf8383612949565b845103845250919392505050565b60cd5460405163174dbff160e21b81526000916001600160a01b031690635d36ffc490610e0e90859060040161348d565b60206040518083038186803b158015610e2657600080fd5b505afa158015610e3a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107369190612fe9565b606060cb805480602002602001604051908101604052809291908181526020018280548015610eb657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e98575b5050505050905090565b60d66020526000908152604090205481565b610eda61236b565b6001600160a01b0316610eeb611543565b6001600160a01b031614610f34576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6001600160a01b0316600090815260dd60205260409020805460ff19169055565b60d16020526000908152604090205460ff1681565b60335460ff1690565b610f7b61236b565b6001600160a01b0316610f8c611543565b6001600160a01b031614610fd5576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b60d88190556040517fbe762d516a09c899b785daf0c0f9bea93fd44a062d9ecc24c2ddba4c6f8b47ed9061100a908390613646565b60405180910390a150565b61101d61236b565b6001600160a01b031661102e611543565b6001600160a01b031614611077576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6065546040516000916001600160a01b031690600080516020613db0833981519152908390a3606580546001600160a01b0319169055565b6110b761236b565b6001600160a01b03166110c8611543565b6001600160a01b031614611111576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b61111b82826125f7565b5050565b60cd546001600160a01b031681565b61113661236b565b6001600160a01b0316611147611543565b6001600160a01b031614611190576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b60d98190556040517f5c7a1f308b9ecdacddd5f035f458158e6a2581b1921b2ca7de3732bd1dd6e5909061100a908390613646565b6111cd61236b565b6001600160a01b03166111de611543565b6001600160a01b031614611227576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6001600160a01b038216611276576040805162461bcd60e51b8152602060048201526011602482015270496e76616c696420706f6f6c4c6f67696360781b604482015290519081900360640190fd5b6001600160a01b0381166112cc576040805162461bcd60e51b8152602060048201526018602482015277496e76616c696420706f6f6c4d616e616765724c6f67696360401b604482015290519081900360640190fd5b609780546001600160a01b039384166001600160a01b03199182161790915560988054929093169116179055565b61130261236b565b6001600160a01b0316611313611543565b6001600160a01b03161461135c576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b610b746129a6565b61136c61236b565b6001600160a01b031661137d611543565b6001600160a01b0316146113c6576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b8385111580156113d7575060cb5484105b6113f35760405162461bcd60e51b8152600401610a7a90613679565b61140860016114028688612949565b90612a29565b81146114265760405162461bcd60e51b8152600401610a7a90613774565b845b8481116109ba57600060cb828154811061143e57fe5b6000918252602090912001546001600160a01b031690508061146057506114b8565b6001600160a01b038116600090815260d66020526040902054851161148557506114b8565b6114b6818585611495868c612949565b81811061149e57fe5b90506020028101906114b0919061390d565b88612a81565b505b600101611428565b6114c861236b565b6001600160a01b03166114d9611543565b6001600160a01b031614611522576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6001600160a01b0316600090815260df60205260409020805460ff19169055565b6065546001600160a01b031690565b61155a61236b565b6001600160a01b031661156b611543565b6001600160a01b0316146115b4576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6107db81612485565b60cb81815481106115cd57600080fd5b6000918252602090912001546001600160a01b0316905081565b6115ef61236b565b6001600160a01b0316611600611543565b6001600160a01b031614611649576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b8060005b818110156116eb57600084848381811061166357fe5b905060400201803603810190611679919061328a565b80516001600160a01b0316600090815260d1602052604090205490915060ff166116b55760405162461bcd60e51b8152600401610a7a906138af565b60208181015191516001600160a01b0316600090815260e190915260409020805460ff191691151591909117905560010161164d565b50505050565b60cf5460d0549091565b61170361236b565b6001600160a01b0316611714611543565b6001600160a01b03161461175d576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b61111b828261265f565b60d55490565b61177561236b565b6001600160a01b0316611786611543565b6001600160a01b0316146117cf576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6107db816126bb565b60da546001600160a01b031681565b60006117f1610f6a565b905090565b60ce54604051638b2f0f4f60e01b81526000916001600160a01b031690638b2f0f4f9061182790859060040161348d565b60206040518083038186803b15801561183f57600080fd5b505afa158015611853573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073691906132c7565b6000611881610f6a565b1561189e5760405162461bcd60e51b8152600401610a7a906137f4565b6000308a88886040516024016118b79493929190613536565b60408051601f198184030181529190526020810180516001600160e01b0316635426f81d60e01b17905290506118ee816002610c5e565b91506000308a8a8589898960405160240161190f97969594939291906134a1565b60408051601f198184030181529190526020810180516001600160e01b031663361315ff60e11b17905290506000611948826001610c5e565b604051633a81136f60e11b81529091506001600160a01b0385169063750226de9061197790849060040161348d565b602060405180830381600087803b15801561199157600080fd5b505af11580156119a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119c9919061311c565b5060cb849080600181540180825580915050600190039060005260206000200160009091909190916101000a8154816001600160a01b0302191690836001600160a01b03160217905550600160d16000866001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff02191690831515021790555060d75460d66000866001600160a01b03166001600160a01b03168152602001908152602001600020819055507f7568e63260f13515e4b3208667c411fbf4c7dce047496ca5f9a56f1c92440d93848d8b8d8f428d8d60d354604051611abe9998979695949392919061357f565b60405180910390a150505098975050505050505050565b611add61236b565b6001600160a01b0316611aee611543565b6001600160a01b031614611b37576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6001600160a01b0316600090815260dd60205260409020805460ff19166001179055565b611b6361236b565b6001600160a01b0316611b74611543565b6001600160a01b031614611bbd576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b611bcb83838360d354612567565b505050565b60d95481565b60ce5460405163b4fb127960e01b815260009182916001600160a01b039091169063b4fb127990611c0b90869060040161348d565b60206040518083038186803b158015611c2357600080fd5b505afa158015611c37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c5b9190612fe9565b6001600160a01b0316141592915050565b60e16020526000908152604090205460ff1681565b611c8961236b565b6001600160a01b0316611c9a611543565b6001600160a01b031614611ce3576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6107db816124f6565b60d85481565b611cfa61236b565b6001600160a01b0316611d0b611543565b6001600160a01b031614611d54576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b838511158015611d65575060cb5484105b611d815760405162461bcd60e51b8152600401610a7a90613679565b845b8481116109ba57600060cb8281548110611d9957fe5b6000918252602090912001546001600160a01b0316905080611dbb5750611dee565b6001600160a01b038116600090815260d660205260409020548511611de05750611dee565b611dec81858588612a81565b505b600101611d83565b60df6020526000908152604090205460ff1681565b611e1361236b565b6001600160a01b0316611e24611543565b6001600160a01b031614611e6d576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6107db81612414565b60cb54606090806001600160401b0381118015611e9257600080fd5b50604051908082528060200260200182016040528015611ebc578160200160208202803683370190505b5091506000805b82811015610dc257600060cb8281548110611eda57fe5b6000918252602091829020015460408051630f28525360e11b815290516001600160a01b0390921692631e50a4a692600480840193829003018186803b158015611f2357600080fd5b505afa158015611f37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5b9190612fe9565b9050856001600160a01b0316816001600160a01b031663481c6a756040518163ffffffff1660e01b815260040160206040518083038186803b158015611fa057600080fd5b505afa158015611fb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd89190612fe9565b6001600160a01b0316141561203d5760cb8281548110611ff457fe5b9060005260206000200160009054906101000a90046001600160a01b031685848151811061201e57fe5b6001600160a01b03909216602092830291909101909101526001909201915b50600101611ec3565b60db5460dc549091565b60008160ff166001141561207057506098546001600160a01b0316610a83565b506097546001600160a01b0316610a83565b61208a61236b565b6001600160a01b031661209b611543565b6001600160a01b0316146120e4576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6107db816126f0565b6120f561236b565b6001600160a01b0316612106611543565b6001600160a01b03161461214f576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6107db81612725565b61216061236b565b6001600160a01b0316612171611543565b6001600160a01b0316146121ba576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6001600160a01b0381166121ff5760405162461bcd60e51b8152600401808060200182810382526026815260200180613d3c6026913960400191505060405180910390fd5b6065546040516001600160a01b03808416921690600080516020613db083398151915290600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b600061225482611bd6565b15610a835760ce5460405163b02e786f60e01b81526000916001600160a01b03169063b02e786f9061228a90869060040161348d565b60206040518083038186803b1580156122a257600080fd5b505afa1580156122b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122da91906132a5565b60cd5460405162a950c360e81b81529192506001600160a01b03169063a950c3009061230a9084906004016138d5565b60206040518083038186803b15801561232257600080fd5b505afa158015612336573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6a9190612fe9565b600061236530612b9d565b15905090565b3390565b611227612ba3565b600054610100900460ff1680612390575061239061235a565b8061239e575060005460ff16155b6123d95760405162461bcd60e51b815260040180806020018281038252602e815260200180613d62602e913960400191505060405180910390fd5b600054610100900460ff16158015612404576000805460ff1961ff0019909116610100171660011790555b61240c61073c565b6107c9612c40565b6001600160a01b03811661243a5760405162461bcd60e51b8152600401610a7a906137c6565b60ce80546001600160a01b0319166001600160a01b0383161790556040517faca6dca39d79ebceec9b32e3a681f32c1368a5b373cc24d96a02a896a1457ed89061100a90839061348d565b6001600160a01b0381166124ab5760405162461bcd60e51b8152600401610a7a90613883565b60cc80546001600160a01b0319166001600160a01b0383161790556040517f7138c17e9cd38b1f65ba47723efdaec045a981aa53992018fd215e5c09a22fc49061100a90839061348d565b6001600160a01b03811661251c5760405162461bcd60e51b8152600401610a7a9061381e565b60cd80546001600160a01b0319166001600160a01b0383161790556040517fbdb80a7ad60bd8133ed6b01049f9065c4cad1fa0a8e074da74b480f2aa83c9369061100a90839061348d565b8084111580156125775750808311155b80156125835750808211155b61259f5760405162461bcd60e51b8152600401610a7a90613716565b60d284905560de83905560d381905560e08290556040517f720fe36421ecec4b8b4b3282b5714c1fde000f75dcc989cd486474901819d852906125e99086908690869086906138f2565b60405180910390a150505050565b808211156126175760405162461bcd60e51b8152600401610a7a90613716565b60cf82905560d08190556040517fb10da2958bf5ec1bff3164ff753a09e0460ed44d3abf73e79b817b500ed0f2f19061265390849084906138e4565b60405180910390a15050565b8082111561267f5760405162461bcd60e51b8152600401610a7a90613716565b60db82905560dc8190556040517fc84081a9c94a2300cdec20e3d60952b84e96e11edf24cb65ba26b7f8455f29db9061265390849084906138e4565b60d48190556040517f20d916c976f3971e8200089411b0b712ef4612d98380b8ad2e3d8a8a376d85c79061100a908390613646565b60d58190556040517f0cd8fcb5e08d7632af461f0ad793e5c63dc0d7595c301f5880650175e37a87489061100a908390613646565b60d75481116127465760405162461bcd60e51b8152600401610a7a90613740565b60d78190556040517f2983f04849f6bc055a842a8036b38adc41a780193744d7320475e29f0c78391f9061100a908390613646565b612783610f6a565b6127cb576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b6033805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6127fe61236b565b604080516001600160a01b039092168252519081900360200190a1565b600080612826612ceb565b604080516001600160a01b038316815290519192507efffc2da0b561cae30d9826d37709e9421c4725faebc226cbbb7ef5fc5e7349919081900360200190a1806001600160a01b031663e74a474a3086866040518463ffffffff1660e01b815260040180846001600160a01b03168152602001806020018360ff168152602001828103825284818151815260200191508051906020019080838360005b838110156128db5781810151838201526020016128c3565b50505050905090810190601f1680156129085780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561292957600080fd5b505af115801561293d573d6000803e3d6000fd5b50929695505050505050565b6000828211156129a0576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6129ae610f6a565b156129f3576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6033805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586127fe61236b565b600082820183811015610c6a576040805162461bcd60e51b815260206004820152601b60248201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604482015290519081900360640190fd5b6001600160a01b038416612aa75760405162461bcd60e51b8152600401610a7a906136ee565b81612ac45760405162461bcd60e51b8152600401610a7a906136c8565b6001600160a01b038416600090815260d660205260409020548111612afb5760405162461bcd60e51b8152600401610a7a9061364f565b612b4583838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506001600160a01b03881692915050612d32565b506040516001600160a01b0385169033907f78a9b536049c39a00adaf57016b1376c99dd48a0faf2cef23690232f21ce42cc90600090a36001600160a01b03909316600090815260d660205260409020929092555050565b3b151590565b600054610100900460ff1680612bbc5750612bbc61235a565b80612bca575060005460ff16155b612c055760405162461bcd60e51b815260040180806020018281038252602e815260200180613d62602e913960400191505060405180910390fd5b600054610100900460ff16158015612c30576000805460ff1961ff0019909116610100171660011790555b612c3861073c565b6107c9612d63565b600054610100900460ff1680612c595750612c5961235a565b80612c67575060005460ff16155b612ca25760405162461bcd60e51b815260040180806020018281038252602e815260200180613d62602e913960400191505060405180910390fd5b600054610100900460ff16158015612ccd576000805460ff1961ff0019909116610100171660011790555b6033805460ff1916905580156107db576000805461ff001916905550565b600080600060405180602001612d0090612e4a565b6020820181038252601f19601f8201166040525090508051602082016000f09150813b612d2c57600080fd5b50905090565b6000806000835160208501865af49050801560018114612d5157612d5c565b3d806000803e806000fd5b5092915050565b600054610100900460ff1680612d7c5750612d7c61235a565b80612d8a575060005460ff16155b612dc55760405162461bcd60e51b815260040180806020018281038252602e815260200180613d62602e913960400191505060405180910390fd5b600054610100900460ff16158015612df0576000805460ff1961ff0019909116610100171660011790555b6000612dfa61236b565b606580546001600160a01b0319166001600160a01b03831690811790915560405191925090600090600080516020613db0833981519152908290a35080156107db576000805461ff001916905550565b61039d8061399f83390190565b60006001600160401b03831115612e6a57fe5b612e7d601f8401601f1916602001613958565b9050828152838383011115612e9157600080fd5b828260208301376000602084830101529392505050565b8035610a838161397b565b600082601f830112612ec3578081fd5b813560206001600160401b03821115612ed857fe5b612ee58182840201613958565b82815281810190858301604080860288018501891015612f03578687fd5b865b86811015612f2957612f178a84612f61565b85529385019391810191600101612f05565b509198975050505050505050565b8035610a8381613990565b600082601f830112612f52578081fd5b610c6a83833560208501612e57565b600060408284031215612f72578081fd5b604051604081018181106001600160401b0382111715612f8e57fe5b6040529050808235612f9f8161397b565b81526020830135612faf81613990565b6020919091015292915050565b803560ff81168114610a8357600080fd5b600060208284031215612fde578081fd5b8135610c6a8161397b565b600060208284031215612ffa578081fd5b8151610c6a8161397b565b60008060408385031215613017578081fd5b82356130228161397b565b915060208301356130328161397b565b809150509250929050565b600080600080600060a08688031215613054578081fd5b853561305f8161397b565b9450602086013561306f8161397b565b9350604086013561307f8161397b565b9250606086013561308f8161397b565b9150608086013561309f8161397b565b809150509295509295909350565b600080602083850312156130bf578182fd5b82356001600160401b03808211156130d5578384fd5b818501915085601f8301126130e8578384fd5b8135818111156130f6578485fd5b86602060408302850101111561310a578485fd5b60209290920196919550909350505050565b60006020828403121561312d578081fd5b8151610c6a81613990565b600080600080600080600080610100898b031215613154578586fd5b61315d89612f37565b975061316b60208a01612ea8565b965060408901356001600160401b0380821115613186578788fd5b6131928c838d01612f42565b975060608b01359150808211156131a7578485fd5b6131b38c838d01612f42565b965060808b01359150808211156131c8578485fd5b6131d48c838d01612f42565b955060a08b0135945060c08b0135935060e08b01359150808211156131f7578283fd5b506132048b828c01612eb3565b9150509295985092959890939650565b600060208284031215613225578081fd5b5035919050565b6000806040838503121561323e578182fd5b82356001600160401b03811115613253578283fd5b8301601f81018513613263578283fd5b61327285823560208401612e57565b92505061328160208401612fbc565b90509250929050565b60006040828403121561329b578081fd5b610c6a8383612f61565b6000602082840312156132b6578081fd5b815161ffff81168114610c6a578182fd5b6000602082840312156132d8578081fd5b5051919050565b600080604083850312156132f1578182fd5b50508035926020909101359150565b600080600060608486031215613314578081fd5b505081359360208301359350604090920135919050565b600080600080600060808688031215613342578283fd5b85359450602086013593506040860135925060608601356001600160401b038082111561336d578283fd5b818801915088601f830112613380578283fd5b81358181111561338e578384fd5b89602080830285010111156133a1578384fd5b9699959850939650602001949392505050565b6000806000806000608086880312156133cb578283fd5b85359450602086013593506040860135925060608601356001600160401b03808211156133f6578283fd5b818801915088601f830112613409578283fd5b813581811115613417578384fd5b8960208285010111156133a1578384fd5b600060208284031215613439578081fd5b610c6a82612fbc565b60008151808452815b818110156134675760208185018101518683018201520161344b565b818111156134785782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b600060018060a01b03808a1683526020818a1681850152604060e0818601526134cd60e086018b613442565b89841660608701526080860189905260a0860188905285810360c0870152865180825283880191840190865b8181101561352257835180518816845286015115158684015292850192918401916001016134f9565b50909e9d5050505050505050505050505050565b6001600160a01b0385168152831515602082015260806040820181905260009061356290830185613442565b82810360608401526135748185613442565b979650505050505050565b6001600160a01b038a811682528915156020830152610120604083018190526000916135ad8483018c613442565b915083820360608501526135c1828b613442565b98166080840152505060a081019490945260c084019290925260e083015261010090910152949350505050565b6020808252825182820181905260009190848201906040850190845b8181101561362f5783516001600160a01b03168352928401929184019160010161360a565b50909695505050505050565b901515815260200190565b90815260200190565b60208082526010908201526f185b1c9958591e481d5c19dc9859195960821b604082015260600190565b6020808252600e908201526d696e76616c696420626f756e647360901b604082015260600190565b6020808252600d908201526c6f6e6c79206d616e616765727360981b604082015260600190565b6020808252600c908201526b19185d184b5a5b9d985b1a5960a21b604082015260600190565b6020808252600e908201526d1d185c99d95d0b5a5b9d985b1a5960921b604082015260600190565b60208082526010908201526f34b73b30b634b210333930b1ba34b7b760811b604082015260600190565b6020808252601a90820152793b32b939b4b7b7103732b2b239903a37903132903434b3b432b960311b604082015260600190565b6020808252601490820152730c8c2e8c240dcdee840dacae8c6d040d2dcc8caf60631b604082015260600190565b6020808252600a90820152696f6e6c7920706f6f6c7360b01b604082015260600190565b60208082526014908201527324b73b30b634b21030b9b9b2ba2430b7323632b960611b604082015260600190565b60208082526010908201526f18dbdb9d1c9858dd1cc81c185d5cd95960821b604082015260600190565b602080825260199082015278496e76616c696420676f7665726e616e63654164647265737360381b604082015260600190565b602080825260189082015277676f7665726e616e63653a20696e76616c6964206e616d6560401b604082015260600190565b602080825260129082015271496e76616c69642064616f4164647265737360701b604082015260600190565b6020808252600c908201526b1a5b9d985b1a59081c1bdbdb60a21b604082015260600190565b61ffff91909116815260200190565b918252602082015260400190565b93845260208401929092526040830152606082015260800190565b6000808335601e19843603018112613923578283fd5b8301803591506001600160401b0382111561393c578283fd5b60200191503681900382131561395157600080fd5b9250929050565b6040518181016001600160401b038111828210171561397357fe5b604052919050565b6001600160a01b03811681146107db57600080fd5b80151581146107db57600080fdfe608060405234801561001057600080fd5b5061037d806100206000396000f3fe6080604052600436106100225760003560e01c8063e74a474a1461003957610031565b366100315761002f6100f2565b005b61002f6100f2565b61002f6004803603606081101561004f57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561007957600080fd5b82018360208201111561008b57600080fd5b803590602001918460018302840111600160201b831117156100ac57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505050903560ff16915061010c9050565b6100fa61010a565b61010a61010561019c565b61025d565b565b600061011661019c565b6001600160a01b031614610161576040805162461bcd60e51b815260206004820152600d60248201526c496d706c206e6f74207a65726f60981b604482015290519081900360640190fd5b61016a83610281565b610173816102ff565b815115610197576101958261018661019c565b6001600160a01b031690610307565b505b505050565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546000916001600160a01b0382166101db5760009250505061025a565b816001600160a01b031663ecef89d56101f2610338565b6040518263ffffffff1660e01b8152600401808260ff16815260200191505060206040518083038186803b15801561022957600080fd5b505afa15801561023d573d6000803e3d6000fd5b505050506040513d602081101561025357600080fd5b5051925050505b90565b3660008037600080366000845af43d6000803e80801561027c573d6000f35b3d6000fd5b61028a81610341565b6102db576040805162461bcd60e51b815260206004820181905260248201527f43616e6e6f742073657420696d706c656d656e746174696f6e20746f20454f41604482015290519081900360640190fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b600160fc1b55565b6000806000835160208501865af4905080156001811461032657610331565b3d806000803e806000fd5b5092915050565b600160fc1b5490565b3b15159056fea2646970667358221220b01e751b5b5a4cced04d4a29df301abad765089b3f62b118e08acda884219e0364736f6c634300070600334f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a65644f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65728be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0a26469706673582212204740ffbb7b132ae4c273f6e74a3c227531b399d36e54020567a920029f80b9ad64736f6c63430007060033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102c45760003560e01c806389da8ad71161017957806389da8ad7146104c55780638da5cb5b146104d8578063965afa89146104e05780639a068bd6146104f35780639b313686146105065780639cada6e4146105195780639f49b60e1461052f578063aa12ae4d14610542578063aa7d664e1461054a578063af8902151461055d578063b187bd2614610565578063b3596f071461056d578063b8ff28ac14610580578063bdcede0c14610593578063c8f88a80146105a6578063cb6f3bbc146105b9578063cc435bf3146105c1578063cdf04c07146105d4578063cfc16254146105e7578063d77268e6146105fa578063dbf5974d14610602578063e0cb599614610615578063e5ac13a914610628578063eb849a041461063b578063ecb0116a1461064e578063ecef89d514610656578063eec16c4414610669578063eed0ff461461067c578063f2fde38b1461068f578063fcc08cbc146106a2576102c4565b8063032c49ed146102c957806307120115146102f257806308d7ce02146102fc57806309ed4893146103145780630ddefe14146103295780630f6559c41461033c5780631459457a146103515780632131c68c1461036457806321f8a7211461036c57806325c4121b1461037f5780632927233b146103875780633f4ba83a146103a75780633f7f5c72146103af5780634501b088146103b757806345812ca5146103bf5780634da0be1d146103d25780634f8419b9146103f257806354d8a5bd146104055780635556ee551461040d5780635a97284b146104205780635b16ebb7146104335780635c975abb146104465780635fbf37a31461044e578063715018a614610461578063771d1baf14610469578063795053d31461047c5780637b7d612b14610484578063808ae5fb146104975780638456cb59146104aa578063878f4778146104b2575b600080fd5b6102dc6102d7366004612fcd565b6106b5565b6040516102e991906138d5565b60405180910390f35b6102fa61073c565b005b6103046107de565b6040516102e994939291906138f2565b61031c6107f0565b6040516102e9919061348d565b6102fa610337366004612fcd565b6107ff565b610344610885565b6040516102e99190613646565b6102fa61035f36600461303d565b61088b565b61031c6109c2565b61031c61037a366004613214565b6109d1565b6102fa610a88565b61039a610395366004612fcd565b610af5565b6040516102e9919061363b565b6102fa610b0a565b6102fa610b76565b610344610c58565b61031c6103cd36600461322c565b610c5e565b6103e56103e0366004612fcd565b610c71565b6040516102e991906135ee565b61031c610400366004612fcd565b610ddd565b6103e5610e5e565b61034461041b366004612fcd565b610ec0565b6102fa61042e366004612fcd565b610ed2565b61039a610441366004612fcd565b610f55565b61039a610f6a565b6102fa61045c366004613214565b610f73565b6102fa611015565b6102fa6104773660046132df565b6110af565b61031c61111f565b6102fa610492366004613214565b61112e565b6102fa6104a5366004613005565b6111c5565b6102fa6112fa565b6102fa6104c036600461332b565b611364565b6102fa6104d3366004612fcd565b6114c0565b61031c611543565b6102fa6104ee366004612fcd565b611552565b61031c610501366004613214565b6115bd565b6102fa6105143660046130ad565b6115e7565b6105216116f1565b6040516102e99291906138e4565b6102fa61053d3660046132df565b6116fb565b610344611767565b6102fa610558366004613214565b61176d565b61031c6117d8565b61039a6117e7565b61034461057b366004612fcd565b6117f6565b61031c61058e366004613138565b611877565b6102fa6105a1366004612fcd565b611ad5565b6102fa6105b4366004613300565b611b5b565b610344611bd0565b61039a6105cf366004612fcd565b611bd6565b61039a6105e2366004612fcd565b611c6c565b6102fa6105f5366004612fcd565b611c81565b610344611cec565b6102fa6106103660046133b4565b611cf2565b61039a610623366004612fcd565b611df6565b6102fa610636366004612fcd565b611e0b565b6103e5610649366004612fcd565b611e76565b610521612046565b61031c610664366004613428565b612050565b6102fa610677366004613214565b612082565b6102fa61068a366004613214565b6120ed565b6102fa61069d366004612fcd565b612158565b61031c6106b0366004612fcd565b612249565b60ce5460405163b02e786f60e01b81526000916001600160a01b03169063b02e786f906106e690859060040161348d565b60206040518083038186803b1580156106fe57600080fd5b505afa158015610712573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073691906132a5565b92915050565b600054610100900460ff1680610755575061075561235a565b80610763575060005460ff16155b61079e5760405162461bcd60e51b815260040180806020018281038252602e815260200180613d62602e913960400191505060405180910390fd5b600054610100900460ff161580156107c9576000805460ff1961ff0019909116610100171660011790555b80156107db576000805461ff00191690555b50565b60d25460de5460e05460d35490919293565b60ce546001600160a01b031690565b61080761236b565b6001600160a01b0316610818611543565b6001600160a01b031614610861576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6001600160a01b0316600090815260df60205260409020805460ff19166001179055565b60d75481565b600054610100900460ff16806108a457506108a461235a565b806108b2575060005460ff16155b6108ed5760405162461bcd60e51b815260040180806020018281038252602e815260200180613d62602e913960400191505060405180910390fd5b600054610100900460ff16158015610918576000805460ff1961ff0019909116610100171660011790555b610922868661236f565b61092a612377565b61093384612414565b61093c83612485565b610945826124f6565b61095861138861012c6064612710612567565b610964600a60646125f7565b61097160056103e861265f565b61097d620151806126bb565b6109896224ea0061112e565b6109946103e8610f73565b61099e600a6126f0565b6109a860e6612725565b80156109ba576000805461ff00191690555b505050505050565b60cc546001600160a01b031681565b60cd5460405163c2a9ffb160e01b81526000916001600160a01b03169063c2a9ffb190610a02908590600401613646565b60206040518083038186803b158015610a1a57600080fd5b505afa158015610a2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a529190612fe9565b90506001600160a01b038116610a835760405162461bcd60e51b8152600401610a7a90613851565b60405180910390fd5b919050565b33600090815260d1602052604090205460ff161515600114610abc5760405162461bcd60e51b8152600401610a7a906137a2565b7fdbd4d7b818d776167ae42054b0831aa269b1eb3ea73bd2e7ef6091f2879b183733604051610aeb919061348d565b60405180910390a1565b60dd6020526000908152604090205460ff1681565b610b1261236b565b6001600160a01b0316610b23611543565b6001600160a01b031614610b6c576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b610b7461277b565b565b60d16000336001600160a01b03166339b81fd96040518163ffffffff1660e01b815260040160206040518083038186803b158015610bb357600080fd5b505afa158015610bc7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610beb9190612fe9565b6001600160a01b0316815260208101919091526040016000205460ff161515600114610c295760405162461bcd60e51b8152600401610a7a906136a1565b7f686c28f13f997a49532b3373c8e5b4a6e22e6b06b66d06487a8241a599717f4933604051610aeb919061348d565b60d45490565b6000610c6a838361281b565b9392505050565b60cb54606090806001600160401b0381118015610c8d57600080fd5b50604051908082528060200260200182016040528015610cb7578160200160208202803683370190505b5091506000805b82811015610dc257600060cb8281548110610cd557fe5b6000918252602090912001546040516370a0823160e01b81526001600160a01b03909116906370a0823190610d0e90899060040161348d565b60206040518083038186803b158015610d2657600080fd5b505afa158015610d3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5e91906132c7565b1115610dba5760cb8181548110610d7157fe5b9060005260206000200160009054906101000a90046001600160a01b0316848381518110610d9b57fe5b6001600160a01b03909216602092830291909101909101526001909101905b600101610cbe565b506000610dcf8383612949565b845103845250919392505050565b60cd5460405163174dbff160e21b81526000916001600160a01b031690635d36ffc490610e0e90859060040161348d565b60206040518083038186803b158015610e2657600080fd5b505afa158015610e3a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107369190612fe9565b606060cb805480602002602001604051908101604052809291908181526020018280548015610eb657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e98575b5050505050905090565b60d66020526000908152604090205481565b610eda61236b565b6001600160a01b0316610eeb611543565b6001600160a01b031614610f34576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6001600160a01b0316600090815260dd60205260409020805460ff19169055565b60d16020526000908152604090205460ff1681565b60335460ff1690565b610f7b61236b565b6001600160a01b0316610f8c611543565b6001600160a01b031614610fd5576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b60d88190556040517fbe762d516a09c899b785daf0c0f9bea93fd44a062d9ecc24c2ddba4c6f8b47ed9061100a908390613646565b60405180910390a150565b61101d61236b565b6001600160a01b031661102e611543565b6001600160a01b031614611077576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6065546040516000916001600160a01b031690600080516020613db0833981519152908390a3606580546001600160a01b0319169055565b6110b761236b565b6001600160a01b03166110c8611543565b6001600160a01b031614611111576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b61111b82826125f7565b5050565b60cd546001600160a01b031681565b61113661236b565b6001600160a01b0316611147611543565b6001600160a01b031614611190576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b60d98190556040517f5c7a1f308b9ecdacddd5f035f458158e6a2581b1921b2ca7de3732bd1dd6e5909061100a908390613646565b6111cd61236b565b6001600160a01b03166111de611543565b6001600160a01b031614611227576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6001600160a01b038216611276576040805162461bcd60e51b8152602060048201526011602482015270496e76616c696420706f6f6c4c6f67696360781b604482015290519081900360640190fd5b6001600160a01b0381166112cc576040805162461bcd60e51b8152602060048201526018602482015277496e76616c696420706f6f6c4d616e616765724c6f67696360401b604482015290519081900360640190fd5b609780546001600160a01b039384166001600160a01b03199182161790915560988054929093169116179055565b61130261236b565b6001600160a01b0316611313611543565b6001600160a01b03161461135c576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b610b746129a6565b61136c61236b565b6001600160a01b031661137d611543565b6001600160a01b0316146113c6576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b8385111580156113d7575060cb5484105b6113f35760405162461bcd60e51b8152600401610a7a90613679565b61140860016114028688612949565b90612a29565b81146114265760405162461bcd60e51b8152600401610a7a90613774565b845b8481116109ba57600060cb828154811061143e57fe5b6000918252602090912001546001600160a01b031690508061146057506114b8565b6001600160a01b038116600090815260d66020526040902054851161148557506114b8565b6114b6818585611495868c612949565b81811061149e57fe5b90506020028101906114b0919061390d565b88612a81565b505b600101611428565b6114c861236b565b6001600160a01b03166114d9611543565b6001600160a01b031614611522576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6001600160a01b0316600090815260df60205260409020805460ff19169055565b6065546001600160a01b031690565b61155a61236b565b6001600160a01b031661156b611543565b6001600160a01b0316146115b4576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6107db81612485565b60cb81815481106115cd57600080fd5b6000918252602090912001546001600160a01b0316905081565b6115ef61236b565b6001600160a01b0316611600611543565b6001600160a01b031614611649576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b8060005b818110156116eb57600084848381811061166357fe5b905060400201803603810190611679919061328a565b80516001600160a01b0316600090815260d1602052604090205490915060ff166116b55760405162461bcd60e51b8152600401610a7a906138af565b60208181015191516001600160a01b0316600090815260e190915260409020805460ff191691151591909117905560010161164d565b50505050565b60cf5460d0549091565b61170361236b565b6001600160a01b0316611714611543565b6001600160a01b03161461175d576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b61111b828261265f565b60d55490565b61177561236b565b6001600160a01b0316611786611543565b6001600160a01b0316146117cf576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6107db816126bb565b60da546001600160a01b031681565b60006117f1610f6a565b905090565b60ce54604051638b2f0f4f60e01b81526000916001600160a01b031690638b2f0f4f9061182790859060040161348d565b60206040518083038186803b15801561183f57600080fd5b505afa158015611853573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073691906132c7565b6000611881610f6a565b1561189e5760405162461bcd60e51b8152600401610a7a906137f4565b6000308a88886040516024016118b79493929190613536565b60408051601f198184030181529190526020810180516001600160e01b0316635426f81d60e01b17905290506118ee816002610c5e565b91506000308a8a8589898960405160240161190f97969594939291906134a1565b60408051601f198184030181529190526020810180516001600160e01b031663361315ff60e11b17905290506000611948826001610c5e565b604051633a81136f60e11b81529091506001600160a01b0385169063750226de9061197790849060040161348d565b602060405180830381600087803b15801561199157600080fd5b505af11580156119a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119c9919061311c565b5060cb849080600181540180825580915050600190039060005260206000200160009091909190916101000a8154816001600160a01b0302191690836001600160a01b03160217905550600160d16000866001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff02191690831515021790555060d75460d66000866001600160a01b03166001600160a01b03168152602001908152602001600020819055507f7568e63260f13515e4b3208667c411fbf4c7dce047496ca5f9a56f1c92440d93848d8b8d8f428d8d60d354604051611abe9998979695949392919061357f565b60405180910390a150505098975050505050505050565b611add61236b565b6001600160a01b0316611aee611543565b6001600160a01b031614611b37576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6001600160a01b0316600090815260dd60205260409020805460ff19166001179055565b611b6361236b565b6001600160a01b0316611b74611543565b6001600160a01b031614611bbd576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b611bcb83838360d354612567565b505050565b60d95481565b60ce5460405163b4fb127960e01b815260009182916001600160a01b039091169063b4fb127990611c0b90869060040161348d565b60206040518083038186803b158015611c2357600080fd5b505afa158015611c37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c5b9190612fe9565b6001600160a01b0316141592915050565b60e16020526000908152604090205460ff1681565b611c8961236b565b6001600160a01b0316611c9a611543565b6001600160a01b031614611ce3576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6107db816124f6565b60d85481565b611cfa61236b565b6001600160a01b0316611d0b611543565b6001600160a01b031614611d54576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b838511158015611d65575060cb5484105b611d815760405162461bcd60e51b8152600401610a7a90613679565b845b8481116109ba57600060cb8281548110611d9957fe5b6000918252602090912001546001600160a01b0316905080611dbb5750611dee565b6001600160a01b038116600090815260d660205260409020548511611de05750611dee565b611dec81858588612a81565b505b600101611d83565b60df6020526000908152604090205460ff1681565b611e1361236b565b6001600160a01b0316611e24611543565b6001600160a01b031614611e6d576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6107db81612414565b60cb54606090806001600160401b0381118015611e9257600080fd5b50604051908082528060200260200182016040528015611ebc578160200160208202803683370190505b5091506000805b82811015610dc257600060cb8281548110611eda57fe5b6000918252602091829020015460408051630f28525360e11b815290516001600160a01b0390921692631e50a4a692600480840193829003018186803b158015611f2357600080fd5b505afa158015611f37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5b9190612fe9565b9050856001600160a01b0316816001600160a01b031663481c6a756040518163ffffffff1660e01b815260040160206040518083038186803b158015611fa057600080fd5b505afa158015611fb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd89190612fe9565b6001600160a01b0316141561203d5760cb8281548110611ff457fe5b9060005260206000200160009054906101000a90046001600160a01b031685848151811061201e57fe5b6001600160a01b03909216602092830291909101909101526001909201915b50600101611ec3565b60db5460dc549091565b60008160ff166001141561207057506098546001600160a01b0316610a83565b506097546001600160a01b0316610a83565b61208a61236b565b6001600160a01b031661209b611543565b6001600160a01b0316146120e4576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6107db816126f0565b6120f561236b565b6001600160a01b0316612106611543565b6001600160a01b03161461214f576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6107db81612725565b61216061236b565b6001600160a01b0316612171611543565b6001600160a01b0316146121ba576040805162461bcd60e51b81526020600482018190526024820152600080516020613d90833981519152604482015290519081900360640190fd5b6001600160a01b0381166121ff5760405162461bcd60e51b8152600401808060200182810382526026815260200180613d3c6026913960400191505060405180910390fd5b6065546040516001600160a01b03808416921690600080516020613db083398151915290600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b600061225482611bd6565b15610a835760ce5460405163b02e786f60e01b81526000916001600160a01b03169063b02e786f9061228a90869060040161348d565b60206040518083038186803b1580156122a257600080fd5b505afa1580156122b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122da91906132a5565b60cd5460405162a950c360e81b81529192506001600160a01b03169063a950c3009061230a9084906004016138d5565b60206040518083038186803b15801561232257600080fd5b505afa158015612336573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6a9190612fe9565b600061236530612b9d565b15905090565b3390565b611227612ba3565b600054610100900460ff1680612390575061239061235a565b8061239e575060005460ff16155b6123d95760405162461bcd60e51b815260040180806020018281038252602e815260200180613d62602e913960400191505060405180910390fd5b600054610100900460ff16158015612404576000805460ff1961ff0019909116610100171660011790555b61240c61073c565b6107c9612c40565b6001600160a01b03811661243a5760405162461bcd60e51b8152600401610a7a906137c6565b60ce80546001600160a01b0319166001600160a01b0383161790556040517faca6dca39d79ebceec9b32e3a681f32c1368a5b373cc24d96a02a896a1457ed89061100a90839061348d565b6001600160a01b0381166124ab5760405162461bcd60e51b8152600401610a7a90613883565b60cc80546001600160a01b0319166001600160a01b0383161790556040517f7138c17e9cd38b1f65ba47723efdaec045a981aa53992018fd215e5c09a22fc49061100a90839061348d565b6001600160a01b03811661251c5760405162461bcd60e51b8152600401610a7a9061381e565b60cd80546001600160a01b0319166001600160a01b0383161790556040517fbdb80a7ad60bd8133ed6b01049f9065c4cad1fa0a8e074da74b480f2aa83c9369061100a90839061348d565b8084111580156125775750808311155b80156125835750808211155b61259f5760405162461bcd60e51b8152600401610a7a90613716565b60d284905560de83905560d381905560e08290556040517f720fe36421ecec4b8b4b3282b5714c1fde000f75dcc989cd486474901819d852906125e99086908690869086906138f2565b60405180910390a150505050565b808211156126175760405162461bcd60e51b8152600401610a7a90613716565b60cf82905560d08190556040517fb10da2958bf5ec1bff3164ff753a09e0460ed44d3abf73e79b817b500ed0f2f19061265390849084906138e4565b60405180910390a15050565b8082111561267f5760405162461bcd60e51b8152600401610a7a90613716565b60db82905560dc8190556040517fc84081a9c94a2300cdec20e3d60952b84e96e11edf24cb65ba26b7f8455f29db9061265390849084906138e4565b60d48190556040517f20d916c976f3971e8200089411b0b712ef4612d98380b8ad2e3d8a8a376d85c79061100a908390613646565b60d58190556040517f0cd8fcb5e08d7632af461f0ad793e5c63dc0d7595c301f5880650175e37a87489061100a908390613646565b60d75481116127465760405162461bcd60e51b8152600401610a7a90613740565b60d78190556040517f2983f04849f6bc055a842a8036b38adc41a780193744d7320475e29f0c78391f9061100a908390613646565b612783610f6a565b6127cb576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b6033805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6127fe61236b565b604080516001600160a01b039092168252519081900360200190a1565b600080612826612ceb565b604080516001600160a01b038316815290519192507efffc2da0b561cae30d9826d37709e9421c4725faebc226cbbb7ef5fc5e7349919081900360200190a1806001600160a01b031663e74a474a3086866040518463ffffffff1660e01b815260040180846001600160a01b03168152602001806020018360ff168152602001828103825284818151815260200191508051906020019080838360005b838110156128db5781810151838201526020016128c3565b50505050905090810190601f1680156129085780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561292957600080fd5b505af115801561293d573d6000803e3d6000fd5b50929695505050505050565b6000828211156129a0576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6129ae610f6a565b156129f3576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6033805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586127fe61236b565b600082820183811015610c6a576040805162461bcd60e51b815260206004820152601b60248201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604482015290519081900360640190fd5b6001600160a01b038416612aa75760405162461bcd60e51b8152600401610a7a906136ee565b81612ac45760405162461bcd60e51b8152600401610a7a906136c8565b6001600160a01b038416600090815260d660205260409020548111612afb5760405162461bcd60e51b8152600401610a7a9061364f565b612b4583838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506001600160a01b03881692915050612d32565b506040516001600160a01b0385169033907f78a9b536049c39a00adaf57016b1376c99dd48a0faf2cef23690232f21ce42cc90600090a36001600160a01b03909316600090815260d660205260409020929092555050565b3b151590565b600054610100900460ff1680612bbc5750612bbc61235a565b80612bca575060005460ff16155b612c055760405162461bcd60e51b815260040180806020018281038252602e815260200180613d62602e913960400191505060405180910390fd5b600054610100900460ff16158015612c30576000805460ff1961ff0019909116610100171660011790555b612c3861073c565b6107c9612d63565b600054610100900460ff1680612c595750612c5961235a565b80612c67575060005460ff16155b612ca25760405162461bcd60e51b815260040180806020018281038252602e815260200180613d62602e913960400191505060405180910390fd5b600054610100900460ff16158015612ccd576000805460ff1961ff0019909116610100171660011790555b6033805460ff1916905580156107db576000805461ff001916905550565b600080600060405180602001612d0090612e4a565b6020820181038252601f19601f8201166040525090508051602082016000f09150813b612d2c57600080fd5b50905090565b6000806000835160208501865af49050801560018114612d5157612d5c565b3d806000803e806000fd5b5092915050565b600054610100900460ff1680612d7c5750612d7c61235a565b80612d8a575060005460ff16155b612dc55760405162461bcd60e51b815260040180806020018281038252602e815260200180613d62602e913960400191505060405180910390fd5b600054610100900460ff16158015612df0576000805460ff1961ff0019909116610100171660011790555b6000612dfa61236b565b606580546001600160a01b0319166001600160a01b03831690811790915560405191925090600090600080516020613db0833981519152908290a35080156107db576000805461ff001916905550565b61039d8061399f83390190565b60006001600160401b03831115612e6a57fe5b612e7d601f8401601f1916602001613958565b9050828152838383011115612e9157600080fd5b828260208301376000602084830101529392505050565b8035610a838161397b565b600082601f830112612ec3578081fd5b813560206001600160401b03821115612ed857fe5b612ee58182840201613958565b82815281810190858301604080860288018501891015612f03578687fd5b865b86811015612f2957612f178a84612f61565b85529385019391810191600101612f05565b509198975050505050505050565b8035610a8381613990565b600082601f830112612f52578081fd5b610c6a83833560208501612e57565b600060408284031215612f72578081fd5b604051604081018181106001600160401b0382111715612f8e57fe5b6040529050808235612f9f8161397b565b81526020830135612faf81613990565b6020919091015292915050565b803560ff81168114610a8357600080fd5b600060208284031215612fde578081fd5b8135610c6a8161397b565b600060208284031215612ffa578081fd5b8151610c6a8161397b565b60008060408385031215613017578081fd5b82356130228161397b565b915060208301356130328161397b565b809150509250929050565b600080600080600060a08688031215613054578081fd5b853561305f8161397b565b9450602086013561306f8161397b565b9350604086013561307f8161397b565b9250606086013561308f8161397b565b9150608086013561309f8161397b565b809150509295509295909350565b600080602083850312156130bf578182fd5b82356001600160401b03808211156130d5578384fd5b818501915085601f8301126130e8578384fd5b8135818111156130f6578485fd5b86602060408302850101111561310a578485fd5b60209290920196919550909350505050565b60006020828403121561312d578081fd5b8151610c6a81613990565b600080600080600080600080610100898b031215613154578586fd5b61315d89612f37565b975061316b60208a01612ea8565b965060408901356001600160401b0380821115613186578788fd5b6131928c838d01612f42565b975060608b01359150808211156131a7578485fd5b6131b38c838d01612f42565b965060808b01359150808211156131c8578485fd5b6131d48c838d01612f42565b955060a08b0135945060c08b0135935060e08b01359150808211156131f7578283fd5b506132048b828c01612eb3565b9150509295985092959890939650565b600060208284031215613225578081fd5b5035919050565b6000806040838503121561323e578182fd5b82356001600160401b03811115613253578283fd5b8301601f81018513613263578283fd5b61327285823560208401612e57565b92505061328160208401612fbc565b90509250929050565b60006040828403121561329b578081fd5b610c6a8383612f61565b6000602082840312156132b6578081fd5b815161ffff81168114610c6a578182fd5b6000602082840312156132d8578081fd5b5051919050565b600080604083850312156132f1578182fd5b50508035926020909101359150565b600080600060608486031215613314578081fd5b505081359360208301359350604090920135919050565b600080600080600060808688031215613342578283fd5b85359450602086013593506040860135925060608601356001600160401b038082111561336d578283fd5b818801915088601f830112613380578283fd5b81358181111561338e578384fd5b89602080830285010111156133a1578384fd5b9699959850939650602001949392505050565b6000806000806000608086880312156133cb578283fd5b85359450602086013593506040860135925060608601356001600160401b03808211156133f6578283fd5b818801915088601f830112613409578283fd5b813581811115613417578384fd5b8960208285010111156133a1578384fd5b600060208284031215613439578081fd5b610c6a82612fbc565b60008151808452815b818110156134675760208185018101518683018201520161344b565b818111156134785782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b600060018060a01b03808a1683526020818a1681850152604060e0818601526134cd60e086018b613442565b89841660608701526080860189905260a0860188905285810360c0870152865180825283880191840190865b8181101561352257835180518816845286015115158684015292850192918401916001016134f9565b50909e9d5050505050505050505050505050565b6001600160a01b0385168152831515602082015260806040820181905260009061356290830185613442565b82810360608401526135748185613442565b979650505050505050565b6001600160a01b038a811682528915156020830152610120604083018190526000916135ad8483018c613442565b915083820360608501526135c1828b613442565b98166080840152505060a081019490945260c084019290925260e083015261010090910152949350505050565b6020808252825182820181905260009190848201906040850190845b8181101561362f5783516001600160a01b03168352928401929184019160010161360a565b50909695505050505050565b901515815260200190565b90815260200190565b60208082526010908201526f185b1c9958591e481d5c19dc9859195960821b604082015260600190565b6020808252600e908201526d696e76616c696420626f756e647360901b604082015260600190565b6020808252600d908201526c6f6e6c79206d616e616765727360981b604082015260600190565b6020808252600c908201526b19185d184b5a5b9d985b1a5960a21b604082015260600190565b6020808252600e908201526d1d185c99d95d0b5a5b9d985b1a5960921b604082015260600190565b60208082526010908201526f34b73b30b634b210333930b1ba34b7b760811b604082015260600190565b6020808252601a90820152793b32b939b4b7b7103732b2b239903a37903132903434b3b432b960311b604082015260600190565b6020808252601490820152730c8c2e8c240dcdee840dacae8c6d040d2dcc8caf60631b604082015260600190565b6020808252600a90820152696f6e6c7920706f6f6c7360b01b604082015260600190565b60208082526014908201527324b73b30b634b21030b9b9b2ba2430b7323632b960611b604082015260600190565b60208082526010908201526f18dbdb9d1c9858dd1cc81c185d5cd95960821b604082015260600190565b602080825260199082015278496e76616c696420676f7665726e616e63654164647265737360381b604082015260600190565b602080825260189082015277676f7665726e616e63653a20696e76616c6964206e616d6560401b604082015260600190565b602080825260129082015271496e76616c69642064616f4164647265737360701b604082015260600190565b6020808252600c908201526b1a5b9d985b1a59081c1bdbdb60a21b604082015260600190565b61ffff91909116815260200190565b918252602082015260400190565b93845260208401929092526040830152606082015260800190565b6000808335601e19843603018112613923578283fd5b8301803591506001600160401b0382111561393c578283fd5b60200191503681900382131561395157600080fd5b9250929050565b6040518181016001600160401b038111828210171561397357fe5b604052919050565b6001600160a01b03811681146107db57600080fd5b80151581146107db57600080fdfe608060405234801561001057600080fd5b5061037d806100206000396000f3fe6080604052600436106100225760003560e01c8063e74a474a1461003957610031565b366100315761002f6100f2565b005b61002f6100f2565b61002f6004803603606081101561004f57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561007957600080fd5b82018360208201111561008b57600080fd5b803590602001918460018302840111600160201b831117156100ac57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505050903560ff16915061010c9050565b6100fa61010a565b61010a61010561019c565b61025d565b565b600061011661019c565b6001600160a01b031614610161576040805162461bcd60e51b815260206004820152600d60248201526c496d706c206e6f74207a65726f60981b604482015290519081900360640190fd5b61016a83610281565b610173816102ff565b815115610197576101958261018661019c565b6001600160a01b031690610307565b505b505050565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546000916001600160a01b0382166101db5760009250505061025a565b816001600160a01b031663ecef89d56101f2610338565b6040518263ffffffff1660e01b8152600401808260ff16815260200191505060206040518083038186803b15801561022957600080fd5b505afa15801561023d573d6000803e3d6000fd5b505050506040513d602081101561025357600080fd5b5051925050505b90565b3660008037600080366000845af43d6000803e80801561027c573d6000f35b3d6000fd5b61028a81610341565b6102db576040805162461bcd60e51b815260206004820181905260248201527f43616e6e6f742073657420696d706c656d656e746174696f6e20746f20454f41604482015290519081900360640190fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b600160fc1b55565b6000806000835160208501865af4905080156001811461032657610331565b3d806000803e806000fd5b5092915050565b600160fc1b5490565b3b15159056fea2646970667358221220b01e751b5b5a4cced04d4a29df301abad765089b3f62b118e08acda884219e0364736f6c634300070600334f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a65644f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65728be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0a26469706673582212204740ffbb7b132ae4c273f6e74a3c227531b399d36e54020567a920029f80b9ad64736f6c63430007060033
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.