ETH Price: $3,386.92 (+1.72%)

Token

Bao Token (BAO)
 

Overview

Max Total Supply

36,591,470.608506944444442618 BAO

Holders

656

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Filtered by Token Holder
drypt0.eth
Balance
18,756.24577546296296296 BAO

Value
$0.00
0x1e8bd2740f37b8080FD9FF109F887507758D737f
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
BaoToken

Compiler Version
v0.8.12+commit.f00d7308

Optimization Enabled:
Yes with 10000 runs

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

//                                       -\**:. `"^`
//                                     ;HNXav*,^;}?|:,.`
//                                    tbKX&]:,:7I}=\:-_._,`
//                                  :OKgTv)*7}ri=*;::,^``:;:^
//                               :&S@OTnccvtl])*\;:--~.`_;;-,^.`
//                            :cdXDOhT&Yuctl1=*;::,^..,;+*;:--,"~^.
//                         ;LX8dXSDOhasocv}1>+|;:---:;|||;:--,"_^^^..`
//                      :3@bd8dXSDPTasocvtl]>+|;::::;;;:::--,_~^^^..'````
//                   `laP@d88d@DhT0Yo3cjt}i]=+*\;;:::::::---,_^^^..'``    ``
//                 `)3&hSd8dbDhT&YoccvIt}l17=)*|;;:::::::--,"_^^^..'```     ``
//                ;=rnOb88d@OT&nucvjItr}i17==+**\;;;:::::--,"~^^^..''``        `
//              ^^:lnOXg8XDhaYucvjttr}lir3Luv=**|;;;;;:::--,_~^^....'-XMMh='     `
//             ``~>YOdKKd@haYucvttrrINMMMMMMMMMMj\;;;;::::-,"~^^....-MMMHDr=:`
//              ,7YDgmK8@haYucItr}}MMMMMMMMmt|1MMM=;;;;::::-,_^^....MMQ8OT-`';`
//          ` `-}&Smqm8SPTsucjr}}lMMMMMMMMMDl|]MMMM|;;;;:::--"^^..''MMmSOhV7)1:`
//        '"^,+vhdHNNEbOT&ocjtllitMMMMMMMMMMMMMMMMM1||\;;;::-"^..''`TMNKSDhaLt\-
//        =)=}nOmNQBHgDhaYuvIrli?jMMMMMMMMMMMMMMMMM1|||;;;::-~.'''``.dMBq8Oaor*|
//       cLY0OgNQQQWHdDh0Yuvt}i?11MMMMMMMMMMMMMMMMM**|;;;:::-_..''```.c#WHSaul7+        `
//      =OS8mNQMMMMQH8DhasucIrli111MMMMMMMMMMMMMMM+*|;;;::::-,^..''````.1VEHda7`        ``
//      @mHWQMMMMMMQNEbDkan3vtli1]>=?SMMMMMMMMMh)**|\;;::::--,~^..-'```````,,``````     ``
//      NQMMMMMMMMMMQNKbOh0Luv}i7==))))))))+*****||\;;;1MMMXkncuOKo.'''````````````````````
//      QMMMMMMMMMMMMQNmdDh&n3I}17==)))))))+****|\;;;;:::::*71=;,~^^...''''````````````````
//      QMMMMMMMMMMMMMQBHEbOTVocjtli?11]>>==)+**||;;;;::::::----,,_~^^^.........''''''````
//      jMMMMMMMMMMMMMMMQ#q8@hTVLuccvjt}}l?1]>=)***|\;;;::::::-----,,,"__~^^^^^......''```
//       qMMMMMMMMMMMMMMMMWNmXDha&noouccjtr}li17==)+**|\;;;::::::::-----,,,"_~^^^....'``'
//        MMMMMMMMMMMMMMMMMQBHgbOhT0Vnoo3cvIt}li117>=)***|\;;;;::::::::----,,,_~^^^..'''
//         QMMMMMMMMMMMMMMMMQWNq8bOhTa&snoucvjt}ll?1]>=))**||\;;;;;:::::::----,"_^^^..'
//          -MMMMMMMMMMMMMMMMMQWNq8bDOhka0sLo3cvjIr}li?1]7>==)+***|\;;;;:::::----,,~^
//            ;NMMMMMMMMMMMMMMMMQQNqEgdSDOhka0Ynou3ccvjItr}lli117>=))***||;;;:::::-
//               ]MMMMMMMMMMMMMMMMQQWBNHmKdb@OhkTa&sYLooucccvjItr}}li?17==)+*||:'
//                 .1qMMMMMMMMMMMMMMMQQBNHqEKdSDOPkaa&snoou3cccvvjItr}li1]>;,`
//                      :IOMMMMMMMMMMMMQQBNHm8XSOPka0Vnou3cvjtr}llli?>:"`
//                            _|jnbQMMMMMMMMQBNqK8XSDPTasLucvI|~.`
//                                   oMMMMMMMMMMMMQqSTocri7)*|:.
//                                 IMMMMMMMMMMNdksc}1)\::-,~^..'`
//                                lTMMMQMMMQqD0oj}1=*;:-_^.'```````
//                              -cOQMN8KMMM#gO&uj}1=*;:-^.''`````````
//                             :hHQ#gDSQMMMMHSTs3v}])|:-~^.'````` '.``
//                            1KMQEOaLXMMMMMQEDTn3Ii7+;:-_^.''````'^.'`
//                           -WMMghYuYHMMMMMM#dO0Lcr?=|;:-_^..'```.^^.'
//                           gMMKhscckWMMMMMMQm@Ts3Il7*\::-_^..'``^",~.'
//                          ?MMNPscvobMMMMMMMMN8Paov}1)*;:-,_^..``,---~.`
//                         .MMWS&utvV8MMMMMMMMWEDTs3jl>*\;:--"^.`.:\;:-_`
//                         lMMNOLjrcTgMMMMMMMMMNXOTYujl>*\:::-,^.`;ll=-`
//                         'MMNDYccclQMMMMMMMMMWq8@PTsct1)|;;;:"
//                            -;\-`  QMMMMMMMQ#HEEgdSOaLv}i]+:,^
//                                   ]MMMMMHdhs3t`  ^P8gbhu];-.
//                                    MMMMW8kci>)    hgKDV}|:^'
//                                    @MMMHho1*;:    hNHDYl\:^
//                                     dMMmav=;:      |t3v7:.
//                                       '~^'
//
//                                         author: phaze

import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/interfaces/IERC721.sol";

import "./BaoStaking.sol";

contract BaoToken is AccessControl, BaoStaking {
    bytes32 public constant MINT_AUTHORITY = keccak256("MINT_AUTHORITY");
    bytes32 public constant BURN_AUTHORITY = keccak256("BURN_AUTHORITY");

    address public treasuryAddress = address(0x69D8004d527d72eFe1a4d5eECFf4A7f38f5b2B69);

    constructor() ERC20("Bao Token", "BAO", 18) {
        _setupRole(DEFAULT_ADMIN_ROLE, treasuryAddress);
        _mint(treasuryAddress, 10_000_000 * 1e18);
    }

    /* ------------- Restricted ------------- */

    function mint(address user, uint256 amount) external payable onlyRole(MINT_AUTHORITY) {
        _mint(user, amount);
    }

    /* ------------- ERC20Burnable ------------- */

    function burn(uint256 amount) external payable {
        _burn(msg.sender, amount);
    }

    function burnFrom(address user, uint256 amount) external payable {
        if (!hasRole(BURN_AUTHORITY, msg.sender)) {
            uint256 allowed = allowance[user][msg.sender];
            if (allowed != type(uint256).max) allowance[user][msg.sender] = allowed - amount;
        }
        _burn(user, amount);
    }

    /* ------------- MultiCall ------------- */

    function multiCall(bytes[] calldata data) external {
        unchecked {
            for (uint256 i; i < data.length; ++i) address(this).delegatecall(data[i]);
        }
    }

    /* ------------- Owner ------------- */

    function withdraw() external onlyOwner {
        uint256 balance = address(this).balance;
        payable(msg.sender).transfer(balance);
    }

    function recoverToken(ERC20 token) external onlyOwner {
        uint256 balance = token.balanceOf(address(this));
        token.transfer(msg.sender, balance);
    }

    function recoverNFT(IERC721 token, uint256 id) external onlyOwner {
        token.transferFrom(address(this), msg.sender, id);
    }
}

