Contract 0x3E7012c044946baD5718671ae6A4C2300C0D8e73

Txn Hash Method
Block
From
To
Value [Txn Fee]
0x3eec0bbc34fc1a125fe9196e65fac0fc4cec0d462f81cb64d5a4e7c79f9689350xa760d79a19884002022-06-09 9:11:2421 days 4 hrs ago0x2f26b38e01c4cb0fa039174c02103aaa583dfbc9 IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.000481319
0x90d66da963038776a22c7c32a96724523f96eda321d5d8c86fa94da3681ec0630xa760d79a19536002022-06-03 21:11:3026 days 16 hrs ago0xaca3fb055fe92a11b17524319070b30ec73c8a77 IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.000855622
0xd6525820d3b49e7e8a9372797f62d9ce531c0dbfbb7e6cd5c5a0645edb9db3e70xa760d79a19535902022-06-03 21:09:2426 days 16 hrs ago0xaca3fb055fe92a11b17524319070b30ec73c8a77 IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.000768979
0xc47b831f98117b287ef9d163692ec26821b1afb20617b548ae9a0299f32c276fCancel Offer19334452022-05-31 15:25:1229 days 22 hrs ago0x6c08256fe7fd4f831b2b2c04a57fdecab7718407 IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.000233726
0x50c56b7288c0cc8a306c21c56798986984f3828876c2ec68bb3dfafcf285bba1Cancel Offer19333342022-05-31 14:58:4829 days 22 hrs ago0xcb6342d1ea9937e8a877ccb7abe7d08826a4c8ee IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.000601115
0x4fb1bd1631be459d847d4d46e63c1d275967f89676e24f28c29d65b1b9b1cded0xa760d79a19331622022-05-31 14:18:5429 days 23 hrs ago0x6c08256fe7fd4f831b2b2c04a57fdecab7718407 IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.00050892
0xc89f040c4cd374cd6eecd50f71eba6e232ee6ae661f7bd6a33023862b259453eAccept Offer19325862022-05-31 12:09:3630 days 1 hr ago0xc123cab66407844be22e1cc26e496fd2a1dbf26d IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.00110482
0x592abf16139eb044cbfa6150f4cd2d9453995ddf13d8115894142be1f42e78d40xa760d79a19325672022-05-31 12:05:0630 days 1 hr ago0x71f488a37bb5ad354894cab8ebd6af2938366a6f IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.00050892
0x122ec62ae14a9b838796a9d649faaa9a246974f4711fc6c5b65bfc8f68ac2227Accept Offer19271952022-05-30 15:48:2430 days 22 hrs ago0xc123cab66407844be22e1cc26e496fd2a1dbf26d IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.000657815
0x8076a6e55b45f4c44af297fa0d89fcaee90d7f1ff4e5fab63c86f3856782c333Accept Offer18953362022-05-25 14:31:0635 days 23 hrs ago0xc123cab66407844be22e1cc26e496fd2a1dbf26d IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.00056081
0x3449d23739b44646a55e1fe4855c7b529211cb980e144bbbd1a882c27182ccc00xa760d79a18949332022-05-25 12:58:3036 days 56 mins ago0xbac0cc03dc049630c25504426263573d373316b2 IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.000612671
0xda15aa7ffacc0d93afcbdee39d331bc7c5580f82fe2ad5b3bb41eb39430b784fCancel Offer18949202022-05-25 12:55:4836 days 59 mins ago0xbac0cc03dc049630c25504426263573d373316b2 IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.000392365
0xd0c951f0fe26355ab211e53b1450b213d3bb0926825773d7f54b5e5bb677a95f0xa760d79a18949132022-05-25 12:53:5436 days 1 hr ago0xbac0cc03dc049630c25504426263573d373316b2 IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730.005 MOVR0.000494748
0x1247387b72fa34aeeb88f99ae99caf9c6efdf063d893caefa913da81ddf50140Cancel Offer18948912022-05-25 12:48:4236 days 1 hr ago0xbac0cc03dc049630c25504426263573d373316b2 IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.00051442
0x319f1599f1e7267720419a0747a6d222beb95a75ab515bbdf1f024e39ab1bc3a0xa760d79a18948832022-05-25 12:46:4836 days 1 hr ago0xbac0cc03dc049630c25504426263573d373316b2 IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.00055856
0x8afccfe4752163e9ced3f887c449d5b4ad795851dc14129fee736d1368e6e479Cancel Offer18948672022-05-25 12:43:1236 days 1 hr ago0xbac0cc03dc049630c25504426263573d373316b2 IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.00044186
0xa63ffaaa749c2f4eb7cd1fd331d8612db3700dd2b4af31d97765895c0381b0c90xa760d79a18948642022-05-25 12:42:3636 days 1 hr ago0xbac0cc03dc049630c25504426263573d373316b2 IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.000447133
0x5a20ea463e915fd45a50f3fc825afde4a5270dd0eee8bcc73266879f1b8cdee5Accept Offer18948542022-05-25 12:40:3036 days 1 hr ago0x67588292e0755160f439af7b00c60f5217cbd3eb IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.0008704
0xad718ad94abf3084f66a32266575632bcfbf83ffacc13ec4d18d4856278fa7df0xa760d79a18948492022-05-25 12:39:3036 days 1 hr ago0xbac0cc03dc049630c25504426263573d373316b2 IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.000479054
0x4be6f104ed64fcad7a13eeec2b0d30579a5781bb9e875e05d04f5d9a86b9dbfaAccept Offer18948412022-05-25 12:37:5436 days 1 hr ago0x67588292e0755160f439af7b00c60f5217cbd3eb IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.000818785
0xaf430a48d034627bd16a2c4d075fd6b16f7785d4efafa84580f41fb15ce5b2160xa760d79a18948332022-05-25 12:36:1236 days 1 hr ago0xbac0cc03dc049630c25504426263573d373316b2 IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.000421093
0x2c25888457989fc665e3797af9befa3c40ccf66a3b7fa05101e9074df1939bb5Accept Offer18641482022-05-20 13:54:3041 days ago0xbac0cc03dc049630c25504426263573d373316b2 IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.00081874
0xf073f644a5b01e157270cf47cbc0cb5dd4b8801efa9cc5c4048ac47ba433f1700xa760d79a18641422022-05-20 13:53:1841 days 2 mins ago0x67588292e0755160f439af7b00c60f5217cbd3eb IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.000401193
0xb358883b3dc733be6cf04d1918dd34359b0733270a3b211cd39deb70663a6c37Enable Supported...18640492022-05-20 13:31:4241 days 23 mins ago0x5f4275f17533381c130544cad7852b122574a506 IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.000094774
0xc0f01318529b4d6e2aa18566fceae385a11a669e1a94d09a2627e895bf367cb4Enable Supported...18640482022-05-20 13:31:3041 days 23 mins ago0x5f4275f17533381c130544cad7852b122574a506 IN  0x3e7012c044946bad5718671ae6a4c2300c0d8e730 MOVR0.000094774
[ Download CSV Export 
Latest 8 internal transactions
Parent Txn Hash Block From To Value
0xda15aa7ffacc0d93afcbdee39d331bc7c5580f82fe2ad5b3bb41eb39430b784f18949202022-05-25 12:55:4836 days 59 mins ago 0x3e7012c044946bad5718671ae6a4c2300c0d8e730xbac0cc03dc049630c25504426263573d373316b20.005 MOVR
0xd0c951f0fe26355ab211e53b1450b213d3bb0926825773d7f54b5e5bb677a95f18949132022-05-25 12:53:5436 days 1 hr ago 0x3e7012c044946bad5718671ae6a4c2300c0d8e73 0x3e7012c044946bad5718671ae6a4c2300c0d8e730.005 MOVR
0x0ae915f23035bc4642773ca143cc9aa88dd0b73c18f939f87da5812a5645a5c117334612022-04-22 11:30:1869 days 2 hrs ago 0x3e7012c044946bad5718671ae6a4c2300c0d8e730xdfd013b8644f30c1b06a3027dd1e8c71de92e0560.02 MOVR
0x87ce4742159f288c85cf6ee44f99e9e172c926d264396c809d54cc238d0b4e0917334532022-04-22 11:27:3669 days 2 hrs ago 0x3e7012c044946bad5718671ae6a4c2300c0d8e73 0x3e7012c044946bad5718671ae6a4c2300c0d8e730.02 MOVR
0x108e3a19456dc8ae7b51e5cd603dda2586d1d8035a6b40e8f385c9c479150add16731442022-04-04 14:12:4286 days 23 hrs ago 0x3e7012c044946bad5718671ae6a4c2300c0d8e730xbac0cc03dc049630c25504426263573d373316b20.017 MOVR
0x5aa7e4411d1da603eddf43e1bdb638591d5237c50fdbb6da2d2bfdee34a5e55516731292022-04-04 14:07:4286 days 23 hrs ago 0x3e7012c044946bad5718671ae6a4c2300c0d8e73 0x3e7012c044946bad5718671ae6a4c2300c0d8e730.017 MOVR
0xbc16ed6bcda7d146cc4864c2b4e84835d8410586ca33a6b7c84b805d7119939a16730632022-04-04 13:42:3087 days 12 mins ago 0x3e7012c044946bad5718671ae6a4c2300c0d8e730xdfd013b8644f30c1b06a3027dd1e8c71de92e0560.0001 MOVR
0xf165a5ba7e86f6d7e995cf9e3454b89ef300c592e3849257ca65049c1ce68f1d16730562022-04-04 13:38:4287 days 16 mins ago 0x3e7012c044946bad5718671ae6a4c2300c0d8e73 0x3e7012c044946bad5718671ae6a4c2300c0d8e730.0001 MOVR
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
NftSwap

Compiler Version
v0.6.7+commit.b8d736ae

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 15 : NftSwap.sol
pragma solidity 0.6.7;
pragma experimental ABIEncoderV2;

import "./../openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./../openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import "./../openzeppelin/contracts/token/ERC721/IERC721.sol";
import "./../openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "./../openzeppelin/contracts/math/SafeMath.sol";
import "./../openzeppelin/contracts/access/Ownable.sol";
import "./../openzeppelin/contracts/security/ReentrancyGuard.sol";
import "./Crowns.sol";
import "./NftParamsInterface.sol";
import "./SwapSigner.sol";

/// @title Nft Swap is a part of Seascape marketplace platform.
/// It allows users to obtain desired nfts in exchange for their offered nfts,
/// a fee and an optional bounty
/// @author Nejc Schneider
contract NftSwap is Crowns, Ownable, ReentrancyGuard, IERC721Receiver {
    using SafeERC20 for IERC20;
    using SafeMath for uint256;
    SwapSigner private swapSigner;


    uint256 public lastOfferId;             /// @dev keep count of offers (aka offerIds)
    bool public tradeEnabled = true;        /// @dev enable/disable create and accept offer
    uint256 public fee;                     /// @dev fee for creating an offer

    /// @notice individual offer related data
    struct OfferObject{
        uint256 offerId;                   // offer ID
        uint8 offeredTokensAmount;         // total offered tokens
        uint8 requestedTokensAmount;       // total requested tokens
        uint256 bounty;                    // reward for the buyer
        address bountyAddress;             // currency address for paying bounties
        address payable seller;            // seller's address
        uint256 fee;                       // fee amount at the time offer was created
        mapping(uint256 => OfferedToken) offeredTokens;       // offered tokens data
        mapping(uint256 => RequestedToken) requestedTokens;   // requested tokensdata
    }

    /// @notice individual offered token related data
    struct OfferedToken{
        uint256 tokenId;                    // offered token id
        address tokenAddress;               // offered token address
    }

    /// @notice individual requested token related data
    struct RequestedToken{
        address tokenAddress;              // requested token address
        bytes tokenParams;                 // requested token Params
        uint8 v;
        bytes32 r;
        bytes32 s;
    }

    /// @dev store offer objects.
    /// @param offerId => OfferObject
    mapping(uint256 => OfferObject) offerObjects;
    /// @dev supported ERC721 and ERC20 contracts
    mapping(address => bool) public supportedBountyAddresses;
    /// @dev parse params contract addresses (1 per individual nftSeries)
    /// @param nftAddress => nftParams contract address
    mapping(address => address) public supportedNftAddresses;

    event CreateOffer(
        uint256 indexed offerId,
        address indexed seller,
        uint256 bounty,
        address indexed bountyAddress,
        uint256 fee,
        uint256 offeredTokensAmount,
        uint256 requestedTokensAmount,
        OfferedToken [5] offeredTokens,
        RequestedToken [5] requestedTokens
    );

    event AcceptOffer(
        uint256 indexed offerId,
        address indexed buyer,
        uint256 bounty,
        address indexed bountyAddress,
        uint256 fee,
        uint256 requestedTokensAmount,
        uint256 [5] requestedTokenIds,
        uint256 offeredTokensAmount,
        uint256 [5] offeredTokenIds
    );

    event CancelOffer(
        uint256 indexed offerId,
        address indexed seller
    );

    event NftReceived(address operator, address from, uint256 tokenId, bytes data);
    event Received(address, uint);

    /// @param _feeRate - fee amount
    /// @param _crownsAddress staking currency address
    constructor(uint256 _feeRate, address _crownsAddress, address _signerAddress) public {
        /// @dev set crowns is defined in Crowns.sol
        require(_crownsAddress != address(0x0), "invalid cws address");
        setCrowns(_crownsAddress);
        fee = _feeRate;
        swapSigner = SwapSigner(_signerAddress);
    }

    //--------------------------------------------------
    // External methods
    //--------------------------------------------------

    fallback() external payable {
        emit Received(msg.sender, msg.value);
    }

    /// @notice enable/disable createOffer() and acceptOffer() functionality
    /// @param _tradeEnabled set tradeEnabled to true/false
    function enableTrade(bool _tradeEnabled) external onlyOwner { tradeEnabled = _tradeEnabled; }

    /// @notice enable additional nft series
    /// @param _nftAddress ERC721 contract address
    // @param _nftParamsAddress contract address
    function enableSupportedNftAddress(
        address _nftAddress,
        address _nftParamsAddress
    )
        external
        onlyOwner
    {
        require(_nftAddress != address(0x0), "invalid nft address");
        require(_nftParamsAddress != address(0x0), "invalid NftParams address");
        require(supportedNftAddresses[_nftAddress] == address(0x0),
            "nft address already enabled");
        supportedNftAddresses[_nftAddress] = _nftParamsAddress;
    }

    /// @notice disable nft series
    /// @param _nftAddress ERC721 contract address
    function disableSupportedNftAddress(address _nftAddress) external onlyOwner {
        require(_nftAddress != address(0x0), "invalid address");
        require(supportedNftAddresses[_nftAddress] != address(0),
            "nft address already disabled");
        supportedNftAddresses[_nftAddress] = address(0x0);
    }

    /// @notice enable additional bounty currency
    /// @param _bountyAddress ERC20 contract address
    function addSupportedBountyAddress(address _bountyAddress) external onlyOwner {
        require(!supportedBountyAddresses[_bountyAddress], "bounty already supported");
        supportedBountyAddresses[_bountyAddress] = true;
    }

    /// @notice disable supported bounty currency
    /// @param _bountyAddress ERC20 contract address
    function removeSupportedBountyAddress(address _bountyAddress) external onlyOwner {
        require(supportedBountyAddresses[_bountyAddress], "bounty already removed");
        supportedBountyAddresses[_bountyAddress] = false;
    }

    /// @notice update fee value. Change will only apply to new offers.
    /// @param _feeRate set fee to this value.
    function setFee(uint256 _feeRate) external onlyOwner { fee = _feeRate; }

    /// @notice returns amount of offers
    /// @return total amount of offer objects
    function getLastOfferId() external view returns(uint) { return lastOfferId; }

    /// @dev returns all properties of offer object at _offerId element
    /// @param _offerId unique offer ID
    /// @return OfferObject at given index
    function getOffer(uint _offerId)
        external
        view
        returns(uint256, uint8, uint8, uint256, address, address, uint256)
    {
        return (
        offerObjects[_offerId].offerId,
        offerObjects[_offerId].offeredTokensAmount,
        offerObjects[_offerId].requestedTokensAmount,
        offerObjects[_offerId].bounty,
        offerObjects[_offerId].bountyAddress,
        offerObjects[_offerId].seller,
        offerObjects[_offerId].fee
        );
    }

    //--------------------------------------------------
    // Public methods
    //--------------------------------------------------

    /// @notice by creating a new offer, msg.sender will transfer offered tokens,
    /// fee and an optional bounty to the contract
    /// @param _offeredTokens array of five OfferedToken structs
    /// @param _requestedTokens array of five RequestedToken structs
    /// @param _bounty additional cws to offer to buyer
    /// @return lastOfferId total amount of offers
    function createOffer(
        uint8 _offeredTokensAmount,
        OfferedToken [5] memory _offeredTokens,
        uint8 _requestedTokensAmount,
        RequestedToken [5] memory _requestedTokens,
        uint256 _bounty,
        address _bountyAddress
    )
        public
        payable
        returns(uint256)
    {
        /// require statements
        require(tradeEnabled, "trade is disabled");
        require(_offeredTokensAmount > 0, "should offer at least one nft");
        require(_offeredTokensAmount <= 5, "cant offer more than 5 tokens");
        require(_requestedTokensAmount > 0, "should require at least one nft");
        require(_requestedTokensAmount <= 5, "cant request more than 5 tokens");
        // bounty & fee related requirements
        if (_bounty > 0) {
            if (address(crowns) == _bountyAddress) {
                require(crowns.balanceOf(msg.sender) >= fee + _bounty,
                    "not enough CWS for fee & bounty");
            } else {
                require(supportedBountyAddresses[_bountyAddress],
                    "bounty address not supported");

                if (_bountyAddress == address(0x0)) {
                    require (msg.value >= _bounty, "insufficient transfer amount");
                    uint256 returnBack = msg.value.sub(_bounty);
                    if (returnBack > 0)
                        msg.sender.transfer(returnBack);
                } else {
                    IERC20 currency = IERC20(_bountyAddress);
                    require(currency.balanceOf(msg.sender) >= _bounty,
                        "not enough money to pay bounty");
                }
            }
        } else {
            require(crowns.balanceOf(msg.sender) >= fee, "not enough CWS for fee");
        }
        /// input token verification
        // verify offered nft oddresses and ids
        for (uint index = 0; index < _offeredTokensAmount; index++) {
            // the following checks should only apply if slot at index is filled.
            require(_offeredTokens[index].tokenId > 0, "nft id must be greater than 0");
            require(supportedNftAddresses[_offeredTokens[index].tokenAddress] != address(0),
                "offered nft address unsupported");
            IERC721 nft = IERC721(_offeredTokens[index].tokenAddress);
            require(nft.ownerOf(_offeredTokens[index].tokenId) == msg.sender,
                "sender not owner of nft");
        }
        // verify requested nft oddresses
        for (uint _index = 0; _index < _requestedTokensAmount; _index++) {
            address nftParamsAddress = supportedNftAddresses[_requestedTokens[_index].tokenAddress];
            require(nftParamsAddress != address(0),
                "requested nft address unsupported");
            // verify nft parameters
            // external but trusted contract maintained by Seascape
            NftParamsInterface requestedToken = NftParamsInterface (nftParamsAddress);
            require(requestedToken.paramsAreValid(lastOfferId, _requestedTokens[_index].tokenParams,
              _requestedTokens[_index].v, _requestedTokens[_index].r, _requestedTokens[_index].s),
                "invalid nft Params");
        }

        /// make transactions
        // send offered nfts to smart contract
        for (uint index = 0; index < _offeredTokensAmount; index++) {
            // send nfts to contract
            IERC721(_offeredTokens[index].tokenAddress)
                .safeTransferFrom(msg.sender, address(this), _offeredTokens[index].tokenId);
        }
        // send fee and _bounty to contract
        if (_bounty > 0) {
            if (_bountyAddress == address(crowns)) {
                IERC20(crowns).safeTransferFrom(msg.sender, address(this), fee + _bounty);
            } else {
                if (_bountyAddress == address(0)) {
                    address(this).transfer(_bounty);
                } else {
                    IERC20(_bountyAddress).safeTransferFrom(msg.sender, address(this), _bounty);
                }
                IERC20(crowns).safeTransferFrom(msg.sender, address(this), fee);
            }
        } else {
            IERC20(crowns).safeTransferFrom(msg.sender, address(this), fee);
        }

        /// update states
        lastOfferId++;

        offerObjects[lastOfferId].offerId = lastOfferId;
        offerObjects[lastOfferId].offeredTokensAmount = _offeredTokensAmount;
        offerObjects[lastOfferId].requestedTokensAmount = _requestedTokensAmount;
        for(uint256 i = 0; i < _offeredTokensAmount; i++){
            offerObjects[lastOfferId].offeredTokens[i] = _offeredTokens[i];
        }
        for(uint256 i = 0; i < _requestedTokensAmount; i++){
            offerObjects[lastOfferId].requestedTokens[i] = _requestedTokens[i];
        }
        offerObjects[lastOfferId].bounty = _bounty;
        offerObjects[lastOfferId].bountyAddress = _bountyAddress;
        offerObjects[lastOfferId].seller = msg.sender;
        offerObjects[lastOfferId].fee = fee;

        /// emit events
        emit CreateOffer(
            lastOfferId,
            msg.sender,
            _bounty,
            _bountyAddress,
            fee,
            _offeredTokensAmount,
            _requestedTokensAmount,
            _offeredTokens,
            _requestedTokens
          );

        return lastOfferId;
    }

    /// @notice by accepting offer, buyer will transfer requested tokens to the seller,
    /// in exchange for offered tokens and an optional bounty. Fee is spend.
    function acceptOffer(
        uint256 _offerId,
        uint256 [5] memory _requestedTokenIds,
        address [5] memory _requestedTokenAddresses,
        uint8 [5] memory _v,
        bytes32 [5] memory _r,
        bytes32 [5] memory _s
    )
        public
        nonReentrant
        payable
    {
        OfferObject storage obj = offerObjects[_offerId];
        require(tradeEnabled, "trade is disabled");
        require(msg.sender != obj.seller, "cant buy self-made offer");

        /// @dev verify requested tokens
        for(uint256 i = 0; i < obj.requestedTokensAmount; i++){
            require(_requestedTokenIds[i] > 0, "nft id must be greater than 0");
            require(_requestedTokenAddresses[i] == obj.requestedTokens[i].tokenAddress,
                "wrong requested token address");
            IERC721 nft = IERC721(obj.requestedTokens[i].tokenAddress);
            require(nft.ownerOf(_requestedTokenIds[i]) == msg.sender,
                "sender not owner of nft");
            /// digital signature part
            bytes32 _messageNoPrefix = keccak256(abi.encodePacked(
                _offerId,
                _requestedTokenIds[i],
                _requestedTokenAddresses[i],
                msg.sender
            ));
            bytes32 _message = keccak256(abi.encodePacked(
                "\x19Ethereum Signed Message:\n32", _messageNoPrefix));
            address _recover = ecrecover(_message, _v[i], _r[i], _s[i]);
            require(_recover == swapSigner.getSigner(),  "Verification failed");
        }

        /// make transactions
        // send requestedTokens from buyer to seller
        for (uint index = 0; index < obj.requestedTokensAmount; index++) {
            IERC721(_requestedTokenAddresses[index])
                .safeTransferFrom(msg.sender, obj.seller, _requestedTokenIds[index]);
        }
        // send offeredTokens from SC to buyer
        for (uint index = 0; index < obj.offeredTokensAmount; index++) {
            IERC721(obj.offeredTokens[index].tokenAddress)
                .safeTransferFrom(address(this), msg.sender, obj.offeredTokens[index].tokenId);
        }
        // spend obj.fee and send obj.bounty from SC to buyer
        crowns.spend(obj.fee);
        if(obj.bounty > 0) {
            if(obj.bountyAddress == address(0))
                msg.sender.transfer(obj.bounty);
            else
                IERC20(obj.bountyAddress).safeTransfer(msg.sender, obj.bounty);
        }

        /// emit events
        emit AcceptOffer(
            obj.offerId,
            msg.sender,
            obj.bounty,
            obj.bountyAddress,
            obj.fee,
            obj.requestedTokensAmount,
            _requestedTokenIds,
            obj.offeredTokensAmount,
            [obj.offeredTokens[0].tokenId,
            obj.offeredTokens[1].tokenId,
            obj.offeredTokens[2].tokenId,
            obj.offeredTokens[3].tokenId,
            obj.offeredTokens[4].tokenId]
        );

        /// update states
        delete offerObjects[_offerId];
    }

    /// @notice offered tokens, fee, and an optional bounty is returned to seller
    /// @param _offerId offer unique ID
    function cancelOffer(uint _offerId) public {
        OfferObject storage obj = offerObjects[_offerId];
        require(obj.seller == msg.sender, "sender is not creator of offer");

        /// make transactions
        // send the offeredTokens from SC to seller
        for (uint index=0; index < obj.offeredTokensAmount; index++) {
            IERC721(obj.offeredTokens[index].tokenAddress)
                .safeTransferFrom(address(this), obj.seller, obj.offeredTokens[index].tokenId);
        }

        // send crowns and bounty from SC to seller
        if (obj.bounty > 0) {
            if (obj.bountyAddress == address(crowns)) {
                crowns.transfer(msg.sender, obj.fee + obj.bounty);
            } else {
                if (obj.bountyAddress == address(0)) {
                    msg.sender.transfer(obj.bounty);
                } else {
                    IERC20(obj.bountyAddress).safeTransfer(msg.sender, obj.bounty);
                }
                crowns.transfer(msg.sender, obj.fee);
            }
        } else {
            crowns.transfer(msg.sender, obj.fee);
        }

        /// emit events
        emit CancelOffer(
            obj.offerId,
            obj.seller
        );

        /// update states
        delete offerObjects[_offerId];
    }

    /// @dev encrypt token data
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes memory data
    )
        public
        override
        returns (bytes4)
    {
        //only receive the _nft staff
        if (address(this) != operator) {
            //invalid from nft
            return 0;
        }

        //success
        emit NftReceived(operator, from, tokenId, data);
        return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"));
    }

}

