Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 517 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Bulk Purchase | 16867020 | 530 days ago | IN | 0.00000707 ETH | 0.03493456 | ||||
Single Purchase | 16862764 | 530 days ago | IN | 0.0067 ETH | 0.00478176 | ||||
Single Purchase | 16859134 | 531 days ago | IN | 0.23 ETH | 0.00255984 | ||||
Single Purchase | 16859089 | 531 days ago | IN | 0.18 ETH | 0.00283106 | ||||
Single Purchase | 16858835 | 531 days ago | IN | 0.03845 ETH | 0.00311126 | ||||
Single Purchase | 16858171 | 531 days ago | IN | 0.02 ETH | 0.0034388 | ||||
Single Purchase | 16857192 | 531 days ago | IN | 0.037 ETH | 0.00389511 | ||||
Bulk Purchase | 16856898 | 531 days ago | IN | 1.2462 ETH | 0.00672708 | ||||
Single Purchase | 16856291 | 531 days ago | IN | 0.13269028 ETH | 0.00240027 | ||||
Single Purchase | 16856117 | 531 days ago | IN | 0.12517951 ETH | 0.00374052 | ||||
Bulk Purchase | 16855890 | 531 days ago | IN | 0.105 ETH | 0.01121123 | ||||
Bulk Purchase | 16855002 | 531 days ago | IN | 1.2524 ETH | 0.00673729 | ||||
Bulk Purchase | 16854314 | 531 days ago | IN | 0.01 ETH | 0.00484247 | ||||
Bulk Purchase | 16854307 | 531 days ago | IN | 1.2524 ETH | 0.00746953 | ||||
Bulk Purchase | 16853788 | 532 days ago | IN | 1.2524 ETH | 0.00642084 | ||||
Single Purchase | 16852121 | 532 days ago | IN | 0.164 ETH | 0.00340552 | ||||
Single Purchase | 16850531 | 532 days ago | IN | 0.1 ETH | 0.00767572 | ||||
Single Purchase | 16848477 | 532 days ago | IN | 0.01 ETH | 0.00471477 | ||||
Single Purchase | 16848472 | 532 days ago | IN | 0.01 ETH | 0.00503932 | ||||
Single Purchase | 16847974 | 532 days ago | IN | 0.0055 ETH | 0.00927399 | ||||
Single Purchase | 16844217 | 533 days ago | IN | 0.03612106 ETH | 0.00213576 | ||||
Single Purchase | 16843881 | 533 days ago | IN | 0.0285 ETH | 0.00819321 | ||||
Single Purchase | 16843754 | 533 days ago | IN | 0.028 ETH | 0.00406305 | ||||
Single Purchase | 16843023 | 533 days ago | IN | 0.04231041 ETH | 0.00426132 | ||||
Single Purchase | 16842934 | 533 days ago | IN | 0.03 ETH | 0.00635376 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
16867020 | 530 days ago | 0.00000101 ETH | ||||
16867020 | 530 days ago | 0.00000101 ETH | ||||
16867020 | 530 days ago | 0.00000101 ETH | ||||
16867020 | 530 days ago | 0.00000101 ETH | ||||
16867020 | 530 days ago | 0.00000101 ETH | ||||
16867020 | 530 days ago | 0.00000101 ETH | ||||
16867020 | 530 days ago | 0.00000101 ETH | ||||
16862764 | 530 days ago | 0.0067 ETH | ||||
16859134 | 531 days ago | 0.23 ETH | ||||
16859089 | 531 days ago | 0.18 ETH | ||||
16858835 | 531 days ago | 0.03845 ETH | ||||
16858171 | 531 days ago | 0.02 ETH | ||||
16857192 | 531 days ago | 0.037 ETH | ||||
16856898 | 531 days ago | 2 wei | ||||
16856898 | 531 days ago | 2 wei | ||||
16856898 | 531 days ago | 0.62 ETH | ||||
16856898 | 531 days ago | 0.6262 ETH | ||||
16856291 | 531 days ago | 0.13269028 ETH | ||||
16856117 | 531 days ago | 0.12517951 ETH | ||||
16855890 | 531 days ago | 4 wei | ||||
16855890 | 531 days ago | 2 wei | ||||
16855890 | 531 days ago | 0.054 ETH | ||||
16855890 | 531 days ago | 2 wei | ||||
16855890 | 531 days ago | 0.051 ETH | ||||
16855002 | 531 days ago | 0.6262 ETH |
Loading...
Loading
Contract Name:
RaribleExchangeWrapper
Compiler Version
v0.7.6+commit.7338295f
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.7.6; pragma abicoder v2; import "@rarible/transfer-manager/contracts/lib/LibTransfer.sol"; import "@rarible/lib-bp/contracts/BpLibrary.sol"; import "@rarible/lib-part/contracts/LibPart.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts/token/ERC721/ERC721Holder.sol"; import "@openzeppelin/contracts/token/ERC1155/ERC1155Holder.sol"; import "./interfaces/IWyvernExchange.sol"; import "./interfaces/IExchangeV2.sol"; import "./interfaces/ISeaPort.sol"; import "./interfaces/Ix2y2.sol"; import "./interfaces/ILooksRare.sol"; import "./libraries/IsPausable.sol"; contract RaribleExchangeWrapper is Ownable, ERC721Holder, ERC1155Holder, IsPausable { using LibTransfer for address; using BpLibrary for uint; using SafeMath for uint; address public immutable wyvernExchange; address public immutable exchangeV2; address public immutable seaPort; address public immutable x2y2; address public immutable looksRare; address public immutable sudoswap; event Execution(bool result); enum Markets { ExchangeV2, WyvernExchange, SeaPort, X2Y2, LooksRareOrders, SudoSwap } enum AdditionalDataTypes { NoAdditionalData, RoyaltiesAdditionalData } /** @notice struct for the purchase data @param marketId - market key from Markets enum (what market to use) @param amount - eth price (amount of eth that needs to be send to the marketplace) @param fees - 2 fees (in base points) that are going to be taken on top of order amount encoded in 1 uint256 bytes (27,28) used for dataType bytes (29,30) used for the first value (goes to feeRecipientFirst) bytes (31,32) are used for the second value (goes to feeRecipientSecond) @param data - data for market call */ struct PurchaseDetails { Markets marketId; uint256 amount; uint fees; bytes data; } /** @notice struct for the data with additional Ddta @param data - data for market call @param additionalRoyalties - array additional Royalties (in base points plus address Royalty recipient) */ struct AdditionalData { bytes data; uint[] additionalRoyalties; } constructor( address _wyvernExchange, address _exchangeV2, address _seaPort, address _x2y2, address _looksRare, address _sudoswap ) { wyvernExchange = _wyvernExchange; exchangeV2 = _exchangeV2; seaPort = _seaPort; x2y2 = _x2y2; looksRare = _looksRare; sudoswap = _sudoswap; } /** @notice executes a single purchase @param purchaseDetails - deatails about the purchase (more info in PurchaseDetails struct) @param feeRecipientFirst - address of the first fee recipient @param feeRecipientSecond - address of the second fee recipient */ function singlePurchase(PurchaseDetails memory purchaseDetails, address feeRecipientFirst, address feeRecipientSecond) external payable { requireNotPaused(); (bool success, uint feeAmountFirst, uint feeAmountSecond) = purchase(purchaseDetails, false); emit Execution(success); transferFee(feeAmountFirst, feeRecipientFirst); transferFee(feeAmountSecond, feeRecipientSecond); transferChange(); } /** @notice executes an array of purchases @param purchaseDetails - array of deatails about the purchases (more info in PurchaseDetails struct) @param feeRecipientFirst - address of the first fee recipient @param feeRecipientSecond - address of the second fee recipient @param allowFail - true if fails while executing orders are allowed, false if fail of a single order means fail of the whole batch */ function bulkPurchase(PurchaseDetails[] memory purchaseDetails, address feeRecipientFirst, address feeRecipientSecond, bool allowFail) external payable { requireNotPaused(); uint sumFirstFees = 0; uint sumSecondFees = 0; bool result = false; for (uint i = 0; i < purchaseDetails.length; ++i) { (bool success, uint firstFeeAmount, uint secondFeeAmount) = purchase(purchaseDetails[i], allowFail); result = result || success; emit Execution(success); sumFirstFees = sumFirstFees.add(firstFeeAmount); sumSecondFees = sumSecondFees.add(secondFeeAmount); } require(result, "no successful executions"); transferFee(sumFirstFees, feeRecipientFirst); transferFee(sumSecondFees, feeRecipientSecond); transferChange(); } /** @notice executes one purchase @param purchaseDetails - details about the purchase @param allowFail - true if errors are handled, false if revert on errors @return result false if execution failed, true if succeded @return firstFeeAmount amount of the first fee of the purchase, 0 if failed @return secondFeeAmount amount of the second fee of the purchase, 0 if failed */ function purchase(PurchaseDetails memory purchaseDetails, bool allowFail) internal returns(bool, uint, uint) { (bytes memory marketData, uint[] memory additionalRoyalties) = getDataAndAdditionalData (purchaseDetails.data, purchaseDetails.fees, purchaseDetails.marketId); uint paymentAmount = purchaseDetails.amount; if (purchaseDetails.marketId == Markets.SeaPort){ (bool success,) = address(seaPort).call{value : paymentAmount}(marketData); if (allowFail) { if (!success) { return (false, 0, 0); } } else { require(success, "Purchase SeaPort failed"); } } else if (purchaseDetails.marketId == Markets.WyvernExchange) { (bool success,) = address(wyvernExchange).call{value : paymentAmount}(marketData); if (allowFail) { if (!success) { return (false, 0, 0); } } else { require(success, "Purchase wyvernExchange failed"); } } else if (purchaseDetails.marketId == Markets.ExchangeV2) { (bool success,) = address(exchangeV2).call{value : paymentAmount}(marketData); if (allowFail) { if (!success) { return (false, 0, 0); } } else { require(success, "Purchase rarible failed"); } } else if (purchaseDetails.marketId == Markets.X2Y2) { Ix2y2.RunInput memory input = abi.decode(marketData, (Ix2y2.RunInput)); if (allowFail) { try Ix2y2(x2y2).run{value : paymentAmount}(input) { } catch { return (false, 0, 0); } } else { Ix2y2(x2y2).run{value : paymentAmount}(input); } //for every element in input.details[] getting // order = input.details[i].orderIdx // and from that order getting item = input.details[i].itemId for (uint i = 0; i < input.details.length; ++i) { uint orderId = input.details[i].orderIdx; uint itemId = input.details[i].itemIdx; bytes memory data = input.orders[orderId].items[itemId].data; { if (input.orders[orderId].dataMask.length > 0 && input.details[i].dataReplacement.length > 0) { _arrayReplace(data, input.details[i].dataReplacement, input.orders[orderId].dataMask); } } // 1 = erc-721 if (input.orders[orderId].delegateType == 1) { Ix2y2.Pair721[] memory pairs = abi.decode(data, (Ix2y2.Pair721[])); for (uint256 j = 0; j < pairs.length; j++) { Ix2y2.Pair721 memory p = pairs[j]; IERC721Upgradeable(address(p.token)).safeTransferFrom(address(this), _msgSender(), p.tokenId); } } else if (input.orders[orderId].delegateType == 2) { // 2 = erc-1155 Ix2y2.Pair1155[] memory pairs = abi.decode(data, (Ix2y2.Pair1155[])); for (uint256 j = 0; j < pairs.length; j++) { Ix2y2.Pair1155 memory p = pairs[j]; IERC1155Upgradeable(address(p.token)).safeTransferFrom(address(this), _msgSender(), p.tokenId, p.amount, ""); } } else { revert("unknown delegateType x2y2"); } } } else if (purchaseDetails.marketId == Markets.LooksRareOrders) { (LibLooksRare.TakerOrder memory takerOrder, LibLooksRare.MakerOrder memory makerOrder, bytes4 typeNft) = abi.decode(marketData, (LibLooksRare.TakerOrder, LibLooksRare.MakerOrder, bytes4)); if (allowFail) { try ILooksRare(looksRare).matchAskWithTakerBidUsingETHAndWETH{value : paymentAmount}(takerOrder, makerOrder) { } catch { return (false, 0, 0); } } else { ILooksRare(looksRare).matchAskWithTakerBidUsingETHAndWETH{value : paymentAmount}(takerOrder, makerOrder); } if (typeNft == LibAsset.ERC721_ASSET_CLASS) { IERC721Upgradeable(makerOrder.collection).safeTransferFrom(address(this), _msgSender(), makerOrder.tokenId); } else if (typeNft == LibAsset.ERC1155_ASSET_CLASS) { IERC1155Upgradeable(makerOrder.collection).safeTransferFrom(address(this), _msgSender(), makerOrder.tokenId, makerOrder.amount, ""); } else { revert("Unknown token type"); } } else if (purchaseDetails.marketId == Markets.SudoSwap) { (bool success,) = address(sudoswap).call{value : paymentAmount}(marketData); if (allowFail) { if (!success) { return (false, 0, 0); } } else { require(success, "Purchase sudoswap failed"); } } else { revert("Unknown purchase details"); } //transferring royalties transferAdditionalRoyalties(additionalRoyalties, purchaseDetails.amount); (uint firstFeeAmount, uint secondFeeAmount) = getFees(purchaseDetails.fees, purchaseDetails.amount); return (true, firstFeeAmount, secondFeeAmount); } /** @notice transfers fee to feeRecipient @param feeAmount - amount to be transfered @param feeRecipient - address of the recipient */ function transferFee(uint feeAmount, address feeRecipient) internal { if (feeAmount > 0 && feeRecipient != address(0)) { LibTransfer.transferEth(feeRecipient, feeAmount); } } /** @notice transfers change back to sender */ function transferChange() internal { uint ethAmount = address(this).balance; if (ethAmount > 0) { address(msg.sender).transferEth(ethAmount); } } /** @notice parses fees in base points from one uint and calculates real amount of fees @param fees two fees encoded in one uint, 29 and 30 bytes are used for the first fee, 31 and 32 bytes for second fee @param amount price of the order @return firstFeeAmount real amount for the first fee @return secondFeeAmount real amount for the second fee */ function getFees(uint fees, uint amount) internal pure returns(uint, uint) { uint firstFee = uint(uint16(fees >> 16)); uint secondFee = uint(uint16(fees)); return (amount.bp(firstFee), amount.bp(secondFee)); } /** @notice parses _data to data for market call and additionalData @param feesAndDataType 27 and 28 bytes for dataType @return marketData data for market call @return additionalRoyalties array uint256, (base point + address) */ function getDataAndAdditionalData (bytes memory _data, uint feesAndDataType, Markets marketId) internal pure returns (bytes memory, uint[] memory) { AdditionalDataTypes dataType = AdditionalDataTypes(uint16(feesAndDataType >> 32)); uint[] memory additionalRoyalties; //return no royalties if wrong data type if (dataType == AdditionalDataTypes.NoAdditionalData) { return (_data, additionalRoyalties); } if (dataType == AdditionalDataTypes.RoyaltiesAdditionalData) { AdditionalData memory additionalData = abi.decode(_data, (AdditionalData)); //return no royalties if market doesn't support royalties if (supportsRoyalties(marketId)) { return (additionalData.data, additionalData.additionalRoyalties); } else { return (additionalData.data, additionalRoyalties); } } revert("unknown additionalDataType"); } /** @notice transfer additional royalties @param _additionalRoyalties array uint256 (base point + royalty recipient address) */ function transferAdditionalRoyalties (uint[] memory _additionalRoyalties, uint amount) internal { for (uint i = 0; i < _additionalRoyalties.length; ++i) { if (_additionalRoyalties[i] > 0) { address payable account = payable(address(_additionalRoyalties[i])); uint basePoint = uint(_additionalRoyalties[i] >> 160); uint value = amount.bp(basePoint); transferFee(value, account); } } } // modifies `src` function _arrayReplace( bytes memory src, bytes memory replacement, bytes memory mask ) internal view virtual { require(src.length == replacement.length); require(src.length == mask.length); for (uint256 i = 0; i < src.length; ++i) { if (mask[i] != 0) { src[i] = replacement[i]; } } } /** @notice returns true if this contract supports additional royalties for the marketplace now royalties are supported for: 1. SudoSwap 2. LooksRare */ function supportsRoyalties(Markets marketId) internal pure returns (bool){ if ( marketId == Markets.SudoSwap || marketId == Markets.LooksRareOrders ) { return true; } return false; } receive() external payable {} }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.9 <0.8.0; import "@rarible/role-operator/contracts/OperatorRole.sol"; import "@rarible/exchange-interfaces/contracts/INftTransferProxy.sol"; contract TransferProxy is INftTransferProxy, Initializable, OperatorRole { function __TransferProxy_init() external initializer { __Ownable_init(); } function erc721safeTransferFrom(IERC721Upgradeable token, address from, address to, uint256 tokenId) override external onlyOperator { token.safeTransferFrom(from, to, tokenId); } function erc1155safeTransferFrom(IERC1155Upgradeable token, address from, address to, uint256 id, uint256 value, bytes calldata data) override external onlyOperator { token.safeTransferFrom(from, to, id, value, data); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.9 <0.8.0; import "@rarible/role-operator/contracts/OperatorRole.sol"; import "@rarible/exchange-interfaces/contracts/IERC20TransferProxy.sol"; contract ERC20TransferProxy is IERC20TransferProxy, Initializable, OperatorRole { function __ERC20TransferProxy_init() external initializer { __Ownable_init(); } function erc20safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) override external onlyOperator { require(token.transferFrom(from, to, value), "failure while transferring"); } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; library LibTransfer { function transferEth(address to, uint value) internal { (bool success,) = to.call{ value: value }(""); require(success, "transfer failed"); } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "@rarible/lib-asset/contracts/LibAsset.sol"; library LibFeeSide { enum FeeSide {NONE, LEFT, RIGHT} function getFeeSide(bytes4 leftClass, bytes4 rightClass) internal pure returns (FeeSide) { if (leftClass == LibAsset.ETH_ASSET_CLASS) { return FeeSide.LEFT; } if (rightClass == LibAsset.ETH_ASSET_CLASS) { return FeeSide.RIGHT; } if (leftClass == LibAsset.ERC20_ASSET_CLASS) { return FeeSide.LEFT; } if (rightClass == LibAsset.ERC20_ASSET_CLASS) { return FeeSide.RIGHT; } if (leftClass == LibAsset.ERC1155_ASSET_CLASS) { return FeeSide.LEFT; } if (rightClass == LibAsset.ERC1155_ASSET_CLASS) { return FeeSide.RIGHT; } return FeeSide.NONE; } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import "@rarible/lib-part/contracts/LibPart.sol"; import "@rarible/lib-asset/contracts/LibAsset.sol"; import "./LibFeeSide.sol"; library LibDeal { struct DealSide { LibAsset.Asset asset; LibPart.Part[] payouts; LibPart.Part[] originFees; address proxy; address from; } struct DealData { uint maxFeesBasePoint; LibFeeSide.FeeSide feeSide; } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import "../lib/LibDeal.sol"; import "./ITransferExecutor.sol"; abstract contract ITransferManager is ITransferExecutor { function doTransfers( LibDeal.DealSide memory left, LibDeal.DealSide memory right, LibDeal.DealData memory dealData ) internal virtual returns (uint totalMakeValue, uint totalTakeValue); }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import "@rarible/lib-asset/contracts/LibAsset.sol"; abstract contract ITransferExecutor { function transfer( LibAsset.Asset memory asset, address from, address to, address proxy ) internal virtual; }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import "@rarible/exchange-interfaces/contracts/ITransferProxy.sol"; import "@rarible/exchange-interfaces/contracts/INftTransferProxy.sol"; import "@rarible/exchange-interfaces/contracts/IERC20TransferProxy.sol"; import "./interfaces/ITransferExecutor.sol"; import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "./lib/LibTransfer.sol"; abstract contract TransferExecutor is Initializable, OwnableUpgradeable, ITransferExecutor { using LibTransfer for address; mapping (bytes4 => address) internal proxies; event ProxyChange(bytes4 indexed assetType, address proxy); function __TransferExecutor_init_unchained(address transferProxy, address erc20TransferProxy) internal { proxies[LibAsset.ERC20_ASSET_CLASS] = address(erc20TransferProxy); proxies[LibAsset.ERC721_ASSET_CLASS] = address(transferProxy); proxies[LibAsset.ERC1155_ASSET_CLASS] = address(transferProxy); } function setTransferProxy(bytes4 assetType, address proxy) external onlyOwner { proxies[assetType] = proxy; emit ProxyChange(assetType, proxy); } function transfer( LibAsset.Asset memory asset, address from, address to, address proxy ) internal override { if (asset.assetType.assetClass == LibAsset.ERC721_ASSET_CLASS) { //not using transfer proxy when transfering from this contract (address token, uint tokenId) = abi.decode(asset.assetType.data, (address, uint256)); require(asset.value == 1, "erc721 value error"); if (from == address(this)){ IERC721Upgradeable(token).safeTransferFrom(address(this), to, tokenId); } else { INftTransferProxy(proxy).erc721safeTransferFrom(IERC721Upgradeable(token), from, to, tokenId); } } else if (asset.assetType.assetClass == LibAsset.ERC20_ASSET_CLASS) { //not using transfer proxy when transfering from this contract (address token) = abi.decode(asset.assetType.data, (address)); if (from == address(this)){ require(IERC20Upgradeable(token).transfer(to, asset.value), "erc20 transfer failed"); } else { IERC20TransferProxy(proxy).erc20safeTransferFrom(IERC20Upgradeable(token), from, to, asset.value); } } else if (asset.assetType.assetClass == LibAsset.ERC1155_ASSET_CLASS) { //not using transfer proxy when transfering from this contract (address token, uint tokenId) = abi.decode(asset.assetType.data, (address, uint256)); if (from == address(this)){ IERC1155Upgradeable(token).safeTransferFrom(address(this), to, tokenId, asset.value, ""); } else { INftTransferProxy(proxy).erc1155safeTransferFrom(IERC1155Upgradeable(token), from, to, tokenId, asset.value, ""); } } else if (asset.assetType.assetClass == LibAsset.ETH_ASSET_CLASS) { if (to != address(this)) { to.transferEth(asset.value); } } else { ITransferProxy(proxy).transfer(asset, from, to); } } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@rarible/lazy-mint/contracts/erc-721/LibERC721LazyMint.sol"; import "@rarible/lazy-mint/contracts/erc-1155/LibERC1155LazyMint.sol"; import "@rarible/exchange-interfaces/contracts/IRoyaltiesProvider.sol"; import "@rarible/lib-bp/contracts/BpLibrary.sol"; import "./interfaces/ITransferManager.sol"; abstract contract RaribleTransferManager is OwnableUpgradeable, ITransferManager { using BpLibrary for uint; using SafeMathUpgradeable for uint; // @notice protocolFee is deprecated uint private protocolFee; IRoyaltiesProvider public royaltiesRegistry; // deprecated: no need without protocolFee address private defaultFeeReceiver; // deprecated: no need without protocolFee mapping(address => address) private feeReceivers; function __RaribleTransferManager_init_unchained( uint newProtocolFee, address newDefaultFeeReceiver, IRoyaltiesProvider newRoyaltiesProvider ) internal initializer { protocolFee = newProtocolFee; defaultFeeReceiver = newDefaultFeeReceiver; royaltiesRegistry = newRoyaltiesProvider; } function setRoyaltiesRegistry(IRoyaltiesProvider newRoyaltiesRegistry) external onlyOwner { royaltiesRegistry = newRoyaltiesRegistry; } /** @notice executes transfers for 2 matched orders @param left DealSide from the left order (see LibDeal.sol) @param right DealSide from the right order (see LibDeal.sol) @param dealData DealData of the match (see LibDeal.sol) @return totalLeftValue - total amount for the left order @return totalRightValue - total amout for the right order */ function doTransfers( LibDeal.DealSide memory left, LibDeal.DealSide memory right, LibDeal.DealData memory dealData ) override internal returns (uint totalLeftValue, uint totalRightValue) { totalLeftValue = left.asset.value; totalRightValue = right.asset.value; if (dealData.feeSide == LibFeeSide.FeeSide.LEFT) { totalLeftValue = doTransfersWithFees(left, right, dealData.maxFeesBasePoint); transferPayouts(right.asset.assetType, right.asset.value, right.from, left.payouts, right.proxy); } else if (dealData.feeSide == LibFeeSide.FeeSide.RIGHT) { totalRightValue = doTransfersWithFees(right, left, dealData.maxFeesBasePoint); transferPayouts(left.asset.assetType, left.asset.value, left.from, right.payouts, left.proxy); } else { transferPayouts(left.asset.assetType, left.asset.value, left.from, right.payouts, left.proxy); transferPayouts(right.asset.assetType, right.asset.value, right.from, left.payouts, right.proxy); } } /** @notice executes the fee-side transfers (payment + fees) @param paymentSide DealSide of the fee-side order @param nftSide DealSide of the nft-side order @param maxFeesBasePoint max fee for the sell-order (used and is > 0 for V3 orders only) @return totalAmount of fee-side asset */ function doTransfersWithFees( LibDeal.DealSide memory paymentSide, LibDeal.DealSide memory nftSide, uint maxFeesBasePoint ) internal returns (uint totalAmount) { totalAmount = calculateTotalAmount(paymentSide.asset.value, paymentSide.originFees, maxFeesBasePoint); uint rest = totalAmount; rest = transferRoyalties(paymentSide.asset.assetType, nftSide.asset.assetType, nftSide.payouts, rest, paymentSide.asset.value, paymentSide.from, paymentSide.proxy); if ( paymentSide.originFees.length == 1 && nftSide.originFees.length == 1 && nftSide.originFees[0].account == paymentSide.originFees[0].account ) { LibPart.Part[] memory origin = new LibPart.Part[](1); origin[0].account = nftSide.originFees[0].account; origin[0].value = nftSide.originFees[0].value + paymentSide.originFees[0].value; (rest,) = transferFees(paymentSide.asset.assetType, rest, paymentSide.asset.value, origin, paymentSide.from, paymentSide.proxy); } else { (rest,) = transferFees(paymentSide.asset.assetType, rest, paymentSide.asset.value, paymentSide.originFees, paymentSide.from, paymentSide.proxy); (rest,) = transferFees(paymentSide.asset.assetType, rest, paymentSide.asset.value, nftSide.originFees, paymentSide.from, paymentSide.proxy); } transferPayouts(paymentSide.asset.assetType, rest, paymentSide.from, nftSide.payouts, paymentSide.proxy); } /** @notice Transfer royalties. If there is only one royalties receiver and one address in payouts and they match, nothing is transferred in this function @param paymentAssetType Asset Type which represents payment @param nftAssetType Asset Type which represents NFT to pay royalties for @param payouts Payouts to be made @param rest How much of the amount left after previous transfers @param from owner of the Asset to transfer @param proxy Transfer proxy to use @return How much left after transferring royalties */ function transferRoyalties( LibAsset.AssetType memory paymentAssetType, LibAsset.AssetType memory nftAssetType, LibPart.Part[] memory payouts, uint rest, uint amount, address from, address proxy ) internal returns (uint) { LibPart.Part[] memory royalties = getRoyaltiesByAssetType(nftAssetType); if ( royalties.length == 1 && payouts.length == 1 && royalties[0].account == payouts[0].account ) { require(royalties[0].value <= 5000, "Royalties are too high (>50%)"); return rest; } (uint result, uint totalRoyalties) = transferFees(paymentAssetType, rest, amount, royalties, from, proxy); require(totalRoyalties <= 5000, "Royalties are too high (>50%)"); return result; } /** @notice calculates royalties by asset type. If it's a lazy NFT, then royalties are extracted from asset. otherwise using royaltiesRegistry @param nftAssetType NFT Asset Type to calculate royalties for @return calculated royalties (Array of LibPart.Part) */ function getRoyaltiesByAssetType(LibAsset.AssetType memory nftAssetType) internal returns (LibPart.Part[] memory) { if (nftAssetType.assetClass == LibAsset.ERC1155_ASSET_CLASS || nftAssetType.assetClass == LibAsset.ERC721_ASSET_CLASS) { (address token, uint tokenId) = abi.decode(nftAssetType.data, (address, uint)); return royaltiesRegistry.getRoyalties(token, tokenId); } else if (nftAssetType.assetClass == LibERC1155LazyMint.ERC1155_LAZY_ASSET_CLASS) { (, LibERC1155LazyMint.Mint1155Data memory data) = abi.decode(nftAssetType.data, (address, LibERC1155LazyMint.Mint1155Data)); return data.royalties; } else if (nftAssetType.assetClass == LibERC721LazyMint.ERC721_LAZY_ASSET_CLASS) { (, LibERC721LazyMint.Mint721Data memory data) = abi.decode(nftAssetType.data, (address, LibERC721LazyMint.Mint721Data)); return data.royalties; } LibPart.Part[] memory empty; return empty; } /** @notice Transfer fees @param assetType Asset Type to transfer @param rest How much of the amount left after previous transfers @param amount Total amount of the Asset. Used as a base to calculate part from (100%) @param fees Array of LibPart.Part which represents fees to pay @param from owner of the Asset to transfer @param proxy Transfer proxy to use @return newRest how much left after transferring fees @return totalFees total number of fees in bp */ function transferFees( LibAsset.AssetType memory assetType, uint rest, uint amount, LibPart.Part[] memory fees, address from, address proxy ) internal returns (uint newRest, uint totalFees) { totalFees = 0; newRest = rest; for (uint256 i = 0; i < fees.length; ++i) { totalFees = totalFees.add(fees[i].value); uint feeValue; (newRest, feeValue) = subFeeInBp(newRest, amount, fees[i].value); if (feeValue > 0) { transfer(LibAsset.Asset(assetType, feeValue), from, fees[i].account, proxy); } } } /** @notice transfers main part of the asset (payout) @param assetType Asset Type to transfer @param amount Amount of the asset to transfer @param from Current owner of the asset @param payouts List of payouts - receivers of the Asset @param proxy Transfer Proxy to use */ function transferPayouts( LibAsset.AssetType memory assetType, uint amount, address from, LibPart.Part[] memory payouts, address proxy ) internal { require(payouts.length > 0, "transferPayouts: nothing to transfer"); uint sumBps = 0; uint rest = amount; for (uint256 i = 0; i < payouts.length - 1; ++i) { uint currentAmount = amount.bp(payouts[i].value); sumBps = sumBps.add(payouts[i].value); if (currentAmount > 0) { rest = rest.sub(currentAmount); transfer(LibAsset.Asset(assetType, currentAmount), from, payouts[i].account, proxy); } } LibPart.Part memory lastPayout = payouts[payouts.length - 1]; sumBps = sumBps.add(lastPayout.value); require(sumBps == 10000, "Sum payouts Bps not equal 100%"); if (rest > 0) { transfer(LibAsset.Asset(assetType, rest), from, lastPayout.account, proxy); } } /** @notice calculates total amount of fee-side asset that is going to be used in match @param amount fee-side order value @param orderOriginFees fee-side order's origin fee (it adds on top of the amount) @param maxFeesBasePoint max fee for the sell-order (used and is > 0 for V3 orders only) @return total amount of fee-side asset */ function calculateTotalAmount( uint amount, LibPart.Part[] memory orderOriginFees, uint maxFeesBasePoint ) internal pure returns (uint) { if (maxFeesBasePoint > 0) { return amount; } uint fees = 0; for (uint256 i = 0; i < orderOriginFees.length; ++i) { require(orderOriginFees[i].value <= 10000, "origin fee is too big"); fees = fees + orderOriginFees[i].value; } return amount.add(amount.bp(fees)); } function subFeeInBp(uint value, uint total, uint feeInBp) internal pure returns (uint newValue, uint realFee) { return subFee(value, total.bp(feeInBp)); } function subFee(uint value, uint fee) internal pure returns (uint newValue, uint realFee) { if (value > fee) { newValue = value.sub(fee); realFee = fee; } else { newValue = 0; realFee = value; } } uint256[46] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; pragma abicoder v2; import "@rarible/lib-part/contracts/LibPart.sol"; interface RoyaltiesV2 { event RoyaltiesSet(uint256 tokenId, LibPart.Part[] royalties); function getRaribleV2Royalties(uint256 id) external view returns (LibPart.Part[] memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; interface RoyaltiesV1 { event SecondarySaleFees(uint256 tokenId, address[] recipients, uint[] bps); function getFeeRecipients(uint256 id) external view returns (address payable[] memory); function getFeeBps(uint256 id) external view returns (uint[] memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; library LibRoyaltiesV2 { /* * bytes4(keccak256('getRaribleV2Royalties(uint256)')) == 0xcad96cca */ bytes4 constant _INTERFACE_ID_ROYALTIES = 0xcad96cca; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; library LibRoyaltiesV1 { /* * bytes4(keccak256('getFeeBps(uint256)')) == 0x0ebd4c7f * bytes4(keccak256('getFeeRecipients(uint256)')) == 0xb9c4d9fb * * => 0x0ebd4c7f ^ 0xb9c4d9fb == 0xb7799584 */ bytes4 constant _INTERFACE_ID_FEES = 0xb7799584; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; import "@rarible/lib-part/contracts/LibPart.sol"; library LibRoyalties2981 { /* * https://eips.ethereum.org/EIPS/eip-2981: bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a; */ bytes4 constant _INTERFACE_ID_ROYALTIES = 0x2a55205a; uint96 constant _WEIGHT_VALUE = 1000000; /*Method for converting amount to percent and forming LibPart*/ function calculateRoyalties(address to, uint256 amount) internal view returns (LibPart.Part[] memory) { LibPart.Part[] memory result; if (amount == 0) { return result; } uint256 percent = amount * 10000 / _WEIGHT_VALUE; require(percent < 10000, "Royalties 2981 exceeds 100%"); result = new LibPart.Part[](1); result[0].account = payable(to); result[0].value = uint96(percent); return result; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; import "@rarible/lib-part/contracts/LibPart.sol"; /// /// @dev Interface for the NFT Royalty Standard /// //interface IERC2981 is IERC165 { interface IERC2981 { /// ERC165 bytes to add to interface array - set in parent contract /// implementing this standard /// /// bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a /// bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a; /// _registerInterface(_INTERFACE_ID_ERC2981); /// @notice Called with the sale price to determine how much royalty // is owed and to whom. /// @param _tokenId - the NFT asset queried for royalty information /// @param _salePrice - the sale price of the NFT asset specified by _tokenId /// @return receiver - address of who should be sent the royalty payment /// @return royaltyAmount - the royalty payment amount for _salePrice function royaltyInfo( uint256 _tokenId, uint256 _salePrice ) external view returns ( address receiver, uint256 royaltyAmount ); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; pragma abicoder v2; import "@rarible/exchange-interfaces/contracts/IRoyaltiesProvider.sol"; import "@rarible/royalties/contracts/LibRoyaltiesV2.sol"; import "@rarible/royalties/contracts/LibRoyaltiesV1.sol"; import "@rarible/royalties/contracts/LibRoyalties2981.sol"; import "@rarible/royalties/contracts/RoyaltiesV1.sol"; import "@rarible/royalties/contracts/RoyaltiesV2.sol"; import "@rarible/royalties/contracts/IERC2981.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; contract RoyaltiesRegistry is IRoyaltiesProvider, OwnableUpgradeable { /// @dev deprecated event RoyaltiesSetForToken(address indexed token, uint indexed tokenId, LibPart.Part[] royalties); /// @dev emitted when royalties set for token in event RoyaltiesSetForContract(address indexed token, LibPart.Part[] royalties); /// @dev struct to store royalties in royaltiesByToken struct RoyaltiesSet { bool initialized; LibPart.Part[] royalties; } /// @dev deprecated mapping(bytes32 => RoyaltiesSet) public royaltiesByTokenAndTokenId; /// @dev stores royalties for token contract, set in setRoyaltiesByToken() method mapping(address => RoyaltiesSet) public royaltiesByToken; /// @dev stores external provider and royalties type for token contract mapping(address => uint) public royaltiesProviders; /// @dev total amount or supported royalties types // 0 - royalties type is unset // 1 - royaltiesByToken, 2 - v2, 3 - v1, // 4 - external provider, 5 - EIP-2981 // 6 - unsupported/nonexistent royalties type uint constant royaltiesTypesAmount = 6; function __RoyaltiesRegistry_init() external initializer { __Ownable_init_unchained(); } /// @dev sets external provider for token contract, and royalties type = 4 function setProviderByToken(address token, address provider) external { checkOwner(token); setRoyaltiesType(token, 4, provider); } /// @dev returns provider address for token contract from royaltiesProviders mapping function getProvider(address token) public view returns(address) { return address(royaltiesProviders[token]); } /// @dev returns royalties type for token contract function getRoyaltiesType(address token) external view returns(uint) { return _getRoyaltiesType(royaltiesProviders[token]); } /// @dev returns royalties type from uint function _getRoyaltiesType(uint data) internal pure returns(uint) { for (uint i = 1; i <= royaltiesTypesAmount; ++i) { if (data / 2**(256-i) == 1) { return i; } } return 0; } /// @dev sets royalties type for token contract function setRoyaltiesType(address token, uint royaltiesType, address royaltiesProvider) internal { require(royaltiesType > 0 && royaltiesType <= royaltiesTypesAmount, "wrong royaltiesType"); royaltiesProviders[token] = uint(royaltiesProvider) + 2**(256 - royaltiesType); } /// @dev clears and sets new royalties type for token contract function forceSetRoyaltiesType(address token, uint royaltiesType) external { checkOwner(token); setRoyaltiesType(token, royaltiesType, getProvider(token)); } /// @dev clears royalties type for token contract function clearRoyaltiesType(address token) external { checkOwner(token); royaltiesProviders[token] = uint(getProvider(token)); } /// @dev sets royalties for token contract in royaltiesByToken mapping and royalties type = 1 function setRoyaltiesByToken(address token, LibPart.Part[] memory royalties) external { checkOwner(token); //clearing royaltiesProviders value for the token delete royaltiesProviders[token]; // setting royaltiesType = 1 for the token setRoyaltiesType(token, 1, address(0)); uint sumRoyalties = 0; delete royaltiesByToken[token]; for (uint i = 0; i < royalties.length; ++i) { require(royalties[i].account != address(0x0), "RoyaltiesByToken recipient should be present"); require(royalties[i].value != 0, "Royalty value for RoyaltiesByToken should be > 0"); royaltiesByToken[token].royalties.push(royalties[i]); sumRoyalties += royalties[i].value; } require(sumRoyalties < 10000, "Set by token royalties sum more, than 100%"); royaltiesByToken[token].initialized = true; emit RoyaltiesSetForContract(token, royalties); } /// @dev checks if msg.sender is owner of this contract or owner of the token contract function checkOwner(address token) internal view { if ((owner() != _msgSender()) && (OwnableUpgradeable(token).owner() != _msgSender())) { revert("Token owner not detected"); } } /// @dev calculates royalties type for token contract function calculateRoyaltiesType(address token, address royaltiesProvider ) internal view returns(uint) { try IERC165Upgradeable(token).supportsInterface(LibRoyaltiesV2._INTERFACE_ID_ROYALTIES) returns(bool result) { if (result) { return 2; } } catch { } try IERC165Upgradeable(token).supportsInterface(LibRoyaltiesV1._INTERFACE_ID_FEES) returns(bool result) { if (result) { return 3; } } catch { } try IERC165Upgradeable(token).supportsInterface(LibRoyalties2981._INTERFACE_ID_ROYALTIES) returns(bool result) { if (result) { return 5; } } catch { } if (royaltiesProvider != address(0)) { return 4; } if (royaltiesByToken[token].initialized) { return 1; } return 6; } /// @dev returns royalties for token contract and token id function getRoyalties(address token, uint tokenId) override external returns (LibPart.Part[] memory) { uint royaltiesProviderData = royaltiesProviders[token]; address royaltiesProvider = address(royaltiesProviderData); uint royaltiesType = _getRoyaltiesType(royaltiesProviderData); // case when royaltiesType is not set if (royaltiesType == 0) { // calculating royalties type for token royaltiesType = calculateRoyaltiesType(token, royaltiesProvider); //saving royalties type setRoyaltiesType(token, royaltiesType, royaltiesProvider); } //case royaltiesType = 1, royalties are set in royaltiesByToken if (royaltiesType == 1) { return royaltiesByToken[token].royalties; } //case royaltiesType = 2, royalties rarible v2 if (royaltiesType == 2) { return getRoyaltiesRaribleV2(token,tokenId); } //case royaltiesType = 3, royalties rarible v1 if (royaltiesType == 3) { return getRoyaltiesRaribleV1(token, tokenId); } //case royaltiesType = 4, royalties from external provider if (royaltiesType == 4) { return providerExtractor(token, tokenId, royaltiesProvider); } //case royaltiesType = 5, royalties EIP-2981 if (royaltiesType == 5) { return getRoyaltiesEIP2981(token, tokenId); } // case royaltiesType = 6, unknown/empty royalties if (royaltiesType == 6) { return new LibPart.Part[](0); } revert("something wrong in getRoyalties"); } /// @dev tries to get royalties rarible-v2 for token and tokenId function getRoyaltiesRaribleV2(address token, uint tokenId) internal view returns (LibPart.Part[] memory) { try RoyaltiesV2(token).getRaribleV2Royalties(tokenId) returns (LibPart.Part[] memory result) { return result; } catch { return new LibPart.Part[](0); } } /// @dev tries to get royalties rarible-v1 for token and tokenId function getRoyaltiesRaribleV1(address token, uint tokenId) internal view returns (LibPart.Part[] memory) { RoyaltiesV1 v1 = RoyaltiesV1(token); address payable[] memory recipients; try v1.getFeeRecipients(tokenId) returns (address payable[] memory resultRecipients) { recipients = resultRecipients; } catch { return new LibPart.Part[](0); } uint[] memory values; try v1.getFeeBps(tokenId) returns (uint[] memory resultValues) { values = resultValues; } catch { return new LibPart.Part[](0); } if (values.length != recipients.length) { return new LibPart.Part[](0); } LibPart.Part[] memory result = new LibPart.Part[](values.length); for (uint256 i = 0; i < values.length; ++i) { result[i].value = uint96(values[i]); result[i].account = recipients[i]; } return result; } /// @dev tries to get royalties EIP-2981 for token and tokenId function getRoyaltiesEIP2981(address token, uint tokenId) internal view returns (LibPart.Part[] memory) { try IERC2981(token).royaltyInfo(tokenId, LibRoyalties2981._WEIGHT_VALUE) returns (address receiver, uint256 royaltyAmount) { return LibRoyalties2981.calculateRoyalties(receiver, royaltyAmount); } catch { return new LibPart.Part[](0); } } /// @dev tries to get royalties for token and tokenId from external provider set in royaltiesProviders function providerExtractor(address token, uint tokenId, address providerAddress) internal returns (LibPart.Part[] memory) { try IRoyaltiesProvider(providerAddress).getRoyalties(token, tokenId) returns (LibPart.Part[] memory result) { return result; } catch { return new LibPart.Part[](0); } } uint256[46] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.9 <0.8.0; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; contract OperatorRole is OwnableUpgradeable { mapping (address => bool) operators; function __OperatorRole_init() external initializer { __Context_init_unchained(); __Ownable_init_unchained(); } function addOperator(address operator) external onlyOwner { operators[operator] = true; } function removeOperator(address operator) external onlyOwner { operators[operator] = false; } modifier onlyOperator() { require(operators[_msgSender()], "OperatorRole: caller is not the operator"); _; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; library LibSignature { /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { // Check the signature length if (signature.length != 65) { revert("ECDSA: invalid signature length"); } // Divide the signature in r, s and v variables bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. // solhint-disable-next-line no-inline-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return recover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover-bytes32-bytes-} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. require( uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ECDSA: invalid signature 's' value" ); // If the signature is valid (and not malleable), return the signer address // v > 30 is a special case, we need to adjust hash with "\x19Ethereum Signed Message:\n32" // and v = v - 4 address signer; if (v > 30) { require( v - 4 == 27 || v - 4 == 28, "ECDSA: invalid signature 'v' value" ); signer = ecrecover(toEthSignedMessageHash(hash), v - 4, r, s); } else { require(v == 27 || v == 28, "ECDSA: invalid signature 'v' value"); signer = ecrecover(hash, v, r, s); } require(signer != address(0), "ECDSA: invalid signature"); return signer; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * replicates the behavior of the * https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`] * JSON-RPC method. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256( abi.encodePacked("\x19Ethereum Signed Message:\n32", hash) ); } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; interface IERC1271 { /** * @dev Should return whether the signature provided is valid for the provided data * @param _hash Hash of the data signed on the behalf of address(this) * @param _signature Signature byte array associated with _data * * MUST return the bytes4 magic value 0x1626ba7e when function passes. * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5) * MUST allow external calls */ function isValidSignature(bytes32 _hash, bytes calldata _signature) virtual external view returns (bytes4 magicValue); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; library LibPart { bytes32 public constant TYPE_HASH = keccak256("Part(address account,uint96 value)"); struct Part { address payable account; uint96 value; } function hash(Part memory part) internal pure returns (bytes32) { return keccak256(abi.encode(TYPE_HASH, part.account, part.value)); } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; library BpLibrary { using SafeMathUpgradeable for uint; function bp(uint value, uint bpValue) internal pure returns (uint) { return value.mul(bpValue).div(10000); } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; library LibAsset { bytes4 constant public ETH_ASSET_CLASS = bytes4(keccak256("ETH")); bytes4 constant public ERC20_ASSET_CLASS = bytes4(keccak256("ERC20")); bytes4 constant public ERC721_ASSET_CLASS = bytes4(keccak256("ERC721")); bytes4 constant public ERC1155_ASSET_CLASS = bytes4(keccak256("ERC1155")); bytes4 constant public COLLECTION = bytes4(keccak256("COLLECTION")); bytes4 constant public CRYPTO_PUNKS = bytes4(keccak256("CRYPTO_PUNKS")); bytes32 constant ASSET_TYPE_TYPEHASH = keccak256( "AssetType(bytes4 assetClass,bytes data)" ); bytes32 constant ASSET_TYPEHASH = keccak256( "Asset(AssetType assetType,uint256 value)AssetType(bytes4 assetClass,bytes data)" ); struct AssetType { bytes4 assetClass; bytes data; } struct Asset { AssetType assetType; uint value; } function hash(AssetType memory assetType) internal pure returns (bytes32) { return keccak256(abi.encode( ASSET_TYPE_TYPEHASH, assetType.assetClass, keccak256(assetType.data) )); } function hash(Asset memory asset) internal pure returns (bytes32) { return keccak256(abi.encode( ASSET_TYPEHASH, hash(asset.assetType), asset.value )); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; import "@rarible/lib-part/contracts/LibPart.sol"; library LibERC721LazyMint { bytes4 constant public ERC721_LAZY_ASSET_CLASS = bytes4(keccak256("ERC721_LAZY")); bytes4 constant _INTERFACE_ID_MINT_AND_TRANSFER = 0x8486f69f; struct Mint721Data { uint tokenId; string tokenURI; LibPart.Part[] creators; LibPart.Part[] royalties; bytes[] signatures; } bytes32 public constant MINT_AND_TRANSFER_TYPEHASH = keccak256("Mint721(uint256 tokenId,string tokenURI,Part[] creators,Part[] royalties)Part(address account,uint96 value)"); function hash(Mint721Data memory data) internal pure returns (bytes32) { bytes32[] memory royaltiesBytes = new bytes32[](data.royalties.length); for (uint i = 0; i < data.royalties.length; ++i) { royaltiesBytes[i] = LibPart.hash(data.royalties[i]); } bytes32[] memory creatorsBytes = new bytes32[](data.creators.length); for (uint i = 0; i < data.creators.length; ++i) { creatorsBytes[i] = LibPart.hash(data.creators[i]); } return keccak256(abi.encode( MINT_AND_TRANSFER_TYPEHASH, data.tokenId, keccak256(bytes(data.tokenURI)), keccak256(abi.encodePacked(creatorsBytes)), keccak256(abi.encodePacked(royaltiesBytes)) )); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; import "@rarible/lib-part/contracts/LibPart.sol"; library LibERC1155LazyMint { bytes4 constant public ERC1155_LAZY_ASSET_CLASS = bytes4(keccak256("ERC1155_LAZY")); bytes4 constant _INTERFACE_ID_MINT_AND_TRANSFER = 0x6db15a0f; struct Mint1155Data { uint tokenId; string tokenURI; uint supply; LibPart.Part[] creators; LibPart.Part[] royalties; bytes[] signatures; } bytes32 public constant MINT_AND_TRANSFER_TYPEHASH = keccak256("Mint1155(uint256 tokenId,uint256 supply,string tokenURI,Part[] creators,Part[] royalties)Part(address account,uint96 value)"); function hash(Mint1155Data memory data) internal pure returns (bytes32) { bytes32[] memory royaltiesBytes = new bytes32[](data.royalties.length); for (uint i = 0; i < data.royalties.length; ++i) { royaltiesBytes[i] = LibPart.hash(data.royalties[i]); } bytes32[] memory creatorsBytes = new bytes32[](data.creators.length); for (uint i = 0; i < data.creators.length; ++i) { creatorsBytes[i] = LibPart.hash(data.creators[i]); } return keccak256(abi.encode( MINT_AND_TRANSFER_TYPEHASH, data.tokenId, data.supply, keccak256(bytes(data.tokenURI)), keccak256(abi.encodePacked(creatorsBytes)), keccak256(abi.encodePacked(royaltiesBytes)) )); } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; library LibSeaPort { /** * @dev For basic orders involving ETH / native / ERC20 <=> ERC721 / ERC1155 * matching, a group of six functions may be called that only requires a * subset of the usual order arguments. Note the use of a "basicOrderType" * enum; this represents both the usual order type as well as the "route" * of the basic order (a simple derivation function for the basic order * type is `basicOrderType = orderType + (4 * basicOrderRoute)`.) */ struct BasicOrderParameters { address considerationToken; // 0x24 uint256 considerationIdentifier; // 0x44 uint256 considerationAmount; // 0x64 address payable offerer; // 0x84 address zone; // 0xa4 address offerToken; // 0xc4 uint256 offerIdentifier; // 0xe4 uint256 offerAmount; // 0x104 BasicOrderType basicOrderType; // 0x124 uint256 startTime; // 0x144 uint256 endTime; // 0x164 bytes32 zoneHash; // 0x184 uint256 salt; // 0x1a4 bytes32 offererConduitKey; // 0x1c4 bytes32 fulfillerConduitKey; // 0x1e4 uint256 totalOriginalAdditionalRecipients; // 0x204 AdditionalRecipient[] additionalRecipients; // 0x224 bytes signature; // 0x244 } /** * @dev Basic orders can supply any number of additional recipients, with the * implied assumption that they are supplied from the offered ETH (or other * native token) or ERC20 token for the order. */ struct AdditionalRecipient { uint256 amount; address payable recipient; } // prettier-ignore enum BasicOrderType { // 0: no partial fills, anyone can execute ETH_TO_ERC721_FULL_OPEN, // 1: partial fills supported, anyone can execute ETH_TO_ERC721_PARTIAL_OPEN, // 2: no partial fills, only offerer or zone can execute ETH_TO_ERC721_FULL_RESTRICTED, // 3: partial fills supported, only offerer or zone can execute ETH_TO_ERC721_PARTIAL_RESTRICTED, // 4: no partial fills, anyone can execute ETH_TO_ERC1155_FULL_OPEN, // 5: partial fills supported, anyone can execute ETH_TO_ERC1155_PARTIAL_OPEN, // 6: no partial fills, only offerer or zone can execute ETH_TO_ERC1155_FULL_RESTRICTED, // 7: partial fills supported, only offerer or zone can execute ETH_TO_ERC1155_PARTIAL_RESTRICTED, // 8: no partial fills, anyone can execute ERC20_TO_ERC721_FULL_OPEN, // 9: partial fills supported, anyone can execute ERC20_TO_ERC721_PARTIAL_OPEN, // 10: no partial fills, only offerer or zone can execute ERC20_TO_ERC721_FULL_RESTRICTED, // 11: partial fills supported, only offerer or zone can execute ERC20_TO_ERC721_PARTIAL_RESTRICTED, // 12: no partial fills, anyone can execute ERC20_TO_ERC1155_FULL_OPEN, // 13: partial fills supported, anyone can execute ERC20_TO_ERC1155_PARTIAL_OPEN, // 14: no partial fills, only offerer or zone can execute ERC20_TO_ERC1155_FULL_RESTRICTED, // 15: partial fills supported, only offerer or zone can execute ERC20_TO_ERC1155_PARTIAL_RESTRICTED, // 16: no partial fills, anyone can execute ERC721_TO_ERC20_FULL_OPEN, // 17: partial fills supported, anyone can execute ERC721_TO_ERC20_PARTIAL_OPEN, // 18: no partial fills, only offerer or zone can execute ERC721_TO_ERC20_FULL_RESTRICTED, // 19: partial fills supported, only offerer or zone can execute ERC721_TO_ERC20_PARTIAL_RESTRICTED, // 20: no partial fills, anyone can execute ERC1155_TO_ERC20_FULL_OPEN, // 21: partial fills supported, anyone can execute ERC1155_TO_ERC20_PARTIAL_OPEN, // 22: no partial fills, only offerer or zone can execute ERC1155_TO_ERC20_FULL_RESTRICTED, // 23: partial fills supported, only offerer or zone can execute ERC1155_TO_ERC20_PARTIAL_RESTRICTED } /** * @dev The full set of order components, with the exception of the counter, * must be supplied when fulfilling more sophisticated orders or groups of * orders. The total number of original consideration items must also be * supplied, as the caller may specify additional consideration items. */ struct OrderParameters { address offerer; // 0x00 address zone; // 0x20 OfferItem[] offer; // 0x40 ConsiderationItem[] consideration; // 0x60 OrderType orderType; // 0x80 uint256 startTime; // 0xa0 uint256 endTime; // 0xc0 bytes32 zoneHash; // 0xe0 uint256 salt; // 0x100 bytes32 conduitKey; // 0x120 uint256 totalOriginalConsiderationItems; // 0x140 // offer.length // 0x160 } /** * @dev Orders require a signature in addition to the other order parameters. */ struct Order { OrderParameters parameters; bytes signature; } struct AdvancedOrder { OrderParameters parameters; uint120 numerator; uint120 denominator; bytes signature; bytes extraData; } struct OfferItem { ItemType itemType; address token; uint256 identifierOrCriteria; uint256 startAmount; uint256 endAmount; } /** * @dev A consideration item has the same five components as an offer item and * an additional sixth component designating the required recipient of the * item. */ struct ConsiderationItem { ItemType itemType; address token; uint256 identifierOrCriteria; uint256 startAmount; uint256 endAmount; address payable recipient; } // prettier-ignore enum OrderType { // 0: no partial fills, anyone can execute FULL_OPEN, // 1: partial fills supported, anyone can execute PARTIAL_OPEN, // 2: no partial fills, only offerer or zone can execute FULL_RESTRICTED, // 3: partial fills supported, only offerer or zone can execute PARTIAL_RESTRICTED } // prettier-ignore enum ItemType { // 0: ETH on mainnet, MATIC on polygon, etc. NATIVE, // 1: ERC20 items (ERC777 and ERC20 analogues could also technically work) ERC20, // 2: ERC721 items ERC721, // 3: ERC1155 items ERC1155, // 4: ERC721 items where a number of tokenIds are supported ERC721_WITH_CRITERIA, // 5: ERC1155 items where a number of ids are supported ERC1155_WITH_CRITERIA } /** * @dev A fulfillment is applied to a group of orders. It decrements a series of * offer and consideration items, then generates a single execution * element. A given fulfillment can be applied to as many offer and * consideration items as desired, but must contain at least one offer and * at least one consideration that match. The fulfillment must also remain * consistent on all key parameters across all offer items (same offerer, * token, type, tokenId, and conduit preference) as well as across all * consideration items (token, type, tokenId, and recipient). */ struct Fulfillment { FulfillmentComponent[] offerComponents; FulfillmentComponent[] considerationComponents; } /** * @dev Each fulfillment component contains one index referencing a specific * order and another referencing a specific offer or consideration item. */ struct FulfillmentComponent { uint256 orderIndex; uint256 itemIndex; } /** * @dev An execution is triggered once all consideration items have been zeroed * out. It sends the item in question from the offerer to the item's * recipient, optionally sourcing approvals from either this contract * directly or from the offerer's chosen conduit if one is specified. An * execution is not provided as an argument, but rather is derived via * orders, criteria resolvers, and fulfillments (where the total number of * executions will be less than or equal to the total number of indicated * fulfillments) and returned as part of `matchOrders`. */ struct Execution { ReceivedItem item; address offerer; bytes32 conduitKey; } /** * @dev A received item is translated from a utilized consideration item and has * the same four components as a spent item, as well as an additional fifth * component designating the required recipient of the item. */ struct ReceivedItem { ItemType itemType; address token; uint256 identifier; uint256 amount; address payable recipient; } struct CriteriaResolver { uint256 orderIndex; Side side; uint256 index; uint256 identifier; bytes32[] criteriaProof; } // prettier-ignore enum Side { // 0: Items that can be spent OFFER, // 1: Items that must be received CONSIDERATION } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; library LibLooksRare { struct MakerOrder { bool isOrderAsk; // true --> ask / false --> bid address signer; // signer of the maker order address collection; // collection address uint256 price; // price (used as ) uint256 tokenId; // id of the token uint256 amount; // amount of tokens to sell/purchase (must be 1 for ERC721, 1+ for ERC1155) address strategy; // strategy for trade execution (e.g., DutchAuction, StandardSaleForFixedPrice) address currency; // currency (e.g., WETH) uint256 nonce; // order nonce (must be unique unless new maker order is meant to override existing one e.g., lower ask price) uint256 startTime; // startTime in timestamp uint256 endTime; // endTime in timestamp uint256 minPercentageToAsk; // slippage protection (9000 --> 90% of the final price must return to ask) bytes params; // additional parameters uint8 v; // v: parameter (27 or 28) bytes32 r; // r: parameter bytes32 s; // s: parameter } struct TakerOrder { bool isOrderAsk; // true --> ask / false --> bid address taker; // msg.sender uint256 price; // final price for the purchase uint256 tokenId; uint256 minPercentageToAsk; // // slippage protection (9000 --> 90% of the final price must return to ask) bytes params; // other params (e.g., tokenId) } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "@openzeppelin/contracts/access/Ownable.sol"; abstract contract IsPausable is Ownable { bool public paused; event Paused(bool paused); function pause(bool _paused) external onlyOwner { paused = _paused; emit Paused(_paused); } function requireNotPaused() internal view { require (!paused, "the contract is paused"); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.9 <0.8.0; pragma abicoder v2; interface Ix2y2 { struct OrderItem { uint256 price; bytes data; } struct Pair721 { address token; uint256 tokenId; } struct Pair1155 { address token; uint256 tokenId; uint256 amount; } struct Order { uint256 salt; address user; uint256 network; uint256 intent; uint256 delegateType; uint256 deadline; address currency; bytes dataMask; OrderItem[] items; // signature bytes32 r; bytes32 s; uint8 v; uint8 signVersion; } struct Fee { uint256 percentage; address to; } struct SettleDetail { Op op; uint256 orderIdx; uint256 itemIdx; uint256 price; bytes32 itemHash; address executionDelegate; bytes dataReplacement; uint256 bidIncentivePct; uint256 aucMinIncrementPct; uint256 aucIncDurationSecs; Fee[] fees; } struct SettleShared { uint256 salt; uint256 deadline; uint256 amountToEth; uint256 amountToWeth; address user; bool canFail; } struct RunInput { Order[] orders; SettleDetail[] details; SettleShared shared; // signature bytes32 r; bytes32 s; uint8 v; } enum Op { INVALID, // off-chain COMPLETE_SELL_OFFER, COMPLETE_BUY_OFFER, CANCEL_OFFER, // auction BID, COMPLETE_AUCTION, REFUND_AUCTION, REFUND_AUCTION_STUCK_ITEM } function run(RunInput memory input) external payable; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.9 <0.8.0; pragma abicoder v2; interface IWyvernExchange { function atomicMatch_( address[14] memory addrs, uint[18] memory uints, uint8[8] memory feeMethodsSidesKindsHowToCalls, bytes memory calldataBuy, bytes memory calldataSell, bytes memory replacementPatternBuy, bytes memory replacementPatternSell, bytes memory staticExtradataBuy, bytes memory staticExtradataSell, uint8[2] memory vs, bytes32[5] memory rssMetadata) external payable; enum Side { Buy, Sell } enum SaleKind { FixedPrice, DutchAuction } function calculateFinalPrice( Side side, SaleKind saleKind, uint256 basePrice, uint256 extra, uint256 listingTime, uint256 expirationTime ) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.9 <0.8.0; pragma abicoder v2; import "../libraries/LibSeaPort.sol"; interface ISeaPort { function fulfillAdvancedOrder( LibSeaPort.AdvancedOrder calldata advancedOrder, LibSeaPort.CriteriaResolver[] calldata criteriaResolvers, bytes32 fulfillerConduitKey, address recipient ) external payable returns (bool fulfilled); function fulfillAvailableAdvancedOrders( LibSeaPort.AdvancedOrder[] memory advancedOrders, LibSeaPort.CriteriaResolver[] calldata criteriaResolvers, LibSeaPort.FulfillmentComponent[][] calldata offerFulfillments, LibSeaPort.FulfillmentComponent[][] calldata considerationFulfillments, bytes32 fulfillerConduitKey, address recipient, uint256 maximumFulfilled ) external payable returns (bool[] memory availableOrders, LibSeaPort.Execution[] memory executions); function fulfillBasicOrder(LibSeaPort.BasicOrderParameters calldata parameters) external payable returns (bool fulfilled); }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import "../libraries/LibLooksRare.sol"; interface ILooksRare { function matchAskWithTakerBidUsingETHAndWETH( LibLooksRare.TakerOrder calldata takerBid, LibLooksRare.MakerOrder calldata makerAsk ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.9 <0.8.0; pragma abicoder v2; import "@rarible/exchange-v2/contracts/ExchangeV2.sol"; import {RoyaltiesRegistry} from "@rarible/royalties-registry/contracts/RoyaltiesRegistry.sol"; import {TransferProxy} from "@rarible/transfer-proxy/contracts/proxy/TransferProxy.sol"; import {ERC20TransferProxy} from "@rarible/transfer-proxy/contracts/proxy/ERC20TransferProxy.sol"; interface IExchangeV2 { function matchOrders( LibOrder.Order memory orderLeft, bytes memory signatureLeft, LibOrder.Order memory orderRight, bytes memory signatureRight ) external payable; function directPurchase( LibDirectTransfer.Purchase calldata direct ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import "@rarible/lib-part/contracts/LibPart.sol"; library LibOrderDataV3 { bytes4 constant public V3_SELL = bytes4(keccak256("V3_SELL")); bytes4 constant public V3_BUY = bytes4(keccak256("V3_BUY")); struct DataV3_SELL { uint payouts; uint originFeeFirst; uint originFeeSecond; uint maxFeesBasePoint; bytes32 marketplaceMarker; } struct DataV3_BUY { uint payouts; uint originFeeFirst; uint originFeeSecond; bytes32 marketplaceMarker; } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import "@rarible/lib-part/contracts/LibPart.sol"; library LibOrderDataV2 { bytes4 constant public V2 = bytes4(keccak256("V2")); struct DataV2 { LibPart.Part[] payouts; LibPart.Part[] originFees; bool isMakeFill; } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import "@rarible/lib-part/contracts/LibPart.sol"; library LibOrderDataV1 { bytes4 constant public V1 = bytes4(keccak256("V1")); struct DataV1 { LibPart.Part[] payouts; LibPart.Part[] originFees; } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import "./LibOrder.sol"; library LibOrderData { struct GenericOrderData { LibPart.Part[] payouts; LibPart.Part[] originFees; bool isMakeFill; uint maxFeesBasePoint; } function parse(LibOrder.Order memory order) pure internal returns (GenericOrderData memory dataOrder) { if (order.dataType == LibOrderDataV1.V1) { LibOrderDataV1.DataV1 memory data = abi.decode(order.data, (LibOrderDataV1.DataV1)); dataOrder.payouts = data.payouts; dataOrder.originFees = data.originFees; } else if (order.dataType == LibOrderDataV2.V2) { LibOrderDataV2.DataV2 memory data = abi.decode(order.data, (LibOrderDataV2.DataV2)); dataOrder.payouts = data.payouts; dataOrder.originFees = data.originFees; dataOrder.isMakeFill = data.isMakeFill; } else if (order.dataType == LibOrderDataV3.V3_SELL) { LibOrderDataV3.DataV3_SELL memory data = abi.decode(order.data, (LibOrderDataV3.DataV3_SELL)); dataOrder.payouts = parsePayouts(data.payouts); dataOrder.originFees = parseOriginFeeData(data.originFeeFirst, data.originFeeSecond); dataOrder.isMakeFill = true; dataOrder.maxFeesBasePoint = data.maxFeesBasePoint; } else if (order.dataType == LibOrderDataV3.V3_BUY) { LibOrderDataV3.DataV3_BUY memory data = abi.decode(order.data, (LibOrderDataV3.DataV3_BUY)); dataOrder.payouts = parsePayouts(data.payouts); dataOrder.originFees = parseOriginFeeData(data.originFeeFirst, data.originFeeSecond); dataOrder.isMakeFill = false; } else if (order.dataType == 0xffffffff) { } else { revert("Unknown Order data type"); } if (dataOrder.payouts.length == 0) { dataOrder.payouts = payoutSet(order.maker); } } function payoutSet(address orderAddress) pure internal returns (LibPart.Part[] memory) { LibPart.Part[] memory payout = new LibPart.Part[](1); payout[0].account = payable(orderAddress); payout[0].value = 10000; return payout; } function parseOriginFeeData(uint dataFirst, uint dataSecond) internal pure returns(LibPart.Part[] memory) { LibPart.Part[] memory originFee; if (dataFirst > 0 && dataSecond > 0){ originFee = new LibPart.Part[](2); originFee[0] = uintToLibPart(dataFirst); originFee[1] = uintToLibPart(dataSecond); } if (dataFirst > 0 && dataSecond == 0) { originFee = new LibPart.Part[](1); originFee[0] = uintToLibPart(dataFirst); } if (dataFirst == 0 && dataSecond > 0) { originFee = new LibPart.Part[](1); originFee[0] = uintToLibPart(dataSecond); } return originFee; } function parsePayouts(uint data) internal pure returns(LibPart.Part[] memory) { LibPart.Part[] memory payouts; if (data > 0) { payouts = new LibPart.Part[](1); payouts[0] = uintToLibPart(data); } return payouts; } /** @notice converts uint to LibPart.Part @param data address and value encoded in uint (first 12 bytes ) @return result LibPart.Part */ function uintToLibPart(uint data) internal pure returns(LibPart.Part memory result) { if (data > 0){ result.account = payable(address(data)); result.value = uint96(data >> 160); } } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "@rarible/lib-asset/contracts/LibAsset.sol"; import "./LibMath.sol"; import "./LibOrderDataV3.sol"; import "./LibOrderDataV2.sol"; import "./LibOrderDataV1.sol"; library LibOrder { using SafeMathUpgradeable for uint; bytes32 constant ORDER_TYPEHASH = keccak256( "Order(address maker,Asset makeAsset,address taker,Asset takeAsset,uint256 salt,uint256 start,uint256 end,bytes4 dataType,bytes data)Asset(AssetType assetType,uint256 value)AssetType(bytes4 assetClass,bytes data)" ); bytes4 constant DEFAULT_ORDER_TYPE = 0xffffffff; struct Order { address maker; LibAsset.Asset makeAsset; address taker; LibAsset.Asset takeAsset; uint salt; uint start; uint end; bytes4 dataType; bytes data; } function calculateRemaining(Order memory order, uint fill, bool isMakeFill) internal pure returns (uint makeValue, uint takeValue) { if (isMakeFill){ makeValue = order.makeAsset.value.sub(fill); takeValue = LibMath.safeGetPartialAmountFloor(order.takeAsset.value, order.makeAsset.value, makeValue); } else { takeValue = order.takeAsset.value.sub(fill); makeValue = LibMath.safeGetPartialAmountFloor(order.makeAsset.value, order.takeAsset.value, takeValue); } } function hashKey(Order memory order) internal pure returns (bytes32) { if (order.dataType == LibOrderDataV1.V1 || order.dataType == DEFAULT_ORDER_TYPE) { return keccak256(abi.encode( order.maker, LibAsset.hash(order.makeAsset.assetType), LibAsset.hash(order.takeAsset.assetType), order.salt )); } else { //order.data is in hash for V2, V3 and all new order return keccak256(abi.encode( order.maker, LibAsset.hash(order.makeAsset.assetType), LibAsset.hash(order.takeAsset.assetType), order.salt, order.data )); } } function hash(Order memory order) internal pure returns (bytes32) { return keccak256(abi.encode( ORDER_TYPEHASH, order.maker, LibAsset.hash(order.makeAsset), order.taker, LibAsset.hash(order.takeAsset), order.salt, order.start, order.end, order.dataType, keccak256(order.data) )); } function validateOrderTime(LibOrder.Order memory order) internal view { require(order.start == 0 || order.start < block.timestamp, "Order start validation failed"); require(order.end == 0 || order.end > block.timestamp, "Order end validation failed"); } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; library LibMath { using SafeMathUpgradeable for uint; /// @dev Calculates partial value given a numerator and denominator rounded down. /// Reverts if rounding error is >= 0.1% /// @param numerator Numerator. /// @param denominator Denominator. /// @param target Value to calculate partial of. /// @return partialAmount value of target rounded down. function safeGetPartialAmountFloor( uint256 numerator, uint256 denominator, uint256 target ) internal pure returns (uint256 partialAmount) { if (isRoundingErrorFloor(numerator, denominator, target)) { revert("rounding error"); } partialAmount = numerator.mul(target).div(denominator); } /// @dev Checks if rounding error >= 0.1% when rounding down. /// @param numerator Numerator. /// @param denominator Denominator. /// @param target Value to multiply with numerator/denominator. /// @return isError Rounding error is present. function isRoundingErrorFloor( uint256 numerator, uint256 denominator, uint256 target ) internal pure returns (bool isError) { if (denominator == 0) { revert("division by zero"); } // The absolute rounding error is the difference between the rounded // value and the ideal value. The relative rounding error is the // absolute rounding error divided by the absolute value of the // ideal value. This is undefined when the ideal value is zero. // // The ideal value is `numerator * target / denominator`. // Let's call `numerator * target % denominator` the remainder. // The absolute error is `remainder / denominator`. // // When the ideal value is zero, we require the absolute error to // be zero. Fortunately, this is always the case. The ideal value is // zero iff `numerator == 0` and/or `target == 0`. In this case the // remainder and absolute error are also zero. if (target == 0 || numerator == 0) { return false; } // Otherwise, we want the relative rounding error to be strictly // less than 0.1%. // The relative error is `remainder / (numerator * target)`. // We want the relative error less than 1 / 1000: // remainder / (numerator * target) < 1 / 1000 // or equivalently: // 1000 * remainder < numerator * target // so we have a rounding error iff: // 1000 * remainder >= numerator * target uint256 remainder = mulmod( target, numerator, denominator ); isError = remainder.mul(1000) >= numerator.mul(target); } function safeGetPartialAmountCeil( uint256 numerator, uint256 denominator, uint256 target ) internal pure returns (uint256 partialAmount) { if (isRoundingErrorCeil(numerator, denominator, target)) { revert("rounding error"); } partialAmount = numerator.mul(target).add(denominator.sub(1)).div(denominator); } /// @dev Checks if rounding error >= 0.1% when rounding up. /// @param numerator Numerator. /// @param denominator Denominator. /// @param target Value to multiply with numerator/denominator. /// @return isError Rounding error is present. function isRoundingErrorCeil( uint256 numerator, uint256 denominator, uint256 target ) internal pure returns (bool isError) { if (denominator == 0) { revert("division by zero"); } // See the comments in `isRoundingError`. if (target == 0 || numerator == 0) { // When either is zero, the ideal value and rounded value are zero // and there is no rounding error. (Although the relative error // is undefined.) return false; } // Compute remainder as before uint256 remainder = mulmod( target, numerator, denominator ); remainder = denominator.sub(remainder) % denominator; isError = remainder.mul(1000) >= numerator.mul(target); return isError; } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "./LibOrder.sol"; library LibFill { struct FillResult { uint leftValue; uint rightValue; } struct IsMakeFill { bool leftMake; bool rightMake; } /** * @dev Should return filled values * @param leftOrder left order * @param rightOrder right order * @param leftOrderFill current fill of the left order (0 if order is unfilled) * @param rightOrderFill current fill of the right order (0 if order is unfilled) * @param leftIsMakeFill true if left orders fill is calculated from the make side, false if from the take side * @param rightIsMakeFill true if right orders fill is calculated from the make side, false if from the take side */ function fillOrder(LibOrder.Order memory leftOrder, LibOrder.Order memory rightOrder, uint leftOrderFill, uint rightOrderFill, bool leftIsMakeFill, bool rightIsMakeFill) internal pure returns (FillResult memory) { (uint leftMakeValue, uint leftTakeValue) = LibOrder.calculateRemaining(leftOrder, leftOrderFill, leftIsMakeFill); (uint rightMakeValue, uint rightTakeValue) = LibOrder.calculateRemaining(rightOrder, rightOrderFill, rightIsMakeFill); //We have 3 cases here: if (rightTakeValue > leftMakeValue) { //1nd: left order should be fully filled return fillLeft(leftMakeValue, leftTakeValue, rightOrder.makeAsset.value, rightOrder.takeAsset.value); }//2st: right order should be fully filled or 3d: both should be fully filled if required values are the same return fillRight(leftOrder.makeAsset.value, leftOrder.takeAsset.value, rightMakeValue, rightTakeValue); } function fillRight(uint leftMakeValue, uint leftTakeValue, uint rightMakeValue, uint rightTakeValue) internal pure returns (FillResult memory result) { uint makerValue = LibMath.safeGetPartialAmountFloor(rightTakeValue, leftMakeValue, leftTakeValue); require(makerValue <= rightMakeValue, "fillRight: unable to fill"); return FillResult(rightTakeValue, makerValue); } function fillLeft(uint leftMakeValue, uint leftTakeValue, uint rightMakeValue, uint rightTakeValue) internal pure returns (FillResult memory result) { uint rightTake = LibMath.safeGetPartialAmountFloor(leftTakeValue, rightMakeValue, rightTakeValue); require(rightTake <= leftMakeValue, "fillLeft: unable to fill"); return FillResult(leftMakeValue, leftTakeValue); } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "@rarible/lib-asset/contracts/LibAsset.sol"; library LibDirectTransfer { //LibDirectTransfers /*All buy parameters need for create buyOrder and sellOrder*/ struct Purchase { address sellOrderMaker; // uint256 sellOrderNftAmount; bytes4 nftAssetClass; bytes nftData; uint256 sellOrderPaymentAmount; address paymentToken; uint256 sellOrderSalt; uint sellOrderStart; uint sellOrderEnd; bytes4 sellOrderDataType; bytes sellOrderData; bytes sellOrderSignature; uint256 buyOrderPaymentAmount; uint256 buyOrderNftAmount; bytes buyOrderData; } /*All accept bid parameters need for create buyOrder and sellOrder*/ struct AcceptBid { address bidMaker; // uint256 bidNftAmount; bytes4 nftAssetClass; bytes nftData; uint256 bidPaymentAmount; address paymentToken; uint256 bidSalt; uint bidStart; uint bidEnd; bytes4 bidDataType; bytes bidData; bytes bidSignature; uint256 sellOrderPaymentAmount; uint256 sellOrderNftAmount; bytes sellOrderData; } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "./libraries/LibOrder.sol"; import "@rarible/lib-signature/contracts/IERC1271.sol"; import "@rarible/lib-signature/contracts/LibSignature.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/drafts/EIP712Upgradeable.sol"; abstract contract OrderValidator is Initializable, ContextUpgradeable, EIP712Upgradeable { using LibSignature for bytes32; using AddressUpgradeable for address; bytes4 constant internal MAGICVALUE = 0x1626ba7e; function __OrderValidator_init_unchained() internal initializer { __EIP712_init_unchained("Exchange", "2"); } function validate(LibOrder.Order memory order, bytes memory signature) internal view { if (order.salt == 0) { if (order.maker != address(0)) { require(_msgSender() == order.maker, "maker is not tx sender"); } } else { if (_msgSender() != order.maker) { bytes32 hash = LibOrder.hash(order); // if maker is contract checking ERC1271 signature if (order.maker.isContract()) { require( IERC1271(order.maker).isValidSignature(_hashTypedDataV4(hash), signature) == MAGICVALUE, "contract order signature verification error" ); } else { // if maker is not contract then checking ECDSA signature if (_hashTypedDataV4(hash).recover(signature) != order.maker) { revert("order signature verification error"); } else { require (order.maker != address(0), "no maker"); } } } } } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import "./libraries/LibFill.sol"; import "./libraries/LibOrderData.sol"; import "./libraries/LibDirectTransfer.sol"; import "./OrderValidator.sol"; import "./AssetMatcher.sol"; import "@rarible/transfer-manager/contracts/TransferExecutor.sol"; import "@rarible/transfer-manager/contracts/interfaces/ITransferManager.sol"; import "@rarible/transfer-manager/contracts/lib/LibDeal.sol"; abstract contract ExchangeV2Core is Initializable, OwnableUpgradeable, AssetMatcher, TransferExecutor, OrderValidator, ITransferManager { using SafeMathUpgradeable for uint; using LibTransfer for address; uint256 private constant UINT256_MAX = type(uint256).max; //state of the orders mapping(bytes32 => uint) public fills; //events event Cancel(bytes32 hash); event Match(bytes32 leftHash, bytes32 rightHash, uint newLeftFill, uint newRightFill); function cancel(LibOrder.Order memory order) external { require(_msgSender() == order.maker, "not a maker"); require(order.salt != 0, "0 salt can't be used"); bytes32 orderKeyHash = LibOrder.hashKey(order); fills[orderKeyHash] = UINT256_MAX; emit Cancel(orderKeyHash); } /** * @dev function, generate sellOrder and buyOrder from parameters and call validateAndMatch() for purchase transaction */ function directPurchase( LibDirectTransfer.Purchase calldata direct ) external payable{ LibAsset.AssetType memory paymentAssetType = getPaymentAssetType(direct.paymentToken); LibOrder.Order memory sellOrder = LibOrder.Order( direct.sellOrderMaker, LibAsset.Asset( LibAsset.AssetType( direct.nftAssetClass, direct.nftData ), direct.sellOrderNftAmount ), address(0), LibAsset.Asset( paymentAssetType, direct.sellOrderPaymentAmount ), direct.sellOrderSalt, direct.sellOrderStart, direct.sellOrderEnd, direct.sellOrderDataType, direct.sellOrderData ); LibOrder.Order memory buyOrder = LibOrder.Order( address(0), LibAsset.Asset( paymentAssetType, direct.buyOrderPaymentAmount ), address(0), LibAsset.Asset( LibAsset.AssetType( direct.nftAssetClass, direct.nftData ), direct.buyOrderNftAmount ), 0, 0, 0, getOtherOrderType(direct.sellOrderDataType), direct.buyOrderData ); validateFull(sellOrder, direct.sellOrderSignature); matchAndTransfer(sellOrder, buyOrder); } /** * @dev function, generate sellOrder and buyOrder from parameters and call validateAndMatch() for accept bid transaction * @param direct struct with parameters for accept bid operation */ function directAcceptBid( LibDirectTransfer.AcceptBid calldata direct ) external payable { LibAsset.AssetType memory paymentAssetType = getPaymentAssetType(direct.paymentToken); LibOrder.Order memory buyOrder = LibOrder.Order( direct.bidMaker, LibAsset.Asset( paymentAssetType, direct.bidPaymentAmount ), address(0), LibAsset.Asset( LibAsset.AssetType( direct.nftAssetClass, direct.nftData ), direct.bidNftAmount ), direct.bidSalt, direct.bidStart, direct.bidEnd, direct.bidDataType, direct.bidData ); LibOrder.Order memory sellOrder = LibOrder.Order( address(0), LibAsset.Asset( LibAsset.AssetType( direct.nftAssetClass, direct.nftData ), direct.sellOrderNftAmount ), address(0), LibAsset.Asset( paymentAssetType, direct.sellOrderPaymentAmount ), 0, 0, 0, getOtherOrderType(direct.bidDataType), direct.sellOrderData ); validateFull(buyOrder, direct.bidSignature); matchAndTransfer(sellOrder, buyOrder); } function matchOrders( LibOrder.Order memory orderLeft, bytes memory signatureLeft, LibOrder.Order memory orderRight, bytes memory signatureRight ) external payable { validateOrders(orderLeft, signatureLeft, orderRight, signatureRight); matchAndTransfer(orderLeft, orderRight); } /** * @dev function, validate orders * @param orderLeft left order * @param signatureLeft order left signature * @param orderRight right order * @param signatureRight order right signature */ function validateOrders(LibOrder.Order memory orderLeft, bytes memory signatureLeft, LibOrder.Order memory orderRight, bytes memory signatureRight) internal view { validateFull(orderLeft, signatureLeft); validateFull(orderRight, signatureRight); if (orderLeft.taker != address(0)) { if (orderRight.maker != address(0)) require(orderRight.maker == orderLeft.taker, "leftOrder.taker verification failed"); } if (orderRight.taker != address(0)) { if (orderLeft.maker != address(0)) require(orderRight.taker == orderLeft.maker, "rightOrder.taker verification failed"); } } /** @notice matches valid orders and transfers their assets @param orderLeft the left order of the match @param orderRight the right order of the match */ function matchAndTransfer(LibOrder.Order memory orderLeft, LibOrder.Order memory orderRight) internal { (LibAsset.AssetType memory makeMatch, LibAsset.AssetType memory takeMatch) = matchAssets(orderLeft, orderRight); (LibOrderData.GenericOrderData memory leftOrderData, LibOrderData.GenericOrderData memory rightOrderData, LibFill.FillResult memory newFill) = parseOrdersSetFillEmitMatch(orderLeft, orderRight); (uint totalMakeValue, uint totalTakeValue) = doTransfers( LibDeal.DealSide({ asset: LibAsset.Asset({ assetType: makeMatch, value: newFill.leftValue }), payouts: leftOrderData.payouts, originFees: leftOrderData.originFees, proxy: proxies[makeMatch.assetClass], from: orderLeft.maker }), LibDeal.DealSide({ asset: LibAsset.Asset( takeMatch, newFill.rightValue ), payouts: rightOrderData.payouts, originFees: rightOrderData.originFees, proxy: proxies[takeMatch.assetClass], from: orderRight.maker }), getDealData( makeMatch.assetClass, takeMatch.assetClass, orderLeft.dataType, orderRight.dataType, leftOrderData, rightOrderData ) ); if (makeMatch.assetClass == LibAsset.ETH_ASSET_CLASS) { require(takeMatch.assetClass != LibAsset.ETH_ASSET_CLASS); require(msg.value >= totalMakeValue, "not enough eth"); if (msg.value > totalMakeValue) { address(msg.sender).transferEth(msg.value.sub(totalMakeValue)); } } else if (takeMatch.assetClass == LibAsset.ETH_ASSET_CLASS) { require(msg.value >= totalTakeValue, "not enough eth"); if (msg.value > totalTakeValue) { address(msg.sender).transferEth(msg.value.sub(totalTakeValue)); } } } function parseOrdersSetFillEmitMatch( LibOrder.Order memory orderLeft, LibOrder.Order memory orderRight ) internal returns (LibOrderData.GenericOrderData memory leftOrderData, LibOrderData.GenericOrderData memory rightOrderData, LibFill.FillResult memory newFill) { bytes32 leftOrderKeyHash = LibOrder.hashKey(orderLeft); bytes32 rightOrderKeyHash = LibOrder.hashKey(orderRight); address msgSender = _msgSender(); if (orderLeft.maker == address(0)) { orderLeft.maker = msgSender; } if (orderRight.maker == address(0)) { orderRight.maker = msgSender; } leftOrderData = LibOrderData.parse(orderLeft); rightOrderData = LibOrderData.parse(orderRight); newFill = setFillEmitMatch( orderLeft, orderRight, leftOrderKeyHash, rightOrderKeyHash, leftOrderData.isMakeFill, rightOrderData.isMakeFill ); } function getDealData( bytes4 makeMatchAssetClass, bytes4 takeMatchAssetClass, bytes4 leftDataType, bytes4 rightDataType, LibOrderData.GenericOrderData memory leftOrderData, LibOrderData.GenericOrderData memory rightOrderData ) internal pure returns(LibDeal.DealData memory dealData) { dealData.feeSide = LibFeeSide.getFeeSide(makeMatchAssetClass, takeMatchAssetClass); dealData.maxFeesBasePoint = getMaxFee( leftDataType, rightDataType, leftOrderData, rightOrderData, dealData.feeSide ); } /** @notice determines the max amount of fees for the match @param dataTypeLeft data type of the left order @param dataTypeRight data type of the right order @param leftOrderData data of the left order @param rightOrderData data of the right order @param feeSide fee side of the match @return max fee amount in base points */ function getMaxFee( bytes4 dataTypeLeft, bytes4 dataTypeRight, LibOrderData.GenericOrderData memory leftOrderData, LibOrderData.GenericOrderData memory rightOrderData, LibFeeSide.FeeSide feeSide ) internal pure returns(uint) { if ( dataTypeLeft != LibOrderDataV3.V3_SELL && dataTypeRight != LibOrderDataV3.V3_SELL && dataTypeLeft != LibOrderDataV3.V3_BUY && dataTypeRight != LibOrderDataV3.V3_BUY ){ return 0; } uint matchFees = getSumFees(leftOrderData.originFees, rightOrderData.originFees); uint maxFee; if (feeSide == LibFeeSide.FeeSide.LEFT) { maxFee = rightOrderData.maxFeesBasePoint; require( dataTypeLeft == LibOrderDataV3.V3_BUY && dataTypeRight == LibOrderDataV3.V3_SELL, "wrong V3 type1" ); } else if (feeSide == LibFeeSide.FeeSide.RIGHT) { maxFee = leftOrderData.maxFeesBasePoint; require( dataTypeRight == LibOrderDataV3.V3_BUY && dataTypeLeft == LibOrderDataV3.V3_SELL, "wrong V3 type2" ); } else { return 0; } require( maxFee > 0 && maxFee >= matchFees && maxFee <= 1000, "wrong maxFee" ); return maxFee; } /** @notice calculates amount of fees for the match @param originLeft origin fees of the left order @param originRight origin fees of the right order @return sum of all fees for the match (protcolFee + leftOrder.originFees + rightOrder.originFees) */ function getSumFees(LibPart.Part[] memory originLeft, LibPart.Part[] memory originRight) internal pure returns(uint) { uint result = 0; //adding left origin fees for (uint i; i < originLeft.length; i ++) { result = result + originLeft[i].value; } //adding right origin fees for (uint i; i < originRight.length; i ++) { result = result + originRight[i].value; } return result; } /** @notice calculates fills for the matched orders and set them in "fills" mapping @param orderLeft left order of the match @param orderRight right order of the match @param leftMakeFill true if the left orders uses make-side fills, false otherwise @param rightMakeFill true if the right orders uses make-side fills, false otherwise @return returns change in orders' fills by the match */ function setFillEmitMatch( LibOrder.Order memory orderLeft, LibOrder.Order memory orderRight, bytes32 leftOrderKeyHash, bytes32 rightOrderKeyHash, bool leftMakeFill, bool rightMakeFill ) internal returns (LibFill.FillResult memory) { uint leftOrderFill = getOrderFill(orderLeft.salt, leftOrderKeyHash); uint rightOrderFill = getOrderFill(orderRight.salt, rightOrderKeyHash); LibFill.FillResult memory newFill = LibFill.fillOrder(orderLeft, orderRight, leftOrderFill, rightOrderFill, leftMakeFill, rightMakeFill); require(newFill.rightValue > 0 && newFill.leftValue > 0, "nothing to fill"); if (orderLeft.salt != 0) { if (leftMakeFill) { fills[leftOrderKeyHash] = leftOrderFill.add(newFill.leftValue); } else { fills[leftOrderKeyHash] = leftOrderFill.add(newFill.rightValue); } } if (orderRight.salt != 0) { if (rightMakeFill) { fills[rightOrderKeyHash] = rightOrderFill.add(newFill.rightValue); } else { fills[rightOrderKeyHash] = rightOrderFill.add(newFill.leftValue); } } emit Match(leftOrderKeyHash, rightOrderKeyHash, newFill.rightValue, newFill.leftValue); return newFill; } function getOrderFill(uint salt, bytes32 hash) internal view returns (uint fill) { if (salt == 0) { fill = 0; } else { fill = fills[hash]; } } function matchAssets(LibOrder.Order memory orderLeft, LibOrder.Order memory orderRight) internal view returns (LibAsset.AssetType memory makeMatch, LibAsset.AssetType memory takeMatch) { makeMatch = matchAssets(orderLeft.makeAsset.assetType, orderRight.takeAsset.assetType); require(makeMatch.assetClass != 0, "assets don't match"); takeMatch = matchAssets(orderLeft.takeAsset.assetType, orderRight.makeAsset.assetType); require(takeMatch.assetClass != 0, "assets don't match"); } function validateFull(LibOrder.Order memory order, bytes memory signature) internal view { LibOrder.validateOrderTime(order); validate(order, signature); } function getPaymentAssetType(address token) internal pure returns(LibAsset.AssetType memory){ LibAsset.AssetType memory result; if(token == address(0)) { result.assetClass = LibAsset.ETH_ASSET_CLASS; } else { result.assetClass = LibAsset.ERC20_ASSET_CLASS; result.data = abi.encode(token); } return result; } function getOtherOrderType(bytes4 dataType) internal pure returns(bytes4) { if (dataType == LibOrderDataV3.V3_SELL) { return LibOrderDataV3.V3_BUY; } if (dataType == LibOrderDataV3.V3_BUY) { return LibOrderDataV3.V3_SELL; } return dataType; } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import "./ExchangeV2Core.sol"; import "@rarible/transfer-manager/contracts/RaribleTransferManager.sol"; contract ExchangeV2 is ExchangeV2Core, RaribleTransferManager { function __ExchangeV2_init( address _transferProxy, address _erc20TransferProxy, uint newProtocolFee, address newDefaultFeeReceiver, IRoyaltiesProvider newRoyaltiesProvider ) external initializer { __Context_init_unchained(); __Ownable_init_unchained(); __TransferExecutor_init_unchained(_transferProxy, _erc20TransferProxy); __RaribleTransferManager_init_unchained(newProtocolFee, newDefaultFeeReceiver, newRoyaltiesProvider); __OrderValidator_init_unchained(); } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import "@rarible/exchange-interfaces/contracts/IAssetMatcher.sol"; import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; abstract contract AssetMatcher is Initializable, OwnableUpgradeable { bytes constant EMPTY = ""; mapping(bytes4 => address) internal matchers; event MatcherChange(bytes4 indexed assetType, address matcher); function setAssetMatcher(bytes4 assetType, address matcher) external onlyOwner { matchers[assetType] = matcher; emit MatcherChange(assetType, matcher); } function matchAssets(LibAsset.AssetType memory leftAssetType, LibAsset.AssetType memory rightAssetType) internal view returns (LibAsset.AssetType memory) { LibAsset.AssetType memory result = matchAssetOneSide(leftAssetType, rightAssetType); if (result.assetClass == 0) { return matchAssetOneSide(rightAssetType, leftAssetType); } else { return result; } } function matchAssetOneSide(LibAsset.AssetType memory leftAssetType, LibAsset.AssetType memory rightAssetType) private view returns (LibAsset.AssetType memory) { bytes4 classLeft = leftAssetType.assetClass; bytes4 classRight = rightAssetType.assetClass; if (classLeft == LibAsset.ETH_ASSET_CLASS) { if (classRight == LibAsset.ETH_ASSET_CLASS) { return leftAssetType; } return LibAsset.AssetType(0, EMPTY); } if (classLeft == LibAsset.ERC20_ASSET_CLASS) { if (classRight == LibAsset.ERC20_ASSET_CLASS) { return simpleMatch(leftAssetType, rightAssetType); } return LibAsset.AssetType(0, EMPTY); } if (classLeft == LibAsset.ERC721_ASSET_CLASS) { if (classRight == LibAsset.ERC721_ASSET_CLASS) { return simpleMatch(leftAssetType, rightAssetType); } return LibAsset.AssetType(0, EMPTY); } if (classLeft == LibAsset.ERC1155_ASSET_CLASS) { if (classRight == LibAsset.ERC1155_ASSET_CLASS) { return simpleMatch(leftAssetType, rightAssetType); } return LibAsset.AssetType(0, EMPTY); } address matcher = matchers[classLeft]; if (matcher != address(0)) { return IAssetMatcher(matcher).matchAssets(leftAssetType, rightAssetType); } if (classLeft == classRight) { return simpleMatch(leftAssetType, rightAssetType); } revert("not found IAssetMatcher"); } function simpleMatch(LibAsset.AssetType memory leftAssetType, LibAsset.AssetType memory rightAssetType) private pure returns (LibAsset.AssetType memory) { bytes32 leftHash = keccak256(leftAssetType.data); bytes32 rightHash = keccak256(rightAssetType.data); if (leftHash == rightHash) { return leftAssetType; } return LibAsset.AssetType(0, EMPTY); } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.9 <0.8.0; pragma abicoder v2; import "@rarible/lib-asset/contracts/LibAsset.sol"; interface ITransferProxy { function transfer(LibAsset.Asset calldata asset, address from, address to) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; pragma abicoder v2; import "@rarible/lib-part/contracts/LibPart.sol"; interface IRoyaltiesProvider { function getRoyalties(address token, uint tokenId) external returns (LibPart.Part[] memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.9 <0.8.0; pragma abicoder v2; import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol"; interface INftTransferProxy { function erc721safeTransferFrom(IERC721Upgradeable token, address from, address to, uint256 tokenId) external; function erc1155safeTransferFrom(IERC1155Upgradeable token, address from, address to, uint256 id, uint256 value, bytes calldata data) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.9 <0.8.0; pragma abicoder v2; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; interface IERC20TransferProxy { function erc20safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import "@rarible/lib-asset/contracts/LibAsset.sol"; interface IAssetMatcher { function matchAssets( LibAsset.AssetType memory leftAssetType, LibAsset.AssetType memory rightAssetType ) external view returns (LibAsset.AssetType memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <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 GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <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 `IERC721.onERC721Received.selector`. */ function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <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 pragma solidity >=0.6.0 <0.8.0; import "../../introspection/IERC165.sol"; /** * _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. 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. 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 pragma solidity >=0.6.0 <0.8.0; import "./IERC1155Receiver.sol"; import "../../introspection/ERC165.sol"; /** * @dev _Available since v3.1._ */ abstract contract ERC1155Receiver is ERC165, IERC1155Receiver { constructor() internal { _registerInterface( ERC1155Receiver(address(0)).onERC1155Received.selector ^ ERC1155Receiver(address(0)).onERC1155BatchReceived.selector ); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./ERC1155Receiver.sol"; /** * @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 pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <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 pragma solidity >=0.6.0 <0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts may inherit from this and call {_registerInterface} to declare * their support of an interface. */ abstract contract ERC165 is IERC165 { /* * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7 */ bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; /** * @dev Mapping of interface ids to whether or not it's supported. */ mapping(bytes4 => bool) private _supportedInterfaces; constructor () internal { // Derived contracts need only register support for their own interfaces, // we register support for ERC165 itself here _registerInterface(_INTERFACE_ID_ERC165); } /** * @dev See {IERC165-supportsInterface}. * * Time complexity O(1), guaranteed to always use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return _supportedInterfaces[interfaceId]; } /** * @dev Registers the contract as an implementer of the interface defined by * `interfaceId`. Support of the actual ERC165 interface is automatic and * registering its interface id is not required. * * See {IERC165-supportsInterface}. * * Requirements: * * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`). */ function _registerInterface(bytes4 interfaceId) internal virtual { require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); _supportedInterfaces[interfaceId] = true; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <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 () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../proxy/Initializable.sol"; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; import "../../introspection/IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721Upgradeable is IERC165Upgradeable { /** * @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`, 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 be 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 Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @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 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); /** * @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; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; import "../../introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable { /** * @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 be 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 // solhint-disable-next-line compiler-version pragma solidity >=0.4.24 <0.8.0; import "../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || _isConstructor() || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /// @dev Returns true if and only if the function is running in the constructor function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMathUpgradeable { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <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 IERC165Upgradeable { /** * @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 pragma solidity >=0.6.0 <0.8.0; import "../proxy/Initializable.sol"; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * _Available since v3.4._ */ abstract contract EIP712Upgradeable is Initializable { /* solhint-disable var-name-mixedcase */ bytes32 private _HASHED_NAME; bytes32 private _HASHED_VERSION; bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); /* solhint-enable var-name-mixedcase */ /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ function __EIP712_init(string memory name, string memory version) internal initializer { __EIP712_init_unchained(name, version); } function __EIP712_init_unchained(string memory name, string memory version) internal initializer { bytes32 hashedName = keccak256(bytes(name)); bytes32 hashedVersion = keccak256(bytes(version)); _HASHED_NAME = hashedName; _HASHED_VERSION = hashedVersion; } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash()); } function _buildDomainSeparator(bytes32 typeHash, bytes32 name, bytes32 version) private view returns (bytes32) { return keccak256( abi.encode( typeHash, name, version, _getChainId(), address(this) ) ); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", _domainSeparatorV4(), structHash)); } function _getChainId() private view returns (uint256 chainId) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 // solhint-disable-next-line no-inline-assembly assembly { chainId := chainid() } } /** * @dev The hash of the name parameter for the EIP712 domain. * * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs * are a concern. */ function _EIP712NameHash() internal virtual view returns (bytes32) { return _HASHED_NAME; } /** * @dev The hash of the version parameter for the EIP712 domain. * * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs * are a concern. */ function _EIP712VersionHash() internal virtual view returns (bytes32) { return _HASHED_VERSION; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal initializer { __Context_init_unchained(); __Ownable_init_unchained(); } function __Ownable_init_unchained() internal initializer { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } uint256[49] private __gap; }
{ "remappings": [], "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "istanbul", "libraries": {}, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_wyvernExchange","type":"address"},{"internalType":"address","name":"_exchangeV2","type":"address"},{"internalType":"address","name":"_seaPort","type":"address"},{"internalType":"address","name":"_x2y2","type":"address"},{"internalType":"address","name":"_looksRare","type":"address"},{"internalType":"address","name":"_sudoswap","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"result","type":"bool"}],"name":"Execution","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"Paused","type":"event"},{"inputs":[{"components":[{"internalType":"enum RaribleExchangeWrapper.Markets","name":"marketId","type":"uint8"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"fees","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct RaribleExchangeWrapper.PurchaseDetails[]","name":"purchaseDetails","type":"tuple[]"},{"internalType":"address","name":"feeRecipientFirst","type":"address"},{"internalType":"address","name":"feeRecipientSecond","type":"address"},{"internalType":"bool","name":"allowFail","type":"bool"}],"name":"bulkPurchase","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"exchangeV2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"looksRare","outputs":[{"internalType":"address","name":"","type":"address"}],"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":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"seaPort","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"enum RaribleExchangeWrapper.Markets","name":"marketId","type":"uint8"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"fees","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct RaribleExchangeWrapper.PurchaseDetails","name":"purchaseDetails","type":"tuple"},{"internalType":"address","name":"feeRecipientFirst","type":"address"},{"internalType":"address","name":"feeRecipientSecond","type":"address"}],"name":"singlePurchase","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"sudoswap","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wyvernExchange","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"x2y2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6101406040523480156200001257600080fd5b506040516200314638038062003146833981016040819052620000359162000199565b600062000041620000f0565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506200009d6301ffc9a760e01b620000f4565b620000af630271189760e51b620000f4565b6001600160601b0319606096871b811660805294861b851660a05292851b841660c05290841b831660e052831b82166101005290911b166101205262000219565b3390565b6001600160e01b0319808216141562000154576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152600160208190526040909120805460ff19169091179055565b80516001600160a01b03811681146200019457600080fd5b919050565b60008060008060008060c08789031215620001b2578182fd5b620001bd876200017c565b9550620001cd602088016200017c565b9450620001dd604088016200017c565b9350620001ed606088016200017c565b9250620001fd608088016200017c565b91506200020d60a088016200017c565b90509295509295509295565b60805160601c60a05160601c60c05160601c60e05160601c6101005160601c6101205160601c612ea96200029d600039806103dc52806111f252508061056a5280610fc652806110605250806108005280610b6d5280610c0352508061040052806108bb52508061058e5280610a6a5250806106b752806109985250612ea96000f3fe6080604052600436106101025760003560e01c80638da5cb5b11610095578063bc197c8111610064578063bc197c8114610259578063c9f0a2fa14610279578063f23a6e611461028e578063f2fde38b146102ae578063fc40c9c7146102ce57610109565b80638da5cb5b146102075780639110c7771461021c578063a05f32dc14610231578063b94ee3321461024657610109565b80635ea1e4c9116100d15780635ea1e4c9146101a857806362c1a97d146101ca578063715018a6146101df57806386496e7a146101f457610109565b806301ffc9a71461010e57806302329a2914610144578063150b7a02146101665780635c975abb1461019357610109565b3661010957005b600080fd5b34801561011a57600080fd5b5061012e6101293660046122a2565b6102e3565b60405161013b919061287e565b60405180910390f35b34801561015057600080fd5b5061016461015f366004612286565b610306565b005b34801561017257600080fd5b50610186610181366004611f5e565b6103c1565b60405161013b9190612889565b34801561019f57600080fd5b5061012e6103d1565b3480156101b457600080fd5b506101bd6103da565b60405161013b919061280e565b3480156101d657600080fd5b506101bd6103fe565b3480156101eb57600080fd5b50610164610422565b6101646102023660046123b2565b6104e0565b34801561021357600080fd5b506101bd610559565b34801561022857600080fd5b506101bd610568565b34801561023d57600080fd5b506101bd61058c565b6101646102543660046121cb565b6105b0565b34801561026557600080fd5b50610186610274366004611eb5565b6106a4565b34801561028557600080fd5b506101bd6106b5565b34801561029a57600080fd5b506101866102a9366004611fc7565b6106d9565b3480156102ba57600080fd5b506101646102c9366004611e99565b6106ea565b3480156102da57600080fd5b506101bd6107fe565b6001600160e01b0319811660009081526001602052604090205460ff165b919050565b61030e610822565b6001600160a01b031661031f610559565b6001600160a01b03161461037a576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6002805482151560ff19909116811790915560408051918252517f0e2fb031ee032dc02d8011dc50b816eb450cf856abd8261680dac74f72165bd29181900360200190a150565b630a85bd0160e11b949350505050565b60025460ff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b61042a610822565b6001600160a01b031661043b610559565b6001600160a01b031614610496576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6104e8610826565b60008060006104f8866000610879565b9250925092507fcc54b89ca2d75d5612023b14f0a477212b0e08bc0c5b8ad2804e2f8e2e401fc08360405161052d919061287e565b60405180910390a161053f82866112fc565b61054981856112fc565b610551611327565b505050505050565b6000546001600160a01b031690565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b6105b8610826565b6000806000805b87518110156106585760008060006105ea8b85815181106105dc57fe5b602002602001015189610879565b92509250925084806105f95750825b94507fcc54b89ca2d75d5612023b14f0a477212b0e08bc0c5b8ad2804e2f8e2e401fc08360405161062a919061287e565b60405180910390a161063c878361133b565b9650610648868261133b565b95505050508060010190506105bf565b508061067f5760405162461bcd60e51b815260040161067690612a4b565b60405180910390fd5b61068983876112fc565b61069382866112fc565b61069b611327565b50505050505050565b63bc197c8160e01b95945050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b63f23a6e6160e01b95945050505050565b6106f2610822565b6001600160a01b0316610703610559565b6001600160a01b03161461075e576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0381166107a35760405162461bcd60e51b8152600401808060200182810382526026815260200180612e2d6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b7f000000000000000000000000000000000000000000000000000000000000000081565b3390565b60025460ff1615610877576040805162461bcd60e51b81526020600482015260166024820152751d1a194818dbdb9d1c9858dd081a5cc81c185d5cd95960521b604482015290519081900360640190fd5b565b600080600080600061089887606001518860400151896000015161139e565b602089015191935091506002885160058111156108b157fe5b141561097f5760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031682856040516108f291906127f2565b60006040518083038185875af1925050503d806000811461092f576040519150601f19603f3d011682016040523d82523d6000602084013e610934565b606091505b50509050871561095c5780610957576000806000965096509650505050506112f5565b610979565b806109795760405162461bcd60e51b815260040161067690612943565b506112c3565b60018851600581111561098e57fe5b1415610a515760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031682856040516109cf91906127f2565b60006040518083038185875af1925050503d8060008114610a0c576040519150601f19603f3d011682016040523d82523d6000602084013e610a11565b606091505b505090508715610a345780610957576000806000965096509650505050506112f5565b806109795760405162461bcd60e51b81526004016106769061289e565b600088516005811115610a6057fe5b1415610b235760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168285604051610aa191906127f2565b60006040518083038185875af1925050503d8060008114610ade576040519150601f19603f3d011682016040523d82523d6000602084013e610ae3565b606091505b505090508715610b065780610957576000806000965096509650505050506112f5565b806109795760405162461bcd60e51b81526004016106769061290c565b600388516005811115610b3257fe5b1415610f7557600083806020019051810190610b4e9190612413565b90508715610bec5760405163357a150b60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063357a150b908490610ba4908590600401612a82565b6000604051808303818588803b158015610bbd57600080fd5b505af193505050508015610bcf575060015b610be7576000806000965096509650505050506112f5565b610c6d565b60405163357a150b60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063357a150b908490610c3a908590600401612a82565b6000604051808303818588803b158015610c5357600080fd5b505af1158015610c67573d6000803e3d6000fd5b50505050505b60005b816020015151811015610f6e57600082602001518281518110610c8f57fe5b6020026020010151602001519050600083602001518381518110610caf57fe5b6020026020010151604001519050600084600001518381518110610ccf57fe5b602002602001015161010001518281518110610ce757fe5b6020026020010151602001519050600085600001518481518110610d0757fe5b602002602001015160e0015151118015610d3d5750600085602001518581518110610d2e57fe5b602002602001015160c0015151115b15610d8357610d838186602001518681518110610d5657fe5b602002602001015160c0015187600001518681518110610d7257fe5b602002602001015160e00151611457565b8451805184908110610d9157fe5b60200260200101516080015160011415610e6657600081806020019051810190610dbb919061210a565b905060005b8151811015610e5f576000828281518110610dd757fe5b6020026020010151905080600001516001600160a01b03166342842e0e30610dfd610822565b84602001516040518463ffffffff1660e01b8152600401610e2093929190612822565b600060405180830381600087803b158015610e3a57600080fd5b505af1158015610e4e573d6000803e3d6000fd5b505060019093019250610dc0915050565b5050610f60565b8451805184908110610e7457fe5b60200260200101516080015160021415610f4857600081806020019051810190610e9e919061202d565b905060005b8151811015610e5f576000828281518110610eba57fe5b6020026020010151905080600001516001600160a01b031663f242432a30610ee0610822565b846020015185604001516040518563ffffffff1660e01b8152600401610f099493929190612846565b600060405180830381600087803b158015610f2357600080fd5b505af1158015610f37573d6000803e3d6000fd5b505060019093019250610ea3915050565b60405162461bcd60e51b8152600401610676906129b1565b505050806001019050610c70565b50506112c3565b600488516005811115610f8457fe5b14156111d957600080600085806020019051810190610fa391906124db565b925092509250891561104957604051635a72594b60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063b4e4b296908690610fff9087908790600401612c09565b6000604051808303818588803b15801561101857600080fd5b505af19350505050801561102a575060015b6110445760008060009850985098505050505050506112f5565b6110cc565b604051635a72594b60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063b4e4b2969086906110999087908790600401612c09565b6000604051808303818588803b1580156110b257600080fd5b505af11580156110c6573d6000803e3d6000fd5b50505050505b6001600160e01b031981166339d690a360e11b141561115b5781604001516001600160a01b03166342842e0e30611101610822565b85608001516040518463ffffffff1660e01b815260040161112493929190612822565b600060405180830381600087803b15801561113e57600080fd5b505af1158015611152573d6000803e3d6000fd5b505050506111d1565b6001600160e01b0319811663025ceed960e61b14156111b95781604001516001600160a01b031663f242432a30611190610822565b85608001518660a001516040518563ffffffff1660e01b81526004016111249493929190612846565b60405162461bcd60e51b8152600401610676906129e8565b5050506112c3565b6005885160058111156111e857fe5b14156112ab5760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316828560405161122991906127f2565b60006040518083038185875af1925050503d8060008114611266576040519150601f19603f3d011682016040523d82523d6000602084013e61126b565b606091505b50509050871561128e5780610957576000806000965096509650505050506112f5565b806109795760405162461bcd60e51b81526004016106769061297a565b60405162461bcd60e51b8152600401610676906128d5565b6112d18289602001516114e8565b6000806112e68a604001518b60200151611576565b60019950909750955050505050505b9250925092565b60008211801561131457506001600160a01b03811615155b156113235761132381836115a7565b5050565b4780156113385761133833826115a7565b50565b600082820183811015611395576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b6060806000602085901c61ffff1660018111156113b757fe5b9050606060008260018111156113c957fe5b14156113db57869350915061144f9050565b60018260018111156113e957fe5b14156114375760008780602001905181019061140591906122be565b90506114108661163f565b1561142b57806000015181602001519450945050505061144f565b519350915061144f9050565b60405162461bcd60e51b815260040161067690612a14565b935093915050565b815183511461146557600080fd5b805183511461147357600080fd5b60005b83518110156114e25781818151811061148b57fe5b01602001516001600160f81b031916156114da578281815181106114ab57fe5b602001015160f81c60f81b8482815181106114c257fe5b60200101906001600160f81b031916908160001a9053505b600101611476565b50505050565b60005b825181101561157157600083828151811061150257fe5b6020026020010151111561156957600083828151811061151e57fe5b60200260200101519050600060a085848151811061153857fe5b6020026020010151901c90506000611559828661167b90919063ffffffff16565b905061156581846112fc565b5050505b6001016114eb565b505050565b60008061ffff601085901c8116908516611590858361167b565b61159a868361167b565b9350935050509250929050565b6040516000906001600160a01b0384169083908381818185875af1925050503d80600081146115f2576040519150601f19603f3d011682016040523d82523d6000602084013e6115f7565b606091505b5050905080611571576040805162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b604482015290519081900360640190fd5b6000600582600581111561164f57fe5b14806116665750600482600581111561166457fe5b145b1561167357506001610301565b506000919050565b600061139561271061168d8585611693565b906116ec565b6000826116a257506000611398565b828202828482816116af57fe5b04146113955760405162461bcd60e51b8152600401808060200182810382526021815260200180612e536021913960400191505060405180910390fd5b6000808211611742576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161174b57fe5b049392505050565b803561030181612df3565b805161030181612df3565b600082601f830112611779578081fd5b8151602061178e61178983612d89565b612d66565b828152818101908583016040808602880185018910156117ac578687fd5b865b868110156118075781838b0312156117c4578788fd5b81518281018181106001600160401b03821117156117de57fe5b835283518152868401516117f181612df3565b81880152855293850193918101916001016117ae565b509198975050505050505050565b600082601f830112611825578081fd5b8151602061183561178983612d89565b82815281810190858301855b858110156118be5781518801604080601f19838d03011215611861578889fd5b80518181016001600160401b03828210818311171561187c57fe5b818452848a01518352928401519280841115611896578b8cfd5b50506118a68c8984860101611c09565b81890152865250509284019290840190600101611841565b5090979650505050505050565b600082601f8301126118db578081fd5b815160206118eb61178983612d89565b82815281810190858301855b858110156118be57815188016101a080601f19838d03011215611918578889fd5b61192181612d66565b8783015181526119336040840161175e565b88820152606083015160408201526080830151606082015260a0830151608082015260c083015160a082015261196b60e0840161175e565b60c08201526101008301516001600160401b038082111561198a578b8cfd5b6119988e8b84880101611c09565b60e0840152610120915081850151818111156119b2578c8dfd5b6119c08f8c83890101611815565b6101008501525050610140808501518284015261016091508185015181840152506101806119ef818601611e88565b828401526119fe848601611e88565b90830152508652505092840192908401906001016118f7565b600082601f830112611a27578081fd5b81516020611a3761178983612d89565b82815281810190858301855b858110156118be578151880161016080601f19838d03011215611a64578889fd5b611a6d81612d66565b611a78888401611c54565b815260408301518882015260608301516040820152608080840151606083015260a0808501518284015260c09150611ab182860161175e565b9083015260e08401516001600160401b0380821115611ace578c8dfd5b611adc8f8c84890101611c09565b8385015261010092508286015160e0850152610120915081860151838501526101409250828601518285015284860151945080851115611b1a578c8dfd5b5050611b2a8d8a85870101611769565b90820152865250509284019290840190600101611a43565b600082601f830112611b52578081fd5b81356020611b6261178983612d89565b8281528181019085830183850287018401881015611b7e578586fd5b855b858110156118be57813584529284019290840190600101611b80565b803561030181612e08565b805161030181612e08565b805161030181612e16565b600082601f830112611bcd578081fd5b8135611bdb61178982612da6565b818152846020838601011115611bef578283fd5b816020850160208301379081016020019190915292915050565b600082601f830112611c19578081fd5b8151611c2761178982612da6565b818152846020838601011115611c3b578283fd5b611c4c826020830160208701612dc7565b949350505050565b80516008811061030157600080fd5b6000610200808385031215611c76578182fd5b611c7f81612d66565b915050611c8b82611ba7565b8152611c996020830161175e565b6020820152611caa6040830161175e565b6040820152606082015160608201526080820151608082015260a082015160a0820152611cd960c0830161175e565b60c0820152611cea60e0830161175e565b60e08201526101008281015190820152610120808301519082015261014080830151908201526101608083015190820152610180808301516001600160401b03811115611d3657600080fd5b611d4285828601611c09565b8284015250506101a0611d56818401611e88565b908201526101c082810151908201526101e09182015191810191909152919050565b600060808284031215611d89578081fd5b604051608081016001600160401b038282108183111715611da657fe5b816040528293508435915060068210611dbe57600080fd5b81835260208501356020840152604085013560408401526060850135915080821115611de957600080fd5b50611df685828601611bbd565b6060830152505092915050565b600060c08284031215611e14578081fd5b60405160c081018181106001600160401b0382111715611e3057fe5b8060405250809150825181526020830151602082015260408301516040820152606083015160608201526080830151611e6881612df3565b608082015260a0830151611e7b81612e08565b60a0919091015292915050565b805160ff8116811461030157600080fd5b600060208284031215611eaa578081fd5b813561139581612df3565b600080600080600060a08688031215611ecc578081fd5b8535611ed781612df3565b94506020860135611ee781612df3565b935060408601356001600160401b0380821115611f02578283fd5b611f0e89838a01611b42565b94506060880135915080821115611f23578283fd5b611f2f89838a01611b42565b93506080880135915080821115611f44578283fd5b50611f5188828901611bbd565b9150509295509295909350565b60008060008060808587031215611f73578182fd5b8435611f7e81612df3565b93506020850135611f8e81612df3565b92506040850135915060608501356001600160401b03811115611faf578182fd5b611fbb87828801611bbd565b91505092959194509250565b600080600080600060a08688031215611fde578283fd5b8535611fe981612df3565b94506020860135611ff981612df3565b9350604086013592506060860135915060808601356001600160401b03811115612021578182fd5b611f5188828901611bbd565b6000602080838503121561203f578182fd5b82516001600160401b0380821115612055578384fd5b818501915085601f830112612068578384fd5b815161207661178982612d89565b818152848101908486016060808502870188018b1015612094578889fd5b8896505b848710156120fb5780828c0312156120ae578889fd5b6040805182810181811089821117156120c357fe5b825283516120d081612df3565b8152838a01518a82015281840151918101919091528452600196909601959287019290810190612098565b50909998505050505050505050565b6000602080838503121561211c578182fd5b82516001600160401b0380821115612132578384fd5b818501915085601f830112612145578384fd5b815161215361178982612d89565b818152848101908486016040808502870188018b1015612171578889fd5b8896505b848710156120fb5780828c03121561218b578889fd5b8051818101818110888211171561219e57fe5b825282516121ab81612df3565b815282890151898201528452600196909601959287019290810190612175565b600080600080608085870312156121e0578182fd5b84356001600160401b038111156121f5578283fd5b8501601f81018713612205578283fd5b8035602061221561178983612d89565b82815281810190848301875b8581101561224a576122388d8684358a0101611d78565b84529284019290840190600101612221565b5050809850505061225c818901611753565b955050505061226d60408601611753565b915061227b60608601611b9c565b905092959194509250565b600060208284031215612297578081fd5b813561139581612e08565b6000602082840312156122b3578081fd5b813561139581612e16565b600060208083850312156122d0578182fd5b82516001600160401b03808211156122e6578384fd5b90840190604082870312156122f9578384fd5b60405160408101818110838211171561230e57fe5b60405282518281111561231f578586fd5b61232b88828601611c09565b825250838301518281111561233e578586fd5b80840193505086601f840112612352578485fd5b8251915061236261178983612d89565b82815284810190848601868502860187018a101561237e578788fd5b8795505b848610156123a0578051835260019590950194918601918601612382565b50948201949094529695505050505050565b6000806000606084860312156123c6578081fd5b83356001600160401b038111156123db578182fd5b6123e786828701611d78565b93505060208401356123f881612df3565b9150604084013561240881612df3565b809150509250925092565b600060208284031215612424578081fd5b81516001600160401b038082111561243a578283fd5b90830190610160828603121561244e578283fd5b61245860c0612d66565b825182811115612466578485fd5b612472878286016118cb565b825250602083015182811115612486578485fd5b61249287828601611a17565b6020830152506124a58660408501611e03565b6040820152610100830151606082015261012083015160808201526124cd6101408401611e88565b60a082015295945050505050565b6000806000606084860312156124ef578081fd5b83516001600160401b0380821115612505578283fd5b9085019060c08288031215612518578283fd5b60405160c08101818110838211171561252d57fe5b60405261253983611ba7565b81526125476020840161175e565b602082015260408301516040820152606083015160608201526080830151608082015260a08301518281111561257b578485fd5b61258789828601611c09565b60a08301525060208701519095509150808211156125a3578283fd5b506125b086828701611c63565b9250506125bf60408501611bb2565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b83811015612618578151805188528301516001600160a01b031683880152604090960195908201906001016125e8565b509495945050505050565b6000815180845260208085018081965082840281019150828601855b8581101561267d57828403895281518051855285015160408686018190526126698187018361276f565b9a87019a955050509084019060010161263f565b5091979650505050505050565b6000815180845260208085018081965082840281019150828601855b8581101561267d57828403895281516101606126c386835161279b565b818701518688015260408083015190870152606080830151908701526080808301519087015260a0808301516126fb828901826125c8565b505060c08083015182828901526127148389018261276f565b60e085810151908a015261010080860151908a015261012080860151908a015261014094850151898203958a019590955292506127559150829050836125d5565b9a87019a95505050908401906001016126a6565b15159052565b60008151808452612787816020860160208601612dc7565b601f01601f19169290920160200192915050565b600881106127a557fe5b9052565b805182526020808201519083015260408082015190830152606080820151908301526080808201516001600160a01b03169083015260a0908101511515910152565b60ff169052565b60008251612804818460208701612dc7565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b901515815260200190565b6001600160e01b031991909116815260200190565b6020808252601e908201527f50757263686173652077797665726e45786368616e6765206661696c65640000604082015260600190565b60208082526018908201527f556e6b6e6f776e2070757263686173652064657461696c730000000000000000604082015260600190565b60208082526017908201527f50757263686173652072617269626c65206661696c6564000000000000000000604082015260600190565b60208082526017908201527f507572636861736520536561506f7274206661696c6564000000000000000000604082015260600190565b60208082526018908201527f5075726368617365207375646f73776170206661696c65640000000000000000604082015260600190565b60208082526019908201527f756e6b6e6f776e2064656c656761746554797065207832793200000000000000604082015260600190565b602080825260129082015271556e6b6e6f776e20746f6b656e207479706560701b604082015260600190565b6020808252601a908201527f756e6b6e6f776e206164646974696f6e616c4461746154797065000000000000604082015260600190565b60208082526018908201527f6e6f207375636365737366756c20657865637574696f6e730000000000000000604082015260600190565b60006020808352610180808401855161016080858801528282518085526101a094508489019150848782028a01018785019450885b82811015612b9f578a820361019f1901845285518051835289810151612adf8b8501826125c8565b5060408181015190840152606080820151908401526080808201519084015260a0808201519084015260c080820151612b1a828601826125c8565b505060e0808201518982860152612b338a86018261276f565b9150506101008083015185830382870152612b4e8382612623565b9250505061012080830151818601525061014080830151818601525086820151612b7a888601826127eb565b509089015190612b8c848b01836127eb565b968a0196948a0194925050600101612ab7565b50968a0151898803601f190160408b015296612bbb818961268a565b975050505060408801519350612bd460608801856127a9565b6060880151610120880152608088015161014088015260a08801519350612bfd818801856127eb565b50929695505050505050565b60006040825261010084511515604084015260018060a01b03602086015116606084015260408501516080840152606085015160a0840152608085015160c084015260a085015160c060e0850152612c638285018261276f565b90508381036020850152610200612c7b828751612769565b6020860151612c8d60208401826125c8565b506040860151612ca060408401826125c8565b50606086015160608301526080860151608083015260a086015160a083015260c0860151612cd160c08401826125c8565b5060e0860151612ce460e08401826125c8565b50858301519282019290925261012080860151908201526101408086015190820152610160808601519082015261018080860151818301849052909290612d2d8284018261276f565b935050506101a080860151612d44828401826127eb565b50506101c085810151908201526101e094850151940193909352509092915050565b6040518181016001600160401b0381118282101715612d8157fe5b604052919050565b60006001600160401b03821115612d9c57fe5b5060209081020190565b60006001600160401b03821115612db957fe5b50601f01601f191660200190565b60005b83811015612de2578181015183820152602001612dca565b838111156114e25750506000910152565b6001600160a01b038116811461133857600080fd5b801515811461133857600080fd5b6001600160e01b03198116811461133857600080fdfe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220e8b00d7cb3cc483e0e17ffbbb344b6cbf1730dde1d401f953eb870e6ad41465764736f6c634300070600330000000000000000000000007f268357a8c2552623316e2562d90e642bb538e50000000000000000000000009757f2d2b135150bbeb65308d4a91804107cd8d600000000000000000000000000000000006c3852cbef3e08e8df289169ede58100000000000000000000000074312363e45dcaba76c59ec49a7aa8a65a67eed300000000000000000000000059728544b08ab483533076417fbbb2fd0b17ce3a0000000000000000000000002b2e8cda09bba9660dca5cb6233787738ad68329
Deployed Bytecode
0x6080604052600436106101025760003560e01c80638da5cb5b11610095578063bc197c8111610064578063bc197c8114610259578063c9f0a2fa14610279578063f23a6e611461028e578063f2fde38b146102ae578063fc40c9c7146102ce57610109565b80638da5cb5b146102075780639110c7771461021c578063a05f32dc14610231578063b94ee3321461024657610109565b80635ea1e4c9116100d15780635ea1e4c9146101a857806362c1a97d146101ca578063715018a6146101df57806386496e7a146101f457610109565b806301ffc9a71461010e57806302329a2914610144578063150b7a02146101665780635c975abb1461019357610109565b3661010957005b600080fd5b34801561011a57600080fd5b5061012e6101293660046122a2565b6102e3565b60405161013b919061287e565b60405180910390f35b34801561015057600080fd5b5061016461015f366004612286565b610306565b005b34801561017257600080fd5b50610186610181366004611f5e565b6103c1565b60405161013b9190612889565b34801561019f57600080fd5b5061012e6103d1565b3480156101b457600080fd5b506101bd6103da565b60405161013b919061280e565b3480156101d657600080fd5b506101bd6103fe565b3480156101eb57600080fd5b50610164610422565b6101646102023660046123b2565b6104e0565b34801561021357600080fd5b506101bd610559565b34801561022857600080fd5b506101bd610568565b34801561023d57600080fd5b506101bd61058c565b6101646102543660046121cb565b6105b0565b34801561026557600080fd5b50610186610274366004611eb5565b6106a4565b34801561028557600080fd5b506101bd6106b5565b34801561029a57600080fd5b506101866102a9366004611fc7565b6106d9565b3480156102ba57600080fd5b506101646102c9366004611e99565b6106ea565b3480156102da57600080fd5b506101bd6107fe565b6001600160e01b0319811660009081526001602052604090205460ff165b919050565b61030e610822565b6001600160a01b031661031f610559565b6001600160a01b03161461037a576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6002805482151560ff19909116811790915560408051918252517f0e2fb031ee032dc02d8011dc50b816eb450cf856abd8261680dac74f72165bd29181900360200190a150565b630a85bd0160e11b949350505050565b60025460ff1681565b7f0000000000000000000000002b2e8cda09bba9660dca5cb6233787738ad6832981565b7f00000000000000000000000000000000006c3852cbef3e08e8df289169ede58181565b61042a610822565b6001600160a01b031661043b610559565b6001600160a01b031614610496576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6104e8610826565b60008060006104f8866000610879565b9250925092507fcc54b89ca2d75d5612023b14f0a477212b0e08bc0c5b8ad2804e2f8e2e401fc08360405161052d919061287e565b60405180910390a161053f82866112fc565b61054981856112fc565b610551611327565b505050505050565b6000546001600160a01b031690565b7f00000000000000000000000059728544b08ab483533076417fbbb2fd0b17ce3a81565b7f0000000000000000000000009757f2d2b135150bbeb65308d4a91804107cd8d681565b6105b8610826565b6000806000805b87518110156106585760008060006105ea8b85815181106105dc57fe5b602002602001015189610879565b92509250925084806105f95750825b94507fcc54b89ca2d75d5612023b14f0a477212b0e08bc0c5b8ad2804e2f8e2e401fc08360405161062a919061287e565b60405180910390a161063c878361133b565b9650610648868261133b565b95505050508060010190506105bf565b508061067f5760405162461bcd60e51b815260040161067690612a4b565b60405180910390fd5b61068983876112fc565b61069382866112fc565b61069b611327565b50505050505050565b63bc197c8160e01b95945050505050565b7f0000000000000000000000007f268357a8c2552623316e2562d90e642bb538e581565b63f23a6e6160e01b95945050505050565b6106f2610822565b6001600160a01b0316610703610559565b6001600160a01b03161461075e576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0381166107a35760405162461bcd60e51b8152600401808060200182810382526026815260200180612e2d6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b7f00000000000000000000000074312363e45dcaba76c59ec49a7aa8a65a67eed381565b3390565b60025460ff1615610877576040805162461bcd60e51b81526020600482015260166024820152751d1a194818dbdb9d1c9858dd081a5cc81c185d5cd95960521b604482015290519081900360640190fd5b565b600080600080600061089887606001518860400151896000015161139e565b602089015191935091506002885160058111156108b157fe5b141561097f5760007f00000000000000000000000000000000006c3852cbef3e08e8df289169ede5816001600160a01b031682856040516108f291906127f2565b60006040518083038185875af1925050503d806000811461092f576040519150601f19603f3d011682016040523d82523d6000602084013e610934565b606091505b50509050871561095c5780610957576000806000965096509650505050506112f5565b610979565b806109795760405162461bcd60e51b815260040161067690612943565b506112c3565b60018851600581111561098e57fe5b1415610a515760007f0000000000000000000000007f268357a8c2552623316e2562d90e642bb538e56001600160a01b031682856040516109cf91906127f2565b60006040518083038185875af1925050503d8060008114610a0c576040519150601f19603f3d011682016040523d82523d6000602084013e610a11565b606091505b505090508715610a345780610957576000806000965096509650505050506112f5565b806109795760405162461bcd60e51b81526004016106769061289e565b600088516005811115610a6057fe5b1415610b235760007f0000000000000000000000009757f2d2b135150bbeb65308d4a91804107cd8d66001600160a01b03168285604051610aa191906127f2565b60006040518083038185875af1925050503d8060008114610ade576040519150601f19603f3d011682016040523d82523d6000602084013e610ae3565b606091505b505090508715610b065780610957576000806000965096509650505050506112f5565b806109795760405162461bcd60e51b81526004016106769061290c565b600388516005811115610b3257fe5b1415610f7557600083806020019051810190610b4e9190612413565b90508715610bec5760405163357a150b60e01b81526001600160a01b037f00000000000000000000000074312363e45dcaba76c59ec49a7aa8a65a67eed3169063357a150b908490610ba4908590600401612a82565b6000604051808303818588803b158015610bbd57600080fd5b505af193505050508015610bcf575060015b610be7576000806000965096509650505050506112f5565b610c6d565b60405163357a150b60e01b81526001600160a01b037f00000000000000000000000074312363e45dcaba76c59ec49a7aa8a65a67eed3169063357a150b908490610c3a908590600401612a82565b6000604051808303818588803b158015610c5357600080fd5b505af1158015610c67573d6000803e3d6000fd5b50505050505b60005b816020015151811015610f6e57600082602001518281518110610c8f57fe5b6020026020010151602001519050600083602001518381518110610caf57fe5b6020026020010151604001519050600084600001518381518110610ccf57fe5b602002602001015161010001518281518110610ce757fe5b6020026020010151602001519050600085600001518481518110610d0757fe5b602002602001015160e0015151118015610d3d5750600085602001518581518110610d2e57fe5b602002602001015160c0015151115b15610d8357610d838186602001518681518110610d5657fe5b602002602001015160c0015187600001518681518110610d7257fe5b602002602001015160e00151611457565b8451805184908110610d9157fe5b60200260200101516080015160011415610e6657600081806020019051810190610dbb919061210a565b905060005b8151811015610e5f576000828281518110610dd757fe5b6020026020010151905080600001516001600160a01b03166342842e0e30610dfd610822565b84602001516040518463ffffffff1660e01b8152600401610e2093929190612822565b600060405180830381600087803b158015610e3a57600080fd5b505af1158015610e4e573d6000803e3d6000fd5b505060019093019250610dc0915050565b5050610f60565b8451805184908110610e7457fe5b60200260200101516080015160021415610f4857600081806020019051810190610e9e919061202d565b905060005b8151811015610e5f576000828281518110610eba57fe5b6020026020010151905080600001516001600160a01b031663f242432a30610ee0610822565b846020015185604001516040518563ffffffff1660e01b8152600401610f099493929190612846565b600060405180830381600087803b158015610f2357600080fd5b505af1158015610f37573d6000803e3d6000fd5b505060019093019250610ea3915050565b60405162461bcd60e51b8152600401610676906129b1565b505050806001019050610c70565b50506112c3565b600488516005811115610f8457fe5b14156111d957600080600085806020019051810190610fa391906124db565b925092509250891561104957604051635a72594b60e11b81526001600160a01b037f00000000000000000000000059728544b08ab483533076417fbbb2fd0b17ce3a169063b4e4b296908690610fff9087908790600401612c09565b6000604051808303818588803b15801561101857600080fd5b505af19350505050801561102a575060015b6110445760008060009850985098505050505050506112f5565b6110cc565b604051635a72594b60e11b81526001600160a01b037f00000000000000000000000059728544b08ab483533076417fbbb2fd0b17ce3a169063b4e4b2969086906110999087908790600401612c09565b6000604051808303818588803b1580156110b257600080fd5b505af11580156110c6573d6000803e3d6000fd5b50505050505b6001600160e01b031981166339d690a360e11b141561115b5781604001516001600160a01b03166342842e0e30611101610822565b85608001516040518463ffffffff1660e01b815260040161112493929190612822565b600060405180830381600087803b15801561113e57600080fd5b505af1158015611152573d6000803e3d6000fd5b505050506111d1565b6001600160e01b0319811663025ceed960e61b14156111b95781604001516001600160a01b031663f242432a30611190610822565b85608001518660a001516040518563ffffffff1660e01b81526004016111249493929190612846565b60405162461bcd60e51b8152600401610676906129e8565b5050506112c3565b6005885160058111156111e857fe5b14156112ab5760007f0000000000000000000000002b2e8cda09bba9660dca5cb6233787738ad683296001600160a01b0316828560405161122991906127f2565b60006040518083038185875af1925050503d8060008114611266576040519150601f19603f3d011682016040523d82523d6000602084013e61126b565b606091505b50509050871561128e5780610957576000806000965096509650505050506112f5565b806109795760405162461bcd60e51b81526004016106769061297a565b60405162461bcd60e51b8152600401610676906128d5565b6112d18289602001516114e8565b6000806112e68a604001518b60200151611576565b60019950909750955050505050505b9250925092565b60008211801561131457506001600160a01b03811615155b156113235761132381836115a7565b5050565b4780156113385761133833826115a7565b50565b600082820183811015611395576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b6060806000602085901c61ffff1660018111156113b757fe5b9050606060008260018111156113c957fe5b14156113db57869350915061144f9050565b60018260018111156113e957fe5b14156114375760008780602001905181019061140591906122be565b90506114108661163f565b1561142b57806000015181602001519450945050505061144f565b519350915061144f9050565b60405162461bcd60e51b815260040161067690612a14565b935093915050565b815183511461146557600080fd5b805183511461147357600080fd5b60005b83518110156114e25781818151811061148b57fe5b01602001516001600160f81b031916156114da578281815181106114ab57fe5b602001015160f81c60f81b8482815181106114c257fe5b60200101906001600160f81b031916908160001a9053505b600101611476565b50505050565b60005b825181101561157157600083828151811061150257fe5b6020026020010151111561156957600083828151811061151e57fe5b60200260200101519050600060a085848151811061153857fe5b6020026020010151901c90506000611559828661167b90919063ffffffff16565b905061156581846112fc565b5050505b6001016114eb565b505050565b60008061ffff601085901c8116908516611590858361167b565b61159a868361167b565b9350935050509250929050565b6040516000906001600160a01b0384169083908381818185875af1925050503d80600081146115f2576040519150601f19603f3d011682016040523d82523d6000602084013e6115f7565b606091505b5050905080611571576040805162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b604482015290519081900360640190fd5b6000600582600581111561164f57fe5b14806116665750600482600581111561166457fe5b145b1561167357506001610301565b506000919050565b600061139561271061168d8585611693565b906116ec565b6000826116a257506000611398565b828202828482816116af57fe5b04146113955760405162461bcd60e51b8152600401808060200182810382526021815260200180612e536021913960400191505060405180910390fd5b6000808211611742576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161174b57fe5b049392505050565b803561030181612df3565b805161030181612df3565b600082601f830112611779578081fd5b8151602061178e61178983612d89565b612d66565b828152818101908583016040808602880185018910156117ac578687fd5b865b868110156118075781838b0312156117c4578788fd5b81518281018181106001600160401b03821117156117de57fe5b835283518152868401516117f181612df3565b81880152855293850193918101916001016117ae565b509198975050505050505050565b600082601f830112611825578081fd5b8151602061183561178983612d89565b82815281810190858301855b858110156118be5781518801604080601f19838d03011215611861578889fd5b80518181016001600160401b03828210818311171561187c57fe5b818452848a01518352928401519280841115611896578b8cfd5b50506118a68c8984860101611c09565b81890152865250509284019290840190600101611841565b5090979650505050505050565b600082601f8301126118db578081fd5b815160206118eb61178983612d89565b82815281810190858301855b858110156118be57815188016101a080601f19838d03011215611918578889fd5b61192181612d66565b8783015181526119336040840161175e565b88820152606083015160408201526080830151606082015260a0830151608082015260c083015160a082015261196b60e0840161175e565b60c08201526101008301516001600160401b038082111561198a578b8cfd5b6119988e8b84880101611c09565b60e0840152610120915081850151818111156119b2578c8dfd5b6119c08f8c83890101611815565b6101008501525050610140808501518284015261016091508185015181840152506101806119ef818601611e88565b828401526119fe848601611e88565b90830152508652505092840192908401906001016118f7565b600082601f830112611a27578081fd5b81516020611a3761178983612d89565b82815281810190858301855b858110156118be578151880161016080601f19838d03011215611a64578889fd5b611a6d81612d66565b611a78888401611c54565b815260408301518882015260608301516040820152608080840151606083015260a0808501518284015260c09150611ab182860161175e565b9083015260e08401516001600160401b0380821115611ace578c8dfd5b611adc8f8c84890101611c09565b8385015261010092508286015160e0850152610120915081860151838501526101409250828601518285015284860151945080851115611b1a578c8dfd5b5050611b2a8d8a85870101611769565b90820152865250509284019290840190600101611a43565b600082601f830112611b52578081fd5b81356020611b6261178983612d89565b8281528181019085830183850287018401881015611b7e578586fd5b855b858110156118be57813584529284019290840190600101611b80565b803561030181612e08565b805161030181612e08565b805161030181612e16565b600082601f830112611bcd578081fd5b8135611bdb61178982612da6565b818152846020838601011115611bef578283fd5b816020850160208301379081016020019190915292915050565b600082601f830112611c19578081fd5b8151611c2761178982612da6565b818152846020838601011115611c3b578283fd5b611c4c826020830160208701612dc7565b949350505050565b80516008811061030157600080fd5b6000610200808385031215611c76578182fd5b611c7f81612d66565b915050611c8b82611ba7565b8152611c996020830161175e565b6020820152611caa6040830161175e565b6040820152606082015160608201526080820151608082015260a082015160a0820152611cd960c0830161175e565b60c0820152611cea60e0830161175e565b60e08201526101008281015190820152610120808301519082015261014080830151908201526101608083015190820152610180808301516001600160401b03811115611d3657600080fd5b611d4285828601611c09565b8284015250506101a0611d56818401611e88565b908201526101c082810151908201526101e09182015191810191909152919050565b600060808284031215611d89578081fd5b604051608081016001600160401b038282108183111715611da657fe5b816040528293508435915060068210611dbe57600080fd5b81835260208501356020840152604085013560408401526060850135915080821115611de957600080fd5b50611df685828601611bbd565b6060830152505092915050565b600060c08284031215611e14578081fd5b60405160c081018181106001600160401b0382111715611e3057fe5b8060405250809150825181526020830151602082015260408301516040820152606083015160608201526080830151611e6881612df3565b608082015260a0830151611e7b81612e08565b60a0919091015292915050565b805160ff8116811461030157600080fd5b600060208284031215611eaa578081fd5b813561139581612df3565b600080600080600060a08688031215611ecc578081fd5b8535611ed781612df3565b94506020860135611ee781612df3565b935060408601356001600160401b0380821115611f02578283fd5b611f0e89838a01611b42565b94506060880135915080821115611f23578283fd5b611f2f89838a01611b42565b93506080880135915080821115611f44578283fd5b50611f5188828901611bbd565b9150509295509295909350565b60008060008060808587031215611f73578182fd5b8435611f7e81612df3565b93506020850135611f8e81612df3565b92506040850135915060608501356001600160401b03811115611faf578182fd5b611fbb87828801611bbd565b91505092959194509250565b600080600080600060a08688031215611fde578283fd5b8535611fe981612df3565b94506020860135611ff981612df3565b9350604086013592506060860135915060808601356001600160401b03811115612021578182fd5b611f5188828901611bbd565b6000602080838503121561203f578182fd5b82516001600160401b0380821115612055578384fd5b818501915085601f830112612068578384fd5b815161207661178982612d89565b818152848101908486016060808502870188018b1015612094578889fd5b8896505b848710156120fb5780828c0312156120ae578889fd5b6040805182810181811089821117156120c357fe5b825283516120d081612df3565b8152838a01518a82015281840151918101919091528452600196909601959287019290810190612098565b50909998505050505050505050565b6000602080838503121561211c578182fd5b82516001600160401b0380821115612132578384fd5b818501915085601f830112612145578384fd5b815161215361178982612d89565b818152848101908486016040808502870188018b1015612171578889fd5b8896505b848710156120fb5780828c03121561218b578889fd5b8051818101818110888211171561219e57fe5b825282516121ab81612df3565b815282890151898201528452600196909601959287019290810190612175565b600080600080608085870312156121e0578182fd5b84356001600160401b038111156121f5578283fd5b8501601f81018713612205578283fd5b8035602061221561178983612d89565b82815281810190848301875b8581101561224a576122388d8684358a0101611d78565b84529284019290840190600101612221565b5050809850505061225c818901611753565b955050505061226d60408601611753565b915061227b60608601611b9c565b905092959194509250565b600060208284031215612297578081fd5b813561139581612e08565b6000602082840312156122b3578081fd5b813561139581612e16565b600060208083850312156122d0578182fd5b82516001600160401b03808211156122e6578384fd5b90840190604082870312156122f9578384fd5b60405160408101818110838211171561230e57fe5b60405282518281111561231f578586fd5b61232b88828601611c09565b825250838301518281111561233e578586fd5b80840193505086601f840112612352578485fd5b8251915061236261178983612d89565b82815284810190848601868502860187018a101561237e578788fd5b8795505b848610156123a0578051835260019590950194918601918601612382565b50948201949094529695505050505050565b6000806000606084860312156123c6578081fd5b83356001600160401b038111156123db578182fd5b6123e786828701611d78565b93505060208401356123f881612df3565b9150604084013561240881612df3565b809150509250925092565b600060208284031215612424578081fd5b81516001600160401b038082111561243a578283fd5b90830190610160828603121561244e578283fd5b61245860c0612d66565b825182811115612466578485fd5b612472878286016118cb565b825250602083015182811115612486578485fd5b61249287828601611a17565b6020830152506124a58660408501611e03565b6040820152610100830151606082015261012083015160808201526124cd6101408401611e88565b60a082015295945050505050565b6000806000606084860312156124ef578081fd5b83516001600160401b0380821115612505578283fd5b9085019060c08288031215612518578283fd5b60405160c08101818110838211171561252d57fe5b60405261253983611ba7565b81526125476020840161175e565b602082015260408301516040820152606083015160608201526080830151608082015260a08301518281111561257b578485fd5b61258789828601611c09565b60a08301525060208701519095509150808211156125a3578283fd5b506125b086828701611c63565b9250506125bf60408501611bb2565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b83811015612618578151805188528301516001600160a01b031683880152604090960195908201906001016125e8565b509495945050505050565b6000815180845260208085018081965082840281019150828601855b8581101561267d57828403895281518051855285015160408686018190526126698187018361276f565b9a87019a955050509084019060010161263f565b5091979650505050505050565b6000815180845260208085018081965082840281019150828601855b8581101561267d57828403895281516101606126c386835161279b565b818701518688015260408083015190870152606080830151908701526080808301519087015260a0808301516126fb828901826125c8565b505060c08083015182828901526127148389018261276f565b60e085810151908a015261010080860151908a015261012080860151908a015261014094850151898203958a019590955292506127559150829050836125d5565b9a87019a95505050908401906001016126a6565b15159052565b60008151808452612787816020860160208601612dc7565b601f01601f19169290920160200192915050565b600881106127a557fe5b9052565b805182526020808201519083015260408082015190830152606080820151908301526080808201516001600160a01b03169083015260a0908101511515910152565b60ff169052565b60008251612804818460208701612dc7565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b901515815260200190565b6001600160e01b031991909116815260200190565b6020808252601e908201527f50757263686173652077797665726e45786368616e6765206661696c65640000604082015260600190565b60208082526018908201527f556e6b6e6f776e2070757263686173652064657461696c730000000000000000604082015260600190565b60208082526017908201527f50757263686173652072617269626c65206661696c6564000000000000000000604082015260600190565b60208082526017908201527f507572636861736520536561506f7274206661696c6564000000000000000000604082015260600190565b60208082526018908201527f5075726368617365207375646f73776170206661696c65640000000000000000604082015260600190565b60208082526019908201527f756e6b6e6f776e2064656c656761746554797065207832793200000000000000604082015260600190565b602080825260129082015271556e6b6e6f776e20746f6b656e207479706560701b604082015260600190565b6020808252601a908201527f756e6b6e6f776e206164646974696f6e616c4461746154797065000000000000604082015260600190565b60208082526018908201527f6e6f207375636365737366756c20657865637574696f6e730000000000000000604082015260600190565b60006020808352610180808401855161016080858801528282518085526101a094508489019150848782028a01018785019450885b82811015612b9f578a820361019f1901845285518051835289810151612adf8b8501826125c8565b5060408181015190840152606080820151908401526080808201519084015260a0808201519084015260c080820151612b1a828601826125c8565b505060e0808201518982860152612b338a86018261276f565b9150506101008083015185830382870152612b4e8382612623565b9250505061012080830151818601525061014080830151818601525086820151612b7a888601826127eb565b509089015190612b8c848b01836127eb565b968a0196948a0194925050600101612ab7565b50968a0151898803601f190160408b015296612bbb818961268a565b975050505060408801519350612bd460608801856127a9565b6060880151610120880152608088015161014088015260a08801519350612bfd818801856127eb565b50929695505050505050565b60006040825261010084511515604084015260018060a01b03602086015116606084015260408501516080840152606085015160a0840152608085015160c084015260a085015160c060e0850152612c638285018261276f565b90508381036020850152610200612c7b828751612769565b6020860151612c8d60208401826125c8565b506040860151612ca060408401826125c8565b50606086015160608301526080860151608083015260a086015160a083015260c0860151612cd160c08401826125c8565b5060e0860151612ce460e08401826125c8565b50858301519282019290925261012080860151908201526101408086015190820152610160808601519082015261018080860151818301849052909290612d2d8284018261276f565b935050506101a080860151612d44828401826127eb565b50506101c085810151908201526101e094850151940193909352509092915050565b6040518181016001600160401b0381118282101715612d8157fe5b604052919050565b60006001600160401b03821115612d9c57fe5b5060209081020190565b60006001600160401b03821115612db957fe5b50601f01601f191660200190565b60005b83811015612de2578181015183820152602001612dca565b838111156114e25750506000910152565b6001600160a01b038116811461133857600080fd5b801515811461133857600080fd5b6001600160e01b03198116811461133857600080fdfe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220e8b00d7cb3cc483e0e17ffbbb344b6cbf1730dde1d401f953eb870e6ad41465764736f6c63430007060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007f268357a8c2552623316e2562d90e642bb538e50000000000000000000000009757f2d2b135150bbeb65308d4a91804107cd8d600000000000000000000000000000000006c3852cbef3e08e8df289169ede58100000000000000000000000074312363e45dcaba76c59ec49a7aa8a65a67eed300000000000000000000000059728544b08ab483533076417fbbb2fd0b17ce3a0000000000000000000000002b2e8cda09bba9660dca5cb6233787738ad68329
-----Decoded View---------------
Arg [0] : _wyvernExchange (address): 0x7f268357A8c2552623316e2562D90e642bB538E5
Arg [1] : _exchangeV2 (address): 0x9757F2d2b135150BBeb65308D4a91804107cd8D6
Arg [2] : _seaPort (address): 0x00000000006c3852cbEf3e08E8dF289169EdE581
Arg [3] : _x2y2 (address): 0x74312363e45DCaBA76c59ec49a7Aa8A65a67EeD3
Arg [4] : _looksRare (address): 0x59728544B08AB483533076417FbBB2fD0B17CE3a
Arg [5] : _sudoswap (address): 0x2B2e8cDA09bBA9660dCA5cB6233787738Ad68329
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000007f268357a8c2552623316e2562d90e642bb538e5
Arg [1] : 0000000000000000000000009757f2d2b135150bbeb65308d4a91804107cd8d6
Arg [2] : 00000000000000000000000000000000006c3852cbef3e08e8df289169ede581
Arg [3] : 00000000000000000000000074312363e45dcaba76c59ec49a7aa8a65a67eed3
Arg [4] : 00000000000000000000000059728544b08ab483533076417fbbb2fd0b17ce3a
Arg [5] : 0000000000000000000000002b2e8cda09bba9660dca5cb6233787738ad68329
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.