File 2 of 12 : AccessControl.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (access/AccessControl.sol)

pragma solidity ^0.8.0;

import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";

/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role);
        _;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `_msgSender()` is missing `role`.
     * Overriding this function changes the behavior of the {onlyRole} modifier.
     *
     * Format of the revert message is described in {_checkRole}.
     *
     * _Available since v4.6._
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     *
     * NOTE: This function is deprecated in favor of {_grantRole}.
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * Internal function without access restriction.
     */
    function _grantRole(bytes32 role, address account) internal virtual {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * Internal function without access restriction.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

File 3 of 12 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol)

pragma solidity ^0.8.0;

import "../token/ERC721/IERC721.sol";

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

//                                       -\**:. `"^`
//                                     ;HNXav*,^;}?|:,.`
//                                    tbKX&]:,:7I}=\:-_._,`
//                                  :OKgTv)*7}ri=*;::,^``:;:^
//                               :&S@OTnccvtl])*\;:--~.`_;;-,^.`
//                            :cdXDOhT&Yuctl1=*;::,^..,;+*;:--,"~^.
//                         ;LX8dXSDOhasocv}1>+|;:---:;|||;:--,"_^^^..`
//                      :3@bd8dXSDPTasocvtl]>+|;::::;;;:::--,_~^^^..'````
//                   `laP@d88d@DhT0Yo3cjt}i]=+*\;;:::::::---,_^^^..'``    ``
//                 `)3&hSd8dbDhT&YoccvIt}l17=)*|;;:::::::--,"_^^^..'```     ``
//                ;=rnOb88d@OT&nucvjItr}i17==+**\;;;:::::--,"~^^^..''``        `
//              ^^:lnOXg8XDhaYucvjttr}lir3Luv=**|;;;;;:::--,_~^^....'-XMMh='     `
//             ``~>YOdKKd@haYucvttrrINMMMMMMMMMMj\;;;;::::-,"~^^....-MMMHDr=:`
//              ,7YDgmK8@haYucItr}}MMMMMMMMmt|1MMM=;;;;::::-,_^^....MMQ8OT-`';`
//          ` `-}&Smqm8SPTsucjr}}lMMMMMMMMMDl|]MMMM|;;;;:::--"^^..''MMmSOhV7)1:`
//        '"^,+vhdHNNEbOT&ocjtllitMMMMMMMMMMMMMMMMM1||\;;;::-"^..''`TMNKSDhaLt\-
//        =)=}nOmNQBHgDhaYuvIrli?jMMMMMMMMMMMMMMMMM1|||;;;::-~.'''``.dMBq8Oaor*|
//       cLY0OgNQQQWHdDh0Yuvt}i?11MMMMMMMMMMMMMMMMM**|;;;:::-_..''```.c#WHSaul7+        `
//      =OS8mNQMMMMQH8DhasucIrli111MMMMMMMMMMMMMMM+*|;;;::::-,^..''````.1VEHda7`        ``
//      @mHWQMMMMMMQNEbDkan3vtli1]>=?SMMMMMMMMMh)**|\;;::::--,~^..-'```````,,``````     ``
//      NQMMMMMMMMMMQNKbOh0Luv}i7==))))))))+*****||\;;;1MMMXkncuOKo.'''````````````````````
//      QMMMMMMMMMMMMQNmdDh&n3I}17==)))))))+****|\;;;;:::::*71=;,~^^...''''````````````````
//      QMMMMMMMMMMMMMQBHEbOTVocjtli?11]>>==)+**||;;;;::::::----,,_~^^^.........''''''````
//      jMMMMMMMMMMMMMMMQ#q8@hTVLuccvjt}}l?1]>=)***|\;;;::::::-----,,,"__~^^^^^......''```
//       qMMMMMMMMMMMMMMMMWNmXDha&noouccjtr}li17==)+**|\;;;::::::::-----,,,"_~^^^....'``'
//        MMMMMMMMMMMMMMMMMQBHgbOhT0Vnoo3cvIt}li117>=)***|\;;;;::::::::----,,,_~^^^..'''
//         QMMMMMMMMMMMMMMMMQWNq8bOhTa&snoucvjt}ll?1]>=))**||\;;;;;:::::::----,"_^^^..'
//          -MMMMMMMMMMMMMMMMMQWNq8bDOhka0sLo3cvjIr}li?1]7>==)+***|\;;;;:::::----,,~^
//            ;NMMMMMMMMMMMMMMMMQQNqEgdSDOhka0Ynou3ccvjItr}lli117>=))***||;;;:::::-
//               ]MMMMMMMMMMMMMMMMQQWBNHmKdb@OhkTa&sYLooucccvjItr}}li?17==)+*||:'
//                 .1qMMMMMMMMMMMMMMMQQBNHqEKdSDOPkaa&snoou3cccvvjItr}li1]>;,`
//                      :IOMMMMMMMMMMMMQQBNHm8XSOPka0Vnou3cvjtr}llli?>:"`
//                            _|jnbQMMMMMMMMQBNqK8XSDPTasLucvI|~.`
//                                   oMMMMMMMMMMMMQqSTocri7)*|:.
//                                 IMMMMMMMMMMNdksc}1)\::-,~^..'`
//                                lTMMMQMMMQqD0oj}1=*;:-_^.'```````
//                              -cOQMN8KMMM#gO&uj}1=*;:-^.''`````````
//                             :hHQ#gDSQMMMMHSTs3v}])|:-~^.'````` '.``
//                            1KMQEOaLXMMMMMQEDTn3Ii7+;:-_^.''````'^.'`
//                           -WMMghYuYHMMMMMM#dO0Lcr?=|;:-_^..'```.^^.'
//                           gMMKhscckWMMMMMMQm@Ts3Il7*\::-_^..'``^",~.'
//                          ?MMNPscvobMMMMMMMMN8Paov}1)*;:-,_^..``,---~.`
//                         .MMWS&utvV8MMMMMMMMWEDTs3jl>*\;:--"^.`.:\;:-_`
//                         lMMNOLjrcTgMMMMMMMMMNXOTYujl>*\:::-,^.`;ll=-`
//                         'MMNDYccclQMMMMMMMMMWq8@PTsct1)|;;;:"
//                            -;\-`  QMMMMMMMQ#HEEgdSOaLv}i]+:,^
//                                   ]MMMMMHdhs3t`  ^P8gbhu];-.
//                                    MMMMW8kci>)    hgKDV}|:^'
//                                    @MMMHho1*;:    hNHDYl\:^
//                                     dMMmav=;:      |t3v7:.
//                                       '~^'
//
//                                         author: phaze

import {IERC721 as IBaoSociety} from "@openzeppelin/contracts/interfaces/IERC721.sol";
import "../lib/solmate/src/tokens/ERC20.sol";

import "./Ownable.sol";

error IncorrectOwner();