File 2 of 15 : Address.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.2;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash := extcodehash(account) }
        return (codehash != accountHash && codehash != 0x0);
    }

    /**
     * @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");
        return _functionCallWithValue(target, data, value, errorMessage);
    }

    function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
        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);
            }
        }
    }
}

File 3 of 15 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.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);
}

File 4 of 15 : IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.2;

import "../../introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transfered 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;
}

File 5 of 15 : SafeERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

import "./IERC20.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using SafeMath for uint256;
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).add(value);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 6 of 15 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @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);
}

File 7 of 15 : ReentrancyGuard.sol
// File: contracts/library/ReentrancyGuard.sol

pragma solidity ^0.6.7;

contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() internal {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }

    function initReentrancyStatus() internal {
        _status = _NOT_ENTERED;
    }
}

File 8 of 15 : SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.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, 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) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * 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);
        uint256 c = a - b;

        return c;
    }

    /**
     * @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) {
        // 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 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts 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) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts 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) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

File 9 of 15 : IERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.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);
}

File 10 of 15 : Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

import "../GSN/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.
 */
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 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;
    }
}

File 11 of 15 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.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;
    }
}

File 12 of 15 : SwapSigner.sol
pragma solidity 0.6.7;

import "./../openzeppelin/contracts/access/Ownable.sol";

