ETH Price: $2,611.03 (-2.83%)

Contract

0x5E446574a7E46C1c11f073C484e6d4a1CB1b92A6
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Unstack215190662024-12-31 1:07:1138 days ago1735607231IN
0x5E446574...1CB1b92A6
0 ETH0.002062074.30130272
Unstack214969982024-12-27 23:11:5942 days ago1735341119IN
0x5E446574...1CB1b92A6
0 ETH0.002842333.85909003
Unstack214662972024-12-23 16:12:3546 days ago1734970355IN
0x5E446574...1CB1b92A6
0 ETH0.0094946616.69956208
Unstack214282022024-12-18 8:23:3551 days ago1734510215IN
0x5E446574...1CB1b92A6
0 ETH0.0064028.61249411
Unstack211239842024-11-05 20:58:3594 days ago1730840315IN
0x5E446574...1CB1b92A6
0 ETH0.00450327.25623031
Unstack210184452024-10-22 3:30:47108 days ago1729567847IN
0x5E446574...1CB1b92A6
0 ETH0.001697687.04635091
Unstack208762772024-10-02 7:19:59128 days ago1727853599IN
0x5E446574...1CB1b92A6
0 ETH0.000792455.0604336
Unstack207493402024-09-14 14:07:11146 days ago1726322831IN
0x5E446574...1CB1b92A6
0 ETH0.002893912.7544475
Unstack207493292024-09-14 14:04:59146 days ago1726322699IN
0x5E446574...1CB1b92A6
0 ETH0.005156582.9099733
Unstack206846802024-09-05 13:27:23155 days ago1725542843IN
0x5E446574...1CB1b92A6
0 ETH0.000864374.25306429
Unstack206846722024-09-05 13:25:47155 days ago1725542747IN
0x5E446574...1CB1b92A6
0 ETH0.000587583.77031015
Unstack206299842024-08-28 22:10:59163 days ago1724883059IN
0x5E446574...1CB1b92A6
0 ETH0.000351912.18909356
Unstack206131952024-08-26 13:54:35165 days ago1724680475IN
0x5E446574...1CB1b92A6
0 ETH0.002439993.04965137
Unstack206018102024-08-24 23:43:47166 days ago1724543027IN
0x5E446574...1CB1b92A6
0 ETH0.001524571.80341163
Unstack206018082024-08-24 23:43:23166 days ago1724543003IN
0x5E446574...1CB1b92A6
0 ETH0.002981031.73978783
Unstack206018022024-08-24 23:42:11166 days ago1724542931IN
0x5E446574...1CB1b92A6
0 ETH0.002759321.69829875
Unstack206017412024-08-24 23:29:47167 days ago1724542187IN
0x5E446574...1CB1b92A6
0 ETH0.002815351.77697767
Unstack205956892024-08-24 3:10:47167 days ago1724469047IN
0x5E446574...1CB1b92A6
0 ETH0.003412580.92739339
Unstack205937782024-08-23 20:46:23168 days ago1724445983IN
0x5E446574...1CB1b92A6
0 ETH0.004548931.82516711
Unstack205937732024-08-23 20:45:23168 days ago1724445923IN
0x5E446574...1CB1b92A6
0 ETH0.006113271.82128123
Unstack205937662024-08-23 20:43:59168 days ago1724445839IN
0x5E446574...1CB1b92A6
0 ETH0.002911021.78015591
Unstack205937372024-08-23 20:38:11168 days ago1724445491IN
0x5E446574...1CB1b92A6
0 ETH0.00356992.17299983
Unstack205937252024-08-23 20:35:47168 days ago1724445347IN
0x5E446574...1CB1b92A6
0 ETH0.003826532.25758386
Unstack205917292024-08-23 13:55:11168 days ago1724421311IN
0x5E446574...1CB1b92A6
0 ETH0.00115711.67452345
Unstack205878062024-08-23 0:43:35168 days ago1724373815IN
0x5E446574...1CB1b92A6
0 ETH0.000229661.38733875
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CryptoFoxesStakingV2

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 1500 runs

Other Settings:
default evmVersion
File 1 of 16 : CryptoFoxesStakingV2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "./interfaces/ICryptoFoxesOriginsV2.sol";
import "./interfaces/ICryptoFoxesStakingV2.sol";
import "./interfaces/ICryptoFoxesCalculationV2.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "./CryptoFoxesUtility.sol";

// @author: miinded.com

/////////////////////////////////////////////////////////////////////////////////////
//                                                                                 //
//                                                                                 //
//                    ((((((((.                (((((                               //
//                    @@@@@@@@.                @@@@@                               //
//                    @@@&&&%%@@@              @@@&&@@@                            //
//                    @@@%%%@@#((@@@        @@@&&&&&%%%@@@                         //
//                    @@@(((%%,..(((@@&     @@@&&&%%///@@@                         //
//                 %@@(((@@@..   ...@@&     @@@%%%/////(((@@%                      //
//                 %@@///@@&        ///@@@@@%%%%%%((//////@@%                      //
//                 (%%///@@&        @@@/////(((@@@%%%%%///@@%                      //
//                 (%%///@@&     %%%(((///////////((@@@(((%%#                      //
//                 (%%///...  #%%/////////////////////////%%#                      //
//                 %@@///@@@@@#((/////////////////////////@@%                      //
//                 %@@///%%%%%(((////////((((((/////((((((%%#//                    //
//                 %@@///(((/////////////((((((/////((((((((#@@                    //
//               @@#((//////////////////////////////////////(%%                    //
//               @@#((//////////////&&&&&&&&&&&////////&&&&&&%%                    //
//               @@(/////////////&&&     (((   ////////(((  ,&&                    //
//            @@@((///////////(((&&&     ###   ///(((((###  ,&&%%%                 //
//            @@@/////......     (((///////////((#&&&&&&&&..,((%%%                 //
//            @@@((.                ..,//,.....     &&&     .//@@@                 //
//               @@#((...                      &&&&&...&&&     @@@                 //
//    @@@@@      @@#((                                       ..@@@                 //
// @@@..(%%        %@@%%%%%%.....                         ..*%%                    //
// (((../((***     /((///////////*************************/////                    //
//      ...%%%              @@&%%%%%%%%%%%%%%%%%%%%%@@@@@@%%#                      //
//         ...%%%        &&%##(((.................**@@@                            //
//            ...@@,     %%%/////...              ..(((@@@                         //
// ...        ///((&@@@@@////////%%%             .%%(((@@@              Miinded    //
// ...     ////////(((@@@/////(((%%%             .%%((((((%%#                      //
/////////////////////////////////////////////////////////////////////////////////////

