Overview
ETH Balance
0.204064588207897792 ETH
Eth Value
$515.14 (@ $2,524.40/ETH)Token Holdings
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 128 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Take Swap | 19998525 | 89 days ago | IN | 0.001 ETH | 0.0018506 | ||||
Take Swap | 19071827 | 219 days ago | IN | 0.001 ETH | 0.00202724 | ||||
Make Swap | 19035702 | 224 days ago | IN | 0 ETH | 0.0169651 | ||||
Take Swap | 18889400 | 245 days ago | IN | 0.001 ETH | 0.01407277 | ||||
Make Swap | 18889393 | 245 days ago | IN | 0 ETH | 0.04660525 | ||||
Drop Swap | 18653016 | 278 days ago | IN | 0 ETH | 0.00299269 | ||||
Make Swap | 18653001 | 278 days ago | IN | 0 ETH | 0.00905052 | ||||
Make Swap | 18621917 | 282 days ago | IN | 0 ETH | 0.03221671 | ||||
Make Swap | 18341788 | 321 days ago | IN | 0 ETH | 0.00288484 | ||||
Withdraw | 17999723 | 369 days ago | IN | 0 ETH | 0.00069812 | ||||
Take Swap | 17999569 | 369 days ago | IN | 0.001 ETH | 0.00295593 | ||||
Make Swap | 17999482 | 369 days ago | IN | 90 ETH | 0.00426872 | ||||
Drop Swap | 17999425 | 369 days ago | IN | 0 ETH | 0.00112463 | ||||
Make Swap | 17988018 | 371 days ago | IN | 0 ETH | 0.00896503 | ||||
Drop Swap | 17987553 | 371 days ago | IN | 0 ETH | 0.00325265 | ||||
Make Swap | 17986096 | 371 days ago | IN | 0 ETH | 0.00927563 | ||||
Drop Swap | 17530264 | 435 days ago | IN | 0 ETH | 0.00188588 | ||||
Drop Swap | 17530260 | 435 days ago | IN | 0 ETH | 0.00178938 | ||||
Make Swap | 17452512 | 446 days ago | IN | 0 ETH | 0.00538655 | ||||
Make Swap | 17230947 | 477 days ago | IN | 0 ETH | 0.0315928 | ||||
Make Swap | 17230392 | 477 days ago | IN | 0 ETH | 0.03206389 | ||||
Take Swap | 16905007 | 523 days ago | IN | 1 wei | 0.00459157 | ||||
Make Swap | 16905003 | 523 days ago | IN | 0 ETH | 0.01062312 | ||||
Take Swap | 16904854 | 523 days ago | IN | 1 wei | 0.00528253 | ||||
Make Swap | 16904849 | 523 days ago | IN | 0 ETH | 0.00968849 |
Latest 11 internal transactions
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
17999723 | 369 days ago | 90 ETH | ||||
16884201 | 526 days ago | 1.662 ETH | ||||
16599798 | 566 days ago | 2.9925 ETH | ||||
16522206 | 577 days ago | 0.016 ETH | ||||
16405820 | 593 days ago | 0.01 ETH | ||||
15940871 | 658 days ago | 0.061252 ETH | ||||
15903191 | 663 days ago | 0.05 ETH | ||||
15664901 | 697 days ago | 0.09 ETH | ||||
15624224 | 702 days ago | 0.028 ETH | ||||
15404401 | 736 days ago | 0.002 ETH | ||||
15404204 | 736 days ago | 0.001 ETH |
Loading...
Loading
Contract Name:
NFTProtocolDEX
Compiler Version
v0.8.12+commit.f00d7308
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol"; import "@openzeppelin/contracts/utils/math/Math.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "./interface/INFTProtocolDEX.sol"; import "./DEXConstants.sol"; import "./DEXAccessControl.sol"; contract NFTProtocolDEX is INFTProtocolDEX, DEXAccessControl, DEXConstants, ERC1155Holder, ERC721Holder, ReentrancyGuard { using Address for address; using SafeERC20 for IERC20; /** * @inheritdoc INFTProtocolDEX */ string public constant name = "NFTProtocolDEX"; /** * @inheritdoc INFTProtocolDEX */ uint16 public constant majorVersion = 3; /** * @inheritdoc INFTProtocolDEX */ uint16 public constant minorVersion = 0; /** * @inheritdoc INFTProtocolDEX */ address public immutable token; /** * @inheritdoc INFTProtocolDEX * @dev Default is 0.001 Ether. */ uint256 public flatFee = 1_000_000_000_000_000; /** * @inheritdoc INFTProtocolDEX * @dev Default is 10,000 tokens. */ uint256 public lowFee = 10_000 * 10**18; /** * @inheritdoc INFTProtocolDEX * @dev Default is 100,000 tokens. */ uint256 public highFee = 100_000 * 10**18; /** * @inheritdoc INFTProtocolDEX */ uint256 public numSwaps; /** * @dev Map of Ether balances. */ mapping(address => uint256) private _balances; /** * @dev Total value locked, including all swap ether, excluding the contract owner's fees. */ uint256 public tvl; /** * @dev Mapping from swapID to swap structures for all swaps, * including closed and dropped swaps. */ mapping(uint256 => Swap) private _swaps; /** * @dev Mapping from swapID to swap whitelist. */ mapping(uint256 => mapping(address => bool)) private _whitelists; /** * @dev Valid swap check. */ modifier validSwap(uint256 swapID) { require(swapID < numSwaps, "Invalid swapID"); _; } /** * @dev Valid side check. */ modifier validSide(uint8 side) { require(side == MAKER_SIDE || side == TAKER_SIDE, "Invalid side"); _; } /** * Initializes the contract with the address of the NFT Protocol token * and the address of the administrator account. * @param token_ address of the NFT Protocol ERC20 token * @param admin_ address of the administrator account (multisig) */ constructor(address token_, address admin_) DEXAccessControl(admin_) { token = token_; emit FeesChanged(flatFee, lowFee, highFee); } /** * @inheritdoc INFTProtocolDEX * * @dev This function is not available: * - in `deprecated` or `locked` mode, see :sol:func:deprecated and :sol:func:locked, respectively. * - to the contract administrator, see :sol:func:owner. */ function makeSwap( Component[] calldata make_, Component[] calldata take_, bool custodial_, uint256 expiration_, address[] calldata whitelist_ ) external payable override supported unlocked notOwner nonReentrant { require(make_.length > 0, "Make side is empty"); require(take_.length > 0, "Take side is empty"); require(_notExpired(expiration_), "Invalid expiration"); // Calc make value, pay amount, and updated balance, also checks asset types. address sender = _msgSender(); (uint256 pay, uint256 updated) = _requiredValue(sender, make_, msg.value, 0); _checkComponents(take_); // Check sent value. require(msg.value >= pay, "Insufficient Ether value"); // Create swap. _addSwap(make_, take_, custodial_, expiration_, whitelist_); // Update tvl. tvl += msg.value; // Transfer in maker assets. _transferAssetsIn(make_, custodial_); // Update balance. _updateBalance(updated, numSwaps); // Finalize swap. numSwaps += 1; // Issue event. emit SwapMade(numSwaps - 1, make_, take_, sender, custodial_, expiration_, whitelist_); } /** * @inheritdoc INFTProtocolDEX * * @dev This function is not available: * - in `locked` mode, see :sol:func:locked, * - to the contract administrator, see :sol:func:owner. */ function takeSwap(uint256 swapID_, uint256 seqNum_) external payable override unlocked notOwner nonReentrant { address sender = _msgSender(); (Swap storage swp, uint256 pay, uint256 updated, uint256 fee) = _takerSwapAndValues(sender, swapID_, msg.value); require(swp.seqNum == seqNum_, "Wrong seqNum"); require(msg.value >= pay, "Insufficient Ether value (price + fee)"); // Close out swap. swp.status = CLOSED_SWAP; swp.taker = sender; // Update balance. _updateBalance(updated, swapID_); // Transfer assets from DEX to taker. _transferAssetsOut(swp.components[MAKER_SIDE], swp.maker, swp.custodial); // Transfer assets from taker to maker. for (uint256 i = 0; i < swp.components[TAKER_SIDE].length; i++) { _transferAsset(swp.components[TAKER_SIDE][i], sender, swp.maker); } // Credit fee to owner. address owner_ = owner(); _balances[owner_] += fee; tvl += msg.value; tvl -= fee; // Issue events. emit SwapTaken(swapID_, swp.seqNum, sender, fee); emit Deposited(owner(), fee); } /** * @inheritdoc INFTProtocolDEX * * @dev This function is not available: * - in `locked` mode, see :sol:func:locked, * - to the contract administrator, see :sol:func:owner. */ function dropSwap(uint256 swapID_) external override unlocked notOwner nonReentrant { Swap storage swp = _swaps[swapID_]; require(swp.status == OPEN_SWAP, "Swap not open"); require(_msgSender() == swp.maker, "Not swap maker"); // Drop swap. swp.status = DROPPED_SWAP; // Transfer assets back to maker. for (uint256 i = 0; i < swp.components[MAKER_SIDE].length; i++) { if (swp.custodial || swp.components[MAKER_SIDE][i].assetType == ETHER_ASSET) { _transferAsset(swp.components[MAKER_SIDE][i], address(this), swp.maker); } } // Issue event. emit SwapDropped(swapID_); } /** * @inheritdoc INFTProtocolDEX * * @dev This function is not available: * - in `locked` mode, see :sol:func:locked, * - to the contract administrator, see :sol:func:owner. */ function amendSwapEther( uint256 swapID_, uint8 side_, uint256 value_ ) external payable override unlocked notOwner nonReentrant validSide(side_) validSwap(swapID_) { Swap storage swp = _swaps[swapID_]; require(swp.status == OPEN_SWAP, "Swap not open"); address sender = _msgSender(); require(sender == swp.maker, "Not swap maker"); require(_notExpired(swp.expiration), "Swap expired"); Component[] storage comps = swp.components[side_]; // Set ether asset. (uint256 previous, uint256 index) = _setEtherAsset(comps, value_); require(value_ != previous, "Ether value unchanged"); require(value_ > 0 || comps.length > 1, "Swap side becomes empty"); // Update balance. uint256 balance_ = _balances[sender]; if (side_ == TAKER_SIDE && msg.value > 0) { _updateBalance(balance_ + msg.value, swapID_); } else if (side_ == MAKER_SIDE) { if (value_ > previous) { require(balance_ + msg.value >= value_ - previous, "Insufficient Ether value"); } _updateBalance(balance_ + msg.value + previous - value_, swapID_); } // Update tvl. tvl += msg.value; // Update seqNum. swp.seqNum += 1; // Issue event. emit SwapEtherAmended(swapID_, swp.seqNum, side_, index, previous, value_); } /** * @inheritdoc INFTProtocolDEX * * @dev This function requires the swap to be defined. */ function swap(uint256 swapID_) external view override validSwap(swapID_) returns (Swap memory) { return _swaps[swapID_]; } /** * @inheritdoc INFTProtocolDEX * * @dev This function requires the swap to be defined. */ function whitelistedWith(address sender_, uint256 swapID_) public view override validSwap(swapID_) returns (bool) { return _whitelists[swapID_][sender_]; } /** * @inheritdoc INFTProtocolDEX */ function whitelisted(uint256 swapID_) external view override returns (bool) { return whitelistedWith(_msgSender(), swapID_); } /** * @inheritdoc INFTProtocolDEX * * @dev This function requires the swap to be defined and open. */ function requireCanTakeSwapWith(address sender_, uint256 swapID_) public view override unlocked validSwap(swapID_) { (Swap storage swp, , , ) = _takerSwapAndValues(sender_, swapID_, 0); _requireComponents(swp.components[TAKER_SIDE], sender_, true); if (!swp.custodial) { _requireComponents(swp.components[MAKER_SIDE], swp.maker, false); } } /** * @inheritdoc INFTProtocolDEX */ function requireCanTakeSwap(uint256 swapID_) external view override { return requireCanTakeSwapWith(_msgSender(), swapID_); } /** * @inheritdoc INFTProtocolDEX */ function requireMakerAssets(uint256 swapID) external view override unlocked validSwap(swapID) { Swap memory swp = _swaps[swapID]; require(swp.status == OPEN_SWAP, "Swap not open"); require(!swp.custodial, "Swap custodial"); _requireComponents(swp.components[MAKER_SIDE], swp.maker, false); } /** * @inheritdoc INFTProtocolDEX */ function requireTakerAssetsWith(address sender_, uint256 swapID_) public view override unlocked validSwap(swapID_) { (Swap storage swp, , , ) = _takerSwapAndValues(sender_, swapID_, 0); _requireComponents(swp.components[TAKER_SIDE], sender_, true); } /** * @inheritdoc INFTProtocolDEX */ function requireTakerAssets(uint256 swapID_) public view override { return requireTakerAssetsWith(_msgSender(), swapID_); } /** * @inheritdoc INFTProtocolDEX */ function balanceOf(address of_) public view override returns (uint256) { return _balances[of_]; } /** * @inheritdoc INFTProtocolDEX */ function balance() external view override returns (uint256) { return balanceOf(_msgSender()); } /** * @inheritdoc INFTProtocolDEX */ function withdraw(uint256 value_) external override { _withdraw(value_); } /** * @inheritdoc INFTProtocolDEX */ function withdrawFull() external override { _withdraw(_balances[_msgSender()]); } /** * @inheritdoc INFTProtocolDEX */ function makerSendValueWith(address sender_, Component[] calldata make_) public view override supported unlocked returns (uint256) { (uint256 pay, ) = _requiredValue(sender_, make_, 0, 0); return pay; } /** * @inheritdoc INFTProtocolDEX */ function makerSendValue(Component[] calldata make_) external view override returns (uint256) { return makerSendValueWith(_msgSender(), make_); } /** * @inheritdoc INFTProtocolDEX */ function takerSendValueWith(address sender_, uint256 swapID_) public view override unlocked returns (uint256) { (, uint256 pay, , ) = _takerSwapAndValues(sender_, swapID_, 0); return pay; } /** * @inheritdoc INFTProtocolDEX */ function takerSendValue(uint256 swapID_) external view override unlocked returns (uint256) { return takerSendValueWith(_msgSender(), swapID_); } /** * @inheritdoc INFTProtocolDEX */ function amendSwapEtherSendValueWith( address sender_, uint256 swapID_, uint8 side_, uint256 value_ ) public view override unlocked validSide(side_) returns (uint256) { Swap storage swp = _swaps[swapID_]; require(swp.status == OPEN_SWAP, "Swap not open"); require(sender_ == swp.maker, "Not swap maker"); require(_notExpired(swp.expiration), "Swap expired"); Component[] storage comps = swp.components[side_]; // Ether value. uint256 current = _getEtherAsset(comps); require(value_ != current, "Ether value unchanged"); require(value_ > 0 || comps.length > 1, "Swap side becomes empty"); // Value required to amend swap Ether. uint256 balance_ = _balances[sender_]; if (side_ == MAKER_SIDE && value_ > current && balance_ < value_ - current) { return value_ - current - balance_; } return 0; } /** * @inheritdoc INFTProtocolDEX */ function amendSwapEtherSendValue( uint256 swapID_, uint8 side_, uint256 value_ ) external view override returns (uint256) { return amendSwapEtherSendValueWith(_msgSender(), swapID_, side_, value_); } /** * @inheritdoc INFTProtocolDEX */ function takerFeeWith(address sender_) public view override unlocked returns (uint256) { uint256 balance_ = IERC20(token).balanceOf(sender_); if (balance_ >= highFee) { return 0; } if (balance_ < lowFee) { return flatFee; } // Take 10% off as soon as feeBypassLow is reached. uint256 startFee = (flatFee * 9) / 10; return startFee - (startFee * (balance_ - lowFee)) / (highFee - lowFee); } /** * @inheritdoc INFTProtocolDEX */ function takerFee() external view override returns (uint256) { return takerFeeWith(_msgSender()); } /** * @inheritdoc INFTProtocolDEX * * @dev This function can only be called by the contract administrator, see :sol:func:`owner`. */ function setFees( uint256 flatFee_, uint256 lowFee_, uint256 highFee_ ) external override supported onlyOwner { require(lowFee_ <= highFee_, "lowFee must be <= highFee"); flatFee = flatFee_; lowFee = lowFee_; highFee = highFee_; emit FeesChanged(flatFee, lowFee, highFee); } /** * @inheritdoc INFTProtocolDEX * * @dev This function can only be called by the contract administrator, see :sol:func:`owner`. */ function rescue() external override onlyOwner nonReentrant { address sender = _msgSender(); uint256 balance_ = _balances[sender]; uint256 total = address(this).balance - tvl; require(total > balance_, "No value to rescue"); uint256 amount = total - balance_; _balances[sender] += amount; emit Deposited(sender, amount); emit Rescued(sender, amount); } /** * Appends a new swap to the list. */ function _addSwap( Component[] calldata make_, Component[] calldata take_, bool custodial_, uint256 expiration_, address[] calldata whitelist_ ) internal { _swaps[numSwaps].id = numSwaps; _swaps[numSwaps].custodial = custodial_; _swaps[numSwaps].expiration = expiration_; _swaps[numSwaps].maker = _msgSender(); for (uint256 i = 0; i < make_.length; i++) { _swaps[numSwaps].components[MAKER_SIDE].push(make_[i]); } for (uint256 i = 0; i < take_.length; i++) { _swaps[numSwaps].components[TAKER_SIDE].push(take_[i]); } // Initialize whitelist mapping for this swap. _swaps[numSwaps].whitelist = whitelist_.length > 0; for (uint256 i = 0; i < whitelist_.length; i++) { _whitelists[numSwaps][whitelist_[i]] = true; } } /** * Transfers assets in. */ function _transferAssetsIn(Component[] calldata make_, bool custodial_) internal { address sender = _msgSender(); for (uint256 i = 0; i < make_.length; i++) { if (custodial_ || make_[i].assetType == ETHER_ASSET) { _transferAsset(make_[i], sender, address(this)); } else { _requireAssets(make_[i], sender, msg.value); } } } /** * Transfers assets out. */ function _transferAssetsOut( Component[] storage comps, address from, bool custodial ) internal { address sender = _msgSender(); for (uint256 i = 0; i < comps.length; i++) { if (custodial || comps[i].assetType == ETHER_ASSET) { _transferAsset(comps[i], address(this), sender); } else { _transferAsset(comps[i], from, sender); } } } /** * Sets the ether component to value, create one if needed. * Returns the previous Ether value. */ function _setEtherAsset(Component[] storage comps, uint256 value) internal returns (uint256, uint256) { for (uint256 i = 0; i < comps.length; i++) { if (comps[i].assetType == ETHER_ASSET) { uint256 previous = comps[i].amounts[0]; comps[i].amounts[0] = value; return (previous, i); } } Component memory comp = Component({ assetType: ETHER_ASSET, tokenAddress: address(0), tokenIDs: new uint256[](0), amounts: new uint256[](1) }); comp.amounts[0] = value; comps.push(comp); return (0, comps.length - 1); } /** * Gets the Ether component value. */ function _getEtherAsset(Component[] memory comps) internal pure returns (uint256) { for (uint256 i = 0; i < comps.length; i++) { if (comps[i].assetType == ETHER_ASSET) { return comps[i].amounts[0]; } } return 0; } /** * Transfers asset from one account to another. */ function _transferAsset( Component memory comp, address from, address to ) internal { // All component checks were conducted before. if (comp.assetType == ERC1155_ASSET) { IERC1155 nft = IERC1155(comp.tokenAddress); nft.safeBatchTransferFrom(from, to, comp.tokenIDs, comp.amounts, ""); } else if (comp.assetType == ERC721_ASSET) { IERC721 nft = IERC721(comp.tokenAddress); nft.safeTransferFrom(from, to, comp.tokenIDs[0]); } else if (comp.assetType == ERC20_ASSET) { IERC20 coin = IERC20(comp.tokenAddress); uint256 amount = comp.amounts[0]; if (from == address(this)) { coin.safeTransfer(to, amount); } else { coin.safeTransferFrom(from, to, amount); } } else { // Ether, single length amounts array was checked before. _balances[to] += comp.amounts[0]; } } /** * Verifies ownerships, balances, and approval for list of components. */ function _requireComponents( Component[] memory comps, address wallet, bool includeEther ) internal view { for (uint256 i = 0; i < comps.length; i++) { if (includeEther || comps[i].assetType != ETHER_ASSET) { _requireAssets(comps[i], wallet, 0); } } } /** * Verifies ownerships, balances, and approval of component assets. */ function _requireAssets( Component memory comp, address wallet, uint256 sentValue ) internal view { if (comp.assetType == ERC1155_ASSET) { _requireERC1155Assets(comp, wallet); } else if (comp.assetType == ERC721_ASSET) { _requireERC721Asset(comp, wallet); } else if (comp.assetType == ERC20_ASSET) { _requireERC20Asset(comp, wallet); } else { _requireSufficientValue(comp, wallet, sentValue); } } /** * Verifies balance and approval of ERC1155 assets. */ function _requireERC1155Assets(Component memory comp, address wallet) internal view { IERC1155 nft = IERC1155(comp.tokenAddress); // Create accounts for batch balance. address[] memory wallets = new address[](comp.tokenIDs.length); for (uint256 i = 0; i < comp.tokenIDs.length; i++) { wallets[i] = wallet; } // Batch balance. uint256[] memory balances = nft.balanceOfBatch(wallets, comp.tokenIDs); require(balances.length == comp.tokenIDs.length, "Invalid balanceOfBatch call"); for (uint256 i = 0; i < comp.tokenIDs.length; i++) { require(balances[i] >= comp.amounts[i], "Insufficient ERC1155 balance"); } // Check if DEX has approval for all. bool approved = nft.isApprovedForAll(wallet, address(this)); require(approved, "DEX not ERC1155 approved"); } /** * Verifies balance and approval of ERC721 asset. */ function _requireERC721Asset(Component memory comp, address wallet) internal view { IERC721 nft = IERC721(comp.tokenAddress); // Check owner. address owner = nft.ownerOf(comp.tokenIDs[0]); require(owner == wallet, "Not ERC721 token owner"); // Check approval. bool approved = nft.isApprovedForAll(wallet, address(this)); if (!approved) { approved = address(this) == nft.getApproved(comp.tokenIDs[0]); } require(approved, "DEX not ERC721 approved"); } /** * Verifies balance and approval of ERC20 asset. */ function _requireERC20Asset(Component memory comp, address wallet) internal view { IERC20 coin = IERC20(comp.tokenAddress); // Check balance needed, since ERC20 does not update allowance at transfer (only transferFrom). uint256 balance_ = coin.balanceOf(wallet); require(balance_ >= comp.amounts[0], "Insufficient ERC20 balance"); // Check allowance. uint256 allowance = coin.allowance(wallet, address(this)); require(allowance >= comp.amounts[0], "Insufficient ERC20 allowance"); } /** * Checks a required Ether value against a wallet balances and sent value. * This function ignores transaction (gas) and taker fees. */ function _requireSufficientValue( Component memory comp, address wallet, uint256 sentValue ) internal view { uint256 balance_ = _balances[wallet]; require(wallet.balance + balance_ + sentValue >= comp.amounts[0], "Insufficient Ether value"); } /** * Checks components against the balance of a sender, the sent value, and a fee. * This function ignores transaction (gas) fees. */ function _requiredValue( address sender, Component[] memory comps, uint256 sentValue, uint256 fee ) internal view returns (uint256, uint256) { uint256 value = _checkComponents(comps); uint256 balance_ = _balances[sender]; if (balance_ + sentValue >= value + fee) { return (0, balance_ + sentValue - value - fee); } return (value + fee - balance_, 0); } /** * Checks all assets in a component array. */ function _checkComponents(Component[] memory comps) internal pure returns (uint256) { uint256 total; bool etherSeen; for (uint256 i = 0; i < comps.length; i++) { // Allow only one ether component. if (comps[i].assetType == ETHER_ASSET) { require(!etherSeen, "Multiple ether components"); etherSeen = true; } total += _checkComponent(comps[i]); } return total; } /** * Checks asset type and array sizes within a component. */ function _checkComponent(Component memory comp) internal pure returns (uint256) { if (comp.assetType == ERC1155_ASSET) { require(comp.tokenIDs.length == comp.amounts.length, "TokenIDs and amounts len differ"); } else if (comp.assetType == ERC721_ASSET) { require(comp.tokenIDs.length == 1, "TokenIDs array length must be 1"); } else if (comp.assetType == ERC20_ASSET) { require(comp.amounts.length == 1, "Amounts array length must be 1"); } else if (comp.assetType == ETHER_ASSET) { require(comp.amounts.length == 1, "Amounts array length must be 1"); return comp.amounts[0]; } else { revert("Invalid asset type"); } return 0; } /** * Checks an expiration parameter against the current block. */ function _notExpired(uint256 expiration) internal view returns (bool) { return expiration == 0 || expiration > block.number; } /** * Returns information about a swap take operation. * * @return (swap, value to send, updated balance, fee) */ function _takerSwapAndValues( address sender, uint256 swapID, uint256 sentValue ) internal view validSwap(swapID) returns ( Swap storage, uint256, uint256, uint256 ) { // Get swap. Swap storage swp = _swaps[swapID]; require(swp.status == OPEN_SWAP, "Swap not open"); require(sender != swp.maker, "Sender is swap maker"); require(!swp.whitelist || _whitelists[swapID][sender], "Not in whitelist"); require(_notExpired(swp.expiration), "Swap expired"); // Return total Ether to be provided by the taker (including), updated balance. uint256 fee = takerFeeWith(sender); (uint256 pay, uint256 updated) = _requiredValue(sender, swp.components[TAKER_SIDE], sentValue, fee); return (swp, pay, updated, fee); } /** * Updates the balance of an account. */ function _updateBalance(uint256 updated, uint256 swapID) internal { address sender = _msgSender(); uint256 balance_ = _balances[sender]; _balances[sender] = updated; if (updated > balance_) { emit Deposited(sender, updated - balance_); } else if (updated < balance_) { emit Spent(sender, balance_ - updated, swapID); } } /** * Withdraws funds from an account. */ function _withdraw(uint256 value) internal nonReentrant { require(value > 0, "Ether value is zero"); address sender = _msgSender(); uint256 balance_ = _balances[sender]; require(value <= balance_, "Ether value exceeds balance"); _balances[sender] -= value; if (sender != owner()) { tvl -= value; } (bool ok, ) = sender.call{value: value}(""); require(ok, "Withdrawal failed"); emit Withdrawn(sender, value); } /** * Receives Ether funds. */ receive() external payable supported unlocked notOwner { uint256 amount = msg.value; require(amount > 0, "Ether value is zero"); address sender = _msgSender(); _balances[sender] += amount; tvl += amount; emit Deposited(sender, amount); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol) pragma solidity ^0.8.0; import "../IERC721Receiver.sol"; /** * @dev Implementation of the {IERC721Receiver} interface. * * Accepts all token transfers. * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}. */ contract ERC721Holder is IERC721Receiver { /** * @dev See {IERC721Receiver-onERC721Received}. * * Always returns `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address, address, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC721Received.selector; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/utils/ERC1155Holder.sol) pragma solidity ^0.8.0; import "./ERC1155Receiver.sol"; /** * Simple implementation of `ERC1155Receiver` that will allow a contract to hold ERC1155 tokens. * * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be * stuck. * * @dev _Available since v3.1._ */ contract ERC1155Holder is ERC1155Receiver { function onERC1155Received( address, address, uint256, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155Received.selector; } function onERC1155BatchReceived( address, address, uint256[] memory, uint256[] memory, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155BatchReceived.selector; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`. // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`. // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a // good first aproximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1; uint256 x = a; if (x >> 128 > 0) { x >>= 128; result <<= 64; } if (x >> 64 > 0) { x >>= 64; result <<= 32; } if (x >> 32 > 0) { x >>= 32; result <<= 16; } if (x >> 16 > 0) { x >>= 16; result <<= 8; } if (x >> 8 > 0) { x >>= 8; result <<= 4; } if (x >> 4 > 0) { x >>= 4; result <<= 2; } if (x >> 2 > 0) { result <<= 1; } // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { uint256 result = sqrt(a); if (rounding == Rounding.Up && result * result < a) { result += 1; } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.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 Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { 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 { _transferOwnership(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"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface INFTProtocolDEX { /** * Structure representing a single component of a swap. */ struct Component { uint8 assetType; address tokenAddress; uint256[] tokenIDs; uint256[] amounts; } /** * Swap structure. */ struct Swap { uint256 id; uint8 status; Component[][2] components; address maker; address taker; bool whitelist; bool custodial; uint256 expiration; uint256 seqNum; } /** * Returns the name of the DEX contract. */ function name() external view returns (string memory); /** * Returns the major version of the DEX contract. */ function majorVersion() external view returns (uint16); /** * Returns the minor version of the DEX contract. */ function minorVersion() external view returns (uint16); /** * Returns the address of NFT Protocol Token. */ function token() external view returns (address); /** * The total number of swaps in the contract. */ function numSwaps() external view returns (uint256); /** * Returns `True` if sender is in the whitelist of a swap. * * @param sender_ Account of the sender. * @param swapID_ ID of the swap. */ function whitelistedWith(address sender_, uint256 swapID_) external view returns (bool); /** * Same as :sol:func:`whitelisted` with the sender account. */ function whitelisted(uint256 swapID_) external view returns (bool); /** * Checks if a swap can be taken by the caller. * * This function reverts with a message if the swap cannot be taken by the caller. * Reasons include: * - Swap not open. * - Swap has a whitelist and caller is not included. * - Taker assets are not available. * - Swap is non-custodial and maker has not made all assets available (e.g., moved assets or revoked allowances). * - Sender is swap maker. * * @param sender_ Address of the hypothetical swap taker. * @param swapID_ ID of the swap. */ function requireCanTakeSwapWith(address sender_, uint256 swapID_) external view; /** * Same as :sol:func:`requireCanTakeSwapWith` with the sender account. */ function requireCanTakeSwap(uint256 swapID_) external view; /** * Checks if all maker assets are available for non-custodial swaps, including balances and allowances. * * @param swapID_ ID of the swap. */ function requireMakerAssets(uint256 swapID_) external view; /** * Checks if all taker assets are available. * * @param sender_ Address of the hypothetical swap taker. * @param swapID_ ID of the swap. */ function requireTakerAssetsWith(address sender_, uint256 swapID_) external view; /** * Same as :sol:func:`requireTakerAssetsWith` with the sender account. */ function requireTakerAssets(uint256 swapID_) external view; /** * Returns the total ether value locked (tvl), including all deposited swap ether, * excluding the fees collected by the administrator. */ function tvl() external view returns (uint256); /** * Opens a swap with a list of assets on the maker side (`make_`) and on the taker side (`take_`). * * All assets listed on the maker side have to be available in the caller's account. * They are transferred to the DEX contract during this contract call. * * If the maker list contains Ether assets, then the total Ether funds have to be sent along with * the message of this contract call. * * Emits a :sol:event:`SwapMade` event, if successful. * * @param make_ Array of components for the maker side of the swap. * @param take_ Array of components for the taker side of the swap. * @param custodial_ True if the swap is custodial, e.g., maker assets are transfered into the DEX. * @param expiration_ Block number at which the swap expires, 0 for no expiration. * @param whitelist_ List of addresses that shall be permitted to take the swap. * If empty, then whitelisting will be disabled for this swap. */ function makeSwap( Component[] calldata make_, Component[] calldata take_, bool custodial_, uint256 expiration_, address[] calldata whitelist_ ) external payable; /** * Takes a swap that is currently open. * * All assets listed on the taker side have to be available in the caller's account, see :sol:func:`make`. * They are transferred to the maker's account in exchange for the maker's assets that currently reside within the DEX contract for custodial swaps, * which are transferred to the taker's account. For non-custodial swaps, the maker assets are transfered from the maker account. * This functions checks allowances, ownerships, and balances of all assets that are involved in this swap. * * The fee for this trade has to be sent along with the message of this contract call, see :sol:func:`fees`. * * If the taker list contains ETHER assets, then the total ETHER value also has to be added in WEI to the value that is sent along with * the message of this contract call. * * This function requires the caller to provide the most recent sequence number of the swap, which only changes when * the swap ether component is updated. The sequence number is used to prevent mempool front-running attacks. * * @param swapID_ ID of the swap to be taken. * @param seqNum_ Most recent sequence number of the swap. */ function takeSwap(uint256 swapID_, uint256 seqNum_) external payable; /** * Drop a swap and return the assets on the maker side back to the maker. * * All ERC1155, ERC721, and ERC20 assets will the transferred back directly to the maker. * Ether assets are booked to the maker account and can be extracted via :sol:func:`withdraw` and :sol:func:`withdrawFull`. * * Only the swap maker will be able to call this function successfully. * * Only swaps that are currently open can be dropped. * * @param swapID_ id of the swap to be dropped. */ function dropSwap(uint256 swapID_) external; /** * Amend ether value of a swap. * * @param swapID_ ID fo the swap to be modified. * @param side_ Swap side to modify, see :sol:func:`MAKER_SIDE` and :sol:func:`TAKER_SIDE`. * @param value_ New Ether value in Wei to be set for the swap side. */ function amendSwapEther( uint256 swapID_, uint8 side_, uint256 value_ ) external payable; /** * Returns the total Ether value in Wei that is required by the sender to take a swap. * * @param sender_ Address of the sender. * @param swapID_ ID of the swap. */ function takerSendValueWith(address sender_, uint256 swapID_) external view returns (uint256); /** * Same as :sol:func:`takerSendValueWith` with the sender account. */ function takerSendValue(uint256 swapID_) external view returns (uint256); /** * Returns the total Ether value in Wei that is required by the sender to make a swap. * * @param sender_ Address of the sender. * @param make_ Component array for make side of the swap, see :sol:func:`makeSwap`. */ function makerSendValueWith(address sender_, Component[] calldata make_) external view returns (uint256); /** * Same as :sol:func:`makerSendValueWith` with the sender account. */ function makerSendValue(Component[] calldata make_) external view returns (uint256); /** * Returns the total Ether value in Wei that is required by the caller to send in order to adjust the Ether of a swap, * see :sol:func:`adjustSwapEther`. * * @param sender_ Sender account. * @param swapID_ ID of the swap to be modified. * @param side_ Swap side to modify, see :sol:func:`MAKER_SIDE` and :sol:func:`TAKER_SIDE`. * @param value_ New Ether value in Wei to be set for the swap side. */ function amendSwapEtherSendValueWith( address sender_, uint256 swapID_, uint8 side_, uint256 value_ ) external view returns (uint256); /** * Same as :sol:func:`amendSwapEtherSendValueWith` with the sender account. */ function amendSwapEtherSendValue( uint256 swapID_, uint8 side_, uint256 value_ ) external view returns (uint256); /** * Returns the Wei of Ether balance of a user, see :sol:func:`withdraw` and :sol:func:`withdrawFull`. * * @param of_ Address of the account. */ function balanceOf(address of_) external view returns (uint256); /** * Same as :sol:func:`balanceOf` with the sender account. */ function balance() external view returns (uint256); /** * Withdraw funds in Wei of Ether from the contract, see :sol:func:`balance`. * * @param value_ Wei of Ether to withdraw. */ function withdraw(uint256 value_) external; /** * Withdraw all Ether funds from the contract that are available to the caller, see :sol:func:`withdraw`. */ function withdrawFull() external; /** * Rescue funds that are stuck in the DEX, e.g., no user has access to. * This function only runs successfully if , which should never happen. */ function rescue() external; /** * Get a swap, including closed and dropped swaps. * * @param swapID_ ID of the swap. * @return Swap data structure. */ function swap(uint256 swapID_) external view returns (Swap memory); /** * The flat fee in Wei of Ether to take a swap, see :sol:func:`setFlatFee`. * * @return Flat fee in Wei of Ether. */ function flatFee() external view returns (uint256); /** * The threshold of NFT Protocol token holdings for swap takersto get a 10% discount on the flat fee. * * @return Threshold for amounts in smallest unit of NFT Protocol token holdings to get a 10% discount. */ function lowFee() external view returns (uint256); /** * The threshold of NFT Protocol token holdings for swap takes to waive the flat fee. * * @return Threshold for amount in smallest unit of NFT Protocol token holdings to waive the flat fee. */ function highFee() external view returns (uint256); /** * Returns the taker fee owed for a swap, taking into account the holdings of NFT Protocol tokens, * see :sol:func:`flatFee`, :sol:func:`lowFee`, :sol:func:`highFee`. * * @param sender_ Address of the sender. */ function takerFeeWith(address sender_) external view returns (uint256); /** * Same as :sol:func:`takerFeeOf` with the sender account. */ function takerFee() external view returns (uint256); /** * Set the flat fee structure for swaps taking. * * @param flatFee_ Flat fee in Wei of Ether paid by the taker of swap, * if they hold less than `lowFee_` in smallest units of NFT Protocol token. * @param lowFee_ Threshold in smallest unit of NFT Protocol token to be held by the swap taker to get a 10% fee discount. * @param highFee_ Threshold in smallest unit of NFT Protocol token to be held by the swap taker to pay no fees. */ function setFees( uint256 flatFee_, uint256 lowFee_, uint256 highFee_ ) external; /** * Emitted when a swap was opened, see :sol:func:`makeSwap`. * * @param swapID ID of the swap. * @param make Array of swap components on the maker side, see :sol:struct:`Component`. * @param take Array of swap components on the taker side, see :sol:struct:`Component`. * @param maker Account of the swap maker. * @param custodial True if swap is custodial. * @param expiration Block where the swap expires, 0 for no expiration. * @param whitelist Array of addresses that are allowed to take the swap. */ event SwapMade( uint256 indexed swapID, Component[] make, Component[] take, address indexed maker, bool indexed custodial, uint256 expiration, address[] whitelist ); /** * Emitted when a swap was executed, see :sol:func:`takeSwap`. * * @param swapID ID of the swap that was taken. * @param seqNum Sequence number of the swap. * @param taker Address of the account that executed the swap. * @param fee Fee value in Wei of Ether paid by the swap taker. */ event SwapTaken(uint256 indexed swapID, uint256 seqNum, address indexed taker, uint256 fee); /** * Emitted when a swap was dropped, ie. cancelled. * * @param swapID ID of the dropped swap. */ event SwapDropped(uint256 indexed swapID); /** * Emitted when a Ether component of a swap was amended, see :sol:func:`amendSwapEther`. * * @param swapID ID of the swap. * @param seqNum New sequence number of the swap. * @param side Swap side, either MAKER_SIDE or TAKER_SIDE. * @param index Index of the amended or added Ether component in the components array. * @param from Previous amount of Ether in Wei. * @param to Updated amount of Ether in Wei. */ event SwapEtherAmended( uint256 indexed swapID, uint256 seqNum, uint8 indexed side, uint256 index, uint256 from, uint256 to ); /** * Emitted when the flat fee parameters have changed, see :sol:func:`setFees`. * * @param flatFee Fee to be paid by a swap taker in Wei of Ether. * @param lowFee Threshold of NFT Protocol tokens to be held by a swap taker in order to get a 10% fee discount. * @param highFee Threshold of NFT Protocol tokens to be held by a swap taker in order to pay no fees. */ event FeesChanged(uint256 flatFee, uint256 lowFee, uint256 highFee); /** * Emitted when Ether funds were deposited into the DEX, see :sol:func:`balance`. * * @param account Address of the account. * @param value Wei of Ether deposited. */ event Deposited(address indexed account, uint256 value); /** * Emitted when Ether funds were withdrawn from the DEX, see :sol:func:`balance`. * * @param account Address of the account. * @param value Wei of Ether withdrawn. */ event Withdrawn(address indexed account, uint256 value); /** * Emitted when Ether funds were spent during a make or take swap operation, see :sol:func:`balance`. * * @param spender Address of the spender. * @param value Wei of Ether spent. * @param swapID ID of the swap, the Ether was spent on, see :sol:func:`takeSwap`, :sol:func:`amendSwapEther`. */ event Spent(address indexed spender, uint256 value, uint256 indexed swapID); /** * Emitted when funds were rescued, see :sol:func:`rescue`. * * @param recipient Address of the beneficiary, e.g., the administrator account. * @param value Wei of Ether rescued. */ event Rescued(address indexed recipient, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./interface/IDEXConstants.sol"; abstract contract DEXConstants { uint8 public constant MAKER_SIDE = 0; uint8 public constant TAKER_SIDE = 1; uint8 public constant ERC1155_ASSET = 0; uint8 public constant ERC721_ASSET = 1; uint8 public constant ERC20_ASSET = 2; uint8 public constant ETHER_ASSET = 3; uint8 public constant OPEN_SWAP = 0; uint8 public constant CLOSED_SWAP = 1; uint8 public constant DROPPED_SWAP = 2; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/access/Ownable.sol"; import "./interface/IDEXAccessControl.sol"; contract DEXAccessControl is IDEXAccessControl, Ownable { /** * @inheritdoc IDEXAccessControl */ bool public locked = false; /** * @inheritdoc IDEXAccessControl */ bool public deprecated = false; /** * @dev Unlocked DEX function modifier. */ modifier unlocked() { require(!locked, "DEX locked"); _; } /** * @dev Supported (not deprecated) function modifier. */ modifier supported() { require(!deprecated, "DEX deprecated"); _; } /** * @dev Not owner function modifier. */ modifier notOwner() { require(owner() != _msgSender(), "Owner prohibited"); _; } /** * Initializes access control. * @param owner_ Address of the administrator account (multisig). */ constructor(address owner_) { transferOwnership(owner_); } /** * @inheritdoc IDEXAccessControl * @dev This function is only accessible by the administrator account. */ function lock(bool lock_) external override onlyOwner { require(lock_ != locked, "State unchanged"); locked = lock_; emit Locked(locked); } /** * @inheritdoc IDEXAccessControl * @dev This function is only accessible by the administrator account. */ function deprecate(bool deprecate_) external override onlyOwner { require(deprecate_ != deprecated, "State unchanged"); deprecated = deprecate_; emit Deprecated(deprecated); } /** * @dev This function is disabled. */ function renounceOwnership() public override onlyOwner { revert("Disabled"); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://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"); (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"); (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"); (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"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol) pragma solidity ^0.8.0; import "../IERC1155Receiver.sol"; import "../../../utils/introspection/ERC165.sol"; /** * @dev _Available since v3.1._ */ abstract contract ERC1155Receiver is ERC165, IERC1155Receiver { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155Receiver is IERC165 { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IDEXConstants { /** * @dev Returns the index of maker side in the swap components array. */ function MAKER_SIDE() external pure returns (uint8); /** * @dev Returns the index of taker side in the swap components array. */ function TAKER_SIDE() external pure returns (uint8); /** * @dev Returns the asset type for ERC1155 swap components. */ function ERC1155_ASSET() external pure returns (uint8); /** * @dev Returns the asset type for ERC721 swap components. */ function ERC721_ASSET() external pure returns (uint8); /** * @dev Returns the asset type for ERC20 swap components. */ function ERC20_ASSET() external pure returns (uint8); /** * @dev Returns to asset type for Ether swap components. */ function ETHER_ASSET() external pure returns (uint8); /** * @dev Returns the swap status for open (i.e. active) swaps. */ function OPEN_SWAP() external pure returns (uint8); /** * @dev Returns the swap status for closed swaps. */ function CLOSED_SWAP() external pure returns (uint8); /** * @dev Returns the swap status for dropped swaps. */ function DROPPED_SWAP() external pure returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IDEXAccessControl { /** * Return the locked state of the DEX. * In locked state, all transactional functions are disabled. * @return `True` if the DEX is in locked state, `false` if the DEX is in unlocked state. */ function locked() external view returns (bool); /** * Return the deprecated state of the DEX. * In deprecated state, no new swaps can be opened. All other functions remain intact. * @return `True` if the DEX is in deprecated state. */ function deprecated() external view returns (bool); /** * Lock the DEX in case of an emergency. * @param lock_ `True` to lock the DEX, `false` to unlock the DEX. */ function lock(bool lock_) external; /** * Deprecate the DEX if a new contract is rolled out. * @param deprecate_ `True` to deprecate the DEX, `false` to lift DEX deprecation. */ function deprecate(bool deprecate_) external; /** * Emitted when the DEX locked state changed, see :sol:func:`locked`. * @param locked_ `True` if the DEX was locked, `false` if the DEX was unlocked. */ event Locked(bool locked_); /** * Emitted when the DEX deprecated state changed, see :sol:func:`deprecated`. * @param deprecated_ `True` if the DEX was deprecated, `false` if DEX deprecation was lifted. */ event Deprecated(bool deprecated_); }
{ "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "bytecodeHash": "none" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"token_","type":"address"},{"internalType":"address","name":"admin_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"deprecated_","type":"bool"}],"name":"Deprecated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"flatFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lowFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"highFee","type":"uint256"}],"name":"FeesChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"locked_","type":"bool"}],"name":"Locked","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":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Rescued","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"swapID","type":"uint256"}],"name":"Spent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"swapID","type":"uint256"}],"name":"SwapDropped","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"swapID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"seqNum","type":"uint256"},{"indexed":true,"internalType":"uint8","name":"side","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"from","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"to","type":"uint256"}],"name":"SwapEtherAmended","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"swapID","type":"uint256"},{"components":[{"internalType":"uint8","name":"assetType","type":"uint8"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256[]","name":"tokenIDs","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"indexed":false,"internalType":"struct INFTProtocolDEX.Component[]","name":"make","type":"tuple[]"},{"components":[{"internalType":"uint8","name":"assetType","type":"uint8"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256[]","name":"tokenIDs","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"indexed":false,"internalType":"struct INFTProtocolDEX.Component[]","name":"take","type":"tuple[]"},{"indexed":true,"internalType":"address","name":"maker","type":"address"},{"indexed":true,"internalType":"bool","name":"custodial","type":"bool"},{"indexed":false,"internalType":"uint256","name":"expiration","type":"uint256"},{"indexed":false,"internalType":"address[]","name":"whitelist","type":"address[]"}],"name":"SwapMade","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"swapID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"seqNum","type":"uint256"},{"indexed":true,"internalType":"address","name":"taker","type":"address"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SwapTaken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[],"name":"CLOSED_SWAP","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DROPPED_SWAP","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERC1155_ASSET","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERC20_ASSET","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERC721_ASSET","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETHER_ASSET","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAKER_SIDE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPEN_SWAP","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TAKER_SIDE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"swapID_","type":"uint256"},{"internalType":"uint8","name":"side_","type":"uint8"},{"internalType":"uint256","name":"value_","type":"uint256"}],"name":"amendSwapEther","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"swapID_","type":"uint256"},{"internalType":"uint8","name":"side_","type":"uint8"},{"internalType":"uint256","name":"value_","type":"uint256"}],"name":"amendSwapEtherSendValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender_","type":"address"},{"internalType":"uint256","name":"swapID_","type":"uint256"},{"internalType":"uint8","name":"side_","type":"uint8"},{"internalType":"uint256","name":"value_","type":"uint256"}],"name":"amendSwapEtherSendValueWith","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"of_","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"deprecate_","type":"bool"}],"name":"deprecate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deprecated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"swapID_","type":"uint256"}],"name":"dropSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flatFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"highFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"lock_","type":"bool"}],"name":"lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"locked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lowFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"majorVersion","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint8","name":"assetType","type":"uint8"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256[]","name":"tokenIDs","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"internalType":"struct INFTProtocolDEX.Component[]","name":"make_","type":"tuple[]"},{"components":[{"internalType":"uint8","name":"assetType","type":"uint8"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256[]","name":"tokenIDs","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"internalType":"struct INFTProtocolDEX.Component[]","name":"take_","type":"tuple[]"},{"internalType":"bool","name":"custodial_","type":"bool"},{"internalType":"uint256","name":"expiration_","type":"uint256"},{"internalType":"address[]","name":"whitelist_","type":"address[]"}],"name":"makeSwap","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint8","name":"assetType","type":"uint8"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256[]","name":"tokenIDs","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"internalType":"struct INFTProtocolDEX.Component[]","name":"make_","type":"tuple[]"}],"name":"makerSendValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender_","type":"address"},{"components":[{"internalType":"uint8","name":"assetType","type":"uint8"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256[]","name":"tokenIDs","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"internalType":"struct INFTProtocolDEX.Component[]","name":"make_","type":"tuple[]"}],"name":"makerSendValueWith","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minorVersion","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numSwaps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"swapID_","type":"uint256"}],"name":"requireCanTakeSwap","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender_","type":"address"},{"internalType":"uint256","name":"swapID_","type":"uint256"}],"name":"requireCanTakeSwapWith","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"swapID","type":"uint256"}],"name":"requireMakerAssets","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"swapID_","type":"uint256"}],"name":"requireTakerAssets","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender_","type":"address"},{"internalType":"uint256","name":"swapID_","type":"uint256"}],"name":"requireTakerAssetsWith","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rescue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"flatFee_","type":"uint256"},{"internalType":"uint256","name":"lowFee_","type":"uint256"},{"internalType":"uint256","name":"highFee_","type":"uint256"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"swapID_","type":"uint256"}],"name":"swap","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint8","name":"status","type":"uint8"},{"components":[{"internalType":"uint8","name":"assetType","type":"uint8"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256[]","name":"tokenIDs","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"internalType":"struct INFTProtocolDEX.Component[][2]","name":"components","type":"tuple[][2]"},{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"taker","type":"address"},{"internalType":"bool","name":"whitelist","type":"bool"},{"internalType":"bool","name":"custodial","type":"bool"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"uint256","name":"seqNum","type":"uint256"}],"internalType":"struct INFTProtocolDEX.Swap","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"swapID_","type":"uint256"},{"internalType":"uint256","name":"seqNum_","type":"uint256"}],"name":"takeSwap","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"takerFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender_","type":"address"}],"name":"takerFeeWith","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"swapID_","type":"uint256"}],"name":"takerSendValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender_","type":"address"},{"internalType":"uint256","name":"swapID_","type":"uint256"}],"name":"takerSendValueWith","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tvl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"swapID_","type":"uint256"}],"name":"whitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender_","type":"address"},{"internalType":"uint256","name":"swapID_","type":"uint256"}],"name":"whitelistedWith","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value_","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawFull","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a06040526000805461ffff60a01b1916905566038d7ea4c6800060025569021e19e0c9bab240000060035569152d02c7e14af68000006004553480156200004657600080fd5b5060405162005dcb38038062005dcb83398101604081905262000069916200022f565b806200007533620000e1565b620000808162000131565b50600180556001600160a01b03821660805260025460035460045460408051938452602084019290925282820152517fe06a46af1c04656f68e4f75cbbb23baa176651c7f99930a378ef9f1616dc2b8c9181900360600190a1505062000267565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6200013b620001b4565b6001600160a01b038116620001a65760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b620001b181620000e1565b50565b6000546001600160a01b03163314620002105760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016200019d565b565b80516001600160a01b03811681146200022a57600080fd5b919050565b600080604083850312156200024357600080fd5b6200024e8362000212565b91506200025e6020840162000212565b90509250929050565b608051615b416200028a60003960008181610adb015261250a0152615b416000f3fe6080604052600436106103545760003560e01c80638eca4acc116101c6578063c38509eb116100f7578063e5328e0611610095578063f23a6e611161006f578063f23a6e6114610a6a578063f2fde38b14610a96578063f31d433414610ab6578063fc0c546a14610ac957600080fd5b8063e5328e0614610a54578063eb29c7ae14610734578063ef2dbe431461073457600080fd5b8063d3c71cde116100d1578063d3c71cde146109f3578063d528cd6b14610a13578063d9eb594714610a29578063e0dd89ec14610a3f57600080fd5b8063c38509eb14610992578063cec10c11146109b2578063cf309012146109d257600080fd5b8063a85c57f511610164578063b20e27ef1161013e578063b20e27ef14610911578063b43e725314610931578063b69ef8a814610951578063bc197c811461096657600080fd5b8063a85c57f5146108d0578063aa402f7d146108e6578063af05a5c5146108fc57600080fd5b806396b90c59116101a057806396b90c591461087b578063999716581461089b578063a2aabd2a1461089b578063a4b721a6146108b057600080fd5b80638eca4acc1461080e5780639251cff41461082e57806394b918de1461084e57600080fd5b806343f0179b116102a05780636f9abf181161023e578063725d85e111610218578063725d85e1146106df57806372ba01a3146107945780637436f3dc146107b45780638da5cb5b146107dc57600080fd5b80636f9abf181461073457806370a0823114610749578063715018a61461077f57600080fd5b80635a8091121161027a5780635a809112146106df5780635dccad8a146106f45780636eb13096146106df5780636f2b2c211461071457600080fd5b806343f0179b1461068a5780634e9bf15b1461069f57806356f15878146106bf57600080fd5b8063150b7a021161030d5780632e1a7d4d116102e75780632e1a7d4d1461060957806333c12d0d1461062957806338179d0d1461063c5780633d4efe091461066a57600080fd5b8063150b7a021461058957806318574b69146105cd5780631fbe1979146105f457600080fd5b806301ffc9a7146104975780630305d723146104cc57806306fdde03146104e15780630c19eb29146105285780630dd0a042146105485780630e136b191461056857600080fd5b3661049257600054600160a81b900460ff161561038c5760405162461bcd60e51b815260040161038390614a31565b60405180910390fd5b600054600160a01b900460ff16156103b65760405162461bcd60e51b815260040161038390614a59565b6000546001600160a01b03163314156103e15760405162461bcd60e51b815260040161038390614a7d565b34806104255760405162461bcd60e51b815260206004820152601360248201527245746865722076616c7565206973207a65726f60681b6044820152606401610383565b3360008181526006602052604081208054849290610444908490614abd565b92505081905550816007600082825461045d9190614abd565b90915550506040518281526001600160a01b03821690600080516020615b158339815191529060200160405180910390a25050005b600080fd5b3480156104a357600080fd5b506104b76104b2366004614ad5565b610afd565b60405190151581526020015b60405180910390f35b6104df6104da366004614b51565b610b34565b005b3480156104ed57600080fd5b5061051b6040518060400160405280600e81526020016d09c8ca8a0e4dee8dec6ded8888ab60931b81525081565b6040516104c39190614c34565b34801561053457600080fd5b506104b7610543366004614c7c565b610dc4565b34801561055457600080fd5b506104df610563366004614ca8565b610e14565b34801561057457600080fd5b506000546104b790600160a81b900460ff1681565b34801561059557600080fd5b506105b46105a4366004614d7a565b630a85bd0160e11b949350505050565b6040516001600160e01b031990911681526020016104c3565b3480156105d957600080fd5b506105e2600381565b60405160ff90911681526020016104c3565b34801561060057600080fd5b506104df610ecd565b34801561061557600080fd5b506104df610624366004614de5565b61101a565b6104df610637366004614e0d565b611026565b34801561064857600080fd5b5061065c610657366004614de5565b6113af565b6040519081526020016104c3565b34801561067657600080fd5b506104b7610685366004614de5565b6113e4565b34801561069657600080fd5b5061065c6113f0565b3480156106ab57600080fd5b5061065c6106ba366004614e45565b611400565b3480156106cb57600080fd5b5061065c6106da366004614e99565b611479565b3480156106eb57600080fd5b506105e2600181565b34801561070057600080fd5b5061065c61070f366004614e0d565b6117d8565b34801561072057600080fd5b506104df61072f366004614de5565b6117ee565b34801561074057600080fd5b506105e2600081565b34801561075557600080fd5b5061065c610764366004614ee1565b6001600160a01b031660009081526006602052604090205490565b34801561078b57600080fd5b506104df611aa1565b3480156107a057600080fd5b506104df6107af366004614de5565b611adc565b3480156107c057600080fd5b506107c9600081565b60405161ffff90911681526020016104c3565b3480156107e857600080fd5b506000546001600160a01b03165b6040516001600160a01b0390911681526020016104c3565b34801561081a57600080fd5b506104df610829366004614c7c565b611d86565b34801561083a57600080fd5b506104df610849366004614ca8565b612068565b34801561085a57600080fd5b5061086e610869366004614de5565b61211a565b6040516104c3919061500a565b34801561088757600080fd5b506104df610896366004614de5565b61232a565b3480156108a757600080fd5b506105e2600281565b3480156108bc57600080fd5b506104df6108cb366004614c7c565b612330565b3480156108dc57600080fd5b5061065c60035481565b3480156108f257600080fd5b5061065c60055481565b34801561090857600080fd5b506107c9600381565b34801561091d57600080fd5b5061065c61092c3660046150b6565b6124b0565b34801561093d57600080fd5b5061065c61094c366004614ee1565b6124bd565b34801561095d57600080fd5b5061065c6125f9565b34801561097257600080fd5b506105b4610981366004615185565b63bc197c8160e01b95945050505050565b34801561099e57600080fd5b506104df6109ad366004614de5565b612604565b3480156109be57600080fd5b506104df6109cd366004615232565b61260e565b3480156109de57600080fd5b506000546104b790600160a01b900460ff1681565b3480156109ff57600080fd5b5061065c610a0e366004614c7c565b6126e5565b348015610a1f57600080fd5b5061065c60045481565b348015610a3557600080fd5b5061065c60025481565b348015610a4b57600080fd5b506104df61272a565b348015610a6057600080fd5b5061065c60075481565b348015610a7657600080fd5b506105b4610a8536600461525e565b63f23a6e6160e01b95945050505050565b348015610aa257600080fd5b506104df610ab1366004614ee1565b612745565b6104df610ac43660046152c6565b6127bb565b348015610ad557600080fd5b506107f67f000000000000000000000000000000000000000000000000000000000000000081565b60006001600160e01b03198216630271189760e51b1480610b2e57506301ffc9a760e01b6001600160e01b03198316145b92915050565b600054600160a81b900460ff1615610b5e5760405162461bcd60e51b815260040161038390614a31565b600054600160a01b900460ff1615610b885760405162461bcd60e51b815260040161038390614a59565b6000546001600160a01b0316331415610bb35760405162461bcd60e51b815260040161038390614a7d565b60026001541415610bd65760405162461bcd60e51b8152600401610383906152e8565b600260015586610c1d5760405162461bcd60e51b81526020600482015260126024820152714d616b65207369646520697320656d70747960701b6044820152606401610383565b84610c5f5760405162461bcd60e51b815260206004820152601260248201527154616b65207369646520697320656d70747960701b6044820152606401610383565b610c6883612b85565b610ca95760405162461bcd60e51b815260206004820152601260248201527124b73b30b634b21032bc3834b930ba34b7b760711b6044820152606401610383565b33600080610cc383610cbb8c8e6153d3565b346000612b95565b9092509050610cda610cd5898b6153d3565b612c2c565b5081341015610cfb5760405162461bcd60e51b815260040161038390615446565b610d0b8b8b8b8b8b8b8b8b612d03565b3460076000828254610d1d9190614abd565b90915550610d2e90508b8b89612f00565b610d3a81600554612fdd565b600160056000828254610d4d9190614abd565b92505081905550861515836001600160a01b03166001600554610d70919061547d565b7f576c6928b032607301c93952b75a4f7057cc22a7113d7a7434fe50bdfa65c0aa8e8e8e8e8d8d8d604051610dab97969594939291906155e6565b60405180910390a4505060018055505050505050505050565b6000816005548110610de85760405162461bcd60e51b815260040161038390615666565b505060009081526009602090815260408083206001600160a01b03949094168352929052205460ff1690565b610e1c613088565b600060149054906101000a900460ff1615158115151415610e715760405162461bcd60e51b815260206004820152600f60248201526e14dd185d19481d5b98da185b99d959608a1b6044820152606401610383565b6000805460ff60a01b1916600160a01b8315158102919091179182905560405160ff9190920416151581527fe3f0ec9c4af57e69d5aeff78a5912ca25733e4458710bab2b55d0985e98aeb5e906020015b60405180910390a150565b610ed5613088565b60026001541415610ef85760405162461bcd60e51b8152600401610383906152e8565b600260015533600081815260066020526040812054600754909190610f1d904761547d565b9050818111610f635760405162461bcd60e51b81526020600482015260126024820152714e6f2076616c756520746f2072657363756560701b6044820152606401610383565b6000610f6f838361547d565b6001600160a01b038516600090815260066020526040812080549293508392909190610f9c908490614abd565b90915550506040518181526001600160a01b03851690600080516020615b158339815191529060200160405180910390a2836001600160a01b03167f8aec0ce3dadffacf4b7a963e0fed1ff2e6151b4c95d4a65acafa9d12996304028260405161100891815260200190565b60405180910390a25050600180555050565b611023816130e2565b50565b600054600160a01b900460ff16156110505760405162461bcd60e51b815260040161038390614a59565b6000546001600160a01b031633141561107b5760405162461bcd60e51b815260040161038390614a7d565b6002600154141561109e5760405162461bcd60e51b8152600401610383906152e8565b60026001558160ff811615806110b7575060ff81166001145b6110f25760405162461bcd60e51b815260206004820152600c60248201526b496e76616c6964207369646560a01b6044820152606401610383565b8360055481106111145760405162461bcd60e51b815260040161038390615666565b6000858152600860205260409020600181015460ff16156111475760405162461bcd60e51b81526004016103839061568e565b600481015433906001600160a01b031681146111755760405162461bcd60e51b8152600401610383906156b5565b6111828260060154612b85565b61119e5760405162461bcd60e51b8152600401610383906156dd565b6000826002018760ff16600281106111b8576111b8615703565b0190506000806111c883896132d9565b91509150818814156112145760405162461bcd60e51b8152602060048201526015602482015274115d1a195c881d985b1d59481d5b98da185b99d959605a1b6044820152606401610383565b6000881180611224575082546001105b61126a5760405162461bcd60e51b8152602060048201526017602482015276537761702073696465206265636f6d657320656d70747960481b6044820152606401610383565b6001600160a01b03841660009081526006602052604090205460ff8a1660011480156112965750600034115b156112b3576112ae6112a83483614abd565b8c612fdd565b611318565b60ff8a1661131857828911156112f5576112cd838a61547d565b6112d73483614abd565b10156112f55760405162461bcd60e51b815260040161038390615446565b61131889846113043485614abd565b61130e9190614abd565b6112a8919061547d565b346007600082825461132a9190614abd565b9250508190555060018660070160008282546113469190614abd565b9091555050600786015460408051918252602082018490528101849052606081018a905260ff8b16908c907f5d7324c5c976f20efe1908630c8d665420079e838769ac3657dffa3e8ba050f49060800160405180910390a3505060018055505050505050505050565b60008054600160a01b900460ff16156113da5760405162461bcd60e51b815260040161038390614a59565b610b2e33836126e5565b6000610b2e3383610dc4565b60006113fb336124bd565b905090565b60008054600160a81b900460ff161561142b5760405162461bcd60e51b815260040161038390614a31565b600054600160a01b900460ff16156114555760405162461bcd60e51b815260040161038390614a59565b600061146d8561146585876153d3565b600080612b95565b509150505b9392505050565b60008054600160a01b900460ff16156114a45760405162461bcd60e51b815260040161038390614a59565b8260ff811615806114b8575060ff81166001145b6114f35760405162461bcd60e51b815260206004820152600c60248201526b496e76616c6964207369646560a01b6044820152606401610383565b6000858152600860205260409020600181015460ff16156115265760405162461bcd60e51b81526004016103839061568e565b60048101546001600160a01b038881169116146115555760405162461bcd60e51b8152600401610383906156b5565b6115628160060154612b85565b61157e5760405162461bcd60e51b8152600401610383906156dd565b6000816002018660ff166002811061159857611598615703565b01905060006116c482805480602002602001604051908101604052809291908181526020016000905b828210156116bb5760008481526020908190206040805160808101825260038602909201805460ff8116845261010090046001600160a01b031683850152600181018054835181870281018701855281815294959294938601939283018282801561164b57602002820191906000526020600020905b815481526020019060010190808311611637575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156116a357602002820191906000526020600020905b81548152602001906001019080831161168f575b505050505081525050815260200190600101906115c1565b505050506134c9565b90508086141561170e5760405162461bcd60e51b8152602060048201526015602482015274115d1a195c881d985b1d59481d5b98da185b99d959605a1b6044820152606401610383565b600086118061171e575081546001105b6117645760405162461bcd60e51b8152602060048201526017602482015276537761702073696465206265636f6d657320656d70747960481b6044820152606401610383565b6001600160a01b03891660009081526006602052604090205460ff881615801561178d57508187115b80156117a1575061179e828861547d565b81105b156117c657806117b1838961547d565b6117bb919061547d565b9550505050506117cf565b60009550505050505b50949350505050565b60006117e633858585611479565b949350505050565b600054600160a01b900460ff16156118185760405162461bcd60e51b815260040161038390614a59565b80600554811061183a5760405162461bcd60e51b815260040161038390615666565b600082815260086020908152604080832081516101208101835281548152600182015460ff169381019390935281518083018352909183019060028084019086835b828210156119b457838201805480602002602001604051908101604052809291908181526020016000905b828210156119a15760008481526020908190206040805160808101825260038602909201805460ff8116845261010090046001600160a01b031683850152600181018054835181870281018701855281815294959294938601939283018282801561193157602002820191906000526020600020905b81548152602001906001019080831161191d575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561198957602002820191906000526020600020905b815481526020019060010190808311611975575b505050505081525050815260200190600101906118a7565b505050508152602001906001019061187c565b5050509082525060048201546001600160a01b039081166020808401919091526005840154918216604084015260ff600160a01b8304811615156060850152600160a81b909204821615156080840152600684015460a084015260079093015460c090920191909152908201519192501615611a425760405162461bcd60e51b81526004016103839061568e565b8060c0015115611a855760405162461bcd60e51b815260206004820152600e60248201526d14ddd85c0818dd5cdd1bd91a585b60921b6044820152606401610383565b6040810151516060820151611a9c9190600061355d565b505050565b611aa9613088565b60405162461bcd60e51b8152602060048201526008602482015267111a5cd8589b195960c21b6044820152606401610383565b600054600160a01b900460ff1615611b065760405162461bcd60e51b815260040161038390614a59565b6000546001600160a01b0316331415611b315760405162461bcd60e51b815260040161038390614a7d565b60026001541415611b545760405162461bcd60e51b8152600401610383906152e8565b6002600190815560008281526008602052604090209081015460ff1615611b8d5760405162461bcd60e51b81526004016103839061568e565b60048101546001600160a01b0316336001600160a01b031614611bc25760405162461bcd60e51b8152600401610383906156b5565b60018101805460ff1916600217905560005b6002820154811015611d52576005820154600160a81b900460ff1680611c2557506003600283016000018281548110611c0f57611c0f615703565b600091825260209091206003909102015460ff16145b15611d4057611d40600283016000018281548110611c4557611c45615703565b6000918252602091829020604080516080810182526003909302909101805460ff811684526001600160a01b0361010090910416838501526001810180548351818702810187018552818152949592949386019392830182828015611cc957602002820191906000526020600020905b815481526020019060010190808311611cb5575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015611d2157602002820191906000526020600020905b815481526020019060010190808311611d0d575b50505091909252505050600484015430906001600160a01b03166135d5565b80611d4a81615719565b915050611bd4565b5060405182907f0fd96601866cb818103091fe53228f73be296da894da73b40c0185fde3e4d0c690600090a2505060018055565b600054600160a01b900460ff1615611db05760405162461bcd60e51b815260040161038390614a59565b806005548110611dd25760405162461bcd60e51b815260040161038390615666565b6000611de0848460006137b5565b50505060038101805460408051602080840282018101909252828152939450611f129392919060009084015b82821015611f065760008481526020908190206040805160808101825260038602909201805460ff8116845261010090046001600160a01b0316838501526001810180548351818702810187018552818152949592949386019392830182828015611e9657602002820191906000526020600020905b815481526020019060010190808311611e82575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015611eee57602002820191906000526020600020905b815481526020019060010190808311611eda575b50505050508152505081526020019060010190611e0c565b5050505085600161355d565b6005810154600160a81b900460ff166120625761206260028201600001805480602002602001604051908101604052809291908181526020016000905b828210156120495760008481526020908190206040805160808101825260038602909201805460ff8116845261010090046001600160a01b0316838501526001810180548351818702810187018552818152949592949386019392830182828015611fd957602002820191906000526020600020905b815481526020019060010190808311611fc5575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561203157602002820191906000526020600020905b81548152602001906001019080831161201d575b50505050508152505081526020019060010190611f4f565b5050505060048301546001600160a01b0316600061355d565b50505050565b612070613088565b600060159054906101000a900460ff16151581151514156120c55760405162461bcd60e51b815260206004820152600f60248201526e14dd185d19481d5b98da185b99d959608a1b6044820152606401610383565b6000805460ff60a81b1916600160a81b8315158102919091179182905560405160ff9190920416151581527f92a709fe0704b42849ae468c6c839690d63164022fbd0d6b49502f95bc6424ff90602001610ec2565b61212261495a565b8160055481106121445760405162461bcd60e51b815260040161038390615666565b600083815260086020908152604080832081516101208101835281548152600182015460ff169381019390935281518083018352929390929184019190600280850191835b828210156122c157838201805480602002602001604051908101604052809291908181526020016000905b828210156122ae5760008481526020908190206040805160808101825260038602909201805460ff8116845261010090046001600160a01b031683850152600181018054835181870281018701855281815294959294938601939283018282801561223e57602002820191906000526020600020905b81548152602001906001019080831161222a575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561229657602002820191906000526020600020905b815481526020019060010190808311612282575b505050505081525050815260200190600101906121b4565b5050505081526020019060010190612189565b5050509082525060048201546001600160a01b0390811660208301526005830154908116604083015260ff600160a01b8204811615156060840152600160a81b9091041615156080820152600682015460a082015260079091015460c090910152915050919050565b61102333825b600054600160a01b900460ff161561235a5760405162461bcd60e51b815260040161038390614a59565b80600554811061237c5760405162461bcd60e51b815260040161038390615666565b600061238a848460006137b5565b505050600381018054604080516020808402820181019092528281529394506120629392919060009084015b82821015611f065760008481526020908190206040805160808101825260038602909201805460ff8116845261010090046001600160a01b031683850152600181018054835181870281018701855281815294959294938601939283018282801561244057602002820191906000526020600020905b81548152602001906001019080831161242c575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561249857602002820191906000526020600020905b815481526020019060010190808311612484575b505050505081525050815260200190600101906123b6565b6000611472338484611400565b60008054600160a01b900460ff16156124e85760405162461bcd60e51b815260040161038390614a59565b6040516370a0823160e01b81526001600160a01b0383811660048301526000917f0000000000000000000000000000000000000000000000000000000000000000909116906370a0823190602401602060405180830381865afa158015612553573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125779190615734565b9050600454811061258b5750600092915050565b60035481101561259f575050600254919050565b6000600a60025460096125b2919061574d565b6125bc919061576c565b90506003546004546125ce919061547d565b6003546125db908461547d565b6125e5908361574d565b6125ef919061576c565b6117e6908261547d565b60006113fb33610764565b6110233382611d86565b600054600160a81b900460ff16156126385760405162461bcd60e51b815260040161038390614a31565b612640613088565b808211156126905760405162461bcd60e51b815260206004820152601960248201527f6c6f77466565206d757374206265203c3d2068696768466565000000000000006044820152606401610383565b60028390556003829055600481905560408051848152602081018490529081018290527fe06a46af1c04656f68e4f75cbbb23baa176651c7f99930a378ef9f1616dc2b8c9060600160405180910390a1505050565b60008054600160a01b900460ff16156127105760405162461bcd60e51b815260040161038390614a59565b600061271e848460006137b5565b50909695505050505050565b33600090815260066020526040902054612743906130e2565b565b61274d613088565b6001600160a01b0381166127b25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610383565b61102381613a62565b600054600160a01b900460ff16156127e55760405162461bcd60e51b815260040161038390614a59565b6000546001600160a01b03163314156128105760405162461bcd60e51b815260040161038390614a7d565b600260015414156128335760405162461bcd60e51b8152600401610383906152e8565b60026001553360008080806128498588346137b5565b9350935093509350858460070154146128935760405162461bcd60e51b815260206004820152600c60248201526b57726f6e67207365714e756d60a01b6044820152606401610383565b823410156128f25760405162461bcd60e51b815260206004820152602660248201527f496e73756666696369656e742045746865722076616c756520287072696365206044820152652b206665652960d01b6064820152608401610383565b6001848101805460ff191690911790556005840180546001600160a01b0319166001600160a01b0387161790556129298288612fdd565b600484015460058501546129579160028701916001600160a01b0390911690600160a81b900460ff16613ab2565b60005b6003850154811015612a8e57612a7c60028601600101828154811061298157612981615703565b6000918252602091829020604080516080810182526003909302909101805460ff811684526001600160a01b0361010090910416838501526001810180548351818702810187018552818152949592949386019392830182828015612a0557602002820191906000526020600020905b8154815260200190600101908083116129f1575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015612a5d57602002820191906000526020600020905b815481526020019060010190808311612a49575b50505091909252505050600487015488906001600160a01b03166135d5565b80612a8681615719565b91505061295a565b50600080546001600160a01b0316808252600660205260408220805491928492612ab9908490614abd565b925050819055503460076000828254612ad29190614abd565b925050819055508160076000828254612aeb919061547d565b9091555050600785015460408051918252602082018490526001600160a01b038816918a917f07e2fe203bcde02eeeacd77c107f07b910c790f014f45fb11a8e745456647f16910160405180910390a36000546001600160a01b03166001600160a01b0316600080516020615b1583398151915283604051612b6f91815260200190565b60405180910390a2505060018055505050505050565b6000811580610b2e575050431090565b6000806000612ba386612c2c565b6001600160a01b038816600090815260066020526040902054909150612bc98583614abd565b612bd38783614abd565b10612c055760008583612be68985614abd565b612bf0919061547d565b612bfa919061547d565b935093505050612c23565b80612c108684614abd565b612c1a919061547d565b60009350935050505b94509492505050565b60008080805b8451811015612cfa57600360ff16858281518110612c5257612c52615703565b60200260200101516000015160ff161415612cba578115612cb55760405162461bcd60e51b815260206004820152601960248201527f4d756c7469706c6520657468657220636f6d706f6e656e7473000000000000006044820152606401610383565b600191505b612cdc858281518110612ccf57612ccf615703565b6020026020010151613d11565b612ce69084614abd565b925080612cf281615719565b915050612c32565b50909392505050565b600580546000818152600860205260408082209283559183018054881515600160a81b0260ff60a81b199091161790558254815281812060060186905591548252812060040180546001600160a01b031916331790555b87811015612dd1576005546000908152600860205260409020600201898983818110612d8857612d88615703565b9050602002810190612d9a919061578e565b815460018101835560009283526020909220909160030201612dbc828261586d565b50508080612dc990615719565b915050612d5a565b5060005b85811015612e4c576005546000908152600860205260409020600301878783818110612e0357612e03615703565b9050602002810190612e15919061578e565b815460018101835560009283526020909220909160030201612e37828261586d565b50508080612e4490615719565b915050612dd5565b50600580546000908152600860205260408120909101805460ff60a01b1916831515600160a01b021790555b81811015612ef5576005546000908152600960205260408120600191858585818110612ea657612ea6615703565b9050602002016020810190612ebb9190614ee1565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905580612eed81615719565b915050612e78565b505050505050505050565b3360005b83811015612fd6578280612f4c57506003858583818110612f2757612f27615703565b9050602002810190612f39919061578e565b612f4790602081019061595f565b60ff16145b15612f8d57612f88858583818110612f6657612f66615703565b9050602002810190612f78919061578e565b612f819061597c565b83306135d5565b612fc4565b612fc4858583818110612fa257612fa2615703565b9050602002810190612fb4919061578e565b612fbd9061597c565b8334613f0c565b80612fce81615719565b915050612f04565b5050505050565b33600081815260066020526040902080549084905580841115613033576001600160a01b038216600080516020615b1583398151915261301d838761547d565b60405190815260200160405180910390a2612062565b8084101561206257826001600160a01b0383167f535148561d77998b1c55b0df8e3a745c169a3c2d06073ca7cf45743224cef85d613071878561547d565b60405190815260200160405180910390a350505050565b6000546001600160a01b031633146127435760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610383565b600260015414156131055760405162461bcd60e51b8152600401610383906152e8565b60026001558061314d5760405162461bcd60e51b815260206004820152601360248201527245746865722076616c7565206973207a65726f60681b6044820152606401610383565b33600081815260066020526040902054808311156131ad5760405162461bcd60e51b815260206004820152601b60248201527f45746865722076616c756520657863656564732062616c616e636500000000006044820152606401610383565b6001600160a01b038216600090815260066020526040812080548592906131d590849061547d565b90915550506000546001600160a01b03838116911614613207578260076000828254613201919061547d565b90915550505b6000826001600160a01b03168460405160006040518083038185875af1925050503d8060008114613254576040519150601f19603f3d011682016040523d82523d6000602084013e613259565b606091505b505090508061329e5760405162461bcd60e51b815260206004820152601160248201527015da5d1a191c985dd85b0819985a5b1959607a1b6044820152606401610383565b826001600160a01b03167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d58560405161100891815260200190565b60008060005b84548110156133ba57600360ff168582815481106132ff576132ff615703565b600091825260209091206003909102015460ff1614156133a857600085828154811061332d5761332d615703565b906000526020600020906003020160020160008154811061335057613350615703565b906000526020600020015490508486838154811061337057613370615703565b906000526020600020906003020160020160008154811061339357613393615703565b600091825260209091200155925090506134c2565b806133b281615719565b9150506132df565b506040805160808101825260038152600060208083018290528351828152808201855283850152835160018082528186019095529193606084019291828101908036833701905050815250905083816060015160008151811061341f5761341f615703565b602090810291909101810191909152855460018181018855600088815283902084516003909302018054858501516001600160a01b0316610100026001600160a81b031990911660ff9094169390931792909217825560408401518051859461348c9385019201906149aa565b50606082015180516134a89160028401916020909101906149aa565b50508554600091506134bc9060019061547d565b92509250505b9250929050565b6000805b825181101561355457600360ff168382815181106134ed576134ed615703565b60200260200101516000015160ff1614156135425782818151811061351457613514615703565b60200260200101516060015160008151811061353257613532615703565b6020026020010151915050919050565b8061354c81615719565b9150506134cd565b50600092915050565b60005b83518110156120625781806135995750600360ff1684828151811061358757613587615703565b60200260200101516000015160ff1614155b156135c3576135c38482815181106135b3576135b3615703565b6020026020010151846000613f0c565b806135cd81615719565b915050613560565b825160ff1661365457602083015160408085015160608601519151631759616b60e11b81526001600160a01b03841692632eb2c2d69261361c928892889291600401615988565b600060405180830381600087803b15801561363657600080fd5b505af115801561364a573d6000803e3d6000fd5b5050505050505050565b825160ff16600114156136d757600083602001519050806001600160a01b03166342842e0e8484876040015160008151811061369257613692615703565b60209081029190910101516040516001600160e01b031960e086901b1681526001600160a01b039384166004820152929091166024830152604482015260640161361c565b825160ff1660021415613758576000836020015190506000846060015160008151811061370657613706615703565b60200260200101519050306001600160a01b0316846001600160a01b031614156137435761373e6001600160a01b0383168483613f58565b612fd6565b612fd66001600160a01b038316858584613fbb565b826060015160008151811061376f5761376f615703565b602002602001015160066000836001600160a01b03166001600160a01b0316815260200190815260200160002060008282546137ab9190614abd565b9091555050505050565b6000806000808560055481106137dd5760405162461bcd60e51b815260040161038390615666565b6000878152600860205260409020600181015460ff16156138105760405162461bcd60e51b81526004016103839061568e565b60048101546001600160a01b038a8116911614156138675760405162461bcd60e51b815260206004820152601460248201527329b2b73232b91034b99039bbb0b81036b0b5b2b960611b6044820152606401610383565b6005810154600160a01b900460ff1615806138a4575060008881526009602090815260408083206001600160a01b038d16845290915290205460ff165b6138e35760405162461bcd60e51b815260206004820152601060248201526f139bdd081a5b881dda1a5d195b1a5cdd60821b6044820152606401610383565b6138f08160060154612b85565b61390c5760405162461bcd60e51b8152600401610383906156dd565b60006139178a6124bd565b9050600080613a4c8c60028601600101805480602002602001604051908101604052809291908181526020016000905b82821015613a415760008481526020908190206040805160808101825260038602909201805460ff8116845261010090046001600160a01b03168385015260018101805483518187028101870185528181529495929493860193928301828280156139d157602002820191906000526020600020905b8154815260200190600101908083116139bd575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015613a2957602002820191906000526020600020905b815481526020019060010190808311613a15575b50505050508152505081526020019060010190613947565b505050508c86612b95565b949d909c50939a50919850919650505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b3360005b8454811015612fd6578280613af35750600360ff16858281548110613add57613add615703565b600091825260209091206003909102015460ff16145b15613bfe57613bf9858281548110613b0d57613b0d615703565b6000918252602091829020604080516080810182526003909302909101805460ff811684526001600160a01b0361010090910416838501526001810180548351818702810187018552818152949592949386019392830182828015613b9157602002820191906000526020600020905b815481526020019060010190808311613b7d575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015613be957602002820191906000526020600020905b815481526020019060010190808311613bd5575b50505050508152505030846135d5565b613cff565b613cff858281548110613c1357613c13615703565b6000918252602091829020604080516080810182526003909302909101805460ff811684526001600160a01b0361010090910416838501526001810180548351818702810187018552818152949592949386019392830182828015613c9757602002820191906000526020600020905b815481526020019060010190808311613c83575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015613cef57602002820191906000526020600020905b815481526020019060010190808311613cdb575b50505050508152505085846135d5565b80613d0981615719565b915050613ab6565b805160009060ff16613d7b5781606001515182604001515114613d765760405162461bcd60e51b815260206004820152601f60248201527f546f6b656e49447320616e6420616d6f756e7473206c656e20646966666572006044820152606401610383565b613f04565b815160ff1660011415613ddd57816040015151600114613d765760405162461bcd60e51b815260206004820152601f60248201527f546f6b656e494473206172726179206c656e677468206d7573742062652031006044820152606401610383565b815160ff1660021415613e3f57816060015151600114613d765760405162461bcd60e51b815260206004820152601e60248201527f416d6f756e7473206172726179206c656e677468206d757374206265203100006044820152606401610383565b815160ff1660031415613ec757816060015151600114613ea15760405162461bcd60e51b815260206004820152601e60248201527f416d6f756e7473206172726179206c656e677468206d757374206265203100006044820152606401610383565b8160600151600081518110613eb857613eb8615703565b60200260200101519050919050565b60405162461bcd60e51b8152602060048201526012602482015271496e76616c6964206173736574207479706560701b6044820152606401610383565b506000919050565b825160ff16613f1f57611a9c8383613ff3565b825160ff1660011415613f3657611a9c83836142d6565b825160ff1660021415613f4d57611a9c8383614536565b611a9c8383836146fd565b6040516001600160a01b038316602482015260448101829052611a9c90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614774565b6040516001600160a01b03808516602483015283166044820152606481018290526120629085906323b872dd60e01b90608401613f84565b60208201516040830151516000906001600160401b0381111561401857614018614cc5565b604051908082528060200260200182016040528015614041578160200160208202803683370190505b50905060005b846040015151811015614091578382828151811061406757614067615703565b6001600160a01b03909216602092830291909101909101528061408981615719565b915050614047565b506000826001600160a01b0316634e1273f48387604001516040518363ffffffff1660e01b81526004016140c69291906159e3565b600060405180830381865afa1580156140e3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261410b9190810190615a43565b90508460400151518151146141625760405162461bcd60e51b815260206004820152601b60248201527f496e76616c69642062616c616e63654f6642617463682063616c6c00000000006044820152606401610383565b60005b85604001515181101561420a578560600151818151811061418857614188615703565b60200260200101518282815181106141a2576141a2615703565b602002602001015110156141f85760405162461bcd60e51b815260206004820152601c60248201527f496e73756666696369656e7420455243313135352062616c616e6365000000006044820152606401610383565b8061420281615719565b915050614165565b5060405163e985e9c560e01b81526001600160a01b0385811660048301523060248301526000919085169063e985e9c590604401602060405180830381865afa15801561425b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061427f9190615ac8565b9050806142ce5760405162461bcd60e51b815260206004820152601860248201527f444558206e6f74204552433131353520617070726f76656400000000000000006044820152606401610383565b505050505050565b6000826020015190506000816001600160a01b0316636352211e856040015160008151811061430757614307615703565b60200260200101516040518263ffffffff1660e01b815260040161432d91815260200190565b602060405180830381865afa15801561434a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061436e9190615ae5565b9050826001600160a01b0316816001600160a01b0316146143ca5760405162461bcd60e51b81526020600482015260166024820152752737ba1022a9219b9918903a37b5b2b71037bbb732b960511b6044820152606401610383565b60405163e985e9c560e01b81526001600160a01b0384811660048301523060248301526000919084169063e985e9c590604401602060405180830381865afa15801561441a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061443e9190615ac8565b9050806144e957826001600160a01b031663081812fc866040015160008151811061446b5761446b615703565b60200260200101516040518263ffffffff1660e01b815260040161449191815260200190565b602060405180830381865afa1580156144ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144d29190615ae5565b6001600160a01b0316306001600160a01b03161490505b80612fd65760405162461bcd60e51b815260206004820152601760248201527f444558206e6f742045524337323120617070726f7665640000000000000000006044820152606401610383565b60208201516040516370a0823160e01b81526001600160a01b038381166004830152600091908316906370a0823190602401602060405180830381865afa158015614585573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145a99190615734565b905083606001516000815181106145c2576145c2615703565b60200260200101518110156146195760405162461bcd60e51b815260206004820152601a60248201527f496e73756666696369656e742045524332302062616c616e63650000000000006044820152606401610383565b604051636eb1769f60e11b81526001600160a01b0384811660048301523060248301526000919084169063dd62ed3e90604401602060405180830381865afa158015614669573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061468d9190615734565b905084606001516000815181106146a6576146a6615703565b6020026020010151811015612fd65760405162461bcd60e51b815260206004820152601c60248201527f496e73756666696369656e7420455243323020616c6c6f77616e6365000000006044820152606401610383565b6001600160a01b038216600090815260066020526040812054606085015180519192909161472d5761472d615703565b60200260200101518282856001600160a01b03163161474c9190614abd565b6147569190614abd565b10156120625760405162461bcd60e51b815260040161038390615446565b60006147c9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166148469092919063ffffffff16565b805190915015611a9c57808060200190518101906147e79190615ac8565b611a9c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610383565b60606117e68484600085856001600160a01b0385163b6148a85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610383565b600080866001600160a01b031685876040516148c49190615b02565b60006040518083038185875af1925050503d8060008114614901576040519150601f19603f3d011682016040523d82523d6000602084013e614906565b606091505b5091509150614916828286614921565b979650505050505050565b60608315614930575081611472565b8251156149405782518084602001fd5b8160405162461bcd60e51b81526004016103839190614c34565b60408051610120810182526000808252602082015290810161497a6149f5565b815260006020820181905260408201819052606082018190526080820181905260a0820181905260c09091015290565b8280548282559060005260206000209081019282156149e5579160200282015b828111156149e55782518255916020019190600101906149ca565b506149f1929150614a1c565b5090565b60405180604001604052806002905b6060815260200190600190039081614a045790505090565b5b808211156149f15760008155600101614a1d565b6020808252600e908201526d1111560819195c1c9958d85d195960921b604082015260600190565b6020808252600a9082015269111156081b1bd8dad95960b21b604082015260600190565b60208082526010908201526f13dddb995c881c1c9bda1a589a5d195960821b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60008219821115614ad057614ad0614aa7565b500190565b600060208284031215614ae757600080fd5b81356001600160e01b03198116811461147257600080fd5b60008083601f840112614b1157600080fd5b5081356001600160401b03811115614b2857600080fd5b6020830191508360208260051b85010111156134c257600080fd5b801515811461102357600080fd5b60008060008060008060008060a0898b031215614b6d57600080fd5b88356001600160401b0380821115614b8457600080fd5b614b908c838d01614aff565b909a50985060208b0135915080821115614ba957600080fd5b614bb58c838d01614aff565b909850965060408b01359150614bca82614b43565b90945060608a0135935060808a01359080821115614be757600080fd5b50614bf48b828c01614aff565b999c989b5096995094979396929594505050565b60005b83811015614c23578181015183820152602001614c0b565b838111156120625750506000910152565b6020815260008251806020840152614c53816040850160208701614c08565b601f01601f19169190910160400192915050565b6001600160a01b038116811461102357600080fd5b60008060408385031215614c8f57600080fd5b8235614c9a81614c67565b946020939093013593505050565b600060208284031215614cba57600080fd5b813561147281614b43565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715614d0357614d03614cc5565b604052919050565b600082601f830112614d1c57600080fd5b81356001600160401b03811115614d3557614d35614cc5565b614d48601f8201601f1916602001614cdb565b818152846020838601011115614d5d57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215614d9057600080fd5b8435614d9b81614c67565b93506020850135614dab81614c67565b92506040850135915060608501356001600160401b03811115614dcd57600080fd5b614dd987828801614d0b565b91505092959194509250565b600060208284031215614df757600080fd5b5035919050565b60ff8116811461102357600080fd5b600080600060608486031215614e2257600080fd5b833592506020840135614e3481614dfe565b929592945050506040919091013590565b600080600060408486031215614e5a57600080fd5b8335614e6581614c67565b925060208401356001600160401b03811115614e8057600080fd5b614e8c86828701614aff565b9497909650939450505050565b60008060008060808587031215614eaf57600080fd5b8435614eba81614c67565b9350602085013592506040850135614ed181614dfe565b9396929550929360600135925050565b600060208284031215614ef357600080fd5b813561147281614c67565b600081518084526020808501945080840160005b83811015614f2e57815187529582019590820190600101614f12565b509495945050505050565b6000826040808201846000805b6002811015614ffd578584038952825180518086526020918201918087019190600582901b88018101865b83811015614fe657898203601f190185528551805160ff168352838101516001600160a01b0316848401528b81015160808d850181905290614fb582860182614efe565b91505060608083015192508482038186015250614fd28183614efe565b978501979685019693505050600101614f71565b509c81019c97509590950194505050600101614f46565b5091979650505050505050565b60208152815160208201526000602083015161502b604084018260ff169052565b506040830151610120806060850152615048610140850183614f39565b9150606085015161506460808601826001600160a01b03169052565b5060808501516001600160a01b03811660a08601525060a085015180151560c08601525060c085015180151560e08601525060e085015161010085810191909152909401519390920192909252919050565b600080602083850312156150c957600080fd5b82356001600160401b038111156150df57600080fd5b6150eb85828601614aff565b90969095509350505050565b60006001600160401b0382111561511057615110614cc5565b5060051b60200190565b600082601f83011261512b57600080fd5b8135602061514061513b836150f7565b614cdb565b82815260059290921b8401810191818101908684111561515f57600080fd5b8286015b8481101561517a5780358352918301918301615163565b509695505050505050565b600080600080600060a0868803121561519d57600080fd5b85356151a881614c67565b945060208601356151b881614c67565b935060408601356001600160401b03808211156151d457600080fd5b6151e089838a0161511a565b945060608801359150808211156151f657600080fd5b61520289838a0161511a565b9350608088013591508082111561521857600080fd5b5061522588828901614d0b565b9150509295509295909350565b60008060006060848603121561524757600080fd5b505081359360208301359350604090920135919050565b600080600080600060a0868803121561527657600080fd5b853561528181614c67565b9450602086013561529181614c67565b9350604086013592506060860135915060808601356001600160401b038111156152ba57600080fd5b61522588828901614d0b565b600080604083850312156152d957600080fd5b50508035926020909101359150565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60006080828403121561533157600080fd5b604051608081016001600160401b03828210818311171561535457615354614cc5565b816040528293508435915061536882614dfe565b90825260208401359061537a82614c67565b816020840152604085013591508082111561539457600080fd5b6153a08683870161511a565b604084015260608501359150808211156153b957600080fd5b506153c68582860161511a565b6060830152505092915050565b60006153e161513b846150f7565b80848252602080830192508560051b8501368111156153ff57600080fd5b855b8181101561543a5780356001600160401b038111156154205760008081fd5b61542c36828a0161531f565b865250938201938201615401565b50919695505050505050565b60208082526018908201527f496e73756666696369656e742045746865722076616c75650000000000000000604082015260600190565b60008282101561548f5761548f614aa7565b500390565b6000808335601e198436030181126154ab57600080fd5b83016020810192503590506001600160401b038111156154ca57600080fd5b8060051b36038313156134c257600080fd5b81835260006001600160fb1b038311156154f557600080fd5b8260051b8083602087013760009401602001938452509192915050565b81835260006020808501808196508560051b81019150846000805b888110156155d8578385038a528235607e1989360301811261554d578283fd5b88016080813561555c81614dfe565b60ff1687528188013561556e81614c67565b6001600160a01b031687890152604061558983820184615494565b83838b015261559b848b0182846154dc565b935050505060606155ae81840184615494565b9350888303828a01526155c28385836154dc565b9d8a019d9850505093870193505060010161552d565b509298975050505050505050565b6080815260006155fa60808301898b615512565b60208382038185015261560e82898b615512565b604085018890528481036060860152858152869250810160005b8681101561565657833561563b81614c67565b6001600160a01b031682529282019290820190600101615628565b509b9a5050505050505050505050565b6020808252600e908201526d125b9d985b1a59081cddd85c125160921b604082015260600190565b6020808252600d908201526c29bbb0b8103737ba1037b832b760991b604082015260600190565b6020808252600e908201526d2737ba1039bbb0b81036b0b5b2b960911b604082015260600190565b6020808252600c908201526b14ddd85c08195e1c1a5c995960a21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b600060001982141561572d5761572d614aa7565b5060010190565b60006020828403121561574657600080fd5b5051919050565b600081600019048311821515161561576757615767614aa7565b500290565b60008261578957634e487b7160e01b600052601260045260246000fd5b500490565b60008235607e198336030181126157a457600080fd5b9190910192915050565b6000808335601e198436030181126157c557600080fd5b8301803591506001600160401b038211156157df57600080fd5b6020019150600581901b36038213156134c257600080fd5b600160401b83111561580b5761580b614cc5565b805483825580841015615842576000828152602081208581019083015b8082101561583e57828255600182019150615828565b5050505b5060008181526020812083915b858110156142ce57823582556020909201916001918201910161584f565b813561587881614dfe565b60ff8116905081548160ff19821617835560208085013561589881614c67565b6001600160a81b03199290921690921760089190911b610100600160a81b0316178255600190828201906158cf60408601866157ae565b600160401b8111156158e3576158e3614cc5565b8354818555808210156159175760008581528481208381019083015b8082101561591357828255908801906158ff565b5050505b50600093845260208420935b8181101561593e578235855593850193918301918501615923565b50505050505061595160608301836157ae565b6120628183600286016157f7565b60006020828403121561597157600080fd5b813561147281614dfe565b6000610b2e368361531f565b6001600160a01b0385811682528416602082015260a0604082018190526000906159b490830185614efe565b82810360608401526159c68185614efe565b838103608090940193909352505060008152602001949350505050565b604080825283519082018190526000906020906060840190828701845b82811015615a255781516001600160a01b031684529284019290840190600101615a00565b50505083810382850152615a398186614efe565b9695505050505050565b60006020808385031215615a5657600080fd5b82516001600160401b03811115615a6c57600080fd5b8301601f81018513615a7d57600080fd5b8051615a8b61513b826150f7565b81815260059190911b82018301908381019087831115615aaa57600080fd5b928401925b8284101561491657835182529284019290840190615aaf565b600060208284031215615ada57600080fd5b815161147281614b43565b600060208284031215615af757600080fd5b815161147281614c67565b600082516157a4818460208701614c0856fe2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4a164736f6c634300080c000a000000000000000000000000cb8d1260f9c92a3a545d409466280ffdd7af70420000000000000000000000004820379a5bfff51df342ba20cc547654a4356a8f
Deployed Bytecode
0x6080604052600436106103545760003560e01c80638eca4acc116101c6578063c38509eb116100f7578063e5328e0611610095578063f23a6e611161006f578063f23a6e6114610a6a578063f2fde38b14610a96578063f31d433414610ab6578063fc0c546a14610ac957600080fd5b8063e5328e0614610a54578063eb29c7ae14610734578063ef2dbe431461073457600080fd5b8063d3c71cde116100d1578063d3c71cde146109f3578063d528cd6b14610a13578063d9eb594714610a29578063e0dd89ec14610a3f57600080fd5b8063c38509eb14610992578063cec10c11146109b2578063cf309012146109d257600080fd5b8063a85c57f511610164578063b20e27ef1161013e578063b20e27ef14610911578063b43e725314610931578063b69ef8a814610951578063bc197c811461096657600080fd5b8063a85c57f5146108d0578063aa402f7d146108e6578063af05a5c5146108fc57600080fd5b806396b90c59116101a057806396b90c591461087b578063999716581461089b578063a2aabd2a1461089b578063a4b721a6146108b057600080fd5b80638eca4acc1461080e5780639251cff41461082e57806394b918de1461084e57600080fd5b806343f0179b116102a05780636f9abf181161023e578063725d85e111610218578063725d85e1146106df57806372ba01a3146107945780637436f3dc146107b45780638da5cb5b146107dc57600080fd5b80636f9abf181461073457806370a0823114610749578063715018a61461077f57600080fd5b80635a8091121161027a5780635a809112146106df5780635dccad8a146106f45780636eb13096146106df5780636f2b2c211461071457600080fd5b806343f0179b1461068a5780634e9bf15b1461069f57806356f15878146106bf57600080fd5b8063150b7a021161030d5780632e1a7d4d116102e75780632e1a7d4d1461060957806333c12d0d1461062957806338179d0d1461063c5780633d4efe091461066a57600080fd5b8063150b7a021461058957806318574b69146105cd5780631fbe1979146105f457600080fd5b806301ffc9a7146104975780630305d723146104cc57806306fdde03146104e15780630c19eb29146105285780630dd0a042146105485780630e136b191461056857600080fd5b3661049257600054600160a81b900460ff161561038c5760405162461bcd60e51b815260040161038390614a31565b60405180910390fd5b600054600160a01b900460ff16156103b65760405162461bcd60e51b815260040161038390614a59565b6000546001600160a01b03163314156103e15760405162461bcd60e51b815260040161038390614a7d565b34806104255760405162461bcd60e51b815260206004820152601360248201527245746865722076616c7565206973207a65726f60681b6044820152606401610383565b3360008181526006602052604081208054849290610444908490614abd565b92505081905550816007600082825461045d9190614abd565b90915550506040518281526001600160a01b03821690600080516020615b158339815191529060200160405180910390a25050005b600080fd5b3480156104a357600080fd5b506104b76104b2366004614ad5565b610afd565b60405190151581526020015b60405180910390f35b6104df6104da366004614b51565b610b34565b005b3480156104ed57600080fd5b5061051b6040518060400160405280600e81526020016d09c8ca8a0e4dee8dec6ded8888ab60931b81525081565b6040516104c39190614c34565b34801561053457600080fd5b506104b7610543366004614c7c565b610dc4565b34801561055457600080fd5b506104df610563366004614ca8565b610e14565b34801561057457600080fd5b506000546104b790600160a81b900460ff1681565b34801561059557600080fd5b506105b46105a4366004614d7a565b630a85bd0160e11b949350505050565b6040516001600160e01b031990911681526020016104c3565b3480156105d957600080fd5b506105e2600381565b60405160ff90911681526020016104c3565b34801561060057600080fd5b506104df610ecd565b34801561061557600080fd5b506104df610624366004614de5565b61101a565b6104df610637366004614e0d565b611026565b34801561064857600080fd5b5061065c610657366004614de5565b6113af565b6040519081526020016104c3565b34801561067657600080fd5b506104b7610685366004614de5565b6113e4565b34801561069657600080fd5b5061065c6113f0565b3480156106ab57600080fd5b5061065c6106ba366004614e45565b611400565b3480156106cb57600080fd5b5061065c6106da366004614e99565b611479565b3480156106eb57600080fd5b506105e2600181565b34801561070057600080fd5b5061065c61070f366004614e0d565b6117d8565b34801561072057600080fd5b506104df61072f366004614de5565b6117ee565b34801561074057600080fd5b506105e2600081565b34801561075557600080fd5b5061065c610764366004614ee1565b6001600160a01b031660009081526006602052604090205490565b34801561078b57600080fd5b506104df611aa1565b3480156107a057600080fd5b506104df6107af366004614de5565b611adc565b3480156107c057600080fd5b506107c9600081565b60405161ffff90911681526020016104c3565b3480156107e857600080fd5b506000546001600160a01b03165b6040516001600160a01b0390911681526020016104c3565b34801561081a57600080fd5b506104df610829366004614c7c565b611d86565b34801561083a57600080fd5b506104df610849366004614ca8565b612068565b34801561085a57600080fd5b5061086e610869366004614de5565b61211a565b6040516104c3919061500a565b34801561088757600080fd5b506104df610896366004614de5565b61232a565b3480156108a757600080fd5b506105e2600281565b3480156108bc57600080fd5b506104df6108cb366004614c7c565b612330565b3480156108dc57600080fd5b5061065c60035481565b3480156108f257600080fd5b5061065c60055481565b34801561090857600080fd5b506107c9600381565b34801561091d57600080fd5b5061065c61092c3660046150b6565b6124b0565b34801561093d57600080fd5b5061065c61094c366004614ee1565b6124bd565b34801561095d57600080fd5b5061065c6125f9565b34801561097257600080fd5b506105b4610981366004615185565b63bc197c8160e01b95945050505050565b34801561099e57600080fd5b506104df6109ad366004614de5565b612604565b3480156109be57600080fd5b506104df6109cd366004615232565b61260e565b3480156109de57600080fd5b506000546104b790600160a01b900460ff1681565b3480156109ff57600080fd5b5061065c610a0e366004614c7c565b6126e5565b348015610a1f57600080fd5b5061065c60045481565b348015610a3557600080fd5b5061065c60025481565b348015610a4b57600080fd5b506104df61272a565b348015610a6057600080fd5b5061065c60075481565b348015610a7657600080fd5b506105b4610a8536600461525e565b63f23a6e6160e01b95945050505050565b348015610aa257600080fd5b506104df610ab1366004614ee1565b612745565b6104df610ac43660046152c6565b6127bb565b348015610ad557600080fd5b506107f67f000000000000000000000000cb8d1260f9c92a3a545d409466280ffdd7af704281565b60006001600160e01b03198216630271189760e51b1480610b2e57506301ffc9a760e01b6001600160e01b03198316145b92915050565b600054600160a81b900460ff1615610b5e5760405162461bcd60e51b815260040161038390614a31565b600054600160a01b900460ff1615610b885760405162461bcd60e51b815260040161038390614a59565b6000546001600160a01b0316331415610bb35760405162461bcd60e51b815260040161038390614a7d565b60026001541415610bd65760405162461bcd60e51b8152600401610383906152e8565b600260015586610c1d5760405162461bcd60e51b81526020600482015260126024820152714d616b65207369646520697320656d70747960701b6044820152606401610383565b84610c5f5760405162461bcd60e51b815260206004820152601260248201527154616b65207369646520697320656d70747960701b6044820152606401610383565b610c6883612b85565b610ca95760405162461bcd60e51b815260206004820152601260248201527124b73b30b634b21032bc3834b930ba34b7b760711b6044820152606401610383565b33600080610cc383610cbb8c8e6153d3565b346000612b95565b9092509050610cda610cd5898b6153d3565b612c2c565b5081341015610cfb5760405162461bcd60e51b815260040161038390615446565b610d0b8b8b8b8b8b8b8b8b612d03565b3460076000828254610d1d9190614abd565b90915550610d2e90508b8b89612f00565b610d3a81600554612fdd565b600160056000828254610d4d9190614abd565b92505081905550861515836001600160a01b03166001600554610d70919061547d565b7f576c6928b032607301c93952b75a4f7057cc22a7113d7a7434fe50bdfa65c0aa8e8e8e8e8d8d8d604051610dab97969594939291906155e6565b60405180910390a4505060018055505050505050505050565b6000816005548110610de85760405162461bcd60e51b815260040161038390615666565b505060009081526009602090815260408083206001600160a01b03949094168352929052205460ff1690565b610e1c613088565b600060149054906101000a900460ff1615158115151415610e715760405162461bcd60e51b815260206004820152600f60248201526e14dd185d19481d5b98da185b99d959608a1b6044820152606401610383565b6000805460ff60a01b1916600160a01b8315158102919091179182905560405160ff9190920416151581527fe3f0ec9c4af57e69d5aeff78a5912ca25733e4458710bab2b55d0985e98aeb5e906020015b60405180910390a150565b610ed5613088565b60026001541415610ef85760405162461bcd60e51b8152600401610383906152e8565b600260015533600081815260066020526040812054600754909190610f1d904761547d565b9050818111610f635760405162461bcd60e51b81526020600482015260126024820152714e6f2076616c756520746f2072657363756560701b6044820152606401610383565b6000610f6f838361547d565b6001600160a01b038516600090815260066020526040812080549293508392909190610f9c908490614abd565b90915550506040518181526001600160a01b03851690600080516020615b158339815191529060200160405180910390a2836001600160a01b03167f8aec0ce3dadffacf4b7a963e0fed1ff2e6151b4c95d4a65acafa9d12996304028260405161100891815260200190565b60405180910390a25050600180555050565b611023816130e2565b50565b600054600160a01b900460ff16156110505760405162461bcd60e51b815260040161038390614a59565b6000546001600160a01b031633141561107b5760405162461bcd60e51b815260040161038390614a7d565b6002600154141561109e5760405162461bcd60e51b8152600401610383906152e8565b60026001558160ff811615806110b7575060ff81166001145b6110f25760405162461bcd60e51b815260206004820152600c60248201526b496e76616c6964207369646560a01b6044820152606401610383565b8360055481106111145760405162461bcd60e51b815260040161038390615666565b6000858152600860205260409020600181015460ff16156111475760405162461bcd60e51b81526004016103839061568e565b600481015433906001600160a01b031681146111755760405162461bcd60e51b8152600401610383906156b5565b6111828260060154612b85565b61119e5760405162461bcd60e51b8152600401610383906156dd565b6000826002018760ff16600281106111b8576111b8615703565b0190506000806111c883896132d9565b91509150818814156112145760405162461bcd60e51b8152602060048201526015602482015274115d1a195c881d985b1d59481d5b98da185b99d959605a1b6044820152606401610383565b6000881180611224575082546001105b61126a5760405162461bcd60e51b8152602060048201526017602482015276537761702073696465206265636f6d657320656d70747960481b6044820152606401610383565b6001600160a01b03841660009081526006602052604090205460ff8a1660011480156112965750600034115b156112b3576112ae6112a83483614abd565b8c612fdd565b611318565b60ff8a1661131857828911156112f5576112cd838a61547d565b6112d73483614abd565b10156112f55760405162461bcd60e51b815260040161038390615446565b61131889846113043485614abd565b61130e9190614abd565b6112a8919061547d565b346007600082825461132a9190614abd565b9250508190555060018660070160008282546113469190614abd565b9091555050600786015460408051918252602082018490528101849052606081018a905260ff8b16908c907f5d7324c5c976f20efe1908630c8d665420079e838769ac3657dffa3e8ba050f49060800160405180910390a3505060018055505050505050505050565b60008054600160a01b900460ff16156113da5760405162461bcd60e51b815260040161038390614a59565b610b2e33836126e5565b6000610b2e3383610dc4565b60006113fb336124bd565b905090565b60008054600160a81b900460ff161561142b5760405162461bcd60e51b815260040161038390614a31565b600054600160a01b900460ff16156114555760405162461bcd60e51b815260040161038390614a59565b600061146d8561146585876153d3565b600080612b95565b509150505b9392505050565b60008054600160a01b900460ff16156114a45760405162461bcd60e51b815260040161038390614a59565b8260ff811615806114b8575060ff81166001145b6114f35760405162461bcd60e51b815260206004820152600c60248201526b496e76616c6964207369646560a01b6044820152606401610383565b6000858152600860205260409020600181015460ff16156115265760405162461bcd60e51b81526004016103839061568e565b60048101546001600160a01b038881169116146115555760405162461bcd60e51b8152600401610383906156b5565b6115628160060154612b85565b61157e5760405162461bcd60e51b8152600401610383906156dd565b6000816002018660ff166002811061159857611598615703565b01905060006116c482805480602002602001604051908101604052809291908181526020016000905b828210156116bb5760008481526020908190206040805160808101825260038602909201805460ff8116845261010090046001600160a01b031683850152600181018054835181870281018701855281815294959294938601939283018282801561164b57602002820191906000526020600020905b815481526020019060010190808311611637575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156116a357602002820191906000526020600020905b81548152602001906001019080831161168f575b505050505081525050815260200190600101906115c1565b505050506134c9565b90508086141561170e5760405162461bcd60e51b8152602060048201526015602482015274115d1a195c881d985b1d59481d5b98da185b99d959605a1b6044820152606401610383565b600086118061171e575081546001105b6117645760405162461bcd60e51b8152602060048201526017602482015276537761702073696465206265636f6d657320656d70747960481b6044820152606401610383565b6001600160a01b03891660009081526006602052604090205460ff881615801561178d57508187115b80156117a1575061179e828861547d565b81105b156117c657806117b1838961547d565b6117bb919061547d565b9550505050506117cf565b60009550505050505b50949350505050565b60006117e633858585611479565b949350505050565b600054600160a01b900460ff16156118185760405162461bcd60e51b815260040161038390614a59565b80600554811061183a5760405162461bcd60e51b815260040161038390615666565b600082815260086020908152604080832081516101208101835281548152600182015460ff169381019390935281518083018352909183019060028084019086835b828210156119b457838201805480602002602001604051908101604052809291908181526020016000905b828210156119a15760008481526020908190206040805160808101825260038602909201805460ff8116845261010090046001600160a01b031683850152600181018054835181870281018701855281815294959294938601939283018282801561193157602002820191906000526020600020905b81548152602001906001019080831161191d575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561198957602002820191906000526020600020905b815481526020019060010190808311611975575b505050505081525050815260200190600101906118a7565b505050508152602001906001019061187c565b5050509082525060048201546001600160a01b039081166020808401919091526005840154918216604084015260ff600160a01b8304811615156060850152600160a81b909204821615156080840152600684015460a084015260079093015460c090920191909152908201519192501615611a425760405162461bcd60e51b81526004016103839061568e565b8060c0015115611a855760405162461bcd60e51b815260206004820152600e60248201526d14ddd85c0818dd5cdd1bd91a585b60921b6044820152606401610383565b6040810151516060820151611a9c9190600061355d565b505050565b611aa9613088565b60405162461bcd60e51b8152602060048201526008602482015267111a5cd8589b195960c21b6044820152606401610383565b600054600160a01b900460ff1615611b065760405162461bcd60e51b815260040161038390614a59565b6000546001600160a01b0316331415611b315760405162461bcd60e51b815260040161038390614a7d565b60026001541415611b545760405162461bcd60e51b8152600401610383906152e8565b6002600190815560008281526008602052604090209081015460ff1615611b8d5760405162461bcd60e51b81526004016103839061568e565b60048101546001600160a01b0316336001600160a01b031614611bc25760405162461bcd60e51b8152600401610383906156b5565b60018101805460ff1916600217905560005b6002820154811015611d52576005820154600160a81b900460ff1680611c2557506003600283016000018281548110611c0f57611c0f615703565b600091825260209091206003909102015460ff16145b15611d4057611d40600283016000018281548110611c4557611c45615703565b6000918252602091829020604080516080810182526003909302909101805460ff811684526001600160a01b0361010090910416838501526001810180548351818702810187018552818152949592949386019392830182828015611cc957602002820191906000526020600020905b815481526020019060010190808311611cb5575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015611d2157602002820191906000526020600020905b815481526020019060010190808311611d0d575b50505091909252505050600484015430906001600160a01b03166135d5565b80611d4a81615719565b915050611bd4565b5060405182907f0fd96601866cb818103091fe53228f73be296da894da73b40c0185fde3e4d0c690600090a2505060018055565b600054600160a01b900460ff1615611db05760405162461bcd60e51b815260040161038390614a59565b806005548110611dd25760405162461bcd60e51b815260040161038390615666565b6000611de0848460006137b5565b50505060038101805460408051602080840282018101909252828152939450611f129392919060009084015b82821015611f065760008481526020908190206040805160808101825260038602909201805460ff8116845261010090046001600160a01b0316838501526001810180548351818702810187018552818152949592949386019392830182828015611e9657602002820191906000526020600020905b815481526020019060010190808311611e82575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015611eee57602002820191906000526020600020905b815481526020019060010190808311611eda575b50505050508152505081526020019060010190611e0c565b5050505085600161355d565b6005810154600160a81b900460ff166120625761206260028201600001805480602002602001604051908101604052809291908181526020016000905b828210156120495760008481526020908190206040805160808101825260038602909201805460ff8116845261010090046001600160a01b0316838501526001810180548351818702810187018552818152949592949386019392830182828015611fd957602002820191906000526020600020905b815481526020019060010190808311611fc5575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561203157602002820191906000526020600020905b81548152602001906001019080831161201d575b50505050508152505081526020019060010190611f4f565b5050505060048301546001600160a01b0316600061355d565b50505050565b612070613088565b600060159054906101000a900460ff16151581151514156120c55760405162461bcd60e51b815260206004820152600f60248201526e14dd185d19481d5b98da185b99d959608a1b6044820152606401610383565b6000805460ff60a81b1916600160a81b8315158102919091179182905560405160ff9190920416151581527f92a709fe0704b42849ae468c6c839690d63164022fbd0d6b49502f95bc6424ff90602001610ec2565b61212261495a565b8160055481106121445760405162461bcd60e51b815260040161038390615666565b600083815260086020908152604080832081516101208101835281548152600182015460ff169381019390935281518083018352929390929184019190600280850191835b828210156122c157838201805480602002602001604051908101604052809291908181526020016000905b828210156122ae5760008481526020908190206040805160808101825260038602909201805460ff8116845261010090046001600160a01b031683850152600181018054835181870281018701855281815294959294938601939283018282801561223e57602002820191906000526020600020905b81548152602001906001019080831161222a575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561229657602002820191906000526020600020905b815481526020019060010190808311612282575b505050505081525050815260200190600101906121b4565b5050505081526020019060010190612189565b5050509082525060048201546001600160a01b0390811660208301526005830154908116604083015260ff600160a01b8204811615156060840152600160a81b9091041615156080820152600682015460a082015260079091015460c090910152915050919050565b61102333825b600054600160a01b900460ff161561235a5760405162461bcd60e51b815260040161038390614a59565b80600554811061237c5760405162461bcd60e51b815260040161038390615666565b600061238a848460006137b5565b505050600381018054604080516020808402820181019092528281529394506120629392919060009084015b82821015611f065760008481526020908190206040805160808101825260038602909201805460ff8116845261010090046001600160a01b031683850152600181018054835181870281018701855281815294959294938601939283018282801561244057602002820191906000526020600020905b81548152602001906001019080831161242c575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561249857602002820191906000526020600020905b815481526020019060010190808311612484575b505050505081525050815260200190600101906123b6565b6000611472338484611400565b60008054600160a01b900460ff16156124e85760405162461bcd60e51b815260040161038390614a59565b6040516370a0823160e01b81526001600160a01b0383811660048301526000917f000000000000000000000000cb8d1260f9c92a3a545d409466280ffdd7af7042909116906370a0823190602401602060405180830381865afa158015612553573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125779190615734565b9050600454811061258b5750600092915050565b60035481101561259f575050600254919050565b6000600a60025460096125b2919061574d565b6125bc919061576c565b90506003546004546125ce919061547d565b6003546125db908461547d565b6125e5908361574d565b6125ef919061576c565b6117e6908261547d565b60006113fb33610764565b6110233382611d86565b600054600160a81b900460ff16156126385760405162461bcd60e51b815260040161038390614a31565b612640613088565b808211156126905760405162461bcd60e51b815260206004820152601960248201527f6c6f77466565206d757374206265203c3d2068696768466565000000000000006044820152606401610383565b60028390556003829055600481905560408051848152602081018490529081018290527fe06a46af1c04656f68e4f75cbbb23baa176651c7f99930a378ef9f1616dc2b8c9060600160405180910390a1505050565b60008054600160a01b900460ff16156127105760405162461bcd60e51b815260040161038390614a59565b600061271e848460006137b5565b50909695505050505050565b33600090815260066020526040902054612743906130e2565b565b61274d613088565b6001600160a01b0381166127b25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610383565b61102381613a62565b600054600160a01b900460ff16156127e55760405162461bcd60e51b815260040161038390614a59565b6000546001600160a01b03163314156128105760405162461bcd60e51b815260040161038390614a7d565b600260015414156128335760405162461bcd60e51b8152600401610383906152e8565b60026001553360008080806128498588346137b5565b9350935093509350858460070154146128935760405162461bcd60e51b815260206004820152600c60248201526b57726f6e67207365714e756d60a01b6044820152606401610383565b823410156128f25760405162461bcd60e51b815260206004820152602660248201527f496e73756666696369656e742045746865722076616c756520287072696365206044820152652b206665652960d01b6064820152608401610383565b6001848101805460ff191690911790556005840180546001600160a01b0319166001600160a01b0387161790556129298288612fdd565b600484015460058501546129579160028701916001600160a01b0390911690600160a81b900460ff16613ab2565b60005b6003850154811015612a8e57612a7c60028601600101828154811061298157612981615703565b6000918252602091829020604080516080810182526003909302909101805460ff811684526001600160a01b0361010090910416838501526001810180548351818702810187018552818152949592949386019392830182828015612a0557602002820191906000526020600020905b8154815260200190600101908083116129f1575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015612a5d57602002820191906000526020600020905b815481526020019060010190808311612a49575b50505091909252505050600487015488906001600160a01b03166135d5565b80612a8681615719565b91505061295a565b50600080546001600160a01b0316808252600660205260408220805491928492612ab9908490614abd565b925050819055503460076000828254612ad29190614abd565b925050819055508160076000828254612aeb919061547d565b9091555050600785015460408051918252602082018490526001600160a01b038816918a917f07e2fe203bcde02eeeacd77c107f07b910c790f014f45fb11a8e745456647f16910160405180910390a36000546001600160a01b03166001600160a01b0316600080516020615b1583398151915283604051612b6f91815260200190565b60405180910390a2505060018055505050505050565b6000811580610b2e575050431090565b6000806000612ba386612c2c565b6001600160a01b038816600090815260066020526040902054909150612bc98583614abd565b612bd38783614abd565b10612c055760008583612be68985614abd565b612bf0919061547d565b612bfa919061547d565b935093505050612c23565b80612c108684614abd565b612c1a919061547d565b60009350935050505b94509492505050565b60008080805b8451811015612cfa57600360ff16858281518110612c5257612c52615703565b60200260200101516000015160ff161415612cba578115612cb55760405162461bcd60e51b815260206004820152601960248201527f4d756c7469706c6520657468657220636f6d706f6e656e7473000000000000006044820152606401610383565b600191505b612cdc858281518110612ccf57612ccf615703565b6020026020010151613d11565b612ce69084614abd565b925080612cf281615719565b915050612c32565b50909392505050565b600580546000818152600860205260408082209283559183018054881515600160a81b0260ff60a81b199091161790558254815281812060060186905591548252812060040180546001600160a01b031916331790555b87811015612dd1576005546000908152600860205260409020600201898983818110612d8857612d88615703565b9050602002810190612d9a919061578e565b815460018101835560009283526020909220909160030201612dbc828261586d565b50508080612dc990615719565b915050612d5a565b5060005b85811015612e4c576005546000908152600860205260409020600301878783818110612e0357612e03615703565b9050602002810190612e15919061578e565b815460018101835560009283526020909220909160030201612e37828261586d565b50508080612e4490615719565b915050612dd5565b50600580546000908152600860205260408120909101805460ff60a01b1916831515600160a01b021790555b81811015612ef5576005546000908152600960205260408120600191858585818110612ea657612ea6615703565b9050602002016020810190612ebb9190614ee1565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905580612eed81615719565b915050612e78565b505050505050505050565b3360005b83811015612fd6578280612f4c57506003858583818110612f2757612f27615703565b9050602002810190612f39919061578e565b612f4790602081019061595f565b60ff16145b15612f8d57612f88858583818110612f6657612f66615703565b9050602002810190612f78919061578e565b612f819061597c565b83306135d5565b612fc4565b612fc4858583818110612fa257612fa2615703565b9050602002810190612fb4919061578e565b612fbd9061597c565b8334613f0c565b80612fce81615719565b915050612f04565b5050505050565b33600081815260066020526040902080549084905580841115613033576001600160a01b038216600080516020615b1583398151915261301d838761547d565b60405190815260200160405180910390a2612062565b8084101561206257826001600160a01b0383167f535148561d77998b1c55b0df8e3a745c169a3c2d06073ca7cf45743224cef85d613071878561547d565b60405190815260200160405180910390a350505050565b6000546001600160a01b031633146127435760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610383565b600260015414156131055760405162461bcd60e51b8152600401610383906152e8565b60026001558061314d5760405162461bcd60e51b815260206004820152601360248201527245746865722076616c7565206973207a65726f60681b6044820152606401610383565b33600081815260066020526040902054808311156131ad5760405162461bcd60e51b815260206004820152601b60248201527f45746865722076616c756520657863656564732062616c616e636500000000006044820152606401610383565b6001600160a01b038216600090815260066020526040812080548592906131d590849061547d565b90915550506000546001600160a01b03838116911614613207578260076000828254613201919061547d565b90915550505b6000826001600160a01b03168460405160006040518083038185875af1925050503d8060008114613254576040519150601f19603f3d011682016040523d82523d6000602084013e613259565b606091505b505090508061329e5760405162461bcd60e51b815260206004820152601160248201527015da5d1a191c985dd85b0819985a5b1959607a1b6044820152606401610383565b826001600160a01b03167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d58560405161100891815260200190565b60008060005b84548110156133ba57600360ff168582815481106132ff576132ff615703565b600091825260209091206003909102015460ff1614156133a857600085828154811061332d5761332d615703565b906000526020600020906003020160020160008154811061335057613350615703565b906000526020600020015490508486838154811061337057613370615703565b906000526020600020906003020160020160008154811061339357613393615703565b600091825260209091200155925090506134c2565b806133b281615719565b9150506132df565b506040805160808101825260038152600060208083018290528351828152808201855283850152835160018082528186019095529193606084019291828101908036833701905050815250905083816060015160008151811061341f5761341f615703565b602090810291909101810191909152855460018181018855600088815283902084516003909302018054858501516001600160a01b0316610100026001600160a81b031990911660ff9094169390931792909217825560408401518051859461348c9385019201906149aa565b50606082015180516134a89160028401916020909101906149aa565b50508554600091506134bc9060019061547d565b92509250505b9250929050565b6000805b825181101561355457600360ff168382815181106134ed576134ed615703565b60200260200101516000015160ff1614156135425782818151811061351457613514615703565b60200260200101516060015160008151811061353257613532615703565b6020026020010151915050919050565b8061354c81615719565b9150506134cd565b50600092915050565b60005b83518110156120625781806135995750600360ff1684828151811061358757613587615703565b60200260200101516000015160ff1614155b156135c3576135c38482815181106135b3576135b3615703565b6020026020010151846000613f0c565b806135cd81615719565b915050613560565b825160ff1661365457602083015160408085015160608601519151631759616b60e11b81526001600160a01b03841692632eb2c2d69261361c928892889291600401615988565b600060405180830381600087803b15801561363657600080fd5b505af115801561364a573d6000803e3d6000fd5b5050505050505050565b825160ff16600114156136d757600083602001519050806001600160a01b03166342842e0e8484876040015160008151811061369257613692615703565b60209081029190910101516040516001600160e01b031960e086901b1681526001600160a01b039384166004820152929091166024830152604482015260640161361c565b825160ff1660021415613758576000836020015190506000846060015160008151811061370657613706615703565b60200260200101519050306001600160a01b0316846001600160a01b031614156137435761373e6001600160a01b0383168483613f58565b612fd6565b612fd66001600160a01b038316858584613fbb565b826060015160008151811061376f5761376f615703565b602002602001015160066000836001600160a01b03166001600160a01b0316815260200190815260200160002060008282546137ab9190614abd565b9091555050505050565b6000806000808560055481106137dd5760405162461bcd60e51b815260040161038390615666565b6000878152600860205260409020600181015460ff16156138105760405162461bcd60e51b81526004016103839061568e565b60048101546001600160a01b038a8116911614156138675760405162461bcd60e51b815260206004820152601460248201527329b2b73232b91034b99039bbb0b81036b0b5b2b960611b6044820152606401610383565b6005810154600160a01b900460ff1615806138a4575060008881526009602090815260408083206001600160a01b038d16845290915290205460ff165b6138e35760405162461bcd60e51b815260206004820152601060248201526f139bdd081a5b881dda1a5d195b1a5cdd60821b6044820152606401610383565b6138f08160060154612b85565b61390c5760405162461bcd60e51b8152600401610383906156dd565b60006139178a6124bd565b9050600080613a4c8c60028601600101805480602002602001604051908101604052809291908181526020016000905b82821015613a415760008481526020908190206040805160808101825260038602909201805460ff8116845261010090046001600160a01b03168385015260018101805483518187028101870185528181529495929493860193928301828280156139d157602002820191906000526020600020905b8154815260200190600101908083116139bd575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015613a2957602002820191906000526020600020905b815481526020019060010190808311613a15575b50505050508152505081526020019060010190613947565b505050508c86612b95565b949d909c50939a50919850919650505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b3360005b8454811015612fd6578280613af35750600360ff16858281548110613add57613add615703565b600091825260209091206003909102015460ff16145b15613bfe57613bf9858281548110613b0d57613b0d615703565b6000918252602091829020604080516080810182526003909302909101805460ff811684526001600160a01b0361010090910416838501526001810180548351818702810187018552818152949592949386019392830182828015613b9157602002820191906000526020600020905b815481526020019060010190808311613b7d575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015613be957602002820191906000526020600020905b815481526020019060010190808311613bd5575b50505050508152505030846135d5565b613cff565b613cff858281548110613c1357613c13615703565b6000918252602091829020604080516080810182526003909302909101805460ff811684526001600160a01b0361010090910416838501526001810180548351818702810187018552818152949592949386019392830182828015613c9757602002820191906000526020600020905b815481526020019060010190808311613c83575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015613cef57602002820191906000526020600020905b815481526020019060010190808311613cdb575b50505050508152505085846135d5565b80613d0981615719565b915050613ab6565b805160009060ff16613d7b5781606001515182604001515114613d765760405162461bcd60e51b815260206004820152601f60248201527f546f6b656e49447320616e6420616d6f756e7473206c656e20646966666572006044820152606401610383565b613f04565b815160ff1660011415613ddd57816040015151600114613d765760405162461bcd60e51b815260206004820152601f60248201527f546f6b656e494473206172726179206c656e677468206d7573742062652031006044820152606401610383565b815160ff1660021415613e3f57816060015151600114613d765760405162461bcd60e51b815260206004820152601e60248201527f416d6f756e7473206172726179206c656e677468206d757374206265203100006044820152606401610383565b815160ff1660031415613ec757816060015151600114613ea15760405162461bcd60e51b815260206004820152601e60248201527f416d6f756e7473206172726179206c656e677468206d757374206265203100006044820152606401610383565b8160600151600081518110613eb857613eb8615703565b60200260200101519050919050565b60405162461bcd60e51b8152602060048201526012602482015271496e76616c6964206173736574207479706560701b6044820152606401610383565b506000919050565b825160ff16613f1f57611a9c8383613ff3565b825160ff1660011415613f3657611a9c83836142d6565b825160ff1660021415613f4d57611a9c8383614536565b611a9c8383836146fd565b6040516001600160a01b038316602482015260448101829052611a9c90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614774565b6040516001600160a01b03808516602483015283166044820152606481018290526120629085906323b872dd60e01b90608401613f84565b60208201516040830151516000906001600160401b0381111561401857614018614cc5565b604051908082528060200260200182016040528015614041578160200160208202803683370190505b50905060005b846040015151811015614091578382828151811061406757614067615703565b6001600160a01b03909216602092830291909101909101528061408981615719565b915050614047565b506000826001600160a01b0316634e1273f48387604001516040518363ffffffff1660e01b81526004016140c69291906159e3565b600060405180830381865afa1580156140e3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261410b9190810190615a43565b90508460400151518151146141625760405162461bcd60e51b815260206004820152601b60248201527f496e76616c69642062616c616e63654f6642617463682063616c6c00000000006044820152606401610383565b60005b85604001515181101561420a578560600151818151811061418857614188615703565b60200260200101518282815181106141a2576141a2615703565b602002602001015110156141f85760405162461bcd60e51b815260206004820152601c60248201527f496e73756666696369656e7420455243313135352062616c616e6365000000006044820152606401610383565b8061420281615719565b915050614165565b5060405163e985e9c560e01b81526001600160a01b0385811660048301523060248301526000919085169063e985e9c590604401602060405180830381865afa15801561425b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061427f9190615ac8565b9050806142ce5760405162461bcd60e51b815260206004820152601860248201527f444558206e6f74204552433131353520617070726f76656400000000000000006044820152606401610383565b505050505050565b6000826020015190506000816001600160a01b0316636352211e856040015160008151811061430757614307615703565b60200260200101516040518263ffffffff1660e01b815260040161432d91815260200190565b602060405180830381865afa15801561434a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061436e9190615ae5565b9050826001600160a01b0316816001600160a01b0316146143ca5760405162461bcd60e51b81526020600482015260166024820152752737ba1022a9219b9918903a37b5b2b71037bbb732b960511b6044820152606401610383565b60405163e985e9c560e01b81526001600160a01b0384811660048301523060248301526000919084169063e985e9c590604401602060405180830381865afa15801561441a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061443e9190615ac8565b9050806144e957826001600160a01b031663081812fc866040015160008151811061446b5761446b615703565b60200260200101516040518263ffffffff1660e01b815260040161449191815260200190565b602060405180830381865afa1580156144ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144d29190615ae5565b6001600160a01b0316306001600160a01b03161490505b80612fd65760405162461bcd60e51b815260206004820152601760248201527f444558206e6f742045524337323120617070726f7665640000000000000000006044820152606401610383565b60208201516040516370a0823160e01b81526001600160a01b038381166004830152600091908316906370a0823190602401602060405180830381865afa158015614585573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145a99190615734565b905083606001516000815181106145c2576145c2615703565b60200260200101518110156146195760405162461bcd60e51b815260206004820152601a60248201527f496e73756666696369656e742045524332302062616c616e63650000000000006044820152606401610383565b604051636eb1769f60e11b81526001600160a01b0384811660048301523060248301526000919084169063dd62ed3e90604401602060405180830381865afa158015614669573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061468d9190615734565b905084606001516000815181106146a6576146a6615703565b6020026020010151811015612fd65760405162461bcd60e51b815260206004820152601c60248201527f496e73756666696369656e7420455243323020616c6c6f77616e6365000000006044820152606401610383565b6001600160a01b038216600090815260066020526040812054606085015180519192909161472d5761472d615703565b60200260200101518282856001600160a01b03163161474c9190614abd565b6147569190614abd565b10156120625760405162461bcd60e51b815260040161038390615446565b60006147c9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166148469092919063ffffffff16565b805190915015611a9c57808060200190518101906147e79190615ac8565b611a9c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610383565b60606117e68484600085856001600160a01b0385163b6148a85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610383565b600080866001600160a01b031685876040516148c49190615b02565b60006040518083038185875af1925050503d8060008114614901576040519150601f19603f3d011682016040523d82523d6000602084013e614906565b606091505b5091509150614916828286614921565b979650505050505050565b60608315614930575081611472565b8251156149405782518084602001fd5b8160405162461bcd60e51b81526004016103839190614c34565b60408051610120810182526000808252602082015290810161497a6149f5565b815260006020820181905260408201819052606082018190526080820181905260a0820181905260c09091015290565b8280548282559060005260206000209081019282156149e5579160200282015b828111156149e55782518255916020019190600101906149ca565b506149f1929150614a1c565b5090565b60405180604001604052806002905b6060815260200190600190039081614a045790505090565b5b808211156149f15760008155600101614a1d565b6020808252600e908201526d1111560819195c1c9958d85d195960921b604082015260600190565b6020808252600a9082015269111156081b1bd8dad95960b21b604082015260600190565b60208082526010908201526f13dddb995c881c1c9bda1a589a5d195960821b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60008219821115614ad057614ad0614aa7565b500190565b600060208284031215614ae757600080fd5b81356001600160e01b03198116811461147257600080fd5b60008083601f840112614b1157600080fd5b5081356001600160401b03811115614b2857600080fd5b6020830191508360208260051b85010111156134c257600080fd5b801515811461102357600080fd5b60008060008060008060008060a0898b031215614b6d57600080fd5b88356001600160401b0380821115614b8457600080fd5b614b908c838d01614aff565b909a50985060208b0135915080821115614ba957600080fd5b614bb58c838d01614aff565b909850965060408b01359150614bca82614b43565b90945060608a0135935060808a01359080821115614be757600080fd5b50614bf48b828c01614aff565b999c989b5096995094979396929594505050565b60005b83811015614c23578181015183820152602001614c0b565b838111156120625750506000910152565b6020815260008251806020840152614c53816040850160208701614c08565b601f01601f19169190910160400192915050565b6001600160a01b038116811461102357600080fd5b60008060408385031215614c8f57600080fd5b8235614c9a81614c67565b946020939093013593505050565b600060208284031215614cba57600080fd5b813561147281614b43565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715614d0357614d03614cc5565b604052919050565b600082601f830112614d1c57600080fd5b81356001600160401b03811115614d3557614d35614cc5565b614d48601f8201601f1916602001614cdb565b818152846020838601011115614d5d57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215614d9057600080fd5b8435614d9b81614c67565b93506020850135614dab81614c67565b92506040850135915060608501356001600160401b03811115614dcd57600080fd5b614dd987828801614d0b565b91505092959194509250565b600060208284031215614df757600080fd5b5035919050565b60ff8116811461102357600080fd5b600080600060608486031215614e2257600080fd5b833592506020840135614e3481614dfe565b929592945050506040919091013590565b600080600060408486031215614e5a57600080fd5b8335614e6581614c67565b925060208401356001600160401b03811115614e8057600080fd5b614e8c86828701614aff565b9497909650939450505050565b60008060008060808587031215614eaf57600080fd5b8435614eba81614c67565b9350602085013592506040850135614ed181614dfe565b9396929550929360600135925050565b600060208284031215614ef357600080fd5b813561147281614c67565b600081518084526020808501945080840160005b83811015614f2e57815187529582019590820190600101614f12565b509495945050505050565b6000826040808201846000805b6002811015614ffd578584038952825180518086526020918201918087019190600582901b88018101865b83811015614fe657898203601f190185528551805160ff168352838101516001600160a01b0316848401528b81015160808d850181905290614fb582860182614efe565b91505060608083015192508482038186015250614fd28183614efe565b978501979685019693505050600101614f71565b509c81019c97509590950194505050600101614f46565b5091979650505050505050565b60208152815160208201526000602083015161502b604084018260ff169052565b506040830151610120806060850152615048610140850183614f39565b9150606085015161506460808601826001600160a01b03169052565b5060808501516001600160a01b03811660a08601525060a085015180151560c08601525060c085015180151560e08601525060e085015161010085810191909152909401519390920192909252919050565b600080602083850312156150c957600080fd5b82356001600160401b038111156150df57600080fd5b6150eb85828601614aff565b90969095509350505050565b60006001600160401b0382111561511057615110614cc5565b5060051b60200190565b600082601f83011261512b57600080fd5b8135602061514061513b836150f7565b614cdb565b82815260059290921b8401810191818101908684111561515f57600080fd5b8286015b8481101561517a5780358352918301918301615163565b509695505050505050565b600080600080600060a0868803121561519d57600080fd5b85356151a881614c67565b945060208601356151b881614c67565b935060408601356001600160401b03808211156151d457600080fd5b6151e089838a0161511a565b945060608801359150808211156151f657600080fd5b61520289838a0161511a565b9350608088013591508082111561521857600080fd5b5061522588828901614d0b565b9150509295509295909350565b60008060006060848603121561524757600080fd5b505081359360208301359350604090920135919050565b600080600080600060a0868803121561527657600080fd5b853561528181614c67565b9450602086013561529181614c67565b9350604086013592506060860135915060808601356001600160401b038111156152ba57600080fd5b61522588828901614d0b565b600080604083850312156152d957600080fd5b50508035926020909101359150565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60006080828403121561533157600080fd5b604051608081016001600160401b03828210818311171561535457615354614cc5565b816040528293508435915061536882614dfe565b90825260208401359061537a82614c67565b816020840152604085013591508082111561539457600080fd5b6153a08683870161511a565b604084015260608501359150808211156153b957600080fd5b506153c68582860161511a565b6060830152505092915050565b60006153e161513b846150f7565b80848252602080830192508560051b8501368111156153ff57600080fd5b855b8181101561543a5780356001600160401b038111156154205760008081fd5b61542c36828a0161531f565b865250938201938201615401565b50919695505050505050565b60208082526018908201527f496e73756666696369656e742045746865722076616c75650000000000000000604082015260600190565b60008282101561548f5761548f614aa7565b500390565b6000808335601e198436030181126154ab57600080fd5b83016020810192503590506001600160401b038111156154ca57600080fd5b8060051b36038313156134c257600080fd5b81835260006001600160fb1b038311156154f557600080fd5b8260051b8083602087013760009401602001938452509192915050565b81835260006020808501808196508560051b81019150846000805b888110156155d8578385038a528235607e1989360301811261554d578283fd5b88016080813561555c81614dfe565b60ff1687528188013561556e81614c67565b6001600160a01b031687890152604061558983820184615494565b83838b015261559b848b0182846154dc565b935050505060606155ae81840184615494565b9350888303828a01526155c28385836154dc565b9d8a019d9850505093870193505060010161552d565b509298975050505050505050565b6080815260006155fa60808301898b615512565b60208382038185015261560e82898b615512565b604085018890528481036060860152858152869250810160005b8681101561565657833561563b81614c67565b6001600160a01b031682529282019290820190600101615628565b509b9a5050505050505050505050565b6020808252600e908201526d125b9d985b1a59081cddd85c125160921b604082015260600190565b6020808252600d908201526c29bbb0b8103737ba1037b832b760991b604082015260600190565b6020808252600e908201526d2737ba1039bbb0b81036b0b5b2b960911b604082015260600190565b6020808252600c908201526b14ddd85c08195e1c1a5c995960a21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b600060001982141561572d5761572d614aa7565b5060010190565b60006020828403121561574657600080fd5b5051919050565b600081600019048311821515161561576757615767614aa7565b500290565b60008261578957634e487b7160e01b600052601260045260246000fd5b500490565b60008235607e198336030181126157a457600080fd5b9190910192915050565b6000808335601e198436030181126157c557600080fd5b8301803591506001600160401b038211156157df57600080fd5b6020019150600581901b36038213156134c257600080fd5b600160401b83111561580b5761580b614cc5565b805483825580841015615842576000828152602081208581019083015b8082101561583e57828255600182019150615828565b5050505b5060008181526020812083915b858110156142ce57823582556020909201916001918201910161584f565b813561587881614dfe565b60ff8116905081548160ff19821617835560208085013561589881614c67565b6001600160a81b03199290921690921760089190911b610100600160a81b0316178255600190828201906158cf60408601866157ae565b600160401b8111156158e3576158e3614cc5565b8354818555808210156159175760008581528481208381019083015b8082101561591357828255908801906158ff565b5050505b50600093845260208420935b8181101561593e578235855593850193918301918501615923565b50505050505061595160608301836157ae565b6120628183600286016157f7565b60006020828403121561597157600080fd5b813561147281614dfe565b6000610b2e368361531f565b6001600160a01b0385811682528416602082015260a0604082018190526000906159b490830185614efe565b82810360608401526159c68185614efe565b838103608090940193909352505060008152602001949350505050565b604080825283519082018190526000906020906060840190828701845b82811015615a255781516001600160a01b031684529284019290840190600101615a00565b50505083810382850152615a398186614efe565b9695505050505050565b60006020808385031215615a5657600080fd5b82516001600160401b03811115615a6c57600080fd5b8301601f81018513615a7d57600080fd5b8051615a8b61513b826150f7565b81815260059190911b82018301908381019087831115615aaa57600080fd5b928401925b8284101561491657835182529284019290840190615aaf565b600060208284031215615ada57600080fd5b815161147281614b43565b600060208284031215615af757600080fd5b815161147281614c67565b600082516157a4818460208701614c0856fe2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4a164736f6c634300080c000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000cb8d1260f9c92a3a545d409466280ffdd7af70420000000000000000000000004820379a5bfff51df342ba20cc547654a4356a8f
-----Decoded View---------------
Arg [0] : token_ (address): 0xcB8d1260F9c92A3A545d409466280fFdD7AF7042
Arg [1] : admin_ (address): 0x4820379a5BfFF51Df342ba20CC547654A4356A8F
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000cb8d1260f9c92a3a545d409466280ffdd7af7042
Arg [1] : 0000000000000000000000004820379a5bfff51df342ba20cc547654a4356a8f
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | Ether (ETH) | 100.00% | $2,525.24 | 0.2041 | $515.31 |
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.