/// @title SwapSigner holds address for signature verification.
/// It is used by NftSwap and SwapParams contracts.
/// @author Nejc Schneider
contract SwapSigner is Ownable {

    address public signer;         // @dev verify v, r, s signature

    constructor() public { signer = msg.sender; }

    /// @notice change address to verify signature against
    /// @param _signer new signer address
    function setSigner(address _signer) external onlyOwner {
        require(_signer != address(0), "invalid signer address");
        signer = _signer;
    }

    /// @notice returns verifier of signatures
    /// @return signer address
    function getSigner() external view returns(address) { return signer; }
}

File 13 of 15 : NftParamsInterface.sol
pragma solidity 0.6.7;


/// @dev Interface of the nftSwapParams

interface NftParamsInterface {

    /// @dev Returns true if signature is valid
    function paramsAreValid(uint256 _offerId, bytes calldata _encodedParams,
        uint8 v, bytes32 r, bytes32 s) external view returns (bool);

}

File 14 of 15 : Crowns.sol
pragma solidity 0.6.7;

import "./../crowns/erc-20/contracts/CrownsToken/CrownsToken.sol";

/// @dev Nft Rush and Leaderboard contracts both are with Crowns.
/// So, making Crowns available for both Contracts by moving it to another contract.
///
/// @author Medet Ahmetson
contract Crowns {
    CrownsToken public crowns;

   function setCrowns(address _crowns) internal {
        require(_crowns != address(0), "Crowns can't be zero address");
       	crowns = CrownsToken(_crowns);
   }
}