contract CryptoFoxesStakingV2 is Ownable, CryptoFoxesUtility, ICryptoFoxesStakingV2 {

    uint32 constant HASH_SIGN_STAKING_V2 = 9248467;
    uint8 constant MIN_SLOT = 9;
    uint8 constant MAX_SLOT = 20;
    uint16 constant NULL = 65535;

    mapping(uint16 => Staking) public staked;
    mapping(uint16 => Origin) public origins;
    mapping(uint256 => bool) private signatures;
    mapping(address => uint16[]) public walletOwner;
    mapping(uint16 => uint16) private walletOwnerTokenIndex;

    address private signAddress;

    IERC721 public cryptoFoxes;
    ICryptoFoxesOriginsV2 public cryptoFoxesOrigin;
    ICryptoFoxesCalculationV2 public calculationContract;

    constructor( address _cryptoFoxesOrigin, address _cryptoFoxesContract, address _signAddress) {
        cryptoFoxesOrigin = ICryptoFoxesOriginsV2(_cryptoFoxesOrigin);
        cryptoFoxes = IERC721(_cryptoFoxesContract);
        signAddress = _signAddress;
    }

    event EventStack(uint16 _tokenId, uint16 _tokenIdOrigin, address _owner);
    event EventUnstack(uint16 _tokenId, address _owner);
    event EventClaim(uint16 _tokenId, address _owner);
    event EventMove(uint16 _tokenId, uint16 _tokenIdOriginTo, address _owner);

    //////////////////////////////////////////////////
    //      STAKING                                 //
    //////////////////////////////////////////////////

    function stack(uint16[] memory _tokenIds, uint16 _tokenIdOrigin) public {
        require(!disablePublicFunctions, "Function disabled");
        _stack(_msgSender(), _tokenIds, _tokenIdOrigin);
    }
    function stackByContract(address _wallet, uint16[] memory _tokenIds, uint16 _tokenIdOrigin) public isFoxContract{
        _stack(_wallet, _tokenIds, _tokenIdOrigin);
    }
    function _stack(address _wallet, uint16[] memory _tokenIds, uint16 _tokenIdOrigin) private {

        require(cryptoFoxesOrigin.ownerOf(_tokenIdOrigin) != address(0), "CryptoFoxesStakingV2:stack origin not minted");
        require(_tokenIdOrigin >= 1 && _tokenIdOrigin <= 1000, "CryptoFoxesStakingV2:stack token out of range");

        if(origins[_tokenIdOrigin].maxSlots == 0){
            origins[_tokenIdOrigin].maxSlots = MIN_SLOT;
        }

        require(origins[_tokenIdOrigin].stacked.length + _tokenIds.length <= origins[_tokenIdOrigin].maxSlots, "CryptoFoxesStakingV2:stack no slots");

        for(uint16 i = 0; i < _tokenIds.length; i++){

            require(cryptoFoxes.ownerOf(_tokenIds[i]) == _wallet, "CryptoFoxesStakingV2:stack Not owner");

            staked[_tokenIds[i]].tokenId = _tokenIds[i];
            staked[_tokenIds[i]].owner = _wallet;
            staked[_tokenIds[i]].timestampV2 = uint64(block.timestamp);

            _stackAction(_tokenIds[i],_tokenIdOrigin);

            cryptoFoxes.transferFrom(_wallet, address(this), _tokenIds[i]);

            walletOwnerTokenIndex[_tokenIds[i]] = uint16(walletOwner[_wallet].length);
            walletOwner[_wallet].push(_tokenIds[i]);

            emit EventStack(_tokenIds[i], _tokenIdOrigin, _wallet);
        }
    }

    function _stackAction(uint16 _tokenId, uint16 _tokenIdOrigin) private{
        staked[_tokenId].origin = _tokenIdOrigin;
        staked[_tokenId].slotIndex = uint8(origins[_tokenIdOrigin].stacked.length);
        origins[_tokenIdOrigin].stacked.push(_tokenId);
    }

    function unstack(uint16[] memory _tokenIds, uint256 _bonusSteak, uint256 _signatureId, bytes memory _signature) public {
        require(!disablePublicFunctions, "Function disabled");
        _unstack(_msgSender(), _tokenIds, _bonusSteak, _signatureId, _signature);
    }
    function unstackByContract(address _wallet, uint16[] memory _tokenIds, uint256 _bonusSteak, uint256 _signatureId, bytes memory _signature) public isFoxContract{
        _unstack(_wallet, _tokenIds, _bonusSteak, _signatureId, _signature);
    }
    function _unstack(address _wallet, uint16[] memory _tokenIds, uint256 _bonusSteak, uint256 _signatureId, bytes memory _signature) private {

        _claimRewardsV2(_wallet, _tokenIds, _bonusSteak, _signatureId, _signature);

        for(uint16 i = 0; i < _tokenIds.length; i++){

            require(isStaked(_tokenIds[i]) && staked[_tokenIds[i]].owner == _wallet, "CryptoFoxesStakingV2:unstack Not owner");

            uint16 tokenIdOrigin = getOriginByV2(_tokenIds[i]);
            _unstackAction(_tokenIds[i], tokenIdOrigin);

            staked[_tokenIds[i]].tokenId = NULL;

            cryptoFoxes.transferFrom(address(this), _wallet, _tokenIds[i]);

            uint16 index = walletOwnerTokenIndex[_tokenIds[i]];
            uint16 last = uint16(walletOwner[_wallet].length - 1);

            if(index != last){
                walletOwner[_wallet][index] = walletOwner[_wallet][last];
                walletOwnerTokenIndex[ walletOwner[_wallet][last] ] = index;
            }
            walletOwner[_wallet].pop();

            emit EventUnstack(_tokenIds[i], _wallet);
        }
    }

    function _unstackAction(uint16 _tokenId, uint16 _tokenIdOrigin) private{
        uint8 slotIndex = staked[_tokenId].slotIndex;
        uint8 lastSlot = uint8(origins[_tokenIdOrigin].stacked.length - 1);

        if(slotIndex != lastSlot){
            origins[_tokenIdOrigin].stacked[slotIndex] = origins[_tokenIdOrigin].stacked[lastSlot];
            staked[ origins[_tokenIdOrigin].stacked[lastSlot] ].slotIndex = slotIndex;
        }

        origins[_tokenIdOrigin].stacked.pop();
    }

    function claimSignature(address _wallet, uint256 _bonusSteak, uint256 _signatureId, bytes memory _signature) public pure returns(address){
        return ECDSA.recover(keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", keccak256(abi.encode(_wallet, _bonusSteak, _signatureId, HASH_SIGN_STAKING_V2)))), _signature);
    }

    function moveStack(uint16 _tokenId, uint16 _tokenIdOriginTo) public {
        require(!disablePublicFunctions, "Function disabled");
        _moveStack(_msgSender(), _tokenId, _tokenIdOriginTo);
    }
    function moveStackByContract(address _wallet, uint16 _tokenId, uint16 _tokenIdOriginTo) public isFoxContract {
        _moveStack(_wallet, _tokenId, _tokenIdOriginTo);
    }
    function _moveStack(address _wallet, uint16 _tokenId, uint16 _tokenIdOriginTo) private {

        require(isStaked(_tokenId), "CryptoFoxesStakingV2:moveStack Not owner");
        uint16 tokenIdOrigin = getOriginByV2(_tokenId);
        require(tokenIdOrigin != _tokenIdOriginTo, "CryptoFoxesStakingV2:moveStack not moving tokenId");
        require(cryptoFoxesOrigin.ownerOf(tokenIdOrigin) == _wallet, "CryptoFoxesStakingV2:moveStack origin not owner");
        require(cryptoFoxesOrigin.ownerOf(_tokenIdOriginTo) != address(0), "CryptoFoxesStakingV2:moveStack originTo not minted");
        require(_tokenIdOriginTo >= 1 && _tokenIdOriginTo <= 1000, "CryptoFoxesStakingV2:moveStack tokenTo out of range");

        if(origins[_tokenIdOriginTo].maxSlots == 0){
            origins[_tokenIdOriginTo].maxSlots = MIN_SLOT;
        }

        require(origins[_tokenIdOriginTo].stacked.length < origins[_tokenIdOriginTo].maxSlots, "CryptoFoxesStakingV2:moveStack no slots");

        _unstackAction(_tokenId, tokenIdOrigin);
        _stackAction(_tokenId,_tokenIdOriginTo);

        calculationContract.claimMoveRewardsOrigin(address(this), _tokenId, _wallet);

        staked[_tokenId].timestampV2 = uint64(block.timestamp);

        emit EventMove(_tokenId, _tokenIdOriginTo, _wallet);
    }

    //////////////////////////////////////////////////
    //      SLOTS                                   //
    //////////////////////////////////////////////////

    function unlockSlot(uint16 _tokenIdOrigin, uint8 _count) public override isFoxContractOrOwner {
        if(origins[_tokenIdOrigin].maxSlots == 0){
            origins[_tokenIdOrigin].maxSlots = MIN_SLOT;
        }
        require(origins[_tokenIdOrigin].maxSlots + _count <= MAX_SLOT, "CryptoFoxesStakingV2:unlockSlot Max slot limit");
        origins[_tokenIdOrigin].maxSlots += _count;
    }

    //////////////////////////////////////////////////
    //      REWARDS                                 //
    //////////////////////////////////////////////////

    function calculateRewardsV2(uint16[] memory _tokenIds, uint256 _currentTimestamp) public view returns (uint256) {
        return calculationContract.calculationRewardsV2(address(this), _tokenIds, _currentTimestamp);
    }

    function claimRewardsV2(uint16[] memory _tokenIds, uint256 _bonusSteak, uint256 _signatureId, bytes memory _signature) public {
        require(!disablePublicFunctions, "Function disabled");
        _claimRewardsV2(_msgSender(), _tokenIds, _bonusSteak, _signatureId, _signature);
    }
    function claimRewardsV2ByContract(address _wallet, uint16[] memory _tokenIds, uint256 _bonusSteak, uint256 _signatureId, bytes memory _signature) public isFoxContract {
        _claimRewardsV2(_wallet, _tokenIds, _bonusSteak, _signatureId, _signature);
    }
    function _claimRewardsV2(address _wallet, uint16[] memory _tokenIds, uint256 _bonusSteak, uint256 _signatureId, bytes memory _signature) private {

        require(_tokenIds.length > 0 && !isPaused(), "Tokens empty");

        if(_bonusSteak > 0){
            require(signatures[_signatureId] == false, "CryptoFoxesStakingV2:claimRewardsV2 signature used");
            signatures[_signatureId] = true;
            require(claimSignature(_wallet, _bonusSteak, _signatureId, _signature) == signAddress, "CryptoFoxesStakingV2:claimRewardsV2 signature fail"); // 6k
            _addRewards(_wallet, _bonusSteak);
        }

        for(uint16 i = 0; i < _tokenIds.length; i++){
            require(isStaked(_tokenIds[i]) && staked[_tokenIds[i]].owner == _wallet, "Bad owner");

            for (uint16 j = 0; j < i; j++) {
                require(_tokenIds[j] != _tokenIds[i], "Duplicate id");
            }
        }

        calculationContract.claimRewardsV2(address(this), _tokenIds, _wallet);

        for(uint16 i = 0; i < _tokenIds.length; i++){
            staked[_tokenIds[i]].timestampV2 = uint64(block.timestamp);

            emit EventClaim(_tokenIds[i], _wallet);
        }

    }

    //////////////////////////////////////////////////
    //      GETTERS                                 //
    //////////////////////////////////////////////////

    function getFoxesV2(uint16 _tokenId) public view override returns(Staking memory){
        return staked[_tokenId];
    }
    function getOriginByV2(uint16 _tokenId) public view override returns(uint16){
        return staked[_tokenId].origin;
    }
    function getStakingTokenV2(uint16 _tokenId) public override view returns(uint256){
        return uint256(staked[_tokenId].timestampV2);
    }
    function totalSupply() public view returns(uint16){
        uint16 totalStaked = 0;
        for(uint16 i = 1; i <= 1000; i++){
            totalStaked += uint16(origins[i].stacked.length);
        }
        return totalStaked;
    }
    function getOriginMaxSlot(uint16 _tokenIdOrigin) public view override returns(uint8){
        return origins[_tokenIdOrigin].maxSlots;
    }
    function getV2ByOrigin(uint16 _tokenIdOrigin) public override view returns(Staking[] memory){
        Staking[] memory tokenIds = new Staking[](origins[_tokenIdOrigin].stacked.length);
        for(uint16 i = 0; i < origins[_tokenIdOrigin].stacked.length; i++){
            tokenIds[i] = staked[ origins[_tokenIdOrigin].stacked[i] ];
        }
        return tokenIds;
    }
    function walletOfOwner(address _wallet) public view returns(Staking[] memory){
        Staking[] memory tokenIds = new Staking[](walletOwner[_wallet].length);
        for(uint16 i = 0; i < walletOwner[_wallet].length; i++){
            tokenIds[i] = staked[ walletOwner[_wallet][i] ];
        }
        return tokenIds;
    }

    //////////////////////////////////////////////////
    //      SETTERS                                 //
    //////////////////////////////////////////////////

    function setCryptoFoxes(address _contract) public onlyOwner{
        if(address(cryptoFoxes) != address(0)) {
            setAllowedContract(address(cryptoFoxes), false);
        }
        cryptoFoxes = IERC721(_contract);
        setAllowedContract(_contract, true);

    }
    function setCryptoFoxesOrigin(address _contract) public onlyOwner{
        if(address(cryptoFoxesOrigin) != address(0)) {
            setAllowedContract(address(cryptoFoxesOrigin), false);
        }
        cryptoFoxesOrigin = ICryptoFoxesOriginsV2(_contract);
        setAllowedContract(_contract, true);

    }
    function setCalculationContract(address _contract) public isFoxContractOrOwner {
        if(address(calculationContract) != address(0)) {
            setAllowedContract(address(calculationContract), false);
        }

        calculationContract = ICryptoFoxesCalculationV2(_contract);
        setAllowedContract(_contract, true);
    }
    function setSignAddress(address _signAddress) external onlyOwner{
        signAddress = _signAddress;
    }
    function updateTimestampV2(uint16 _tokenId, uint64 _timestamp) public isFoxContract{
        staked[_tokenId].timestampV2 = _timestamp;
    }

    //////////////////////////////////////////////////
    //      TESTERS                                 //
    //////////////////////////////////////////////////

    function isStaked(uint16 _tokenId) public view returns(bool){
        return staked[_tokenId].tokenId != NULL && staked[_tokenId].timestampV2 != 0;
    }

    //////////////////////////////////////////////////
    //      OTHER                                   //
    //////////////////////////////////////////////////

    function _currentTime(uint256 _currentTimestamp) public override(ICryptoFoxesStakingV2, CryptoFoxesUtility) view returns (uint256) {
        return super._currentTime(_currentTimestamp);
    }
}

File 2 of 16 : ICryptoFoxesSteak.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// @author: miinded.com

interface ICryptoFoxesSteak {
    function addRewards(address _to, uint256 _amount) external;
    function withdrawRewards(address _to) external;
    function isPaused() external view returns(bool);
    function dateEndRewards() external view returns(uint256);
}

File 3 of 16 : ICryptoFoxesStakingV2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// @author: miinded.com
import "./ICryptoFoxesStakingStruct.sol";

interface ICryptoFoxesStakingV2 is ICryptoFoxesStakingStruct  {
    function getFoxesV2(uint16 _tokenId) external view returns(Staking memory);
    function getOriginMaxSlot(uint16 _tokenIdOrigin) external view returns(uint8);
    function getStakingTokenV2(uint16 _tokenId) external view returns(uint256);
    function getV2ByOrigin(uint16 _tokenIdOrigin) external view returns(Staking[] memory);
    function getOriginByV2(uint16 _tokenId) external view returns(uint16);
    function unlockSlot(uint16 _tokenId, uint8 _count) external;
    function _currentTime(uint256 _currentTimestamp) external view returns(uint256);
}

File 4 of 16 : ICryptoFoxesStakingStruct.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// @author: miinded.com

interface ICryptoFoxesStakingStruct {

    struct Staking {
        uint8 slotIndex;
        uint16 tokenId;
        uint16 origin;
        uint64 timestampV2;
        address owner;
    }

    struct Origin{
        uint8 maxSlots;
        uint16[] stacked;
    }

}

File 5 of 16 : ICryptoFoxesOriginsV2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// @author: miinded.com
import "./ICryptoFoxesOrigins.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

interface ICryptoFoxesOriginsV2 is ICryptoFoxesOrigins, IERC721  {
    function walletOfOwner(address _owner) external view returns(uint256[] memory);
}

File 6 of 16 : ICryptoFoxesOrigins.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// @author: miinded.com

interface ICryptoFoxesOrigins {
    function getStackingToken(uint256 tokenId) external view returns(uint256);
    function _currentTime(uint256 _currentTimestamp) external view returns(uint256);
}

File 7 of 16 : ICryptoFoxesCalculationV2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// @author: miinded.com

interface ICryptoFoxesCalculationV2 {
    function calculationRewardsV2(address _contract, uint16[] calldata _tokenIds, uint256 _currentTimestamp) external view returns(uint256);
    function claimRewardsV2(address _contract, uint16[] calldata _tokenIds, address _owner) external;
    function claimMoveRewardsOrigin(address _contract, uint16 _tokenId, address _ownerOrigin) external;
}

File 8 of 16 : CryptoFoxesUtility.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./interfaces/ICryptoFoxesSteak.sol";
import "./CryptoFoxesAllowed.sol";

// @author: miinded.com

abstract contract CryptoFoxesUtility is Ownable,CryptoFoxesAllowed, ICryptoFoxesSteak {
    using SafeMath for uint256;

    uint256 public endRewards = 0;
    ICryptoFoxesSteak public cryptofoxesSteak;
    bool public disablePublicFunctions = false;

    function setCryptoFoxesSteak(address _contract) public onlyOwner {
        cryptofoxesSteak = ICryptoFoxesSteak(_contract);
        setAllowedContract(_contract, true);
        synchroEndRewards();
    }
    function _addRewards(address _to, uint256 _amount) internal {
        cryptofoxesSteak.addRewards(_to, _amount);
    }
    function addRewards(address _to, uint256 _amount) public override isFoxContract  {
        _addRewards(_to, _amount);
    }
    function withdrawRewards(address _to) public override isFoxContract {
        cryptofoxesSteak.withdrawRewards(_to);
    }
    function _withdrawRewards(address _to) internal {
        cryptofoxesSteak.withdrawRewards(_to);
    }
    function isPaused() public view override returns(bool){
        return cryptofoxesSteak.isPaused();
    }
    function synchroEndRewards() public {
        endRewards = cryptofoxesSteak.dateEndRewards();
    }
    function dateEndRewards() public view override returns(uint256){
        require(endRewards > 0, "End Rewards error");
        return endRewards;
    }
    function _currentTime(uint256 _currentTimestamp) public view virtual returns (uint256) {
        return min(_currentTimestamp, dateEndRewards());
    }
    function min(uint256 a, uint256 b) public pure returns (uint256){
        return a > b ? b : a;
    }
    function max(uint256 a, uint256 b) public pure returns (uint256){
        return a > b ? a : b;
    }
    function setDisablePublicFunctions(bool _toggle) public isFoxContractOrOwner{
        disablePublicFunctions = _toggle;
    }
}

File 9 of 16 : CryptoFoxesAllowed.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./interfaces/ICryptoFoxesSteak.sol";

// @author: miinded.com

abstract contract CryptoFoxesAllowed is Ownable {

    mapping (address => bool) public allowedContracts;

    modifier isFoxContract() {
        require(allowedContracts[_msgSender()] == true, "Not allowed");
        _;
    }
    
    modifier isFoxContractOrOwner() {
        require(allowedContracts[_msgSender()] == true || _msgSender() == owner(), "Not allowed");
        _;
    }

    function setAllowedContract(address _contract, bool _allowed) public onlyOwner {
        allowedContracts[_contract] = _allowed;
    }

}

File 10 of 16 : SafeMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @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 a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * 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) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

