Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 16555304 | 511 days ago | IN | Create: NFTXInventoryStaking | 0 ETH | 0.11652189 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
NFTXInventoryStaking
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./util/PausableUpgradeable.sol"; import "./util/SafeERC20Upgradeable.sol"; import "./util/Create2.sol"; import "./proxy/UpgradeableBeacon.sol"; import "./proxy/Create2BeaconProxy.sol"; import "./token/XTokenUpgradeable.sol"; import "./interface/INFTXInventoryStaking.sol"; import "./interface/INFTXVaultFactory.sol"; import "./interface/ITimelockExcludeList.sol"; // Author: 0xKiwi. // Pausing codes for inventory staking are: // 10: Deposit contract NFTXInventoryStaking is PausableUpgradeable, UpgradeableBeacon, INFTXInventoryStaking { using SafeERC20Upgradeable for IERC20Upgradeable; // Small locktime to prevent flash deposits. uint256 internal constant DEFAULT_LOCKTIME = 2; // bytes internal constant beaconCode = type(Create2BeaconProxy).creationCode; bytes internal constant beaconCode = hex"608060405261002f60017fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d51610451565b6000805160206107cf8339815191521461005957634e487b7160e01b600052600160045260246000fd5b610078336040518060200160405280600081525061007d60201b60201c565b6104a0565b6100908261023860201b6100291760201c565b6100ef5760405162461bcd60e51b815260206004820152602560248201527f426561636f6e50726f78793a20626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b610172826001600160a01b031663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561012b57600080fd5b505afa15801561013f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016391906103db565b61023860201b6100291760201c565b6101e45760405162461bcd60e51b815260206004820152603460248201527f426561636f6e50726f78793a20626561636f6e20696d706c656d656e7461746960448201527f6f6e206973206e6f74206120636f6e747261637400000000000000000000000060648201526084016100e6565b6000805160206107cf8339815191528281558151156102335761023161020861023e565b836040518060600160405280602181526020016107ef602191396102cb60201b61002f1760201c565b505b505050565b3b151590565b60006102566000805160206107cf8339815191525490565b6001600160a01b031663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561028e57600080fd5b505afa1580156102a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c691906103db565b905090565b6060833b61032a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016100e6565b600080856001600160a01b0316856040516103459190610402565b600060405180830381855af49150503d8060008114610380576040519150601f19603f3d011682016040523d82523d6000602084013e610385565b606091505b5090925090506103968282866103a2565b925050505b9392505050565b606083156103b157508161039b565b8251156103c15782518084602001fd5b8160405162461bcd60e51b81526004016100e6919061041e565b6000602082840312156103ec578081fd5b81516001600160a01b038116811461039b578182fd5b60008251610414818460208701610474565b9190910192915050565b602081526000825180602084015261043d816040850160208701610474565b601f01601f19169190910160400192915050565b60008282101561046f57634e487b7160e01b81526011600452602481fd5b500390565b60005b8381101561048f578181015183820152602001610477565b838111156102315750506000910152565b610320806104af6000396000f3fe60806040523661001357610011610017565b005b6100115b61002761002261012e565b6101da565b565b3b151590565b6060833b6100aa5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516100d2919061026b565b600060405180830381855af49150503d806000811461010d576040519150601f19603f3d011682016040523d82523d6000602084013e610112565b606091505b50915091506101228282866101fe565b925050505b9392505050565b60006101587fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d505490565b73ffffffffffffffffffffffffffffffffffffffff1663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561019d57600080fd5b505afa1580156101b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d59190610237565b905090565b3660008037600080366000845af43d6000803e8080156101f9573d6000f35b3d6000fd5b6060831561020d575081610127565b82511561021d5782518084602001fd5b8160405162461bcd60e51b81526004016100a19190610287565b600060208284031215610248578081fd5b815173ffffffffffffffffffffffffffffffffffffffff81168114610127578182fd5b6000825161027d8184602087016102ba565b9190910192915050565b60208152600082518060208401526102a68160408501602087016102ba565b601f01601f19169190910160400192915050565b60005b838110156102d55781810151838201526020016102bd565b838111156102e4576000848401525b5050505056fea2646970667358221220186f38c9868951054a26d8e78dfc388c93ba31dab42cd0982029e5f5f85fc42164736f6c63430008040033a3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50426561636f6e50726f78793a2066756e6374696f6e2063616c6c206661696c6564"; // this code is used to determine xToken address while calling `directWithdraw()` bytes internal constant duplicateBeaconCode = hex"608060405261002f60017fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d51610451565b6000805160206107cf8339815191521461005957634e487b7160e01b600052600160045260246000fd5b610078336040518060200160405280600081525061007d60201b60201c565b6104a0565b6100908261023860201b6100291760201c565b6100ef5760405162461bcd60e51b815260206004820152602560248201527f426561636f6e50726f78793a20626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b610172826001600160a01b031663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561012b57600080fd5b505afa15801561013f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016391906103db565b61023860201b6100291760201c565b6101e45760405162461bcd60e51b815260206004820152603460248201527f426561636f6e50726f78793a20626561636f6e20696d706c656d656e7461746960448201527f6f6e206973206e6f74206120636f6e747261637400000000000000000000000060648201526084016100e6565b6000805160206107cf8339815191528281558151156102335761023161020861023e565b836040518060600160405280602181526020016107ef602191396102cb60201b61002f1760201c565b505b505050565b3b151590565b60006102566000805160206107cf8339815191525490565b6001600160a01b031663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561028e57600080fd5b505afa1580156102a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c691906103db565b905090565b6060833b61032a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016100e6565b600080856001600160a01b0316856040516103459190610402565b600060405180830381855af49150503d8060008114610380576040519150601f19603f3d011682016040523d82523d6000602084013e610385565b606091505b5090925090506103968282866103a2565b925050505b9392505050565b606083156103b157508161039b565b8251156103c15782518084602001fd5b8160405162461bcd60e51b81526004016100e6919061041e565b6000602082840312156103ec578081fd5b81516001600160a01b038116811461039b578182fd5b60008251610414818460208701610474565b9190910192915050565b602081526000825180602084015261043d816040850160208701610474565b601f01601f19169190910160400192915050565b60008282101561046f57634e487b7160e01b81526011600452602481fd5b500390565b60005b8381101561048f578181015183820152602001610477565b838111156102315750506000910152565b610320806104af6000396000f3fe60806040523661001357610011610017565b005b6100115b61002761002261012e565b6101da565b565b3b151590565b6060833b6100aa5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516100d2919061026b565b600060405180830381855af49150503d806000811461010d576040519150601f19603f3d011682016040523d82523d6000602084013e610112565b606091505b50915091506101228282866101fe565b925050505b9392505050565b60006101587fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d505490565b73ffffffffffffffffffffffffffffffffffffffff1663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561019d57600080fd5b505afa1580156101b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d59190610237565b905090565b3660008037600080366000845af43d6000803e8080156101f9573d6000f35b3d6000fd5b6060831561020d575081610127565b82511561021d5782518084602001fd5b8160405162461bcd60e51b81526004016100a19190610287565b600060208284031215610248578081fd5b815173ffffffffffffffffffffffffffffffffffffffff81168114610127578182fd5b6000825161027d8184602087016102ba565b9190910192915050565b60208152600082518060208401526102a68160408501602087016102ba565b601f01601f19169190910160400192915050565b60005b838110156102d55781810151838201526020016102bd565b838111156102e4576000848401525b5050505056fea26469706673582212207fa982cc2707bb3e77c4aa1e243fbbca2a5b4869b87391cdd12e6a56d1e36e9164736f6c63430008040033a3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50426561636f6e50726f78793a2066756e6374696f6e2063616c6c206661696c6564"; INFTXVaultFactory public override nftxVaultFactory; uint256 public inventoryLockTimeErc20; ITimelockExcludeList public timelockExcludeList; event XTokenCreated(uint256 vaultId, address baseToken, address xToken); event Deposit( uint256 vaultId, uint256 baseTokenAmount, uint256 xTokenAmount, uint256 timelockUntil, address sender ); event Withdraw( uint256 vaultId, uint256 baseTokenAmount, uint256 xTokenAmount, address sender ); event DirectWithdraw( address xToken, uint256 baseTokenAmount, uint256 xTokenAmount, address sender ); event FeesReceived(uint256 vaultId, uint256 amount); function __NFTXInventoryStaking_init(address _nftxVaultFactory) external virtual override initializer { __Ownable_init(); nftxVaultFactory = INFTXVaultFactory(_nftxVaultFactory); address xTokenImpl = address(new XTokenUpgradeable()); __UpgradeableBeacon__init(xTokenImpl); } modifier onlyAdmin() { require( msg.sender == owner() || msg.sender == nftxVaultFactory.feeDistributor(), "LPStaking: Not authorized" ); _; } function setTimelockExcludeList(address addr) external onlyOwner { timelockExcludeList = ITimelockExcludeList(addr); } function setInventoryLockTimeErc20(uint256 time) external onlyOwner { require(time <= 14 days, "Lock too long"); inventoryLockTimeErc20 = time; } function isAddressTimelockExcluded(address addr, uint256 vaultId) public view returns (bool) { if (address(timelockExcludeList) == address(0)) { return false; } else { return timelockExcludeList.isExcluded(addr, vaultId); } } function deployXTokenForVault(uint256 vaultId) public virtual override { address baseToken = nftxVaultFactory.vault(vaultId); address deployedXToken = xTokenAddr(address(baseToken)); if (isContract(deployedXToken)) { return; } address xToken = _deployXToken(baseToken); emit XTokenCreated(vaultId, baseToken, xToken); } function receiveRewards(uint256 vaultId, uint256 amount) external virtual override onlyAdmin returns (bool) { address baseToken = nftxVaultFactory.vault(vaultId); address deployedXToken = xTokenAddr(address(baseToken)); // Don't distribute rewards unless there are people to distribute to. // Also added here if the distribution token is not deployed, just forfeit rewards for now. if ( !isContract(deployedXToken) || XTokenUpgradeable(deployedXToken).totalSupply() == 0 ) { return false; } // We "pull" to the dividend tokens so the fee distributor only needs to approve this contract. IERC20Upgradeable(baseToken).safeTransferFrom( msg.sender, deployedXToken, amount ); emit FeesReceived(vaultId, amount); return true; } // Enter staking. Staking, get minted shares and // locks base tokens and mints xTokens. function deposit(uint256 vaultId, uint256 _amount) external virtual override { onlyOwnerIfPaused(10); uint256 timelockTime = isAddressTimelockExcluded(msg.sender, vaultId) ? 0 : inventoryLockTimeErc20; ( IERC20Upgradeable baseToken, XTokenUpgradeable xToken, uint256 xTokensMinted ) = _timelockMintFor(vaultId, msg.sender, _amount, timelockTime); // Lock the base token in the xtoken contract baseToken.safeTransferFrom(msg.sender, address(xToken), _amount); emit Deposit(vaultId, _amount, xTokensMinted, timelockTime, msg.sender); } function timelockMintFor( uint256 vaultId, uint256 amount, address to, uint256 timelockLength ) external virtual override returns (uint256) { onlyOwnerIfPaused(10); require(nftxVaultFactory.zapContracts(msg.sender), "Not staking zap"); require( nftxVaultFactory.excludedFromFees(msg.sender), "Not fee excluded" ); (, , uint256 xTokensMinted) = _timelockMintFor( vaultId, to, amount, timelockLength ); emit Deposit(vaultId, amount, xTokensMinted, timelockLength, to); return xTokensMinted; } // Leave the bar. Claim back your tokens. // Unlocks the staked + gained tokens and burns xTokens. function withdraw(uint256 vaultId, uint256 _share) external virtual override { IERC20Upgradeable baseToken = IERC20Upgradeable( nftxVaultFactory.vault(vaultId) ); XTokenUpgradeable xToken = XTokenUpgradeable( xTokenAddr(address(baseToken)) ); uint256 baseTokensRedeemed = xToken.burnXTokens(msg.sender, _share); emit Withdraw(vaultId, baseTokensRedeemed, _share, msg.sender); } function directWithdraw(uint256 vaultId, uint256 _share) external { IERC20Upgradeable baseToken = IERC20Upgradeable( nftxVaultFactory.vault(vaultId) ); bytes32 salt = keccak256(abi.encodePacked(baseToken)); address xToken = Create2.computeAddress( salt, keccak256(duplicateBeaconCode) ); uint256 baseTokensRedeemed = XTokenUpgradeable(xToken).burnXTokens( msg.sender, _share ); emit DirectWithdraw(xToken, baseTokensRedeemed, _share, msg.sender); } function xTokenShareValue(uint256 vaultId) external view virtual override returns (uint256) { IERC20Upgradeable baseToken = IERC20Upgradeable( nftxVaultFactory.vault(vaultId) ); XTokenUpgradeable xToken = XTokenUpgradeable( xTokenAddr(address(baseToken)) ); require(address(xToken) != address(0), "XToken not deployed"); uint256 multiplier = 10**18; return xToken.totalSupply() > 0 ? (multiplier * baseToken.balanceOf(address(xToken))) / xToken.totalSupply() : multiplier; } function timelockUntil(uint256 vaultId, address who) external view returns (uint256) { XTokenUpgradeable xToken = XTokenUpgradeable(vaultXToken(vaultId)); return xToken.timelockUntil(who); } function balanceOf(uint256 vaultId, address who) external view returns (uint256) { XTokenUpgradeable xToken = XTokenUpgradeable(vaultXToken(vaultId)); return xToken.balanceOf(who); } // Note: this function does not guarantee the token is deployed, we leave that check to elsewhere to save gas. function xTokenAddr(address baseToken) public view virtual override returns (address) { bytes32 salt = keccak256(abi.encodePacked(baseToken)); address tokenAddr = Create2.computeAddress(salt, keccak256(beaconCode)); return tokenAddr; } function vaultXToken(uint256 vaultId) public view virtual override returns (address) { address baseToken = nftxVaultFactory.vault(vaultId); address xToken = xTokenAddr(baseToken); require(isContract(xToken), "XToken not deployed"); return xToken; } function _timelockMintFor( uint256 vaultId, address account, uint256 _amount, uint256 timelockLength ) internal returns ( IERC20Upgradeable, XTokenUpgradeable, uint256 ) { deployXTokenForVault(vaultId); IERC20Upgradeable baseToken = IERC20Upgradeable( nftxVaultFactory.vault(vaultId) ); XTokenUpgradeable xToken = XTokenUpgradeable( (xTokenAddr(address(baseToken))) ); uint256 xTokensMinted = xToken.mintXTokens( account, _amount, timelockLength ); return (baseToken, xToken, xTokensMinted); } function _deployXToken(address baseToken) internal returns (address) { string memory symbol = IERC20Metadata(baseToken).symbol(); symbol = string(abi.encodePacked("x", symbol)); bytes32 salt = keccak256(abi.encodePacked(baseToken)); address deployedXToken = Create2.deploy(0, salt, beaconCode); XTokenUpgradeable(deployedXToken).__XToken_init( baseToken, symbol, symbol ); return deployedXToken; } 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; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./INFTXVaultFactory.sol"; interface INFTXInventoryStaking { function nftxVaultFactory() external view returns (INFTXVaultFactory); function vaultXToken(uint256 vaultId) external view returns (address); function xTokenAddr(address baseToken) external view returns (address); function xTokenShareValue(uint256 vaultId) external view returns (uint256); function __NFTXInventoryStaking_init(address nftxFactory) external; function deployXTokenForVault(uint256 vaultId) external; function receiveRewards(uint256 vaultId, uint256 amount) external returns (bool); function timelockMintFor( uint256 vaultId, uint256 amount, address to, uint256 timelockLength ) external returns (uint256); function deposit(uint256 vaultId, uint256 _amount) external; function withdraw(uint256 vaultId, uint256 _share) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../proxy/IBeacon.sol"; interface INFTXVaultFactory is IBeacon { // Read functions. function numVaults() external view returns (uint256); function zapContract() external view returns (address); function zapContracts(address addr) external view returns (bool); function feeDistributor() external view returns (address); function eligibilityManager() external view returns (address); function vault(uint256 vaultId) external view returns (address); function allVaults() external view returns (address[] memory); function vaultsForAsset(address asset) external view returns (address[] memory); function isLocked(uint256 id) external view returns (bool); function excludedFromFees(address addr) external view returns (bool); function factoryMintFee() external view returns (uint64); function factoryRandomRedeemFee() external view returns (uint64); function factoryTargetRedeemFee() external view returns (uint64); function factoryRandomSwapFee() external view returns (uint64); function factoryTargetSwapFee() external view returns (uint64); function vaultFees(uint256 vaultId) external view returns ( uint256, uint256, uint256, uint256, uint256 ); event NewFeeDistributor(address oldDistributor, address newDistributor); event NewZapContract(address oldZap, address newZap); event UpdatedZapContract(address zap, bool excluded); event FeeExclusion(address feeExcluded, bool excluded); event NewEligibilityManager(address oldEligManager, address newEligManager); event NewVault( uint256 indexed vaultId, address vaultAddress, address assetAddress ); event UpdateVaultFees( uint256 vaultId, uint256 mintFee, uint256 randomRedeemFee, uint256 targetRedeemFee, uint256 randomSwapFee, uint256 targetSwapFee ); event DisableVaultFees(uint256 vaultId); event UpdateFactoryFees( uint256 mintFee, uint256 randomRedeemFee, uint256 targetRedeemFee, uint256 randomSwapFee, uint256 targetSwapFee ); // Write functions. function __NFTXVaultFactory_init( address _vaultImpl, address _feeDistributor ) external; function createVault( string calldata name, string calldata symbol, address _assetAddress, bool is1155, bool allowAllItems ) external returns (uint256); function setFeeDistributor(address _feeDistributor) external; function setEligibilityManager(address _eligibilityManager) external; function setZapContract(address _zapContract, bool _excluded) external; function setFeeExclusion(address _excludedAddr, bool excluded) external; function setFactoryFees( uint256 mintFee, uint256 randomRedeemFee, uint256 targetRedeemFee, uint256 randomSwapFee, uint256 targetSwapFee ) external; function setVaultFees( uint256 vaultId, uint256 mintFee, uint256 randomRedeemFee, uint256 targetRedeemFee, uint256 randomSwapFee, uint256 targetSwapFee ) external; function disableVaultFees(uint256 vaultId) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface ITimelockExcludeList { function isExcluded(address addr, uint256 vaultId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../util/Address.sol"; import "./Proxy.sol"; import "./IBeacon.sol"; /** * @dev This contract implements a proxy that gets the implementation address for each call from a {UpgradeableBeacon}. * Slightly modified to allow using beacon proxies with Create2. * * The beacon address is stored in storage slot `uint256(keccak256('eip1967.proxy.beacon')) - 1`, so that it doesn't * conflict with the storage layout of the implementation behind the proxy. * * _Available since v3.4._ */ contract Create2BeaconProxy is Proxy { /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 private constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Initializes the proxy with `beacon`. * * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This * will typically be an encoded function call, and allows initializating the storage of the proxy like a Solidity * constructor. * * Requirements: * * - `beacon` must be a contract with the interface {IBeacon}. */ constructor() payable { assert( _BEACON_SLOT == bytes32(uint256(keccak256("eip1967.proxy.beacon")) - 1) ); _setBeacon(msg.sender, ""); } /** * @dev Returns the current beacon address. */ function _beacon() internal view virtual returns (address beacon) { bytes32 slot = _BEACON_SLOT; // solhint-disable-next-line no-inline-assembly assembly { beacon := sload(slot) } } /** * @dev Returns the current implementation address of the associated beacon. */ function _implementation() internal view virtual override returns (address) { return IBeacon(_beacon()).childImplementation(); } /** * @dev Changes the proxy to use a new beacon. * * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. * * Requirements: * * - `beacon` must be a contract. * - The implementation returned by `beacon` must be a contract. */ function _setBeacon(address beacon, bytes memory data) internal virtual { require( Address.isContract(beacon), "BeaconProxy: beacon is not a contract" ); require( Address.isContract(IBeacon(beacon).childImplementation()), "BeaconProxy: beacon implementation is not a contract" ); bytes32 slot = _BEACON_SLOT; // solhint-disable-next-line no-inline-assembly assembly { sstore(slot, beacon) } if (data.length > 0) { Address.functionDelegateCall( _implementation(), data, "BeaconProxy: function call failed" ); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function childImplementation() external view returns (address); function upgradeChildTo(address newImplementation) external; }
// SPDX-License-Identifier: MIT // solhint-disable-next-line compiler-version pragma solidity ^0.8.0; /** * @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 {ERC1967Proxy-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 || !_initialized, "Initializable: contract is already initialized" ); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to * be specified by overriding the virtual {_implementation} function. * * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a * different contract through the {_delegate} function. * * The success and return data of the delegated call will be returned back to the caller of the proxy. */ abstract contract Proxy { /** * @dev Delegates the current call to `implementation`. * * This function does not return to its internall call site, it will return directly to the external caller. */ function _delegate(address implementation) internal virtual { // solhint-disable-next-line no-inline-assembly assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall( gas(), implementation, 0, calldatasize(), 0, 0 ) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function * and {_fallback} should delegate. */ function _implementation() internal view virtual returns (address); /** * @dev Delegates the current call to the address returned by `_implementation()`. * * This function does not return to its internall call site, it will return directly to the external caller. */ function _fallback() internal virtual { _beforeFallback(); _delegate(_implementation()); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other * function in the contract matches the call data. */ fallback() external payable virtual { _fallback(); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data * is empty. */ receive() external payable virtual { _fallback(); } /** * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback` * call, or as part of the Solidity `fallback` or `receive` functions. * * If overriden should call `super._beforeFallback()`. */ function _beforeFallback() internal virtual {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IBeacon.sol"; import "../util/Address.sol"; import "../util/OwnableUpgradeable.sol"; /** * @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their * implementation contract, which is where they will delegate all function calls. * * An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon. */ contract UpgradeableBeacon is IBeacon, OwnableUpgradeable { address private _childImplementation; /** * @dev Emitted when the child implementation returned by the beacon is changed. */ event Upgraded(address indexed childImplementation); /** * @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the * beacon. */ function __UpgradeableBeacon__init(address childImplementation_) public initializer { _setChildImplementation(childImplementation_); } /** * @dev Returns the current child implementation address. */ function childImplementation() public view virtual override returns (address) { return _childImplementation; } /** * @dev Upgrades the beacon to a new implementation. * * Emits an {Upgraded} event. * * Requirements: * * - msg.sender must be the owner of the contract. * - `newChildImplementation` must be a contract. */ function upgradeChildTo(address newChildImplementation) public virtual override onlyOwner { _setChildImplementation(newChildImplementation); } /** * @dev Sets the implementation contract address for this beacon * * Requirements: * * - `newChildImplementation` must be a contract. */ function _setChildImplementation(address newChildImplementation) private { require( Address.isContract(newChildImplementation), "UpgradeableBeacon: child implementation is not a contract" ); _childImplementation = newChildImplementation; emit Upgraded(newChildImplementation); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../proxy/Initializable.sol"; import "../util/ContextUpgradeable.sol"; import "./IERC20Upgradeable.sol"; import "./IERC20Metadata.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name_, string memory symbol_) internal initializer { __Context_init_unchained(); __ERC20_init_unchained(name_, symbol_); } function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer { _name = name_; _symbol = symbol_; } function _setMetadata(string memory name_, string memory symbol_) internal { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require( currentAllowance >= amount, "ERC20: transfer amount exceeds allowance" ); _approve(sender, _msgSender(), currentAllowance - amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve( _msgSender(), spender, _allowances[_msgSender()][spender] + addedValue ); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require( currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero" ); _approve(_msgSender(), spender, currentAllowance - subtractedValue); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require( senderBalance >= amount, "ERC20: transfer amount exceeds balance" ); _balances[sender] = senderBalance - amount; _balances[recipient] += amount; emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); _balances[account] = accountBalance - amount; _totalSupply -= amount; emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be to transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} uint256[45] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC20Upgradeable.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20Upgradeable { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval( address indexed owner, address indexed spender, uint256 value ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../util/OwnableUpgradeable.sol"; import "../util/SafeERC20Upgradeable.sol"; import "../token/ERC20Upgradeable.sol"; // XTokens let uou come in with some vault tokens, and leave with more! The longer you stay, the more vault tokens you get. // // This contract handles swapping to and from xSushi, SushiSwap's staking token. contract XTokenUpgradeable is OwnableUpgradeable, ERC20Upgradeable { using SafeERC20Upgradeable for IERC20Upgradeable; uint256 internal constant MAX_TIMELOCK = 2592000; IERC20Upgradeable public baseToken; mapping(address => uint256) internal timelock; event Timelocked(address user, uint256 until); function __XToken_init( address _baseToken, string memory name, string memory symbol ) public initializer { __Ownable_init(); // string memory _name = INFTXInventoryStaking(msg.sender).nftxVaultFactory().vault(); __ERC20_init(name, symbol); baseToken = IERC20Upgradeable(_baseToken); } // Needs to be called BEFORE new base tokens are deposited. function mintXTokens( address account, uint256 _amount, uint256 timelockLength ) external onlyOwner returns (uint256) { // Gets the amount of Base Token locked in the contract uint256 totalBaseToken = baseToken.balanceOf(address(this)); // Gets the amount of xTokens in existence uint256 totalShares = totalSupply(); // If no xTokens exist, mint it 1:1 to the amount put in if (totalShares == 0 || totalBaseToken == 0) { _timelockMint(account, _amount, timelockLength); return _amount; } // Calculate and mint the amount of xTokens the base tokens are worth. The ratio will change overtime, as xTokens are burned/minted and base tokens deposited + gained from fees / withdrawn. else { uint256 what = (_amount * totalShares) / totalBaseToken; _timelockMint(account, what, timelockLength); return what; } } function burnXTokens(address who, uint256 _share) external onlyOwner returns (uint256) { // Gets the amount of xToken in existence uint256 totalShares = totalSupply(); // Calculates the amount of base tokens the xToken is worth uint256 what = (_share * baseToken.balanceOf(address(this))) / totalShares; _burn(who, _share); baseToken.safeTransfer(who, what); return what; } function timelockAccount(address account, uint256 timelockLength) public virtual onlyOwner { require(timelockLength < MAX_TIMELOCK, "Too long lock"); uint256 timelockFinish = block.timestamp + timelockLength; if (timelockFinish > timelock[account]) { timelock[account] = timelockFinish; emit Timelocked(account, timelockFinish); } } function _burn(address who, uint256 amount) internal override { require(block.timestamp > timelock[who], "User locked"); super._burn(who, amount); } function timelockUntil(address account) public view returns (uint256) { return timelock[account]; } function _timelockMint( address account, uint256 amount, uint256 timelockLength ) internal virtual { timelockAccount(account, timelockLength); _mint(account, amount); } function _transfer( address from, address to, uint256 value ) internal override { require(block.timestamp > timelock[from], "User locked"); super._transfer(from, to, value); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ 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); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall( target, data, "Address: low-level delegate call failed" ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) private pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.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 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) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { 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.8.0; /** * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer. * `CREATE2` can be used to compute in advance the address where a smart * contract will be deployed, which allows for interesting new mechanisms known * as 'counterfactual interactions'. * * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more * information. */ library Create2 { /** * @dev Deploys a contract using `CREATE2`. The address where the contract * will be deployed can be known in advance via {computeAddress}. * * The bytecode for a contract can be obtained from Solidity with * `type(contractName).creationCode`. * * Requirements: * * - `bytecode` must not be empty. * - `salt` must have not been used for `bytecode` already. * - the factory must have a balance of at least `amount`. * - if `amount` is non-zero, `bytecode` must have a `payable` constructor. */ function deploy( uint256 amount, bytes32 salt, bytes memory bytecode ) internal returns (address) { address addr; require( address(this).balance >= amount, "Create2: insufficient balance" ); require(bytecode.length != 0, "Create2: bytecode length is zero"); // solhint-disable-next-line no-inline-assembly assembly { addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt) } require(addr != address(0), "Create2: Failed on deploy"); return addr; } /** * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the * `bytecodeHash` or `salt` will result in a new destination address. */ function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) { return computeAddress(salt, bytecodeHash, address(this)); } /** * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}. */ function computeAddress( bytes32 salt, bytes32 bytecodeHash, address deployer ) internal pure returns (address) { bytes32 _data = keccak256( abi.encodePacked(bytes1(0xff), deployer, salt, bytecodeHash) ); return address(uint160(uint256(_data))); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../proxy/Initializable.sol"; import "./ContextUpgradeable.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.8.0; import "./OwnableUpgradeable.sol"; contract PausableUpgradeable is OwnableUpgradeable { function __Pausable_init() internal initializer { __Ownable_init(); } event SetPaused(uint256 lockId, bool paused); event SetIsGuardian(address addr, bool isGuardian); mapping(address => bool) public isGuardian; mapping(uint256 => bool) public isPaused; // 0 : createVault // 1 : mint // 2 : redeem // 3 : swap // 4 : flashloan function onlyOwnerIfPaused(uint256 lockId) public view virtual { require(!isPaused[lockId] || msg.sender == owner(), "Paused"); } function unpause(uint256 lockId) public virtual onlyOwner { isPaused[lockId] = false; emit SetPaused(lockId, false); } function pause(uint256 lockId) public virtual { require(isGuardian[msg.sender], "Can't pause"); isPaused[lockId] = true; emit SetPaused(lockId, true); } function setIsGuardian(address addr, bool _isGuardian) public virtual onlyOwner { isGuardian[addr] = _isGuardian; emit SetIsGuardian(addr, _isGuardian); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./Address.sol"; import "../token/IERC20Upgradeable.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20Upgradeable { using Address for address; function safeTransfer( IERC20Upgradeable token, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transfer.selector, to, value) ); } function safeTransferFrom( IERC20Upgradeable token, address from, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value) ); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20Upgradeable token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn( token, abi.encodeWithSelector(token.approve.selector, spender, value) ); } function safeIncreaseAllowance( IERC20Upgradeable token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } function safeDecreaseAllowance( IERC20Upgradeable token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require( oldAllowance >= value, "SafeERC20: decreased allowance below zero" ); uint256 newAllowance = oldAllowance - value; _callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall( data, "SafeERC20: low-level call failed" ); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require( abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed" ); } } }
{ "evmVersion": "istanbul", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 1000 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"baseTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"xTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timelockUntil","type":"uint256"},{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"xToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"baseTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"xTokenAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"DirectWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeesReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"bool","name":"isGuardian","type":"bool"}],"name":"SetIsGuardian","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lockId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"SetPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"childImplementation","type":"address"}],"name":"Upgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"baseTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"xTokenAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":false,"internalType":"address","name":"baseToken","type":"address"},{"indexed":false,"internalType":"address","name":"xToken","type":"address"}],"name":"XTokenCreated","type":"event"},{"inputs":[{"internalType":"address","name":"_nftxVaultFactory","type":"address"}],"name":"__NFTXInventoryStaking_init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"childImplementation_","type":"address"}],"name":"__UpgradeableBeacon__init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"address","name":"who","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"childImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"}],"name":"deployXTokenForVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"_share","type":"uint256"}],"name":"directWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"inventoryLockTimeErc20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"vaultId","type":"uint256"}],"name":"isAddressTimelockExcluded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isGuardian","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nftxVaultFactory","outputs":[{"internalType":"contract INFTXVaultFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"lockId","type":"uint256"}],"name":"onlyOwnerIfPaused","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"lockId","type":"uint256"}],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"receiveRewards","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"}],"name":"setInventoryLockTimeErc20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"_isGuardian","type":"bool"}],"name":"setIsGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setTimelockExcludeList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"timelockExcludeList","outputs":[{"internalType":"contract ITimelockExcludeList","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"timelockLength","type":"uint256"}],"name":"timelockMintFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"address","name":"who","type":"address"}],"name":"timelockUntil","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"lockId","type":"uint256"}],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newChildImplementation","type":"address"}],"name":"upgradeChildTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"}],"name":"vaultXToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"_share","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"baseToken","type":"address"}],"name":"xTokenAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"}],"name":"xTokenShareValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50615702806100206000396000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80637c77b61611610104578063cda13d67116100a2578063f0f2a4d711610071578063f0f2a4d714610411578063f2fde38b14610424578063f36d52da14610437578063fabc1cbc1461044a57600080fd5b8063cda13d67146103c7578063da525716146103da578063e2bbb158146103eb578063e5956027146103fe57600080fd5b806392054f8b116100de57806392054f8b1461036b578063a2700d781461037e578063bdf2a43c14610391578063c23c6da0146103b457600080fd5b80637c77b61614610334578063881b2f2d146103475780638da5cb5b1461035a57600080fd5b80632699f55a1161017c5780633a2950af1161014b5780633a2950af146102f35780634363fcd214610306578063441a3e7014610319578063715018a61461032c57600080fd5b80632699f55a146102a35780633656eec2146102c457806337ce42bf146102d75780633801daf1146102e057600080fd5b806311ad9d38116101b857806311ad9d3814610257578063136439dd1461026a5780631f1713fc1461027d57806323845fb51461029057600080fd5b8063034fc83c146101df5780630b38768f1461020f5780630c68ba2114610224575b600080fd5b6101f26101ed36600461267a565b61045d565b6040516001600160a01b0390911681526020015b60405180910390f35b61022261021d3660046126ce565b610547565b005b610247610232366004612525565b60656020526000908152604090205460ff1681565b6040519015158152602001610206565b606a546101f2906001600160a01b031681565b61022261027836600461267a565b610711565b61022261028b366004612525565b6107c8565b61022261029e36600461255d565b61082e565b6102b66102b13660046126ef565b6108eb565b604051908152602001610206565b6102b66102d23660046126aa565b610b29565b6102b660695481565b6068546101f2906001600160a01b031681565b61022261030136600461267a565b610bbd565b6102b661031436600461267a565b610c6f565b6102226103273660046126ce565b610ee7565b610222611048565b61022261034236600461267a565b6110ec565b610247610355366004612595565b611160565b6033546001600160a01b03166101f2565b610222610379366004612525565b61121f565b61022261038c366004612525565b61129b565b61024761039f36600461267a565b60666020526000908152604090205460ff1681565b6102b66103c23660046126aa565b6113aa565b6101f26103d5366004612525565b611401565b6067546001600160a01b03166101f2565b6102226103f93660046126ce565b611473565b61022261040c366004612525565b611512565b61022261041f36600461267a565b6115ce565b610222610432366004612525565b6116c4565b6102476104453660046126ce565b6117f6565b61022261045836600461267a565b611a7c565b6068546040516340d1b7db60e11b81526004810183905260009182916001600160a01b03909116906381a36fb69060240160206040518083038186803b1580156104a657600080fd5b505afa1580156104ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104de9190612541565b905060006104eb82611401565b9050803b6105405760405162461bcd60e51b815260206004820152601360248201527f58546f6b656e206e6f74206465706c6f7965640000000000000000000000000060448201526064015b60405180910390fd5b9392505050565b6068546040516340d1b7db60e11b8152600481018490526000916001600160a01b0316906381a36fb69060240160206040518083038186803b15801561058c57600080fd5b505afa1580156105a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c49190612541565b6040516bffffffffffffffffffffffff19606083901b166020820152909150600090603401604051602081830303815290604052805190602001209050600061062f826040518061084001604052806108108152602001614ebd610810913980519060200120611b23565b6040516319e616a360e01b8152336004820152602481018690529091506000906001600160a01b038316906319e616a390604401602060405180830381600087803b15801561067d57600080fd5b505af1158015610691573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106b59190612692565b604080516001600160a01b0385168152602081018390529081018790523360608201529091507fe0b88c458b57c7c2bbc8dbf5b262a5bffa40cad29c4f1749512a230423d3e177906080015b60405180910390a1505050505050565b3360009081526065602052604090205460ff166107705760405162461bcd60e51b815260206004820152600b60248201527f43616e27742070617573650000000000000000000000000000000000000000006044820152606401610537565b600081815260666020908152604091829020805460ff191660019081179091558251848152918201527f77f1fcfcce67dc392d64f842056d2ec06c80986c47c910f7e79c5b23a2738d7491015b60405180910390a150565b6033546001600160a01b031633146108225760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610537565b61082b81611b97565b50565b6033546001600160a01b031633146108885760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610537565b6001600160a01b038216600081815260656020908152604091829020805460ff19168515159081179091558251938452908301527fd0b6b573d5442f7c29fd50d9735ae341581c25c6ed07748d50eda519f1ffa88a910160405180910390a15050565b60006108f7600a6110ec565b6068546040517fc6172ecd0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b039091169063c6172ecd9060240160206040518083038186803b15801561095357600080fd5b505afa158015610967573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098b91906125c0565b6109d75760405162461bcd60e51b815260206004820152600f60248201527f4e6f74207374616b696e67207a617000000000000000000000000000000000006044820152606401610537565b6068546040517fdbe66ca00000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b039091169063dbe66ca09060240160206040518083038186803b158015610a3357600080fd5b505afa158015610a47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6b91906125c0565b610ab75760405162461bcd60e51b815260206004820152601060248201527f4e6f7420666565206578636c75646564000000000000000000000000000000006044820152606401610537565b6000610ac586858786611c55565b604080518a8152602081018a9052808201839052606081018890526001600160a01b038916608082015290519194507ff6d712df0bc2e9953a525976e57448a1dcb9b85f49402ab6cce0cea20fc5249c935081900360a0019150a195945050505050565b600080610b358461045d565b6040516370a0823160e01b81526001600160a01b038581166004830152919250908216906370a08231906024015b60206040518083038186803b158015610b7b57600080fd5b505afa158015610b8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb39190612692565b9150505b92915050565b6033546001600160a01b03163314610c175760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610537565b62127500811115610c6a5760405162461bcd60e51b815260206004820152600d60248201527f4c6f636b20746f6f206c6f6e67000000000000000000000000000000000000006044820152606401610537565b606955565b6068546040516340d1b7db60e11b81526004810183905260009182916001600160a01b03909116906381a36fb69060240160206040518083038186803b158015610cb857600080fd5b505afa158015610ccc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf09190612541565b90506000610cfd82611401565b90506001600160a01b038116610d555760405162461bcd60e51b815260206004820152601360248201527f58546f6b656e206e6f74206465706c6f796564000000000000000000000000006044820152606401610537565b6000670de0b6b3a764000090506000826001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610d9d57600080fd5b505afa158015610db1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd59190612692565b11610de05780610ede565b816001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e1957600080fd5b505afa158015610e2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e519190612692565b6040516370a0823160e01b81526001600160a01b0384811660048301528516906370a082319060240160206040518083038186803b158015610e9257600080fd5b505afa158015610ea6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eca9190612692565b610ed4908361282b565b610ede919061280b565b95945050505050565b6068546040516340d1b7db60e11b8152600481018490526000916001600160a01b0316906381a36fb69060240160206040518083038186803b158015610f2c57600080fd5b505afa158015610f40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f649190612541565b90506000610f7182611401565b6040516319e616a360e01b8152336004820152602481018590529091506000906001600160a01b038316906319e616a390604401602060405180830381600087803b158015610fbf57600080fd5b505af1158015610fd3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ff79190612692565b60408051878152602081018390529081018690523360608201529091507f3049105fcf2a17b0c1862f64c05a6b2df2176ea17686f7cbf2689887594dd2f89060800160405180910390a15050505050565b6033546001600160a01b031633146110a25760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610537565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b60008181526066602052604090205460ff16158061111457506033546001600160a01b031633145b61082b5760405162461bcd60e51b815260206004820152600660248201527f50617573656400000000000000000000000000000000000000000000000000006044820152606401610537565b606a546000906001600160a01b031661117b57506000610bb7565b606a546040517f81e97b660000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015260248201859052909116906381e97b669060440160206040518083038186803b1580156111e057600080fd5b505afa1580156111f4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121891906125c0565b9050610bb7565b6033546001600160a01b031633146112795760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610537565b606a80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff16806112b4575060005460ff16155b6113175760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610537565b600054610100900460ff16158015611339576000805461ffff19166101011790555b611341611da6565b606880546001600160a01b0319166001600160a01b03841617905560405160009061136b90612518565b604051809103906000f080158015611387573d6000803e3d6000fd5b50905061139381611512565b5080156113a6576000805461ff00191690555b5050565b6000806113b68461045d565b6040517fc19ea0530000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301529192509082169063c19ea05390602401610b63565b6040516bffffffffffffffffffffffff19606083901b1660208201526000908190603401604051602081830303815290604052805190602001209050600061146b8260405180610840016040528061081081526020016146ad610810913980519060200120611b23565b949350505050565b61147d600a6110ec565b60006114893384611160565b61149557606954611498565b60005b905060008060006114ab86338787611c55565b919450925090506114c76001600160a01b038416338488611e68565b6040805187815260208101879052908101829052606081018590523360808201527ff6d712df0bc2e9953a525976e57448a1dcb9b85f49402ab6cce0cea20fc5249c9060a001610701565b600054610100900460ff168061152b575060005460ff16155b61158e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610537565b600054610100900460ff161580156115b0576000805461ffff19166101011790555b6115b982611b97565b80156113a6576000805461ff00191690555050565b6068546040516340d1b7db60e11b8152600481018390526000916001600160a01b0316906381a36fb69060240160206040518083038186803b15801561161357600080fd5b505afa158015611627573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164b9190612541565b9050600061165882611401565b9050803b1561166657505050565b600061167183611ef6565b604080518681526001600160a01b03868116602083015283168183015290519192507fb3f4e35b757d28b36d957b4485e408df4f1b3a43f1fe56a7a74eb66f9904d734919081900360600190a150505050565b6033546001600160a01b0316331461171e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610537565b6001600160a01b03811661179a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610537565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b600061180a6033546001600160a01b031690565b6001600160a01b0316336001600160a01b031614806118bf5750606860009054906101000a90046001600160a01b03166001600160a01b0316630d43e8ad6040518163ffffffff1660e01b815260040160206040518083038186803b15801561187257600080fd5b505afa158015611886573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118aa9190612541565b6001600160a01b0316336001600160a01b0316145b61190b5760405162461bcd60e51b815260206004820152601960248201527f4c505374616b696e673a204e6f7420617574686f72697a6564000000000000006044820152606401610537565b6068546040516340d1b7db60e11b8152600481018590526000916001600160a01b0316906381a36fb69060240160206040518083038186803b15801561195057600080fd5b505afa158015611964573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119889190612541565b9050600061199582611401565b9050803b1580611a135750806001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156119d957600080fd5b505afa1580156119ed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a119190612692565b155b15611a2357600092505050610bb7565b611a386001600160a01b038316338387611e68565b60408051868152602081018690527f0299314386021feac38b734d748626da8e75d6abb4e6a897c0f9c8f23ff42715910160405180910390a1506001949350505050565b6033546001600160a01b03163314611ad65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610537565b6000818152606660209081526040808320805460ff191690558051848152918201929092527f77f1fcfcce67dc392d64f842056d2ec06c80986c47c910f7e79c5b23a2738d7491016107bd565b604080517fff000000000000000000000000000000000000000000000000000000000000006020808301919091526bffffffffffffffffffffffff193060601b1660218301526035820185905260558083018590528351808403909101815260759092019092528051910120600090610540565b803b611c0b5760405162461bcd60e51b815260206004820152603960248201527f5570677261646561626c65426561636f6e3a206368696c6420696d706c656d6560448201527f6e746174696f6e206973206e6f74206120636f6e7472616374000000000000006064820152608401610537565b606780546001600160a01b0319166001600160a01b0383169081179091556040517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6000806000611c63876115ce565b6068546040516340d1b7db60e11b8152600481018990526000916001600160a01b0316906381a36fb69060240160206040518083038186803b158015611ca857600080fd5b505afa158015611cbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ce09190612541565b90506000611ced82611401565b6040517f7efe41b10000000000000000000000000000000000000000000000000000000081526001600160a01b038a81166004830152602482018a905260448201899052919250600091831690637efe41b190606401602060405180830381600087803b158015611d5d57600080fd5b505af1158015611d71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d959190612692565b929a91995091975095505050505050565b600054610100900460ff1680611dbf575060005460ff16155b611e225760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610537565b600054610100900460ff16158015611e44576000805461ffff19166101011790555b611e4c61207b565b611e5461212c565b801561082b576000805461ff001916905550565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052611ef0908590612221565b50505050565b600080826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611f3257600080fd5b505afa158015611f46573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611f6e91908101906125dc565b905080604051602001611f819190612775565b60408051601f19818403018152908290526bffffffffffffffffffffffff19606086901b16602083015291506000906034016040516020818303038152906040528051906020012090506000611ff460008360405180610840016040528061081081526020016146ad610810913961230b565b6040517f30fe73fd0000000000000000000000000000000000000000000000000000000081529091506001600160a01b038216906330fe73fd90612040908890879081906004016127ba565b600060405180830381600087803b15801561205a57600080fd5b505af115801561206e573d6000803e3d6000fd5b5092979650505050505050565b600054610100900460ff1680612094575060005460ff16155b6120f75760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610537565b600054610100900460ff16158015611e54576000805461ffff1916610101179055801561082b576000805461ff001916905550565b600054610100900460ff1680612145575060005460ff16155b6121a85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610537565b600054610100900460ff161580156121ca576000805461ffff19166101011790555b603380546001600160a01b0319163390811790915560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350801561082b576000805461ff001916905550565b6000612276826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661240d9092919063ffffffff16565b805190915015612306578080602001905181019061229491906125c0565b6123065760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610537565b505050565b6000808447101561235e5760405162461bcd60e51b815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401610537565b82516123ac5760405162461bcd60e51b815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401610537565b8383516020850187f590506001600160a01b03811661146b5760405162461bcd60e51b815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401610537565b606061146b848460008585843b6124665760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610537565b600080866001600160a01b031685876040516124829190612759565b60006040518083038185875af1925050503d80600081146124bf576040519150601f19603f3d011682016040523d82523d6000602084013e6124c4565b606091505b50915091506124d48282866124df565b979650505050505050565b606083156124ee575081610540565b8251156124fe5782518084602001fd5b8160405162461bcd60e51b815260040161053791906127f8565b611df1806128bc83390190565b600060208284031215612536578081fd5b813561054081612898565b600060208284031215612552578081fd5b815161054081612898565b6000806040838503121561256f578081fd5b823561257a81612898565b9150602083013561258a816128ad565b809150509250929050565b600080604083850312156125a7578182fd5b82356125b281612898565b946020939093013593505050565b6000602082840312156125d1578081fd5b8151610540816128ad565b6000602082840312156125ed578081fd5b815167ffffffffffffffff80821115612604578283fd5b818401915084601f830112612617578283fd5b81518181111561262957612629612882565b604051601f8201601f19908116603f0116810190838211818310171561265157612651612882565b81604052828152876020848701011115612669578586fd5b6124d4836020830160208801612856565b60006020828403121561268b578081fd5b5035919050565b6000602082840312156126a3578081fd5b5051919050565b600080604083850312156126bc578182fd5b82359150602083013561258a81612898565b600080604083850312156126e0578182fd5b50508035926020909101359150565b60008060008060808587031215612704578182fd5b8435935060208501359250604085013561271d81612898565b9396929550929360600135925050565b60008151808452612745816020860160208601612856565b601f01601f19169290920160200192915050565b6000825161276b818460208701612856565b9190910192915050565b7f78000000000000000000000000000000000000000000000000000000000000008152600082516127ad816001850160208701612856565b9190910160010192915050565b6001600160a01b03841681526060602082015260006127dc606083018561272d565b82810360408401526127ee818561272d565b9695505050505050565b602081526000610540602083018461272d565b60008261282657634e487b7160e01b81526012600452602481fd5b500490565b600081600019048311821515161561285157634e487b7160e01b81526011600452602481fd5b500290565b60005b83811015612871578181015183820152602001612859565b83811115611ef05750506000910152565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461082b57600080fd5b801515811461082b57600080fdfe608060405234801561001057600080fd5b50611dd1806100206000396000f3fe608060405234801561001057600080fd5b506004361061016c5760003560e01c80637efe41b1116100cd578063b068498d11610081578063c55dae6311610066578063c55dae63146102f4578063dd62ed3e14610307578063f2fde38b1461034057600080fd5b8063b068498d146102b8578063c19ea053146102cb57600080fd5b806395d89b41116100b257806395d89b411461028a578063a457c2d714610292578063a9059cbb146102a557600080fd5b80637efe41b1146102525780638da5cb5b1461026557600080fd5b806330fe73fd116101245780633950935111610109578063395093511461020e57806370a0823114610221578063715018a61461024a57600080fd5b806330fe73fd146101ea578063313ce567146101ff57600080fd5b806318160ddd1161015557806318160ddd146101b257806319e616a3146101c457806323b872dd146101d757600080fd5b806306fdde0314610171578063095ea7b31461018f575b600080fd5b610179610353565b6040516101869190611c67565b60405180910390f35b6101a261019d366004611bb8565b6103e5565b6040519015158152602001610186565b6067545b604051908152602001610186565b6101b66101d2366004611bb8565b6103fb565b6101a26101e5366004611b0c565b610528565b6101fd6101f8366004611b47565b6105f0565b005b60405160128152602001610186565b6101a261021c366004611bb8565b6106e0565b6101b661022f366004611ac0565b6001600160a01b031660009081526065602052604090205490565b6101fd610717565b6101b6610260366004611be1565b6107c8565b6033546001600160a01b03165b6040516001600160a01b039091168152602001610186565b610179610903565b6101a26102a0366004611bb8565b610912565b6101a26102b3366004611bb8565b6109c5565b6101fd6102c6366004611bb8565b6109d2565b6101b66102d9366004611ac0565b6001600160a01b031660009081526098602052604090205490565b609754610272906001600160a01b031681565b6101b6610315366004611ada565b6001600160a01b03918216600090815260666020908152604080832093909416825291909152205490565b6101fd61034e366004611ac0565b610b07565b60606068805461036290611d34565b80601f016020809104026020016040519081016040528092919081815260200182805461038e90611d34565b80156103db5780601f106103b0576101008083540402835291602001916103db565b820191906000526020600020905b8154815290600101906020018083116103be57829003601f168201915b5050505050905090565b60006103f2338484610c46565b50600192915050565b6033546000906001600160a01b0316331461045d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b600061046860675490565b6097546040516370a0823160e01b815230600482015291925060009183916001600160a01b0316906370a082319060240160206040518083038186803b1580156104b157600080fd5b505afa1580156104c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e99190611c33565b6104f39086611cd2565b6104fd9190611cb2565b90506105098585610d9f565b609754610520906001600160a01b03168683610e02565b949350505050565b6000610535848484610e82565b6001600160a01b0384166000908152606660209081526040808320338452909152902054828110156105cf5760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610454565b6105e385336105de8685611cf1565b610c46565b60019150505b9392505050565b600054610100900460ff1680610609575060005460ff16155b61066c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff1615801561068e576000805461ffff19166101011790555b610696610ee2565b6106a08383610fa5565b6097805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03861617905580156106da576000805461ff00191690555b50505050565b3360008181526066602090815260408083206001600160a01b038716845290915281205490916103f29185906105de908690611c9a565b6033546001600160a01b031633146107715760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610454565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a36033805473ffffffffffffffffffffffffffffffffffffffff19169055565b6033546000906001600160a01b031633146108255760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610454565b6097546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561086957600080fd5b505afa15801561087d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a19190611c33565b905060006108ae60675490565b90508015806108bb575081155b156108d5576108cb86868661106b565b84925050506105e9565b6000826108e28388611cd2565b6108ec9190611cb2565b90506108f987828761106b565b92506105e9915050565b60606069805461036290611d34565b3360009081526066602090815260408083206001600160a01b0386168452909152812054828110156109ac5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610454565b6109bb33856105de8685611cf1565b5060019392505050565b60006103f2338484610e82565b6033546001600160a01b03163314610a2c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610454565b62278d008110610a7e5760405162461bcd60e51b815260206004820152600d60248201527f546f6f206c6f6e67206c6f636b000000000000000000000000000000000000006044820152606401610454565b6000610a8a8242611c9a565b6001600160a01b038416600090815260986020526040902054909150811115610b02576001600160a01b038316600081815260986020908152604091829020849055815192835282018390527f38f63775093182d55eb9f15cb41c506fd976eadb1b4544ba0aeaed494ee70cde910160405180910390a15b505050565b6033546001600160a01b03163314610b615760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610454565b6001600160a01b038116610bdd5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610454565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36033805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6001600160a01b038316610cc15760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b038216610d3d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b0383811660008181526066602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b0382166000908152609860205260409020544211610df45760405162461bcd60e51b815260206004820152600b60248201526a155cd95c881b1bd8dad95960aa1b6044820152606401610454565b610dfe828261107f565b5050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610b02908490611205565b6001600160a01b0383166000908152609860205260409020544211610ed75760405162461bcd60e51b815260206004820152600b60248201526a155cd95c881b1bd8dad95960aa1b6044820152606401610454565b610b028383836112ea565b600054610100900460ff1680610efb575060005460ff16155b610f5e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff16158015610f80576000805461ffff19166101011790555b610f8861150b565b610f906115bc565b8015610fa2576000805461ff00191690555b50565b600054610100900460ff1680610fbe575060005460ff16155b6110215760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff16158015611043576000805461ffff19166101011790555b61104b61150b565b61105583836116be565b8015610b02576000805461ff0019169055505050565b61107583826109d2565b610b02838361179a565b6001600160a01b0382166110fb5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b0382166000908152606560205260409020548181101561118a5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610454565b6111948282611cf1565b6001600160a01b038416600090815260656020526040812091909155606780548492906111c2908490611cf1565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610d92565b600061125a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166118799092919063ffffffff16565b805190915015610b0257808060200190518101906112789190611c13565b610b025760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b0383166113665760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b0382166113e25760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b038316600090815260656020526040902054818110156114715760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610454565b61147b8282611cf1565b6001600160a01b0380861660009081526065602052604080822093909355908516815290812080548492906114b1908490611c9a565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516114fd91815260200190565b60405180910390a350505050565b600054610100900460ff1680611524575060005460ff16155b6115875760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff16158015610f90576000805461ffff19166101011790558015610fa2576000805461ff001916905550565b600054610100900460ff16806115d5575060005460ff16155b6116385760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff1615801561165a576000805461ffff19166101011790555b6033805473ffffffffffffffffffffffffffffffffffffffff19163390811790915560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015610fa2576000805461ff001916905550565b600054610100900460ff16806116d7575060005460ff16155b61173a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff1615801561175c576000805461ffff19166101011790555b825161176f906068906020860190611984565b508151611783906069906020850190611984565b508015610b02576000805461ff0019169055505050565b6001600160a01b0382166117f05760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610454565b80606760008282546118029190611c9a565b90915550506001600160a01b0382166000908152606560205260408120805483929061182f908490611c9a565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6060610520848460008585843b6118d25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610454565b600080866001600160a01b031685876040516118ee9190611c4b565b60006040518083038185875af1925050503d806000811461192b576040519150601f19603f3d011682016040523d82523d6000602084013e611930565b606091505b509150915061194082828661194b565b979650505050505050565b6060831561195a5750816105e9565b82511561196a5782518084602001fd5b8160405162461bcd60e51b81526004016104549190611c67565b82805461199090611d34565b90600052602060002090601f0160209004810192826119b257600085556119f8565b82601f106119cb57805160ff19168380011785556119f8565b828001600101855582156119f8579182015b828111156119f85782518255916020019190600101906119dd565b50611a04929150611a08565b5090565b5b80821115611a045760008155600101611a09565b80356001600160a01b0381168114611a3457600080fd5b919050565b600082601f830112611a49578081fd5b813567ffffffffffffffff80821115611a6457611a64611d85565b604051601f8301601f19908116603f01168101908282118183101715611a8c57611a8c611d85565b81604052838152866020858801011115611aa4578485fd5b8360208701602083013792830160200193909352509392505050565b600060208284031215611ad1578081fd5b6105e982611a1d565b60008060408385031215611aec578081fd5b611af583611a1d565b9150611b0360208401611a1d565b90509250929050565b600080600060608486031215611b20578081fd5b611b2984611a1d565b9250611b3760208501611a1d565b9150604084013590509250925092565b600080600060608486031215611b5b578283fd5b611b6484611a1d565b9250602084013567ffffffffffffffff80821115611b80578384fd5b611b8c87838801611a39565b93506040860135915080821115611ba1578283fd5b50611bae86828701611a39565b9150509250925092565b60008060408385031215611bca578182fd5b611bd383611a1d565b946020939093013593505050565b600080600060608486031215611bf5578283fd5b611bfe84611a1d565b95602085013595506040909401359392505050565b600060208284031215611c24578081fd5b815180151581146105e9578182fd5b600060208284031215611c44578081fd5b5051919050565b60008251611c5d818460208701611d08565b9190910192915050565b6020815260008251806020840152611c86816040850160208701611d08565b601f01601f19169190910160400192915050565b60008219821115611cad57611cad611d6f565b500190565b600082611ccd57634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615611cec57611cec611d6f565b500290565b600082821015611d0357611d03611d6f565b500390565b60005b83811015611d23578181015183820152602001611d0b565b838111156106da5750506000910152565b600181811c90821680611d4857607f821691505b60208210811415611d6957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fdfea264697066735822122063063acdd6925a304044a775786197375e3dd34ad90a07e424c8fcee00e484cd64736f6c63430008040033608060405261002f60017fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d51610451565b6000805160206107cf8339815191521461005957634e487b7160e01b600052600160045260246000fd5b610078336040518060200160405280600081525061007d60201b60201c565b6104a0565b6100908261023860201b6100291760201c565b6100ef5760405162461bcd60e51b815260206004820152602560248201527f426561636f6e50726f78793a20626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b610172826001600160a01b031663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561012b57600080fd5b505afa15801561013f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016391906103db565b61023860201b6100291760201c565b6101e45760405162461bcd60e51b815260206004820152603460248201527f426561636f6e50726f78793a20626561636f6e20696d706c656d656e7461746960448201527f6f6e206973206e6f74206120636f6e747261637400000000000000000000000060648201526084016100e6565b6000805160206107cf8339815191528281558151156102335761023161020861023e565b836040518060600160405280602181526020016107ef602191396102cb60201b61002f1760201c565b505b505050565b3b151590565b60006102566000805160206107cf8339815191525490565b6001600160a01b031663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561028e57600080fd5b505afa1580156102a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c691906103db565b905090565b6060833b61032a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016100e6565b600080856001600160a01b0316856040516103459190610402565b600060405180830381855af49150503d8060008114610380576040519150601f19603f3d011682016040523d82523d6000602084013e610385565b606091505b5090925090506103968282866103a2565b925050505b9392505050565b606083156103b157508161039b565b8251156103c15782518084602001fd5b8160405162461bcd60e51b81526004016100e6919061041e565b6000602082840312156103ec578081fd5b81516001600160a01b038116811461039b578182fd5b60008251610414818460208701610474565b9190910192915050565b602081526000825180602084015261043d816040850160208701610474565b601f01601f19169190910160400192915050565b60008282101561046f57634e487b7160e01b81526011600452602481fd5b500390565b60005b8381101561048f578181015183820152602001610477565b838111156102315750506000910152565b610320806104af6000396000f3fe60806040523661001357610011610017565b005b6100115b61002761002261012e565b6101da565b565b3b151590565b6060833b6100aa5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516100d2919061026b565b600060405180830381855af49150503d806000811461010d576040519150601f19603f3d011682016040523d82523d6000602084013e610112565b606091505b50915091506101228282866101fe565b925050505b9392505050565b60006101587fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d505490565b73ffffffffffffffffffffffffffffffffffffffff1663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561019d57600080fd5b505afa1580156101b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d59190610237565b905090565b3660008037600080366000845af43d6000803e8080156101f9573d6000f35b3d6000fd5b6060831561020d575081610127565b82511561021d5782518084602001fd5b8160405162461bcd60e51b81526004016100a19190610287565b600060208284031215610248578081fd5b815173ffffffffffffffffffffffffffffffffffffffff81168114610127578182fd5b6000825161027d8184602087016102ba565b9190910192915050565b60208152600082518060208401526102a68160408501602087016102ba565b601f01601f19169190910160400192915050565b60005b838110156102d55781810151838201526020016102bd565b838111156102e4576000848401525b5050505056fea2646970667358221220186f38c9868951054a26d8e78dfc388c93ba31dab42cd0982029e5f5f85fc42164736f6c63430008040033a3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50426561636f6e50726f78793a2066756e6374696f6e2063616c6c206661696c6564608060405261002f60017fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d51610451565b6000805160206107cf8339815191521461005957634e487b7160e01b600052600160045260246000fd5b610078336040518060200160405280600081525061007d60201b60201c565b6104a0565b6100908261023860201b6100291760201c565b6100ef5760405162461bcd60e51b815260206004820152602560248201527f426561636f6e50726f78793a20626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b610172826001600160a01b031663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561012b57600080fd5b505afa15801561013f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016391906103db565b61023860201b6100291760201c565b6101e45760405162461bcd60e51b815260206004820152603460248201527f426561636f6e50726f78793a20626561636f6e20696d706c656d656e7461746960448201527f6f6e206973206e6f74206120636f6e747261637400000000000000000000000060648201526084016100e6565b6000805160206107cf8339815191528281558151156102335761023161020861023e565b836040518060600160405280602181526020016107ef602191396102cb60201b61002f1760201c565b505b505050565b3b151590565b60006102566000805160206107cf8339815191525490565b6001600160a01b031663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561028e57600080fd5b505afa1580156102a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c691906103db565b905090565b6060833b61032a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016100e6565b600080856001600160a01b0316856040516103459190610402565b600060405180830381855af49150503d8060008114610380576040519150601f19603f3d011682016040523d82523d6000602084013e610385565b606091505b5090925090506103968282866103a2565b925050505b9392505050565b606083156103b157508161039b565b8251156103c15782518084602001fd5b8160405162461bcd60e51b81526004016100e6919061041e565b6000602082840312156103ec578081fd5b81516001600160a01b038116811461039b578182fd5b60008251610414818460208701610474565b9190910192915050565b602081526000825180602084015261043d816040850160208701610474565b601f01601f19169190910160400192915050565b60008282101561046f57634e487b7160e01b81526011600452602481fd5b500390565b60005b8381101561048f578181015183820152602001610477565b838111156102315750506000910152565b610320806104af6000396000f3fe60806040523661001357610011610017565b005b6100115b61002761002261012e565b6101da565b565b3b151590565b6060833b6100aa5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516100d2919061026b565b600060405180830381855af49150503d806000811461010d576040519150601f19603f3d011682016040523d82523d6000602084013e610112565b606091505b50915091506101228282866101fe565b925050505b9392505050565b60006101587fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d505490565b73ffffffffffffffffffffffffffffffffffffffff1663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561019d57600080fd5b505afa1580156101b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d59190610237565b905090565b3660008037600080366000845af43d6000803e8080156101f9573d6000f35b3d6000fd5b6060831561020d575081610127565b82511561021d5782518084602001fd5b8160405162461bcd60e51b81526004016100a19190610287565b600060208284031215610248578081fd5b815173ffffffffffffffffffffffffffffffffffffffff81168114610127578182fd5b6000825161027d8184602087016102ba565b9190910192915050565b60208152600082518060208401526102a68160408501602087016102ba565b601f01601f19169190910160400192915050565b60005b838110156102d55781810151838201526020016102bd565b838111156102e4576000848401525b5050505056fea26469706673582212207fa982cc2707bb3e77c4aa1e243fbbca2a5b4869b87391cdd12e6a56d1e36e9164736f6c63430008040033a3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50426561636f6e50726f78793a2066756e6374696f6e2063616c6c206661696c6564a2646970667358221220a6d8bd71e3c209440cbda6ee0e4b571d323b100b123ab27dd77d39b7b30a662564736f6c63430008040033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101da5760003560e01c80637c77b61611610104578063cda13d67116100a2578063f0f2a4d711610071578063f0f2a4d714610411578063f2fde38b14610424578063f36d52da14610437578063fabc1cbc1461044a57600080fd5b8063cda13d67146103c7578063da525716146103da578063e2bbb158146103eb578063e5956027146103fe57600080fd5b806392054f8b116100de57806392054f8b1461036b578063a2700d781461037e578063bdf2a43c14610391578063c23c6da0146103b457600080fd5b80637c77b61614610334578063881b2f2d146103475780638da5cb5b1461035a57600080fd5b80632699f55a1161017c5780633a2950af1161014b5780633a2950af146102f35780634363fcd214610306578063441a3e7014610319578063715018a61461032c57600080fd5b80632699f55a146102a35780633656eec2146102c457806337ce42bf146102d75780633801daf1146102e057600080fd5b806311ad9d38116101b857806311ad9d3814610257578063136439dd1461026a5780631f1713fc1461027d57806323845fb51461029057600080fd5b8063034fc83c146101df5780630b38768f1461020f5780630c68ba2114610224575b600080fd5b6101f26101ed36600461267a565b61045d565b6040516001600160a01b0390911681526020015b60405180910390f35b61022261021d3660046126ce565b610547565b005b610247610232366004612525565b60656020526000908152604090205460ff1681565b6040519015158152602001610206565b606a546101f2906001600160a01b031681565b61022261027836600461267a565b610711565b61022261028b366004612525565b6107c8565b61022261029e36600461255d565b61082e565b6102b66102b13660046126ef565b6108eb565b604051908152602001610206565b6102b66102d23660046126aa565b610b29565b6102b660695481565b6068546101f2906001600160a01b031681565b61022261030136600461267a565b610bbd565b6102b661031436600461267a565b610c6f565b6102226103273660046126ce565b610ee7565b610222611048565b61022261034236600461267a565b6110ec565b610247610355366004612595565b611160565b6033546001600160a01b03166101f2565b610222610379366004612525565b61121f565b61022261038c366004612525565b61129b565b61024761039f36600461267a565b60666020526000908152604090205460ff1681565b6102b66103c23660046126aa565b6113aa565b6101f26103d5366004612525565b611401565b6067546001600160a01b03166101f2565b6102226103f93660046126ce565b611473565b61022261040c366004612525565b611512565b61022261041f36600461267a565b6115ce565b610222610432366004612525565b6116c4565b6102476104453660046126ce565b6117f6565b61022261045836600461267a565b611a7c565b6068546040516340d1b7db60e11b81526004810183905260009182916001600160a01b03909116906381a36fb69060240160206040518083038186803b1580156104a657600080fd5b505afa1580156104ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104de9190612541565b905060006104eb82611401565b9050803b6105405760405162461bcd60e51b815260206004820152601360248201527f58546f6b656e206e6f74206465706c6f7965640000000000000000000000000060448201526064015b60405180910390fd5b9392505050565b6068546040516340d1b7db60e11b8152600481018490526000916001600160a01b0316906381a36fb69060240160206040518083038186803b15801561058c57600080fd5b505afa1580156105a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c49190612541565b6040516bffffffffffffffffffffffff19606083901b166020820152909150600090603401604051602081830303815290604052805190602001209050600061062f826040518061084001604052806108108152602001614ebd610810913980519060200120611b23565b6040516319e616a360e01b8152336004820152602481018690529091506000906001600160a01b038316906319e616a390604401602060405180830381600087803b15801561067d57600080fd5b505af1158015610691573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106b59190612692565b604080516001600160a01b0385168152602081018390529081018790523360608201529091507fe0b88c458b57c7c2bbc8dbf5b262a5bffa40cad29c4f1749512a230423d3e177906080015b60405180910390a1505050505050565b3360009081526065602052604090205460ff166107705760405162461bcd60e51b815260206004820152600b60248201527f43616e27742070617573650000000000000000000000000000000000000000006044820152606401610537565b600081815260666020908152604091829020805460ff191660019081179091558251848152918201527f77f1fcfcce67dc392d64f842056d2ec06c80986c47c910f7e79c5b23a2738d7491015b60405180910390a150565b6033546001600160a01b031633146108225760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610537565b61082b81611b97565b50565b6033546001600160a01b031633146108885760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610537565b6001600160a01b038216600081815260656020908152604091829020805460ff19168515159081179091558251938452908301527fd0b6b573d5442f7c29fd50d9735ae341581c25c6ed07748d50eda519f1ffa88a910160405180910390a15050565b60006108f7600a6110ec565b6068546040517fc6172ecd0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b039091169063c6172ecd9060240160206040518083038186803b15801561095357600080fd5b505afa158015610967573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098b91906125c0565b6109d75760405162461bcd60e51b815260206004820152600f60248201527f4e6f74207374616b696e67207a617000000000000000000000000000000000006044820152606401610537565b6068546040517fdbe66ca00000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b039091169063dbe66ca09060240160206040518083038186803b158015610a3357600080fd5b505afa158015610a47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6b91906125c0565b610ab75760405162461bcd60e51b815260206004820152601060248201527f4e6f7420666565206578636c75646564000000000000000000000000000000006044820152606401610537565b6000610ac586858786611c55565b604080518a8152602081018a9052808201839052606081018890526001600160a01b038916608082015290519194507ff6d712df0bc2e9953a525976e57448a1dcb9b85f49402ab6cce0cea20fc5249c935081900360a0019150a195945050505050565b600080610b358461045d565b6040516370a0823160e01b81526001600160a01b038581166004830152919250908216906370a08231906024015b60206040518083038186803b158015610b7b57600080fd5b505afa158015610b8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb39190612692565b9150505b92915050565b6033546001600160a01b03163314610c175760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610537565b62127500811115610c6a5760405162461bcd60e51b815260206004820152600d60248201527f4c6f636b20746f6f206c6f6e67000000000000000000000000000000000000006044820152606401610537565b606955565b6068546040516340d1b7db60e11b81526004810183905260009182916001600160a01b03909116906381a36fb69060240160206040518083038186803b158015610cb857600080fd5b505afa158015610ccc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf09190612541565b90506000610cfd82611401565b90506001600160a01b038116610d555760405162461bcd60e51b815260206004820152601360248201527f58546f6b656e206e6f74206465706c6f796564000000000000000000000000006044820152606401610537565b6000670de0b6b3a764000090506000826001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610d9d57600080fd5b505afa158015610db1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd59190612692565b11610de05780610ede565b816001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e1957600080fd5b505afa158015610e2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e519190612692565b6040516370a0823160e01b81526001600160a01b0384811660048301528516906370a082319060240160206040518083038186803b158015610e9257600080fd5b505afa158015610ea6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eca9190612692565b610ed4908361282b565b610ede919061280b565b95945050505050565b6068546040516340d1b7db60e11b8152600481018490526000916001600160a01b0316906381a36fb69060240160206040518083038186803b158015610f2c57600080fd5b505afa158015610f40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f649190612541565b90506000610f7182611401565b6040516319e616a360e01b8152336004820152602481018590529091506000906001600160a01b038316906319e616a390604401602060405180830381600087803b158015610fbf57600080fd5b505af1158015610fd3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ff79190612692565b60408051878152602081018390529081018690523360608201529091507f3049105fcf2a17b0c1862f64c05a6b2df2176ea17686f7cbf2689887594dd2f89060800160405180910390a15050505050565b6033546001600160a01b031633146110a25760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610537565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b60008181526066602052604090205460ff16158061111457506033546001600160a01b031633145b61082b5760405162461bcd60e51b815260206004820152600660248201527f50617573656400000000000000000000000000000000000000000000000000006044820152606401610537565b606a546000906001600160a01b031661117b57506000610bb7565b606a546040517f81e97b660000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015260248201859052909116906381e97b669060440160206040518083038186803b1580156111e057600080fd5b505afa1580156111f4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121891906125c0565b9050610bb7565b6033546001600160a01b031633146112795760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610537565b606a80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff16806112b4575060005460ff16155b6113175760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610537565b600054610100900460ff16158015611339576000805461ffff19166101011790555b611341611da6565b606880546001600160a01b0319166001600160a01b03841617905560405160009061136b90612518565b604051809103906000f080158015611387573d6000803e3d6000fd5b50905061139381611512565b5080156113a6576000805461ff00191690555b5050565b6000806113b68461045d565b6040517fc19ea0530000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301529192509082169063c19ea05390602401610b63565b6040516bffffffffffffffffffffffff19606083901b1660208201526000908190603401604051602081830303815290604052805190602001209050600061146b8260405180610840016040528061081081526020016146ad610810913980519060200120611b23565b949350505050565b61147d600a6110ec565b60006114893384611160565b61149557606954611498565b60005b905060008060006114ab86338787611c55565b919450925090506114c76001600160a01b038416338488611e68565b6040805187815260208101879052908101829052606081018590523360808201527ff6d712df0bc2e9953a525976e57448a1dcb9b85f49402ab6cce0cea20fc5249c9060a001610701565b600054610100900460ff168061152b575060005460ff16155b61158e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610537565b600054610100900460ff161580156115b0576000805461ffff19166101011790555b6115b982611b97565b80156113a6576000805461ff00191690555050565b6068546040516340d1b7db60e11b8152600481018390526000916001600160a01b0316906381a36fb69060240160206040518083038186803b15801561161357600080fd5b505afa158015611627573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164b9190612541565b9050600061165882611401565b9050803b1561166657505050565b600061167183611ef6565b604080518681526001600160a01b03868116602083015283168183015290519192507fb3f4e35b757d28b36d957b4485e408df4f1b3a43f1fe56a7a74eb66f9904d734919081900360600190a150505050565b6033546001600160a01b0316331461171e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610537565b6001600160a01b03811661179a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610537565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b600061180a6033546001600160a01b031690565b6001600160a01b0316336001600160a01b031614806118bf5750606860009054906101000a90046001600160a01b03166001600160a01b0316630d43e8ad6040518163ffffffff1660e01b815260040160206040518083038186803b15801561187257600080fd5b505afa158015611886573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118aa9190612541565b6001600160a01b0316336001600160a01b0316145b61190b5760405162461bcd60e51b815260206004820152601960248201527f4c505374616b696e673a204e6f7420617574686f72697a6564000000000000006044820152606401610537565b6068546040516340d1b7db60e11b8152600481018590526000916001600160a01b0316906381a36fb69060240160206040518083038186803b15801561195057600080fd5b505afa158015611964573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119889190612541565b9050600061199582611401565b9050803b1580611a135750806001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156119d957600080fd5b505afa1580156119ed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a119190612692565b155b15611a2357600092505050610bb7565b611a386001600160a01b038316338387611e68565b60408051868152602081018690527f0299314386021feac38b734d748626da8e75d6abb4e6a897c0f9c8f23ff42715910160405180910390a1506001949350505050565b6033546001600160a01b03163314611ad65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610537565b6000818152606660209081526040808320805460ff191690558051848152918201929092527f77f1fcfcce67dc392d64f842056d2ec06c80986c47c910f7e79c5b23a2738d7491016107bd565b604080517fff000000000000000000000000000000000000000000000000000000000000006020808301919091526bffffffffffffffffffffffff193060601b1660218301526035820185905260558083018590528351808403909101815260759092019092528051910120600090610540565b803b611c0b5760405162461bcd60e51b815260206004820152603960248201527f5570677261646561626c65426561636f6e3a206368696c6420696d706c656d6560448201527f6e746174696f6e206973206e6f74206120636f6e7472616374000000000000006064820152608401610537565b606780546001600160a01b0319166001600160a01b0383169081179091556040517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6000806000611c63876115ce565b6068546040516340d1b7db60e11b8152600481018990526000916001600160a01b0316906381a36fb69060240160206040518083038186803b158015611ca857600080fd5b505afa158015611cbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ce09190612541565b90506000611ced82611401565b6040517f7efe41b10000000000000000000000000000000000000000000000000000000081526001600160a01b038a81166004830152602482018a905260448201899052919250600091831690637efe41b190606401602060405180830381600087803b158015611d5d57600080fd5b505af1158015611d71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d959190612692565b929a91995091975095505050505050565b600054610100900460ff1680611dbf575060005460ff16155b611e225760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610537565b600054610100900460ff16158015611e44576000805461ffff19166101011790555b611e4c61207b565b611e5461212c565b801561082b576000805461ff001916905550565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052611ef0908590612221565b50505050565b600080826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611f3257600080fd5b505afa158015611f46573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611f6e91908101906125dc565b905080604051602001611f819190612775565b60408051601f19818403018152908290526bffffffffffffffffffffffff19606086901b16602083015291506000906034016040516020818303038152906040528051906020012090506000611ff460008360405180610840016040528061081081526020016146ad610810913961230b565b6040517f30fe73fd0000000000000000000000000000000000000000000000000000000081529091506001600160a01b038216906330fe73fd90612040908890879081906004016127ba565b600060405180830381600087803b15801561205a57600080fd5b505af115801561206e573d6000803e3d6000fd5b5092979650505050505050565b600054610100900460ff1680612094575060005460ff16155b6120f75760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610537565b600054610100900460ff16158015611e54576000805461ffff1916610101179055801561082b576000805461ff001916905550565b600054610100900460ff1680612145575060005460ff16155b6121a85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610537565b600054610100900460ff161580156121ca576000805461ffff19166101011790555b603380546001600160a01b0319163390811790915560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350801561082b576000805461ff001916905550565b6000612276826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661240d9092919063ffffffff16565b805190915015612306578080602001905181019061229491906125c0565b6123065760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610537565b505050565b6000808447101561235e5760405162461bcd60e51b815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401610537565b82516123ac5760405162461bcd60e51b815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401610537565b8383516020850187f590506001600160a01b03811661146b5760405162461bcd60e51b815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401610537565b606061146b848460008585843b6124665760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610537565b600080866001600160a01b031685876040516124829190612759565b60006040518083038185875af1925050503d80600081146124bf576040519150601f19603f3d011682016040523d82523d6000602084013e6124c4565b606091505b50915091506124d48282866124df565b979650505050505050565b606083156124ee575081610540565b8251156124fe5782518084602001fd5b8160405162461bcd60e51b815260040161053791906127f8565b611df1806128bc83390190565b600060208284031215612536578081fd5b813561054081612898565b600060208284031215612552578081fd5b815161054081612898565b6000806040838503121561256f578081fd5b823561257a81612898565b9150602083013561258a816128ad565b809150509250929050565b600080604083850312156125a7578182fd5b82356125b281612898565b946020939093013593505050565b6000602082840312156125d1578081fd5b8151610540816128ad565b6000602082840312156125ed578081fd5b815167ffffffffffffffff80821115612604578283fd5b818401915084601f830112612617578283fd5b81518181111561262957612629612882565b604051601f8201601f19908116603f0116810190838211818310171561265157612651612882565b81604052828152876020848701011115612669578586fd5b6124d4836020830160208801612856565b60006020828403121561268b578081fd5b5035919050565b6000602082840312156126a3578081fd5b5051919050565b600080604083850312156126bc578182fd5b82359150602083013561258a81612898565b600080604083850312156126e0578182fd5b50508035926020909101359150565b60008060008060808587031215612704578182fd5b8435935060208501359250604085013561271d81612898565b9396929550929360600135925050565b60008151808452612745816020860160208601612856565b601f01601f19169290920160200192915050565b6000825161276b818460208701612856565b9190910192915050565b7f78000000000000000000000000000000000000000000000000000000000000008152600082516127ad816001850160208701612856565b9190910160010192915050565b6001600160a01b03841681526060602082015260006127dc606083018561272d565b82810360408401526127ee818561272d565b9695505050505050565b602081526000610540602083018461272d565b60008261282657634e487b7160e01b81526012600452602481fd5b500490565b600081600019048311821515161561285157634e487b7160e01b81526011600452602481fd5b500290565b60005b83811015612871578181015183820152602001612859565b83811115611ef05750506000910152565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461082b57600080fd5b801515811461082b57600080fdfe608060405234801561001057600080fd5b50611dd1806100206000396000f3fe608060405234801561001057600080fd5b506004361061016c5760003560e01c80637efe41b1116100cd578063b068498d11610081578063c55dae6311610066578063c55dae63146102f4578063dd62ed3e14610307578063f2fde38b1461034057600080fd5b8063b068498d146102b8578063c19ea053146102cb57600080fd5b806395d89b41116100b257806395d89b411461028a578063a457c2d714610292578063a9059cbb146102a557600080fd5b80637efe41b1146102525780638da5cb5b1461026557600080fd5b806330fe73fd116101245780633950935111610109578063395093511461020e57806370a0823114610221578063715018a61461024a57600080fd5b806330fe73fd146101ea578063313ce567146101ff57600080fd5b806318160ddd1161015557806318160ddd146101b257806319e616a3146101c457806323b872dd146101d757600080fd5b806306fdde0314610171578063095ea7b31461018f575b600080fd5b610179610353565b6040516101869190611c67565b60405180910390f35b6101a261019d366004611bb8565b6103e5565b6040519015158152602001610186565b6067545b604051908152602001610186565b6101b66101d2366004611bb8565b6103fb565b6101a26101e5366004611b0c565b610528565b6101fd6101f8366004611b47565b6105f0565b005b60405160128152602001610186565b6101a261021c366004611bb8565b6106e0565b6101b661022f366004611ac0565b6001600160a01b031660009081526065602052604090205490565b6101fd610717565b6101b6610260366004611be1565b6107c8565b6033546001600160a01b03165b6040516001600160a01b039091168152602001610186565b610179610903565b6101a26102a0366004611bb8565b610912565b6101a26102b3366004611bb8565b6109c5565b6101fd6102c6366004611bb8565b6109d2565b6101b66102d9366004611ac0565b6001600160a01b031660009081526098602052604090205490565b609754610272906001600160a01b031681565b6101b6610315366004611ada565b6001600160a01b03918216600090815260666020908152604080832093909416825291909152205490565b6101fd61034e366004611ac0565b610b07565b60606068805461036290611d34565b80601f016020809104026020016040519081016040528092919081815260200182805461038e90611d34565b80156103db5780601f106103b0576101008083540402835291602001916103db565b820191906000526020600020905b8154815290600101906020018083116103be57829003601f168201915b5050505050905090565b60006103f2338484610c46565b50600192915050565b6033546000906001600160a01b0316331461045d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b600061046860675490565b6097546040516370a0823160e01b815230600482015291925060009183916001600160a01b0316906370a082319060240160206040518083038186803b1580156104b157600080fd5b505afa1580156104c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e99190611c33565b6104f39086611cd2565b6104fd9190611cb2565b90506105098585610d9f565b609754610520906001600160a01b03168683610e02565b949350505050565b6000610535848484610e82565b6001600160a01b0384166000908152606660209081526040808320338452909152902054828110156105cf5760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610454565b6105e385336105de8685611cf1565b610c46565b60019150505b9392505050565b600054610100900460ff1680610609575060005460ff16155b61066c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff1615801561068e576000805461ffff19166101011790555b610696610ee2565b6106a08383610fa5565b6097805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03861617905580156106da576000805461ff00191690555b50505050565b3360008181526066602090815260408083206001600160a01b038716845290915281205490916103f29185906105de908690611c9a565b6033546001600160a01b031633146107715760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610454565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a36033805473ffffffffffffffffffffffffffffffffffffffff19169055565b6033546000906001600160a01b031633146108255760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610454565b6097546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561086957600080fd5b505afa15801561087d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a19190611c33565b905060006108ae60675490565b90508015806108bb575081155b156108d5576108cb86868661106b565b84925050506105e9565b6000826108e28388611cd2565b6108ec9190611cb2565b90506108f987828761106b565b92506105e9915050565b60606069805461036290611d34565b3360009081526066602090815260408083206001600160a01b0386168452909152812054828110156109ac5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610454565b6109bb33856105de8685611cf1565b5060019392505050565b60006103f2338484610e82565b6033546001600160a01b03163314610a2c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610454565b62278d008110610a7e5760405162461bcd60e51b815260206004820152600d60248201527f546f6f206c6f6e67206c6f636b000000000000000000000000000000000000006044820152606401610454565b6000610a8a8242611c9a565b6001600160a01b038416600090815260986020526040902054909150811115610b02576001600160a01b038316600081815260986020908152604091829020849055815192835282018390527f38f63775093182d55eb9f15cb41c506fd976eadb1b4544ba0aeaed494ee70cde910160405180910390a15b505050565b6033546001600160a01b03163314610b615760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610454565b6001600160a01b038116610bdd5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610454565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36033805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6001600160a01b038316610cc15760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b038216610d3d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b0383811660008181526066602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b0382166000908152609860205260409020544211610df45760405162461bcd60e51b815260206004820152600b60248201526a155cd95c881b1bd8dad95960aa1b6044820152606401610454565b610dfe828261107f565b5050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610b02908490611205565b6001600160a01b0383166000908152609860205260409020544211610ed75760405162461bcd60e51b815260206004820152600b60248201526a155cd95c881b1bd8dad95960aa1b6044820152606401610454565b610b028383836112ea565b600054610100900460ff1680610efb575060005460ff16155b610f5e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff16158015610f80576000805461ffff19166101011790555b610f8861150b565b610f906115bc565b8015610fa2576000805461ff00191690555b50565b600054610100900460ff1680610fbe575060005460ff16155b6110215760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff16158015611043576000805461ffff19166101011790555b61104b61150b565b61105583836116be565b8015610b02576000805461ff0019169055505050565b61107583826109d2565b610b02838361179a565b6001600160a01b0382166110fb5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b0382166000908152606560205260409020548181101561118a5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610454565b6111948282611cf1565b6001600160a01b038416600090815260656020526040812091909155606780548492906111c2908490611cf1565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610d92565b600061125a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166118799092919063ffffffff16565b805190915015610b0257808060200190518101906112789190611c13565b610b025760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b0383166113665760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b0382166113e25760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b038316600090815260656020526040902054818110156114715760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610454565b61147b8282611cf1565b6001600160a01b0380861660009081526065602052604080822093909355908516815290812080548492906114b1908490611c9a565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516114fd91815260200190565b60405180910390a350505050565b600054610100900460ff1680611524575060005460ff16155b6115875760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff16158015610f90576000805461ffff19166101011790558015610fa2576000805461ff001916905550565b600054610100900460ff16806115d5575060005460ff16155b6116385760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff1615801561165a576000805461ffff19166101011790555b6033805473ffffffffffffffffffffffffffffffffffffffff19163390811790915560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015610fa2576000805461ff001916905550565b600054610100900460ff16806116d7575060005460ff16155b61173a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff1615801561175c576000805461ffff19166101011790555b825161176f906068906020860190611984565b508151611783906069906020850190611984565b508015610b02576000805461ff0019169055505050565b6001600160a01b0382166117f05760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610454565b80606760008282546118029190611c9a565b90915550506001600160a01b0382166000908152606560205260408120805483929061182f908490611c9a565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6060610520848460008585843b6118d25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610454565b600080866001600160a01b031685876040516118ee9190611c4b565b60006040518083038185875af1925050503d806000811461192b576040519150601f19603f3d011682016040523d82523d6000602084013e611930565b606091505b509150915061194082828661194b565b979650505050505050565b6060831561195a5750816105e9565b82511561196a5782518084602001fd5b8160405162461bcd60e51b81526004016104549190611c67565b82805461199090611d34565b90600052602060002090601f0160209004810192826119b257600085556119f8565b82601f106119cb57805160ff19168380011785556119f8565b828001600101855582156119f8579182015b828111156119f85782518255916020019190600101906119dd565b50611a04929150611a08565b5090565b5b80821115611a045760008155600101611a09565b80356001600160a01b0381168114611a3457600080fd5b919050565b600082601f830112611a49578081fd5b813567ffffffffffffffff80821115611a6457611a64611d85565b604051601f8301601f19908116603f01168101908282118183101715611a8c57611a8c611d85565b81604052838152866020858801011115611aa4578485fd5b8360208701602083013792830160200193909352509392505050565b600060208284031215611ad1578081fd5b6105e982611a1d565b60008060408385031215611aec578081fd5b611af583611a1d565b9150611b0360208401611a1d565b90509250929050565b600080600060608486031215611b20578081fd5b611b2984611a1d565b9250611b3760208501611a1d565b9150604084013590509250925092565b600080600060608486031215611b5b578283fd5b611b6484611a1d565b9250602084013567ffffffffffffffff80821115611b80578384fd5b611b8c87838801611a39565b93506040860135915080821115611ba1578283fd5b50611bae86828701611a39565b9150509250925092565b60008060408385031215611bca578182fd5b611bd383611a1d565b946020939093013593505050565b600080600060608486031215611bf5578283fd5b611bfe84611a1d565b95602085013595506040909401359392505050565b600060208284031215611c24578081fd5b815180151581146105e9578182fd5b600060208284031215611c44578081fd5b5051919050565b60008251611c5d818460208701611d08565b9190910192915050565b6020815260008251806020840152611c86816040850160208701611d08565b601f01601f19169190910160400192915050565b60008219821115611cad57611cad611d6f565b500190565b600082611ccd57634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615611cec57611cec611d6f565b500290565b600082821015611d0357611d03611d6f565b500390565b60005b83811015611d23578181015183820152602001611d0b565b838111156106da5750506000910152565b600181811c90821680611d4857607f821691505b60208210811415611d6957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fdfea264697066735822122063063acdd6925a304044a775786197375e3dd34ad90a07e424c8fcee00e484cd64736f6c63430008040033608060405261002f60017fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d51610451565b6000805160206107cf8339815191521461005957634e487b7160e01b600052600160045260246000fd5b610078336040518060200160405280600081525061007d60201b60201c565b6104a0565b6100908261023860201b6100291760201c565b6100ef5760405162461bcd60e51b815260206004820152602560248201527f426561636f6e50726f78793a20626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b610172826001600160a01b031663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561012b57600080fd5b505afa15801561013f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016391906103db565b61023860201b6100291760201c565b6101e45760405162461bcd60e51b815260206004820152603460248201527f426561636f6e50726f78793a20626561636f6e20696d706c656d656e7461746960448201527f6f6e206973206e6f74206120636f6e747261637400000000000000000000000060648201526084016100e6565b6000805160206107cf8339815191528281558151156102335761023161020861023e565b836040518060600160405280602181526020016107ef602191396102cb60201b61002f1760201c565b505b505050565b3b151590565b60006102566000805160206107cf8339815191525490565b6001600160a01b031663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561028e57600080fd5b505afa1580156102a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c691906103db565b905090565b6060833b61032a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016100e6565b600080856001600160a01b0316856040516103459190610402565b600060405180830381855af49150503d8060008114610380576040519150601f19603f3d011682016040523d82523d6000602084013e610385565b606091505b5090925090506103968282866103a2565b925050505b9392505050565b606083156103b157508161039b565b8251156103c15782518084602001fd5b8160405162461bcd60e51b81526004016100e6919061041e565b6000602082840312156103ec578081fd5b81516001600160a01b038116811461039b578182fd5b60008251610414818460208701610474565b9190910192915050565b602081526000825180602084015261043d816040850160208701610474565b601f01601f19169190910160400192915050565b60008282101561046f57634e487b7160e01b81526011600452602481fd5b500390565b60005b8381101561048f578181015183820152602001610477565b838111156102315750506000910152565b610320806104af6000396000f3fe60806040523661001357610011610017565b005b6100115b61002761002261012e565b6101da565b565b3b151590565b6060833b6100aa5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516100d2919061026b565b600060405180830381855af49150503d806000811461010d576040519150601f19603f3d011682016040523d82523d6000602084013e610112565b606091505b50915091506101228282866101fe565b925050505b9392505050565b60006101587fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d505490565b73ffffffffffffffffffffffffffffffffffffffff1663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561019d57600080fd5b505afa1580156101b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d59190610237565b905090565b3660008037600080366000845af43d6000803e8080156101f9573d6000f35b3d6000fd5b6060831561020d575081610127565b82511561021d5782518084602001fd5b8160405162461bcd60e51b81526004016100a19190610287565b600060208284031215610248578081fd5b815173ffffffffffffffffffffffffffffffffffffffff81168114610127578182fd5b6000825161027d8184602087016102ba565b9190910192915050565b60208152600082518060208401526102a68160408501602087016102ba565b601f01601f19169190910160400192915050565b60005b838110156102d55781810151838201526020016102bd565b838111156102e4576000848401525b5050505056fea2646970667358221220186f38c9868951054a26d8e78dfc388c93ba31dab42cd0982029e5f5f85fc42164736f6c63430008040033a3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50426561636f6e50726f78793a2066756e6374696f6e2063616c6c206661696c6564608060405261002f60017fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d51610451565b6000805160206107cf8339815191521461005957634e487b7160e01b600052600160045260246000fd5b610078336040518060200160405280600081525061007d60201b60201c565b6104a0565b6100908261023860201b6100291760201c565b6100ef5760405162461bcd60e51b815260206004820152602560248201527f426561636f6e50726f78793a20626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b610172826001600160a01b031663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561012b57600080fd5b505afa15801561013f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016391906103db565b61023860201b6100291760201c565b6101e45760405162461bcd60e51b815260206004820152603460248201527f426561636f6e50726f78793a20626561636f6e20696d706c656d656e7461746960448201527f6f6e206973206e6f74206120636f6e747261637400000000000000000000000060648201526084016100e6565b6000805160206107cf8339815191528281558151156102335761023161020861023e565b836040518060600160405280602181526020016107ef602191396102cb60201b61002f1760201c565b505b505050565b3b151590565b60006102566000805160206107cf8339815191525490565b6001600160a01b031663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561028e57600080fd5b505afa1580156102a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c691906103db565b905090565b6060833b61032a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016100e6565b600080856001600160a01b0316856040516103459190610402565b600060405180830381855af49150503d8060008114610380576040519150601f19603f3d011682016040523d82523d6000602084013e610385565b606091505b5090925090506103968282866103a2565b925050505b9392505050565b606083156103b157508161039b565b8251156103c15782518084602001fd5b8160405162461bcd60e51b81526004016100e6919061041e565b6000602082840312156103ec578081fd5b81516001600160a01b038116811461039b578182fd5b60008251610414818460208701610474565b9190910192915050565b602081526000825180602084015261043d816040850160208701610474565b601f01601f19169190910160400192915050565b60008282101561046f57634e487b7160e01b81526011600452602481fd5b500390565b60005b8381101561048f578181015183820152602001610477565b838111156102315750506000910152565b610320806104af6000396000f3fe60806040523661001357610011610017565b005b6100115b61002761002261012e565b6101da565b565b3b151590565b6060833b6100aa5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516100d2919061026b565b600060405180830381855af49150503d806000811461010d576040519150601f19603f3d011682016040523d82523d6000602084013e610112565b606091505b50915091506101228282866101fe565b925050505b9392505050565b60006101587fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d505490565b73ffffffffffffffffffffffffffffffffffffffff1663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561019d57600080fd5b505afa1580156101b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d59190610237565b905090565b3660008037600080366000845af43d6000803e8080156101f9573d6000f35b3d6000fd5b6060831561020d575081610127565b82511561021d5782518084602001fd5b8160405162461bcd60e51b81526004016100a19190610287565b600060208284031215610248578081fd5b815173ffffffffffffffffffffffffffffffffffffffff81168114610127578182fd5b6000825161027d8184602087016102ba565b9190910192915050565b60208152600082518060208401526102a68160408501602087016102ba565b601f01601f19169190910160400192915050565b60005b838110156102d55781810151838201526020016102bd565b838111156102e4576000848401525b5050505056fea26469706673582212207fa982cc2707bb3e77c4aa1e243fbbca2a5b4869b87391cdd12e6a56d1e36e9164736f6c63430008040033a3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50426561636f6e50726f78793a2066756e6374696f6e2063616c6c206661696c6564a2646970667358221220a6d8bd71e3c209440cbda6ee0e4b571d323b100b123ab27dd77d39b7b30a662564736f6c63430008040033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.