File 15 of 15 : CrownsToken.sol
// contracts/Crowns.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.6.7;

import "./../../../../openzeppelin/contracts/access/Ownable.sol";
import "./../../../../openzeppelin/contracts/GSN/Context.sol";
import "./../../../../openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./../../../../openzeppelin/contracts/math/SafeMath.sol";
import "./../../../../openzeppelin/contracts/utils/Address.sol";

/// @title Official token of Blocklords and the Seascape ecosystem.
/// @author Medet Ahmetson
/// @notice Crowns (CWS) is an ERC-20 token with a Rebase feature.
/// Rebasing is a distribution of spent tokens among all current token holders.
/// In order to appear in balance, rebased tokens need to be claimed by users by triggering transaction with the ERC-20 contract.
/// @dev Implementation of the {IERC20} interface.
contract CrownsToken is Context, IERC20, Ownable {
    using SafeMath for uint256;
    using Address for address;

    struct Account {
        uint256 balance;
        uint256 lastRebase;
    }

    mapping (address => Account) private _accounts;
    mapping (address => mapping (address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;
    uint8 private _decimals;

    uint256 private constant _minSpend = 10 ** 6;
    uint256 private constant _decimalFactor = 10 ** 18;
    uint256 private constant _million = 1000000;

    /// @notice Total amount of tokens that have yet to be transferred to token holders as part of a rebase.
    /// @dev Used Variable tracking unclaimed rebase token amounts.
    uint256 public unclaimedRebase = 0;
    /// @notice Amount of tokens spent by users that have not been rebased yet.
    /// @dev Calling the rebase function will move the amount to {totalRebase}
    uint256 public unconfirmedRebase = 0;
    /// @notice Total amount of tokens that were rebased overall.
    /// @dev Total aggregate rebase amount that is always increasing.
    uint256 public totalRebase = 0;

    /**
     * @dev Sets the {name} and {symbol} of token.
     * Initializes {decimals} with a default value of 18.
     * Mints all tokens.
     * Transfers ownership to another account. So, the token creator will not be counted as an owner.
     */
    constructor () public {
        _name = "Crowns";
        _symbol = "CWS";
        _decimals = 18;

        // Grant the minter roles to a specified account
        address inGameAirdropper     = 0xFa4D7D1AC9b7a7454D09B8eAdc35aA70599329EA;
        address rechargeDexManager   = 0x53bd91aEF5e84A61F9B87781A024ee648733f973;
        address teamManager          = 0xB5de2b5186E1Edc947B73019F3102EF53c2Ac691;
        address investManager        = 0x1D3Db9BCA5aa2CE931cE13B7B51f8E14F5895368;
        address communityManager     = 0x0811e2DFb6482507461ca2Ab583844313f2549B5;
        address newOwner             = msg.sender;

        // 3 million tokens
        uint256 inGameAirdrop        = 3 * _million * _decimalFactor;
        uint256 rechargeDex          = inGameAirdrop;
        // 1 million tokens
        uint256 teamAllocation       = 1 * _million * _decimalFactor;
        uint256 investment           = teamAllocation;
        // 750,000 tokens
        uint256 communityBounty      = 750000 * _decimalFactor;
        // 1,25 million tokens
        uint256 inGameReserve        = 1250000 * _decimalFactor; // reserve for the next 5 years.

        _mint(inGameAirdropper,      inGameAirdrop);
        _mint(rechargeDexManager,    rechargeDex);
        _mint(teamManager,           teamAllocation);
        _mint(investManager,         investment);
        _mint(communityManager,      communityBounty);
        _mint(newOwner,              inGameReserve);

        transferOwnership(newOwner);
   }

    /**
     * @notice Return amount of tokens that {account} gets during rebase
     * @dev Used both internally and externally to calculate the rebase amount
     * @param account is an address of token holder to calculate for
     * @return amount of tokens that player could get
     */
    function rebaseOwing (address account) public view returns(uint256) {
        Account memory _account = _accounts[account];

        uint256 newRebase = totalRebase.sub(_account.lastRebase);
        uint256 proportion = _account.balance.mul(newRebase);

        // The rebase is not a part of total supply, since it was moved out of balances
        uint256 supply = _totalSupply.sub(newRebase);

        // rebase owed proportional to current balance of the account.
        // The decimal factor is used to avoid floating issue.
        uint256 rebase = proportion.mul(_decimalFactor).div(supply).div(_decimalFactor);

        return rebase;
    }

    /**
     * @dev Called before any edit of {account} balance.
     * Modifier moves the belonging rebase amount to its balance.
     * @param account is an address of Token holder.
     */
    modifier updateAccount(address account) {
        uint256 owing = rebaseOwing(account);
        _accounts[account].lastRebase = totalRebase;

        if (owing > 0) {
            _accounts[account].balance    = _accounts[account].balance.add(owing);
            unclaimedRebase     = unclaimedRebase.sub(owing);

            emit Transfer(
                address(0),
                account,
                owing
            );
        }

        _;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view returns (uint8) {
        return _decimals;
    }

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() public view override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) public view override returns (uint256) {
        return _getBalance(account);
    }

    /**
     * @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) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @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) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @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) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @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) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal updateAccount(sender) updateAccount(recipient) virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");
        require(amount > 0, "Can not send 0 token");
        require(_getBalance(sender) >= amount, "ERC20: Not enough token to send");

        _beforeTokenTransfer(sender, recipient, amount);

        _accounts[sender].balance =  _accounts[sender].balance.sub(amount);
        _accounts[recipient].balance = _accounts[recipient].balance.add(amount);

        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply = _totalSupply.add(amount);
        _accounts[account].balance = _accounts[account].balance.add(amount);
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Moves `amount` tokens from `account` to {unconfirmedRebase} without reducing the
     * total supply. Will be rebased among token holders.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal updateAccount(account) virtual {
        require(account != address(0), "ERC20: burn from the zero address");
        require(_getBalance(account) >= amount, "ERC20: Not enough token to burn");

        _beforeTokenTransfer(account, address(0), amount);

        _accounts[account].balance = _accounts[account].balance.sub(amount);

        unconfirmedRebase = unconfirmedRebase.add(amount);

        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.
     *
     * This is internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be to transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }

    /**
     * @notice Spend some token from caller's balance in the game.
     * @dev Moves `amount` of token from caller to `unconfirmedRebase`.
     * @param amount Amount of token used to spend
     */
    function spend(uint256 amount) public returns(bool) {
        require(amount > _minSpend, "Crowns: trying to spend less than expected");
        require(_getBalance(msg.sender) >= amount, "Crowns: Not enough balance");

        _burn(msg.sender, amount);

	return true;
    }

    function spendFrom(address sender, uint256 amount) public returns(bool) {
	require(amount > _minSpend, "Crowns: trying to spend less than expected");
	require(_getBalance(sender) >= amount, "Crowns: not enough balance");

	_burn(sender, amount);
	_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));

	return true;
    }

    /**
     * @notice Return the rebase amount, when `account` balance was updated.
     */
    function getLastRebase(address account) public view returns (uint256) {
        return _accounts[account].lastRebase;
    }

    /**
     * @dev Returns actual balance of account as a sum of owned divends and current balance.
     * @param account Address of Token holder.
     * @return Token amount
     */
    function _getBalance(address account) private view returns (uint256) {
        uint256 balance = _accounts[account].balance;
    	if (balance == 0) {
    		return 0;
    	}
    	uint256 owing = rebaseOwing(account);

    	return balance.add(owing);
    }

    /**
     * @dev Emitted when `spent` tokens are moved `unconfirmedRebase` to `totalRebase`.
     */
    event Rebase(
        uint256 spent,
        uint256 totalRebase
    );

    /**
     * @notice Rebasing is a unique feature of Crowns (CWS) token. It redistributes tokens spenth within game among all token holders.
     * @dev Moves tokens from {unconfirmedRebase} to {totalRebase}.
     * Any account balance related functions will use {totalRebase} to calculate the dividend shares for each account.
     *
     * Emits a {Rebase} event.
     */
    function rebase() public onlyOwner() returns (bool) {
    	totalRebase = totalRebase.add(unconfirmedRebase);
    	unclaimedRebase = unclaimedRebase.add(unconfirmedRebase);
    	unconfirmedRebase = 0;

        emit Rebase (
            unconfirmedRebase,
            totalRebase
        );

        return true;
    }
}