File 11 of 16 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 12 of 16 : ECDSA.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

import "../Strings.sol";

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s;
        uint8 v;
        assembly {
            s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            v := add(shr(255, vs), 27)
        }
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

File 13 of 16 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

File 14 of 16 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 15 of 16 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

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

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, 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 16 of 16 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_cryptoFoxesOrigin","type":"address"},{"internalType":"address","name":"_cryptoFoxesContract","type":"address"},{"internalType":"address","name":"_signAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_tokenId","type":"uint16"},{"indexed":false,"internalType":"address","name":"_owner","type":"address"}],"name":"EventClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_tokenId","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"_tokenIdOriginTo","type":"uint16"},{"indexed":false,"internalType":"address","name":"_owner","type":"address"}],"name":"EventMove","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_tokenId","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"_tokenIdOrigin","type":"uint16"},{"indexed":false,"internalType":"address","name":"_owner","type":"address"}],"name":"EventStack","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_tokenId","type":"uint16"},{"indexed":false,"internalType":"address","name":"_owner","type":"address"}],"name":"EventUnstack","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"},{"inputs":[{"internalType":"uint256","name":"_currentTimestamp","type":"uint256"}],"name":"_currentTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"addRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowedContracts","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"_tokenIds","type":"uint16[]"},{"internalType":"uint256","name":"_currentTimestamp","type":"uint256"}],"name":"calculateRewardsV2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calculationContract","outputs":[{"internalType":"contract ICryptoFoxesCalculationV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"_tokenIds","type":"uint16[]"},{"internalType":"uint256","name":"_bonusSteak","type":"uint256"},{"internalType":"uint256","name":"_signatureId","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"claimRewardsV2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"uint16[]","name":"_tokenIds","type":"uint16[]"},{"internalType":"uint256","name":"_bonusSteak","type":"uint256"},{"internalType":"uint256","name":"_signatureId","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"claimRewardsV2ByContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"uint256","name":"_bonusSteak","type":"uint256"},{"internalType":"uint256","name":"_signatureId","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"claimSignature","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"cryptoFoxes","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cryptoFoxesOrigin","outputs":[{"internalType":"contract ICryptoFoxesOriginsV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cryptofoxesSteak","outputs":[{"internalType":"contract ICryptoFoxesSteak","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dateEndRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disablePublicFunctions","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_tokenId","type":"uint16"}],"name":"getFoxesV2","outputs":[{"components":[{"internalType":"uint8","name":"slotIndex","type":"uint8"},{"internalType":"uint16","name":"tokenId","type":"uint16"},{"internalType":"uint16","name":"origin","type":"uint16"},{"internalType":"uint64","name":"timestampV2","type":"uint64"},{"internalType":"address","name":"owner","type":"address"}],"internalType":"struct ICryptoFoxesStakingStruct.Staking","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_tokenId","type":"uint16"}],"name":"getOriginByV2","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_tokenIdOrigin","type":"uint16"}],"name":"getOriginMaxSlot","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_tokenId","type":"uint16"}],"name":"getStakingTokenV2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_tokenIdOrigin","type":"uint16"}],"name":"getV2ByOrigin","outputs":[{"components":[{"internalType":"uint8","name":"slotIndex","type":"uint8"},{"internalType":"uint16","name":"tokenId","type":"uint16"},{"internalType":"uint16","name":"origin","type":"uint16"},{"internalType":"uint64","name":"timestampV2","type":"uint64"},{"internalType":"address","name":"owner","type":"address"}],"internalType":"struct ICryptoFoxesStakingStruct.Staking[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_tokenId","type":"uint16"}],"name":"isStaked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"}],"name":"max","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"}],"name":"min","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint16","name":"_tokenId","type":"uint16"},{"internalType":"uint16","name":"_tokenIdOriginTo","type":"uint16"}],"name":"moveStack","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"uint16","name":"_tokenId","type":"uint16"},{"internalType":"uint16","name":"_tokenIdOriginTo","type":"uint16"}],"name":"moveStackByContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"origins","outputs":[{"internalType":"uint8","name":"maxSlots","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"},{"internalType":"bool","name":"_allowed","type":"bool"}],"name":"setAllowedContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"}],"name":"setCalculationContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"}],"name":"setCryptoFoxes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"}],"name":"setCryptoFoxesOrigin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"}],"name":"setCryptoFoxesSteak","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_toggle","type":"bool"}],"name":"setDisablePublicFunctions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signAddress","type":"address"}],"name":"setSignAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"_tokenIds","type":"uint16[]"},{"internalType":"uint16","name":"_tokenIdOrigin","type":"uint16"}],"name":"stack","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"uint16[]","name":"_tokenIds","type":"uint16[]"},{"internalType":"uint16","name":"_tokenIdOrigin","type":"uint16"}],"name":"stackByContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"staked","outputs":[{"internalType":"uint8","name":"slotIndex","type":"uint8"},{"internalType":"uint16","name":"tokenId","type":"uint16"},{"internalType":"uint16","name":"origin","type":"uint16"},{"internalType":"uint64","name":"timestampV2","type":"uint64"},{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"synchroEndRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_tokenIdOrigin","type":"uint16"},{"internalType":"uint8","name":"_count","type":"uint8"}],"name":"unlockSlot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"_tokenIds","type":"uint16[]"},{"internalType":"uint256","name":"_bonusSteak","type":"uint256"},{"internalType":"uint256","name":"_signatureId","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"unstack","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"uint16[]","name":"_tokenIds","type":"uint16[]"},{"internalType":"uint256","name":"_bonusSteak","type":"uint256"},{"internalType":"uint256","name":"_signatureId","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"unstackByContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_tokenId","type":"uint16"},{"internalType":"uint64","name":"_timestamp","type":"uint64"}],"name":"updateTimestampV2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"walletOfOwner","outputs":[{"components":[{"internalType":"uint8","name":"slotIndex","type":"uint8"},{"internalType":"uint16","name":"tokenId","type":"uint16"},{"internalType":"uint16","name":"origin","type":"uint16"},{"internalType":"uint64","name":"timestampV2","type":"uint64"},{"internalType":"address","name":"owner","type":"address"}],"internalType":"struct ICryptoFoxesStakingStruct.Staking[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"walletOwner","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"withdrawRewards","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405260006002556003805460ff60a01b191690553480156200002357600080fd5b506040516200435b3803806200435b833981016040819052620000469162000101565b620000513362000094565b600b80546001600160a01b039485166001600160a01b031991821617909155600a805493851693821693909317909255600980549190931691161790556200014b565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b0381168114620000fc57600080fd5b919050565b6000806000606084860312156200011757600080fd5b6200012284620000e4565b92506200013260208501620000e4565b91506200014260408501620000e4565b90509250925092565b614200806200015b6000396000f3fe608060405234801561001057600080fd5b50600436106103205760003560e01c8063793f6777116101a7578063b4fc0b98116100ee578063e026615b11610097578063e8b1f1b411610071578063e8b1f1b41461085c578063ecb0c3171461086f578063f2fde38b1461088257600080fd5b8063e026615b1461078f578063e05acaa5146107a2578063e64bdbe5146107b557600080fd5b8063d9cd1ca0116100c8578063d9cd1ca014610760578063dc707e3b14610769578063de1f276c1461077c57600080fd5b8063b4fc0b9814610717578063ba477b921461072a578063cfabc2741461074d57600080fd5b8063a12dfd7211610150578063a9fc507b1161012a578063a9fc507b146106e9578063b187bd26146106fc578063b3b623a51461070457600080fd5b8063a12dfd721461068a578063a89448e41461069d578063a897e24f146106d657600080fd5b80638da5cb5b116101815780638da5cb5b1461065e57806399d90a731461066f5780639c1c3a8f1461068257600080fd5b8063793f6777146106255780637ae2b5c7146106385780637e2caf361461064b57600080fd5b806342d866931161026b578063583064fc116102145780636d189c5b116101ee5780636d189c5b146105f75780636d5433e61461060a578063715018a61461061d57600080fd5b8063583064fc146105c95780635c686669146105dc57806369babd3b146105ef57600080fd5b806351e0e26b1161024557806351e0e26b1461056557806355de1faf14610588578063571f5f1d1461059b57600080fd5b806342d866931461051f578063438b6300146105325780635159371c1461055257600080fd5b806318160ddd116102cd5780633a8dac2a116102a75780633a8dac2a146104e65780633dc77e8f146104f95780633f282b711461050c57600080fd5b806318160ddd146104945780631a95082d146104af57806333853ed5146104d357600080fd5b80630ea25ced116102fe5780630ea25ced14610429578063101ce36c1461046e578063151370451461048157600080fd5b8063011df42d146103255780630428a2a71461033a5780630ca7abf9146103fe575b600080fd5b610338610333366004613ac4565b610895565b005b6103e8610348366004613b4e565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091525061ffff908116600090815260046020908152604091829020825160a081018452815460ff811682526101008104861693820193909352630100000083049094169284019290925265010000000000900467ffffffffffffffff166060830152600101546001600160a01b0316608082015290565b6040516103f59190613b69565b60405180910390f35b600b54610411906001600160a01b031681565b6040516001600160a01b0390911681526020016103f5565b610460610437366004613b4e565b61ffff1660009081526004602052604090205465010000000000900467ffffffffffffffff1690565b6040519081526020016103f5565b600354610411906001600160a01b031681565b61033861048f366004613bc2565b610901565b61049c61098a565b60405161ffff90911681526020016103f5565b6003546104c390600160a01b900460ff1681565b60405190151581526020016103f5565b6103386104e1366004613bc2565b6109d8565b6103386104f4366004613ac4565b610a90565b610338610507366004613be6565b610af0565b61033861051a366004613c6b565b610b51565b61033861052d366004613bc2565b610bf2565b610545610540366004613bc2565b610cb9565b6040516103f59190613c88565b610338610560366004613d21565b610e71565b6104c3610573366004613bc2565b60016020526000908152604090205460ff1681565b610338610596366004613d65565b610f08565b61049c6105a9366004613b4e565b61ffff908116600090815260046020526040902054630100000090041690565b6105456105d7366004613b4e565b610f8d565b6104116105ea366004613d93565b611133565b6104606111d4565b61049c610605366004613dea565b61122e565b610460610618366004613e16565b611275565b61033861128f565b610338610633366004613e38565b6112f5565b610460610646366004613e16565b611352565b600a54610411906001600160a01b031681565b6000546001600160a01b0316610411565b61033861067d366004613bc2565b611361565b610338611416565b6104c3610698366004613b4e565b611492565b6106c46106ab366004613b4e565b61ffff1660009081526005602052604090205460ff1690565b60405160ff90911681526020016103f5565b6103386106e4366004613be6565b6114e6565b6103386106f7366004613dea565b611541565b6104c361159e565b610338610712366004613e86565b61162a565b610338610725366004613ecb565b61168d565b6106c4610738366004613b4e565b60056020526000908152604090205460ff1681565b61033861075b366004613bc2565b6116eb565b61046060025481565b610460610777366004613f22565b611780565b61033861078a366004613f3b565b61178b565b61033861079d366004613bc2565b61190b565b6103386107b0366004613f6d565b6119ce565b6108156107c3366004613b4e565b6004602052600090815260409020805460019091015460ff82169161ffff6101008204811692630100000083049091169167ffffffffffffffff6501000000000090910416906001600160a01b031685565b6040805160ff96909616865261ffff9485166020870152929093169184019190915267ffffffffffffffff1660608301526001600160a01b0316608082015260a0016103f5565b61046061086a366004613f97565b611a27565b600c54610411906001600160a01b031681565b610338610890366004613bc2565b611ab6565b3360009081526001602081905260409091205460ff161515146108ed5760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064015b60405180910390fd5b6108fa8585858585611b95565b5050505050565b6000546001600160a01b0316331461095b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108e4565b6009805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b60008060015b6103e88161ffff16116109d25761ffff81166000908152600560205260409020600101546109be9083613ff2565b9150806109ca81614018565b915050610990565b50919050565b6000546001600160a01b03163314610a325760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108e4565b600a546001600160a01b031615610a5a57600a54610a5a906001600160a01b03166000610f08565b600a805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038316179055610a8d816001610f08565b50565b3360009081526001602081905260409091205460ff16151514610ae35760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064016108e4565b6108fa85858585856120cb565b600354600160a01b900460ff1615610b3e5760405162461bcd60e51b8152602060048201526011602482015270119d5b98dd1a5bdb88191a5cd8589b1959607a1b60448201526064016108e4565b610b4b33858585856120cb565b50505050565b3360009081526001602081905260409091205460ff1615151480610b7f57506000546001600160a01b031633145b610bb95760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064016108e4565b60038054911515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b3360009081526001602081905260409091205460ff16151514610c455760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064016108e4565b6003546040517f42d866930000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152909116906342d8669390602401600060405180830381600087803b158015610ca557600080fd5b505af11580156108fa573d6000803e3d6000fd5b6001600160a01b0381166000908152600760205260408120546060919067ffffffffffffffff811115610cee57610cee61396f565b604051908082528060200260200182016040528015610d4757816020015b6040805160a081018252600080825260208083018290529282018190526060820181905260808201528252600019909201910181610d0c5790505b50905060005b6001600160a01b03841660009081526007602052604090205461ffff82161015610e6a576001600160a01b03841660009081526007602052604081208054600492919061ffff8516908110610da457610da461403a565b60009182526020808320601083040154600f90921660020261010090810a90920461ffff9081168552848201959095526040938401909220835160a081018552815460ff811682529283048616938101939093526301000000820485169383019390935265010000000000900467ffffffffffffffff1660608201526001909101546001600160a01b03166080820152835190918491908416908110610e4c57610e4c61403a565b60200260200101819052508080610e6290614018565b915050610d4d565b5092915050565b3360009081526001602081905260409091205460ff16151514610ec45760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064016108e4565b61ffff9091166000908152600460205260409020805467ffffffffffffffff90921665010000000000026cffffffffffffffff000000000019909216919091179055565b6000546001600160a01b03163314610f625760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108e4565b6001600160a01b03919091166000908152600160205260409020805460ff1916911515919091179055565b61ffff81166000908152600560205260408120600101546060919067ffffffffffffffff811115610fc057610fc061396f565b60405190808252806020026020018201604052801561101957816020015b6040805160a081018252600080825260208083018290529282018190526060820181905260808201528252600019909201910181610fde5790505b50905060005b61ffff8085166000908152600560205260409020600101549082161015610e6a5761ffff80851660009081526005602052604081206001018054600493851690811061106d5761106d61403a565b60009182526020808320601083040154600f90921660020261010090810a90920461ffff9081168552848201959095526040938401909220835160a081018552815460ff811682529283048616938101939093526301000000820485169383019390935265010000000000900467ffffffffffffffff1660608201526001909101546001600160a01b031660808201528351909184919084169081106111155761111561403a565b6020026020010181905250808061112b90614018565b91505061101f565b604080516001600160a01b038616602082015290810184905260608101839052628d1ed360808201526000906111cb9060a00160408051601f198184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c016040516020818303038152906040528051906020012083612578565b95945050505050565b600080600254116112275760405162461bcd60e51b815260206004820152601160248201527f456e642052657761726473206572726f7200000000000000000000000000000060448201526064016108e4565b5060025490565b6007602052816000526040600020818154811061124a57600080fd5b9060005260206000209060109182820401919006600202915091509054906101000a900461ffff1681565b60008183116112845781611286565b825b90505b92915050565b6000546001600160a01b031633146112e95760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108e4565b6112f3600061259c565b565b600354600160a01b900460ff16156113435760405162461bcd60e51b8152602060048201526011602482015270119d5b98dd1a5bdb88191a5cd8589b1959607a1b60448201526064016108e4565b61134e3383836125f9565b5050565b60008183116109d25782611286565b6000546001600160a01b031633146113bb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108e4565b600b546001600160a01b0316156113e357600b546113e3906001600160a01b03166000610f08565b600b805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038316179055610a8d816001610f08565b600360009054906101000a90046001600160a01b03166001600160a01b03166369babd3b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611469573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148d9190614050565b600255565b61ffff818116600090815260046020526040812054909161010090910481161480159061128957505061ffff1660009081526004602052604090205465010000000000900467ffffffffffffffff16151590565b600354600160a01b900460ff16156115345760405162461bcd60e51b8152602060048201526011602482015270119d5b98dd1a5bdb88191a5cd8589b1959607a1b60448201526064016108e4565b610b4b3385858585611b95565b3360009081526001602081905260409091205460ff161515146115945760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064016108e4565b61134e8282612da2565b600354604080517fb187bd2600000000000000000000000000000000000000000000000000000000815290516000926001600160a01b03169163b187bd269160048083019260209291908290030181865afa158015611601573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116259190614069565b905090565b3360009081526001602081905260409091205460ff1615151461167d5760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064016108e4565b611688838383612e1d565b505050565b3360009081526001602081905260409091205460ff161515146116e05760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064016108e4565b6116888383836125f9565b6000546001600160a01b031633146117455760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108e4565b6003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038316179055611778816001610f08565b610a8d611416565b600061128982613422565b3360009081526001602081905260409091205460ff16151514806117b957506000546001600160a01b031633145b6117f35760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064016108e4565b61ffff821660009081526005602052604090205460ff1661182d5761ffff82166000908152600560205260409020805460ff191660091790555b61ffff821660009081526005602052604090205460149061185290839060ff16614086565b60ff1611156118c95760405162461bcd60e51b815260206004820152602e60248201527f43727970746f466f7865735374616b696e6756323a756e6c6f636b536c6f742060448201527f4d617820736c6f74206c696d697400000000000000000000000000000000000060648201526084016108e4565b61ffff8216600090815260056020526040812080548392906118ef90849060ff16614086565b92506101000a81548160ff021916908360ff1602179055505050565b3360009081526001602081905260409091205460ff161515148061193957506000546001600160a01b031633145b6119735760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064016108e4565b600c546001600160a01b03161561199b57600c5461199b906001600160a01b03166000610f08565b600c805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038316179055610a8d816001610f08565b600354600160a01b900460ff1615611a1c5760405162461bcd60e51b8152602060048201526011602482015270119d5b98dd1a5bdb88191a5cd8589b1959607a1b60448201526064016108e4565b61134e338383612e1d565b600c546040517f2d011e830000000000000000000000000000000000000000000000000000000081526000916001600160a01b031690632d011e8390611a75903090879087906004016140ea565b602060405180830381865afa158015611a92573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112869190614050565b6000546001600160a01b03163314611b105760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108e4565b6001600160a01b038116611b8c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016108e4565b610a8d8161259c565b611ba285858585856120cb565b60005b84518161ffff1610156120c357611bd8858261ffff1681518110611bcb57611bcb61403a565b6020026020010151611492565b8015611c305750856001600160a01b031660046000878461ffff1681518110611c0357611c0361403a565b60209081029190910181015161ffff168252810191909152604001600020600101546001600160a01b0316145b611ca25760405162461bcd60e51b815260206004820152602660248201527f43727970746f466f7865735374616b696e6756323a756e737461636b204e6f7460448201527f206f776e6572000000000000000000000000000000000000000000000000000060648201526084016108e4565b6000611ce5868361ffff1681518110611cbd57611cbd61403a565b602002602001015161ffff908116600090815260046020526040902054630100000090041690565b9050611d0e868361ffff1681518110611d0057611d0061403a565b602002602001015182613430565b61ffff60046000888561ffff1681518110611d2b57611d2b61403a565b602002602001015161ffff1661ffff16815260200190815260200160002060000160016101000a81548161ffff021916908361ffff160217905550600a60009054906101000a90046001600160a01b03166001600160a01b03166323b872dd3089898661ffff1681518110611da257611da261403a565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b03938416600482015292909116602483015261ffff166044820152606401600060405180830381600087803b158015611e1857600080fd5b505af1158015611e2c573d6000803e3d6000fd5b50505050600060086000888561ffff1681518110611e4c57611e4c61403a565b60209081029190910181015161ffff90811683528282019390935260409182016000908120546001600160a01b038d1682526007909252918220549216925090611e989060019061411c565b90508061ffff168261ffff1614611fea576001600160a01b0389166000908152600760205260409020805461ffff8316908110611ed757611ed761403a565b90600052602060002090601091828204019190066002029054906101000a900461ffff16600760008b6001600160a01b03166001600160a01b031681526020019081526020016000208361ffff1681548110611f3557611f3561403a565b90600052602060002090601091828204019190066002026101000a81548161ffff021916908361ffff1602179055508160086000600760008d6001600160a01b03166001600160a01b031681526020019081526020016000208461ffff1681548110611fa357611fa361403a565b60009182526020808320601083040154600f9092166002026101000a90910461ffff90811684529083019390935260409091019020805461ffff1916929091169190911790555b6001600160a01b038916600090815260076020526040902080548061201157612011614133565b60019003818190600052602060002090601091828204019190066002026101000a81549061ffff021916905590557f39ffe68dc89b1ea2339d31ad856fd7dcf152384c431f59a679e2b099586f211d888561ffff16815181106120765761207661403a565b60200260200101518a6040516120a592919061ffff9290921682526001600160a01b0316602082015260400190565b60405180910390a150505080806120bb90614018565b915050611ba5565b505050505050565b600084511180156120e157506120df61159e565b155b61212d5760405162461bcd60e51b815260206004820152600c60248201527f546f6b656e7320656d707479000000000000000000000000000000000000000060448201526064016108e4565b821561226f5760008281526006602052604090205460ff16156121b85760405162461bcd60e51b815260206004820152603260248201527f43727970746f466f7865735374616b696e6756323a636c61696d52657761726460448201527f735632207369676e61747572652075736564000000000000000000000000000060648201526084016108e4565b6000828152600660205260409020805460ff191660011790556009546001600160a01b03166121e986858585611133565b6001600160a01b0316146122655760405162461bcd60e51b815260206004820152603260248201527f43727970746f466f7865735374616b696e6756323a636c61696d52657761726460448201527f735632207369676e6174757265206661696c000000000000000000000000000060648201526084016108e4565b61226f8584612da2565b60005b84518161ffff16101561240657612298858261ffff1681518110611bcb57611bcb61403a565b80156122f05750856001600160a01b031660046000878461ffff16815181106122c3576122c361403a565b60209081029190910181015161ffff168252810191909152604001600020600101546001600160a01b0316145b61233c5760405162461bcd60e51b815260206004820152600960248201527f426164206f776e6572000000000000000000000000000000000000000000000060448201526064016108e4565b60005b8161ffff168161ffff1610156123f357858261ffff16815181106123655761236561403a565b602002602001015161ffff16868261ffff16815181106123875761238761403a565b602002602001015161ffff1614156123e15760405162461bcd60e51b815260206004820152600c60248201527f4475706c6963617465206964000000000000000000000000000000000000000060448201526064016108e4565b806123eb81614018565b91505061233f565b50806123fe81614018565b915050612272565b50600c546040517f0904f23b0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690630904f23b9061245490309088908a90600401614149565b600060405180830381600087803b15801561246e57600080fd5b505af1158015612482573d6000803e3d6000fd5b5050505060005b84518161ffff1610156120c3574260046000878461ffff16815181106124b1576124b161403a565b602002602001015161ffff1661ffff16815260200190815260200160002060000160056101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f9754042e6e90c2cd4d06d89fd818a6cc3fd0723cee7888f9832663a7147621d6858261ffff168151811061252f5761252f61403a565b60200260200101518760405161255e92919061ffff9290921682526001600160a01b0316602082015260400190565b60405180910390a18061257081614018565b915050612489565b600080600061258785856135fa565b915091506125948161366a565b509392505050565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600b546040516331a9108f60e11b815261ffff831660048201526000916001600160a01b031690636352211e90602401602060405180830381865afa158015612646573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061266a919061417f565b6001600160a01b031614156126e75760405162461bcd60e51b815260206004820152602c60248201527f43727970746f466f7865735374616b696e6756323a737461636b206f7269676960448201527f6e206e6f74206d696e746564000000000000000000000000000000000000000060648201526084016108e4565b60018161ffff161015801561270257506103e88161ffff1611155b6127745760405162461bcd60e51b815260206004820152602d60248201527f43727970746f466f7865735374616b696e6756323a737461636b20746f6b656e60448201527f206f7574206f662072616e67650000000000000000000000000000000000000060648201526084016108e4565b61ffff811660009081526005602052604090205460ff166127ae5761ffff81166000908152600560205260409020805460ff191660091790555b61ffff811660009081526005602052604090208054835160019092015460ff909116916127da9161419c565b111561284e5760405162461bcd60e51b815260206004820152602360248201527f43727970746f466f7865735374616b696e6756323a737461636b206e6f20736c60448201527f6f7473000000000000000000000000000000000000000000000000000000000060648201526084016108e4565b60005b82518161ffff161015610b4b57600a5483516001600160a01b03808716921690636352211e90869061ffff861690811061288d5761288d61403a565b60200260200101516040518263ffffffff1660e01b81526004016128bb919061ffff91909116815260200190565b602060405180830381865afa1580156128d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128fc919061417f565b6001600160a01b0316146129775760405162461bcd60e51b8152602060048201526024808201527f43727970746f466f7865735374616b696e6756323a737461636b204e6f74206f60448201527f776e65720000000000000000000000000000000000000000000000000000000060648201526084016108e4565b828161ffff168151811061298d5761298d61403a565b602002602001015160046000858461ffff16815181106129af576129af61403a565b602002602001015161ffff1661ffff16815260200190815260200160002060000160016101000a81548161ffff021916908361ffff1602179055508360046000858461ffff1681518110612a0557612a0561403a565b602002602001015161ffff1661ffff16815260200190815260200160002060010160006101000a8154816001600160a01b0302191690836001600160a01b031602179055504260046000858461ffff1681518110612a6557612a6561403a565b602002602001015161ffff1661ffff16815260200190815260200160002060000160056101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550612b5e838261ffff1681518110612ac557612ac561403a565b60209081029190910181015161ffff9081166000818152600484526040808220805464ffff0000001981166301000000878c1690810291821784558552600588529284206001908101805464ffff0000ff1990931660ff199095169490941760ff909216919091179091558154908101825590825293902060108404018054600f9094166002026101000a928302199093169102179055565b600a5483516001600160a01b03909116906323b872dd9086903090879061ffff8716908110612b8f57612b8f61403a565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b03938416600482015292909116602483015261ffff166044820152606401600060405180830381600087803b158015612c0557600080fd5b505af1158015612c19573d6000803e3d6000fd5b505050506001600160a01b03841660009081526007602052604081205484519091600891869061ffff8616908110612c5357612c5361403a565b602002602001015161ffff1661ffff16815260200190815260200160002060006101000a81548161ffff021916908361ffff16021790555060076000856001600160a01b03166001600160a01b03168152602001908152602001600020838261ffff1681518110612cc657612cc661403a565b602002602001015190806001815401808255809150506001900390600052602060002090601091828204019190066002029091909190916101000a81548161ffff021916908361ffff1602179055507f04d9141cab8d3f484f6d1a48a806003201182de9425cf677c54ea30f7c591300838261ffff1681518110612d4c57612d4c61403a565b60200260200101518386604051612d889392919061ffff93841681529190921660208201526001600160a01b0391909116604082015260600190565b60405180910390a180612d9a81614018565b915050612851565b6003546040517fa9fc507b0000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152602482018490529091169063a9fc507b90604401600060405180830381600087803b158015612e0957600080fd5b505af11580156120c3573d6000803e3d6000fd5b612e2682611492565b612e985760405162461bcd60e51b815260206004820152602860248201527f43727970746f466f7865735374616b696e6756323a6d6f7665537461636b204e60448201527f6f74206f776e657200000000000000000000000000000000000000000000000060648201526084016108e4565b6000612ebe8361ffff908116600090815260046020526040902054630100000090041690565b90508161ffff168161ffff161415612f3e5760405162461bcd60e51b815260206004820152603160248201527f43727970746f466f7865735374616b696e6756323a6d6f7665537461636b206e60448201527f6f74206d6f76696e6720746f6b656e496400000000000000000000000000000060648201526084016108e4565b600b546040516331a9108f60e11b815261ffff831660048201526001600160a01b03868116921690636352211e90602401602060405180830381865afa158015612f8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fb0919061417f565b6001600160a01b03161461302c5760405162461bcd60e51b815260206004820152602f60248201527f43727970746f466f7865735374616b696e6756323a6d6f7665537461636b206f60448201527f726967696e206e6f74206f776e6572000000000000000000000000000000000060648201526084016108e4565b600b546040516331a9108f60e11b815261ffff841660048201526000916001600160a01b031690636352211e90602401602060405180830381865afa158015613079573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309d919061417f565b6001600160a01b0316141561311a5760405162461bcd60e51b815260206004820152603260248201527f43727970746f466f7865735374616b696e6756323a6d6f7665537461636b206f60448201527f726967696e546f206e6f74206d696e746564000000000000000000000000000060648201526084016108e4565b60018261ffff161015801561313557506103e88261ffff1611155b6131a75760405162461bcd60e51b815260206004820152603360248201527f43727970746f466f7865735374616b696e6756323a6d6f7665537461636b207460448201527f6f6b656e546f206f7574206f662072616e67650000000000000000000000000060648201526084016108e4565b61ffff821660009081526005602052604090205460ff166131e15761ffff82166000908152600560205260409020805460ff191660091790555b61ffff82166000908152600560205260409020805460019091015460ff909116116132745760405162461bcd60e51b815260206004820152602760248201527f43727970746f466f7865735374616b696e6756323a6d6f7665537461636b206e60448201527f6f20736c6f74730000000000000000000000000000000000000000000000000060648201526084016108e4565b61327e8382613430565b61ffff838116600081815260046020908152604080832080548887166301000000810264ffff00000019831681178455908652600585529285206001908101805460ff1660ff1990951664ffff0000ff1990931692909217939093179091558054918201815583529120601082040180546002600f909316929092026101000a928302929093021916179055600c546040517fdd5f296b00000000000000000000000000000000000000000000000000000000815230600482015261ffff851660248201526001600160a01b0386811660448301529091169063dd5f296b90606401600060405180830381600087803b15801561337a57600080fd5b505af115801561338e573d6000803e3d6000fd5b5050505061ffff83811660008181526004602090815260409182902080546cffffffffffffffff00000000001916650100000000004267ffffffffffffffff16021790558151928352928516928201929092526001600160a01b0386168183015290517f2b95f53487e6e92f14a2219e11240a2879334bb9a1df8854ee2f1c5baa943c50916060908290030190a150505050565b6000611289826106466111d4565b61ffff80831660009081526004602090815260408083205493851683526005909152812060019081015460ff9093169261346a919061411c565b90508060ff168260ff16146135a35761ffff83166000908152600560205260409020600101805460ff83169081106134a4576134a461403a565b90600052602060002090601091828204019190066002029054906101000a900461ffff16600560008561ffff1661ffff1681526020019081526020016000206001018360ff16815481106134fa576134fa61403a565b90600052602060002090601091828204019190066002026101000a81548161ffff021916908361ffff1602179055508160046000600560008761ffff1661ffff1681526020019081526020016000206001018460ff16815481106135605761356061403a565b60009182526020808320601083040154600f9092166002026101000a90910461ffff1683528201929092526040019020805460ff191660ff929092169190911790555b61ffff831660009081526005602052604090206001018054806135c8576135c8614133565b600082815260209020601060001990920191820401805461ffff6002600f8516026101000a0219169055905550505050565b6000808251604114156136315760208301516040840151606085015160001a61362587828585613825565b94509450505050613663565b82516040141561365b5760208301516040840151613650868383613912565b935093505050613663565b506000905060025b9250929050565b600081600481111561367e5761367e6141b4565b14156136875750565b600181600481111561369b5761369b6141b4565b14156136e95760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108e4565b60028160048111156136fd576136fd6141b4565b141561374b5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108e4565b600381600481111561375f5761375f6141b4565b14156137b85760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108e4565b60048160048111156137cc576137cc6141b4565b1415610a8d5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016108e4565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561385c5750600090506003613909565b8460ff16601b1415801561387457508460ff16601c14155b156138855750600090506004613909565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156138d9573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661390257600060019250925050613909565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831660ff84901c601b0161394c87828885613825565b935093505050935093915050565b6001600160a01b0381168114610a8d57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156139ae576139ae61396f565b604052919050565b803561ffff811681146139c857600080fd5b919050565b600082601f8301126139de57600080fd5b8135602067ffffffffffffffff8211156139fa576139fa61396f565b8160051b613a09828201613985565b9283528481018201928281019087851115613a2357600080fd5b83870192505b84831015613a4957613a3a836139b6565b82529183019190830190613a29565b979650505050505050565b600082601f830112613a6557600080fd5b813567ffffffffffffffff811115613a7f57613a7f61396f565b613a92601f8201601f1916602001613985565b818152846020838601011115613aa757600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a08688031215613adc57600080fd5b8535613ae78161395a565b9450602086013567ffffffffffffffff80821115613b0457600080fd5b613b1089838a016139cd565b955060408801359450606088013593506080880135915080821115613b3457600080fd5b50613b4188828901613a54565b9150509295509295909350565b600060208284031215613b6057600080fd5b611286826139b6565b60a08101611289828460ff8151168252602081015161ffff8082166020850152806040840151166040850152505067ffffffffffffffff60608201511660608301526001600160a01b0360808201511660808301525050565b600060208284031215613bd457600080fd5b8135613bdf8161395a565b9392505050565b60008060008060808587031215613bfc57600080fd5b843567ffffffffffffffff80821115613c1457600080fd5b613c20888389016139cd565b955060208701359450604087013593506060870135915080821115613c4457600080fd5b50613c5187828801613a54565b91505092959194509250565b8015158114610a8d57600080fd5b600060208284031215613c7d57600080fd5b8135613bdf81613c5d565b6020808252825182820181905260009190848201906040850190845b81811015613d1557613d0283855160ff8151168252602081015161ffff8082166020850152806040840151166040850152505067ffffffffffffffff60608201511660608301526001600160a01b0360808201511660808301525050565b9284019260a09290920191600101613ca4565b50909695505050505050565b60008060408385031215613d3457600080fd5b613d3d836139b6565b9150602083013567ffffffffffffffff81168114613d5a57600080fd5b809150509250929050565b60008060408385031215613d7857600080fd5b8235613d838161395a565b91506020830135613d5a81613c5d565b60008060008060808587031215613da957600080fd5b8435613db48161395a565b93506020850135925060408501359150606085013567ffffffffffffffff811115613dde57600080fd5b613c5187828801613a54565b60008060408385031215613dfd57600080fd5b8235613e088161395a565b946020939093013593505050565b60008060408385031215613e2957600080fd5b50508035926020909101359150565b60008060408385031215613e4b57600080fd5b823567ffffffffffffffff811115613e6257600080fd5b613e6e858286016139cd565b925050613e7d602084016139b6565b90509250929050565b600080600060608486031215613e9b57600080fd5b8335613ea68161395a565b9250613eb4602085016139b6565b9150613ec2604085016139b6565b90509250925092565b600080600060608486031215613ee057600080fd5b8335613eeb8161395a565b9250602084013567ffffffffffffffff811115613f0757600080fd5b613f13868287016139cd565b925050613ec2604085016139b6565b600060208284031215613f3457600080fd5b5035919050565b60008060408385031215613f4e57600080fd5b613f57836139b6565b9150602083013560ff81168114613d5a57600080fd5b60008060408385031215613f8057600080fd5b613f89836139b6565b9150613e7d602084016139b6565b60008060408385031215613faa57600080fd5b823567ffffffffffffffff811115613fc157600080fd5b613fcd858286016139cd565b95602094909401359450505050565b634e487b7160e01b600052601160045260246000fd5b600061ffff80831681851680830382111561400f5761400f613fdc565b01949350505050565b600061ffff8083168181141561403057614030613fdc565b6001019392505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561406257600080fd5b5051919050565b60006020828403121561407b57600080fd5b8151613bdf81613c5d565b600060ff821660ff84168060ff038211156140a3576140a3613fdc565b019392505050565b600081518084526020808501945080840160005b838110156140df57815161ffff16875295820195908201906001016140bf565b509495945050505050565b6001600160a01b038416815260606020820152600061410c60608301856140ab565b9050826040830152949350505050565b60008282101561412e5761412e613fdc565b500390565b634e487b7160e01b600052603160045260246000fd5b60006001600160a01b0380861683526060602084015261416c60608401866140ab565b9150808416604084015250949350505050565b60006020828403121561419157600080fd5b8151613bdf8161395a565b600082198211156141af576141af613fdc565b500190565b634e487b7160e01b600052602160045260246000fdfea2646970667358221220069d3e1970e408f667d3ff0fdb36db600c7c8654963596a7476df30cd79a502464736f6c634300080a00330000000000000000000000000d685869cf9ce4a6bda2380ca76f504dd18eab8c000000000000000000000000a9fdb3f96fae7c12d70393659867c6115683ada0000000000000000000000000a66a77dbe5e01027741ec21918b4b6dcd143d627

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106103205760003560e01c8063793f6777116101a7578063b4fc0b98116100ee578063e026615b11610097578063e8b1f1b411610071578063e8b1f1b41461085c578063ecb0c3171461086f578063f2fde38b1461088257600080fd5b8063e026615b1461078f578063e05acaa5146107a2578063e64bdbe5146107b557600080fd5b8063d9cd1ca0116100c8578063d9cd1ca014610760578063dc707e3b14610769578063de1f276c1461077c57600080fd5b8063b4fc0b9814610717578063ba477b921461072a578063cfabc2741461074d57600080fd5b8063a12dfd7211610150578063a9fc507b1161012a578063a9fc507b146106e9578063b187bd26146106fc578063b3b623a51461070457600080fd5b8063a12dfd721461068a578063a89448e41461069d578063a897e24f146106d657600080fd5b80638da5cb5b116101815780638da5cb5b1461065e57806399d90a731461066f5780639c1c3a8f1461068257600080fd5b8063793f6777146106255780637ae2b5c7146106385780637e2caf361461064b57600080fd5b806342d866931161026b578063583064fc116102145780636d189c5b116101ee5780636d189c5b146105f75780636d5433e61461060a578063715018a61461061d57600080fd5b8063583064fc146105c95780635c686669146105dc57806369babd3b146105ef57600080fd5b806351e0e26b1161024557806351e0e26b1461056557806355de1faf14610588578063571f5f1d1461059b57600080fd5b806342d866931461051f578063438b6300146105325780635159371c1461055257600080fd5b806318160ddd116102cd5780633a8dac2a116102a75780633a8dac2a146104e65780633dc77e8f146104f95780633f282b711461050c57600080fd5b806318160ddd146104945780631a95082d146104af57806333853ed5146104d357600080fd5b80630ea25ced116102fe5780630ea25ced14610429578063101ce36c1461046e578063151370451461048157600080fd5b8063011df42d146103255780630428a2a71461033a5780630ca7abf9146103fe575b600080fd5b610338610333366004613ac4565b610895565b005b6103e8610348366004613b4e565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091525061ffff908116600090815260046020908152604091829020825160a081018452815460ff811682526101008104861693820193909352630100000083049094169284019290925265010000000000900467ffffffffffffffff166060830152600101546001600160a01b0316608082015290565b6040516103f59190613b69565b60405180910390f35b600b54610411906001600160a01b031681565b6040516001600160a01b0390911681526020016103f5565b610460610437366004613b4e565b61ffff1660009081526004602052604090205465010000000000900467ffffffffffffffff1690565b6040519081526020016103f5565b600354610411906001600160a01b031681565b61033861048f366004613bc2565b610901565b61049c61098a565b60405161ffff90911681526020016103f5565b6003546104c390600160a01b900460ff1681565b60405190151581526020016103f5565b6103386104e1366004613bc2565b6109d8565b6103386104f4366004613ac4565b610a90565b610338610507366004613be6565b610af0565b61033861051a366004613c6b565b610b51565b61033861052d366004613bc2565b610bf2565b610545610540366004613bc2565b610cb9565b6040516103f59190613c88565b610338610560366004613d21565b610e71565b6104c3610573366004613bc2565b60016020526000908152604090205460ff1681565b610338610596366004613d65565b610f08565b61049c6105a9366004613b4e565b61ffff908116600090815260046020526040902054630100000090041690565b6105456105d7366004613b4e565b610f8d565b6104116105ea366004613d93565b611133565b6104606111d4565b61049c610605366004613dea565b61122e565b610460610618366004613e16565b611275565b61033861128f565b610338610633366004613e38565b6112f5565b610460610646366004613e16565b611352565b600a54610411906001600160a01b031681565b6000546001600160a01b0316610411565b61033861067d366004613bc2565b611361565b610338611416565b6104c3610698366004613b4e565b611492565b6106c46106ab366004613b4e565b61ffff1660009081526005602052604090205460ff1690565b60405160ff90911681526020016103f5565b6103386106e4366004613be6565b6114e6565b6103386106f7366004613dea565b611541565b6104c361159e565b610338610712366004613e86565b61162a565b610338610725366004613ecb565b61168d565b6106c4610738366004613b4e565b60056020526000908152604090205460ff1681565b61033861075b366004613bc2565b6116eb565b61046060025481565b610460610777366004613f22565b611780565b61033861078a366004613f3b565b61178b565b61033861079d366004613bc2565b61190b565b6103386107b0366004613f6d565b6119ce565b6108156107c3366004613b4e565b6004602052600090815260409020805460019091015460ff82169161ffff6101008204811692630100000083049091169167ffffffffffffffff6501000000000090910416906001600160a01b031685565b6040805160ff96909616865261ffff9485166020870152929093169184019190915267ffffffffffffffff1660608301526001600160a01b0316608082015260a0016103f5565b61046061086a366004613f97565b611a27565b600c54610411906001600160a01b031681565b610338610890366004613bc2565b611ab6565b3360009081526001602081905260409091205460ff161515146108ed5760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064015b60405180910390fd5b6108fa8585858585611b95565b5050505050565b6000546001600160a01b0316331461095b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108e4565b6009805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b60008060015b6103e88161ffff16116109d25761ffff81166000908152600560205260409020600101546109be9083613ff2565b9150806109ca81614018565b915050610990565b50919050565b6000546001600160a01b03163314610a325760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108e4565b600a546001600160a01b031615610a5a57600a54610a5a906001600160a01b03166000610f08565b600a805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038316179055610a8d816001610f08565b50565b3360009081526001602081905260409091205460ff16151514610ae35760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064016108e4565b6108fa85858585856120cb565b600354600160a01b900460ff1615610b3e5760405162461bcd60e51b8152602060048201526011602482015270119d5b98dd1a5bdb88191a5cd8589b1959607a1b60448201526064016108e4565b610b4b33858585856120cb565b50505050565b3360009081526001602081905260409091205460ff1615151480610b7f57506000546001600160a01b031633145b610bb95760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064016108e4565b60038054911515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b3360009081526001602081905260409091205460ff16151514610c455760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064016108e4565b6003546040517f42d866930000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152909116906342d8669390602401600060405180830381600087803b158015610ca557600080fd5b505af11580156108fa573d6000803e3d6000fd5b6001600160a01b0381166000908152600760205260408120546060919067ffffffffffffffff811115610cee57610cee61396f565b604051908082528060200260200182016040528015610d4757816020015b6040805160a081018252600080825260208083018290529282018190526060820181905260808201528252600019909201910181610d0c5790505b50905060005b6001600160a01b03841660009081526007602052604090205461ffff82161015610e6a576001600160a01b03841660009081526007602052604081208054600492919061ffff8516908110610da457610da461403a565b60009182526020808320601083040154600f90921660020261010090810a90920461ffff9081168552848201959095526040938401909220835160a081018552815460ff811682529283048616938101939093526301000000820485169383019390935265010000000000900467ffffffffffffffff1660608201526001909101546001600160a01b03166080820152835190918491908416908110610e4c57610e4c61403a565b60200260200101819052508080610e6290614018565b915050610d4d565b5092915050565b3360009081526001602081905260409091205460ff16151514610ec45760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064016108e4565b61ffff9091166000908152600460205260409020805467ffffffffffffffff90921665010000000000026cffffffffffffffff000000000019909216919091179055565b6000546001600160a01b03163314610f625760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108e4565b6001600160a01b03919091166000908152600160205260409020805460ff1916911515919091179055565b61ffff81166000908152600560205260408120600101546060919067ffffffffffffffff811115610fc057610fc061396f565b60405190808252806020026020018201604052801561101957816020015b6040805160a081018252600080825260208083018290529282018190526060820181905260808201528252600019909201910181610fde5790505b50905060005b61ffff8085166000908152600560205260409020600101549082161015610e6a5761ffff80851660009081526005602052604081206001018054600493851690811061106d5761106d61403a565b60009182526020808320601083040154600f90921660020261010090810a90920461ffff9081168552848201959095526040938401909220835160a081018552815460ff811682529283048616938101939093526301000000820485169383019390935265010000000000900467ffffffffffffffff1660608201526001909101546001600160a01b031660808201528351909184919084169081106111155761111561403a565b6020026020010181905250808061112b90614018565b91505061101f565b604080516001600160a01b038616602082015290810184905260608101839052628d1ed360808201526000906111cb9060a00160408051601f198184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c016040516020818303038152906040528051906020012083612578565b95945050505050565b600080600254116112275760405162461bcd60e51b815260206004820152601160248201527f456e642052657761726473206572726f7200000000000000000000000000000060448201526064016108e4565b5060025490565b6007602052816000526040600020818154811061124a57600080fd5b9060005260206000209060109182820401919006600202915091509054906101000a900461ffff1681565b60008183116112845781611286565b825b90505b92915050565b6000546001600160a01b031633146112e95760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108e4565b6112f3600061259c565b565b600354600160a01b900460ff16156113435760405162461bcd60e51b8152602060048201526011602482015270119d5b98dd1a5bdb88191a5cd8589b1959607a1b60448201526064016108e4565b61134e3383836125f9565b5050565b60008183116109d25782611286565b6000546001600160a01b031633146113bb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108e4565b600b546001600160a01b0316156113e357600b546113e3906001600160a01b03166000610f08565b600b805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038316179055610a8d816001610f08565b600360009054906101000a90046001600160a01b03166001600160a01b03166369babd3b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611469573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148d9190614050565b600255565b61ffff818116600090815260046020526040812054909161010090910481161480159061128957505061ffff1660009081526004602052604090205465010000000000900467ffffffffffffffff16151590565b600354600160a01b900460ff16156115345760405162461bcd60e51b8152602060048201526011602482015270119d5b98dd1a5bdb88191a5cd8589b1959607a1b60448201526064016108e4565b610b4b3385858585611b95565b3360009081526001602081905260409091205460ff161515146115945760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064016108e4565b61134e8282612da2565b600354604080517fb187bd2600000000000000000000000000000000000000000000000000000000815290516000926001600160a01b03169163b187bd269160048083019260209291908290030181865afa158015611601573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116259190614069565b905090565b3360009081526001602081905260409091205460ff1615151461167d5760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064016108e4565b611688838383612e1d565b505050565b3360009081526001602081905260409091205460ff161515146116e05760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064016108e4565b6116888383836125f9565b6000546001600160a01b031633146117455760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108e4565b6003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038316179055611778816001610f08565b610a8d611416565b600061128982613422565b3360009081526001602081905260409091205460ff16151514806117b957506000546001600160a01b031633145b6117f35760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064016108e4565b61ffff821660009081526005602052604090205460ff1661182d5761ffff82166000908152600560205260409020805460ff191660091790555b61ffff821660009081526005602052604090205460149061185290839060ff16614086565b60ff1611156118c95760405162461bcd60e51b815260206004820152602e60248201527f43727970746f466f7865735374616b696e6756323a756e6c6f636b536c6f742060448201527f4d617820736c6f74206c696d697400000000000000000000000000000000000060648201526084016108e4565b61ffff8216600090815260056020526040812080548392906118ef90849060ff16614086565b92506101000a81548160ff021916908360ff1602179055505050565b3360009081526001602081905260409091205460ff161515148061193957506000546001600160a01b031633145b6119735760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064016108e4565b600c546001600160a01b03161561199b57600c5461199b906001600160a01b03166000610f08565b600c805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038316179055610a8d816001610f08565b600354600160a01b900460ff1615611a1c5760405162461bcd60e51b8152602060048201526011602482015270119d5b98dd1a5bdb88191a5cd8589b1959607a1b60448201526064016108e4565b61134e338383612e1d565b600c546040517f2d011e830000000000000000000000000000000000000000000000000000000081526000916001600160a01b031690632d011e8390611a75903090879087906004016140ea565b602060405180830381865afa158015611a92573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112869190614050565b6000546001600160a01b03163314611b105760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108e4565b6001600160a01b038116611b8c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016108e4565b610a8d8161259c565b611ba285858585856120cb565b60005b84518161ffff1610156120c357611bd8858261ffff1681518110611bcb57611bcb61403a565b6020026020010151611492565b8015611c305750856001600160a01b031660046000878461ffff1681518110611c0357611c0361403a565b60209081029190910181015161ffff168252810191909152604001600020600101546001600160a01b0316145b611ca25760405162461bcd60e51b815260206004820152602660248201527f43727970746f466f7865735374616b696e6756323a756e737461636b204e6f7460448201527f206f776e6572000000000000000000000000000000000000000000000000000060648201526084016108e4565b6000611ce5868361ffff1681518110611cbd57611cbd61403a565b602002602001015161ffff908116600090815260046020526040902054630100000090041690565b9050611d0e868361ffff1681518110611d0057611d0061403a565b602002602001015182613430565b61ffff60046000888561ffff1681518110611d2b57611d2b61403a565b602002602001015161ffff1661ffff16815260200190815260200160002060000160016101000a81548161ffff021916908361ffff160217905550600a60009054906101000a90046001600160a01b03166001600160a01b03166323b872dd3089898661ffff1681518110611da257611da261403a565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b03938416600482015292909116602483015261ffff166044820152606401600060405180830381600087803b158015611e1857600080fd5b505af1158015611e2c573d6000803e3d6000fd5b50505050600060086000888561ffff1681518110611e4c57611e4c61403a565b60209081029190910181015161ffff90811683528282019390935260409182016000908120546001600160a01b038d1682526007909252918220549216925090611e989060019061411c565b90508061ffff168261ffff1614611fea576001600160a01b0389166000908152600760205260409020805461ffff8316908110611ed757611ed761403a565b90600052602060002090601091828204019190066002029054906101000a900461ffff16600760008b6001600160a01b03166001600160a01b031681526020019081526020016000208361ffff1681548110611f3557611f3561403a565b90600052602060002090601091828204019190066002026101000a81548161ffff021916908361ffff1602179055508160086000600760008d6001600160a01b03166001600160a01b031681526020019081526020016000208461ffff1681548110611fa357611fa361403a565b60009182526020808320601083040154600f9092166002026101000a90910461ffff90811684529083019390935260409091019020805461ffff1916929091169190911790555b6001600160a01b038916600090815260076020526040902080548061201157612011614133565b60019003818190600052602060002090601091828204019190066002026101000a81549061ffff021916905590557f39ffe68dc89b1ea2339d31ad856fd7dcf152384c431f59a679e2b099586f211d888561ffff16815181106120765761207661403a565b60200260200101518a6040516120a592919061ffff9290921682526001600160a01b0316602082015260400190565b60405180910390a150505080806120bb90614018565b915050611ba5565b505050505050565b600084511180156120e157506120df61159e565b155b61212d5760405162461bcd60e51b815260206004820152600c60248201527f546f6b656e7320656d707479000000000000000000000000000000000000000060448201526064016108e4565b821561226f5760008281526006602052604090205460ff16156121b85760405162461bcd60e51b815260206004820152603260248201527f43727970746f466f7865735374616b696e6756323a636c61696d52657761726460448201527f735632207369676e61747572652075736564000000000000000000000000000060648201526084016108e4565b6000828152600660205260409020805460ff191660011790556009546001600160a01b03166121e986858585611133565b6001600160a01b0316146122655760405162461bcd60e51b815260206004820152603260248201527f43727970746f466f7865735374616b696e6756323a636c61696d52657761726460448201527f735632207369676e6174757265206661696c000000000000000000000000000060648201526084016108e4565b61226f8584612da2565b60005b84518161ffff16101561240657612298858261ffff1681518110611bcb57611bcb61403a565b80156122f05750856001600160a01b031660046000878461ffff16815181106122c3576122c361403a565b60209081029190910181015161ffff168252810191909152604001600020600101546001600160a01b0316145b61233c5760405162461bcd60e51b815260206004820152600960248201527f426164206f776e6572000000000000000000000000000000000000000000000060448201526064016108e4565b60005b8161ffff168161ffff1610156123f357858261ffff16815181106123655761236561403a565b602002602001015161ffff16868261ffff16815181106123875761238761403a565b602002602001015161ffff1614156123e15760405162461bcd60e51b815260206004820152600c60248201527f4475706c6963617465206964000000000000000000000000000000000000000060448201526064016108e4565b806123eb81614018565b91505061233f565b50806123fe81614018565b915050612272565b50600c546040517f0904f23b0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690630904f23b9061245490309088908a90600401614149565b600060405180830381600087803b15801561246e57600080fd5b505af1158015612482573d6000803e3d6000fd5b5050505060005b84518161ffff1610156120c3574260046000878461ffff16815181106124b1576124b161403a565b602002602001015161ffff1661ffff16815260200190815260200160002060000160056101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f9754042e6e90c2cd4d06d89fd818a6cc3fd0723cee7888f9832663a7147621d6858261ffff168151811061252f5761252f61403a565b60200260200101518760405161255e92919061ffff9290921682526001600160a01b0316602082015260400190565b60405180910390a18061257081614018565b915050612489565b600080600061258785856135fa565b915091506125948161366a565b509392505050565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600b546040516331a9108f60e11b815261ffff831660048201526000916001600160a01b031690636352211e90602401602060405180830381865afa158015612646573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061266a919061417f565b6001600160a01b031614156126e75760405162461bcd60e51b815260206004820152602c60248201527f43727970746f466f7865735374616b696e6756323a737461636b206f7269676960448201527f6e206e6f74206d696e746564000000000000000000000000000000000000000060648201526084016108e4565b60018161ffff161015801561270257506103e88161ffff1611155b6127745760405162461bcd60e51b815260206004820152602d60248201527f43727970746f466f7865735374616b696e6756323a737461636b20746f6b656e60448201527f206f7574206f662072616e67650000000000000000000000000000000000000060648201526084016108e4565b61ffff811660009081526005602052604090205460ff166127ae5761ffff81166000908152600560205260409020805460ff191660091790555b61ffff811660009081526005602052604090208054835160019092015460ff909116916127da9161419c565b111561284e5760405162461bcd60e51b815260206004820152602360248201527f43727970746f466f7865735374616b696e6756323a737461636b206e6f20736c60448201527f6f7473000000000000000000000000000000000000000000000000000000000060648201526084016108e4565b60005b82518161ffff161015610b4b57600a5483516001600160a01b03808716921690636352211e90869061ffff861690811061288d5761288d61403a565b60200260200101516040518263ffffffff1660e01b81526004016128bb919061ffff91909116815260200190565b602060405180830381865afa1580156128d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128fc919061417f565b6001600160a01b0316146129775760405162461bcd60e51b8152602060048201526024808201527f43727970746f466f7865735374616b696e6756323a737461636b204e6f74206f60448201527f776e65720000000000000000000000000000000000000000000000000000000060648201526084016108e4565b828161ffff168151811061298d5761298d61403a565b602002602001015160046000858461ffff16815181106129af576129af61403a565b602002602001015161ffff1661ffff16815260200190815260200160002060000160016101000a81548161ffff021916908361ffff1602179055508360046000858461ffff1681518110612a0557612a0561403a565b602002602001015161ffff1661ffff16815260200190815260200160002060010160006101000a8154816001600160a01b0302191690836001600160a01b031602179055504260046000858461ffff1681518110612a6557612a6561403a565b602002602001015161ffff1661ffff16815260200190815260200160002060000160056101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550612b5e838261ffff1681518110612ac557612ac561403a565b60209081029190910181015161ffff9081166000818152600484526040808220805464ffff0000001981166301000000878c1690810291821784558552600588529284206001908101805464ffff0000ff1990931660ff199095169490941760ff909216919091179091558154908101825590825293902060108404018054600f9094166002026101000a928302199093169102179055565b600a5483516001600160a01b03909116906323b872dd9086903090879061ffff8716908110612b8f57612b8f61403a565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b03938416600482015292909116602483015261ffff166044820152606401600060405180830381600087803b158015612c0557600080fd5b505af1158015612c19573d6000803e3d6000fd5b505050506001600160a01b03841660009081526007602052604081205484519091600891869061ffff8616908110612c5357612c5361403a565b602002602001015161ffff1661ffff16815260200190815260200160002060006101000a81548161ffff021916908361ffff16021790555060076000856001600160a01b03166001600160a01b03168152602001908152602001600020838261ffff1681518110612cc657612cc661403a565b602002602001015190806001815401808255809150506001900390600052602060002090601091828204019190066002029091909190916101000a81548161ffff021916908361ffff1602179055507f04d9141cab8d3f484f6d1a48a806003201182de9425cf677c54ea30f7c591300838261ffff1681518110612d4c57612d4c61403a565b60200260200101518386604051612d889392919061ffff93841681529190921660208201526001600160a01b0391909116604082015260600190565b60405180910390a180612d9a81614018565b915050612851565b6003546040517fa9fc507b0000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152602482018490529091169063a9fc507b90604401600060405180830381600087803b158015612e0957600080fd5b505af11580156120c3573d6000803e3d6000fd5b612e2682611492565b612e985760405162461bcd60e51b815260206004820152602860248201527f43727970746f466f7865735374616b696e6756323a6d6f7665537461636b204e60448201527f6f74206f776e657200000000000000000000000000000000000000000000000060648201526084016108e4565b6000612ebe8361ffff908116600090815260046020526040902054630100000090041690565b90508161ffff168161ffff161415612f3e5760405162461bcd60e51b815260206004820152603160248201527f43727970746f466f7865735374616b696e6756323a6d6f7665537461636b206e60448201527f6f74206d6f76696e6720746f6b656e496400000000000000000000000000000060648201526084016108e4565b600b546040516331a9108f60e11b815261ffff831660048201526001600160a01b03868116921690636352211e90602401602060405180830381865afa158015612f8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fb0919061417f565b6001600160a01b03161461302c5760405162461bcd60e51b815260206004820152602f60248201527f43727970746f466f7865735374616b696e6756323a6d6f7665537461636b206f60448201527f726967696e206e6f74206f776e6572000000000000000000000000000000000060648201526084016108e4565b600b546040516331a9108f60e11b815261ffff841660048201526000916001600160a01b031690636352211e90602401602060405180830381865afa158015613079573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309d919061417f565b6001600160a01b0316141561311a5760405162461bcd60e51b815260206004820152603260248201527f43727970746f466f7865735374616b696e6756323a6d6f7665537461636b206f60448201527f726967696e546f206e6f74206d696e746564000000000000000000000000000060648201526084016108e4565b60018261ffff161015801561313557506103e88261ffff1611155b6131a75760405162461bcd60e51b815260206004820152603360248201527f43727970746f466f7865735374616b696e6756323a6d6f7665537461636b207460448201527f6f6b656e546f206f7574206f662072616e67650000000000000000000000000060648201526084016108e4565b61ffff821660009081526005602052604090205460ff166131e15761ffff82166000908152600560205260409020805460ff191660091790555b61ffff82166000908152600560205260409020805460019091015460ff909116116132745760405162461bcd60e51b815260206004820152602760248201527f43727970746f466f7865735374616b696e6756323a6d6f7665537461636b206e60448201527f6f20736c6f74730000000000000000000000000000000000000000000000000060648201526084016108e4565b61327e8382613430565b61ffff838116600081815260046020908152604080832080548887166301000000810264ffff00000019831681178455908652600585529285206001908101805460ff1660ff1990951664ffff0000ff1990931692909217939093179091558054918201815583529120601082040180546002600f909316929092026101000a928302929093021916179055600c546040517fdd5f296b00000000000000000000000000000000000000000000000000000000815230600482015261ffff851660248201526001600160a01b0386811660448301529091169063dd5f296b90606401600060405180830381600087803b15801561337a57600080fd5b505af115801561338e573d6000803e3d6000fd5b5050505061ffff83811660008181526004602090815260409182902080546cffffffffffffffff00000000001916650100000000004267ffffffffffffffff16021790558151928352928516928201929092526001600160a01b0386168183015290517f2b95f53487e6e92f14a2219e11240a2879334bb9a1df8854ee2f1c5baa943c50916060908290030190a150505050565b6000611289826106466111d4565b61ffff80831660009081526004602090815260408083205493851683526005909152812060019081015460ff9093169261346a919061411c565b90508060ff168260ff16146135a35761ffff83166000908152600560205260409020600101805460ff83169081106134a4576134a461403a565b90600052602060002090601091828204019190066002029054906101000a900461ffff16600560008561ffff1661ffff1681526020019081526020016000206001018360ff16815481106134fa576134fa61403a565b90600052602060002090601091828204019190066002026101000a81548161ffff021916908361ffff1602179055508160046000600560008761ffff1661ffff1681526020019081526020016000206001018460ff16815481106135605761356061403a565b60009182526020808320601083040154600f9092166002026101000a90910461ffff1683528201929092526040019020805460ff191660ff929092169190911790555b61ffff831660009081526005602052604090206001018054806135c8576135c8614133565b600082815260209020601060001990920191820401805461ffff6002600f8516026101000a0219169055905550505050565b6000808251604114156136315760208301516040840151606085015160001a61362587828585613825565b94509450505050613663565b82516040141561365b5760208301516040840151613650868383613912565b935093505050613663565b506000905060025b9250929050565b600081600481111561367e5761367e6141b4565b14156136875750565b600181600481111561369b5761369b6141b4565b14156136e95760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108e4565b60028160048111156136fd576136fd6141b4565b141561374b5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108e4565b600381600481111561375f5761375f6141b4565b14156137b85760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108e4565b60048160048111156137cc576137cc6141b4565b1415610a8d5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016108e4565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561385c5750600090506003613909565b8460ff16601b1415801561387457508460ff16601c14155b156138855750600090506004613909565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156138d9573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661390257600060019250925050613909565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831660ff84901c601b0161394c87828885613825565b935093505050935093915050565b6001600160a01b0381168114610a8d57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156139ae576139ae61396f565b604052919050565b803561ffff811681146139c857600080fd5b919050565b600082601f8301126139de57600080fd5b8135602067ffffffffffffffff8211156139fa576139fa61396f565b8160051b613a09828201613985565b9283528481018201928281019087851115613a2357600080fd5b83870192505b84831015613a4957613a3a836139b6565b82529183019190830190613a29565b979650505050505050565b600082601f830112613a6557600080fd5b813567ffffffffffffffff811115613a7f57613a7f61396f565b613a92601f8201601f1916602001613985565b818152846020838601011115613aa757600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a08688031215613adc57600080fd5b8535613ae78161395a565b9450602086013567ffffffffffffffff80821115613b0457600080fd5b613b1089838a016139cd565b955060408801359450606088013593506080880135915080821115613b3457600080fd5b50613b4188828901613a54565b9150509295509295909350565b600060208284031215613b6057600080fd5b611286826139b6565b60a08101611289828460ff8151168252602081015161ffff8082166020850152806040840151166040850152505067ffffffffffffffff60608201511660608301526001600160a01b0360808201511660808301525050565b600060208284031215613bd457600080fd5b8135613bdf8161395a565b9392505050565b60008060008060808587031215613bfc57600080fd5b843567ffffffffffffffff80821115613c1457600080fd5b613c20888389016139cd565b955060208701359450604087013593506060870135915080821115613c4457600080fd5b50613c5187828801613a54565b91505092959194509250565b8015158114610a8d57600080fd5b600060208284031215613c7d57600080fd5b8135613bdf81613c5d565b6020808252825182820181905260009190848201906040850190845b81811015613d1557613d0283855160ff8151168252602081015161ffff8082166020850152806040840151166040850152505067ffffffffffffffff60608201511660608301526001600160a01b0360808201511660808301525050565b9284019260a09290920191600101613ca4565b50909695505050505050565b60008060408385031215613d3457600080fd5b613d3d836139b6565b9150602083013567ffffffffffffffff81168114613d5a57600080fd5b809150509250929050565b60008060408385031215613d7857600080fd5b8235613d838161395a565b91506020830135613d5a81613c5d565b60008060008060808587031215613da957600080fd5b8435613db48161395a565b93506020850135925060408501359150606085013567ffffffffffffffff811115613dde57600080fd5b613c5187828801613a54565b60008060408385031215613dfd57600080fd5b8235613e088161395a565b946020939093013593505050565b60008060408385031215613e2957600080fd5b50508035926020909101359150565b60008060408385031215613e4b57600080fd5b823567ffffffffffffffff811115613e6257600080fd5b613e6e858286016139cd565b925050613e7d602084016139b6565b90509250929050565b600080600060608486031215613e9b57600080fd5b8335613ea68161395a565b9250613eb4602085016139b6565b9150613ec2604085016139b6565b90509250925092565b600080600060608486031215613ee057600080fd5b8335613eeb8161395a565b9250602084013567ffffffffffffffff811115613f0757600080fd5b613f13868287016139cd565b925050613ec2604085016139b6565b600060208284031215613f3457600080fd5b5035919050565b60008060408385031215613f4e57600080fd5b613f57836139b6565b9150602083013560ff81168114613d5a57600080fd5b60008060408385031215613f8057600080fd5b613f89836139b6565b9150613e7d602084016139b6565b60008060408385031215613faa57600080fd5b823567ffffffffffffffff811115613fc157600080fd5b613fcd858286016139cd565b95602094909401359450505050565b634e487b7160e01b600052601160045260246000fd5b600061ffff80831681851680830382111561400f5761400f613fdc565b01949350505050565b600061ffff8083168181141561403057614030613fdc565b6001019392505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561406257600080fd5b5051919050565b60006020828403121561407b57600080fd5b8151613bdf81613c5d565b600060ff821660ff84168060ff038211156140a3576140a3613fdc565b019392505050565b600081518084526020808501945080840160005b838110156140df57815161ffff16875295820195908201906001016140bf565b509495945050505050565b6001600160a01b038416815260606020820152600061410c60608301856140ab565b9050826040830152949350505050565b60008282101561412e5761412e613fdc565b500390565b634e487b7160e01b600052603160045260246000fd5b60006001600160a01b0380861683526060602084015261416c60608401866140ab565b9150808416604084015250949350505050565b60006020828403121561419157600080fd5b8151613bdf8161395a565b600082198211156141af576141af613fdc565b500190565b634e487b7160e01b600052602160045260246000fdfea2646970667358221220069d3e1970e408f667d3ff0fdb36db600c7c8654963596a7476df30cd79a502464736f6c634300080a0033

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

0000000000000000000000000d685869cf9ce4a6bda2380ca76f504dd18eab8c000000000000000000000000a9fdb3f96fae7c12d70393659867c6115683ada0000000000000000000000000a66a77dbe5e01027741ec21918b4b6dcd143d627

-----Decoded View---------------
Arg [0] : _cryptoFoxesOrigin (address): 0x0D685869cF9ce4a6BDA2380cA76F504DD18eaB8c
Arg [1] : _cryptoFoxesContract (address): 0xA9FdB3F96fAE7C12D70393659867c6115683AdA0
Arg [2] : _signAddress (address): 0xa66a77dbE5E01027741ec21918b4b6DcD143d627

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000000d685869cf9ce4a6bda2380ca76f504dd18eab8c
Arg [1] : 000000000000000000000000a9fdb3f96fae7c12d70393659867c6115683ada0
Arg [2] : 000000000000000000000000a66a77dbe5e01027741ec21918b4b6dcd143d627


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.