Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
This contract has been verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- FusePoolDirectory
- Optimization enabled
- true
- Compiler version
- v0.6.12+commit.27d51765
- Optimization runs
- 200
- EVM Version
- istanbul
- Verified at
- 2026-04-22T18:09:01.404424Z
/C/Users/david/Dropbox/Rari/v1/fuse-contracts/contracts/FusePoolDirectory.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;
import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "./external/compound/Comptroller.sol";
import "./external/compound/Unitroller.sol";
import "./external/compound/PriceOracle.sol";
/**
* @title FusePoolDirectory
* @author David Lucid <david@rari.capital> (https://github.com/davidlucid)
* @notice FusePoolDirectory is a directory for Fuse interest rate pools.
*/
contract FusePoolDirectory is OwnableUpgradeable {
/**
* @dev Initializes a deployer whitelist if desired.
* @param _enforceDeployerWhitelist Boolean indicating if the deployer whitelist is to be enforced.
* @param _deployerWhitelist Array of Ethereum accounts to be whitelisted.
*/
function initialize(bool _enforceDeployerWhitelist, address[] memory _deployerWhitelist) public initializer {
__Ownable_init();
enforceDeployerWhitelist = _enforceDeployerWhitelist;
for (uint256 i = 0; i < _deployerWhitelist.length; i++) deployerWhitelist[_deployerWhitelist[i]] = true;
}
/**
* @dev Struct for a Fuse interest rate pool.
*/
struct FusePool {
string name;
address creator;
address comptroller;
uint256 blockPosted;
uint256 timestampPosted;
}
/**
* @dev Array of Fuse interest rate pools.
*/
FusePool[] public pools;
/**
* @dev Maps Ethereum accounts to arrays of Fuse pool indexes.
*/
mapping(address => uint256[]) private _poolsByAccount;
/**
* @dev Maps Fuse pool Comptroller addresses to bools indicating if they have been registered via the directory.
*/
mapping(address => bool) public poolExists;
/**
* @dev Emitted when a new Fuse pool is added to the directory.
*/
event PoolRegistered(uint256 index, FusePool pool);
/**
* @dev Booleans indicating if the deployer whitelist is enforced.
*/
bool public enforceDeployerWhitelist;
/**
* @dev Maps Ethereum accounts to booleans indicating if they are allowed to deploy pools.
*/
mapping(address => bool) public deployerWhitelist;
/**
* @dev Controls if the deployer whitelist is to be enforced.
* @param enforce Boolean indicating if the deployer whitelist is to be enforced.
*/
function _setDeployerWhitelistEnforcement(bool enforce) external onlyOwner {
enforceDeployerWhitelist = enforce;
}
/**
* @dev Adds/removes Ethereum accounts to the deployer whitelist.
* @param deployers Array of Ethereum accounts to be whitelisted.
* @param status Whether to add or remove the accounts.
*/
function _editDeployerWhitelist(address[] calldata deployers, bool status) external onlyOwner {
require(deployers.length > 0, "No deployers supplied.");
for (uint256 i = 0; i < deployers.length; i++) deployerWhitelist[deployers[i]] = status;
}
/**
* @dev Adds a new Fuse pool to the directory (without checking msg.sender).
* @param name The name of the pool.
* @param comptroller The pool's Comptroller proxy contract address.
* @return The index of the registered Fuse pool.
*/
function _registerPool(string memory name, address comptroller) internal returns (uint256) {
require(!poolExists[comptroller], "Pool already exists in the directory.");
require(!enforceDeployerWhitelist || deployerWhitelist[msg.sender], "Sender is not on deployer whitelist.");
require(bytes(name).length <= 100, "No pool name supplied.");
FusePool memory pool = FusePool(name, msg.sender, comptroller, block.number, block.timestamp);
pools.push(pool);
_poolsByAccount[msg.sender].push(pools.length - 1);
poolExists[comptroller] = true;
emit PoolRegistered(pools.length - 1, pool);
return pools.length - 1;
}
/**
* @dev Deploys a new Fuse pool and adds to the directory.
* @param name The name of the pool.
* @param implementation The Comptroller implementation contract address.
* @param enforceWhitelist Boolean indicating if the pool's supplier/borrower whitelist is to be enforced.
* @param closeFactor The pool's close factor (scaled by 1e18).
* @param liquidationIncentive The pool's liquidation incentive (scaled by 1e18).
* @param priceOracle The pool's PriceOracle contract address.
* @return The index of the registered Fuse pool and the Unitroller proxy address.
*/
function deployPool(string memory name, address implementation, bool enforceWhitelist, uint256 closeFactor, uint256 liquidationIncentive, address priceOracle) external returns (uint256, address) {
// Input validation
require(implementation != address(0), "No Comptroller implementation contract address specified.");
require(priceOracle != address(0), "No PriceOracle contract address specified.");
// Deploy Unitroller using msg.sender, name, and block.number as a salt
bytes memory unitrollerCreationCode = hex"60806040526001805460ff60a81b1960ff60a01b19909116600160a01b1716600160a81b17905534801561003257600080fd5b50600080546001600160a01b03191633179055610ae1806100546000396000f3fe6080604052600436106100a75760003560e01c8063bb82aa5e11610064578063bb82aa5e14610437578063c1e803341461044c578063dcfbc0c714610461578063e992a04114610476578063e9c714f2146104a9578063f851a440146104be576100a7565b80630225ab9d1461032b5780630a755ec21461036957806326782247146103925780632f1069ba146103c35780636f63af0b146103d8578063b71d1a0c14610404575b3330146102a85760408051600481526024810182526020810180516001600160e01b0316633757348b60e21b1781529151815160009360609330939092909182918083835b6020831061010b5780518252601f1990920191602091820191016100ec565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d806000811461016b576040519150601f19603f3d011682016040523d82523d6000602084013e610170565b606091505b5091509150600082156101975781806020019051602081101561019257600080fd5b505190505b80156102a4576002546040805163bbcdd6d360e01b81526001600160a01b0390921660048301525160009173a731585ab05fc9f83555cf9bff8f58ee94e18f859163bbcdd6d391602480820192602092909190829003018186803b1580156101fe57600080fd5b505afa158015610212573d6000803e3d6000fd5b505050506040513d602081101561022857600080fd5b50516002549091506001600160a01b038083169116146102a257600280546001600160a01b038381166001600160a01b0319831617928390556040805192821680845293909116602083015280517fd604de94d45953f9138079ec1b82d533cb2160c906d1076d1f7ed54befbca97a9281900390910190a1505b505b5050505b6002546040516000916001600160a01b031690829036908083838082843760405192019450600093509091505080830381855af49150503d806000811461030b576040519150601f19603f3d011682016040523d82523d6000602084013e610310565b606091505b505090506040513d6000823e818015610327573d82f35b3d82fd5b34801561033757600080fd5b506103576004803603602081101561034e57600080fd5b503515156104d3565b60408051918252519081900360200190f35b34801561037557600080fd5b5061037e61056f565b604080519115158252519081900360200190f35b34801561039e57600080fd5b506103a761057f565b604080516001600160a01b039092168252519081900360200190f35b3480156103cf57600080fd5b5061037e61058e565b3480156103e457600080fd5b50610357600480360360208110156103fb57600080fd5b5035151561059e565b34801561041057600080fd5b506103576004803603602081101561042757600080fd5b50356001600160a01b031661063a565b34801561044357600080fd5b506103a76106bd565b34801561045857600080fd5b506103576106cc565b34801561046d57600080fd5b506103a76107c7565b34801561048257600080fd5b506103576004803603602081101561049957600080fd5b50356001600160a01b03166107d6565b3480156104b557600080fd5b506103576108f6565b3480156104ca57600080fd5b506103a76109dc565b60006104dd6109eb565b6104f4576104ed60016005610a46565b905061056a565b60015460ff600160a81b90910416151582151514156105145760006104ed565b60018054831515600160a81b810260ff60a81b199092169190911790915560408051918252517f10f9a0a95673b0837d1dce21fd3bffcb6d760435e9b5300b75a271182f75f8229181900360200190a160005b90505b919050565b600154600160a81b900460ff1681565b6001546001600160a01b031681565b600154600160a01b900460ff1681565b60006105a86109eb565b6105b8576104ed60016005610a46565b60015460ff600160a01b90910416151582151514156105d85760006104ed565b60018054831515600160a01b90810260ff60a01b199092169190911791829055604080519190920460ff161515815290517fabb56a15fd39488c914b324690b88f30d7daec63d2131ca0ef47e5739068c86e9181900360200190a16000610567565b60006106446109eb565b610654576104ed60016010610a46565b600180546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9929181900390910190a160005b9392505050565b6002546001600160a01b031681565b6003546000906001600160a01b0316331415806106f257506003546001600160a01b0316155b1561070957610702600180610a46565b90506107c4565b60028054600380546001600160a01b038082166001600160a01b031980861682179687905590921690925560408051938316808552949092166020840152815190927fd604de94d45953f9138079ec1b82d533cb2160c906d1076d1f7ed54befbca97a92908290030190a1600354604080516001600160a01b038085168252909216602083015280517fe945ccee5d701fc83f9b8aa8ca94ea4219ec1fcbd4f4cab4f0ea57c5c3e1d8159281900390910190a160005b925050505b90565b6003546001600160a01b031681565b60006107e06109eb565b6107f0576104ed60016012610a46565b60025460408051639d244f9f60e01b81526001600160a01b03928316600482015291841660248301525173a731585ab05fc9f83555cf9bff8f58ee94e18f8591639d244f9f916044808301926020929190829003018186803b15801561085557600080fd5b505afa158015610869573d6000803e3d6000fd5b505050506040513d602081101561087f57600080fd5b5051610891576104ed60016011610a46565b600380546001600160a01b038481166001600160a01b0319831617928390556040805192821680845293909116602083015280517fe945ccee5d701fc83f9b8aa8ca94ea4219ec1fcbd4f4cab4f0ea57c5c3e1d8159281900390910190a160006106b6565b6001546000906001600160a01b031633141580610911575033155b156109225761070260016000610a46565b60008054600180546001600160a01b038082166001600160a01b031980861682179687905590921690925560408051938316808552949092166020840152815190927ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc92908290030190a1600154604080516001600160a01b038085168252909216602083015280517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99281900390910190a160006107bf565b6000546001600160a01b031681565b600080546001600160a01b031633148015610a0f5750600154600160a81b900460ff165b80610a4157503373a731585ab05fc9f83555cf9bff8f58ee94e18f85148015610a415750600154600160a01b900460ff165b905090565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0836015811115610a7557fe5b83601b811115610a8157fe5b604080519283526020830191909152600082820152519081900360600190a18260158111156106b657fefea265627a7a72315820a5cf9491a370c17ee98b3c08c728cc0ddad83bd43ca76c92dc106835bfccb25664736f6c63430005110032";
bytes32 salt = keccak256(abi.encodePacked(msg.sender, name, block.number));
address proxy;
assembly {
proxy := create2(0, add(unitrollerCreationCode, 32), mload(unitrollerCreationCode), salt)
if iszero(extcodesize(proxy)) {
revert(0, "Failed to deploy Unitroller.")
}
}
// Setup Unitroller
Unitroller unitroller = Unitroller(proxy);
require(unitroller._setPendingImplementation(implementation) == 0, "Failed to set pending implementation on Unitroller."); // Checks Comptroller implementation whitelist
Comptroller comptrollerImplementation = Comptroller(implementation);
comptrollerImplementation._become(unitroller);
Comptroller comptrollerProxy = Comptroller(proxy);
// Set pool parameters
require(comptrollerProxy._setCloseFactor(closeFactor) == 0, "Failed to set pool close factor.");
require(comptrollerProxy._setLiquidationIncentive(liquidationIncentive) == 0, "Failed to set pool liquidation incentive.");
require(comptrollerProxy._setPriceOracle(PriceOracle(priceOracle)) == 0, "Failed to set pool price oracle.");
// Whitelist
if (enforceWhitelist) require(comptrollerProxy._setWhitelistEnforcement(true) == 0, "Failed to enforce supplier/borrower whitelist.");
// Enable auto-implementation
require(comptrollerProxy._toggleAutoImplementations(true) == 0, "Failed to enable pool auto implementations.");
// Make msg.sender the admin
require(unitroller._setPendingAdmin(msg.sender) == 0, "Failed to set pending admin on Unitroller.");
// Register the pool with this FusePoolDirectory
return (_registerPool(name, proxy), proxy);
}
/**
* @notice Returns arrays of all Fuse pools' data.
* @dev This function is not designed to be called in a transaction: it is too gas-intensive.
*/
function getAllPools() external view returns (FusePool[] memory) {
return pools;
}
/**
* @notice Returns arrays of all public Fuse pool indexes and data.
* @dev This function is not designed to be called in a transaction: it is too gas-intensive.
*/
function getPublicPools() external view returns (uint256[] memory, FusePool[] memory) {
uint256 arrayLength = 0;
for (uint256 i = 0; i < pools.length; i++) {
try Comptroller(pools[i].comptroller).enforceWhitelist() returns (bool enforceWhitelist) {
if (enforceWhitelist) continue;
} catch { }
arrayLength++;
}
uint256[] memory indexes = new uint256[](arrayLength);
FusePool[] memory publicPools = new FusePool[](arrayLength);
uint256 index = 0;
for (uint256 i = 0; i < pools.length; i++) {
try Comptroller(pools[i].comptroller).enforceWhitelist() returns (bool enforceWhitelist) {
if (enforceWhitelist) continue;
} catch { }
indexes[index] = i;
publicPools[index] = pools[i];
index++;
}
return (indexes, publicPools);
}
/**
* @notice Returns arrays of Fuse pool indexes and data created by `account`.
*/
function getPoolsByAccount(address account) external view returns (uint256[] memory, FusePool[] memory) {
uint256[] memory indexes = new uint256[](_poolsByAccount[account].length);
FusePool[] memory accountPools = new FusePool[](_poolsByAccount[account].length);
for (uint256 i = 0; i < _poolsByAccount[account].length; i++) {
indexes[i] = _poolsByAccount[account][i];
accountPools[i] = pools[_poolsByAccount[account][i]];
}
return (indexes, accountPools);
}
/**
* @dev Maps Ethereum accounts to arrays of Fuse pool Comptroller proxy contract addresses.
*/
mapping(address => address[]) private _bookmarks;
/**
* @notice Returns arrays of Fuse pool Unitroller (Comptroller proxy) contract addresses bookmarked by `account`.
*/
function getBookmarks(address account) external view returns (address[] memory) {
return _bookmarks[account];
}
/**
* @notice Bookmarks a Fuse pool Unitroller (Comptroller proxy) contract addresses.
*/
function bookmarkPool(address comptroller) external {
_bookmarks[msg.sender].push(comptroller);
}
/**
* @notice Modify existing Fuse pool name.
*/
function setPoolName(uint256 index, string calldata name) external {
Comptroller _comptroller = Comptroller(pools[index].comptroller);
require(msg.sender == _comptroller.admin() && _comptroller.adminHasRights() || msg.sender == owner());
pools[index].name = name;
}
/**
* @dev Maps Ethereum accounts to booleans indicating if they are a whitelisted admin.
*/
mapping(address => bool) public adminWhitelist;
/**
* @dev Event emitted when the admin whitelist is updated.
*/
event AdminWhitelistUpdated(address[] admins, bool status);
/**
* @dev Adds/removes Ethereum accounts to the admin whitelist.
* @param admins Array of Ethereum accounts to be whitelisted.
* @param status Whether to add or remove the accounts.
*/
function _editAdminWhitelist(address[] calldata admins, bool status) external onlyOwner {
require(admins.length > 0, "No admins supplied.");
for (uint256 i = 0; i < admins.length; i++) adminWhitelist[admins[i]] = status;
emit AdminWhitelistUpdated(admins, status);
}
/**
* @notice Returns arrays of all public Fuse pool indexes and data with whitelisted admins.
* @dev This function is not designed to be called in a transaction: it is too gas-intensive.
*/
function getPublicPoolsByVerification(bool whitelistedAdmin) external view returns (uint256[] memory, FusePool[] memory) {
uint256 arrayLength = 0;
for (uint256 i = 0; i < pools.length; i++) {
Comptroller comptroller = Comptroller(pools[i].comptroller);
try comptroller.enforceWhitelist() returns (bool enforceWhitelist) {
if (enforceWhitelist) continue;
try comptroller.admin() returns (address admin) {
if (whitelistedAdmin != adminWhitelist[admin]) continue;
} catch { }
} catch { }
arrayLength++;
}
uint256[] memory indexes = new uint256[](arrayLength);
FusePool[] memory publicPools = new FusePool[](arrayLength);
uint256 index = 0;
for (uint256 i = 0; i < pools.length; i++) {
Comptroller comptroller = Comptroller(pools[i].comptroller);
try comptroller.enforceWhitelist() returns (bool enforceWhitelist) {
if (enforceWhitelist) continue;
try comptroller.admin() returns (address admin) {
if (whitelistedAdmin != adminWhitelist[admin]) continue;
} catch { }
} catch { }
indexes[index] = i;
publicPools[index] = pools[i];
index++;
}
return (indexes, publicPools);
}
}
/Rari/v1/fuse-contracts/contracts/external/compound/RewardsDistributor.sol
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity 0.6.12;
import "./CToken.sol";
/**
* @title RewardsDistributor
* @author Compound
*/
interface RewardsDistributor {
/// @dev The token to reward (i.e., COMP)
function rewardToken() external view returns (address);
/// @notice The portion of compRate that each market currently receives
function compSupplySpeeds(address) external view returns (uint);
/// @notice The portion of compRate that each market currently receives
function compBorrowSpeeds(address) external view returns (uint);
/// @notice The COMP accrued but not yet transferred to each user
function compAccrued(address) external view returns (uint);
/**
* @notice Keeps the flywheel moving pre-mint and pre-redeem
* @dev Called by the Comptroller
* @param cToken The relevant market
* @param supplier The minter/redeemer
*/
function flywheelPreSupplierAction(address cToken, address supplier) external;
/**
* @notice Keeps the flywheel moving pre-borrow and pre-repay
* @dev Called by the Comptroller
* @param cToken The relevant market
* @param borrower The borrower
*/
function flywheelPreBorrowerAction(address cToken, address borrower) external;
/**
* @notice Returns an array of all markets.
*/
function getAllMarkets() external view returns (CToken[] memory);
}
/Rari/v1/fuse-contracts/contracts/external/compound/PriceOracle.sol
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity 0.6.12;
import "./CToken.sol";
interface PriceOracle {
/**
* @notice Get the underlying price of a cToken asset
* @param cToken The cToken to get the underlying price of
* @return The underlying asset price mantissa (scaled by 1e18).
* Zero means the price is unavailable.
*/
function getUnderlyingPrice(CToken cToken) external view returns (uint);
}
/Rari/v1/fuse-contracts/contracts/external/compound/Comptroller.sol
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity 0.6.12;
import "./PriceOracle.sol";
import "./CToken.sol";
import "./Unitroller.sol";
import "./RewardsDistributor.sol";
/**
* @title Compound's Comptroller Contract
* @author Compound
*/
interface Comptroller {
function admin() external view returns (address);
function adminHasRights() external view returns (bool);
function fuseAdminHasRights() external view returns (bool);
function oracle() external view returns (PriceOracle);
function closeFactorMantissa() external view returns (uint);
function liquidationIncentiveMantissa() external view returns (uint);
function markets(address cToken) external view returns (bool, uint);
function getAssetsIn(address account) external view returns (CToken[] memory);
function checkMembership(address account, CToken cToken) external view returns (bool);
function getAccountLiquidity(address account) external view returns (uint, uint, uint);
function _setPriceOracle(PriceOracle newOracle) external returns (uint);
function _setCloseFactor(uint newCloseFactorMantissa) external returns (uint256);
function _setLiquidationIncentive(uint newLiquidationIncentiveMantissa) external returns (uint);
function _become(Unitroller unitroller) external;
function borrowGuardianPaused(address cToken) external view returns (bool);
function getRewardsDistributors() external view returns (RewardsDistributor[] memory);
function getAllMarkets() external view returns (CToken[] memory);
function getAllBorrowers() external view returns (address[] memory);
function suppliers(address account) external view returns (bool);
function enforceWhitelist() external view returns (bool);
function whitelist(address account) external view returns (bool);
function _setWhitelistEnforcement(bool enforce) external returns (uint);
function _setWhitelistStatuses(address[] calldata _suppliers, bool[] calldata statuses) external returns (uint);
function _toggleAutoImplementations(bool enabled) external returns (uint);
}
/Rari/v1/fuse-contracts/contracts/external/compound/Unitroller.sol
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity 0.6.12;
/**
* @title ComptrollerCore
* @dev Storage for the comptroller is at this address, while execution is delegated to the `comptrollerImplementation`.
* CTokens should reference this contract as their comptroller.
*/
interface Unitroller {
function _setPendingImplementation(address newPendingImplementation) external returns (uint);
function _setPendingAdmin(address newPendingAdmin) external returns (uint);
}
/Rari/v1/fuse-contracts/contracts/external/compound/CToken.sol
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity 0.6.12;
/**
* @title Compound's CToken Contract
* @notice Abstract base for CTokens
* @author Compound
*/
interface CToken {
function admin() external view returns (address);
function adminHasRights() external view returns (bool);
function fuseAdminHasRights() external view returns (bool);
function symbol() external view returns (string memory);
function comptroller() external view returns (address);
function adminFeeMantissa() external view returns (uint256);
function fuseFeeMantissa() external view returns (uint256);
function reserveFactorMantissa() external view returns (uint256);
function totalReserves() external view returns (uint);
function totalAdminFees() external view returns (uint);
function totalFuseFees() external view returns (uint);
function isCToken() external view returns (bool);
function isCEther() external view returns (bool);
function balanceOf(address owner) external view returns (uint);
function balanceOfUnderlying(address owner) external returns (uint);
function borrowRatePerBlock() external view returns (uint);
function supplyRatePerBlock() external view returns (uint);
function totalBorrowsCurrent() external returns (uint);
function borrowBalanceStored(address account) external view returns (uint);
function exchangeRateStored() external view returns (uint);
function getCash() external view returns (uint);
function redeem(uint redeemTokens) external returns (uint);
function redeemUnderlying(uint redeemAmount) external returns (uint);
}
/
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../utils/ContextUpgradeable.sol";
import "../proxy/Initializable.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal initializer {
__Context_init_unchained();
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal initializer {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
uint256[49] private __gap;
}
/
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../proxy/Initializable.sol";
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal initializer {
__Context_init_unchained();
}
function __Context_init_unchained() internal initializer {
}
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
uint256[50] private __gap;
}
/
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain`call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
/
// SPDX-License-Identifier: MIT
// solhint-disable-next-line compiler-version
pragma solidity >=0.4.24 <0.8.0;
import "../utils/AddressUpgradeable.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
*/
bool private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Modifier to protect an initializer function from being invoked twice.
*/
modifier initializer() {
require(_initializing || _isConstructor() || !_initialized, "Initializable: contract is already initialized");
bool isTopLevelCall = !_initializing;
if (isTopLevelCall) {
_initializing = true;
_initialized = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
}
}
/// @dev Returns true if and only if the function is running in the constructor
function _isConstructor() private view returns (bool) {
return !AddressUpgradeable.isContract(address(this));
}
}
Compiler Settings
{"remappings":[],"optimizer":{"runs":200,"enabled":true},"metadata":{"bytecodeHash":"ipfs"},"libraries":{},"evmVersion":"istanbul","compilationTarget":{"/C/Users/david/Dropbox/Rari/v1/fuse-contracts/contracts/FusePoolDirectory.sol":"FusePoolDirectory"}}
Contract ABI
[{"type":"event","name":"AdminWhitelistUpdated","inputs":[{"type":"address[]","name":"admins","internalType":"address[]","indexed":false},{"type":"bool","name":"status","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"PoolRegistered","inputs":[{"type":"uint256","name":"index","internalType":"uint256","indexed":false},{"type":"tuple","name":"pool","internalType":"struct FusePoolDirectory.FusePool","indexed":false,"components":[{"type":"string","name":"name","internalType":"string"},{"type":"address","name":"creator","internalType":"address"},{"type":"address","name":"comptroller","internalType":"address"},{"type":"uint256","name":"blockPosted","internalType":"uint256"},{"type":"uint256","name":"timestampPosted","internalType":"uint256"}]}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"_editAdminWhitelist","inputs":[{"type":"address[]","name":"admins","internalType":"address[]"},{"type":"bool","name":"status","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"_editDeployerWhitelist","inputs":[{"type":"address[]","name":"deployers","internalType":"address[]"},{"type":"bool","name":"status","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"_setDeployerWhitelistEnforcement","inputs":[{"type":"bool","name":"enforce","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"adminWhitelist","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"bookmarkPool","inputs":[{"type":"address","name":"comptroller","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"address","name":"","internalType":"address"}],"name":"deployPool","inputs":[{"type":"string","name":"name","internalType":"string"},{"type":"address","name":"implementation","internalType":"address"},{"type":"bool","name":"enforceWhitelist","internalType":"bool"},{"type":"uint256","name":"closeFactor","internalType":"uint256"},{"type":"uint256","name":"liquidationIncentive","internalType":"uint256"},{"type":"address","name":"priceOracle","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"deployerWhitelist","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"enforceDeployerWhitelist","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct FusePoolDirectory.FusePool[]","components":[{"type":"string","name":"name","internalType":"string"},{"type":"address","name":"creator","internalType":"address"},{"type":"address","name":"comptroller","internalType":"address"},{"type":"uint256","name":"blockPosted","internalType":"uint256"},{"type":"uint256","name":"timestampPosted","internalType":"uint256"}]}],"name":"getAllPools","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"}],"name":"getBookmarks","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"},{"type":"tuple[]","name":"","internalType":"struct FusePoolDirectory.FusePool[]","components":[{"type":"string","name":"name","internalType":"string"},{"type":"address","name":"creator","internalType":"address"},{"type":"address","name":"comptroller","internalType":"address"},{"type":"uint256","name":"blockPosted","internalType":"uint256"},{"type":"uint256","name":"timestampPosted","internalType":"uint256"}]}],"name":"getPoolsByAccount","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"},{"type":"tuple[]","name":"","internalType":"struct FusePoolDirectory.FusePool[]","components":[{"type":"string","name":"name","internalType":"string"},{"type":"address","name":"creator","internalType":"address"},{"type":"address","name":"comptroller","internalType":"address"},{"type":"uint256","name":"blockPosted","internalType":"uint256"},{"type":"uint256","name":"timestampPosted","internalType":"uint256"}]}],"name":"getPublicPools","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"},{"type":"tuple[]","name":"","internalType":"struct FusePoolDirectory.FusePool[]","components":[{"type":"string","name":"name","internalType":"string"},{"type":"address","name":"creator","internalType":"address"},{"type":"address","name":"comptroller","internalType":"address"},{"type":"uint256","name":"blockPosted","internalType":"uint256"},{"type":"uint256","name":"timestampPosted","internalType":"uint256"}]}],"name":"getPublicPoolsByVerification","inputs":[{"type":"bool","name":"whitelistedAdmin","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[{"type":"bool","name":"_enforceDeployerWhitelist","internalType":"bool"},{"type":"address[]","name":"_deployerWhitelist","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"poolExists","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"name","internalType":"string"},{"type":"address","name":"creator","internalType":"address"},{"type":"address","name":"comptroller","internalType":"address"},{"type":"uint256","name":"blockPosted","internalType":"uint256"},{"type":"uint256","name":"timestampPosted","internalType":"uint256"}],"name":"pools","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPoolName","inputs":[{"type":"uint256","name":"index","internalType":"uint256"},{"type":"string","name":"name","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]}]
Contract Creation Code
0x608060405234801561001057600080fd5b5061379b806100206000396000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c80635710c6d8116100ad578063a970e76c11610071578063a970e76c14610270578063ac4afa3814610283578063b86579d4146102a7578063d88ff1f4146102ba578063f2fde38b146102cf5761012c565b80635710c6d81461020c578063715018a61461022d5780638da5cb5b14610235578063a155497c1461024a578063a3ed91c61461025d5761012c565b8063218a3bbe116100f4578063218a3bbe146101a857806326bb81d7146101c957806343e20a1d146101d15780634a7462ee146101e45780634ae26ea1146102045761012c565b806304f03c6f1461013157806307421978146101465780630a83d1b0146101595780631e1c6a071461016c57806320c32bfe14610195575b600080fd5b61014461013f366004612216565b6102e2565b005b610144610154366004612157565b61033d565b610144610167366004612196565b61037c565b61017f61017a366004612157565b61047a565b60405161018c91906126bf565b60405180910390f35b6101446101a336600461240f565b61048f565b6101bb6101b6366004612216565b610612565b60405161018c929190612668565b61017f610ab5565b61017f6101df366004612157565b610abe565b6101f76101f2366004612157565b610ad3565b60405161018c9190612608565b6101bb610b49565b61021f61021a36600461230e565b610e99565b60405161018c929190612b82565b610144611437565b61023d6114c0565b60405161018c919061259b565b610144610258366004612196565b6114cf565b6101bb61026b366004612157565b611592565b61017f61027e366004612157565b611823565b6102966102913660046123df565b611838565b60405161018c9594939291906126ca565b6101446102b536600461224e565b61190f565b6102c2611a03565b60405161018c9190612655565b6101446102dd366004612157565b611b2d565b6102ea611bee565b6001600160a01b03166102fb6114c0565b6001600160a01b03161461032a5760405162461bcd60e51b815260040161032190612970565b60405180910390fd5b6068805460ff1916911515919091179055565b336000908152606a602090815260408220805460018101825590835291200180546001600160a01b0319166001600160a01b0392909216919091179055565b610384611bee565b6001600160a01b03166103956114c0565b6001600160a01b0316146103bb5760405162461bcd60e51b815260040161032190612970565b816103d85760405162461bcd60e51b81526004016103219061273f565b60005b828110156104395781606b60008686858181106103f457fe5b90506020020160208101906104099190612157565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790556001016103db565b507f31b67e6853df85403a8c4f4f46dc53f48f700d6917c8e3ec8c77a0e6fd56793b83838360405161046d939291906125af565b60405180910390a1505050565b60676020526000908152604090205460ff1681565b60006065848154811061049e57fe5b600091825260209182902060026005909202010154604080516303e1469160e61b815290516001600160a01b039092169350839263f851a44092600480840193829003018186803b1580156104f257600080fd5b505afa158015610506573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052a919061217a565b6001600160a01b0316336001600160a01b03161480156105b65750806001600160a01b0316630a755ec26040518163ffffffff1660e01b815260040160206040518083038186803b15801561057e57600080fd5b505afa158015610592573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b69190612232565b806105d957506105c46114c0565b6001600160a01b0316336001600160a01b0316145b6105e257600080fd5b8282606586815481106105f157fe5b6000918252602090912061060b9360059092020191611fff565b5050505050565b6060806000805b6065548110156107805760006065828154811061063257fe5b60009182526020918290206002600590920201015460408051630b09572160e41b815290516001600160a01b039092169350839263b095721092600480840193829003018186803b15801561068657600080fd5b505afa9250505080156106b6575060408051601f3d908101601f191682019092526106b391810190612232565b60015b6106bf57610770565b80156106cc575050610778565b816001600160a01b031663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b15801561070557600080fd5b505afa925050508015610735575060408051601f3d908101601f191682019092526107329181019061217a565b60015b61073e5761076e565b6001600160a01b0381166000908152606b602052604090205460ff1615158815151461076c57505050610778565b505b505b506001909101905b600101610619565b5060608167ffffffffffffffff8111801561079a57600080fd5b506040519080825280602002602001820160405280156107c4578160200160208202803683370190505b50905060608267ffffffffffffffff811180156107e057600080fd5b5060405190808252806020026020018201604052801561081a57816020015b61080761207d565b8152602001906001900390816107ff5790505b5090506000805b606554811015610aa85760006065828154811061083a57fe5b60009182526020918290206002600590920201015460408051630b09572160e41b815290516001600160a01b039092169350839263b095721092600480840193829003018186803b15801561088e57600080fd5b505afa9250505080156108be575060408051601f3d908101601f191682019092526108bb91810190612232565b60015b6108c757610978565b80156108d4575050610aa0565b816001600160a01b031663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b15801561090d57600080fd5b505afa92505050801561093d575060408051601f3d908101601f1916820190925261093a9181019061217a565b60015b61094657610976565b6001600160a01b0381166000908152606b602052604090205460ff1615158b15151461097457505050610aa0565b505b505b8185848151811061098557fe5b6020026020010181815250506065828154811061099e57fe5b600091825260209182902060408051600593909302909101805460026001821615610100026000190190911604601f8101859004909402830160c090810190925260a0830184815292939092849290918491840182828015610a415780601f10610a1657610100808354040283529160200191610a41565b820191906000526020600020905b815481529060010190602001808311610a2457829003601f168201915b505050918352505060018201546001600160a01b0390811660208301526002830154166040820152600382015460608201526004909101546080909101528451859085908110610a8d57fe5b6020908102919091010152506001909101905b600101610821565b5091945092505050915091565b60685460ff1681565b606b6020526000908152604090205460ff1681565b6001600160a01b0381166000908152606a6020908152604091829020805483518184028101840190945280845260609392830182828015610b3d57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b1f575b50505050509050919050565b6060806000805b606554811015610c0e5760658181548110610b6757fe5b60009182526020918290206002600590920201015460408051630b09572160e41b815290516001600160a01b039092169263b095721092600480840193829003018186803b158015610bb857600080fd5b505afa925050508015610be8575060408051601f3d908101601f19168201909252610be591810190612232565b60015b610bf157610bff565b8015610bfd5750610c06565b505b6001909101905b600101610b50565b5060608167ffffffffffffffff81118015610c2857600080fd5b50604051908082528060200260200182016040528015610c52578160200160208202803683370190505b50905060608267ffffffffffffffff81118015610c6e57600080fd5b50604051908082528060200260200182016040528015610ca857816020015b610c9561207d565b815260200190600190039081610c8d5790505b5090506000805b606554811015610e8d5760658181548110610cc657fe5b60009182526020918290206002600590920201015460408051630b09572160e41b815290516001600160a01b039092169263b095721092600480840193829003018186803b158015610d1757600080fd5b505afa925050508015610d47575060408051601f3d908101601f19168201909252610d4491810190612232565b60015b610d5057610d5e565b8015610d5c5750610e85565b505b80848381518110610d6b57fe5b60200260200101818152505060658181548110610d8457fe5b600091825260209182902060408051600593909302909101805460026001821615610100026000190190911604601f8101859004909402830160c090810190925260a0830184815292939092849290918491840182828015610e275780601f10610dfc57610100808354040283529160200191610e27565b820191906000526020600020905b815481529060010190602001808311610e0a57829003601f168201915b505050918352505060018201546001600160a01b0390811660208301526002830154166040820152600382015460608201526004909101546080909101528351849084908110610e7357fe5b60209081029190910101526001909101905b600101610caf565b50919450925050509091565b6000806001600160a01b038716610ec25760405162461bcd60e51b81526004016103219061287e565b6001600160a01b038316610ee85760405162461bcd60e51b8152600401610321906129f8565b606060405180610b600160405280610b358152602001612c31610b35913990506000338a43604051602001610f1f9392919061255c565b6040516020818303038152906040528051906020012090506000818351602085016000f59050803b610f70577f4661696c656420746f206465706c6f7920556e6974726f6c6c65722e000000006000fd5b60405163e992a04160e01b815281906001600160a01b0382169063e992a04190610f9e908e9060040161259b565b602060405180830381600087803b158015610fb857600080fd5b505af1158015610fcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ff091906123f7565b1561100d5760405162461bcd60e51b8152600401610321906129a5565b604051630ea826e360e11b81528b906001600160a01b03821690631d504dc69061103b90859060040161259b565b600060405180830381600087803b15801561105557600080fd5b505af1158015611069573d6000803e3d6000fd5b505060405163317b0b7760e01b81528592506001600160a01b038316915063317b0b779061109b908e90600401612b79565b602060405180830381600087803b1580156110b557600080fd5b505af11580156110c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ed91906123f7565b1561110a5760405162461bcd60e51b81526004016103219061270a565b604051634fd42e1760e01b81526001600160a01b03821690634fd42e1790611136908d90600401612b79565b602060405180830381600087803b15801561115057600080fd5b505af1158015611164573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118891906123f7565b156111a55760405162461bcd60e51b81526004016103219061276c565b6040516355ee1fe160e01b81526001600160a01b038216906355ee1fe1906111d1908c9060040161259b565b602060405180830381600087803b1580156111eb57600080fd5b505af11580156111ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122391906123f7565b156112405760405162461bcd60e51b8152600401610321906127fb565b8b156112e257604051634a956fad60e11b81526001600160a01b0382169063952adf5a90611273906001906004016126bf565b602060405180830381600087803b15801561128d57600080fd5b505af11580156112a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c591906123f7565b156112e25760405162461bcd60e51b815260040161032190612a42565b604051636a9998b360e11b81526001600160a01b0382169063d53331669061130f906001906004016126bf565b602060405180830381600087803b15801561132957600080fd5b505af115801561133d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136191906123f7565b1561137e5760405162461bcd60e51b8152600401610321906128db565b604051632dc7468360e21b81526001600160a01b0384169063b71d1a0c906113aa90339060040161259b565b602060405180830381600087803b1580156113c457600080fd5b505af11580156113d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113fc91906123f7565b156114195760405162461bcd60e51b815260040161032190612926565b6114238e85611bf2565b9e939d50929b505050505050505050505050565b61143f611bee565b6001600160a01b03166114506114c0565b6001600160a01b0316146114765760405162461bcd60e51b815260040161032190612970565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6033546001600160a01b031690565b6114d7611bee565b6001600160a01b03166114e86114c0565b6001600160a01b03161461150e5760405162461bcd60e51b815260040161032190612970565b8161152b5760405162461bcd60e51b815260040161032190612a90565b60005b8281101561158c57816069600086868581811061154757fe5b905060200201602081019061155c9190612157565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905560010161152e565b50505050565b6001600160a01b0381166000908152606660205260409020546060908190819067ffffffffffffffff811180156115c857600080fd5b506040519080825280602002602001820160405280156115f2578160200160208202803683370190505b506001600160a01b03851660009081526066602052604090205490915060609067ffffffffffffffff8111801561162857600080fd5b5060405190808252806020026020018201604052801561166257816020015b61164f61207d565b8152602001906001900390816116475790505b50905060005b6001600160a01b038616600090815260666020526040902054811015611818576001600160a01b03861660009081526066602052604090208054829081106116ac57fe5b90600052602060002001548382815181106116c357fe5b602002602001018181525050606560666000886001600160a01b03166001600160a01b03168152602001908152602001600020828154811061170157fe5b90600052602060002001548154811061171657fe5b600091825260209182902060408051600593909302909101805460026001821615610100026000190190911604601f8101859004909402830160c090810190925260a08301848152929390928492909184918401828280156117b95780601f1061178e576101008083540402835291602001916117b9565b820191906000526020600020905b81548152906001019060200180831161179c57829003601f168201915b505050918352505060018201546001600160a01b039081166020830152600283015416604082015260038201546060820152600490910154608090910152825183908390811061180557fe5b6020908102919091010152600101611668565b509092509050915091565b60696020526000908152604090205460ff1681565b6065818154811061184557fe5b60009182526020918290206005919091020180546040805160026001841615610100026000190190931692909204601f8101859004850283018501909152808252919350918391908301828280156118de5780601f106118b3576101008083540402835291602001916118de565b820191906000526020600020905b8154815290600101906020018083116118c157829003601f168201915b5050505060018301546002840154600385015460049095015493946001600160a01b03928316949290911692509085565b600054610100900460ff16806119285750611928611dfa565b80611936575060005460ff16155b6119525760405162461bcd60e51b815260040161032190612830565b600054610100900460ff1615801561197d576000805460ff1961ff0019909116610100171660011790555b611985611e0b565b6068805460ff191684151517905560005b82518110156119eb576001606960008584815181106119b157fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055600101611996565b5080156119fe576000805461ff00191690555b505050565b60606065805480602002602001604051908101604052809291908181526020016000905b82821015611b245760008481526020908190206040805160058602909201805460026001821615610100026000190190911604601f8101859004909402830160c090810190925260a0830184815292939092849290918491840182828015611ad05780601f10611aa557610100808354040283529160200191611ad0565b820191906000526020600020905b815481529060010190602001808311611ab357829003601f168201915b50505091835250506001828101546001600160a01b03908116602080850191909152600285015490911660408401526003840154606084015260049093015460809092019190915291835292019101611a27565b50505050905090565b611b35611bee565b6001600160a01b0316611b466114c0565b6001600160a01b031614611b6c5760405162461bcd60e51b815260040161032190612970565b6001600160a01b038116611b925760405162461bcd60e51b8152600401610321906127b5565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b03811660009081526067602052604081205460ff1615611c2b5760405162461bcd60e51b815260040161032190612af0565b60685460ff161580611c4c57503360009081526069602052604090205460ff165b611c685760405162461bcd60e51b815260040161032190612b35565b606483511115611c8a5760405162461bcd60e51b815260040161032190612ac0565b611c9261207d565b506040805160a081018252848152336020808301919091526001600160a01b0385169282019290925243606082015242608082015260658054600181018255600091909152815180519293849360059093027f8ff97419363ffd7000167f130ef7168fbea05faf9251824ca5043f113cc6a7c70192611d1492849201906120be565b50602082810151600183810180546001600160a01b03199081166001600160a01b0394851617909155604080870151600287018054909316908516179091556060860151600386015560809095015160049094019390935533600090815260668352848120606580548254808801845592845285842060001991820193019290925592891682526067909352849020805460ff1916909317909255905491517f18075ab463b4dc5842f37ecd67abeb192eda5d073f2c08509e189ad173d5c02092611de29201908490612b99565b60405180910390a15050606554600019015b92915050565b6000611e0530611e9e565b15905090565b600054610100900460ff1680611e245750611e24611dfa565b80611e32575060005460ff16155b611e4e5760405162461bcd60e51b815260040161032190612830565b600054610100900460ff16158015611e79576000805460ff1961ff0019909116610100171660011790555b611e81611ea4565b611e89611f25565b8015611e9b576000805461ff00191690555b50565b3b151590565b600054610100900460ff1680611ebd5750611ebd611dfa565b80611ecb575060005460ff16155b611ee75760405162461bcd60e51b815260040161032190612830565b600054610100900460ff16158015611e89576000805460ff1961ff0019909116610100171660011790558015611e9b576000805461ff001916905550565b600054610100900460ff1680611f3e5750611f3e611dfa565b80611f4c575060005460ff16155b611f685760405162461bcd60e51b815260040161032190612830565b600054610100900460ff16158015611f93576000805460ff1961ff0019909116610100171660011790555b6000611f9d611bee565b603380546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015611e9b576000805461ff001916905550565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106120405782800160ff1982351617855561206d565b8280016001018555821561206d579182015b8281111561206d578235825591602001919060010190612052565b5061207992915061212c565b5090565b6040518060a001604052806060815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106120ff57805160ff191683800117855561206d565b8280016001018555821561206d579182015b8281111561206d578251825591602001919060010190612111565b5b80821115612079576000815560010161212d565b8035611df481612c0d565b8035611df481612c22565b600060208284031215612168578081fd5b813561217381612c0d565b9392505050565b60006020828403121561218b578081fd5b815161217381612c0d565b6000806000604084860312156121aa578182fd5b833567ffffffffffffffff808211156121c1578384fd5b818601915086601f8301126121d4578384fd5b8135818111156121e2578485fd5b87602080830285010111156121f5578485fd5b6020928301955093505084013561220b81612c22565b809150509250925092565b600060208284031215612227578081fd5b813561217381612c22565b600060208284031215612243578081fd5b815161217381612c22565b60008060408385031215612260578182fd5b823561226b81612c22565b915060208381013567ffffffffffffffff80821115612288578384fd5b818601915086601f83011261229b578384fd5b8135818111156122a9578485fd5b83810291506122b9848301612bba565b8181528481019084860184860187018b10156122d3578788fd5b8795505b838610156122fd576122e98b82612141565b8352600195909501949186019186016122d7565b508096505050505050509250929050565b60008060008060008060c08789031215612326578182fd5b863567ffffffffffffffff8082111561233d578384fd5b818901915089601f830112612350578384fd5b81358181111561235e578485fd5b60209150612374601f8201601f19168301612bba565b8181528b83838601011115612387578586fd5b8183850184830137908101820185905297506123a58a8a8301612141565b965050506123b6886040890161214c565b935060608701359250608087013591506123d38860a08901612141565b90509295509295509295565b6000602082840312156123f0578081fd5b5035919050565b600060208284031215612408578081fd5b5051919050565b600080600060408486031215612423578283fd5b83359250602084013567ffffffffffffffff80821115612441578384fd5b818601915086601f830112612454578384fd5b813581811115612462578485fd5b876020828501011115612473578485fd5b6020830194508093505050509250925092565b6000815180845260208085018081965082840281019150828601855b858110156124cc5782840389526124ba848351612505565b988501989350908401906001016124a2565b5091979650505050505050565b600081518084526124f1816020860160208601612be1565b601f01601f19169290920160200192915050565b6000815160a0845261251a60a08501826124d9565b9050602083015160018060a01b038082166020870152806040860151166040870152505060608301516060850152608083015160808501528091505092915050565b60006bffffffffffffffffffffffff198560601b1682528351612586816014850160208801612be1565b60149201918201929092526034019392505050565b6001600160a01b0391909116815260200190565b6040808252810183905260008460608301825b868110156125f257602083356125d781612c0d565b6001600160a01b0316835292830192909101906001016125c2565b5080925050508215156020830152949350505050565b6020808252825182820181905260009190848201906040850190845b818110156126495783516001600160a01b031683529284019291840191600101612624565b50909695505050505050565b6000602082526121736020830184612486565b604080825283519082018190526000906020906060840190828701845b828110156126a157815184529284019290840190600101612685565b505050838103828501526126b58186612486565b9695505050505050565b901515815260200190565b600060a082526126dd60a08301886124d9565b6001600160a01b039687166020840152949095166040820152606081019290925260809091015292915050565b6020808252818101527f4661696c656420746f2073657420706f6f6c20636c6f736520666163746f722e604082015260600190565b60208082526013908201527227379030b236b4b7399039bab8383634b2b21760691b604082015260600190565b60208082526029908201527f4661696c656420746f2073657420706f6f6c206c69717569646174696f6e20696040820152683731b2b73a34bb329760b91b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252818101527f4661696c656420746f2073657420706f6f6c207072696365206f7261636c652e604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526039908201527f4e6f20436f6d7074726f6c6c657220696d706c656d656e746174696f6e20636f60408201527f6e74726163742061646472657373207370656369666965642e00000000000000606082015260800190565b6020808252602b908201527f4661696c656420746f20656e61626c6520706f6f6c206175746f20696d706c6560408201526a36b2b73a30ba34b7b7399760a91b606082015260800190565b6020808252602a908201527f4661696c656420746f207365742070656e64696e672061646d696e206f6e20556040820152693734ba3937b63632b91760b11b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526033908201527f4661696c656420746f207365742070656e64696e6720696d706c656d656e74616040820152723a34b7b71037b7102ab734ba3937b63632b91760691b606082015260800190565b6020808252602a908201527f4e6f2050726963654f7261636c6520636f6e747261637420616464726573732060408201526939b832b1b4b334b2b21760b11b606082015260800190565b6020808252602e908201527f4661696c656420746f20656e666f72636520737570706c6965722f626f72726f60408201526d3bb2b9103bb434ba32b634b9ba1760911b606082015260800190565b6020808252601690820152752737903232b83637bcb2b9399039bab8383634b2b21760511b604082015260600190565b6020808252601690820152752737903837b7b6103730b6b29039bab8383634b2b21760511b604082015260600190565b60208082526025908201527f506f6f6c20616c72656164792065786973747320696e207468652064697265636040820152643a37b93c9760d91b606082015260800190565b60208082526024908201527f53656e646572206973206e6f74206f6e206465706c6f7965722077686974656c60408201526334b9ba1760e11b606082015260800190565b90815260200190565b9182526001600160a01b0316602082015260400190565b600083825260406020830152612bb26040830184612505565b949350505050565b60405181810167ffffffffffffffff81118282101715612bd957600080fd5b604052919050565b60005b83811015612bfc578181015183820152602001612be4565b8381111561158c5750506000910152565b6001600160a01b0381168114611e9b57600080fd5b8015158114611e9b57600080fdfe60806040526001805460ff60a81b1960ff60a01b19909116600160a01b1716600160a81b17905534801561003257600080fd5b50600080546001600160a01b03191633179055610ae1806100546000396000f3fe6080604052600436106100a75760003560e01c8063bb82aa5e11610064578063bb82aa5e14610437578063c1e803341461044c578063dcfbc0c714610461578063e992a04114610476578063e9c714f2146104a9578063f851a440146104be576100a7565b80630225ab9d1461032b5780630a755ec21461036957806326782247146103925780632f1069ba146103c35780636f63af0b146103d8578063b71d1a0c14610404575b3330146102a85760408051600481526024810182526020810180516001600160e01b0316633757348b60e21b1781529151815160009360609330939092909182918083835b6020831061010b5780518252601f1990920191602091820191016100ec565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d806000811461016b576040519150601f19603f3d011682016040523d82523d6000602084013e610170565b606091505b5091509150600082156101975781806020019051602081101561019257600080fd5b505190505b80156102a4576002546040805163bbcdd6d360e01b81526001600160a01b0390921660048301525160009173a731585ab05fc9f83555cf9bff8f58ee94e18f859163bbcdd6d391602480820192602092909190829003018186803b1580156101fe57600080fd5b505afa158015610212573d6000803e3d6000fd5b505050506040513d602081101561022857600080fd5b50516002549091506001600160a01b038083169116146102a257600280546001600160a01b038381166001600160a01b0319831617928390556040805192821680845293909116602083015280517fd604de94d45953f9138079ec1b82d533cb2160c906d1076d1f7ed54befbca97a9281900390910190a1505b505b5050505b6002546040516000916001600160a01b031690829036908083838082843760405192019450600093509091505080830381855af49150503d806000811461030b576040519150601f19603f3d011682016040523d82523d6000602084013e610310565b606091505b505090506040513d6000823e818015610327573d82f35b3d82fd5b34801561033757600080fd5b506103576004803603602081101561034e57600080fd5b503515156104d3565b60408051918252519081900360200190f35b34801561037557600080fd5b5061037e61056f565b604080519115158252519081900360200190f35b34801561039e57600080fd5b506103a761057f565b604080516001600160a01b039092168252519081900360200190f35b3480156103cf57600080fd5b5061037e61058e565b3480156103e457600080fd5b50610357600480360360208110156103fb57600080fd5b5035151561059e565b34801561041057600080fd5b506103576004803603602081101561042757600080fd5b50356001600160a01b031661063a565b34801561044357600080fd5b506103a76106bd565b34801561045857600080fd5b506103576106cc565b34801561046d57600080fd5b506103a76107c7565b34801561048257600080fd5b506103576004803603602081101561049957600080fd5b50356001600160a01b03166107d6565b3480156104b557600080fd5b506103576108f6565b3480156104ca57600080fd5b506103a76109dc565b60006104dd6109eb565b6104f4576104ed60016005610a46565b905061056a565b60015460ff600160a81b90910416151582151514156105145760006104ed565b60018054831515600160a81b810260ff60a81b199092169190911790915560408051918252517f10f9a0a95673b0837d1dce21fd3bffcb6d760435e9b5300b75a271182f75f8229181900360200190a160005b90505b919050565b600154600160a81b900460ff1681565b6001546001600160a01b031681565b600154600160a01b900460ff1681565b60006105a86109eb565b6105b8576104ed60016005610a46565b60015460ff600160a01b90910416151582151514156105d85760006104ed565b60018054831515600160a01b90810260ff60a01b199092169190911791829055604080519190920460ff161515815290517fabb56a15fd39488c914b324690b88f30d7daec63d2131ca0ef47e5739068c86e9181900360200190a16000610567565b60006106446109eb565b610654576104ed60016010610a46565b600180546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9929181900390910190a160005b9392505050565b6002546001600160a01b031681565b6003546000906001600160a01b0316331415806106f257506003546001600160a01b0316155b1561070957610702600180610a46565b90506107c4565b60028054600380546001600160a01b038082166001600160a01b031980861682179687905590921690925560408051938316808552949092166020840152815190927fd604de94d45953f9138079ec1b82d533cb2160c906d1076d1f7ed54befbca97a92908290030190a1600354604080516001600160a01b038085168252909216602083015280517fe945ccee5d701fc83f9b8aa8ca94ea4219ec1fcbd4f4cab4f0ea57c5c3e1d8159281900390910190a160005b925050505b90565b6003546001600160a01b031681565b60006107e06109eb565b6107f0576104ed60016012610a46565b60025460408051639d244f9f60e01b81526001600160a01b03928316600482015291841660248301525173a731585ab05fc9f83555cf9bff8f58ee94e18f8591639d244f9f916044808301926020929190829003018186803b15801561085557600080fd5b505afa158015610869573d6000803e3d6000fd5b505050506040513d602081101561087f57600080fd5b5051610891576104ed60016011610a46565b600380546001600160a01b038481166001600160a01b0319831617928390556040805192821680845293909116602083015280517fe945ccee5d701fc83f9b8aa8ca94ea4219ec1fcbd4f4cab4f0ea57c5c3e1d8159281900390910190a160006106b6565b6001546000906001600160a01b031633141580610911575033155b156109225761070260016000610a46565b60008054600180546001600160a01b038082166001600160a01b031980861682179687905590921690925560408051938316808552949092166020840152815190927ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc92908290030190a1600154604080516001600160a01b038085168252909216602083015280517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99281900390910190a160006107bf565b6000546001600160a01b031681565b600080546001600160a01b031633148015610a0f5750600154600160a81b900460ff165b80610a4157503373a731585ab05fc9f83555cf9bff8f58ee94e18f85148015610a415750600154600160a01b900460ff165b905090565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0836015811115610a7557fe5b83601b811115610a8157fe5b604080519283526020830191909152600082820152519081900360600190a18260158111156106b657fefea265627a7a72315820a5cf9491a370c17ee98b3c08c728cc0ddad83bd43ca76c92dc106835bfccb25664736f6c63430005110032a26469706673582212208a96c2a28ddd4b98261bdfa999ea5d2c82be5083ceb4cff54fd6859d30e2f08564736f6c634300060c0033
Deployed ByteCode
0x608060405234801561001057600080fd5b506004361061012c5760003560e01c80635710c6d8116100ad578063a970e76c11610071578063a970e76c14610270578063ac4afa3814610283578063b86579d4146102a7578063d88ff1f4146102ba578063f2fde38b146102cf5761012c565b80635710c6d81461020c578063715018a61461022d5780638da5cb5b14610235578063a155497c1461024a578063a3ed91c61461025d5761012c565b8063218a3bbe116100f4578063218a3bbe146101a857806326bb81d7146101c957806343e20a1d146101d15780634a7462ee146101e45780634ae26ea1146102045761012c565b806304f03c6f1461013157806307421978146101465780630a83d1b0146101595780631e1c6a071461016c57806320c32bfe14610195575b600080fd5b61014461013f366004612216565b6102e2565b005b610144610154366004612157565b61033d565b610144610167366004612196565b61037c565b61017f61017a366004612157565b61047a565b60405161018c91906126bf565b60405180910390f35b6101446101a336600461240f565b61048f565b6101bb6101b6366004612216565b610612565b60405161018c929190612668565b61017f610ab5565b61017f6101df366004612157565b610abe565b6101f76101f2366004612157565b610ad3565b60405161018c9190612608565b6101bb610b49565b61021f61021a36600461230e565b610e99565b60405161018c929190612b82565b610144611437565b61023d6114c0565b60405161018c919061259b565b610144610258366004612196565b6114cf565b6101bb61026b366004612157565b611592565b61017f61027e366004612157565b611823565b6102966102913660046123df565b611838565b60405161018c9594939291906126ca565b6101446102b536600461224e565b61190f565b6102c2611a03565b60405161018c9190612655565b6101446102dd366004612157565b611b2d565b6102ea611bee565b6001600160a01b03166102fb6114c0565b6001600160a01b03161461032a5760405162461bcd60e51b815260040161032190612970565b60405180910390fd5b6068805460ff1916911515919091179055565b336000908152606a602090815260408220805460018101825590835291200180546001600160a01b0319166001600160a01b0392909216919091179055565b610384611bee565b6001600160a01b03166103956114c0565b6001600160a01b0316146103bb5760405162461bcd60e51b815260040161032190612970565b816103d85760405162461bcd60e51b81526004016103219061273f565b60005b828110156104395781606b60008686858181106103f457fe5b90506020020160208101906104099190612157565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790556001016103db565b507f31b67e6853df85403a8c4f4f46dc53f48f700d6917c8e3ec8c77a0e6fd56793b83838360405161046d939291906125af565b60405180910390a1505050565b60676020526000908152604090205460ff1681565b60006065848154811061049e57fe5b600091825260209182902060026005909202010154604080516303e1469160e61b815290516001600160a01b039092169350839263f851a44092600480840193829003018186803b1580156104f257600080fd5b505afa158015610506573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052a919061217a565b6001600160a01b0316336001600160a01b03161480156105b65750806001600160a01b0316630a755ec26040518163ffffffff1660e01b815260040160206040518083038186803b15801561057e57600080fd5b505afa158015610592573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b69190612232565b806105d957506105c46114c0565b6001600160a01b0316336001600160a01b0316145b6105e257600080fd5b8282606586815481106105f157fe5b6000918252602090912061060b9360059092020191611fff565b5050505050565b6060806000805b6065548110156107805760006065828154811061063257fe5b60009182526020918290206002600590920201015460408051630b09572160e41b815290516001600160a01b039092169350839263b095721092600480840193829003018186803b15801561068657600080fd5b505afa9250505080156106b6575060408051601f3d908101601f191682019092526106b391810190612232565b60015b6106bf57610770565b80156106cc575050610778565b816001600160a01b031663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b15801561070557600080fd5b505afa925050508015610735575060408051601f3d908101601f191682019092526107329181019061217a565b60015b61073e5761076e565b6001600160a01b0381166000908152606b602052604090205460ff1615158815151461076c57505050610778565b505b505b506001909101905b600101610619565b5060608167ffffffffffffffff8111801561079a57600080fd5b506040519080825280602002602001820160405280156107c4578160200160208202803683370190505b50905060608267ffffffffffffffff811180156107e057600080fd5b5060405190808252806020026020018201604052801561081a57816020015b61080761207d565b8152602001906001900390816107ff5790505b5090506000805b606554811015610aa85760006065828154811061083a57fe5b60009182526020918290206002600590920201015460408051630b09572160e41b815290516001600160a01b039092169350839263b095721092600480840193829003018186803b15801561088e57600080fd5b505afa9250505080156108be575060408051601f3d908101601f191682019092526108bb91810190612232565b60015b6108c757610978565b80156108d4575050610aa0565b816001600160a01b031663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b15801561090d57600080fd5b505afa92505050801561093d575060408051601f3d908101601f1916820190925261093a9181019061217a565b60015b61094657610976565b6001600160a01b0381166000908152606b602052604090205460ff1615158b15151461097457505050610aa0565b505b505b8185848151811061098557fe5b6020026020010181815250506065828154811061099e57fe5b600091825260209182902060408051600593909302909101805460026001821615610100026000190190911604601f8101859004909402830160c090810190925260a0830184815292939092849290918491840182828015610a415780601f10610a1657610100808354040283529160200191610a41565b820191906000526020600020905b815481529060010190602001808311610a2457829003601f168201915b505050918352505060018201546001600160a01b0390811660208301526002830154166040820152600382015460608201526004909101546080909101528451859085908110610a8d57fe5b6020908102919091010152506001909101905b600101610821565b5091945092505050915091565b60685460ff1681565b606b6020526000908152604090205460ff1681565b6001600160a01b0381166000908152606a6020908152604091829020805483518184028101840190945280845260609392830182828015610b3d57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b1f575b50505050509050919050565b6060806000805b606554811015610c0e5760658181548110610b6757fe5b60009182526020918290206002600590920201015460408051630b09572160e41b815290516001600160a01b039092169263b095721092600480840193829003018186803b158015610bb857600080fd5b505afa925050508015610be8575060408051601f3d908101601f19168201909252610be591810190612232565b60015b610bf157610bff565b8015610bfd5750610c06565b505b6001909101905b600101610b50565b5060608167ffffffffffffffff81118015610c2857600080fd5b50604051908082528060200260200182016040528015610c52578160200160208202803683370190505b50905060608267ffffffffffffffff81118015610c6e57600080fd5b50604051908082528060200260200182016040528015610ca857816020015b610c9561207d565b815260200190600190039081610c8d5790505b5090506000805b606554811015610e8d5760658181548110610cc657fe5b60009182526020918290206002600590920201015460408051630b09572160e41b815290516001600160a01b039092169263b095721092600480840193829003018186803b158015610d1757600080fd5b505afa925050508015610d47575060408051601f3d908101601f19168201909252610d4491810190612232565b60015b610d5057610d5e565b8015610d5c5750610e85565b505b80848381518110610d6b57fe5b60200260200101818152505060658181548110610d8457fe5b600091825260209182902060408051600593909302909101805460026001821615610100026000190190911604601f8101859004909402830160c090810190925260a0830184815292939092849290918491840182828015610e275780601f10610dfc57610100808354040283529160200191610e27565b820191906000526020600020905b815481529060010190602001808311610e0a57829003601f168201915b505050918352505060018201546001600160a01b0390811660208301526002830154166040820152600382015460608201526004909101546080909101528351849084908110610e7357fe5b60209081029190910101526001909101905b600101610caf565b50919450925050509091565b6000806001600160a01b038716610ec25760405162461bcd60e51b81526004016103219061287e565b6001600160a01b038316610ee85760405162461bcd60e51b8152600401610321906129f8565b606060405180610b600160405280610b358152602001612c31610b35913990506000338a43604051602001610f1f9392919061255c565b6040516020818303038152906040528051906020012090506000818351602085016000f59050803b610f70577f4661696c656420746f206465706c6f7920556e6974726f6c6c65722e000000006000fd5b60405163e992a04160e01b815281906001600160a01b0382169063e992a04190610f9e908e9060040161259b565b602060405180830381600087803b158015610fb857600080fd5b505af1158015610fcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ff091906123f7565b1561100d5760405162461bcd60e51b8152600401610321906129a5565b604051630ea826e360e11b81528b906001600160a01b03821690631d504dc69061103b90859060040161259b565b600060405180830381600087803b15801561105557600080fd5b505af1158015611069573d6000803e3d6000fd5b505060405163317b0b7760e01b81528592506001600160a01b038316915063317b0b779061109b908e90600401612b79565b602060405180830381600087803b1580156110b557600080fd5b505af11580156110c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ed91906123f7565b1561110a5760405162461bcd60e51b81526004016103219061270a565b604051634fd42e1760e01b81526001600160a01b03821690634fd42e1790611136908d90600401612b79565b602060405180830381600087803b15801561115057600080fd5b505af1158015611164573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118891906123f7565b156111a55760405162461bcd60e51b81526004016103219061276c565b6040516355ee1fe160e01b81526001600160a01b038216906355ee1fe1906111d1908c9060040161259b565b602060405180830381600087803b1580156111eb57600080fd5b505af11580156111ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122391906123f7565b156112405760405162461bcd60e51b8152600401610321906127fb565b8b156112e257604051634a956fad60e11b81526001600160a01b0382169063952adf5a90611273906001906004016126bf565b602060405180830381600087803b15801561128d57600080fd5b505af11580156112a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c591906123f7565b156112e25760405162461bcd60e51b815260040161032190612a42565b604051636a9998b360e11b81526001600160a01b0382169063d53331669061130f906001906004016126bf565b602060405180830381600087803b15801561132957600080fd5b505af115801561133d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136191906123f7565b1561137e5760405162461bcd60e51b8152600401610321906128db565b604051632dc7468360e21b81526001600160a01b0384169063b71d1a0c906113aa90339060040161259b565b602060405180830381600087803b1580156113c457600080fd5b505af11580156113d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113fc91906123f7565b156114195760405162461bcd60e51b815260040161032190612926565b6114238e85611bf2565b9e939d50929b505050505050505050505050565b61143f611bee565b6001600160a01b03166114506114c0565b6001600160a01b0316146114765760405162461bcd60e51b815260040161032190612970565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6033546001600160a01b031690565b6114d7611bee565b6001600160a01b03166114e86114c0565b6001600160a01b03161461150e5760405162461bcd60e51b815260040161032190612970565b8161152b5760405162461bcd60e51b815260040161032190612a90565b60005b8281101561158c57816069600086868581811061154757fe5b905060200201602081019061155c9190612157565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905560010161152e565b50505050565b6001600160a01b0381166000908152606660205260409020546060908190819067ffffffffffffffff811180156115c857600080fd5b506040519080825280602002602001820160405280156115f2578160200160208202803683370190505b506001600160a01b03851660009081526066602052604090205490915060609067ffffffffffffffff8111801561162857600080fd5b5060405190808252806020026020018201604052801561166257816020015b61164f61207d565b8152602001906001900390816116475790505b50905060005b6001600160a01b038616600090815260666020526040902054811015611818576001600160a01b03861660009081526066602052604090208054829081106116ac57fe5b90600052602060002001548382815181106116c357fe5b602002602001018181525050606560666000886001600160a01b03166001600160a01b03168152602001908152602001600020828154811061170157fe5b90600052602060002001548154811061171657fe5b600091825260209182902060408051600593909302909101805460026001821615610100026000190190911604601f8101859004909402830160c090810190925260a08301848152929390928492909184918401828280156117b95780601f1061178e576101008083540402835291602001916117b9565b820191906000526020600020905b81548152906001019060200180831161179c57829003601f168201915b505050918352505060018201546001600160a01b039081166020830152600283015416604082015260038201546060820152600490910154608090910152825183908390811061180557fe5b6020908102919091010152600101611668565b509092509050915091565b60696020526000908152604090205460ff1681565b6065818154811061184557fe5b60009182526020918290206005919091020180546040805160026001841615610100026000190190931692909204601f8101859004850283018501909152808252919350918391908301828280156118de5780601f106118b3576101008083540402835291602001916118de565b820191906000526020600020905b8154815290600101906020018083116118c157829003601f168201915b5050505060018301546002840154600385015460049095015493946001600160a01b03928316949290911692509085565b600054610100900460ff16806119285750611928611dfa565b80611936575060005460ff16155b6119525760405162461bcd60e51b815260040161032190612830565b600054610100900460ff1615801561197d576000805460ff1961ff0019909116610100171660011790555b611985611e0b565b6068805460ff191684151517905560005b82518110156119eb576001606960008584815181106119b157fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055600101611996565b5080156119fe576000805461ff00191690555b505050565b60606065805480602002602001604051908101604052809291908181526020016000905b82821015611b245760008481526020908190206040805160058602909201805460026001821615610100026000190190911604601f8101859004909402830160c090810190925260a0830184815292939092849290918491840182828015611ad05780601f10611aa557610100808354040283529160200191611ad0565b820191906000526020600020905b815481529060010190602001808311611ab357829003601f168201915b50505091835250506001828101546001600160a01b03908116602080850191909152600285015490911660408401526003840154606084015260049093015460809092019190915291835292019101611a27565b50505050905090565b611b35611bee565b6001600160a01b0316611b466114c0565b6001600160a01b031614611b6c5760405162461bcd60e51b815260040161032190612970565b6001600160a01b038116611b925760405162461bcd60e51b8152600401610321906127b5565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b03811660009081526067602052604081205460ff1615611c2b5760405162461bcd60e51b815260040161032190612af0565b60685460ff161580611c4c57503360009081526069602052604090205460ff165b611c685760405162461bcd60e51b815260040161032190612b35565b606483511115611c8a5760405162461bcd60e51b815260040161032190612ac0565b611c9261207d565b506040805160a081018252848152336020808301919091526001600160a01b0385169282019290925243606082015242608082015260658054600181018255600091909152815180519293849360059093027f8ff97419363ffd7000167f130ef7168fbea05faf9251824ca5043f113cc6a7c70192611d1492849201906120be565b50602082810151600183810180546001600160a01b03199081166001600160a01b0394851617909155604080870151600287018054909316908516179091556060860151600386015560809095015160049094019390935533600090815260668352848120606580548254808801845592845285842060001991820193019290925592891682526067909352849020805460ff1916909317909255905491517f18075ab463b4dc5842f37ecd67abeb192eda5d073f2c08509e189ad173d5c02092611de29201908490612b99565b60405180910390a15050606554600019015b92915050565b6000611e0530611e9e565b15905090565b600054610100900460ff1680611e245750611e24611dfa565b80611e32575060005460ff16155b611e4e5760405162461bcd60e51b815260040161032190612830565b600054610100900460ff16158015611e79576000805460ff1961ff0019909116610100171660011790555b611e81611ea4565b611e89611f25565b8015611e9b576000805461ff00191690555b50565b3b151590565b600054610100900460ff1680611ebd5750611ebd611dfa565b80611ecb575060005460ff16155b611ee75760405162461bcd60e51b815260040161032190612830565b600054610100900460ff16158015611e89576000805460ff1961ff0019909116610100171660011790558015611e9b576000805461ff001916905550565b600054610100900460ff1680611f3e5750611f3e611dfa565b80611f4c575060005460ff16155b611f685760405162461bcd60e51b815260040161032190612830565b600054610100900460ff16158015611f93576000805460ff1961ff0019909116610100171660011790555b6000611f9d611bee565b603380546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015611e9b576000805461ff001916905550565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106120405782800160ff1982351617855561206d565b8280016001018555821561206d579182015b8281111561206d578235825591602001919060010190612052565b5061207992915061212c565b5090565b6040518060a001604052806060815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106120ff57805160ff191683800117855561206d565b8280016001018555821561206d579182015b8281111561206d578251825591602001919060010190612111565b5b80821115612079576000815560010161212d565b8035611df481612c0d565b8035611df481612c22565b600060208284031215612168578081fd5b813561217381612c0d565b9392505050565b60006020828403121561218b578081fd5b815161217381612c0d565b6000806000604084860312156121aa578182fd5b833567ffffffffffffffff808211156121c1578384fd5b818601915086601f8301126121d4578384fd5b8135818111156121e2578485fd5b87602080830285010111156121f5578485fd5b6020928301955093505084013561220b81612c22565b809150509250925092565b600060208284031215612227578081fd5b813561217381612c22565b600060208284031215612243578081fd5b815161217381612c22565b60008060408385031215612260578182fd5b823561226b81612c22565b915060208381013567ffffffffffffffff80821115612288578384fd5b818601915086601f83011261229b578384fd5b8135818111156122a9578485fd5b83810291506122b9848301612bba565b8181528481019084860184860187018b10156122d3578788fd5b8795505b838610156122fd576122e98b82612141565b8352600195909501949186019186016122d7565b508096505050505050509250929050565b60008060008060008060c08789031215612326578182fd5b863567ffffffffffffffff8082111561233d578384fd5b818901915089601f830112612350578384fd5b81358181111561235e578485fd5b60209150612374601f8201601f19168301612bba565b8181528b83838601011115612387578586fd5b8183850184830137908101820185905297506123a58a8a8301612141565b965050506123b6886040890161214c565b935060608701359250608087013591506123d38860a08901612141565b90509295509295509295565b6000602082840312156123f0578081fd5b5035919050565b600060208284031215612408578081fd5b5051919050565b600080600060408486031215612423578283fd5b83359250602084013567ffffffffffffffff80821115612441578384fd5b818601915086601f830112612454578384fd5b813581811115612462578485fd5b876020828501011115612473578485fd5b6020830194508093505050509250925092565b6000815180845260208085018081965082840281019150828601855b858110156124cc5782840389526124ba848351612505565b988501989350908401906001016124a2565b5091979650505050505050565b600081518084526124f1816020860160208601612be1565b601f01601f19169290920160200192915050565b6000815160a0845261251a60a08501826124d9565b9050602083015160018060a01b038082166020870152806040860151166040870152505060608301516060850152608083015160808501528091505092915050565b60006bffffffffffffffffffffffff198560601b1682528351612586816014850160208801612be1565b60149201918201929092526034019392505050565b6001600160a01b0391909116815260200190565b6040808252810183905260008460608301825b868110156125f257602083356125d781612c0d565b6001600160a01b0316835292830192909101906001016125c2565b5080925050508215156020830152949350505050565b6020808252825182820181905260009190848201906040850190845b818110156126495783516001600160a01b031683529284019291840191600101612624565b50909695505050505050565b6000602082526121736020830184612486565b604080825283519082018190526000906020906060840190828701845b828110156126a157815184529284019290840190600101612685565b505050838103828501526126b58186612486565b9695505050505050565b901515815260200190565b600060a082526126dd60a08301886124d9565b6001600160a01b039687166020840152949095166040820152606081019290925260809091015292915050565b6020808252818101527f4661696c656420746f2073657420706f6f6c20636c6f736520666163746f722e604082015260600190565b60208082526013908201527227379030b236b4b7399039bab8383634b2b21760691b604082015260600190565b60208082526029908201527f4661696c656420746f2073657420706f6f6c206c69717569646174696f6e20696040820152683731b2b73a34bb329760b91b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252818101527f4661696c656420746f2073657420706f6f6c207072696365206f7261636c652e604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526039908201527f4e6f20436f6d7074726f6c6c657220696d706c656d656e746174696f6e20636f60408201527f6e74726163742061646472657373207370656369666965642e00000000000000606082015260800190565b6020808252602b908201527f4661696c656420746f20656e61626c6520706f6f6c206175746f20696d706c6560408201526a36b2b73a30ba34b7b7399760a91b606082015260800190565b6020808252602a908201527f4661696c656420746f207365742070656e64696e672061646d696e206f6e20556040820152693734ba3937b63632b91760b11b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526033908201527f4661696c656420746f207365742070656e64696e6720696d706c656d656e74616040820152723a34b7b71037b7102ab734ba3937b63632b91760691b606082015260800190565b6020808252602a908201527f4e6f2050726963654f7261636c6520636f6e747261637420616464726573732060408201526939b832b1b4b334b2b21760b11b606082015260800190565b6020808252602e908201527f4661696c656420746f20656e666f72636520737570706c6965722f626f72726f60408201526d3bb2b9103bb434ba32b634b9ba1760911b606082015260800190565b6020808252601690820152752737903232b83637bcb2b9399039bab8383634b2b21760511b604082015260600190565b6020808252601690820152752737903837b7b6103730b6b29039bab8383634b2b21760511b604082015260600190565b60208082526025908201527f506f6f6c20616c72656164792065786973747320696e207468652064697265636040820152643a37b93c9760d91b606082015260800190565b60208082526024908201527f53656e646572206973206e6f74206f6e206465706c6f7965722077686974656c60408201526334b9ba1760e11b606082015260800190565b90815260200190565b9182526001600160a01b0316602082015260400190565b600083825260406020830152612bb26040830184612505565b949350505050565b60405181810167ffffffffffffffff81118282101715612bd957600080fd5b604052919050565b60005b83811015612bfc578181015183820152602001612be4565b8381111561158c5750506000910152565b6001600160a01b0381168114611e9b57600080fd5b8015158114611e9b57600080fdfe60806040526001805460ff60a81b1960ff60a01b19909116600160a01b1716600160a81b17905534801561003257600080fd5b50600080546001600160a01b03191633179055610ae1806100546000396000f3fe6080604052600436106100a75760003560e01c8063bb82aa5e11610064578063bb82aa5e14610437578063c1e803341461044c578063dcfbc0c714610461578063e992a04114610476578063e9c714f2146104a9578063f851a440146104be576100a7565b80630225ab9d1461032b5780630a755ec21461036957806326782247146103925780632f1069ba146103c35780636f63af0b146103d8578063b71d1a0c14610404575b3330146102a85760408051600481526024810182526020810180516001600160e01b0316633757348b60e21b1781529151815160009360609330939092909182918083835b6020831061010b5780518252601f1990920191602091820191016100ec565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d806000811461016b576040519150601f19603f3d011682016040523d82523d6000602084013e610170565b606091505b5091509150600082156101975781806020019051602081101561019257600080fd5b505190505b80156102a4576002546040805163bbcdd6d360e01b81526001600160a01b0390921660048301525160009173a731585ab05fc9f83555cf9bff8f58ee94e18f859163bbcdd6d391602480820192602092909190829003018186803b1580156101fe57600080fd5b505afa158015610212573d6000803e3d6000fd5b505050506040513d602081101561022857600080fd5b50516002549091506001600160a01b038083169116146102a257600280546001600160a01b038381166001600160a01b0319831617928390556040805192821680845293909116602083015280517fd604de94d45953f9138079ec1b82d533cb2160c906d1076d1f7ed54befbca97a9281900390910190a1505b505b5050505b6002546040516000916001600160a01b031690829036908083838082843760405192019450600093509091505080830381855af49150503d806000811461030b576040519150601f19603f3d011682016040523d82523d6000602084013e610310565b606091505b505090506040513d6000823e818015610327573d82f35b3d82fd5b34801561033757600080fd5b506103576004803603602081101561034e57600080fd5b503515156104d3565b60408051918252519081900360200190f35b34801561037557600080fd5b5061037e61056f565b604080519115158252519081900360200190f35b34801561039e57600080fd5b506103a761057f565b604080516001600160a01b039092168252519081900360200190f35b3480156103cf57600080fd5b5061037e61058e565b3480156103e457600080fd5b50610357600480360360208110156103fb57600080fd5b5035151561059e565b34801561041057600080fd5b506103576004803603602081101561042757600080fd5b50356001600160a01b031661063a565b34801561044357600080fd5b506103a76106bd565b34801561045857600080fd5b506103576106cc565b34801561046d57600080fd5b506103a76107c7565b34801561048257600080fd5b506103576004803603602081101561049957600080fd5b50356001600160a01b03166107d6565b3480156104b557600080fd5b506103576108f6565b3480156104ca57600080fd5b506103a76109dc565b60006104dd6109eb565b6104f4576104ed60016005610a46565b905061056a565b60015460ff600160a81b90910416151582151514156105145760006104ed565b60018054831515600160a81b810260ff60a81b199092169190911790915560408051918252517f10f9a0a95673b0837d1dce21fd3bffcb6d760435e9b5300b75a271182f75f8229181900360200190a160005b90505b919050565b600154600160a81b900460ff1681565b6001546001600160a01b031681565b600154600160a01b900460ff1681565b60006105a86109eb565b6105b8576104ed60016005610a46565b60015460ff600160a01b90910416151582151514156105d85760006104ed565b60018054831515600160a01b90810260ff60a01b199092169190911791829055604080519190920460ff161515815290517fabb56a15fd39488c914b324690b88f30d7daec63d2131ca0ef47e5739068c86e9181900360200190a16000610567565b60006106446109eb565b610654576104ed60016010610a46565b600180546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9929181900390910190a160005b9392505050565b6002546001600160a01b031681565b6003546000906001600160a01b0316331415806106f257506003546001600160a01b0316155b1561070957610702600180610a46565b90506107c4565b60028054600380546001600160a01b038082166001600160a01b031980861682179687905590921690925560408051938316808552949092166020840152815190927fd604de94d45953f9138079ec1b82d533cb2160c906d1076d1f7ed54befbca97a92908290030190a1600354604080516001600160a01b038085168252909216602083015280517fe945ccee5d701fc83f9b8aa8ca94ea4219ec1fcbd4f4cab4f0ea57c5c3e1d8159281900390910190a160005b925050505b90565b6003546001600160a01b031681565b60006107e06109eb565b6107f0576104ed60016012610a46565b60025460408051639d244f9f60e01b81526001600160a01b03928316600482015291841660248301525173a731585ab05fc9f83555cf9bff8f58ee94e18f8591639d244f9f916044808301926020929190829003018186803b15801561085557600080fd5b505afa158015610869573d6000803e3d6000fd5b505050506040513d602081101561087f57600080fd5b5051610891576104ed60016011610a46565b600380546001600160a01b038481166001600160a01b0319831617928390556040805192821680845293909116602083015280517fe945ccee5d701fc83f9b8aa8ca94ea4219ec1fcbd4f4cab4f0ea57c5c3e1d8159281900390910190a160006106b6565b6001546000906001600160a01b031633141580610911575033155b156109225761070260016000610a46565b60008054600180546001600160a01b038082166001600160a01b031980861682179687905590921690925560408051938316808552949092166020840152815190927ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc92908290030190a1600154604080516001600160a01b038085168252909216602083015280517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99281900390910190a160006107bf565b6000546001600160a01b031681565b600080546001600160a01b031633148015610a0f5750600154600160a81b900460ff165b80610a4157503373a731585ab05fc9f83555cf9bff8f58ee94e18f85148015610a415750600154600160a01b900460ff165b905090565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0836015811115610a7557fe5b83601b811115610a8157fe5b604080519283526020830191909152600082820152519081900360600190a18260158111156106b657fefea265627a7a72315820a5cf9491a370c17ee98b3c08c728cc0ddad83bd43ca76c92dc106835bfccb25664736f6c63430005110032a26469706673582212208a96c2a28ddd4b98261bdfa999ea5d2c82be5083ceb4cff54fd6859d30e2f08564736f6c634300060c0033