Settings
{
  "remappings": [],
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "evmVersion": "istanbul",
  "libraries": {},
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"_feeRate","type":"uint256"},{"internalType":"address","name":"_crownsAddress","type":"address"},{"internalType":"address","name":"_signerAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"offerId","type":"uint256"},{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"bounty","type":"uint256"},{"indexed":true,"internalType":"address","name":"bountyAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requestedTokensAmount","type":"uint256"},{"indexed":false,"internalType":"uint256[5]","name":"requestedTokenIds","type":"uint256[5]"},{"indexed":false,"internalType":"uint256","name":"offeredTokensAmount","type":"uint256"},{"indexed":false,"internalType":"uint256[5]","name":"offeredTokenIds","type":"uint256[5]"}],"name":"AcceptOffer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"offerId","type":"uint256"},{"indexed":true,"internalType":"address","name":"seller","type":"address"}],"name":"CancelOffer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"offerId","type":"uint256"},{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"uint256","name":"bounty","type":"uint256"},{"indexed":true,"internalType":"address","name":"bountyAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"offeredTokensAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requestedTokensAmount","type":"uint256"},{"components":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"}],"indexed":false,"internalType":"struct NftSwap.OfferedToken[5]","name":"offeredTokens","type":"tuple[5]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"bytes","name":"tokenParams","type":"bytes"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"indexed":false,"internalType":"struct NftSwap.RequestedToken[5]","name":"requestedTokens","type":"tuple[5]"}],"name":"CreateOffer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"NftReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"","type":"address"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"Received","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"uint256","name":"_offerId","type":"uint256"},{"internalType":"uint256[5]","name":"_requestedTokenIds","type":"uint256[5]"},{"internalType":"address[5]","name":"_requestedTokenAddresses","type":"address[5]"},{"internalType":"uint8[5]","name":"_v","type":"uint8[5]"},{"internalType":"bytes32[5]","name":"_r","type":"bytes32[5]"},{"internalType":"bytes32[5]","name":"_s","type":"bytes32[5]"}],"name":"acceptOffer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_bountyAddress","type":"address"}],"name":"addSupportedBountyAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_offerId","type":"uint256"}],"name":"cancelOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_offeredTokensAmount","type":"uint8"},{"components":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"}],"internalType":"struct NftSwap.OfferedToken[5]","name":"_offeredTokens","type":"tuple[5]"},{"internalType":"uint8","name":"_requestedTokensAmount","type":"uint8"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"bytes","name":"tokenParams","type":"bytes"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct NftSwap.RequestedToken[5]","name":"_requestedTokens","type":"tuple[5]"},{"internalType":"uint256","name":"_bounty","type":"uint256"},{"internalType":"address","name":"_bountyAddress","type":"address"}],"name":"createOffer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"crowns","outputs":[{"internalType":"contract CrownsToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nftAddress","type":"address"}],"name":"disableSupportedNftAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nftAddress","type":"address"},{"internalType":"address","name":"_nftParamsAddress","type":"address"}],"name":"enableSupportedNftAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_tradeEnabled","type":"bool"}],"name":"enableTrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastOfferId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_offerId","type":"uint256"}],"name":"getOffer","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastOfferId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","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":"address","name":"_bountyAddress","type":"address"}],"name":"removeSupportedBountyAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feeRate","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"supportedBountyAddresses","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"supportedNftAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradeEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526001600560006101000a81548160ff0219169083151502179055503480156200002c57600080fd5b5060405162006136380380620061368339818101604052810190620000529190620002cc565b600062000064620001e060201b60201c565b905080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3506001600281905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156200017e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200017590620003a6565b60405180910390fd5b6200018f82620001e860201b60201c565b8260068190555080600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050506200046d565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156200025b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200025290620003c8565b60405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600081519050620002af8162000439565b92915050565b600081519050620002c68162000453565b92915050565b600080600060608486031215620002e257600080fd5b6000620002f286828701620002b5565b935050602062000305868287016200029e565b925050604062000318868287016200029e565b9150509250925092565b600062000331601383620003ea565b91507f696e76616c6964206377732061646472657373000000000000000000000000006000830152602082019050919050565b600062000373601c83620003ea565b91507f43726f776e732063616e2774206265207a65726f2061646472657373000000006000830152602082019050919050565b60006020820190508181036000830152620003c18162000322565b9050919050565b60006020820190508181036000830152620003e38162000364565b9050919050565b600082825260208201905092915050565b600062000408826200040f565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6200044481620003fb565b81146200045057600080fd5b50565b6200045e816200042f565b81146200046a57600080fd5b50565b615cb9806200047d6000396000f3fe60806040526004361061012e5760003560e01c80638da5cb5b116100ab578063d621e8131161006f578063d621e81314610415578063ddca3f4314610440578063e388bf211461046b578063ea5ed05d14610494578063ef706adf146104bf578063f2fde38b146104e85761012f565b80638da5cb5b1461032b578063a760d79a14610356578063af13b97114610386578063c00f04d1146103af578063cdd21397146103d85761012f565b8063643268c9116100f2578063643268c91461027b57806369fe0e2d146102a6578063715018a6146102cf5780637e6c2378146102e6578063834a37b9146103025761012f565b806306edf3461461016a578063150b7a02146101935780634579268a146101d057806347eda88f1461021357806359e148fc146102505761012f565b5b7f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f885258743334604051610160929190615133565b60405180910390a1005b34801561017657600080fd5b50610191600480360381019061018c9190614067565b610511565b005b34801561019f57600080fd5b506101ba60048036038101906101b591906140f5565b61068f565b6040516101c79190615268565b60405180910390f35b3480156101dc57600080fd5b506101f760048036038101906101f291906141c2565b61072c565b60405161020a97969594939291906157e3565b60405180910390f35b34801561021f57600080fd5b5061023a60048036038101906102359190614067565b61084e565b6040516102479190615208565b60405180910390f35b34801561025c57600080fd5b5061026561086e565b60405161027291906156a0565b60405180910390f35b34801561028757600080fd5b50610290610878565b60405161029d91906156a0565b60405180910390f35b3480156102b257600080fd5b506102cd60048036038101906102c891906141c2565b61087e565b005b3480156102db57600080fd5b506102e461091f565b005b61030060048036038101906102fb9190614214565b610a77565b005b34801561030e57600080fd5b50610329600480360381019061032491906140b9565b6115ef565b005b34801561033757600080fd5b506103406118b6565b60405161034d91906150c6565b60405180910390f35b610370600480360381019061036b91906142a1565b6118e0565b60405161037d91906156a0565b60405180910390f35b34801561039257600080fd5b506103ad60048036038101906103a89190614067565b6129e7565b005b3480156103bb57600080fd5b506103d660048036038101906103d19190614170565b612c3f565b005b3480156103e457600080fd5b506103ff60048036038101906103fa9190614067565b612cf3565b60405161040c91906150c6565b60405180910390f35b34801561042157600080fd5b5061042a612d26565b6040516104379190615208565b60405180910390f35b34801561044c57600080fd5b50610455612d39565b60405161046291906156a0565b60405180910390f35b34801561047757600080fd5b50610492600480360381019061048d9190614067565b612d3f565b005b3480156104a057600080fd5b506104a9612ebe565b6040516104b69190615283565b60405180910390f35b3480156104cb57600080fd5b506104e660048036038101906104e191906141c2565b612ee3565b005b3480156104f457600080fd5b5061050f600480360381019061050a9190614067565b613561565b005b610519613728565b73ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146105a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161059f906154c0565b60405180910390fd5b600860008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610634576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161062b90615620565b60405180910390fd5b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008473ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16146106d057600060e01b9050610724565b7f0895c277367ff99b8c0dec875f3149fc2c82df592f63ca6f0747ac2095169087858585856040516107059493929190615193565b60405180910390a16040516107199061503d565b604051809103902090505b949350505050565b60008060008060008060006007600089815260200190815260200160002060000154600760008a815260200190815260200160002060010160009054906101000a900460ff16600760008b815260200190815260200160002060010160019054906101000a900460ff16600760008c815260200190815260200160002060020154600760008d815260200190815260200160002060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600760008e815260200190815260200160002060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600760008f8152602001908152602001600020600501548191509650965096509650965096509650919395979092949650565b60086020528060005260406000206000915054906101000a900460ff1681565b6000600454905090565b60045481565b610886613728565b73ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610915576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090c906154c0565b60405180910390fd5b8060068190555050565b610927613728565b73ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146109b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ad906154c0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600280541415610abc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ab390615640565b60405180910390fd5b600280819055506000600760008881526020019081526020016000209050600560009054906101000a900460ff16610b29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b20906155e0565b60405180910390fd5b8060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610bbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bb390615400565b60405180910390fd5b60008090505b8160010160019054906101000a900460ff1660ff16811015611047576000878260058110610bec57fe5b602002015111610c31576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2890615540565b60405180910390fd5b81600701600082815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16868260058110610c8c57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1614610ce7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cde906155a0565b60405180910390fd5b600082600701600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16636352211e8a8560058110610d6357fe5b60200201516040518263ffffffff1660e01b8152600401610d8491906156a0565b60206040518083038186803b158015610d9c57600080fd5b505afa158015610db0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd49190614090565b73ffffffffffffffffffffffffffffffffffffffff1614610e2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e21906155c0565b60405180910390fd5b600089898460058110610e3957fe5b6020020151898560058110610e4a57fe5b602002015133604051602001610e639493929190615078565b604051602081830303815290604052805190602001209050600081604051602001610e8e9190615052565b60405160208183030381529060405280519060200120905060006001828a8760058110610eb757fe5b60200201518a8860058110610ec857fe5b60200201518a8960058110610ed957fe5b602002015160405160008152602001604052604051610efb9493929190615223565b6020604051602081039080840390855afa158015610f1d573d6000803e3d6000fd5b505050602060405103519050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637ac3c02f6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f9157600080fd5b505afa158015610fa5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc99190614090565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611036576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161102d906153e0565b60405180910390fd5b505050508080600101915050610bc2565b5060008090505b8160010160019054906101000a900460ff1660ff1681101561112a5785816005811061107657fe5b602002015173ffffffffffffffffffffffffffffffffffffffff166342842e0e338460040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168a85600581106110c857fe5b60200201516040518463ffffffff1660e01b81526004016110eb939291906150fc565b600060405180830381600087803b15801561110557600080fd5b505af1158015611119573d6000803e3d6000fd5b50505050808060010191505061104e565b5060008090505b8160010160009054906101000a900460ff1660ff168110156112195781600601600082815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3033856006016000868152602001908152602001600020600001546040518463ffffffff1660e01b81526004016111da939291906150fc565b600060405180830381600087803b1580156111f457600080fd5b505af1158015611208573d6000803e3d6000fd5b505050508080600101915050611131565b506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631dbf3bc782600501546040518263ffffffff1660e01b815260040161127891906156a0565b602060405180830381600087803b15801561129257600080fd5b505af11580156112a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ca9190614199565b506000816002015411156113d657600073ffffffffffffffffffffffffffffffffffffffff168160030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611381573373ffffffffffffffffffffffffffffffffffffffff166108fc82600201549081150290604051600060405180830381858888f1935050505015801561137b573d6000803e3d6000fd5b506113d5565b6113d43382600201548360030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166137309092919063ffffffff16565b5b5b8060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1682600001547f02fcdef9298c6a533466daaf962b24b1953ac9fa98b50e68493263c3b593df4f846002015485600501548660010160019054906101000a900460ff168c8860010160009054906101000a900460ff166040518060a001604052808b60060160008081526020019081526020016000206000015481526020018b6006016000600181526020019081526020016000206000015481526020018b6006016000600281526020019081526020016000206000015481526020018b6006016000600381526020019081526020016000206000015481526020018b6006016000600481526020019081526020016000206000015481525060405161153296959493929190615715565b60405180910390a4600760008881526020019081526020016000206000808201600090556001820160006101000a81549060ff02191690556001820160016101000a81549060ff021916905560028201600090556003820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556004820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560058201600090555050506001600281905550505050505050565b6115f7613728565b73ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611686576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167d906154c0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156116f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ed90615300565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611766576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161175d906153c0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611834576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182b90615660565b60405180910390fd5b80600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600560009054906101000a900460ff16611931576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611928906155e0565b60405180910390fd5b60008760ff1611611977576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196e906154e0565b60405180910390fd5b60058760ff1611156119be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119b590615480565b60405180910390fd5b60008560ff1611611a04576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119fb90615360565b60405180910390fd5b60058560ff161115611a4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a42906152e0565b60405180910390fd5b6000831115611de8578173ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611b9e5782600654016000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401611b0891906150e1565b60206040518083038186803b158015611b2057600080fd5b505afa158015611b34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b5891906141eb565b1015611b99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b90906152c0565b60405180910390fd5b611de3565b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2190615380565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611d105782341015611ca2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c99906153a0565b60405180910390fd5b6000611cb784346137b690919063ffffffff16565b90506000811115611d0a573373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611d08573d6000803e3d6000fd5b505b50611de2565b6000829050838173ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401611d4f91906150e1565b60206040518083038186803b158015611d6757600080fd5b505afa158015611d7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9f91906141eb565b1015611de0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dd790615440565b60405180910390fd5b505b5b611ed7565b6006546000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401611e4591906150e1565b60206040518083038186803b158015611e5d57600080fd5b505afa158015611e71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e9591906141eb565b1015611ed6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ecd906154a0565b60405180910390fd5b5b60008090505b8760ff16811015612153576000878260058110611ef657fe5b60200201516000015111611f3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3690615540565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660096000898460058110611f6757fe5b60200201516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415612022576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161201990615580565b60405180910390fd5b600087826005811061203057fe5b60200201516020015190503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16636352211e8a856005811061207a57fe5b6020020151600001516040518263ffffffff1660e01b815260040161209f91906156a0565b60206040518083038186803b1580156120b757600080fd5b505afa1580156120cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ef9190614090565b73ffffffffffffffffffffffffffffffffffffffff1614612145576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213c906155c0565b60405180910390fd5b508080600101915050611edd565b5060008090505b8560ff168110156123835760006009600087846005811061217757fe5b60200201516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561224d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161224490615340565b60405180910390fd5b60008190508073ffffffffffffffffffffffffffffffffffffffff1663640e130860045489866005811061227d57fe5b6020020151602001518a876005811061229257fe5b6020020151604001518b88600581106122a757fe5b6020020151606001518c89600581106122bc57fe5b6020020151608001516040518663ffffffff1660e01b81526004016122e59594939291906156bb565b60206040518083038186803b1580156122fd57600080fd5b505afa158015612311573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123359190614199565b612374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236b90615460565b60405180910390fd5b5050808060010191505061215a565b5060008090505b8760ff16811015612439578681600581106123a157fe5b60200201516020015173ffffffffffffffffffffffffffffffffffffffff166342842e0e33308a85600581106123d357fe5b6020020151600001516040518463ffffffff1660e01b81526004016123fa939291906150fc565b600060405180830381600087803b15801561241457600080fd5b505af1158015612428573d6000803e3d6000fd5b50505050808060010191505061238a565b5060008311156125f4576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156124ef576124ea333085600654016000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613800909392919063ffffffff16565b6125ef565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612570573073ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f1935050505015801561256a573d6000803e3d6000fd5b5061259e565b61259d3330858573ffffffffffffffffffffffffffffffffffffffff16613800909392919063ffffffff16565b5b6125ee33306006546000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613800909392919063ffffffff16565b5b612645565b61264433306006546000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613800909392919063ffffffff16565b5b600460008154809291906001019190505550600454600760006004548152602001908152602001600020600001819055508660076000600454815260200190815260200160002060010160006101000a81548160ff021916908360ff1602179055508460076000600454815260200190815260200160002060010160016101000a81548160ff021916908360ff16021790555060008090505b8760ff16811015612784578681600581106126f557fe5b602002015160076000600454815260200190815260200160002060060160008381526020019081526020016000206000820151816000015560208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505080806001019150506126de565b5060008090505b8560ff16811015612879578481600581106127a257fe5b6020020151600760006004548152602001908152602001600020600701600083815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001019080519060200190612833929190613b31565b5060408201518160020160006101000a81548160ff021916908360ff1602179055506060820151816003015560808201518160040155905050808060010191505061278b565b5082600760006004548152602001908152602001600020600201819055508160076000600454815260200190815260200160002060030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503360076000600454815260200190815260200160002060040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600654600760006004548152602001908152602001600020600501819055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff166004547ff7cb1dace9489604343b4263c9b235428dc3f912546aadc59f5b2afac2bb7f6d866006548c8b8d8c6040516129d096959493929190615779565b60405180910390a460045490509695505050505050565b6129ef613728565b73ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612a7e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a75906154c0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612aee576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae590615420565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415612bbd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bb490615520565b60405180910390fd5b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b612c47613728565b73ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612cd6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ccd906154c0565b60405180910390fd5b80600560006101000a81548160ff02191690831515021790555050565b60096020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600560009054906101000a900460ff1681565b60065481565b612d47613728565b73ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612dd6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dcd906154c0565b60405180910390fd5b600860008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612e63576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e5a90615680565b60405180910390fd5b6001600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006007600083815260200190815260200160002090503373ffffffffffffffffffffffffffffffffffffffff168160040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612f8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f8390615500565b60405180910390fd5b60008090505b8160010160009054906101000a900460ff1660ff1681101561309e5781600601600082815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e308460040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16856006016000868152602001908152602001600020600001546040518463ffffffff1660e01b815260040161305f939291906150fc565b600060405180830381600087803b15801561307957600080fd5b505af115801561308d573d6000803e3d6000fd5b505050508080600101915050612f92565b50600081600201541115613399576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168160030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156131e3576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb3383600201548460050154016040518363ffffffff1660e01b815260040161318b929190615133565b602060405180830381600087803b1580156131a557600080fd5b505af11580156131b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131dd9190614199565b50613394565b600073ffffffffffffffffffffffffffffffffffffffff168160030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561328c573373ffffffffffffffffffffffffffffffffffffffff166108fc82600201549081150290604051600060405180830381858888f19350505050158015613286573d6000803e3d6000fd5b506132e0565b6132df3382600201548360030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166137309092919063ffffffff16565b5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb3383600501546040518363ffffffff1660e01b8152600401613340929190615133565b602060405180830381600087803b15801561335a57600080fd5b505af115801561336e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133929190614199565b505b61344d565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb3383600501546040518363ffffffff1660e01b81526004016133f9929190615133565b602060405180830381600087803b15801561341357600080fd5b505af1158015613427573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061344b9190614199565b505b8060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681600001547fc4caef7e3533865382e608c341581a5e2a1b0d1ac37b0aaf58023ccd4eedfd8e60405160405180910390a3600760008381526020019081526020016000206000808201600090556001820160006101000a81549060ff02191690556001820160016101000a81549060ff021916905560028201600090556003820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556004820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600582016000905550505050565b613569613728565b73ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146135f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135ef906154c0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415613668576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161365f90615320565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600033905090565b6137b18363a9059cbb60e01b848460405160240161374f9291906151df565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613889565b505050565b60006137f883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613950565b905092915050565b613883846323b872dd60e01b8585856040516024016138219392919061515c565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613889565b50505050565b60606138eb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166139ab9092919063ffffffff16565b905060008151111561394b578080602001905181019061390b9190614199565b61394a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161394190615600565b60405180910390fd5b5b505050565b6000838311158290613998576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161398f919061529e565b60405180910390fd5b5060008385039050809150509392505050565b60606139ba84846000856139c3565b90509392505050565b60606139ce85613ae6565b613a0d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a0490615560565b60405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff168587604051613a379190615026565b60006040518083038185875af1925050503d8060008114613a74576040519150601f19603f3d011682016040523d82523d6000602084013e613a79565b606091505b50915091508115613a8e578092505050613ade565b600081511115613aa15780518082602001fd5b836040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613ad5919061529e565b60405180910390fd5b949350505050565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f9150808214158015613b2857506000801b8214155b92505050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613b7257805160ff1916838001178555613ba0565b82800160010185558215613ba0579182015b82811115613b9f578251825591602001919060010190613b84565b5b509050613bad9190613bb1565b5090565b613bd391905b80821115613bcf576000816000905550600101613bb7565b5090565b90565b600081359050613be581615c10565b92915050565b600081519050613bfa81615c10565b92915050565b600082601f830112613c1157600080fd5b6005613c24613c1f8261587f565b615852565b91508183856020840282011115613c3a57600080fd5b60005b83811015613c6a5781613c508882613bd6565b845260208401935060208301925050600181019050613c3d565b5050505092915050565b600082601f830112613c8557600080fd5b6005613c98613c93826158a1565b615852565b91508183856020840282011115613cae57600080fd5b60005b83811015613cde5781613cc48882613ed3565b845260208401935060208301925050600181019050613cb1565b5050505092915050565b600082601f830112613cf957600080fd5b6005613d0c613d07826158c3565b615852565b91508183856040840282011115613d2257600080fd5b60005b83811015613d525781613d388882613f3c565b845260208401935060408301925050600181019050613d25565b5050505092915050565b600082601f830112613d6d57600080fd5b6005613d80613d7b826158e5565b615852565b9150818360005b83811015613db75781358601613d9d8882613f88565b845260208401935060208301925050600181019050613d87565b5050505092915050565b600082601f830112613dd257600080fd5b6005613de5613de082615907565b615852565b91508183856020840282011115613dfb57600080fd5b60005b83811015613e2b5781613e118882614028565b845260208401935060208301925050600181019050613dfe565b5050505092915050565b600082601f830112613e4657600080fd5b6005613e59613e5482615929565b615852565b91508183856020840282011115613e6f57600080fd5b60005b83811015613e9f5781613e858882614052565b845260208401935060208301925050600181019050613e72565b5050505092915050565b600081359050613eb881615c27565b92915050565b600081519050613ecd81615c27565b92915050565b600081359050613ee281615c3e565b92915050565b600082601f830112613ef957600080fd5b8135613f0c613f078261594b565b615852565b91508082526020830160208301858383011115613f2857600080fd5b613f33838284615b66565b50505092915050565b600060408284031215613f4e57600080fd5b613f586040615852565b90506000613f6884828501614028565b6000830152506020613f7c84828501613bd6565b60208301525092915050565b600060a08284031215613f9a57600080fd5b613fa460a0615852565b90506000613fb484828501613bd6565b600083015250602082013567ffffffffffffffff811115613fd457600080fd5b613fe084828501613ee8565b6020830152506040613ff484828501614052565b604083015250606061400884828501613ed3565b606083015250608061401c84828501613ed3565b60808301525092915050565b60008135905061403781615c55565b92915050565b60008151905061404c81615c55565b92915050565b60008135905061406181615c6c565b92915050565b60006020828403121561407957600080fd5b600061408784828501613bd6565b91505092915050565b6000602082840312156140a257600080fd5b60006140b084828501613beb565b91505092915050565b600080604083850312156140cc57600080fd5b60006140da85828601613bd6565b92505060206140eb85828601613bd6565b9150509250929050565b6000806000806080858703121561410b57600080fd5b600061411987828801613bd6565b945050602061412a87828801613bd6565b935050604061413b87828801614028565b925050606085013567ffffffffffffffff81111561415857600080fd5b61416487828801613ee8565b91505092959194509250565b60006020828403121561418257600080fd5b600061419084828501613ea9565b91505092915050565b6000602082840312156141ab57600080fd5b60006141b984828501613ebe565b91505092915050565b6000602082840312156141d457600080fd5b60006141e284828501614028565b91505092915050565b6000602082840312156141fd57600080fd5b600061420b8482850161403d565b91505092915050565b600080600080600080610340878903121561422e57600080fd5b600061423c89828a01614028565b965050602061424d89828a01613dc1565b95505060c061425e89828a01613c00565b94505061016061427089828a01613e35565b93505061020061428289828a01613c74565b9250506102a061429489828a01613c74565b9150509295509295509295565b6000806000806000806101e087890312156142bb57600080fd5b60006142c989828a01614052565b96505060206142da89828a01613ce8565b9550506101606142ec89828a01614052565b94505061018087013567ffffffffffffffff81111561430a57600080fd5b61431689828a01613d5c565b9350506101a061432889828a01614028565b9250506101c061433a89828a01613bd6565b9150509295509295509295565b60006143538383614f1f565b60408301905092915050565b600061436b8383614f4e565b905092915050565b600061437f8383614fc4565b60208301905092915050565b61439481615afa565b82525050565b6143ab6143a682615a6f565b615bba565b82525050565b6143ba81615a5d565b82525050565b6143c981615a5d565b82525050565b6143e06143db82615a5d565b615ba8565b82525050565b6143ef81615995565b6143f981846159f3565b925061440482615977565b8060005b8381101561443557815161441c8782614347565b9650614427836159cc565b925050600181019050614408565b505050505050565b6000614448826159a0565b61445281856159fe565b93508360208202850161446485615981565b8060005b858110156144a05784840389528151614481858261435f565b945061448c836159d9565b925060208a01995050600181019050614468565b50829750879550505050505092915050565b6144bb816159ab565b6144c58184615a09565b92506144d08261598b565b8060005b838110156145015781516144e88782614373565b96506144f3836159e6565b9250506001810190506144d4565b505050505050565b61451281615a81565b82525050565b61452181615a8d565b82525050565b61453081615a8d565b82525050565b61454761454282615a8d565b615bcc565b82525050565b61455681615a97565b82525050565b6000614567826159b6565b6145718185615a14565b9350614581818560208601615b75565b61458a81615bf2565b840191505092915050565b60006145a0826159b6565b6145aa8185615a25565b93506145ba818560208601615b75565b6145c381615bf2565b840191505092915050565b60006145d9826159b6565b6145e38185615a36565b93506145f3818560208601615b75565b80840191505092915050565b61460881615b0c565b82525050565b6000614619826159c1565b6146238185615a41565b9350614633818560208601615b75565b61463c81615bf2565b840191505092915050565b6000614654601f83615a41565b91507f6e6f7420656e6f7567682043575320666f7220666565202620626f756e7479006000830152602082019050919050565b6000614694602f83615a52565b91507f6f6e455243373231526563656976656428616464726573732c6164647265737360008301527f2c75696e743235362c62797465732900000000000000000000000000000000006020830152602f82019050919050565b60006146fa601c83615a52565b91507f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000830152601c82019050919050565b600061473a601f83615a41565b91507f63616e742072657175657374206d6f7265207468616e203520746f6b656e73006000830152602082019050919050565b600061477a601383615a41565b91507f696e76616c6964206e66742061646472657373000000000000000000000000006000830152602082019050919050565b60006147ba602683615a41565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614820602183615a41565b91507f726571756573746564206e6674206164647265737320756e737570706f72746560008301527f64000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614886601f83615a41565b91507f73686f756c642072657175697265206174206c65617374206f6e65206e6674006000830152602082019050919050565b60006148c6601c83615a41565b91507f626f756e74792061646472657373206e6f7420737570706f72746564000000006000830152602082019050919050565b6000614906601c83615a41565b91507f696e73756666696369656e74207472616e7366657220616d6f756e74000000006000830152602082019050919050565b6000614946601983615a41565b91507f696e76616c6964204e6674506172616d732061646472657373000000000000006000830152602082019050919050565b6000614986601383615a41565b91507f566572696669636174696f6e206661696c6564000000000000000000000000006000830152602082019050919050565b60006149c6601883615a41565b91507f63616e74206275792073656c662d6d616465206f6666657200000000000000006000830152602082019050919050565b6000614a06600f83615a41565b91507f696e76616c6964206164647265737300000000000000000000000000000000006000830152602082019050919050565b6000614a46601e83615a41565b91507f6e6f7420656e6f756768206d6f6e657920746f2070617920626f756e747900006000830152602082019050919050565b6000614a86601283615a41565b91507f696e76616c6964206e667420506172616d7300000000000000000000000000006000830152602082019050919050565b6000614ac6601d83615a41565b91507f63616e74206f66666572206d6f7265207468616e203520746f6b656e730000006000830152602082019050919050565b6000614b06601683615a41565b91507f6e6f7420656e6f7567682043575320666f7220666565000000000000000000006000830152602082019050919050565b6000614b46602083615a41565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000614b86601d83615a41565b91507f73686f756c64206f66666572206174206c65617374206f6e65206e66740000006000830152602082019050919050565b6000614bc6601e83615a41565b91507f73656e646572206973206e6f742063726561746f72206f66206f6666657200006000830152602082019050919050565b6000614c06601c83615a41565b91507f6e6674206164647265737320616c72656164792064697361626c6564000000006000830152602082019050919050565b6000614c46601d83615a41565b91507f6e6674206964206d7573742062652067726561746572207468616e20300000006000830152602082019050919050565b6000614c86601d83615a41565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b6000614cc6601f83615a41565b91507f6f666665726564206e6674206164647265737320756e737570706f72746564006000830152602082019050919050565b6000614d06601d83615a41565b91507f77726f6e672072657175657374656420746f6b656e20616464726573730000006000830152602082019050919050565b6000614d46601783615a41565b91507f73656e646572206e6f74206f776e6572206f66206e66740000000000000000006000830152602082019050919050565b6000614d86601183615a41565b91507f74726164652069732064697361626c65640000000000000000000000000000006000830152602082019050919050565b6000614dc6602a83615a41565b91507f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008301527f6f742073756363656564000000000000000000000000000000000000000000006020830152604082019050919050565b6000614e2c601683615a41565b91507f626f756e747920616c72656164792072656d6f766564000000000000000000006000830152602082019050919050565b6000614e6c601f83615a41565b91507f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006000830152602082019050919050565b6000614eac601b83615a41565b91507f6e6674206164647265737320616c726561647920656e61626c656400000000006000830152602082019050919050565b6000614eec601883615a41565b91507f626f756e747920616c726561647920737570706f7274656400000000000000006000830152602082019050919050565b604082016000820151614f356000850182614fc4565b506020820151614f4860208501826143b1565b50505050565b600060a083016000830151614f6660008601826143b1565b5060208301518482036020860152614f7e828261455c565b9150506040830151614f936040860182615008565b506060830151614fa66060860182614518565b506080830151614fb96080860182614518565b508091505092915050565b614fcd81615ae3565b82525050565b614fdc81615ae3565b82525050565b614ff3614fee82615ae3565b615be8565b82525050565b61500281615b54565b82525050565b61501181615aed565b82525050565b61502081615aed565b82525050565b600061503282846145ce565b915081905092915050565b600061504882614687565b9150819050919050565b600061505d826146ed565b91506150698284614536565b60208201915081905092915050565b60006150848287614fe2565b6020820191506150948286614fe2565b6020820191506150a482856143cf565b6014820191506150b4828461439a565b60148201915081905095945050505050565b60006020820190506150db60008301846143c0565b92915050565b60006020820190506150f6600083018461438b565b92915050565b6000606082019050615111600083018661438b565b61511e602083018561438b565b61512b6040830184614fd3565b949350505050565b6000604082019050615148600083018561438b565b6151556020830184614fd3565b9392505050565b600060608201905061517160008301866143c0565b61517e60208301856143c0565b61518b6040830184614fd3565b949350505050565b60006080820190506151a860008301876143c0565b6151b560208301866143c0565b6151c26040830185614fd3565b81810360608301526151d48184614595565b905095945050505050565b60006040820190506151f460008301856143c0565b6152016020830184614fd3565b9392505050565b600060208201905061521d6000830184614509565b92915050565b60006080820190506152386000830187614527565b6152456020830186615017565b6152526040830185614527565b61525f6060830184614527565b95945050505050565b600060208201905061527d600083018461454d565b92915050565b600060208201905061529860008301846145ff565b92915050565b600060208201905081810360008301526152b8818461460e565b905092915050565b600060208201905081810360008301526152d981614647565b9050919050565b600060208201905081810360008301526152f98161472d565b9050919050565b600060208201905081810360008301526153198161476d565b9050919050565b60006020820190508181036000830152615339816147ad565b9050919050565b6000602082019050818103600083015261535981614813565b9050919050565b6000602082019050818103600083015261537981614879565b9050919050565b60006020820190508181036000830152615399816148b9565b9050919050565b600060208201905081810360008301526153b9816148f9565b9050919050565b600060208201905081810360008301526153d981614939565b9050919050565b600060208201905081810360008301526153f981614979565b9050919050565b60006020820190508181036000830152615419816149b9565b9050919050565b60006020820190508181036000830152615439816149f9565b9050919050565b6000602082019050818103600083015261545981614a39565b9050919050565b6000602082019050818103600083015261547981614a79565b9050919050565b6000602082019050818103600083015261549981614ab9565b9050919050565b600060208201905081810360008301526154b981614af9565b9050919050565b600060208201905081810360008301526154d981614b39565b9050919050565b600060208201905081810360008301526154f981614b79565b9050919050565b6000602082019050818103600083015261551981614bb9565b9050919050565b6000602082019050818103600083015261553981614bf9565b9050919050565b6000602082019050818103600083015261555981614c39565b9050919050565b6000602082019050818103600083015261557981614c79565b9050919050565b6000602082019050818103600083015261559981614cb9565b9050919050565b600060208201905081810360008301526155b981614cf9565b9050919050565b600060208201905081810360008301526155d981614d39565b9050919050565b600060208201905081810360008301526155f981614d79565b9050919050565b6000602082019050818103600083015261561981614db9565b9050919050565b6000602082019050818103600083015261563981614e1f565b9050919050565b6000602082019050818103600083015261565981614e5f565b9050919050565b6000602082019050818103600083015261567981614e9f565b9050919050565b6000602082019050818103600083015261569981614edf565b9050919050565b60006020820190506156b56000830184614fd3565b92915050565b600060a0820190506156d06000830188614fd3565b81810360208301526156e28187614595565b90506156f16040830186615017565b6156fe6060830185614527565b61570b6080830184614527565b9695505050505050565b60006101c08201905061572b6000830189614fd3565b6157386020830188614fd3565b6157456040830187614ff9565b61575260608301866144b2565b615760610100830185614ff9565b61576e6101208301846144b2565b979650505050505050565b60006101e08201905061578f6000830189614fd3565b61579c6020830188614fd3565b6157a96040830187614ff9565b6157b66060830186614ff9565b6157c360808301856143e6565b8181036101c08301526157d6818461443d565b9050979650505050505050565b600060e0820190506157f8600083018a614fd3565b6158056020830189615017565b6158126040830188615017565b61581f6060830187614fd3565b61582c60808301866143c0565b61583960a08301856143c0565b61584660c0830184614fd3565b98975050505050505050565b6000604051905081810181811067ffffffffffffffff8211171561587557600080fd5b8060405250919050565b600067ffffffffffffffff82111561589657600080fd5b602082029050919050565b600067ffffffffffffffff8211156158b857600080fd5b602082029050919050565b600067ffffffffffffffff8211156158da57600080fd5b602082029050919050565b600067ffffffffffffffff8211156158fc57600080fd5b602082029050919050565b600067ffffffffffffffff82111561591e57600080fd5b602082029050919050565b600067ffffffffffffffff82111561594057600080fd5b602082029050919050565b600067ffffffffffffffff82111561596257600080fd5b601f19601f8301169050602081019050919050565b6000819050919050565b6000819050919050565b6000819050919050565b600060059050919050565b600060059050919050565b600060059050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b600081905092915050565b600081905092915050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000615a6882615ac3565b9050919050565b6000615a7a82615ac3565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b6000615b0582615b30565b9050919050565b6000615b1782615b1e565b9050919050565b6000615b2982615ac3565b9050919050565b6000615b3b82615b42565b9050919050565b6000615b4d82615ac3565b9050919050565b6000615b5f82615aed565b9050919050565b82818337600083830152505050565b60005b83811015615b93578082015181840152602081019050615b78565b83811115615ba2576000848401525b50505050565b6000615bb382615bd6565b9050919050565b6000615bc582615bd6565b9050919050565b6000819050919050565b6000615be182615c03565b9050919050565b6000819050919050565b6000601f19601f8301169050919050565b60008160601b9050919050565b615c1981615a5d565b8114615c2457600080fd5b50565b615c3081615a81565b8114615c3b57600080fd5b50565b615c4781615a8d565b8114615c5257600080fd5b50565b615c5e81615ae3565b8114615c6957600080fd5b50565b615c7581615aed565b8114615c8057600080fd5b5056fea2646970667358221220e06560d9bd49519047523e7fc9d1da896e97caaa5b8614e2ac83dfa9fa7f818a64736f6c634300060700330000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000006fc9651f45b262ae6338a701d563ab118b1ec0ce0000000000000000000000008033ebe98607fd9b596ec0d746ed197ef3eae311

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000006fc9651f45b262ae6338a701d563ab118b1ec0ce0000000000000000000000008033ebe98607fd9b596ec0d746ed197ef3eae311

-----Decoded View---------------
Arg [0] : _feeRate (uint256): 1000000000000000000
Arg [1] : _crownsAddress (address): 0x6fc9651f45b262ae6338a701d563ab118b1ec0ce
Arg [2] : _signerAddress (address): 0x8033ebe98607fd9b596ec0d746ed197ef3eae311

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [1] : 0000000000000000000000006fc9651f45b262ae6338a701d563ab118b1ec0ce
Arg [2] : 0000000000000000000000008033ebe98607fd9b596ec0d746ed197ef3eae311


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.