abstract contract BaoStaking is Ownable, ERC20 {
    struct TokenData {
        address owner;
        uint40 lastClaimed;
        uint40 rarity;
    }

    struct StakeData {
        uint40 rarityBonus;
        uint40 numStaked;
        uint40 lastClaimed;
    }

    uint256 constant DAILY_BASE_REWARD = 100;
    uint256 constant DAILY_STAKED_REWARD = 150;

    uint256 public immutable REWARD_EMISSION_START = 1652662800;
    uint256 public immutable REWARD_EMISSION_END = 1652662800 + 5 * 365 days;

    mapping(uint256 => TokenData) public tokenData;
    mapping(address => StakeData) public stakeData;

    IBaoSociety public constant baoSociety = IBaoSociety(0xba033D82c64DD514B184e2d1405cD395dfE6e706);

    /* ------------- External ------------- */

    function stake(uint256[] calldata tokenIds) external payable {
        unchecked {
            claimRewardStaked();

            TokenData storage tData;
            StakeData storage sData = stakeData[msg.sender];

            uint256 tokenId;

            uint256 reward;
            uint256 rarityBonus = sData.rarityBonus;

            for (uint256 i; i < tokenIds.length; ++i) {
                tokenId = tokenIds[i];

                baoSociety.transferFrom(msg.sender, address(this), tokenId);

                tData = tokenData[tokenId];
                tData.owner = msg.sender;

                // accrue non-staked rewards
                reward += _calculateRewardSingle(tData, tokenId);
                rarityBonus += getRarityBonus(tData);
            }

            sData.numStaked += uint40(tokenIds.length);
            sData.rarityBonus = uint40(rarityBonus);

            _mint(msg.sender, reward);
        }
    }

    function unstake(uint256[] calldata tokenIds) external payable {
        unchecked {
            claimRewardStaked();

            TokenData storage tData;
            StakeData storage sData = stakeData[msg.sender];

            uint256 tokenId;
            uint256 rarityBonus = sData.rarityBonus;

            for (uint256 i; i < tokenIds.length; ++i) {
                tokenId = tokenIds[i];
                tData = tokenData[tokenId];

                if (tData.owner != msg.sender) revert IncorrectOwner();

                baoSociety.transferFrom(address(this), msg.sender, tokenId);

                rarityBonus -= getRarityBonus(tData); // underflow not possible if rarity stays constant
                tData.lastClaimed = uint40(block.timestamp);
            }

            sData.numStaked -= uint40(tokenIds.length);
            sData.rarityBonus = uint40(rarityBonus);
        }
    }

    function claimRewardStaked() public payable {
        uint256 reward = pendingRewardStaked(msg.sender);

        _mint(msg.sender, reward);

        stakeData[msg.sender].lastClaimed = uint40(block.timestamp);
    }

    function claimReward(uint256[] calldata tokenIds) external payable {
        unchecked {
            TokenData storage tData;

            uint256 reward;
            uint256 tokenId;

            for (uint256 i; i < tokenIds.length; ++i) {
                tokenId = tokenIds[i];
                tData = tokenData[tokenId];

                if (baoSociety.ownerOf(tokenId) != msg.sender) revert IncorrectOwner();

                reward += _calculateRewardSingle(tData, tokenId);
                tData.lastClaimed = uint40(block.timestamp);
            }

            _mint(msg.sender, reward);
        }
    }

    /* ------------- View ------------- */

    function pendingRewardStaked(address user) public view returns (uint256) {
        unchecked {
            uint256 timestamp = block.timestamp;
            if (timestamp > REWARD_EMISSION_END) timestamp = REWARD_EMISSION_END;

            uint256 staked = stakeData[user].numStaked;
            if (staked == 0) return 0;

            uint256 lastClaimed = stakeData[user].lastClaimed;

            if (lastClaimed > timestamp) return 0;
            if (lastClaimed == 0) lastClaimed = REWARD_EMISSION_START;

            return
                ((timestamp - lastClaimed) * (staked * DAILY_STAKED_REWARD + stakeData[user].rarityBonus) * 1e18) /
                1 days;
        }
    }

    function dailyRewardStaked(address user) external view returns (uint256) {
        unchecked {
            return ((uint256(stakeData[user].numStaked) * DAILY_STAKED_REWARD + stakeData[user].rarityBonus) * 1e18);
        }
    }

    function pendingReward(uint256[] calldata tokenIds) external view returns (uint256) {
        unchecked {
            TokenData storage tData;

            uint256 reward;
            uint256 tokenId;

            for (uint256 i; i < tokenIds.length; ++i) {
                tokenId = tokenIds[i];
                tData = tokenData[tokenId];

                reward += _calculateRewardSingle(tData, tokenId);
            }

            return reward;
        }
    }

    function dailyReward(uint256[] calldata tokenIds) external view returns (uint256) {
        unchecked {
            uint256 reward;

            for (uint256 i; i < tokenIds.length; ++i)
                reward += (DAILY_BASE_REWARD + getRarityBonus(tokenData[tokenIds[i]])) * 1e18;

            return reward;
        }
    }

    function getRarityBonus(uint256 tokenId) external view returns (uint256) {
        return getRarityBonus(tokenData[tokenId]);
    }

    function numStaked(address user) external view returns (uint256) {
        return stakeData[user].numStaked;
    }

    function numOwned(address user) external view returns (uint256) {
        return baoSociety.balanceOf(user) + stakeData[user].numStaked;
    }

    function totalNumStaked() external view returns (uint256) {
        return baoSociety.balanceOf(address(this));
    }

    /* ------------- Private ------------- */

    function getRarityBonus(TokenData storage tData) private view returns (uint256) {
        uint256 rarity = tData.rarity;
        return rarity == 0 ? 5 : rarity;
    }

    function _calculateRewardSingle(TokenData storage tData, uint256 tokenId) private view returns (uint256) {
        uint256 rewardBonus;
        uint256 lastClaimed = tData.lastClaimed;

        if (lastClaimed > REWARD_EMISSION_END) return 0;
        if (lastClaimed == 0) {
            lastClaimed = REWARD_EMISSION_START;
            if (tokenId % 5 == 0) rewardBonus = 1500 * 1e18;
        }

        uint256 timestamp = block.timestamp;
        if (timestamp > REWARD_EMISSION_END) timestamp = REWARD_EMISSION_END;

        return rewardBonus + ((timestamp - lastClaimed) * (DAILY_BASE_REWARD + getRarityBonus(tData)) * 1e18) / 1 days;
    }

    /* ------------- Owner ------------- */

    // @note should only be called once before any interaction happens
    // bad things (underflow) can happen if this is changed while someone is staking
    function setRarities(uint256[] calldata ids, uint256[] calldata rarities) external onlyOwner {
        unchecked {
            for (uint256 i; i < ids.length; ++i) tokenData[ids[i]].rarity = uint40(rarities[i]);
        }
    }

    /* ------------- O(n) Read-Only ------------- */

    function stakedTokenIdsOf(address user) external view returns (uint256[] memory) {
        uint256 staked = stakeData[user].numStaked;
        uint256[] memory stakedIds = new uint256[](staked);
        if (staked == 0) return stakedIds;

        uint256 count;
        for (uint256 i = 1; i < 3888 + 1; ++i) {
            if (tokenData[i].owner == user) {
                stakedIds[count++] = i;
                if (staked == count) return stakedIds;
            }
        }

        return stakedIds;
    }
}

File 5 of 12 : IAccessControl.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}

File 6 of 12 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

File 7 of 12 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (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 8 of 12 : ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

File 9 of 12 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

File 10 of 12 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must 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 Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}

File 11 of 12 : ERC20.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 amount);

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    /*//////////////////////////////////////////////////////////////
                            METADATA STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*//////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

    mapping(address => mapping(address => uint256)) public allowance;

    /*//////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }

    /*//////////////////////////////////////////////////////////////
                             EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                keccak256(
                                    "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                ),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                v,
                r,
                s
            );

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

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

    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount;

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

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

File 12 of 12 : Ownable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

error CallerNotOwner();

