Contract 0xC971507165a17290cbAbC7133f95816D7a01bedD

Contract Overview

Balance:
1 DEV

Token:
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x3e926e42c46bd4ff27eddf54ab32f2d9fd235cd9727a165dc0bacd4a18f13a73Accept Offer48879772023-08-10 4:14:5446 days 12 hrs ago0xe8e15b448e1e777490fcfa1fed51d0eb47b61bbd IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.000101095
0x89ad89c68da116ab00ed672f91d9996d869cc0f6e8a6758ae22ac715d322faf9Accept Offer48879772023-08-10 4:14:5446 days 12 hrs ago0xe8e15b448e1e777490fcfa1fed51d0eb47b61bbd IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.00021776625
0xda6393ce13951e1987c19c29041bd37a3d87d5dc7e114e92d926ca511cdbf26dAdd Supported Bo...48762742023-08-08 7:17:4848 days 9 hrs ago0xe71d14a3fa97292bde885c1d134be4698e09b3b7 IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.0001593865
0x9bc1c43faf63cabf2e5dddd185f2575e64fe3590fbb680433b440c40514bdc17Enable Supported...47036592023-07-10 10:37:4277 days 6 hrs ago0xe71d14a3fa97292bde885c1d134be4698e09b3b7 IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.000159601
0xe48bcdd6979b6e2b7dec1950c28848c53580e388f9903ddb30f6fe99f6ee8fc9Cancel Offer45778872023-06-20 10:37:3697 days 6 hrs ago0xfcdf05159a3585f78c8e328f25c74472e7d627ae IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.00009358
0x3b7a0ae0219cd36789f5880fa4cc5d1d2bbb95ff2622ddd567d1a83d839e2d510xa760d79a45778842023-06-20 10:37:0097 days 6 hrs ago0xfcdf05159a3585f78c8e328f25c74472e7d627ae IN 0xc971507165a17290cbabc7133f95816d7a01bedd0.001 DEV0.0000745955
0xf9415efc6e0c846636c5ade62bb19dcf40af221a5f75a6c2e036b23b874e19a50xa760d79a45774002023-06-20 8:44:3097 days 7 hrs ago0x5e6eb2bc758d07d0af367610816c630e3bd11c37 IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.000079186375
0x353a45771706e4a2827431022b7f33682f5810233128b2289ed935464593fefdCancel Offer45706722023-06-19 7:09:1898 days 9 hrs ago0x5e6eb2bc758d07d0af367610816c630e3bd11c37 IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.00009254875
0x2514563710416ba65b21749d7da7ef0d73da55aa4022619f623b8a642ac0a814Accept Offer45706682023-06-19 7:08:2498 days 9 hrs ago0x5e6eb2bc758d07d0af367610816c630e3bd11c37 IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.000220166875
0x0bf9827a45ee40edc5ccd82a4000afb51005f4ba90ec3f90565ee2d637225d280xa760d79a45706612023-06-19 7:06:5498 days 9 hrs ago0x5bded8f6bdae766c361edae25c5dc966bcaf8f43 IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.00008172475
0xc4d464d09436723df1c98855634d2dd211fe9c113d19f6abcac325260607fd200xa760d79a45706132023-06-19 6:56:1298 days 9 hrs ago0x5e6eb2bc758d07d0af367610816c630e3bd11c37 IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.000068751
0x6b44e2f2168879f7a408ef9978aefad3214761db3b3648d1ada6585fc908c29dCancel Offer45705872023-06-19 6:50:2498 days 9 hrs ago0x5bded8f6bdae766c361edae25c5dc966bcaf8f43 IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.00014661375
0x6fd2509ecec418189cfa476500c31a9dfe781a3f260e4491bc76db7adc43ca89Cancel Offer38630232023-03-03 6:38:54206 days 10 hrs ago0x5bded8f6bdae766c361edae25c5dc966bcaf8f43 IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.0001006525
0x1976bd266a314572ab888506581298cf3b24ea01859845db7aacd5f72e92f8080xa760d79a38630072023-03-03 6:35:36206 days 10 hrs ago0x5bded8f6bdae766c361edae25c5dc966bcaf8f43 IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.000080451875
0x106e5a2770eae7c40bd61865e1dab61160998bee48b63bc59a34220eacf59826Accept Offer38629442023-03-03 6:22:54206 days 10 hrs ago0xe8e15b448e1e777490fcfa1fed51d0eb47b61bbd IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.00022174875
0xa9444c9b5a0083d0c08d05a6a2765db8f3806a18a0494eb2c75d1ef8bf2efe380xa760d79a38629212023-03-03 6:18:04206 days 10 hrs ago0x5bded8f6bdae766c361edae25c5dc966bcaf8f43 IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.000091455222
0x243803358d8be1d3fa3e2c635699790fbb5b13541558171e327d2d9d1b496cedAccept Offer38585022023-03-02 15:04:06207 days 1 hr ago0xe8e15b448e1e777490fcfa1fed51d0eb47b61bbd IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.000217855511
0xf4e3388e0512ad9b28a845b4aa4d531da2c202859d80af4ea523d591c390e4e0Accept Offer38584902023-03-02 15:01:30207 days 1 hr ago0xe8e15b448e1e777490fcfa1fed51d0eb47b61bbd IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.000220793125
0x9cf540e385b4803989b31f6969fdce426f25335ff2db366977921342bc7443580xa760d79a38584792023-03-02 14:59:06207 days 1 hr ago0x5bded8f6bdae766c361edae25c5dc966bcaf8f43 IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.000092184865
0xd934ca689b73d10d0baba6c277df2b959bdacfa911045f819cb265b259feebe30xa760d79a38582962023-03-02 14:21:30207 days 2 hrs ago0x5bded8f6bdae766c361edae25c5dc966bcaf8f43 IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.000105100737
0x353c1cbda83aa66c1ed1e1ab315beb2031cbd7f3f9765f100e8efcc16c0307faCancel Offer38575772023-03-02 11:53:30207 days 4 hrs ago0xa703c1c587de2815f35096ea6cce4b5d71d22b77 IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.000098694245
0xd2b3ab11654a6c8a7be62b4e63b1a38cccba9addc519a1e552af9c2397c13f9bCancel Offer38568302023-03-02 9:17:12207 days 7 hrs ago0x37824ea65394388d92f6ebd3b1186c463c0cdcdb IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.0001055525
0x9624ecf24d825a6456aa416dd5a053987f0d817bab9d9f3651f001d462847f880xa760d79a38568162023-03-02 9:14:12207 days 7 hrs ago0x37824ea65394388d92f6ebd3b1186c463c0cdcdb IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.000085120145
0x7bfd5f1ae1559f4991c1f61db9c3d77c6f18e76789055c1756e8bd26479fe3760xa760d79a38568042023-03-02 9:11:00207 days 7 hrs ago0xa703c1c587de2815f35096ea6cce4b5d71d22b77 IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.00007124
0x6398cb5f627c0c6934f4641e6f6bb023f0521abf9f5db0e86e9cf4739cc8dab9Accept Offer38499972023-03-01 9:27:12208 days 7 hrs ago0x37824ea65394388d92f6ebd3b1186c463c0cdcdb IN 0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV0.00022174875
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x3e926e42c46bd4ff27eddf54ab32f2d9fd235cd9727a165dc0bacd4a18f13a7348879772023-08-10 4:14:5446 days 12 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0xfde9cad69e98b3cc8c998a8f2094293cb0bd69110 DEV
0x89ad89c68da116ab00ed672f91d9996d869cc0f6e8a6758ae22ac715d322faf948879772023-08-10 4:14:5446 days 12 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0xfde9cad69e98b3cc8c998a8f2094293cb0bd69110 DEV
0x89ad89c68da116ab00ed672f91d9996d869cc0f6e8a6758ae22ac715d322faf948879772023-08-10 4:14:5446 days 12 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0x9ceab9b5530762de5409f2715e85663405129e540 DEV
0x89ad89c68da116ab00ed672f91d9996d869cc0f6e8a6758ae22ac715d322faf948879772023-08-10 4:14:5446 days 12 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0x9ceab9b5530762de5409f2715e85663405129e540 DEV
0x89ad89c68da116ab00ed672f91d9996d869cc0f6e8a6758ae22ac715d322faf948879772023-08-10 4:14:5446 days 12 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0x9ceab9b5530762de5409f2715e85663405129e540 DEV
0x89ad89c68da116ab00ed672f91d9996d869cc0f6e8a6758ae22ac715d322faf948879772023-08-10 4:14:5446 days 12 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0x7a4e463f0352be1f805f3b4f5ffc1643cde471a90 DEV
0x89ad89c68da116ab00ed672f91d9996d869cc0f6e8a6758ae22ac715d322faf948879772023-08-10 4:14:5446 days 12 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0x00000000000000000000000000000000000000010 DEV
0x89ad89c68da116ab00ed672f91d9996d869cc0f6e8a6758ae22ac715d322faf948879772023-08-10 4:14:5446 days 12 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0x9ceab9b5530762de5409f2715e85663405129e540 DEV
0xe48bcdd6979b6e2b7dec1950c28848c53580e388f9903ddb30f6fe99f6ee8fc945778872023-06-20 10:37:3697 days 6 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0xfde9cad69e98b3cc8c998a8f2094293cb0bd69110 DEV
0xe48bcdd6979b6e2b7dec1950c28848c53580e388f9903ddb30f6fe99f6ee8fc945778872023-06-20 10:37:3697 days 6 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0xfcdf05159a3585f78c8e328f25c74472e7d627ae0.001 DEV
0xe48bcdd6979b6e2b7dec1950c28848c53580e388f9903ddb30f6fe99f6ee8fc945778872023-06-20 10:37:3697 days 6 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0x0fa0a690d71430f1a2da08e82ba50f18dcad452a0 DEV
0x3b7a0ae0219cd36789f5880fa4cc5d1d2bbb95ff2622ddd567d1a83d839e2d5145778842023-06-20 10:37:0097 days 6 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0xfde9cad69e98b3cc8c998a8f2094293cb0bd69110 DEV
0x3b7a0ae0219cd36789f5880fa4cc5d1d2bbb95ff2622ddd567d1a83d839e2d5145778842023-06-20 10:37:0097 days 6 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0xc971507165a17290cbabc7133f95816d7a01bedd0.001 DEV
0x3b7a0ae0219cd36789f5880fa4cc5d1d2bbb95ff2622ddd567d1a83d839e2d5145778842023-06-20 10:37:0097 days 6 hrs ago 0x0fa0a690d71430f1a2da08e82ba50f18dcad452a0xc971507165a17290cbabc7133f95816d7a01bedd0 DEV
0x3b7a0ae0219cd36789f5880fa4cc5d1d2bbb95ff2622ddd567d1a83d839e2d5145778842023-06-20 10:37:0097 days 6 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0x0fa0a690d71430f1a2da08e82ba50f18dcad452a0 DEV
0x3b7a0ae0219cd36789f5880fa4cc5d1d2bbb95ff2622ddd567d1a83d839e2d5145778842023-06-20 10:37:0097 days 6 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0x322049260bf9c7046690336ab77c49284c7ae6a40 DEV
0x3b7a0ae0219cd36789f5880fa4cc5d1d2bbb95ff2622ddd567d1a83d839e2d5145778842023-06-20 10:37:0097 days 6 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0x0fa0a690d71430f1a2da08e82ba50f18dcad452a0 DEV
0xf9415efc6e0c846636c5ade62bb19dcf40af221a5f75a6c2e036b23b874e19a545774002023-06-20 8:44:3097 days 7 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0xfde9cad69e98b3cc8c998a8f2094293cb0bd69110 DEV
0xf9415efc6e0c846636c5ade62bb19dcf40af221a5f75a6c2e036b23b874e19a545774002023-06-20 8:44:3097 days 7 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0xf2c84cb3d1e9fac001f36c965260aa2a9c9d822d0 DEV
0xf9415efc6e0c846636c5ade62bb19dcf40af221a5f75a6c2e036b23b874e19a545774002023-06-20 8:44:3097 days 7 hrs ago 0x9ceab9b5530762de5409f2715e85663405129e540xc971507165a17290cbabc7133f95816d7a01bedd0 DEV
0xf9415efc6e0c846636c5ade62bb19dcf40af221a5f75a6c2e036b23b874e19a545774002023-06-20 8:44:3097 days 7 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0x9ceab9b5530762de5409f2715e85663405129e540 DEV
0xf9415efc6e0c846636c5ade62bb19dcf40af221a5f75a6c2e036b23b874e19a545774002023-06-20 8:44:3097 days 7 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0x322049260bf9c7046690336ab77c49284c7ae6a40 DEV
0xf9415efc6e0c846636c5ade62bb19dcf40af221a5f75a6c2e036b23b874e19a545774002023-06-20 8:44:3097 days 7 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0x9ceab9b5530762de5409f2715e85663405129e540 DEV
0xf9415efc6e0c846636c5ade62bb19dcf40af221a5f75a6c2e036b23b874e19a545774002023-06-20 8:44:3097 days 7 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0xf2c84cb3d1e9fac001f36c965260aa2a9c9d822d0 DEV
0x353a45771706e4a2827431022b7f33682f5810233128b2289ed935464593fefd45706722023-06-19 7:09:1898 days 9 hrs ago 0xc971507165a17290cbabc7133f95816d7a01bedd0xfde9cad69e98b3cc8c998a8f2094293cb0bd69110 DEV
[ Download CSV Export 
Index Block
Loading

Similar Match Source Code
This contract matches the deployed ByteCode of the Source Code for Contract 0xc812d69501A83c5fF5AC2C82619D0DA17f975551
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
NftSwap

Compiler Version
v0.6.7+commit.b8d736ae

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
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 trade
    /// @param _tradeEnabled set tradeEnabled to true/false
    function enableTrade(bool _tradeEnabled) external onlyOwner { tradeEnabled = _tradeEnabled; }

    /// @notice add supported nft contract
    /// @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 supported nft token
    /// @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 add supported currency address for bounty
    /// @param _bountyAddress ERC20 contract address
    function addSupportedBountyAddress(address _bountyAddress) external onlyOwner {
        require(!supportedBountyAddresses[_bountyAddress], "bounty already supported");
        supportedBountyAddresses[_bountyAddress] = true;
    }

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

    /// @notice change fee amount
    /// @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 fetch offer object at offerId and nftAddress
    /// @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 create a new offer
    /// @param _offeredTokensAmount how many nfts to offer
    /// @param _offeredTokens array of five OfferedToken structs
    /// @param _requestedTokensAmount amount of required nfts
    /// @param _requestedTokens array of five RequestedToken structs
    /// @param _bounty additional cws to offer to buyer
    /// @param _bountyAddress currency contract address for bounty
    /// @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 make a trade
    /// @param _offerId offer unique ID
    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 cancel the offer
    /// @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";

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"}]

60806040526001600560006101000a81548160ff0219169083151502179055503480156200002c57600080fd5b5060405162006136380380620061368339818101604052810190620000529190620002cc565b600062000064620001e060201b60201c565b905080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3506001600281905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156200017e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200017590620003a6565b60405180910390fd5b6200018f82620001e860201b60201c565b8260068190555080600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050506200046d565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156200025b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200025290620003c8565b60405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600081519050620002af8162000439565b92915050565b600081519050620002c68162000453565b92915050565b600080600060608486031215620002e257600080fd5b6000620002f286828701620002b5565b935050602062000305868287016200029e565b925050604062000318868287016200029e565b9150509250925092565b600062000331601383620003ea565b91507f696e76616c6964206377732061646472657373000000000000000000000000006000830152602082019050919050565b600062000373601c83620003ea565b91507f43726f776e732063616e2774206265207a65726f2061646472657373000000006000830152602082019050919050565b60006020820190508181036000830152620003c18162000322565b9050919050565b60006020820190508181036000830152620003e38162000364565b9050919050565b600082825260208201905092915050565b600062000408826200040f565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6200044481620003fb565b81146200045057600080fd5b50565b6200045e816200042f565b81146200046a57600080fd5b50565b615cb9806200047d6000396000f3fe60806040526004361061012e5760003560e01c80638da5cb5b116100ab578063d621e8131161006f578063d621e81314610415578063ddca3f4314610440578063e388bf211461046b578063ea5ed05d14610494578063ef706adf146104bf578063f2fde38b146104e85761012f565b80638da5cb5b1461032b578063a760d79a14610356578063af13b97114610386578063c00f04d1146103af578063cdd21397146103d85761012f565b8063643268c9116100f2578063643268c91461027b57806369fe0e2d146102a6578063715018a6146102cf5780637e6c2378146102e6578063834a37b9146103025761012f565b806306edf3461461016a578063150b7a02146101935780634579268a146101d057806347eda88f1461021357806359e148fc146102505761012f565b5b7f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f885258743334604051610160929190615133565b60405180910390a1005b34801561017657600080fd5b50610191600480360381019061018c9190614067565b610511565b005b34801561019f57600080fd5b506101ba60048036038101906101b591906140f5565b61068f565b6040516101c79190615268565b60405180910390f35b3480156101dc57600080fd5b506101f760048036038101906101f291906141c2565b61072c565b60405161020a97969594939291906157e3565b60405180910390f35b34801561021f57600080fd5b5061023a60048036038101906102359190614067565b61084e565b6040516102479190615208565b60405180910390f35b34801561025c57600080fd5b5061026561086e565b60405161027291906156a0565b60405180910390f35b34801561028757600080fd5b50610290610878565b60405161029d91906156a0565b60405180910390f35b3480156102b257600080fd5b506102cd60048036038101906102c891906141c2565b61087e565b005b3480156102db57600080fd5b506102e461091f565b005b61030060048036038101906102fb9190614214565b610a77565b005b34801561030e57600080fd5b50610329600480360381019061032491906140b9565b6115ef565b005b34801561033757600080fd5b506103406118b6565b60405161034d91906150c6565b60405180910390f35b610370600480360381019061036b91906142a1565b6118e0565b60405161037d91906156a0565b60405180910390f35b34801561039257600080fd5b506103ad60048036038101906103a89190614067565b6129e7565b005b3480156103bb57600080fd5b506103d660048036038101906103d19190614170565b612c3f565b005b3480156103e457600080fd5b506103ff60048036038101906103fa9190614067565b612cf3565b60405161040c91906150c6565b60405180910390f35b34801561042157600080fd5b5061042a612d26565b6040516104379190615208565b60405180910390f35b34801561044c57600080fd5b50610455612d39565b60405161046291906156a0565b60405180910390f35b34801561047757600080fd5b50610492600480360381019061048d9190614067565b612d3f565b005b3480156104a057600080fd5b506104a9612ebe565b6040516104b69190615283565b60405180910390f35b3480156104cb57600080fd5b506104e660048036038101906104e191906141c2565b612ee3565b005b3480156104f457600080fd5b5061050f600480360381019061050a9190614067565b613561565b005b610519613728565b73ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146105a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161059f906154c0565b60405180910390fd5b600860008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610634576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161062b90615620565b60405180910390fd5b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008473ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16146106d057600060e01b9050610724565b7f0895c277367ff99b8c0dec875f3149fc2c82df592f63ca6f0747ac2095169087858585856040516107059493929190615193565b60405180910390a16040516107199061503d565b604051809103902090505b949350505050565b60008060008060008060006007600089815260200190815260200160002060000154600760008a815260200190815260200160002060010160009054906101000a900460ff16600760008b815260200190815260200160002060010160019054906101000a900460ff16600760008c815260200190815260200160002060020154600760008d815260200190815260200160002060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600760008e815260200190815260200160002060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600760008f8152602001908152602001600020600501548191509650965096509650965096509650919395979092949650565b60086020528060005260406000206000915054906101000a900460ff1681565b6000600454905090565b60045481565b610886613728565b73ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610915576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090c906154c0565b60405180910390fd5b8060068190555050565b610927613728565b73ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146109b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ad906154c0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600280541415610abc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ab390615640565b60405180910390fd5b600280819055506000600760008881526020019081526020016000209050600560009054906101000a900460ff16610b29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b20906155e0565b60405180910390fd5b8060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610bbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bb390615400565b60405180910390fd5b60008090505b8160010160019054906101000a900460ff1660ff16811015611047576000878260058110610bec57fe5b602002015111610c31576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2890615540565b60405180910390fd5b81600701600082815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16868260058110610c8c57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1614610ce7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cde906155a0565b60405180910390fd5b600082600701600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16636352211e8a8560058110610d6357fe5b60200201516040518263ffffffff1660e01b8152600401610d8491906156a0565b60206040518083038186803b158015610d9c57600080fd5b505afa158015610db0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd49190614090565b73ffffffffffffffffffffffffffffffffffffffff1614610e2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e21906155c0565b60405180910390fd5b600089898460058110610e3957fe5b6020020151898560058110610e4a57fe5b602002015133604051602001610e639493929190615078565b604051602081830303815290604052805190602001209050600081604051602001610e8e9190615052565b60405160208183030381529060405280519060200120905060006001828a8760058110610eb757fe5b60200201518a8860058110610ec857fe5b60200201518a8960058110610ed957fe5b602002015160405160008152602001604052604051610efb9493929190615223565b6020604051602081039080840390855afa158015610f1d573d6000803e3d6000fd5b505050602060405103519050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637ac3c02f6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f9157600080fd5b505afa158015610fa5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc99190614090565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611036576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161102d906153e0565b60405180910390fd5b505050508080600101915050610bc2565b5060008090505b8160010160019054906101000a900460ff1660ff1681101561112a5785816005811061107657fe5b602002015173ffffffffffffffffffffffffffffffffffffffff166342842e0e338460040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168a85600581106110c857fe5b60200201516040518463ffffffff1660e01b81526004016110eb939291906150fc565b600060405180830381600087803b15801561110557600080fd5b505af1158015611119573d6000803e3d6000fd5b50505050808060010191505061104e565b5060008090505b8160010160009054906101000a900460ff1660ff168110156112195781600601600082815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3033856006016000868152602001908152602001600020600001546040518463ffffffff1660e01b81526004016111da939291906150fc565b600060405180830381600087803b1580156111f457600080fd5b505af1158015611208573d6000803e3d6000fd5b505050508080600101915050611131565b506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631dbf3bc782600501546040518263ffffffff1660e01b815260040161127891906156a0565b602060405180830381600087803b15801561129257600080fd5b505af11580156112a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ca9190614199565b506000816002015411156113d657600073ffffffffffffffffffffffffffffffffffffffff168160030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611381573373ffffffffffffffffffffffffffffffffffffffff166108fc82600201549081150290604051600060405180830381858888f1935050505015801561137b573d6000803e3d6000fd5b506113d5565b6113d43382600201548360030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166137309092919063ffffffff16565b5b5b8060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1682600001547f02fcdef9298c6a533466daaf962b24b1953ac9fa98b50e68493263c3b593df4f846002015485600501548660010160019054906101000a900460ff168c8860010160009054906101000a900460ff166040518060a001604052808b60060160008081526020019081526020016000206000015481526020018b6006016000600181526020019081526020016000206000015481526020018b6006016000600281526020019081526020016000206000015481526020018b6006016000600381526020019081526020016000206000015481526020018b6006016000600481526020019081526020016000206000015481525060405161153296959493929190615715565b60405180910390a4600760008881526020019081526020016000206000808201600090556001820160006101000a81549060ff02191690556001820160016101000a81549060ff021916905560028201600090556003820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556004820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560058201600090555050506001600281905550505050505050565b6115f7613728565b73ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611686576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167d906154c0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156116f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ed90615300565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611766576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161175d906153c0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611834576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182b90615660565b60405180910390fd5b80600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600560009054906101000a900460ff16611931576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611928906155e0565b60405180910390fd5b60008760ff1611611977576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196e906154e0565b60405180910390fd5b60058760ff1611156119be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119b590615480565b60405180910390fd5b60008560ff1611611a04576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119fb90615360565b60405180910390fd5b60058560ff161115611a4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a42906152e0565b60405180910390fd5b6000831115611de8578173ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611b9e5782600654016000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401611b0891906150e1565b60206040518083038186803b158015611b2057600080fd5b505afa158015611b34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b5891906141eb565b1015611b99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b90906152c0565b60405180910390fd5b611de3565b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2190615380565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611d105782341015611ca2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c99906153a0565b60405180910390fd5b6000611cb784346137b690919063ffffffff16565b90506000811115611d0a573373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611d08573d6000803e3d6000fd5b505b50611de2565b6000829050838173ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401611d4f91906150e1565b60206040518083038186803b158015611d6757600080fd5b505afa158015611d7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9f91906141eb565b1015611de0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dd790615440565b60405180910390fd5b505b5b611ed7565b6006546000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401611e4591906150e1565b60206040518083038186803b158015611e5d57600080fd5b505afa158015611e71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e9591906141eb565b1015611ed6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ecd906154a0565b60405180910390fd5b5b60008090505b8760ff16811015612153576000878260058110611ef657fe5b60200201516000015111611f3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3690615540565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660096000898460058110611f6757fe5b60200201516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415612022576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161201990615580565b60405180910390fd5b600087826005811061203057fe5b60200201516020015190503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16636352211e8a856005811061207a57fe5b6020020151600001516040518263ffffffff1660e01b815260040161209f91906156a0565b60206040518083038186803b1580156120b757600080fd5b505afa1580156120cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ef9190614090565b73ffffffffffffffffffffffffffffffffffffffff1614612145576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213c906155c0565b60405180910390fd5b508080600101915050611edd565b5060008090505b8560ff168110156123835760006009600087846005811061217757fe5b60200201516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561224d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161224490615340565b60405180910390fd5b60008190508073ffffffffffffffffffffffffffffffffffffffff1663640e130860045489866005811061227d57fe5b6020020151602001518a876005811061229257fe5b6020020151604001518b88600581106122a757fe5b6020020151606001518c89600581106122bc57fe5b6020020151608001516040518663ffffffff1660e01b81526004016122e59594939291906156bb565b60206040518083038186803b1580156122fd57600080fd5b505afa158015612311573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123359190614199565b612374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236b90615460565b60405180910390fd5b5050808060010191505061215a565b5060008090505b8760ff16811015612439578681600581106123a157fe5b60200201516020015173ffffffffffffffffffffffffffffffffffffffff166342842e0e33308a85600581106123d357fe5b6020020151600001516040518463ffffffff1660e01b81526004016123fa939291906150fc565b600060405180830381600087803b15801561241457600080fd5b505af1158015612428573d6000803e3d6000fd5b50505050808060010191505061238a565b5060008311156125f4576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156124ef576124ea333085600654016000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613800909392919063ffffffff16565b6125ef565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612570573073ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f1935050505015801561256a573d6000803e3d6000fd5b5061259e565b61259d3330858573ffffffffffffffffffffffffffffffffffffffff16613800909392919063ffffffff16565b5b6125ee33306006546000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613800909392919063ffffffff16565b5b612645565b61264433306006546000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613800909392919063ffffffff16565b5b600460008154809291906001019190505550600454600760006004548152602001908152602001600020600001819055508660076000600454815260200190815260200160002060010160006101000a81548160ff021916908360ff1602179055508460076000600454815260200190815260200160002060010160016101000a81548160ff021916908360ff16021790555060008090505b8760ff16811015612784578681600581106126f557fe5b602002015160076000600454815260200190815260200160002060060160008381526020019081526020016000206000820151816000015560208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505080806001019150506126de565b5060008090505b8560ff16811015612879578481600581106127a257fe5b6020020151600760006004548152602001908152602001600020600701600083815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001019080519060200190612833929190613b31565b5060408201518160020160006101000a81548160ff021916908360ff1602179055506060820151816003015560808201518160040155905050808060010191505061278b565b5082600760006004548152602001908152602001600020600201819055508160076000600454815260200190815260200160002060030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503360076000600454815260200190815260200160002060040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600654600760006004548152602001908152602001600020600501819055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff166004547ff7cb1dace9489604343b4263c9b235428dc3f912546aadc59f5b2afac2bb7f6d866006548c8b8d8c6040516129d096959493929190615779565b60405180910390a460045490509695505050505050565b6129ef613728565b73ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612a7e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a75906154c0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612aee576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae590615420565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415612bbd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bb490615520565b60405180910390fd5b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b612c47613728565b73ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612cd6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ccd906154c0565b60405180910390fd5b80600560006101000a81548160ff02191690831515021790555050565b60096020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600560009054906101000a900460ff1681565b60065481565b612d47613728565b73ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612dd6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dcd906154c0565b60405180910390fd5b600860008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612e63576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e5a90615680565b60405180910390fd5b6001600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006007600083815260200190815260200160002090503373ffffffffffffffffffffffffffffffffffffffff168160040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612f8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f8390615500565b60405180910390fd5b60008090505b8160010160009054906101000a900460ff1660ff1681101561309e5781600601600082815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e308460040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16856006016000868152602001908152602001600020600001546040518463ffffffff1660e01b815260040161305f939291906150fc565b600060405180830381600087803b15801561307957600080fd5b505af115801561308d573d6000803e3d6000fd5b505050508080600101915050612f92565b50600081600201541115613399576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168160030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156131e3576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb3383600201548460050154016040518363ffffffff1660e01b815260040161318b929190615133565b602060405180830381600087803b1580156131a557600080fd5b505af11580156131b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131dd9190614199565b50613394565b600073ffffffffffffffffffffffffffffffffffffffff168160030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561328c573373ffffffffffffffffffffffffffffffffffffffff166108fc82600201549081150290604051600060405180830381858888f19350505050158015613286573d6000803e3d6000fd5b506132e0565b6132df3382600201548360030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166137309092919063ffffffff16565b5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb3383600501546040518363ffffffff1660e01b8152600401613340929190615133565b602060405180830381600087803b15801561335a57600080fd5b505af115801561336e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133929190614199565b505b61344d565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb3383600501546040518363ffffffff1660e01b81526004016133f9929190615133565b602060405180830381600087803b15801561341357600080fd5b505af1158015613427573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061344b9190614199565b505b8060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681600001547fc4caef7e3533865382e608c341581a5e2a1b0d1ac37b0aaf58023ccd4eedfd8e60405160405180910390a3600760008381526020019081526020016000206000808201600090556001820160006101000a81549060ff02191690556001820160016101000a81549060ff021916905560028201600090556003820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556004820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600582016000905550505050565b613569613728565b73ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146135f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135ef906154c0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415613668576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161365f90615320565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600033905090565b6137b18363a9059cbb60e01b848460405160240161374f9291906151df565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613889565b505050565b60006137f883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613950565b905092915050565b613883846323b872dd60e01b8585856040516024016138219392919061515c565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613889565b50505050565b60606138eb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166139ab9092919063ffffffff16565b905060008151111561394b578080602001905181019061390b9190614199565b61394a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161394190615600565b60405180910390fd5b5b505050565b6000838311158290613998576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161398f919061529e565b60405180910390fd5b5060008385039050809150509392505050565b60606139ba84846000856139c3565b90509392505050565b60606139ce85613ae6565b613a0d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a0490615560565b60405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff168587604051613a379190615026565b60006040518083038185875af1925050503d8060008114613a74576040519150601f19603f3d011682016040523d82523d6000602084013e613a79565b606091505b50915091508115613a8e578092505050613ade565b600081511115613aa15780518082602001fd5b836040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613ad5919061529e565b60405180910390fd5b949350505050565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f9150808214158015613b2857506000801b8214155b92505050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613b7257805160ff1916838001178555613ba0565b82800160010185558215613ba0579182015b82811115613b9f578251825591602001919060010190613b84565b5b509050613bad9190613bb1565b5090565b613bd391905b80821115613bcf576000816000905550600101613bb7565b5090565b90565b600081359050613be581615c10565b92915050565b600081519050613bfa81615c10565b92915050565b600082601f830112613c1157600080fd5b6005613c24613c1f8261587f565b615852565b91508183856020840282011115613c3a57600080fd5b60005b83811015613c6a5781613c508882613bd6565b845260208401935060208301925050600181019050613c3d565b5050505092915050565b600082601f830112613c8557600080fd5b6005613c98613c93826158a1565b615852565b91508183856020840282011115613cae57600080fd5b60005b83811015613cde5781613cc48882613ed3565b845260208401935060208301925050600181019050613cb1565b5050505092915050565b600082601f830112613cf957600080fd5b6005613d0c613d07826158c3565b615852565b91508183856040840282011115613d2257600080fd5b60005b83811015613d525781613d388882613f3c565b845260208401935060408301925050600181019050613d25565b5050505092915050565b600082601f830112613d6d57600080fd5b6005613d80613d7b826158e5565b615852565b9150818360005b83811015613db75781358601613d9d8882613f88565b845260208401935060208301925050600181019050613d87565b5050505092915050565b600082601f830112613dd257600080fd5b6005613de5613de082615907565b615852565b91508183856020840282011115613dfb57600080fd5b60005b83811015613e2b5781613e118882614028565b845260208401935060208301925050600181019050613dfe565b5050505092915050565b600082601f830112613e4657600080fd5b6005613e59613e5482615929565b615852565b91508183856020840282011115613e6f57600080fd5b60005b83811015613e9f5781613e858882614052565b845260208401935060208301925050600181019050613e72565b5050505092915050565b600081359050613eb881615c27565b92915050565b600081519050613ecd81615c27565b92915050565b600081359050613ee281615c3e565b92915050565b600082601f830112613ef957600080fd5b8135613f0c613f078261594b565b615852565b91508082526020830160208301858383011115613f2857600080fd5b613f33838284615b66565b50505092915050565b600060408284031215613f4e57600080fd5b613f586040615852565b90506000613f6884828501614028565b6000830152506020613f7c84828501613bd6565b60208301525092915050565b600060a08284031215613f9a57600080fd5b613fa460a0615852565b90506000613fb484828501613bd6565b600083015250602082013567ffffffffffffffff811115613fd457600080fd5b613fe084828501613ee8565b6020830152506040613ff484828501614052565b604083015250606061400884828501613ed3565b606083015250608061401c84828501613ed3565b60808301525092915050565b60008135905061403781615c55565b92915050565b60008151905061404c81615c55565b92915050565b60008135905061406181615c6c565b92915050565b60006020828403121561407957600080fd5b600061408784828501613bd6565b91505092915050565b6000602082840312156140a257600080fd5b60006140b084828501613beb565b91505092915050565b600080604083850312156140cc57600080fd5b60006140da85828601613bd6565b92505060206140eb85828601613bd6565b9150509250929050565b6000806000806080858703121561410b57600080fd5b600061411987828801613bd6565b945050602061412a87828801613bd6565b935050604061413b87828801614028565b925050606085013567ffffffffffffffff81111561415857600080fd5b61416487828801613ee8565b91505092959194509250565b60006020828403121561418257600080fd5b600061419084828501613ea9565b91505092915050565b6000602082840312156141ab57600080fd5b60006141b984828501613ebe565b91505092915050565b6000602082840312156141d457600080fd5b60006141e284828501614028565b91505092915050565b6000602082840312156141fd57600080fd5b600061420b8482850161403d565b91505092915050565b600080600080600080610340878903121561422e57600080fd5b600061423c89828a01614028565b965050602061424d89828a01613dc1565b95505060c061425e89828a01613c00565b94505061016061427089828a01613e35565b93505061020061428289828a01613c74565b9250506102a061429489828a01613c74565b9150509295509295509295565b6000806000806000806101e087890312156142bb57600080fd5b60006142c989828a01614052565b96505060206142da89828a01613ce8565b9550506101606142ec89828a01614052565b94505061018087013567ffffffffffffffff81111561430a57600080fd5b61431689828a01613d5c565b9350506101a061432889828a01614028565b9250506101c061433a89828a01613bd6565b9150509295509295509295565b60006143538383614f1f565b60408301905092915050565b600061436b8383614f4e565b905092915050565b600061437f8383614fc4565b60208301905092915050565b61439481615afa565b82525050565b6143ab6143a682615a6f565b615bba565b82525050565b6143ba81615a5d565b82525050565b6143c981615a5d565b82525050565b6143e06143db82615a5d565b615ba8565b82525050565b6143ef81615995565b6143f981846159f3565b925061440482615977565b8060005b8381101561443557815161441c8782614347565b9650614427836159cc565b925050600181019050614408565b505050505050565b6000614448826159a0565b61445281856159fe565b93508360208202850161446485615981565b8060005b858110156144a05784840389528151614481858261435f565b945061448c836159d9565b925060208a01995050600181019050614468565b50829750879550505050505092915050565b6144bb816159ab565b6144c58184615a09565b92506144d08261598b565b8060005b838110156145015781516144e88782614373565b96506144f3836159e6565b9250506001810190506144d4565b505050505050565b61451281615a81565b82525050565b61452181615a8d565b82525050565b61453081615a8d565b82525050565b61454761454282615a8d565b615bcc565b82525050565b61455681615a97565b82525050565b6000614567826159b6565b6145718185615a14565b9350614581818560208601615b75565b61458a81615bf2565b840191505092915050565b60006145a0826159b6565b6145aa8185615a25565b93506145ba818560208601615b75565b6145c381615bf2565b840191505092915050565b60006145d9826159b6565b6145e38185615a36565b93506145f3818560208601615b75565b80840191505092915050565b61460881615b0c565b82525050565b6000614619826159c1565b6146238185615a41565b9350614633818560208601615b75565b61463c81615bf2565b840191505092915050565b6000614654601f83615a41565b91507f6e6f7420656e6f7567682043575320666f7220666565202620626f756e7479006000830152602082019050919050565b6000614694602f83615a52565b91507f6f6e455243373231526563656976656428616464726573732c6164647265737360008301527f2c75696e743235362c62797465732900000000000000000000000000000000006020830152602f82019050919050565b60006146fa601c83615a52565b91507f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000830152601c82019050919050565b600061473a601f83615a41565b91507f63616e742072657175657374206d6f7265207468616e203520746f6b656e73006000830152602082019050919050565b600061477a601383615a41565b91507f696e76616c6964206e66742061646472657373000000000000000000000000006000830152602082019050919050565b60006147ba602683615a41565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614820602183615a41565b91507f726571756573746564206e6674206164647265737320756e737570706f72746560008301527f64000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614886601f83615a41565b91507f73686f756c642072657175697265206174206c65617374206f6e65206e6674006000830152602082019050919050565b60006148c6601c83615a41565b91507f626f756e74792061646472657373206e6f7420737570706f72746564000000006000830152602082019050919050565b6000614906601c83615a41565b91507f696e73756666696369656e74207472616e7366657220616d6f756e74000000006000830152602082019050919050565b6000614946601983615a41565b91507f696e76616c6964204e6674506172616d732061646472657373000000000000006000830152602082019050919050565b6000614986601383615a41565b91507f566572696669636174696f6e206661696c6564000000000000000000000000006000830152602082019050919050565b60006149c6601883615a41565b91507f63616e74206275792073656c662d6d616465206f6666657200000000000000006000830152602082019050919050565b6000614a06600f83615a41565b91507f696e76616c6964206164647265737300000000000000000000000000000000006000830152602082019050919050565b6000614a46601e83615a41565b91507f6e6f7420656e6f756768206d6f6e657920746f2070617920626f756e747900006000830152602082019050919050565b6000614a86601283615a41565b91507f696e76616c6964206e667420506172616d7300000000000000000000000000006000830152602082019050919050565b6000614ac6601d83615a41565b91507f63616e74206f66666572206d6f7265207468616e203520746f6b656e730000006000830152602082019050919050565b6000614b06601683615a41565b91507f6e6f7420656e6f7567682043575320666f7220666565000000000000000000006000830152602082019050919050565b6000614b46602083615a41565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000614b86601d83615a41565b91507f73686f756c64206f66666572206174206c65617374206f6e65206e66740000006000830152602082019050919050565b6000614bc6601e83615a41565b91507f73656e646572206973206e6f742063726561746f72206f66206f6666657200006000830152602082019050919050565b6000614c06601c83615a41565b91507f6e6674206164647265737320616c72656164792064697361626c6564000000006000830152602082019050919050565b6000614c46601d83615a41565b91507f6e6674206964206d7573742062652067726561746572207468616e20300000006000830152602082019050919050565b6000614c86601d83615a41565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b6000614cc6601f83615a41565b91507f6f666665726564206e6674206164647265737320756e737570706f72746564006000830152602082019050919050565b6000614d06601d83615a41565b91507f77726f6e672072657175657374656420746f6b656e20616464726573730000006000830152602082019050919050565b6000614d46601783615a41565b91507f73656e646572206e6f74206f776e6572206f66206e66740000000000000000006000830152602082019050919050565b6000614d86601183615a41565b91507f74726164652069732064697361626c65640000000000000000000000000000006000830152602082019050919050565b6000614dc6602a83615a41565b91507f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008301527f6f742073756363656564000000000000000000000000000000000000000000006020830152604082019050919050565b6000614e2c601683615a41565b91507f626f756e747920616c72656164792072656d6f766564000000000000000000006000830152602082019050919050565b6000614e6c601f83615a41565b91507f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006000830152602082019050919050565b6000614eac601b83615a41565b91507f6e6674206164647265737320616c726561647920656e61626c656400000000006000830152602082019050919050565b6000614eec601883615a41565b91507f626f756e747920616c726561647920737570706f7274656400000000000000006000830152602082019050919050565b604082016000820151614f356000850182614fc4565b506020820151614f4860208501826143b1565b50505050565b600060a083016000830151614f6660008601826143b1565b5060208301518482036020860152614f7e828261455c565b9150506040830151614f936040860182615008565b506060830151614fa66060860182614518565b506080830151614fb96080860182614518565b508091505092915050565b614fcd81615ae3565b82525050565b614fdc81615ae3565b82525050565b614ff3614fee82615ae3565b615be8565b82525050565b61500281615b54565b82525050565b61501181615aed565b82525050565b61502081615aed565b82525050565b600061503282846145ce565b915081905092915050565b600061504882614687565b9150819050919050565b600061505d826146ed565b91506150698284614536565b60208201915081905092915050565b60006150848287614fe2565b6020820191506150948286614fe2565b6020820191506150a482856143cf565b6014820191506150b4828461439a565b60148201915081905095945050505050565b60006020820190506150db60008301846143c0565b92915050565b60006020820190506150f6600083018461438b565b92915050565b6000606082019050615111600083018661438b565b61511e602083018561438b565b61512b6040830184614fd3565b949350505050565b6000604082019050615148600083018561438b565b6151556020830184614fd3565b9392505050565b600060608201905061517160008301866143c0565b61517e60208301856143c0565b61518b6040830184614fd3565b949350505050565b60006080820190506151a860008301876143c0565b6151b560208301866143c0565b6151c26040830185614fd3565b81810360608301526151d48184614595565b905095945050505050565b60006040820190506151f460008301856143c0565b6152016020830184614fd3565b9392505050565b600060208201905061521d6000830184614509565b92915050565b60006080820190506152386000830187614527565b6152456020830186615017565b6152526040830185614527565b61525f6060830184614527565b95945050505050565b600060208201905061527d600083018461454d565b92915050565b600060208201905061529860008301846145ff565b92915050565b600060208201905081810360008301526152b8818461460e565b905092915050565b600060208201905081810360008301526152d981614647565b9050919050565b600060208201905081810360008301526152f98161472d565b9050919050565b600060208201905081810360008301526153198161476d565b9050919050565b60006020820190508181036000830152615339816147ad565b9050919050565b6000602082019050818103600083015261535981614813565b9050919050565b6000602082019050818103600083015261537981614879565b9050919050565b60006020820190508181036000830152615399816148b9565b9050919050565b600060208201905081810360008301526153b9816148f9565b9050919050565b600060208201905081810360008301526153d981614939565b9050919050565b600060208201905081810360008301526153f981614979565b9050919050565b60006020820190508181036000830152615419816149b9565b9050919050565b60006020820190508181036000830152615439816149f9565b9050919050565b6000602082019050818103600083015261545981614a39565b9050919050565b6000602082019050818103600083015261547981614a79565b9050919050565b6000602082019050818103600083015261549981614ab9565b9050919050565b600060208201905081810360008301526154b981614af9565b9050919050565b600060208201905081810360008301526154d981614b39565b9050919050565b600060208201905081810360008301526154f981614b79565b9050919050565b6000602082019050818103600083015261551981614bb9565b9050919050565b6000602082019050818103600083015261553981614bf9565b9050919050565b6000602082019050818103600083015261555981614c39565b9050919050565b6000602082019050818103600083015261557981614c79565b9050919050565b6000602082019050818103600083015261559981614cb9565b9050919050565b600060208201905081810360008301526155b981614cf9565b9050919050565b600060208201905081810360008301526155d981614d39565b9050919050565b600060208201905081810360008301526155f981614d79565b9050919050565b6000602082019050818103600083015261561981614db9565b9050919050565b6000602082019050818103600083015261563981614e1f565b9050919050565b6000602082019050818103600083015261565981614e5f565b9050919050565b6000602082019050818103600083015261567981614e9f565b9050919050565b6000602082019050818103600083015261569981614edf565b9050919050565b60006020820190506156b56000830184614fd3565b92915050565b600060a0820190506156d06000830188614fd3565b81810360208301526156e28187614595565b90506156f16040830186615017565b6156fe6060830185614527565b61570b6080830184614527565b9695505050505050565b60006101c08201905061572b6000830189614fd3565b6157386020830188614fd3565b6157456040830187614ff9565b61575260608301866144b2565b615760610100830185614ff9565b61576e6101208301846144b2565b979650505050505050565b60006101e08201905061578f6000830189614fd3565b61579c6020830188614fd3565b6157a96040830187614ff9565b6157b66060830186614ff9565b6157c360808301856143e6565b8181036101c08301526157d6818461443d565b9050979650505050505050565b600060e0820190506157f8600083018a614fd3565b6158056020830189615017565b6158126040830188615017565b61581f6060830187614fd3565b61582c60808301866143c0565b61583960a08301856143c0565b61584660c0830184614fd3565b98975050505050505050565b6000604051905081810181811067ffffffffffffffff8211171561587557600080fd5b8060405250919050565b600067ffffffffffffffff82111561589657600080fd5b602082029050919050565b600067ffffffffffffffff8211156158b857600080fd5b602082029050919050565b600067ffffffffffffffff8211156158da57600080fd5b602082029050919050565b600067ffffffffffffffff8211156158fc57600080fd5b602082029050919050565b600067ffffffffffffffff82111561591e57600080fd5b602082029050919050565b600067ffffffffffffffff82111561594057600080fd5b602082029050919050565b600067ffffffffffffffff82111561596257600080fd5b601f19601f8301169050602081019050919050565b6000819050919050565b6000819050919050565b6000819050919050565b600060059050919050565b600060059050919050565b600060059050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b600081905092915050565b600081905092915050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000615a6882615ac3565b9050919050565b6000615a7a82615ac3565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b6000615b0582615b30565b9050919050565b6000615b1782615b1e565b9050919050565b6000615b2982615ac3565b9050919050565b6000615b3b82615b42565b9050919050565b6000615b4d82615ac3565b9050919050565b6000615b5f82615aed565b9050919050565b82818337600083830152505050565b60005b83811015615b93578082015181840152602081019050615b78565b83811115615ba2576000848401525b50505050565b6000615bb382615bd6565b9050919050565b6000615bc582615bd6565b9050919050565b6000819050919050565b6000615be182615c03565b9050919050565b6000819050919050565b6000601f19601f8301169050919050565b60008160601b9050919050565b615c1981615a5d565b8114615c2457600080fd5b50565b615c3081615a81565b8114615c3b57600080fd5b50565b615c4781615a8d565b8114615c5257600080fd5b50565b615c5e81615ae3565b8114615c6957600080fd5b50565b615c7581615aed565b8114615c8057600080fd5b5056fea2646970667358221220e06560d9bd49519047523e7fc9d1da896e97caaa5b8614e2ac83dfa9fa7f818a64736f6c634300060700330000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000168840df293413a930d3d40bab6e1cd8f406719d00000000000000000000000061983368f5b3d639e3e90bebf708e2a524572f32

Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading