Overview
POL Balance
233.601151697499640232 POL
POL Value
$145.15 (@ $0.62/POL)Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 172 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Disperse | 56508192 | 213 days ago | IN | 0.14343578 POL | 0.00134592 | ||||
Collateralize | 54329915 | 271 days ago | IN | 0.1 POL | 0.01243624 | ||||
Collateralize | 54248201 | 273 days ago | IN | 20 POL | 0.01095327 | ||||
Disperse | 53240282 | 298 days ago | IN | 0.05 POL | 0.00264427 | ||||
Disperse | 53240271 | 298 days ago | IN | 0.05 POL | 0.00267148 | ||||
Disperse | 53240161 | 298 days ago | IN | 0.1 POL | 0.00260108 | ||||
Disperse | 53240155 | 298 days ago | IN | 0.1 POL | 0.00256738 | ||||
Disperse | 50094016 | 380 days ago | IN | 0.1 POL | 0.0019548 | ||||
Disperse | 48698367 | 415 days ago | IN | 0.0008 POL | 0.00293296 | ||||
Collateralize | 47883387 | 436 days ago | IN | 0.01 POL | 0.00696369 | ||||
Collateralize | 44786624 | 514 days ago | IN | 0.01 POL | 0.00801736 | ||||
Disperse | 43645544 | 543 days ago | IN | 0.1 POL | 0.00658689 | ||||
Disperse | 43358585 | 551 days ago | IN | 0.001 POL | 0.00688167 | ||||
Disperse | 43358579 | 551 days ago | IN | 0.001 POL | 0.00705532 | ||||
Disperse | 43274292 | 553 days ago | IN | 0.003 POL | 0.00677068 | ||||
Disperse | 43135303 | 557 days ago | IN | 0.1 POL | 0.00956253 | ||||
Collateralize | 43119749 | 557 days ago | IN | 0.11 POL | 0.01042517 | ||||
Disperse | 43024416 | 559 days ago | IN | 0.1 POL | 0.00782694 | ||||
Collateralize | 42981976 | 561 days ago | IN | 1 POL | 0.01025855 | ||||
Collateralize | 42974806 | 561 days ago | IN | 0.05 POL | 0.01111166 | ||||
Disperse | 42963070 | 561 days ago | IN | 0.001 POL | 0.00749801 | ||||
Collateralize | 42963038 | 561 days ago | IN | 0.001 POL | 0.01042334 | ||||
Collateralize | 42962926 | 561 days ago | IN | 0.001 POL | 0.01016297 | ||||
Collateralize | 42906858 | 562 days ago | IN | 0.02 POL | 0.01728709 | ||||
Collateralize | 42896080 | 563 days ago | IN | 0.01 POL | 0.01102651 |
Loading...
Loading
Contract Name:
EnviousHouse
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
Yes with 1337 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./openzeppelin/token/ERC20/utils/SafeERC20.sol"; import "./openzeppelin/token/ERC20/IERC20.sol"; import "./openzeppelin/token/ERC20/extensions/IERC20Metadata.sol"; import "./openzeppelin/token/ERC721/extensions/IERC721Enumerable.sol"; import "./openzeppelin/utils/Address.sol"; import "./openzeppelin/utils/Context.sol"; import "./interfaces/IEnviousHouse.sol"; import "./interfaces/IERC721Envious.sol"; import "./interfaces/IBondDepository.sol"; import "./interfaces/INoteKeeper.sol"; /** * @title EnviousHouse is contract for any NFT to be collateralized. * * @author F4T50 @ghostchain * @author 571nkY @ghostchain * @author 5Tr3TcH @ghostchain * * @dev The main idea is to maintain any existant ERC721-based token. For any new Envious NFT this smart contract * is optionally needed, only for registration purposes. That's why all Envious functionality is re-routed if * functionality exists and otherwise duplicates it here. * * NOTE: We are using additional key in all mappings. Key is `collection` address. For more in-depth documentation * visit the parent smart contract {ERC721Envious}. */ contract EnviousHouse is Context, IEnviousHouse { using SafeERC20 for IERC20; uint256 private _totalCollections; address private _initializor; uint256 public immutable registerAmount; address private _ghostAddress; address private _ghostBondingAddress; address private _blackHole; mapping(address => uint256[2]) private _commissions; mapping(address => address) private _communityToken; mapping(address => address[]) private _communityPool; mapping(address => mapping(address => uint256)) private _communityBalance; mapping(address => address[]) private _disperseTokens; mapping(address => mapping(address => uint256)) private _disperseBalance; mapping(address => mapping(address => uint256)) private _disperseTotalTaken; mapping(address => mapping(uint256 => mapping(address => uint256))) private _disperseTaken; mapping(address => mapping(uint256 => uint256)) private _bondPayouts; mapping(address => mapping(uint256 => uint256[])) private _bondIndexes; mapping(address => mapping(uint256 => address[])) private _collateralTokens; mapping(address => mapping(uint256 => mapping(address => uint256))) private _collateralBalances; mapping(uint256 => address) public override collections; mapping(address => uint256) public override collectionIds; mapping(address => bool) public override specificCollections; // solhint-disable-next-line string private constant NO_DECIMALS = "no decimals"; // solhint-disable-next-line string private constant LOW_AMOUNT = "low amount"; // solhint-disable-next-line string private constant NOT_TOKEN_OWNER = "not token owner"; // solhint-disable-next-line string private constant INVALID_TOKEN_ID = "invalid tokenId"; // solhint-disable-next-line string private constant EMPTY_GHOST = "ghst address is empty"; // solhint-disable-next-line string private constant LENGTHS_NOT_MATCH = "lengths not match"; // solhint-disable-next-line string private constant ZERO_COMMUNITY_TOKEN = "no community token provided"; // solhint-disable-next-line string private constant COLLECTION_EXISTS = "collection exists"; // solhint-disable-next-line string private constant COLLECTION_NOT_EXISTS = "collection not exists"; // solhint-disable-next-line string private constant INVALID_COLLECTION = "invalid collection address"; // solhint-disable-next-line string private constant NO_TOKENS_MINTED = "no tokens minted"; // solhint-disable-next-line string private constant ALREADY_ENVIOUS = "already envious"; constructor (address blackHoleAddress, uint256 minimalEthAmount) { _initializor = _msgSender(); _blackHole = blackHoleAddress; registerAmount = minimalEthAmount; } function totalCollections() external view override returns (uint256) { return _totalCollections; } function ghostAddress(address collection) external view override returns (address) { if (IERC721(collection).supportsInterface(type(IERC721Envious).interfaceId)) { return IERC721Envious(collection).ghostAddress(); } else { return _ghostAddress; } } function ghostBondingAddress(address collection) external view override returns (address) { if (IERC721(collection).supportsInterface(type(IERC721Envious).interfaceId)) { return IERC721Envious(collection).ghostBondingAddress(); } else { return _ghostBondingAddress; } } function blackHole(address collection) external view override returns (address) { if (IERC721(collection).supportsInterface(type(IERC721Envious).interfaceId)) { return IERC721Envious(collection).blackHole(); } else { return _blackHole; } } function commissions(address collection, uint256 index) external view override returns (uint256) { if (IERC721(collection).supportsInterface(type(IERC721Envious).interfaceId)) { return IERC721Envious(collection).commissions(index); } else { return _commissions[collection][index]; } } function communityToken(address collection) external view override returns (address) { if (IERC721(collection).supportsInterface(type(IERC721Envious).interfaceId)) { return IERC721Envious(collection).communityToken(); } else { return _communityToken[collection]; } } function communityPool(address collection, uint256 index) external view override returns (address) { if (IERC721(collection).supportsInterface(type(IERC721Envious).interfaceId)) { return IERC721Envious(collection).communityPool(index); } else { return _communityPool[collection][index]; } } function communityBalance( address collection, address tokenAddress ) external view override returns (uint256) { if (IERC721(collection).supportsInterface(type(IERC721Envious).interfaceId)) { return IERC721Envious(collection).communityBalance(tokenAddress); } else { return _communityBalance[collection][tokenAddress]; } } function disperseTokens( address collection, uint256 index ) external view override returns (address) { if (IERC721(collection).supportsInterface(type(IERC721Envious).interfaceId)) { return IERC721Envious(collection).disperseTokens(index); } else { return _disperseTokens[collection][index]; } } function disperseBalance( address collection, address tokenAddress ) external view override returns (uint256) { if (IERC721(collection).supportsInterface(type(IERC721Envious).interfaceId)) { return IERC721Envious(collection).disperseBalance(tokenAddress); } else { return _disperseBalance[collection][tokenAddress]; } } function disperseTotalTaken( address collection, address tokenAddress ) external view override returns (uint256) { if (IERC721(collection).supportsInterface(type(IERC721Envious).interfaceId)) { return IERC721Envious(collection).disperseTotalTaken(tokenAddress); } else { return _disperseTotalTaken[collection][tokenAddress]; } } function disperseTaken( address collection, uint256 tokenId, address tokenAddress ) external view override returns (uint256) { if (IERC721(collection).supportsInterface(type(IERC721Envious).interfaceId)) { return IERC721Envious(collection).disperseTaken(tokenId, tokenAddress); } else { return _disperseTaken[collection][tokenId][tokenAddress]; } } function bondPayouts(address collection, uint256 tokenId) external view override returns (uint256) { if (IERC721(collection).supportsInterface(type(IERC721Envious).interfaceId)) { return IERC721Envious(collection).bondPayouts(tokenId); } else { return _bondPayouts[collection][tokenId]; } } function collateralTokens( address collection, uint256 tokenId, uint256 index ) external view override returns (address) { if (IERC721(collection).supportsInterface(type(IERC721Envious).interfaceId)) { return IERC721Envious(collection).collateralTokens(tokenId, index); } else { return _collateralTokens[collection][tokenId][index]; } } function collateralBalances( address collection, uint256 tokenId, address tokenAddress ) external view override returns (uint256) { if (IERC721(collection).supportsInterface(type(IERC721Envious).interfaceId)) { return IERC721Envious(collection).collateralBalances(tokenId, tokenAddress); } else { return _collateralBalances[collection][tokenId][tokenAddress]; } } function bondIndexes( address collection, uint256 tokenId, uint256 index ) external view override returns (uint256) { if (IERC721(collection).supportsInterface(type(IERC721Envious).interfaceId)) { return IERC721Envious(collection).bondIndexes(tokenId, index); } else { return _bondIndexes[collection][tokenId][index]; } } function setGhostAddresses(address ghostToken, address ghostBonding) external override { // solhint-disable-next-line require(_initializor == _msgSender() && ghostToken != address(0) && ghostBonding != address(0)); _ghostAddress = ghostToken; _ghostBondingAddress = ghostBonding; } function setSpecificCollection(address collection) external override { // solhint-disable-next-line require(_initializor == _msgSender() && collection != address(0)); specificCollections[collection] = true; } function registerCollection( address collection, address token, uint256 incoming, uint256 outcoming ) external payable override { require(collectionIds[collection] == 0, COLLECTION_EXISTS); require( IERC721(collection).supportsInterface(type(IERC721).interfaceId) || specificCollections[collection], INVALID_COLLECTION ); _rescueCollection(collection); if (!IERC721(collection).supportsInterface(type(IERC721Envious).interfaceId)) { require(msg.value >= registerAmount, LOW_AMOUNT); if (incoming != 0 || outcoming != 0) { require(token != address(0), ZERO_COMMUNITY_TOKEN); require(incoming < 1e5 && outcoming < 1e5, LOW_AMOUNT); _commissions[collection][0] = incoming; _commissions[collection][1] = outcoming; _communityToken[collection] = token; } _disperseTokenCollateral(collection, msg.value, address(0)); } } function harvest( address collection, uint256[] memory amounts, address[] memory tokenAddresses ) external override { require(collectionIds[collection] != 0, COLLECTION_NOT_EXISTS); require(amounts.length == tokenAddresses.length, LENGTHS_NOT_MATCH); _checkEnvious(collection); for (uint256 i = 0; i < tokenAddresses.length; i++) { _harvest(collection, amounts[i], tokenAddresses[i]); } } function collateralize( address collection, uint256 tokenId, uint256[] memory amounts, address[] memory tokenAddresses ) external payable override { require(amounts.length == tokenAddresses.length, LENGTHS_NOT_MATCH); _checkEnvious(collection); _rescueCollection(collection); uint256 ethAmount = msg.value; for (uint256 i = 0; i < tokenAddresses.length; i++) { if (tokenAddresses[i] == address(0)) { ethAmount -= amounts[i]; } _addTokenCollateral(collection, tokenId, amounts[i], tokenAddresses[i], false); } if (ethAmount > 0) { Address.sendValue(payable(_msgSender()), ethAmount); } } function uncollateralize( address collection, uint256 tokenId, uint256[] memory amounts, address[] memory tokenAddresses ) external override { require(collectionIds[collection] != 0, COLLECTION_NOT_EXISTS); require(amounts.length == tokenAddresses.length, LENGTHS_NOT_MATCH); _checkEnvious(collection); for (uint256 i = 0; i < tokenAddresses.length; i++) { _removeTokenCollateral(collection, tokenId, amounts[i], tokenAddresses[i]); } } function disperse( address collection, uint256[] memory amounts, address[] memory tokenAddresses ) external payable override { require(amounts.length == tokenAddresses.length, LENGTHS_NOT_MATCH); _checkEnvious(collection); _rescueCollection(collection); uint256 ethAmount = msg.value; for (uint256 i = 0; i < tokenAddresses.length; i++) { if (tokenAddresses[i] == address(0)) { ethAmount -= amounts[i]; } _disperseTokenCollateral(collection, amounts[i], tokenAddresses[i]); } if (ethAmount > 0) { Address.sendValue(payable(_msgSender()), ethAmount); } } function getDiscountedCollateral( address collection, uint256 bondId, address quoteToken, uint256 tokenId, uint256 amount, uint256 maxPrice ) external override { require(collectionIds[collection] != 0, COLLECTION_NOT_EXISTS); _checkEnvious(collection); _rescueCollection(collection); // NOTE: this contract is temporary holder of `quoteToken` due to the need of // registration of bond inside. `amount` of `quoteToken`s should be empty in // the end of transaction. IERC20(quoteToken).safeTransferFrom(_msgSender(), address(this), amount); IERC20(quoteToken).safeApprove(_ghostBondingAddress, amount); (uint256 payout,, uint256 index) = IBondDepository(_ghostBondingAddress).deposit( bondId, amount, maxPrice, address(this), address(this) ); if (payout > 0) { _bondPayouts[collection][tokenId] += payout; _bondIndexes[collection][tokenId].push(index); } } function claimDiscountedCollateral( address collection, uint256 tokenId, uint256[] memory indexes ) external override { require(collectionIds[collection] != 0, COLLECTION_NOT_EXISTS); require(_ghostAddress != address(0), EMPTY_GHOST); _checkEnvious(collection); for (uint256 i = 0; i < indexes.length; i++) { uint256 index = _arrayContains(indexes[i], _bondIndexes[collection][tokenId]); uint256 last = _bondIndexes[collection][tokenId].length - 1; _bondIndexes[collection][tokenId][index] = _bondIndexes[collection][tokenId][last]; _bondIndexes[collection][tokenId].pop(); } uint256 payout = INoteKeeper(_ghostBondingAddress).redeem(address(this), indexes, true); if (payout > 0) { _bondPayouts[collection][tokenId] -= payout; _addTokenCollateral(collection, tokenId, payout, _ghostAddress, true); } } function getAmount( address collection, uint256 amount, address tokenAddress ) public view override returns (uint256) { require(collectionIds[collection] != 0, COLLECTION_NOT_EXISTS); if (IERC721(collection).supportsInterface(type(IERC721Envious).interfaceId)) { return IERC721Envious(collection).getAmount(amount, tokenAddress); } else { uint256 circulatingSupply = IERC20(_communityToken[collection]).totalSupply() - IERC20(_communityToken[collection]).balanceOf(_blackHole); return amount * _scaledAmount(collection, tokenAddress) / circulatingSupply; } } function _arrayContains( address tokenAddress, address[] memory findFrom ) private pure returns (bool shouldAppend, uint256 index) { shouldAppend = true; index = type(uint256).max; for (uint256 i = 0; i < findFrom.length; i++) { if (findFrom[i] == tokenAddress) { shouldAppend = false; index = i; break; } } } function _arrayContains( uint256 noteId, uint256[] memory findFrom ) private pure returns (uint256 index) { index = type(uint256).max; for (uint256 i = 0; i < findFrom.length; i++) { if (findFrom[i] == noteId) { index = i; break; } } } function _scaledAmount(address collection, address tokenAddress) private view returns (uint256) { uint256 totalValue = 0; uint256 scaled = 0; uint256 defaultDecimals = 10**IERC20Metadata(_communityToken[collection]).decimals(); for (uint256 i = 0; i < _communityPool[collection].length; i++) { uint256 innerDecimals = _communityPool[collection][i] == address(0) ? 10**18 : 10**IERC20Metadata(_communityPool[collection][i]).decimals(); uint256 tempValue = _communityBalance[collection][_communityPool[collection][i]] * defaultDecimals / innerDecimals; totalValue += tempValue; if (_communityPool[collection][i] == tokenAddress) { scaled = tempValue; } } return _communityBalance[collection][tokenAddress] * totalValue / scaled; } function _harvest(address collection, uint256 amount, address tokenAddress) private { uint256 scaledAmount = getAmount(collection, amount, tokenAddress); _communityBalance[collection][tokenAddress] -= scaledAmount; if (_communityBalance[collection][tokenAddress] == 0) { (, uint256 index) = _arrayContains(tokenAddress, _communityPool[collection]); _communityPool[collection][index] = _communityPool[collection][_communityPool[collection].length - 1]; _communityPool[collection].pop(); } if (tokenAddress == address(0)) { Address.sendValue(payable(_msgSender()), scaledAmount); } else { IERC20(tokenAddress).safeTransfer(_msgSender(), scaledAmount); } // NOTE: not every token implements `burn` function, so that is a littl cheat IERC20(_communityToken[collection]).safeTransferFrom(_msgSender(), _blackHole, amount); emit Harvested(collection, tokenAddress, amount, scaledAmount); } function _addTokenCollateral( address collection, uint256 tokenId, uint256 amount, address tokenAddress, bool claim ) private { require(amount > 0, LOW_AMOUNT); require(IERC721(collection).ownerOf(tokenId) != address(0), INVALID_TOKEN_ID); _disperse(collection, tokenAddress, tokenId); (bool shouldAppend,) = _arrayContains(tokenAddress, _collateralTokens[collection][tokenId]); if (shouldAppend) { _checkValidity(tokenAddress); _collateralTokens[collection][tokenId].push(tokenAddress); } uint256 ownerBalance = _communityCommission(collection, amount, _commissions[collection][0], tokenAddress); _collateralBalances[collection][tokenId][tokenAddress] += ownerBalance; if (tokenAddress != address(0) && !claim) { IERC20(tokenAddress).safeTransferFrom(_msgSender(), address(this), amount); } emit Collateralized(collection, tokenId, amount, tokenAddress); } function _removeTokenCollateral( address collection, uint256 tokenId, uint256 amount, address tokenAddress ) private { require(IERC721(collection).ownerOf(tokenId) == _msgSender(), NOT_TOKEN_OWNER); _disperse(collection, tokenAddress, tokenId); _collateralBalances[collection][tokenId][tokenAddress] -= amount; if (_collateralBalances[collection][tokenId][tokenAddress] == 0) { (, uint256 index) = _arrayContains(tokenAddress, _collateralTokens[collection][tokenId]); _collateralTokens[collection][tokenId][index] = _collateralTokens[collection][tokenId][_collateralTokens[collection][tokenId].length - 1]; _collateralTokens[collection][tokenId].pop(); } uint256 ownerBalance = _communityCommission(collection, amount, _commissions[collection][1], tokenAddress); if (tokenAddress == address(0)) { Address.sendValue(payable(_msgSender()), ownerBalance); } else { IERC20(tokenAddress).safeTransfer(_msgSender(), ownerBalance); } emit Uncollateralized(collection, tokenId, ownerBalance, tokenAddress); } function _disperseTokenCollateral( address collection, uint256 amount, address tokenAddress ) private { require(amount > 0, LOW_AMOUNT); (bool shouldAppend,) = _arrayContains(tokenAddress, _disperseTokens[collection]); if (shouldAppend) { _checkValidity(tokenAddress); _disperseTokens[collection].push(tokenAddress); } _disperseBalance[collection][tokenAddress] += amount; if (tokenAddress != address(0)) { IERC20(tokenAddress).safeTransferFrom(_msgSender(), address(this), amount); } emit Dispersed(collection, tokenAddress, amount); } function _checkValidity(address tokenAddress) private view { if (tokenAddress != address(0)) { require(IERC20Metadata(tokenAddress).decimals() != type(uint8).max, NO_DECIMALS); } } function _communityCommission( address collection, uint256 amount, uint256 percentage, address tokenAddress ) private returns (uint256) { uint256 donation = amount * percentage / 1e5; (bool shouldAppend,) = _arrayContains(tokenAddress, _communityPool[collection]); if (shouldAppend && donation > 0) { _communityPool[collection].push(tokenAddress); } _communityBalance[collection][tokenAddress] += donation; return amount - donation; } function _disperse(address collection, address tokenAddress, uint256 tokenId) private { uint256 balance = _disperseBalance[collection][tokenAddress] / IERC721Enumerable(collection).totalSupply(); if (_disperseTotalTaken[collection][tokenAddress] + balance > _disperseBalance[collection][tokenAddress]) { balance = _disperseBalance[collection][tokenAddress] - _disperseTotalTaken[collection][tokenAddress]; } if (balance > _disperseTaken[collection][tokenId][tokenAddress]) { uint256 amount = balance - _disperseTaken[collection][tokenId][tokenAddress]; _disperseTaken[collection][tokenId][tokenAddress] += amount; (bool shouldAppend,) = _arrayContains(tokenAddress, _collateralTokens[collection][tokenId]); if (shouldAppend) { _collateralTokens[collection][tokenId].push(tokenAddress); } _collateralBalances[collection][tokenId][tokenAddress] += amount; _disperseTotalTaken[collection][tokenAddress] += amount; } } function _rescueCollection(address collection) private { if (collectionIds[collection] == 0) { require(IERC721Enumerable(collection).totalSupply() > 0, NO_TOKENS_MINTED); _totalCollections += 1; collections[_totalCollections] = collection; collectionIds[collection] = _totalCollections; } } function _checkEnvious(address collection) private view { if (IERC721(collection).supportsInterface(type(IERC721Envious).interfaceId)) { revert(ALREADY_ENVIOUS); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @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 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 Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 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://consensys.net/diligence/blog/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"); (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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.0; interface INoteKeeper { // Info for market note struct Note { uint256 payout; // gOHM remaining to be paid uint48 created; // time market was created uint48 matured; // timestamp when market is matured uint48 redeemed; // time market was redeemed uint48 marketID; // market ID of deposit. uint48 to avoid adding a slot. } function redeem(address _user, uint256[] memory _indexes, bool _sendgOHM) external returns (uint256); function redeemAll(address _user, bool _sendgOHM) external returns (uint256); function pushNote(address to, uint256 index) external; function pullNote(address from, uint256 index) external returns (uint256 newIndex_); function indexesFor(address _user) external view returns (uint256[] memory); function pendingFor(address _user, uint256 _index) external view returns (uint256 payout_, bool matured_); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IEnviousHouse { event Collateralized( address indexed collection, uint256 indexed tokenId, uint256 amount, address tokenAddress ); event Uncollateralized( address indexed collection, uint256 indexed tokenId, uint256 amount, address tokenAddress ); event Dispersed( address indexed collection, address indexed tokenAddress, uint256 amount ); event Harvested( address indexed collection, address indexed tokenAddress, uint256 amount, uint256 scaledAmount ); function totalCollections() external view returns (uint256); function ghostAddress(address collection) external view returns (address); function ghostBondingAddress(address collection) external view returns (address); function blackHole(address collection) external view returns (address); function collections(uint256 index) external view returns (address); function collectionIds(address collection) external view returns (uint256); function specificCollections(address collection) external view returns (bool); function commissions(address collection, uint256 index) external view returns (uint256); function communityToken(address collection) external view returns (address); function communityPool(address collection, uint256 index) external view returns (address); function communityBalance(address collection, address tokenAddress) external view returns (uint256); function disperseTokens(address collection, uint256 index) external view returns (address); function disperseBalance(address collection, address tokenAdddress) external view returns (uint256); function disperseTotalTaken(address collection, address tokenAddress) external view returns (uint256); function disperseTaken(address collection, uint256 tokenId, address tokenAddress) external view returns (uint256); function bondPayouts(address collection, uint256 bondId) external view returns (uint256); function bondIndexes(address collection, uint256 tokenId, uint256 index) external view returns (uint256); function collateralTokens(address collection, uint256 tokenId, uint256 index) external view returns (address); function collateralBalances(address collection, uint256 tokenId, address tokenAddress) external view returns (uint256); function getAmount(address collection, uint256 amount, address tokenAddress) external view returns (uint256); function setGhostAddresses(address ghostToken, address ghostBonding) external; function setSpecificCollection(address collection) external; function registerCollection( address collection, address token, uint256 incoming, uint256 outcoming ) external payable; function harvest( address collection, uint256[] memory amounts, address[] memory tokenAddresses ) external; function collateralize( address collection, uint256 tokenId, uint256[] memory amounts, address[] memory tokenAddresses ) external payable; function uncollateralize( address collection, uint256 tokenId, uint256[] memory amounts, address[] memory tokenAddresses ) external; function getDiscountedCollateral( address collection, uint256 bondId, address quoteToken, uint256 tokenId, uint256 amount, uint256 maxPrice ) external; function claimDiscountedCollateral( address collection, uint256 tokenId, uint256[] memory indexes ) external; function disperse( address collection, uint256[] memory amounts, address[] memory tokenAddresses ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../openzeppelin/token/ERC721/IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional Envious extension. * @author F4T50 @ghostchain * @author 571nkY @ghostchain * @author 5Tr3TcH @ghostchain * @dev Ability to collateralize each NFT in collection. */ interface IERC721Envious is IERC721 { event Collateralized(uint256 indexed tokenId, uint256 amount, address tokenAddress); event Uncollateralized(uint256 indexed tokenId, uint256 amount, address tokenAddress); event Dispersed(address indexed tokenAddress, uint256 amount); event Harvested(address indexed tokenAddress, uint256 amount, uint256 scaledAmount); /** * @dev An array with two elements. Each of them represents percentage from collateral * to be taken as a commission. First element represents collateralization commission. * Second element represents uncollateralization commission. There should be 3 * decimal buffer for each of them, e.g. 1000 = 1%. * * @param index of value in array. */ function commissions(uint256 index) external view returns (uint256); /** * @dev Address of token that will be paid on bonds. * * @return address address of token. */ function ghostAddress() external view returns (address); /** * @dev Address of smart contract, that provides purchasing of DeFi 2.0 bonds. * * @return address address of bonding smart. */ function ghostBondingAddress() external view returns (address); /** * @dev 'Black hole' is any address that guarantee tokens sent to it will not be * retrieved from there. Note: some tokens revert on transfer to zero address. * * @return address address of black hole. */ function blackHole() external view returns (address); /** * @dev Token that will be used to harvest collected commissions. * * @return address address of token. */ function communityToken() external view returns (address); /** * @dev Pool of available tokens for harvesting. * * @param index in array. * @return address of token. */ function communityPool(uint256 index) external view returns (address); /** * @dev Token balance available for harvesting. * * @param tokenAddress addres of token. * @return uint256 token balance. */ function communityBalance(address tokenAddress) external view returns (uint256); /** * @dev Array of tokens that were dispersed. * * @param index in array. * @return address address of dispersed token. */ function disperseTokens(uint256 index) external view returns (address); /** * @dev Amount of tokens that was dispersed. * * @param tokenAddress address of token. * @return uint256 token balance. */ function disperseBalance(address tokenAddress) external view returns (uint256); /** * @dev Amount of tokens that was already taken from the disperse. * * @param tokenAddress address of token. * @return uint256 total amount of tokens already taken. */ function disperseTotalTaken(address tokenAddress) external view returns (uint256); /** * @dev Amount of disperse already taken by each tokenId. * * @param tokenId unique identifier of unit. * @param tokenAddress address of token. * @return uint256 amount of tokens already taken. */ function disperseTaken(uint256 tokenId, address tokenAddress) external view returns (uint256); /** * @dev Available payouts. * * @param bondId bond unique identifier. * @return uint256 potential payout. */ function bondPayouts(uint256 bondId) external view returns (uint256); /** * @dev Mapping of `tokenId`s to array of bonds. * * @param tokenId unique identifier of unit. * @param index in array. * @return uint256 index of bond. */ function bondIndexes(uint256 tokenId, uint256 index) external view returns (uint256); /** * @dev Mapping of `tokenId`s to token addresses who have collateralized before. * * @param tokenId unique identifier of unit. * @param index in array. * @return address address of token. */ function collateralTokens(uint256 tokenId, uint256 index) external view returns (address); /** * @dev Token balances that are stored under `tokenId`. * * @param tokenId unique identifier of unit. * @param tokenAddress address of token. * @return uint256 token balance. */ function collateralBalances(uint256 tokenId, address tokenAddress) external view returns (uint256); /** * @dev Calculator function for harvesting. * * @param amount of `communityToken`s to spend * @param tokenAddress of token to be harvested * @return amount to harvest based on inputs */ function getAmount(uint256 amount, address tokenAddress) external view returns (uint256); /** * @dev Collect commission fees gathered in exchange for `communityToken`. * * @param amounts array of amounts to collateralize * @param tokenAddresses array of token addresses */ function harvest(uint256[] memory amounts, address[] memory tokenAddresses) external; /** * @dev Collateralize NFT with different tokens and amounts. * * @param tokenId unique identifier for specific NFT * @param amounts array of amounts to collateralize * @param tokenAddresses array of token addresses */ function collateralize( uint256 tokenId, uint256[] memory amounts, address[] memory tokenAddresses ) external payable; /** * @dev Withdraw underlying collateral. * * Requirements: * - only owner of NFT * * @param tokenId unique identifier for specific NFT * @param amounts array of amounts to collateralize * @param tokenAddresses array of token addresses */ function uncollateralize( uint256 tokenId, uint256[] memory amounts, address[] memory tokenAddresses ) external; /** * @dev Collateralize NFT with discount, based on available bonds. While * purchased bond will have delay the owner will be current smart contract * * @param bondId the ID of the market * @param tokenId unique identifier of NFT inside current smart contract * @param amount the amount of quote token to spend * @param maxPrice the maximum price at which to buy bond */ function getDiscountedCollateral( uint256 bondId, address quoteToken, uint256 tokenId, uint256 amount, uint256 maxPrice ) external; /** * @dev Claim collateral inside this smart contract and extending underlying * data mappings. * * @param tokenId unique identifier of NFT inside current smart contract * @param indexes array of note indexes to redeem */ function claimDiscountedCollateral(uint256 tokenId, uint256[] memory indexes) external; /** * @dev Split collateral among all existent tokens. * * @param amounts to be dispersed among all NFT owners * @param tokenAddresses of token to be dispersed */ function disperse(uint256[] memory amounts, address[] memory tokenAddresses) external payable; /** * @dev See {IERC721-_mint} */ function mint(address who) external; }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.0; import "../openzeppelin/token/ERC20/IERC20.sol"; interface IBondDepository { event CreateMarket( uint256 indexed id, address indexed baseToken, address indexed quoteToken, uint256 initialPrice ); event CloseMarket(uint256 indexed id); event Bond( uint256 indexed id, uint256 amount, uint256 price ); event Tuned( uint256 indexed id, uint64 oldControlVariable, uint64 newControlVariable ); // Info about each type of market struct Market { uint256 capacity; // capacity remaining IERC20 quoteToken; // token to accept as payment bool capacityInQuote; // capacity limit is in payment token (true) or in STRL (false, default) uint64 totalDebt; // total debt from market uint64 maxPayout; // max tokens in/out (determined by capacityInQuote false/true) uint64 sold; // base tokens out uint256 purchased; // quote tokens in } // Info for creating new markets struct Terms { bool fixedTerm; // fixed term or fixed expiration uint64 controlVariable; // scaling variable for price uint48 vesting; // length of time from deposit to maturity if fixed-term uint48 conclusion; // timestamp when market no longer offered (doubles as time when market matures if fixed-expiry) uint64 maxDebt; // 9 decimal debt maximum in STRL } // Additional info about market. struct Metadata { uint48 lastTune; // last timestamp when control variable was tuned uint48 lastDecay; // last timestamp when market was created and debt was decayed uint48 length; // time from creation to conclusion. used as speed to decay debt. uint48 depositInterval; // target frequency of deposits uint48 tuneInterval; // frequency of tuning uint8 quoteDecimals; // decimals of quote token } // Control variable adjustment data struct Adjustment { uint64 change; // adjustment for price scaling variable uint48 lastAdjustment; // time of last adjustment uint48 timeToAdjusted; // time after which adjustment should happen bool active; // if adjustment is available } function deposit( uint256 _bid, // the ID of the market uint256 _amount, // the amount of quote token to spend uint256 _maxPrice, // the maximum price at which to buy address _user, // the recipient of the payout address _referral // the operator address ) external returns (uint256 payout_, uint256 expiry_, uint256 index_); function create ( IERC20 _quoteToken, // token used to deposit uint256[3] memory _market, // [capacity, initial price] bool[2] memory _booleans, // [capacity in quote, fixed term] uint256[2] memory _terms, // [vesting, conclusion] uint32[2] memory _intervals // [deposit interval, tune interval] ) external returns (uint256 id_); function close(uint256 _id) external; function isLive(uint256 _bid) external view returns (bool); function liveMarkets() external view returns (uint256[] memory); function liveMarketsFor(address _quoteToken) external view returns (uint256[] memory); function payoutFor(uint256 _amount, uint256 _bid) external view returns (uint256); function marketPrice(uint256 _bid) external view returns (uint256); function currentDebt(uint256 _bid) external view returns (uint256); function debtRatio(uint256 _bid) external view returns (uint256); function debtDecay(uint256 _bid) external view returns (uint64); }
{ "remappings": [], "optimizer": { "enabled": true, "runs": 1337 }, "evmVersion": "berlin", "libraries": {}, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"blackHoleAddress","type":"address"},{"internalType":"uint256","name":"minimalEthAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"}],"name":"Collateralized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Dispersed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"scaledAmount","type":"uint256"}],"name":"Harvested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"}],"name":"Uncollateralized","type":"event"},{"inputs":[{"internalType":"address","name":"collection","type":"address"}],"name":"blackHole","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"bondIndexes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"bondPayouts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256[]","name":"indexes","type":"uint256[]"}],"name":"claimDiscountedCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"collateralBalances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"collateralTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"address[]","name":"tokenAddresses","type":"address[]"}],"name":"collateralize","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"collectionIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"collections","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"commissions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"communityBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"communityPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"}],"name":"communityToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"address[]","name":"tokenAddresses","type":"address[]"}],"name":"disperse","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"disperseBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"disperseTaken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"disperseTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"disperseTotalTaken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"getAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"bondId","type":"uint256"},{"internalType":"address","name":"quoteToken","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"}],"name":"getDiscountedCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"}],"name":"ghostAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"}],"name":"ghostBondingAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"address[]","name":"tokenAddresses","type":"address[]"}],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"registerAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"incoming","type":"uint256"},{"internalType":"uint256","name":"outcoming","type":"uint256"}],"name":"registerCollection","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"ghostToken","type":"address"},{"internalType":"address","name":"ghostBonding","type":"address"}],"name":"setGhostAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"}],"name":"setSpecificCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"specificCollections","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalCollections","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"address[]","name":"tokenAddresses","type":"address[]"}],"name":"uncollateralize","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b5060405162004c5438038062004c5483398101604081905262000034916200006c565b600180546001600160a01b03199081163317909155600480549091166001600160a01b039390931692909217909155608052620000a6565b600080604083850312156200007f578182fd5b82516001600160a01b038116811462000096578283fd5b6020939093015192949293505050565b608051614b8b620000c9600039600081816104ac0152610bd20152614b8b6000f3fe6080604052600436106101cd5760003560e01c80637158bf6d116100f7578063928962f411610095578063efda37e611610064578063efda37e61461054e578063f4c0ee001461056e578063fcf826951461058e578063fdbda0ec146105ae57600080fd5b8063928962f41461049a578063bdc9e93f146104ce578063d204819a146104ee578063d794565c1461050e57600080fd5b80638c9d7c7a116100d15780638c9d7c7a146104275780638ec52cca1461043a5780638fabac4f1461045a5780638fdc2f761461047a57600080fd5b80637158bf6d146103ba578063775f131a146103da578063895587d5146103fa57600080fd5b80633e9b9ccf1161016f57806352cc4b4d1161013e57806352cc4b4d14610352578063554db8581461036557806361d9db2d146103855780636f94fa691461039a57600080fd5b80633e9b9ccf146102d25780633f06068e146102f25780634e2515931461031257806350ef4a021461033257600080fd5b80631f817a1e116101ab5780631f817a1e146102455780632239ceb61461025a5780633db225b81461027a5780633dde3e051461029a57600080fd5b80630ea4d5c6146101d257806314110286146102055780631e7b3a3c14610225575b600080fd5b3480156101de57600080fd5b506101f26101ed36600461463c565b6105e4565b6040519081526020015b60405180910390f35b34801561021157600080fd5b506101f2610220366004614611565b610742565b34801561023157600080fd5b506101f2610240366004614521565b6108a3565b610258610253366004614559565b61099c565b005b34801561026657600080fd5b506101f261027536600461463c565b610d2a565b34801561028657600080fd5b506101f261029536600461463c565b610e32565b3480156102a657600080fd5b506102ba6102b53660046144e9565b6110f2565b6040516001600160a01b0390911681526020016101fc565b3480156102de57600080fd5b506102586102ed366004614725565b611208565b3480156102fe57600080fd5b506101f261030d366004614521565b61134d565b34801561031e57600080fd5b506101f261032d366004614611565b611446565b34801561033e57600080fd5b506102ba61034d3660046147a2565b61153c565b610258610360366004614725565b6116b9565b34801561037157600080fd5b506102586103803660046144e9565b61181e565b34801561039157600080fd5b506000546101f2565b3480156103a657600080fd5b506102ba6103b5366004614611565b61186d565b3480156103c657600080fd5b506102586103d53660046146d8565b6119d9565b3480156103e657600080fd5b506101f26103f5366004614521565b611d98565b34801561040657600080fd5b506101f26104153660046144e9565b60126020526000908152604090205481565b61025861043536600461459e565b611e91565b34801561044657600080fd5b506102ba6104553660046144e9565b611ff1565b34801561046657600080fd5b5061025861047536600461459e565b6120c1565b34801561048657600080fd5b506102ba610495366004614611565b6121fe565b3480156104a657600080fd5b506101f27f000000000000000000000000000000000000000000000000000000000000000081565b3480156104da57600080fd5b506102ba6104e93660046144e9565b612302565b3480156104fa57600080fd5b5061025861050936600461467d565b6123d2565b34801561051a57600080fd5b5061053e6105293660046144e9565b60136020526000908152604090205460ff1681565b60405190151581526020016101fc565b34801561055a57600080fd5b506102ba6105693660046144e9565b6125bd565b34801561057a57600080fd5b506101f26105893660046147a2565b61268d565b34801561059a57600080fd5b506102586105a9366004614521565b6127b5565b3480156105ba57600080fd5b506102ba6105c93660046147f6565b6011602052600090815260409020546001600160a01b031681565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038516906301ffc9a79060240160206040518083038186803b15801561062d57600080fd5b505afa158015610641573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066591906147d6565b1561070b576040517f7ceb5fa5000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b038381166024830152851690637ceb5fa5906044015b60206040518083038186803b1580156106cc57600080fd5b505afa1580156106e0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610704919061480e565b905061073b565b506001600160a01b038084166000908152600c602090815260408083208684528252808320938516835292905220545b9392505050565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038416906301ffc9a79060240160206040518083038186803b15801561078b57600080fd5b505afa15801561079f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c391906147d6565b15610861576040517f22b3a7c8000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b038416906322b3a7c8906024015b60206040518083038186803b15801561082257600080fd5b505afa158015610836573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085a919061480e565b905061089d565b6001600160a01b0383166000908152600560205260409020826002811061089857634e487b7160e01b600052603260045260246000fd5b015490505b92915050565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038416906301ffc9a79060240160206040518083038186803b1580156108ec57600080fd5b505afa158015610900573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092491906147d6565b15610970576040517fd0068b510000000000000000000000000000000000000000000000000000000081526001600160a01b03838116600483015284169063d0068b519060240161080a565b506001600160a01b0380831660009081526008602090815260408083209385168352929052205461089d565b6001600160a01b038416600090815260126020908152604091829020548251808401909352601183527f636f6c6c656374696f6e206578697374730000000000000000000000000000009183019190915215610a145760405162461bcd60e51b8152600401610a0b91906148f1565b60405180910390fd5b506040516301ffc9a760e01b81527f80ac58cd0000000000000000000000000000000000000000000000000000000060048201526001600160a01b038516906301ffc9a79060240160206040518083038186803b158015610a7457600080fd5b505afa158015610a88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aac91906147d6565b80610acf57506001600160a01b03841660009081526013602052604090205460ff165b6040518060400160405280601a81526020017f696e76616c696420636f6c6c656374696f6e206164647265737300000000000081525090610b235760405162461bcd60e51b8152600401610a0b91906148f1565b50610b2d84612822565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526001600160a01b038516906301ffc9a79060240160206040518083038186803b158015610b7357600080fd5b505afa158015610b87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bab91906147d6565b610d245760408051808201909152600a8152691b1bddc8185b5bdd5b9d60b21b60208201527f0000000000000000000000000000000000000000000000000000000000000000341015610c115760405162461bcd60e51b8152600401610a0b91906148f1565b5081151580610c1f57508015155b15610d185760408051808201909152601b81527f6e6f20636f6d6d756e69747920746f6b656e2070726f7669646564000000000060208201526001600160a01b038416610c7f5760405162461bcd60e51b8152600401610a0b91906148f1565b50620186a082108015610c945750620186a081105b6040518060400160405280600a8152602001691b1bddc8185b5bdd5b9d60b21b81525090610cd55760405162461bcd60e51b8152600401610a0b91906148f1565b506001600160a01b0384811660009081526005602090815260408083208681556001018590556006909152902080546001600160a01b0319169185169190911790555b610d248434600061295f565b50505050565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038516906301ffc9a79060240160206040518083038186803b158015610d7357600080fd5b505afa158015610d87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dab91906147d6565b15610dfe576040517f9bef3546000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b038381166024830152851690639bef3546906044016106b4565b506001600160a01b03808416600090815260106020908152604080832086845282528083209385168352929052205461073b565b6001600160a01b0383166000908152601260209081526040808320548151808301909252601582527f636f6c6c656374696f6e206e6f742065786973747300000000000000000000009282019290925290610ea05760405162461bcd60e51b8152600401610a0b91906148f1565b506040516301ffc9a760e01b8152636dbcb1a160e11b60048201526001600160a01b038516906301ffc9a79060240160206040518083038186803b158015610ee757600080fd5b505afa158015610efb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f1f91906147d6565b15610f72576040517f42da3b6b000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b0383811660248301528516906342da3b6b906044016106b4565b6001600160a01b03848116600090815260066020526040808220546004805492517f70a0823100000000000000000000000000000000000000000000000000000000815292851690830152919291909116906370a082319060240160206040518083038186803b158015610fe557600080fd5b505afa158015610ff9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061101d919061480e565b6001600160a01b038087166000908152600660209081526040918290205482517f18160ddd00000000000000000000000000000000000000000000000000000000815292519316926318160ddd926004808201939291829003018186803b15801561108757600080fd5b505afa15801561109b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110bf919061480e565b6110c99190614ab6565b9050806110d68685612b1b565b6110e09086614a97565b6110ea9190614991565b91505061073b565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038316906301ffc9a79060240160206040518083038186803b15801561113b57600080fd5b505afa15801561114f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117391906147d6565b156111e957816001600160a01b03166329aa16176040518163ffffffff1660e01b815260040160206040518083038186803b1580156111b157600080fd5b505afa1580156111c5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061089d9190614505565b506001600160a01b039081166000908152600660205260409020541690565b6001600160a01b038416600090815260126020908152604091829020548251808401909352601583527f636f6c6c656374696f6e206e6f74206578697374730000000000000000000000918301919091526112765760405162461bcd60e51b8152600401610a0b91906148f1565b508051825114604051806040016040528060118152602001700d8cadccee8d0e640dcdee840dac2e8c6d607b1b815250906112c45760405162461bcd60e51b8152600401610a0b91906148f1565b506112ce84612e55565b60005b81518110156113465761133485858584815181106112ff57634e487b7160e01b600052603260045260246000fd5b602002602001015185858151811061132757634e487b7160e01b600052603260045260246000fd5b6020026020010151612f23565b8061133e81614af9565b9150506112d1565b5050505050565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038416906301ffc9a79060240160206040518083038186803b15801561139657600080fd5b505afa1580156113aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ce91906147d6565b1561141a576040517fca5dd0cb0000000000000000000000000000000000000000000000000000000081526001600160a01b03838116600483015284169063ca5dd0cb9060240161080a565b506001600160a01b038083166000908152600a602090815260408083209385168352929052205461089d565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038416906301ffc9a79060240160206040518083038186803b15801561148f57600080fd5b505afa1580156114a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c791906147d6565b15611512576040517ff7408b53000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b0384169063f7408b539060240161080a565b506001600160a01b0382166000908152600d6020908152604080832084845290915290205461089d565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038516906301ffc9a79060240160206040518083038186803b15801561158557600080fd5b505afa158015611599573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115bd91906147d6565b1561165a576040517f885c46a800000000000000000000000000000000000000000000000000000000815260048101849052602481018390526001600160a01b0385169063885c46a89060440160206040518083038186803b15801561162257600080fd5b505afa158015611636573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107049190614505565b6001600160a01b0384166000908152600f60209081526040808320868452909152902080548390811061169d57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b0316905061073b565b8051825114604051806040016040528060118152602001700d8cadccee8d0e640dcdee840dac2e8c6d607b1b815250906117065760405162461bcd60e51b8152600401610a0b91906148f1565b5061171084612e55565b61171984612822565b3460005b825181101561180c5760006001600160a01b031683828151811061175157634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b0316141561179e5783818151811061178857634e487b7160e01b600052603260045260246000fd5b60200260200101518261179b9190614ab6565b91505b6117fa86868684815181106117c357634e487b7160e01b600052603260045260246000fd5b60200260200101518685815181106117eb57634e487b7160e01b600052603260045260246000fd5b602002602001015160006132d1565b8061180481614af9565b91505061171d565b50801561134657611346335b826135bf565b6001546001600160a01b03163314801561184057506001600160a01b03811615155b61184957600080fd5b6001600160a01b03166000908152601360205260409020805460ff19166001179055565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038416906301ffc9a79060240160206040518083038186803b1580156118b657600080fd5b505afa1580156118ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ee91906147d6565b15611985576040517f9b905f5a000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b03841690639b905f5a906024015b60206040518083038186803b15801561194d57600080fd5b505afa158015611961573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085a9190614505565b6001600160a01b03831660009081526007602052604090208054839081106119bd57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b0316905061089d565b6001600160a01b038316600090815260126020908152604091829020548251808401909352601583527f636f6c6c656374696f6e206e6f7420657869737473000000000000000000000091830191909152611a475760405162461bcd60e51b8152600401610a0b91906148f1565b5060025460408051808201909152601581527f67687374206164647265737320697320656d70747900000000000000000000006020820152906001600160a01b0316611aa65760405162461bcd60e51b8152600401610a0b91906148f1565b50611ab083612e55565b60005b8151811015611c99576000611b5e838381518110611ae157634e487b7160e01b600052603260045260246000fd5b6020908102919091018101516001600160a01b0388166000908152600e835260408082208983528452908190208054825181860281018601909352808352929391929091830182828015611b5457602002820191906000526020600020905b815481526020019060010190808311611b40575b50505050506136dd565b6001600160a01b0386166000908152600e6020908152604080832088845290915281205491925090611b9290600190614ab6565b6001600160a01b0387166000908152600e60209081526040808320898452909152902080549192509082908110611bd957634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b0389168352600e825260408084208985529092529120805484908110611c2457634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101929092556001600160a01b0388168152600e8252604080822088835290925220805480611c6e57634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905550508080611c9190614af9565b915050611ab3565b506003546040517fd62fbdd30000000000000000000000000000000000000000000000000000000081526000916001600160a01b03169063d62fbdd390611ce99030908690600190600401614890565b602060405180830381600087803b158015611d0357600080fd5b505af1158015611d17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d3b919061480e565b90508015610d24576001600160a01b0384166000908152600d6020908152604080832086845290915281208054839290611d76908490614ab6565b9091555050600254610d24908590859084906001600160a01b031660016132d1565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038416906301ffc9a79060240160206040518083038186803b158015611de157600080fd5b505afa158015611df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1991906147d6565b15611e65576040517f8fc3f5610000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152841690638fc3f5619060240161080a565b506001600160a01b038083166000908152600b602090815260408083209385168352929052205461089d565b8051825114604051806040016040528060118152602001700d8cadccee8d0e640dcdee840dac2e8c6d607b1b81525090611ede5760405162461bcd60e51b8152600401610a0b91906148f1565b50611ee883612e55565b611ef183612822565b3460005b8251811015611fe15760006001600160a01b0316838281518110611f2957634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03161415611f7657838181518110611f6057634e487b7160e01b600052603260045260246000fd5b602002602001015182611f739190614ab6565b91505b611fcf85858381518110611f9a57634e487b7160e01b600052603260045260246000fd5b6020026020010151858481518110611fc257634e487b7160e01b600052603260045260246000fd5b602002602001015161295f565b80611fd981614af9565b915050611ef5565b508015610d2457610d2433611818565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038316906301ffc9a79060240160206040518083038186803b15801561203a57600080fd5b505afa15801561204e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207291906147d6565b156120b057816001600160a01b0316635d5892376040518163ffffffff1660e01b815260040160206040518083038186803b1580156111b157600080fd5b50506003546001600160a01b031690565b6001600160a01b038316600090815260126020908152604091829020548251808401909352601583527f636f6c6c656374696f6e206e6f742065786973747300000000000000000000009183019190915261212f5760405162461bcd60e51b8152600401610a0b91906148f1565b508051825114604051806040016040528060118152602001700d8cadccee8d0e640dcdee840dac2e8c6d607b1b8152509061217d5760405162461bcd60e51b8152600401610a0b91906148f1565b5061218783612e55565b60005b8151811015610d24576121ec848483815181106121b757634e487b7160e01b600052603260045260246000fd5b60200260200101518484815181106121df57634e487b7160e01b600052603260045260246000fd5b602002602001015161373c565b806121f681614af9565b91505061218a565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038416906301ffc9a79060240160206040518083038186803b15801561224757600080fd5b505afa15801561225b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061227f91906147d6565b156122ca576040517fe7ab3e0d000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b0384169063e7ab3e0d90602401611935565b6001600160a01b03831660009081526009602052604090208054839081106119bd57634e487b7160e01b600052603260045260246000fd5b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038316906301ffc9a79060240160206040518083038186803b15801561234b57600080fd5b505afa15801561235f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061238391906147d6565b156123c157816001600160a01b031663a14a28286040518163ffffffff1660e01b815260040160206040518083038186803b1580156111b157600080fd5b50506002546001600160a01b031690565b6001600160a01b038616600090815260126020908152604091829020548251808401909352601583527f636f6c6c656374696f6e206e6f74206578697374730000000000000000000000918301919091526124405760405162461bcd60e51b8152600401610a0b91906148f1565b5061244a86612e55565b61245386612822565b6124686001600160a01b0385163330856139d4565b600354612482906001600160a01b03868116911684613a85565b6003546040517f7c770aae0000000000000000000000000000000000000000000000000000000081526004810187905260248101849052604481018390523060648201819052608482015260009182916001600160a01b0390911690637c770aae9060a401606060405180830381600087803b15801561250157600080fd5b505af1158015612515573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125399190614826565b925050915060008211156125b3576001600160a01b0388166000908152600d602090815260408083208884529091528120805484929061257a908490614979565b90915550506001600160a01b0388166000908152600e602090815260408083208884528252822080546001810182559083529120018190555b5050505050505050565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038316906301ffc9a79060240160206040518083038186803b15801561260657600080fd5b505afa15801561261a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061263e91906147d6565b1561267c57816001600160a01b0316639e90f9aa6040518163ffffffff1660e01b815260040160206040518083038186803b1580156111b157600080fd5b50506004546001600160a01b031690565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038516906301ffc9a79060240160206040518083038186803b1580156126d657600080fd5b505afa1580156126ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061270e91906147d6565b15612760576040517f34870a8400000000000000000000000000000000000000000000000000000000815260048101849052602481018390526001600160a01b038516906334870a84906044016106b4565b6001600160a01b0384166000908152600e6020908152604080832086845290915290208054839081106127a357634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905061073b565b6001546001600160a01b0316331480156127d757506001600160a01b03821615155b80156127eb57506001600160a01b03811615155b6127f457600080fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b6001600160a01b03811660009081526012602052604090205461295c576000816001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561287a57600080fd5b505afa15801561288e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128b2919061480e565b116040518060400160405280601081526020017f6e6f20746f6b656e73206d696e74656400000000000000000000000000000000815250906129075760405162461bcd60e51b8152600401610a0b91906148f1565b50600160008082825461291a9190614979565b909155505060008054815260116020908152604080832080546001600160a01b0319166001600160a01b03861690811790915583549084526012909252909120555b50565b60408051808201909152600a8152691b1bddc8185b5bdd5b9d60b21b60208201528261299e5760405162461bcd60e51b8152600401610a0b91906148f1565b506001600160a01b03831660009081526009602090815260408083208054825181850281018501909352808352612a17938693929190830182828015612a0d57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116129ef575b5050505050613be2565b5090508015612a6857612a2982613c5a565b6001600160a01b0384811660009081526009602090815260408220805460018101825590835291200180546001600160a01b0319169184169190911790555b6001600160a01b038085166000908152600a6020908152604080832093861683529290529081208054859290612a9f908490614979565b90915550506001600160a01b03821615612ac857612ac86001600160a01b0383163330866139d4565b816001600160a01b0316846001600160a01b03167f2277a0aba10ed3c0ad4d3636a41f0b585192505cf6fe1584a92a0babcb37f13585604051612b0d91815260200190565b60405180910390a350505050565b6001600160a01b03808316600090815260066020908152604080832054815163313ce56760e01b815291519394859485948594939092169263313ce567926004808301939192829003018186803b158015612b7557600080fd5b505afa158015612b89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bad9190614853565b612bb890600a6149ec565b905060005b6001600160a01b038716600090815260076020526040902054811015612e0d576001600160a01b0387166000908152600760205260408120805482919084908110612c1857634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b031614612cfb576001600160a01b0388166000908152600760205260409020805483908110612c6a57634e487b7160e01b600052603260045260246000fd5b600091825260209182902001546040805163313ce56760e01b815290516001600160a01b039092169263313ce56792600480840193829003018186803b158015612cb357600080fd5b505afa158015612cc7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ceb9190614853565b612cf690600a6149ec565b612d05565b670de0b6b3a76400005b6001600160a01b03891660009081526008602090815260408083206007909252822080549394509192849287929185919088908110612d5457634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b03168352820192909252604001902054612d839190614a97565b612d8d9190614991565b9050612d998187614979565b6001600160a01b038a811660009081526007602052604090208054929850908a169185908110612dd957634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b03161415612df8578094505b50508080612e0590614af9565b915050612bbd565b506001600160a01b038087166000908152600860209081526040808320938916835292905220548290612e41908590614a97565b612e4b9190614991565b9695505050505050565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526001600160a01b038216906301ffc9a79060240160206040518083038186803b158015612e9b57600080fd5b505afa158015612eaf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ed391906147d6565b1561295c57604080518082018252600f81527f616c726561647920656e76696f757300000000000000000000000000000000006020820152905162461bcd60e51b8152610a0b91906004016148f1565b336040516331a9108f60e11b8152600481018590526001600160a01b0391821691861690636352211e9060240160206040518083038186803b158015612f6857600080fd5b505afa158015612f7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fa09190614505565b6001600160a01b0316146040518060400160405280600f81526020017f6e6f7420746f6b656e206f776e6572000000000000000000000000000000000081525090612ffe5760405162461bcd60e51b8152600401610a0b91906148f1565b5061300a848285613d3b565b6001600160a01b038085166000908152601060209081526040808320878452825280832093851683529290529081208054849290613049908490614ab6565b90915550506001600160a01b038085166000908152601060209081526040808320878452825280832093851683529290522054613224576001600160a01b0384166000908152600f60209081526040808320868452825280832080548251818502810185019093528083526130fe938693929190830182828015612a0d576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116129ef575050505050613be2565b6001600160a01b0387166000908152600f6020908152604080832089845290915290208054919350915061313490600190614ab6565b8154811061315257634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b038881168452600f83526040808520898652909352919092208054919092169190839081106131a657634e487b7160e01b600052603260045260246000fd5b600091825260208083209190910180546001600160a01b0319166001600160a01b039485161790559187168152600f825260408082208783529092522080548061320057634e487b7160e01b600052603160045260246000fd5b600082815260209020810160001990810180546001600160a01b0319169055019055505b6001600160a01b038416600090815260056020526040812061324e9086908590600101548561408a565b90506001600160a01b03821661326c5761326733611818565b613282565b613282335b6001600160a01b03841690836141d6565b604080518281526001600160a01b0384811660208301528692908816917f1ed9f521edb3b9ad6a2a0bb795a6273cd047f877551a94d088690d94e0833f8a910160405180910390a35050505050565b60408051808201909152600a8152691b1bddc8185b5bdd5b9d60b21b6020820152836133105760405162461bcd60e51b8152600401610a0b91906148f1565b506040516331a9108f60e11b8152600481018590526000906001600160a01b03871690636352211e9060240160206040518083038186803b15801561335457600080fd5b505afa158015613368573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061338c9190614505565b6001600160a01b031614156040518060400160405280600f81526020017f696e76616c696420746f6b656e49640000000000000000000000000000000000815250906133eb5760405162461bcd60e51b8152600401610a0b91906148f1565b506133f7858386613d3b565b6001600160a01b0385166000908152600f6020908152604080832087845282528083208054825181850281018501909352808352613475938793929190830182828015612a0d576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116129ef575050505050613be2565b50905080156134ce5761348783613c5a565b6001600160a01b038681166000908152600f6020908152604080832089845282528220805460018101825590835291200180546001600160a01b0319169185169190911790555b6001600160a01b0386166000908152600560205260408120546134f590889087908761408a565b6001600160a01b0380891660009081526010602090815260408083208b84528252808320938916835292905290812080549293508392909190613539908490614979565b90915550506001600160a01b03841615801590613554575082155b1561356e5761356e6001600160a01b0385163330886139d4565b604080518681526001600160a01b0386811660208301528892908a16917f9fdd5a3ace7f6e935b38292d6642e558e123b92a512aca74cebfbf1ed6b06203910160405180910390a350505050505050565b8047101561360f5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610a0b565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461365c576040519150601f19603f3d011682016040523d82523d6000602084013e613661565b606091505b50509050806136d85760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610a0b565b505050565b60001960005b8251811015613735578383828151811061370d57634e487b7160e01b600052603260045260246000fd5b6020026020010151141561372357809150613735565b8061372d81614af9565b9150506136e3565b5092915050565b6000613749848484610e32565b6001600160a01b038086166000908152600860209081526040808320938716835292905290812080549293508392909190613785908490614ab6565b90915550506001600160a01b03808516600090815260086020908152604080832093861683529290522054613935576001600160a01b0384166000908152600760209081526040808320805482518185028101850190935280835261382a938793929190830182828015612a0d576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116129ef575050505050613be2565b6001600160a01b03871660009081526007602052604090208054919350915061385590600190614ab6565b8154811061387357634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b038881168452600790925260409092208054919092169190839081106138be57634e487b7160e01b600052603260045260246000fd5b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918716815260079091526040902080548061391157634e487b7160e01b600052603160045260246000fd5b600082815260209020810160001990810180546001600160a01b0319169055019055505b6001600160a01b0382166139515761394c33611818565b61395a565b61395a33613271565b613986336004546001600160a01b038781166000908152600660205260409020548116929116866139d4565b816001600160a01b0316846001600160a01b03167fc5ca8fc2af130d27971637eec9f6085b5535bf62d406885bbb132e17b1c9964c8584604051612b0d929190918252602082015260400190565b6040516001600160a01b0380851660248301528316604482015260648101829052610d249085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261421f565b801580613b2757506040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b158015613aed57600080fd5b505afa158015613b01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b25919061480e565b155b613b995760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610a0b565b6040516001600160a01b0383166024820152604481018290526136d89084907f095ea7b30000000000000000000000000000000000000000000000000000000090606401613a21565b600160001960005b8351811015613c5257846001600160a01b0316848281518110613c1d57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03161415613c405760009250809150613c52565b80613c4a81614af9565b915050613bea565b509250929050565b6001600160a01b0381161561295c5760ff8016816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015613ca657600080fd5b505afa158015613cba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cde9190614853565b60ff1614156040518060400160405280600b81526020017f6e6f20646563696d616c7300000000000000000000000000000000000000000081525090613d375760405162461bcd60e51b8152600401610a0b91906148f1565b5050565b6000836001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015613d7657600080fd5b505afa158015613d8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613dae919061480e565b6001600160a01b038086166000908152600a6020908152604080832093881683529290522054613dde9190614991565b6001600160a01b038086166000818152600a6020908152604080832094891680845294825280832054938352600b8252808320948352939052919091205491925090613e2b908390614979565b1115613e7c576001600160a01b038085166000818152600b6020908152604080832094881680845294825280832054938352600a82528083209483529390529190912054613e799190614ab6565b90505b6001600160a01b038085166000908152600c60209081526040808320868452825280832093871683529290522054811115610d24576001600160a01b038085166000908152600c602090815260408083208684528252808320938716835292905290812054613eeb9083614ab6565b6001600160a01b038087166000908152600c602090815260408083208884528252808320938916835292905290812080549293508392909190613f2f908490614979565b90915550506001600160a01b0385166000908152600f6020908152604080832086845282528083208054825181850281018501909352808352613fb2938993929190830182828015612a0d576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116129ef575050505050613be2565b5090508015614002576001600160a01b038681166000908152600f6020908152604080832088845282528220805460018101825590835291200180546001600160a01b0319169187169190911790555b6001600160a01b038087166000908152601060209081526040808320888452825280832093891683529290529081208054849290614041908490614979565b90915550506001600160a01b038087166000908152600b602090815260408083209389168352929052908120805484929061407d908490614979565b9091555050505050505050565b600080620186a061409b8587614a97565b6140a59190614991565b9050600061412e84600760008a6001600160a01b03166001600160a01b03168152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015612a0d576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116129ef575050505050613be2565b50905080801561413e5750600082115b15614182576001600160a01b0387811660009081526007602090815260408220805460018101825590835291200180546001600160a01b0319169186169190911790555b6001600160a01b038088166000908152600860209081526040808320938816835292905290812080548492906141b9908490614979565b909155506141c990508287614ab6565b925050505b949350505050565b6040516001600160a01b0383166024820152604481018290526136d89084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401613a21565b6000614274826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166143049092919063ffffffff16565b8051909150156136d8578080602001905181019061429291906147d6565b6136d85760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610a0b565b60606141ce848460008585600080866001600160a01b0316858760405161432b9190614874565b60006040518083038185875af1925050503d8060008114614368576040519150601f19603f3d011682016040523d82523d6000602084013e61436d565b606091505b50915091506141c987838387606083156143e55782516143de576001600160a01b0385163b6143de5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a0b565b50816141ce565b6141ce83838151156143fa5781518083602001fd5b8060405162461bcd60e51b8152600401610a0b91906148f1565b600082601f830112614424578081fd5b8135602061443961443483614955565b614924565b80838252828201915082860187848660051b8901011115614458578586fd5b855b8581101561447f57813561446d81614b40565b8452928401929084019060010161445a565b5090979650505050505050565b600082601f83011261449c578081fd5b813560206144ac61443483614955565b80838252828201915082860187848660051b89010111156144cb578586fd5b855b8581101561447f578135845292840192908401906001016144cd565b6000602082840312156144fa578081fd5b813561073b81614b40565b600060208284031215614516578081fd5b815161073b81614b40565b60008060408385031215614533578081fd5b823561453e81614b40565b9150602083013561454e81614b40565b809150509250929050565b6000806000806080858703121561456e578182fd5b843561457981614b40565b9350602085013561458981614b40565b93969395505050506040820135916060013590565b6000806000606084860312156145b2578283fd5b83356145bd81614b40565b9250602084013567ffffffffffffffff808211156145d9578384fd5b6145e58783880161448c565b935060408601359150808211156145fa578283fd5b5061460786828701614414565b9150509250925092565b60008060408385031215614623578182fd5b823561462e81614b40565b946020939093013593505050565b600080600060608486031215614650578283fd5b833561465b81614b40565b925060208401359150604084013561467281614b40565b809150509250925092565b60008060008060008060c08789031215614695578182fd5b86356146a081614b40565b95506020870135945060408701356146b781614b40565b959894975094956060810135955060808101359460a0909101359350915050565b6000806000606084860312156146ec578283fd5b83356146f781614b40565b925060208401359150604084013567ffffffffffffffff811115614719578182fd5b6146078682870161448c565b6000806000806080858703121561473a578384fd5b843561474581614b40565b935060208501359250604085013567ffffffffffffffff80821115614768578384fd5b6147748883890161448c565b93506060870135915080821115614789578283fd5b5061479687828801614414565b91505092959194509250565b6000806000606084860312156147b6578081fd5b83356147c181614b40565b95602085013595506040909401359392505050565b6000602082840312156147e7578081fd5b8151801515811461073b578182fd5b600060208284031215614807578081fd5b5035919050565b60006020828403121561481f578081fd5b5051919050565b60008060006060848603121561483a578081fd5b8351925060208401519150604084015190509250925092565b600060208284031215614864578081fd5b815160ff8116811461073b578182fd5b60008251614886818460208701614acd565b9190910192915050565b6000606082016001600160a01b038616835260206060818501528186518084526080860191508288019350845b818110156148d9578451835293830193918301916001016148bd565b50508093505050508215156040830152949350505050565b6020815260008251806020840152614910816040850160208701614acd565b601f01601f19169190910160400192915050565b604051601f8201601f1916810167ffffffffffffffff8111828210171561494d5761494d614b2a565b604052919050565b600067ffffffffffffffff82111561496f5761496f614b2a565b5060051b60200190565b6000821982111561498c5761498c614b14565b500190565b6000826149ac57634e487b7160e01b81526012600452602481fd5b500490565b600181815b80851115613c525781600019048211156149d2576149d2614b14565b808516156149df57918102915b93841c93908002906149b6565b600061073b60ff841683600082614a055750600161089d565b81614a125750600061089d565b8160018114614a285760028114614a3257614a4e565b600191505061089d565b60ff841115614a4357614a43614b14565b50506001821b61089d565b5060208310610133831016604e8410600b8410161715614a71575081810a61089d565b614a7b83836149b1565b8060001904821115614a8f57614a8f614b14565b029392505050565b6000816000190483118215151615614ab157614ab1614b14565b500290565b600082821015614ac857614ac8614b14565b500390565b60005b83811015614ae8578181015183820152602001614ad0565b83811115610d245750506000910152565b6000600019821415614b0d57614b0d614b14565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461295c57600080fdfea2646970667358221220e8496c72f044d4c5f1e6b475348f8b1a93760a11ac639cad8f876b7e4ed4fe8064736f6c6343000804003300000000000000000000000020765436875aad13ce559da27735a99dad3277b7000000000000000000000000000000000000000000000003e733628714200000
Deployed Bytecode
0x6080604052600436106101cd5760003560e01c80637158bf6d116100f7578063928962f411610095578063efda37e611610064578063efda37e61461054e578063f4c0ee001461056e578063fcf826951461058e578063fdbda0ec146105ae57600080fd5b8063928962f41461049a578063bdc9e93f146104ce578063d204819a146104ee578063d794565c1461050e57600080fd5b80638c9d7c7a116100d15780638c9d7c7a146104275780638ec52cca1461043a5780638fabac4f1461045a5780638fdc2f761461047a57600080fd5b80637158bf6d146103ba578063775f131a146103da578063895587d5146103fa57600080fd5b80633e9b9ccf1161016f57806352cc4b4d1161013e57806352cc4b4d14610352578063554db8581461036557806361d9db2d146103855780636f94fa691461039a57600080fd5b80633e9b9ccf146102d25780633f06068e146102f25780634e2515931461031257806350ef4a021461033257600080fd5b80631f817a1e116101ab5780631f817a1e146102455780632239ceb61461025a5780633db225b81461027a5780633dde3e051461029a57600080fd5b80630ea4d5c6146101d257806314110286146102055780631e7b3a3c14610225575b600080fd5b3480156101de57600080fd5b506101f26101ed36600461463c565b6105e4565b6040519081526020015b60405180910390f35b34801561021157600080fd5b506101f2610220366004614611565b610742565b34801561023157600080fd5b506101f2610240366004614521565b6108a3565b610258610253366004614559565b61099c565b005b34801561026657600080fd5b506101f261027536600461463c565b610d2a565b34801561028657600080fd5b506101f261029536600461463c565b610e32565b3480156102a657600080fd5b506102ba6102b53660046144e9565b6110f2565b6040516001600160a01b0390911681526020016101fc565b3480156102de57600080fd5b506102586102ed366004614725565b611208565b3480156102fe57600080fd5b506101f261030d366004614521565b61134d565b34801561031e57600080fd5b506101f261032d366004614611565b611446565b34801561033e57600080fd5b506102ba61034d3660046147a2565b61153c565b610258610360366004614725565b6116b9565b34801561037157600080fd5b506102586103803660046144e9565b61181e565b34801561039157600080fd5b506000546101f2565b3480156103a657600080fd5b506102ba6103b5366004614611565b61186d565b3480156103c657600080fd5b506102586103d53660046146d8565b6119d9565b3480156103e657600080fd5b506101f26103f5366004614521565b611d98565b34801561040657600080fd5b506101f26104153660046144e9565b60126020526000908152604090205481565b61025861043536600461459e565b611e91565b34801561044657600080fd5b506102ba6104553660046144e9565b611ff1565b34801561046657600080fd5b5061025861047536600461459e565b6120c1565b34801561048657600080fd5b506102ba610495366004614611565b6121fe565b3480156104a657600080fd5b506101f27f000000000000000000000000000000000000000000000003e73362871420000081565b3480156104da57600080fd5b506102ba6104e93660046144e9565b612302565b3480156104fa57600080fd5b5061025861050936600461467d565b6123d2565b34801561051a57600080fd5b5061053e6105293660046144e9565b60136020526000908152604090205460ff1681565b60405190151581526020016101fc565b34801561055a57600080fd5b506102ba6105693660046144e9565b6125bd565b34801561057a57600080fd5b506101f26105893660046147a2565b61268d565b34801561059a57600080fd5b506102586105a9366004614521565b6127b5565b3480156105ba57600080fd5b506102ba6105c93660046147f6565b6011602052600090815260409020546001600160a01b031681565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038516906301ffc9a79060240160206040518083038186803b15801561062d57600080fd5b505afa158015610641573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066591906147d6565b1561070b576040517f7ceb5fa5000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b038381166024830152851690637ceb5fa5906044015b60206040518083038186803b1580156106cc57600080fd5b505afa1580156106e0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610704919061480e565b905061073b565b506001600160a01b038084166000908152600c602090815260408083208684528252808320938516835292905220545b9392505050565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038416906301ffc9a79060240160206040518083038186803b15801561078b57600080fd5b505afa15801561079f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c391906147d6565b15610861576040517f22b3a7c8000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b038416906322b3a7c8906024015b60206040518083038186803b15801561082257600080fd5b505afa158015610836573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085a919061480e565b905061089d565b6001600160a01b0383166000908152600560205260409020826002811061089857634e487b7160e01b600052603260045260246000fd5b015490505b92915050565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038416906301ffc9a79060240160206040518083038186803b1580156108ec57600080fd5b505afa158015610900573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092491906147d6565b15610970576040517fd0068b510000000000000000000000000000000000000000000000000000000081526001600160a01b03838116600483015284169063d0068b519060240161080a565b506001600160a01b0380831660009081526008602090815260408083209385168352929052205461089d565b6001600160a01b038416600090815260126020908152604091829020548251808401909352601183527f636f6c6c656374696f6e206578697374730000000000000000000000000000009183019190915215610a145760405162461bcd60e51b8152600401610a0b91906148f1565b60405180910390fd5b506040516301ffc9a760e01b81527f80ac58cd0000000000000000000000000000000000000000000000000000000060048201526001600160a01b038516906301ffc9a79060240160206040518083038186803b158015610a7457600080fd5b505afa158015610a88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aac91906147d6565b80610acf57506001600160a01b03841660009081526013602052604090205460ff165b6040518060400160405280601a81526020017f696e76616c696420636f6c6c656374696f6e206164647265737300000000000081525090610b235760405162461bcd60e51b8152600401610a0b91906148f1565b50610b2d84612822565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526001600160a01b038516906301ffc9a79060240160206040518083038186803b158015610b7357600080fd5b505afa158015610b87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bab91906147d6565b610d245760408051808201909152600a8152691b1bddc8185b5bdd5b9d60b21b60208201527f000000000000000000000000000000000000000000000003e733628714200000341015610c115760405162461bcd60e51b8152600401610a0b91906148f1565b5081151580610c1f57508015155b15610d185760408051808201909152601b81527f6e6f20636f6d6d756e69747920746f6b656e2070726f7669646564000000000060208201526001600160a01b038416610c7f5760405162461bcd60e51b8152600401610a0b91906148f1565b50620186a082108015610c945750620186a081105b6040518060400160405280600a8152602001691b1bddc8185b5bdd5b9d60b21b81525090610cd55760405162461bcd60e51b8152600401610a0b91906148f1565b506001600160a01b0384811660009081526005602090815260408083208681556001018590556006909152902080546001600160a01b0319169185169190911790555b610d248434600061295f565b50505050565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038516906301ffc9a79060240160206040518083038186803b158015610d7357600080fd5b505afa158015610d87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dab91906147d6565b15610dfe576040517f9bef3546000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b038381166024830152851690639bef3546906044016106b4565b506001600160a01b03808416600090815260106020908152604080832086845282528083209385168352929052205461073b565b6001600160a01b0383166000908152601260209081526040808320548151808301909252601582527f636f6c6c656374696f6e206e6f742065786973747300000000000000000000009282019290925290610ea05760405162461bcd60e51b8152600401610a0b91906148f1565b506040516301ffc9a760e01b8152636dbcb1a160e11b60048201526001600160a01b038516906301ffc9a79060240160206040518083038186803b158015610ee757600080fd5b505afa158015610efb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f1f91906147d6565b15610f72576040517f42da3b6b000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b0383811660248301528516906342da3b6b906044016106b4565b6001600160a01b03848116600090815260066020526040808220546004805492517f70a0823100000000000000000000000000000000000000000000000000000000815292851690830152919291909116906370a082319060240160206040518083038186803b158015610fe557600080fd5b505afa158015610ff9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061101d919061480e565b6001600160a01b038087166000908152600660209081526040918290205482517f18160ddd00000000000000000000000000000000000000000000000000000000815292519316926318160ddd926004808201939291829003018186803b15801561108757600080fd5b505afa15801561109b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110bf919061480e565b6110c99190614ab6565b9050806110d68685612b1b565b6110e09086614a97565b6110ea9190614991565b91505061073b565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038316906301ffc9a79060240160206040518083038186803b15801561113b57600080fd5b505afa15801561114f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117391906147d6565b156111e957816001600160a01b03166329aa16176040518163ffffffff1660e01b815260040160206040518083038186803b1580156111b157600080fd5b505afa1580156111c5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061089d9190614505565b506001600160a01b039081166000908152600660205260409020541690565b6001600160a01b038416600090815260126020908152604091829020548251808401909352601583527f636f6c6c656374696f6e206e6f74206578697374730000000000000000000000918301919091526112765760405162461bcd60e51b8152600401610a0b91906148f1565b508051825114604051806040016040528060118152602001700d8cadccee8d0e640dcdee840dac2e8c6d607b1b815250906112c45760405162461bcd60e51b8152600401610a0b91906148f1565b506112ce84612e55565b60005b81518110156113465761133485858584815181106112ff57634e487b7160e01b600052603260045260246000fd5b602002602001015185858151811061132757634e487b7160e01b600052603260045260246000fd5b6020026020010151612f23565b8061133e81614af9565b9150506112d1565b5050505050565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038416906301ffc9a79060240160206040518083038186803b15801561139657600080fd5b505afa1580156113aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ce91906147d6565b1561141a576040517fca5dd0cb0000000000000000000000000000000000000000000000000000000081526001600160a01b03838116600483015284169063ca5dd0cb9060240161080a565b506001600160a01b038083166000908152600a602090815260408083209385168352929052205461089d565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038416906301ffc9a79060240160206040518083038186803b15801561148f57600080fd5b505afa1580156114a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c791906147d6565b15611512576040517ff7408b53000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b0384169063f7408b539060240161080a565b506001600160a01b0382166000908152600d6020908152604080832084845290915290205461089d565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038516906301ffc9a79060240160206040518083038186803b15801561158557600080fd5b505afa158015611599573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115bd91906147d6565b1561165a576040517f885c46a800000000000000000000000000000000000000000000000000000000815260048101849052602481018390526001600160a01b0385169063885c46a89060440160206040518083038186803b15801561162257600080fd5b505afa158015611636573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107049190614505565b6001600160a01b0384166000908152600f60209081526040808320868452909152902080548390811061169d57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b0316905061073b565b8051825114604051806040016040528060118152602001700d8cadccee8d0e640dcdee840dac2e8c6d607b1b815250906117065760405162461bcd60e51b8152600401610a0b91906148f1565b5061171084612e55565b61171984612822565b3460005b825181101561180c5760006001600160a01b031683828151811061175157634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b0316141561179e5783818151811061178857634e487b7160e01b600052603260045260246000fd5b60200260200101518261179b9190614ab6565b91505b6117fa86868684815181106117c357634e487b7160e01b600052603260045260246000fd5b60200260200101518685815181106117eb57634e487b7160e01b600052603260045260246000fd5b602002602001015160006132d1565b8061180481614af9565b91505061171d565b50801561134657611346335b826135bf565b6001546001600160a01b03163314801561184057506001600160a01b03811615155b61184957600080fd5b6001600160a01b03166000908152601360205260409020805460ff19166001179055565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038416906301ffc9a79060240160206040518083038186803b1580156118b657600080fd5b505afa1580156118ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ee91906147d6565b15611985576040517f9b905f5a000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b03841690639b905f5a906024015b60206040518083038186803b15801561194d57600080fd5b505afa158015611961573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085a9190614505565b6001600160a01b03831660009081526007602052604090208054839081106119bd57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b0316905061089d565b6001600160a01b038316600090815260126020908152604091829020548251808401909352601583527f636f6c6c656374696f6e206e6f7420657869737473000000000000000000000091830191909152611a475760405162461bcd60e51b8152600401610a0b91906148f1565b5060025460408051808201909152601581527f67687374206164647265737320697320656d70747900000000000000000000006020820152906001600160a01b0316611aa65760405162461bcd60e51b8152600401610a0b91906148f1565b50611ab083612e55565b60005b8151811015611c99576000611b5e838381518110611ae157634e487b7160e01b600052603260045260246000fd5b6020908102919091018101516001600160a01b0388166000908152600e835260408082208983528452908190208054825181860281018601909352808352929391929091830182828015611b5457602002820191906000526020600020905b815481526020019060010190808311611b40575b50505050506136dd565b6001600160a01b0386166000908152600e6020908152604080832088845290915281205491925090611b9290600190614ab6565b6001600160a01b0387166000908152600e60209081526040808320898452909152902080549192509082908110611bd957634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b0389168352600e825260408084208985529092529120805484908110611c2457634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101929092556001600160a01b0388168152600e8252604080822088835290925220805480611c6e57634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905550508080611c9190614af9565b915050611ab3565b506003546040517fd62fbdd30000000000000000000000000000000000000000000000000000000081526000916001600160a01b03169063d62fbdd390611ce99030908690600190600401614890565b602060405180830381600087803b158015611d0357600080fd5b505af1158015611d17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d3b919061480e565b90508015610d24576001600160a01b0384166000908152600d6020908152604080832086845290915281208054839290611d76908490614ab6565b9091555050600254610d24908590859084906001600160a01b031660016132d1565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038416906301ffc9a79060240160206040518083038186803b158015611de157600080fd5b505afa158015611df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1991906147d6565b15611e65576040517f8fc3f5610000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152841690638fc3f5619060240161080a565b506001600160a01b038083166000908152600b602090815260408083209385168352929052205461089d565b8051825114604051806040016040528060118152602001700d8cadccee8d0e640dcdee840dac2e8c6d607b1b81525090611ede5760405162461bcd60e51b8152600401610a0b91906148f1565b50611ee883612e55565b611ef183612822565b3460005b8251811015611fe15760006001600160a01b0316838281518110611f2957634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03161415611f7657838181518110611f6057634e487b7160e01b600052603260045260246000fd5b602002602001015182611f739190614ab6565b91505b611fcf85858381518110611f9a57634e487b7160e01b600052603260045260246000fd5b6020026020010151858481518110611fc257634e487b7160e01b600052603260045260246000fd5b602002602001015161295f565b80611fd981614af9565b915050611ef5565b508015610d2457610d2433611818565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038316906301ffc9a79060240160206040518083038186803b15801561203a57600080fd5b505afa15801561204e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207291906147d6565b156120b057816001600160a01b0316635d5892376040518163ffffffff1660e01b815260040160206040518083038186803b1580156111b157600080fd5b50506003546001600160a01b031690565b6001600160a01b038316600090815260126020908152604091829020548251808401909352601583527f636f6c6c656374696f6e206e6f742065786973747300000000000000000000009183019190915261212f5760405162461bcd60e51b8152600401610a0b91906148f1565b508051825114604051806040016040528060118152602001700d8cadccee8d0e640dcdee840dac2e8c6d607b1b8152509061217d5760405162461bcd60e51b8152600401610a0b91906148f1565b5061218783612e55565b60005b8151811015610d24576121ec848483815181106121b757634e487b7160e01b600052603260045260246000fd5b60200260200101518484815181106121df57634e487b7160e01b600052603260045260246000fd5b602002602001015161373c565b806121f681614af9565b91505061218a565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038416906301ffc9a79060240160206040518083038186803b15801561224757600080fd5b505afa15801561225b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061227f91906147d6565b156122ca576040517fe7ab3e0d000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b0384169063e7ab3e0d90602401611935565b6001600160a01b03831660009081526009602052604090208054839081106119bd57634e487b7160e01b600052603260045260246000fd5b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038316906301ffc9a79060240160206040518083038186803b15801561234b57600080fd5b505afa15801561235f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061238391906147d6565b156123c157816001600160a01b031663a14a28286040518163ffffffff1660e01b815260040160206040518083038186803b1580156111b157600080fd5b50506002546001600160a01b031690565b6001600160a01b038616600090815260126020908152604091829020548251808401909352601583527f636f6c6c656374696f6e206e6f74206578697374730000000000000000000000918301919091526124405760405162461bcd60e51b8152600401610a0b91906148f1565b5061244a86612e55565b61245386612822565b6124686001600160a01b0385163330856139d4565b600354612482906001600160a01b03868116911684613a85565b6003546040517f7c770aae0000000000000000000000000000000000000000000000000000000081526004810187905260248101849052604481018390523060648201819052608482015260009182916001600160a01b0390911690637c770aae9060a401606060405180830381600087803b15801561250157600080fd5b505af1158015612515573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125399190614826565b925050915060008211156125b3576001600160a01b0388166000908152600d602090815260408083208884529091528120805484929061257a908490614979565b90915550506001600160a01b0388166000908152600e602090815260408083208884528252822080546001810182559083529120018190555b5050505050505050565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038316906301ffc9a79060240160206040518083038186803b15801561260657600080fd5b505afa15801561261a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061263e91906147d6565b1561267c57816001600160a01b0316639e90f9aa6040518163ffffffff1660e01b815260040160206040518083038186803b1580156111b157600080fd5b50506004546001600160a01b031690565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526000906001600160a01b038516906301ffc9a79060240160206040518083038186803b1580156126d657600080fd5b505afa1580156126ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061270e91906147d6565b15612760576040517f34870a8400000000000000000000000000000000000000000000000000000000815260048101849052602481018390526001600160a01b038516906334870a84906044016106b4565b6001600160a01b0384166000908152600e6020908152604080832086845290915290208054839081106127a357634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905061073b565b6001546001600160a01b0316331480156127d757506001600160a01b03821615155b80156127eb57506001600160a01b03811615155b6127f457600080fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b6001600160a01b03811660009081526012602052604090205461295c576000816001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561287a57600080fd5b505afa15801561288e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128b2919061480e565b116040518060400160405280601081526020017f6e6f20746f6b656e73206d696e74656400000000000000000000000000000000815250906129075760405162461bcd60e51b8152600401610a0b91906148f1565b50600160008082825461291a9190614979565b909155505060008054815260116020908152604080832080546001600160a01b0319166001600160a01b03861690811790915583549084526012909252909120555b50565b60408051808201909152600a8152691b1bddc8185b5bdd5b9d60b21b60208201528261299e5760405162461bcd60e51b8152600401610a0b91906148f1565b506001600160a01b03831660009081526009602090815260408083208054825181850281018501909352808352612a17938693929190830182828015612a0d57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116129ef575b5050505050613be2565b5090508015612a6857612a2982613c5a565b6001600160a01b0384811660009081526009602090815260408220805460018101825590835291200180546001600160a01b0319169184169190911790555b6001600160a01b038085166000908152600a6020908152604080832093861683529290529081208054859290612a9f908490614979565b90915550506001600160a01b03821615612ac857612ac86001600160a01b0383163330866139d4565b816001600160a01b0316846001600160a01b03167f2277a0aba10ed3c0ad4d3636a41f0b585192505cf6fe1584a92a0babcb37f13585604051612b0d91815260200190565b60405180910390a350505050565b6001600160a01b03808316600090815260066020908152604080832054815163313ce56760e01b815291519394859485948594939092169263313ce567926004808301939192829003018186803b158015612b7557600080fd5b505afa158015612b89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bad9190614853565b612bb890600a6149ec565b905060005b6001600160a01b038716600090815260076020526040902054811015612e0d576001600160a01b0387166000908152600760205260408120805482919084908110612c1857634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b031614612cfb576001600160a01b0388166000908152600760205260409020805483908110612c6a57634e487b7160e01b600052603260045260246000fd5b600091825260209182902001546040805163313ce56760e01b815290516001600160a01b039092169263313ce56792600480840193829003018186803b158015612cb357600080fd5b505afa158015612cc7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ceb9190614853565b612cf690600a6149ec565b612d05565b670de0b6b3a76400005b6001600160a01b03891660009081526008602090815260408083206007909252822080549394509192849287929185919088908110612d5457634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b03168352820192909252604001902054612d839190614a97565b612d8d9190614991565b9050612d998187614979565b6001600160a01b038a811660009081526007602052604090208054929850908a169185908110612dd957634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b03161415612df8578094505b50508080612e0590614af9565b915050612bbd565b506001600160a01b038087166000908152600860209081526040808320938916835292905220548290612e41908590614a97565b612e4b9190614991565b9695505050505050565b6040516301ffc9a760e01b8152636dbcb1a160e11b60048201526001600160a01b038216906301ffc9a79060240160206040518083038186803b158015612e9b57600080fd5b505afa158015612eaf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ed391906147d6565b1561295c57604080518082018252600f81527f616c726561647920656e76696f757300000000000000000000000000000000006020820152905162461bcd60e51b8152610a0b91906004016148f1565b336040516331a9108f60e11b8152600481018590526001600160a01b0391821691861690636352211e9060240160206040518083038186803b158015612f6857600080fd5b505afa158015612f7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fa09190614505565b6001600160a01b0316146040518060400160405280600f81526020017f6e6f7420746f6b656e206f776e6572000000000000000000000000000000000081525090612ffe5760405162461bcd60e51b8152600401610a0b91906148f1565b5061300a848285613d3b565b6001600160a01b038085166000908152601060209081526040808320878452825280832093851683529290529081208054849290613049908490614ab6565b90915550506001600160a01b038085166000908152601060209081526040808320878452825280832093851683529290522054613224576001600160a01b0384166000908152600f60209081526040808320868452825280832080548251818502810185019093528083526130fe938693929190830182828015612a0d576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116129ef575050505050613be2565b6001600160a01b0387166000908152600f6020908152604080832089845290915290208054919350915061313490600190614ab6565b8154811061315257634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b038881168452600f83526040808520898652909352919092208054919092169190839081106131a657634e487b7160e01b600052603260045260246000fd5b600091825260208083209190910180546001600160a01b0319166001600160a01b039485161790559187168152600f825260408082208783529092522080548061320057634e487b7160e01b600052603160045260246000fd5b600082815260209020810160001990810180546001600160a01b0319169055019055505b6001600160a01b038416600090815260056020526040812061324e9086908590600101548561408a565b90506001600160a01b03821661326c5761326733611818565b613282565b613282335b6001600160a01b03841690836141d6565b604080518281526001600160a01b0384811660208301528692908816917f1ed9f521edb3b9ad6a2a0bb795a6273cd047f877551a94d088690d94e0833f8a910160405180910390a35050505050565b60408051808201909152600a8152691b1bddc8185b5bdd5b9d60b21b6020820152836133105760405162461bcd60e51b8152600401610a0b91906148f1565b506040516331a9108f60e11b8152600481018590526000906001600160a01b03871690636352211e9060240160206040518083038186803b15801561335457600080fd5b505afa158015613368573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061338c9190614505565b6001600160a01b031614156040518060400160405280600f81526020017f696e76616c696420746f6b656e49640000000000000000000000000000000000815250906133eb5760405162461bcd60e51b8152600401610a0b91906148f1565b506133f7858386613d3b565b6001600160a01b0385166000908152600f6020908152604080832087845282528083208054825181850281018501909352808352613475938793929190830182828015612a0d576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116129ef575050505050613be2565b50905080156134ce5761348783613c5a565b6001600160a01b038681166000908152600f6020908152604080832089845282528220805460018101825590835291200180546001600160a01b0319169185169190911790555b6001600160a01b0386166000908152600560205260408120546134f590889087908761408a565b6001600160a01b0380891660009081526010602090815260408083208b84528252808320938916835292905290812080549293508392909190613539908490614979565b90915550506001600160a01b03841615801590613554575082155b1561356e5761356e6001600160a01b0385163330886139d4565b604080518681526001600160a01b0386811660208301528892908a16917f9fdd5a3ace7f6e935b38292d6642e558e123b92a512aca74cebfbf1ed6b06203910160405180910390a350505050505050565b8047101561360f5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610a0b565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461365c576040519150601f19603f3d011682016040523d82523d6000602084013e613661565b606091505b50509050806136d85760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610a0b565b505050565b60001960005b8251811015613735578383828151811061370d57634e487b7160e01b600052603260045260246000fd5b6020026020010151141561372357809150613735565b8061372d81614af9565b9150506136e3565b5092915050565b6000613749848484610e32565b6001600160a01b038086166000908152600860209081526040808320938716835292905290812080549293508392909190613785908490614ab6565b90915550506001600160a01b03808516600090815260086020908152604080832093861683529290522054613935576001600160a01b0384166000908152600760209081526040808320805482518185028101850190935280835261382a938793929190830182828015612a0d576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116129ef575050505050613be2565b6001600160a01b03871660009081526007602052604090208054919350915061385590600190614ab6565b8154811061387357634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b038881168452600790925260409092208054919092169190839081106138be57634e487b7160e01b600052603260045260246000fd5b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918716815260079091526040902080548061391157634e487b7160e01b600052603160045260246000fd5b600082815260209020810160001990810180546001600160a01b0319169055019055505b6001600160a01b0382166139515761394c33611818565b61395a565b61395a33613271565b613986336004546001600160a01b038781166000908152600660205260409020548116929116866139d4565b816001600160a01b0316846001600160a01b03167fc5ca8fc2af130d27971637eec9f6085b5535bf62d406885bbb132e17b1c9964c8584604051612b0d929190918252602082015260400190565b6040516001600160a01b0380851660248301528316604482015260648101829052610d249085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261421f565b801580613b2757506040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b158015613aed57600080fd5b505afa158015613b01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b25919061480e565b155b613b995760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610a0b565b6040516001600160a01b0383166024820152604481018290526136d89084907f095ea7b30000000000000000000000000000000000000000000000000000000090606401613a21565b600160001960005b8351811015613c5257846001600160a01b0316848281518110613c1d57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03161415613c405760009250809150613c52565b80613c4a81614af9565b915050613bea565b509250929050565b6001600160a01b0381161561295c5760ff8016816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015613ca657600080fd5b505afa158015613cba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cde9190614853565b60ff1614156040518060400160405280600b81526020017f6e6f20646563696d616c7300000000000000000000000000000000000000000081525090613d375760405162461bcd60e51b8152600401610a0b91906148f1565b5050565b6000836001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015613d7657600080fd5b505afa158015613d8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613dae919061480e565b6001600160a01b038086166000908152600a6020908152604080832093881683529290522054613dde9190614991565b6001600160a01b038086166000818152600a6020908152604080832094891680845294825280832054938352600b8252808320948352939052919091205491925090613e2b908390614979565b1115613e7c576001600160a01b038085166000818152600b6020908152604080832094881680845294825280832054938352600a82528083209483529390529190912054613e799190614ab6565b90505b6001600160a01b038085166000908152600c60209081526040808320868452825280832093871683529290522054811115610d24576001600160a01b038085166000908152600c602090815260408083208684528252808320938716835292905290812054613eeb9083614ab6565b6001600160a01b038087166000908152600c602090815260408083208884528252808320938916835292905290812080549293508392909190613f2f908490614979565b90915550506001600160a01b0385166000908152600f6020908152604080832086845282528083208054825181850281018501909352808352613fb2938993929190830182828015612a0d576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116129ef575050505050613be2565b5090508015614002576001600160a01b038681166000908152600f6020908152604080832088845282528220805460018101825590835291200180546001600160a01b0319169187169190911790555b6001600160a01b038087166000908152601060209081526040808320888452825280832093891683529290529081208054849290614041908490614979565b90915550506001600160a01b038087166000908152600b602090815260408083209389168352929052908120805484929061407d908490614979565b9091555050505050505050565b600080620186a061409b8587614a97565b6140a59190614991565b9050600061412e84600760008a6001600160a01b03166001600160a01b03168152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015612a0d576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116129ef575050505050613be2565b50905080801561413e5750600082115b15614182576001600160a01b0387811660009081526007602090815260408220805460018101825590835291200180546001600160a01b0319169186169190911790555b6001600160a01b038088166000908152600860209081526040808320938816835292905290812080548492906141b9908490614979565b909155506141c990508287614ab6565b925050505b949350505050565b6040516001600160a01b0383166024820152604481018290526136d89084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401613a21565b6000614274826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166143049092919063ffffffff16565b8051909150156136d8578080602001905181019061429291906147d6565b6136d85760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610a0b565b60606141ce848460008585600080866001600160a01b0316858760405161432b9190614874565b60006040518083038185875af1925050503d8060008114614368576040519150601f19603f3d011682016040523d82523d6000602084013e61436d565b606091505b50915091506141c987838387606083156143e55782516143de576001600160a01b0385163b6143de5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a0b565b50816141ce565b6141ce83838151156143fa5781518083602001fd5b8060405162461bcd60e51b8152600401610a0b91906148f1565b600082601f830112614424578081fd5b8135602061443961443483614955565b614924565b80838252828201915082860187848660051b8901011115614458578586fd5b855b8581101561447f57813561446d81614b40565b8452928401929084019060010161445a565b5090979650505050505050565b600082601f83011261449c578081fd5b813560206144ac61443483614955565b80838252828201915082860187848660051b89010111156144cb578586fd5b855b8581101561447f578135845292840192908401906001016144cd565b6000602082840312156144fa578081fd5b813561073b81614b40565b600060208284031215614516578081fd5b815161073b81614b40565b60008060408385031215614533578081fd5b823561453e81614b40565b9150602083013561454e81614b40565b809150509250929050565b6000806000806080858703121561456e578182fd5b843561457981614b40565b9350602085013561458981614b40565b93969395505050506040820135916060013590565b6000806000606084860312156145b2578283fd5b83356145bd81614b40565b9250602084013567ffffffffffffffff808211156145d9578384fd5b6145e58783880161448c565b935060408601359150808211156145fa578283fd5b5061460786828701614414565b9150509250925092565b60008060408385031215614623578182fd5b823561462e81614b40565b946020939093013593505050565b600080600060608486031215614650578283fd5b833561465b81614b40565b925060208401359150604084013561467281614b40565b809150509250925092565b60008060008060008060c08789031215614695578182fd5b86356146a081614b40565b95506020870135945060408701356146b781614b40565b959894975094956060810135955060808101359460a0909101359350915050565b6000806000606084860312156146ec578283fd5b83356146f781614b40565b925060208401359150604084013567ffffffffffffffff811115614719578182fd5b6146078682870161448c565b6000806000806080858703121561473a578384fd5b843561474581614b40565b935060208501359250604085013567ffffffffffffffff80821115614768578384fd5b6147748883890161448c565b93506060870135915080821115614789578283fd5b5061479687828801614414565b91505092959194509250565b6000806000606084860312156147b6578081fd5b83356147c181614b40565b95602085013595506040909401359392505050565b6000602082840312156147e7578081fd5b8151801515811461073b578182fd5b600060208284031215614807578081fd5b5035919050565b60006020828403121561481f578081fd5b5051919050565b60008060006060848603121561483a578081fd5b8351925060208401519150604084015190509250925092565b600060208284031215614864578081fd5b815160ff8116811461073b578182fd5b60008251614886818460208701614acd565b9190910192915050565b6000606082016001600160a01b038616835260206060818501528186518084526080860191508288019350845b818110156148d9578451835293830193918301916001016148bd565b50508093505050508215156040830152949350505050565b6020815260008251806020840152614910816040850160208701614acd565b601f01601f19169190910160400192915050565b604051601f8201601f1916810167ffffffffffffffff8111828210171561494d5761494d614b2a565b604052919050565b600067ffffffffffffffff82111561496f5761496f614b2a565b5060051b60200190565b6000821982111561498c5761498c614b14565b500190565b6000826149ac57634e487b7160e01b81526012600452602481fd5b500490565b600181815b80851115613c525781600019048211156149d2576149d2614b14565b808516156149df57918102915b93841c93908002906149b6565b600061073b60ff841683600082614a055750600161089d565b81614a125750600061089d565b8160018114614a285760028114614a3257614a4e565b600191505061089d565b60ff841115614a4357614a43614b14565b50506001821b61089d565b5060208310610133831016604e8410600b8410161715614a71575081810a61089d565b614a7b83836149b1565b8060001904821115614a8f57614a8f614b14565b029392505050565b6000816000190483118215151615614ab157614ab1614b14565b500290565b600082821015614ac857614ac8614b14565b500390565b60005b83811015614ae8578181015183820152602001614ad0565b83811115610d245750506000910152565b6000600019821415614b0d57614b0d614b14565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461295c57600080fdfea2646970667358221220e8496c72f044d4c5f1e6b475348f8b1a93760a11ac639cad8f876b7e4ed4fe8064736f6c63430008040033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000020765436875aad13ce559da27735a99dad3277b7000000000000000000000000000000000000000000000003e733628714200000
-----Decoded View---------------
Arg [0] : blackHoleAddress (address): 0x20765436875AaD13ce559dA27735a99dAD3277b7
Arg [1] : minimalEthAmount (uint256): 72000000000000000000
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000020765436875aad13ce559da27735a99dad3277b7
Arg [1] : 000000000000000000000000000000000000000000000003e733628714200000
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.