abstract contract Ownable {
    address _owner = msg.sender;

    function owner() public view returns (address) {
        return _owner;
    }

    function transferOwnership(address newOwner) external onlyOwner {
        _owner = newOwner;
    }

    modifier onlyOwner() {
        if (msg.sender != _owner) revert CallerNotOwner();
        _;
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CallerNotOwner","type":"error"},{"inputs":[],"name":"IncorrectOwner","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"BURN_AUTHORITY","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_AUTHORITY","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARD_EMISSION_END","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARD_EMISSION_START","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baoSociety","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"claimReward","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"claimRewardStaked","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"dailyReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"dailyRewardStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getRarityBonus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multiCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"numOwned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"numStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"pendingReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"pendingRewardStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC721","name":"token","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"recoverNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC20","name":"token","type":"address"}],"name":"recoverToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"rarities","type":"uint256[]"}],"name":"setRarities","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"stake","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stakeData","outputs":[{"internalType":"uint40","name":"rarityBonus","type":"uint40"},{"internalType":"uint40","name":"numStaked","type":"uint40"},{"internalType":"uint40","name":"lastClaimed","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"stakedTokenIdsOf","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenData","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint40","name":"lastClaimed","type":"uint40"},{"internalType":"uint40","name":"rarity","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalNumStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasuryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"unstake","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

610120604052600180546001600160a01b03199081163317909155636281a21060e052636be7a39061010052600a80549091167369d8004d527d72efe1a4d5eecff4a7f38f5b2b691790553480156200005757600080fd5b5060408051808201825260098152682130b7902a37b5b2b760b91b60208083019182528351808501909452600384526242414f60e81b908401528151919291601291620000a89160029190620002d6565b508151620000be906003906020850190620002d6565b5060ff81166080524660a052620000d46200011d565b60c0525050600a54620000f491506000906001600160a01b0316620001b9565b600a5462000117906001600160a01b03166a084595161401484a000000620001c9565b62000484565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6002604051620001519190620003b9565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b620001c5828262000236565b5050565b8060046000828254620001dd91906200045d565b90915550506001600160a01b0382166000818152600560209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16620001c5576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620002923390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b828054620002e4906200037c565b90600052602060002090601f01602090048101928262000308576000855562000353565b82601f106200032357805160ff191683800117855562000353565b8280016001018555821562000353579182015b828111156200035357825182559160200191906001019062000336565b506200036192915062000365565b5090565b5b8082111562000361576000815560010162000366565b600181811c908216806200039157607f821691505b60208210811415620003b357634e487b7160e01b600052602260045260246000fd5b50919050565b600080835481600182811c915080831680620003d657607f831692505b6020808410821415620003f757634e487b7160e01b86526022600452602486fd5b8180156200040e576001811462000420576200044f565b60ff198616895284890196506200044f565b60008a81526020902060005b86811015620004475781548b8201529085019083016200042c565b505084890196505b509498975050505050505050565b600082198211156200047f57634e487b7160e01b600052601160045260246000fd5b500190565b60805160a05160c05160e0516101005161312c620004fa6000396000818161069d01528181611d7801528181611da1015281816122040152818161227b01526122a40152600081816105fc01528181611e42015261223d01526000611205015260006111d0015260006104e6015261312c6000f3fe6080604052600436106103295760003560e01c806379cc6790116101a5578063c5f956af116100ec578063d78d8f3111610095578063e449f3411161006f578063e449f34114610aae578063e59f0a3f14610ac1578063ec0e90ae14610af5578063f2fde38b14610b1557600080fd5b8063d78d8f3114610a22578063dd62ed3e14610a56578063dec3988514610a8e57600080fd5b8063d505accf116100c6578063d505accf146109b5578063d547741f146109d5578063d67b19c9146109f557600080fd5b8063c5f956af14610907578063c691d19114610927578063c94c7ff4146109a257600080fd5b80639a2d76b31161014e578063a635e9c211610128578063a635e9c2146107e8578063a9059cbb14610843578063b4b5b48f1461086357600080fd5b80639a2d76b3146107ab5780639be65a60146107b3578063a217fddf146107d357600080fd5b80638da5cb5b1161017f5780638da5cb5b1461073457806391d148541461075257806395d89b411461079657600080fd5b806379cc6790146106df5780637ecebe00146106f2578063895d22061461071f57600080fd5b80633319a00d1161027457806340c10f191161021d5780636449c178116101f75780636449c1781461061e57806370a082311461065e5780637120e9e51461068b5780637168fcea146106bf57600080fd5b806340c10f19146105c457806342966c68146105d757806345fa8a35146105ea57600080fd5b806336568abe1161024e57806336568abe1461056f5780633679740d1461058f5780633ccfd60b146105af57600080fd5b80633319a00d1461051a578063348a0cdc1461053a5780633644e5151461055a57600080fd5b806318160ddd116102d6578063248a9ca3116102b0578063248a9ca3146104845780632f2ff15d146104b4578063313ce567146104d457600080fd5b806318160ddd1461042e5780631ab2ed251461044457806323b872dd1461046457600080fd5b8063095ea7b311610307578063095ea7b3146103d95780630fbf0a93146103f9578063132bf7851461040e57600080fd5b806301ffc9a71461032e57806306fdde031461036357806308ee0c7414610385575b600080fd5b34801561033a57600080fd5b5061034e610349366004612935565b610b35565b60405190151581526020015b60405180910390f35b34801561036f57600080fd5b50610378610bce565b60405161035a91906129a7565b34801561039157600080fd5b506103cb6103a0366004612a0d565b6001600160a01b031660009081526009602052604090205465010000000000900464ffffffffff1690565b60405190815260200161035a565b3480156103e557600080fd5b5061034e6103f4366004612a2a565b610c5c565b61040c610407366004612aa2565b610cc8565b005b34801561041a57600080fd5b506103cb610429366004612aa2565b610e78565b34801561043a57600080fd5b506103cb60045481565b34801561045057600080fd5b506103cb61045f366004612aa2565b610eda565b34801561047057600080fd5b5061034e61047f366004612ae4565b610f3f565b34801561049057600080fd5b506103cb61049f366004612b25565b60009081526020819052604090206001015490565b3480156104c057600080fd5b5061040c6104cf366004612b3e565b61104f565b3480156104e057600080fd5b506105087f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff909116815260200161035a565b34801561052657600080fd5b5061040c610535366004612a2a565b611079565b34801561054657600080fd5b5061040c610555366004612aa2565b611140565b34801561056657600080fd5b506103cb6111cc565b34801561057b57600080fd5b5061040c61058a366004612b3e565b611227565b34801561059b57600080fd5b506103cb6105aa366004612b25565b6112d2565b3480156105bb57600080fd5b5061040c6112e9565b61040c6105d2366004612a2a565b61135c565b61040c6105e5366004612b25565b611390565b3480156105f657600080fd5b506103cb7f000000000000000000000000000000000000000000000000000000000000000081565b34801561062a57600080fd5b5061064673ba033d82c64dd514b184e2d1405cd395dfe6e70681565b6040516001600160a01b03909116815260200161035a565b34801561066a57600080fd5b506103cb610679366004612a0d565b60056020526000908152604090205481565b34801561069757600080fd5b506103cb7f000000000000000000000000000000000000000000000000000000000000000081565b3480156106cb57600080fd5b506103cb6106da366004612a0d565b61139d565b61040c6106ed366004612a2a565b611462565b3480156106fe57600080fd5b506103cb61070d366004612a0d565b60076020526000908152604090205481565b34801561072b57600080fd5b506103cb61151e565b34801561074057600080fd5b506001546001600160a01b0316610646565b34801561075e57600080fd5b5061034e61076d366004612b3e565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b3480156107a257600080fd5b506103786115ad565b61040c6115ba565b3480156107bf57600080fd5b5061040c6107ce366004612a0d565b61161f565b3480156107df57600080fd5b506103cb600081565b3480156107f457600080fd5b506103cb610803366004612a0d565b6001600160a01b0316600090815260096020526040902054670de0b6b3a764000065010000000000820464ffffffffff9081166096029216919091010290565b34801561084f57600080fd5b5061034e61085e366004612a2a565b611774565b34801561086f57600080fd5b506108da61087e366004612b25565b6008602052600090815260409020546001600160a01b0381169064ffffffffff74010000000000000000000000000000000000000000820481169179010000000000000000000000000000000000000000000000000090041683565b604080516001600160a01b03909416845264ffffffffff928316602085015291169082015260600161035a565b34801561091357600080fd5b50600a54610646906001600160a01b031681565b34801561093357600080fd5b5061097a610942366004612a0d565b60096020526000908152604090205464ffffffffff808216916501000000000081048216916a01000000000000000000009091041683565b6040805164ffffffffff9485168152928416602084015292169181019190915260600161035a565b61040c6109b0366004612aa2565b6117ec565b3480156109c157600080fd5b5061040c6109d0366004612b6e565b61196a565b3480156109e157600080fd5b5061040c6109f0366004612b3e565b611c48565b348015610a0157600080fd5b50610a15610a10366004612a0d565b611c6d565b60405161035a9190612be5565b348015610a2e57600080fd5b506103cb7f2835a7a5b84b6b14021f9bc9694ea8ba57b01e33d0984ae2c6ac566c9cb317dd81565b348015610a6257600080fd5b506103cb610a71366004612c29565b600660209081526000928352604080842090915290825290205481565b348015610a9a57600080fd5b506103cb610aa9366004612a0d565b611d73565b61040c610abc366004612aa2565b611ea4565b348015610acd57600080fd5b506103cb7f7a8b36176433d2df0a86e42ad61b72ceaa8aec21bcb985daa008471c46cd40b881565b348015610b0157600080fd5b5061040c610b10366004612c57565b61209d565b348015610b2157600080fd5b5061040c610b30366004612a0d565b61215e565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610bc857507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60028054610bdb90612cc3565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0790612cc3565b8015610c545780601f10610c2957610100808354040283529160200191610c54565b820191906000526020600020905b815481529060010190602001808311610c3757829003601f168201915b505050505081565b3360008181526006602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610cb79086815260200190565b60405180910390a350600192915050565b610cd06115ba565b33600090815260096020526040812080548290819064ffffffffff16815b86811015610dfb57878782818110610d0857610d08612d17565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526020909102929092013560448301819052955073ba033d82c64dd514b184e2d1405cd395dfe6e706916323b872dd9150606401600060405180830381600087803b158015610d8757600080fd5b505af1158015610d9b573d6000803e3d6000fd5b505050600085815260086020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016331781559650610de2905086856121dc565b83019250610def86612320565b90910190600101610cee565b5083547fffffffffffffffffffffffffffffffffffffffffffff000000000000000000008116650100000000009182900464ffffffffff908116890181169092027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000001617908216178455610e6f338361235f565b50505050505050565b60008060008060005b85811015610ecf57868682818110610e9b57610e9b612d17565b905060200201359150600860008381526020019081526020016000209350610ec384836121dc565b90920191600101610e81565b509095945050505050565b60008060005b83811015610f3757610f1b60086000878785818110610f0157610f01612d17565b905060200201358152602001908152602001600020612320565b606401670de0b6b3a76400000282019150806001019050610ee0565b509392505050565b6001600160a01b03831660009081526006602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610fb957610f948382612d75565b6001600160a01b03861660009081526006602090815260408083203384529091529020555b6001600160a01b03851660009081526005602052604081208054859290610fe1908490612d75565b90915550506001600160a01b03808516600081815260056020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061103c9087815260200190565b60405180910390a3506001949350505050565b60008281526020819052604090206001015461106a816123cb565b61107483836123d5565b505050565b6001546001600160a01b031633146110bd576040517f5cd8319200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f23b872dd000000000000000000000000000000000000000000000000000000008152306004820152336024820152604481018290526001600160a01b038316906323b872dd90606401600060405180830381600087803b15801561112457600080fd5b505af1158015611138573d6000803e3d6000fd5b505050505050565b60005b81811015611074573083838381811061115e5761115e612d17565b90506020028101906111709190612d8c565b60405161117e929190612df1565b600060405180830381855af49150503d80600081146111b9576040519150601f19603f3d011682016040523d82523d6000602084013e6111be565b606091505b505050806001019050611143565b60007f00000000000000000000000000000000000000000000000000000000000000004614611202576111fd612491565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b6001600160a01b03811633146112c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b6112ce828261252b565b5050565b6000818152600860205260408120610bc890612320565b6001546001600160a01b0316331461132d576040517f5cd8319200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040514790339082156108fc029083906000818181858888f193505050501580156112ce573d6000803e3d6000fd5b7f2835a7a5b84b6b14021f9bc9694ea8ba57b01e33d0984ae2c6ac566c9cb317dd611386816123cb565b611074838361235f565b61139a33826125c8565b50565b6001600160a01b0381166000818152600960205260408082205490517f70a08231000000000000000000000000000000000000000000000000000000008152600481019390935290916501000000000090910464ffffffffff169073ba033d82c64dd514b184e2d1405cd395dfe6e706906370a0823190602401602060405180830381865afa158015611434573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114589190612e01565b610bc89190612e1a565b3360009081527fecb489bb16cd9236c5eb1b8b235278e0e4264156b07bbe7356590388a996546c602052604090205460ff16611514576001600160a01b03821660009081526006602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611512576114ed8282612d75565b6001600160a01b03841660009081526006602090815260408083203384529091529020555b505b6112ce82826125c8565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ba033d82c64dd514b184e2d1405cd395dfe6e706906370a0823190602401602060405180830381865afa158015611589573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fd9190612e01565b60038054610bdb90612cc3565b60006115c533611d73565b90506115d1338261235f565b5033600090815260096020526040902080547fffffffffffffffffffffffffffffffffff0000000000ffffffffffffffffffff166a01000000000000000000004264ffffffffff1602179055565b6001546001600160a01b03163314611663576040517f5cd8319200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156116c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116e79190612e01565b6040517fa9059cbb000000000000000000000000000000000000000000000000000000008152336004820152602481018290529091506001600160a01b0383169063a9059cbb906044016020604051808303816000875af1158015611750573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110749190612e32565b33600090815260056020526040812080548391908390611795908490612d75565b90915550506001600160a01b038316600081815260056020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610cb79086815260200190565b6000806000805b848110156119585785858281811061180d5761180d612d17565b602090810292909201356000818152600890935260409283902092517f6352211e000000000000000000000000000000000000000000000000000000008152600481018290529296509350339173ba033d82c64dd514b184e2d1405cd395dfe6e7069150636352211e90602401602060405180830381865afa158015611897573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118bb9190612e54565b6001600160a01b0316146118fb576040517f3a6bbed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61190584836121dc565b84547fffffffffffffff0000000000ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000004264ffffffffff160217855592909201916001016117f3565b50611963338361235f565b5050505050565b428410156119d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f5045524d49545f444541444c494e455f4558504952454400000000000000000060448201526064016112bb565b600060016119e06111cc565b6001600160a01b038a811660008181526007602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e0830190915280519201919091207f190100000000000000000000000000000000000000000000000000000000000061010083015261010282019290925261012281019190915261014201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015611b25573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001519150506001600160a01b03811615801590611b795750876001600160a01b0316816001600160a01b0316145b611bdf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f494e56414c49445f5349474e455200000000000000000000000000000000000060448201526064016112bb565b6001600160a01b0390811660009081526006602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b600082815260208190526040902060010154611c63816123cb565b611074838361252b565b6001600160a01b0381166000908152600960205260408120546060916501000000000090910464ffffffffff16908167ffffffffffffffff811115611cb457611cb4612e71565b604051908082528060200260200182016040528015611cdd578160200160208202803683370190505b50905081611cec579392505050565b600060015b610f31811015611d69576000818152600860205260409020546001600160a01b0387811691161415611d5957808383611d2981612ea0565b945081518110611d3b57611d3b612d17565b60200260200101818152505081841415611d59575090949350505050565b611d6281612ea0565b9050611cf1565b5090949350505050565b6000427f0000000000000000000000000000000000000000000000000000000000000000811115611dc157507f00000000000000000000000000000000000000000000000000000000000000005b6001600160a01b03831660009081526009602052604090205465010000000000900464ffffffffff1680611df9575060009392505050565b6001600160a01b0384166000908152600960205260409020546a0100000000000000000000900464ffffffffff1682811115611e3a57506000949350505050565b80611e6257507f00000000000000000000000000000000000000000000000000000000000000005b6001600160a01b038516600090815260096020526040902054620151809064ffffffffff16609684020182850302670de0b6b3a7640000020495945050505050565b611eac6115ba565b3360009081526009602052604081208054829064ffffffffff16815b8581101561202a57868682818110611ee257611ee2612d17565b602090810292909201356000818152600890935260409092208054909750919450506001600160a01b03163314611f45576040517f3a6bbed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523060048201523360248201526044810184905273ba033d82c64dd514b184e2d1405cd395dfe6e706906323b872dd90606401600060405180830381600087803b158015611fb757600080fd5b505af1158015611fcb573d6000803e3d6000fd5b50505050611fd885612320565b85547fffffffffffffff0000000000ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000004264ffffffffff160217865590910390600101611ec8565b5082547fffffffffffffffffffffffffffffffffffffffffffff000000000000000000008116650100000000009182900464ffffffffff9081169790970387169091027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000016179416939093179055505050565b6001546001600160a01b031633146120e1576040517f5cd8319200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b83811015611963578282828181106120fe576120fe612d17565b905060200201356008600087878581811061211b5761211b612d17565b90506020020135815260200190815260200160002060000160196101000a81548164ffffffffff021916908364ffffffffff1602179055508060010190506120e4565b6001546001600160a01b031633146121a2576040517f5cd8319200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b8154600090819074010000000000000000000000000000000000000000900464ffffffffff167f000000000000000000000000000000000000000000000000000000000000000081111561223557600092505050610bc8565b8061227857507f0000000000000000000000000000000000000000000000000000000000000000612267600585612f08565b61227857685150ae84a8cdf0000091505b427f00000000000000000000000000000000000000000000000000000000000000008111156122c457507f00000000000000000000000000000000000000000000000000000000000000005b620151806122d187612320565b6122dc906064612e1a565b6122e68484612d75565b6122f09190612f1c565b61230290670de0b6b3a7640000612f1c565b61230c9190612f59565b6123169084612e1a565b9695505050505050565b8054600090790100000000000000000000000000000000000000000000000000900464ffffffffff1680156123555780612358565b60055b9392505050565b80600460008282546123719190612e1a565b90915550506001600160a01b0382166000818152600560209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91015b60405180910390a35050565b61139a813361263c565b6000828152602081815260408083206001600160a01b038516845290915290205460ff166112ce576000828152602081815260408083206001600160a01b0385168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561244d3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60026040516124c39190612f6d565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16156112ce576000828152602081815260408083206001600160a01b038516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6001600160a01b038216600090815260056020526040812080548392906125f0908490612d75565b90915550506004805482900390556040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020016123bf565b6000828152602081815260408083206001600160a01b038516845290915290205460ff166112ce57612678816001600160a01b031660146126f2565b6126838360206126f2565b604051602001612694929190613040565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526112bb916004016129a7565b60606000612701836002612f1c565b61270c906002612e1a565b67ffffffffffffffff81111561272457612724612e71565b6040519080825280601f01601f19166020018201604052801561274e576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061278557612785612d17565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106127e8576127e8612d17565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000612824846002612f1c565b61282f906001612e1a565b90505b60018111156128cc577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061287057612870612d17565b1a60f81b82828151811061288657612886612d17565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936128c5816130c1565b9050612832565b508315612358576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016112bb565b60006020828403121561294757600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461235857600080fd5b60005b8381101561299257818101518382015260200161297a565b838111156129a1576000848401525b50505050565b60208152600082518060208401526129c6816040850160208701612977565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6001600160a01b038116811461139a57600080fd5b600060208284031215612a1f57600080fd5b8135612358816129f8565b60008060408385031215612a3d57600080fd5b8235612a48816129f8565b946020939093013593505050565b60008083601f840112612a6857600080fd5b50813567ffffffffffffffff811115612a8057600080fd5b6020830191508360208260051b8501011115612a9b57600080fd5b9250929050565b60008060208385031215612ab557600080fd5b823567ffffffffffffffff811115612acc57600080fd5b612ad885828601612a56565b90969095509350505050565b600080600060608486031215612af957600080fd5b8335612b04816129f8565b92506020840135612b14816129f8565b929592945050506040919091013590565b600060208284031215612b3757600080fd5b5035919050565b60008060408385031215612b5157600080fd5b823591506020830135612b63816129f8565b809150509250929050565b600080600080600080600060e0888a031215612b8957600080fd5b8735612b94816129f8565b96506020880135612ba4816129f8565b95506040880135945060608801359350608088013560ff81168114612bc857600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6020808252825182820181905260009190848201906040850190845b81811015612c1d57835183529284019291840191600101612c01565b50909695505050505050565b60008060408385031215612c3c57600080fd5b8235612c47816129f8565b91506020830135612b63816129f8565b60008060008060408587031215612c6d57600080fd5b843567ffffffffffffffff80821115612c8557600080fd5b612c9188838901612a56565b90965094506020870135915080821115612caa57600080fd5b50612cb787828801612a56565b95989497509550505050565b600181811c90821680612cd757607f821691505b60208210811415612d11577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612d8757612d87612d46565b500390565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612dc157600080fd5b83018035915067ffffffffffffffff821115612ddc57600080fd5b602001915036819003821315612a9b57600080fd5b8183823760009101908152919050565b600060208284031215612e1357600080fd5b5051919050565b60008219821115612e2d57612e2d612d46565b500190565b600060208284031215612e4457600080fd5b8151801515811461235857600080fd5b600060208284031215612e6657600080fd5b8151612358816129f8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612ed257612ed2612d46565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082612f1757612f17612ed9565b500690565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612f5457612f54612d46565b500290565b600082612f6857612f68612ed9565b500490565b600080835481600182811c915080831680612f8957607f831692505b6020808410821415612fc2577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b818015612fd6576001811461300557613032565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00861689528489019650613032565b60008a81526020902060005b8681101561302a5781548b820152908501908301613011565b505084890196505b509498975050505050505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613078816017850160208801612977565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516130b5816028840160208801612977565b01602801949350505050565b6000816130d0576130d0612d46565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea26469706673582212206b3174f3c3a45da348a2a37d80d1242f9735b703c029a5b64a318ebab0e9acbb64736f6c634300080c0033

Deployed Bytecode

0x6080604052600436106103295760003560e01c806379cc6790116101a5578063c5f956af116100ec578063d78d8f3111610095578063e449f3411161006f578063e449f34114610aae578063e59f0a3f14610ac1578063ec0e90ae14610af5578063f2fde38b14610b1557600080fd5b8063d78d8f3114610a22578063dd62ed3e14610a56578063dec3988514610a8e57600080fd5b8063d505accf116100c6578063d505accf146109b5578063d547741f146109d5578063d67b19c9146109f557600080fd5b8063c5f956af14610907578063c691d19114610927578063c94c7ff4146109a257600080fd5b80639a2d76b31161014e578063a635e9c211610128578063a635e9c2146107e8578063a9059cbb14610843578063b4b5b48f1461086357600080fd5b80639a2d76b3146107ab5780639be65a60146107b3578063a217fddf146107d357600080fd5b80638da5cb5b1161017f5780638da5cb5b1461073457806391d148541461075257806395d89b411461079657600080fd5b806379cc6790146106df5780637ecebe00146106f2578063895d22061461071f57600080fd5b80633319a00d1161027457806340c10f191161021d5780636449c178116101f75780636449c1781461061e57806370a082311461065e5780637120e9e51461068b5780637168fcea146106bf57600080fd5b806340c10f19146105c457806342966c68146105d757806345fa8a35146105ea57600080fd5b806336568abe1161024e57806336568abe1461056f5780633679740d1461058f5780633ccfd60b146105af57600080fd5b80633319a00d1461051a578063348a0cdc1461053a5780633644e5151461055a57600080fd5b806318160ddd116102d6578063248a9ca3116102b0578063248a9ca3146104845780632f2ff15d146104b4578063313ce567146104d457600080fd5b806318160ddd1461042e5780631ab2ed251461044457806323b872dd1461046457600080fd5b8063095ea7b311610307578063095ea7b3146103d95780630fbf0a93146103f9578063132bf7851461040e57600080fd5b806301ffc9a71461032e57806306fdde031461036357806308ee0c7414610385575b600080fd5b34801561033a57600080fd5b5061034e610349366004612935565b610b35565b60405190151581526020015b60405180910390f35b34801561036f57600080fd5b50610378610bce565b60405161035a91906129a7565b34801561039157600080fd5b506103cb6103a0366004612a0d565b6001600160a01b031660009081526009602052604090205465010000000000900464ffffffffff1690565b60405190815260200161035a565b3480156103e557600080fd5b5061034e6103f4366004612a2a565b610c5c565b61040c610407366004612aa2565b610cc8565b005b34801561041a57600080fd5b506103cb610429366004612aa2565b610e78565b34801561043a57600080fd5b506103cb60045481565b34801561045057600080fd5b506103cb61045f366004612aa2565b610eda565b34801561047057600080fd5b5061034e61047f366004612ae4565b610f3f565b34801561049057600080fd5b506103cb61049f366004612b25565b60009081526020819052604090206001015490565b3480156104c057600080fd5b5061040c6104cf366004612b3e565b61104f565b3480156104e057600080fd5b506105087f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff909116815260200161035a565b34801561052657600080fd5b5061040c610535366004612a2a565b611079565b34801561054657600080fd5b5061040c610555366004612aa2565b611140565b34801561056657600080fd5b506103cb6111cc565b34801561057b57600080fd5b5061040c61058a366004612b3e565b611227565b34801561059b57600080fd5b506103cb6105aa366004612b25565b6112d2565b3480156105bb57600080fd5b5061040c6112e9565b61040c6105d2366004612a2a565b61135c565b61040c6105e5366004612b25565b611390565b3480156105f657600080fd5b506103cb7f000000000000000000000000000000000000000000000000000000006281a21081565b34801561062a57600080fd5b5061064673ba033d82c64dd514b184e2d1405cd395dfe6e70681565b6040516001600160a01b03909116815260200161035a565b34801561066a57600080fd5b506103cb610679366004612a0d565b60056020526000908152604090205481565b34801561069757600080fd5b506103cb7f000000000000000000000000000000000000000000000000000000006be7a39081565b3480156106cb57600080fd5b506103cb6106da366004612a0d565b61139d565b61040c6106ed366004612a2a565b611462565b3480156106fe57600080fd5b506103cb61070d366004612a0d565b60076020526000908152604090205481565b34801561072b57600080fd5b506103cb61151e565b34801561074057600080fd5b506001546001600160a01b0316610646565b34801561075e57600080fd5b5061034e61076d366004612b3e565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b3480156107a257600080fd5b506103786115ad565b61040c6115ba565b3480156107bf57600080fd5b5061040c6107ce366004612a0d565b61161f565b3480156107df57600080fd5b506103cb600081565b3480156107f457600080fd5b506103cb610803366004612a0d565b6001600160a01b0316600090815260096020526040902054670de0b6b3a764000065010000000000820464ffffffffff9081166096029216919091010290565b34801561084f57600080fd5b5061034e61085e366004612a2a565b611774565b34801561086f57600080fd5b506108da61087e366004612b25565b6008602052600090815260409020546001600160a01b0381169064ffffffffff74010000000000000000000000000000000000000000820481169179010000000000000000000000000000000000000000000000000090041683565b604080516001600160a01b03909416845264ffffffffff928316602085015291169082015260600161035a565b34801561091357600080fd5b50600a54610646906001600160a01b031681565b34801561093357600080fd5b5061097a610942366004612a0d565b60096020526000908152604090205464ffffffffff808216916501000000000081048216916a01000000000000000000009091041683565b6040805164ffffffffff9485168152928416602084015292169181019190915260600161035a565b61040c6109b0366004612aa2565b6117ec565b3480156109c157600080fd5b5061040c6109d0366004612b6e565b61196a565b3480156109e157600080fd5b5061040c6109f0366004612b3e565b611c48565b348015610a0157600080fd5b50610a15610a10366004612a0d565b611c6d565b60405161035a9190612be5565b348015610a2e57600080fd5b506103cb7f2835a7a5b84b6b14021f9bc9694ea8ba57b01e33d0984ae2c6ac566c9cb317dd81565b348015610a6257600080fd5b506103cb610a71366004612c29565b600660209081526000928352604080842090915290825290205481565b348015610a9a57600080fd5b506103cb610aa9366004612a0d565b611d73565b61040c610abc366004612aa2565b611ea4565b348015610acd57600080fd5b506103cb7f7a8b36176433d2df0a86e42ad61b72ceaa8aec21bcb985daa008471c46cd40b881565b348015610b0157600080fd5b5061040c610b10366004612c57565b61209d565b348015610b2157600080fd5b5061040c610b30366004612a0d565b61215e565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610bc857507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60028054610bdb90612cc3565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0790612cc3565b8015610c545780601f10610c2957610100808354040283529160200191610c54565b820191906000526020600020905b815481529060010190602001808311610c3757829003601f168201915b505050505081565b3360008181526006602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610cb79086815260200190565b60405180910390a350600192915050565b610cd06115ba565b33600090815260096020526040812080548290819064ffffffffff16815b86811015610dfb57878782818110610d0857610d08612d17565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526020909102929092013560448301819052955073ba033d82c64dd514b184e2d1405cd395dfe6e706916323b872dd9150606401600060405180830381600087803b158015610d8757600080fd5b505af1158015610d9b573d6000803e3d6000fd5b505050600085815260086020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016331781559650610de2905086856121dc565b83019250610def86612320565b90910190600101610cee565b5083547fffffffffffffffffffffffffffffffffffffffffffff000000000000000000008116650100000000009182900464ffffffffff908116890181169092027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000001617908216178455610e6f338361235f565b50505050505050565b60008060008060005b85811015610ecf57868682818110610e9b57610e9b612d17565b905060200201359150600860008381526020019081526020016000209350610ec384836121dc565b90920191600101610e81565b509095945050505050565b60008060005b83811015610f3757610f1b60086000878785818110610f0157610f01612d17565b905060200201358152602001908152602001600020612320565b606401670de0b6b3a76400000282019150806001019050610ee0565b509392505050565b6001600160a01b03831660009081526006602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610fb957610f948382612d75565b6001600160a01b03861660009081526006602090815260408083203384529091529020555b6001600160a01b03851660009081526005602052604081208054859290610fe1908490612d75565b90915550506001600160a01b03808516600081815260056020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061103c9087815260200190565b60405180910390a3506001949350505050565b60008281526020819052604090206001015461106a816123cb565b61107483836123d5565b505050565b6001546001600160a01b031633146110bd576040517f5cd8319200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f23b872dd000000000000000000000000000000000000000000000000000000008152306004820152336024820152604481018290526001600160a01b038316906323b872dd90606401600060405180830381600087803b15801561112457600080fd5b505af1158015611138573d6000803e3d6000fd5b505050505050565b60005b81811015611074573083838381811061115e5761115e612d17565b90506020028101906111709190612d8c565b60405161117e929190612df1565b600060405180830381855af49150503d80600081146111b9576040519150601f19603f3d011682016040523d82523d6000602084013e6111be565b606091505b505050806001019050611143565b60007f00000000000000000000000000000000000000000000000000000000000000014614611202576111fd612491565b905090565b507f4b112550a6292df79d13380d6bb6b2056738f9e803fcabf5232c58305770763190565b6001600160a01b03811633146112c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b6112ce828261252b565b5050565b6000818152600860205260408120610bc890612320565b6001546001600160a01b0316331461132d576040517f5cd8319200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040514790339082156108fc029083906000818181858888f193505050501580156112ce573d6000803e3d6000fd5b7f2835a7a5b84b6b14021f9bc9694ea8ba57b01e33d0984ae2c6ac566c9cb317dd611386816123cb565b611074838361235f565b61139a33826125c8565b50565b6001600160a01b0381166000818152600960205260408082205490517f70a08231000000000000000000000000000000000000000000000000000000008152600481019390935290916501000000000090910464ffffffffff169073ba033d82c64dd514b184e2d1405cd395dfe6e706906370a0823190602401602060405180830381865afa158015611434573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114589190612e01565b610bc89190612e1a565b3360009081527fecb489bb16cd9236c5eb1b8b235278e0e4264156b07bbe7356590388a996546c602052604090205460ff16611514576001600160a01b03821660009081526006602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611512576114ed8282612d75565b6001600160a01b03841660009081526006602090815260408083203384529091529020555b505b6112ce82826125c8565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ba033d82c64dd514b184e2d1405cd395dfe6e706906370a0823190602401602060405180830381865afa158015611589573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fd9190612e01565b60038054610bdb90612cc3565b60006115c533611d73565b90506115d1338261235f565b5033600090815260096020526040902080547fffffffffffffffffffffffffffffffffff0000000000ffffffffffffffffffff166a01000000000000000000004264ffffffffff1602179055565b6001546001600160a01b03163314611663576040517f5cd8319200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156116c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116e79190612e01565b6040517fa9059cbb000000000000000000000000000000000000000000000000000000008152336004820152602481018290529091506001600160a01b0383169063a9059cbb906044016020604051808303816000875af1158015611750573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110749190612e32565b33600090815260056020526040812080548391908390611795908490612d75565b90915550506001600160a01b038316600081815260056020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610cb79086815260200190565b6000806000805b848110156119585785858281811061180d5761180d612d17565b602090810292909201356000818152600890935260409283902092517f6352211e000000000000000000000000000000000000000000000000000000008152600481018290529296509350339173ba033d82c64dd514b184e2d1405cd395dfe6e7069150636352211e90602401602060405180830381865afa158015611897573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118bb9190612e54565b6001600160a01b0316146118fb576040517f3a6bbed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61190584836121dc565b84547fffffffffffffff0000000000ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000004264ffffffffff160217855592909201916001016117f3565b50611963338361235f565b5050505050565b428410156119d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f5045524d49545f444541444c494e455f4558504952454400000000000000000060448201526064016112bb565b600060016119e06111cc565b6001600160a01b038a811660008181526007602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e0830190915280519201919091207f190100000000000000000000000000000000000000000000000000000000000061010083015261010282019290925261012281019190915261014201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015611b25573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001519150506001600160a01b03811615801590611b795750876001600160a01b0316816001600160a01b0316145b611bdf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f494e56414c49445f5349474e455200000000000000000000000000000000000060448201526064016112bb565b6001600160a01b0390811660009081526006602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b600082815260208190526040902060010154611c63816123cb565b611074838361252b565b6001600160a01b0381166000908152600960205260408120546060916501000000000090910464ffffffffff16908167ffffffffffffffff811115611cb457611cb4612e71565b604051908082528060200260200182016040528015611cdd578160200160208202803683370190505b50905081611cec579392505050565b600060015b610f31811015611d69576000818152600860205260409020546001600160a01b0387811691161415611d5957808383611d2981612ea0565b945081518110611d3b57611d3b612d17565b60200260200101818152505081841415611d59575090949350505050565b611d6281612ea0565b9050611cf1565b5090949350505050565b6000427f000000000000000000000000000000000000000000000000000000006be7a390811115611dc157507f000000000000000000000000000000000000000000000000000000006be7a3905b6001600160a01b03831660009081526009602052604090205465010000000000900464ffffffffff1680611df9575060009392505050565b6001600160a01b0384166000908152600960205260409020546a0100000000000000000000900464ffffffffff1682811115611e3a57506000949350505050565b80611e6257507f000000000000000000000000000000000000000000000000000000006281a2105b6001600160a01b038516600090815260096020526040902054620151809064ffffffffff16609684020182850302670de0b6b3a7640000020495945050505050565b611eac6115ba565b3360009081526009602052604081208054829064ffffffffff16815b8581101561202a57868682818110611ee257611ee2612d17565b602090810292909201356000818152600890935260409092208054909750919450506001600160a01b03163314611f45576040517f3a6bbed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523060048201523360248201526044810184905273ba033d82c64dd514b184e2d1405cd395dfe6e706906323b872dd90606401600060405180830381600087803b158015611fb757600080fd5b505af1158015611fcb573d6000803e3d6000fd5b50505050611fd885612320565b85547fffffffffffffff0000000000ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000004264ffffffffff160217865590910390600101611ec8565b5082547fffffffffffffffffffffffffffffffffffffffffffff000000000000000000008116650100000000009182900464ffffffffff9081169790970387169091027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000016179416939093179055505050565b6001546001600160a01b031633146120e1576040517f5cd8319200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b83811015611963578282828181106120fe576120fe612d17565b905060200201356008600087878581811061211b5761211b612d17565b90506020020135815260200190815260200160002060000160196101000a81548164ffffffffff021916908364ffffffffff1602179055508060010190506120e4565b6001546001600160a01b031633146121a2576040517f5cd8319200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b8154600090819074010000000000000000000000000000000000000000900464ffffffffff167f000000000000000000000000000000000000000000000000000000006be7a39081111561223557600092505050610bc8565b8061227857507f000000000000000000000000000000000000000000000000000000006281a210612267600585612f08565b61227857685150ae84a8cdf0000091505b427f000000000000000000000000000000000000000000000000000000006be7a3908111156122c457507f000000000000000000000000000000000000000000000000000000006be7a3905b620151806122d187612320565b6122dc906064612e1a565b6122e68484612d75565b6122f09190612f1c565b61230290670de0b6b3a7640000612f1c565b61230c9190612f59565b6123169084612e1a565b9695505050505050565b8054600090790100000000000000000000000000000000000000000000000000900464ffffffffff1680156123555780612358565b60055b9392505050565b80600460008282546123719190612e1a565b90915550506001600160a01b0382166000818152600560209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91015b60405180910390a35050565b61139a813361263c565b6000828152602081815260408083206001600160a01b038516845290915290205460ff166112ce576000828152602081815260408083206001600160a01b0385168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561244d3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60026040516124c39190612f6d565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16156112ce576000828152602081815260408083206001600160a01b038516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6001600160a01b038216600090815260056020526040812080548392906125f0908490612d75565b90915550506004805482900390556040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020016123bf565b6000828152602081815260408083206001600160a01b038516845290915290205460ff166112ce57612678816001600160a01b031660146126f2565b6126838360206126f2565b604051602001612694929190613040565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526112bb916004016129a7565b60606000612701836002612f1c565b61270c906002612e1a565b67ffffffffffffffff81111561272457612724612e71565b6040519080825280601f01601f19166020018201604052801561274e576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061278557612785612d17565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106127e8576127e8612d17565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000612824846002612f1c565b61282f906001612e1a565b90505b60018111156128cc577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061287057612870612d17565b1a60f81b82828151811061288657612886612d17565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936128c5816130c1565b9050612832565b508315612358576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016112bb565b60006020828403121561294757600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461235857600080fd5b60005b8381101561299257818101518382015260200161297a565b838111156129a1576000848401525b50505050565b60208152600082518060208401526129c6816040850160208701612977565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6001600160a01b038116811461139a57600080fd5b600060208284031215612a1f57600080fd5b8135612358816129f8565b60008060408385031215612a3d57600080fd5b8235612a48816129f8565b946020939093013593505050565b60008083601f840112612a6857600080fd5b50813567ffffffffffffffff811115612a8057600080fd5b6020830191508360208260051b8501011115612a9b57600080fd5b9250929050565b60008060208385031215612ab557600080fd5b823567ffffffffffffffff811115612acc57600080fd5b612ad885828601612a56565b90969095509350505050565b600080600060608486031215612af957600080fd5b8335612b04816129f8565b92506020840135612b14816129f8565b929592945050506040919091013590565b600060208284031215612b3757600080fd5b5035919050565b60008060408385031215612b5157600080fd5b823591506020830135612b63816129f8565b809150509250929050565b600080600080600080600060e0888a031215612b8957600080fd5b8735612b94816129f8565b96506020880135612ba4816129f8565b95506040880135945060608801359350608088013560ff81168114612bc857600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6020808252825182820181905260009190848201906040850190845b81811015612c1d57835183529284019291840191600101612c01565b50909695505050505050565b60008060408385031215612c3c57600080fd5b8235612c47816129f8565b91506020830135612b63816129f8565b60008060008060408587031215612c6d57600080fd5b843567ffffffffffffffff80821115612c8557600080fd5b612c9188838901612a56565b90965094506020870135915080821115612caa57600080fd5b50612cb787828801612a56565b95989497509550505050565b600181811c90821680612cd757607f821691505b60208210811415612d11577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612d8757612d87612d46565b500390565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612dc157600080fd5b83018035915067ffffffffffffffff821115612ddc57600080fd5b602001915036819003821315612a9b57600080fd5b8183823760009101908152919050565b600060208284031215612e1357600080fd5b5051919050565b60008219821115612e2d57612e2d612d46565b500190565b600060208284031215612e4457600080fd5b8151801515811461235857600080fd5b600060208284031215612e6657600080fd5b8151612358816129f8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612ed257612ed2612d46565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082612f1757612f17612ed9565b500690565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612f5457612f54612d46565b500290565b600082612f6857612f68612ed9565b500490565b600080835481600182811c915080831680612f8957607f831692505b6020808410821415612fc2577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b818015612fd6576001811461300557613032565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00861689528489019650613032565b60008a81526020902060005b8681101561302a5781548b820152908501908301613011565b505084890196505b509498975050505050505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613078816017850160208801612977565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516130b5816028840160208801612977565b01602801949350505050565b6000816130d0576130d0612d46565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea26469706673582212206b3174f3c3a45da348a2a37d80d1242f9735b703c029a5b64a318ebab0e9acbb64736f6c634300080c0033

Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.