Contract 0x8B6779969e9b5feB6Ad6199041A166741d784e0a

 

Contract Overview

Balance:
0 MATIC

MATIC Value:
$0.00

Token:
 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x2a247370ed02224cd954ceed2a938f48140e9407dc6da1cf0095cb0147851d5bMeta Withdraw338925432022-10-03 20:40:287 hrs 38 mins ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.006161437534 32.027932314
0x5594873a0e197d9ab60b2d419f91d33a14be315effc55c6e4e489b1a5f8798e2Meta Withdraw338840842022-10-03 15:47:5212 hrs 30 mins ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.004826381002 30.500000013
0x212bf0d61e12bb9a0490840d178a79addb4bf830fa9451068d8ed77a48000366Meta Withdraw338438592022-10-02 16:29:511 day 11 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.005074968723 36.921483877
0x195ebf615cdee87dd87fa142ea0dc22dc8fd2cd596098f61dd78420494d99a21Meta Withdraw337573132022-09-30 14:24:113 days 13 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.004720569659 33.140991299
0xe3513470cdaf115cc2ce51721c66b635a98024ebdf88709b3359c4337a5a0166Meta Withdraw337572132022-09-30 14:20:433 days 13 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.006296974717 35.685402291
0xf4d4b71dbeeb6d36998858b8557e05fae6a593fa5daab307628ef1fc9edb5445Meta Withdraw337202752022-09-29 16:51:244 days 11 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.005835267777 32.193159901
0xb96b154699455373cf27bc190914b73155166938e177f27359420c7302f545d2Meta Withdraw337087912022-09-29 10:03:204 days 18 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.002072417714 30.752600011
0xbf051ad54ece764732cb9bc8502d6cfda40c73d2f130b845f8697ea87162ad7aMeta Withdraw337087872022-09-29 10:03:124 days 18 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.00452006476 32.840000001
0x1792e8cb2dd8cf856b4a7c3b10a2b4921e7a94b7ee02620f22f697719f189a6cMeta Withdraw336829612022-09-28 19:12:185 days 9 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.006275832374 36.357819948
0x7b677f1e4c3ec22c945089ddf1defa830dcbf8eadaa0a56057fd05420c1131a9Meta Withdraw336478982022-09-27 22:59:426 days 5 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.008160621319 47.539999999
0x5502036b888619aa85730b27673e9a41ea6618a22efa7b2cb992d0995c9a16aeMeta Withdraw336056162022-09-26 21:46:177 days 6 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.00109805887 33.331073063
0x8ff80f07dd84ab2a3e39a12fbbe39b32fd599710000a55c399b433d1208f1168Meta Withdraw336056132022-09-26 21:46:117 days 6 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.005391122722 31.370000012
0x400ae96c8c53ad407cec0d365181768bd82662b1d9c5676c6bf03d22c97f3f80Meta Withdraw335537092022-09-25 15:26:058 days 12 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.00437935514 30.782
0x4e3f5a51ef86713a626ffea35c3971f7025d36438d71cfb863cea4e356d9c015Meta Withdraw335441792022-09-25 9:55:588 days 18 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.00600735 34.8
0xf4eb9c82fb4e2cc12621e5f6350631e530cbae1acc853cff08bdaa55d1f5d311Meta Withdraw335032812022-09-24 10:09:309 days 18 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.005331184959 30.879999998
0x8acfe3f60efb8be1f57201755a526e663447d39422134783cf1928a0d8e593e1Meta Withdraw334662512022-09-23 12:34:4010 days 15 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.00594134288 30.88
0x6b5490e26eaa70b121848445b9dba347674c776180a8e1e1468a8dffe7d729ecMeta Withdraw333665412022-09-21 2:29:0013 days 1 hr ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.005869115003 30.500000017
0x65b5817162dddb55bac0cde2bcb492ebd599e15c02a6dfb02c190b5f2c937af4Meta Withdraw333413852022-09-20 11:16:3113 days 17 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.0069599261 39.7
0xfebdfa0a7be84e6a74e5ef04f7a1e14c126b0bef8f50f078a6d610ef1f4ae462Meta Withdraw333191492022-09-19 22:21:0114 days 5 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.006035995811 31.37000001
0x844a571af3dfb44e7bb23fe59322b30a8188c29814b7c17f174ca8320e36671aMeta Withdraw332898472022-09-19 5:29:0914 days 22 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.005869328502 30.500000011
0xaef0c590efb40d9819f84c2102c79d857f95b4a2880950df41542fce283af968Meta Withdraw332835622022-09-19 1:52:5615 days 2 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.005241608001 30.500000011
0x0c9ca4a63fc7d69826d88202599943e7d26d35b214ba7b09463e415ddfe56025Meta Withdraw332564362022-09-18 10:06:5115 days 18 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.005691741695 31.370001461
0x0f1b97b941bf4dbc9e1c9a13fcd2b9f01e932135859766ba53cd38bea9771300Meta Withdraw332467362022-09-18 4:29:0715 days 23 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.005449023042 30.880000013
0x60f82c53f1ffce0bddda9aa9a44627eeef7ceab9494983d1d63aca5f43280299Meta Withdraw332246422022-09-17 15:47:3416 days 12 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.004427624542 31.370000015
0xf59e07980e534e5c0588d05b6be1c9acd5cd53a07f6abd6a637977a25a087af5Meta Withdraw331886892022-09-16 18:42:5217 days 9 hrs ago0x0023c3fe7227de11d448ce520bf9f36651050b21 IN  0x8b6779969e9b5feb6ad6199041a166741d784e0a0 MATIC0.008366218007 43.476682468
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SynergyOfSerraAlphaFame

Compiler Version
v0.8.2+commit.661d1103

Optimization Enabled:
Yes with 1337 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at polygonscan.com on 2021-06-09
*/

// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0 <0.9.0;

/**
    @author The Calystral Team
    @title The Fame' Interface
*/
interface IFame {
    /* ========== EVENTS ========== */
    /**
        @dev MUST emit when crates are staked.
        The `from` argument MUST be the owner of the crates.
        The `beneficiary` argument MUST be befeniciary of the owner.
        The `baseAmount` argument MUST be the amount of base set crates staked.
        The `transcendentAmount` argument MUST be the amount of transcendent set crates staked.
    */
    event Staked(
        address indexed from,
        address indexed beneficiary,
        uint256 baseAmount,
        uint256 transcendentAmount
    );
    /**
        @dev MUST emit when crates are staked.
        The `from` argument MUST be the owner of the crates.
        The `beneficiary` argument MUST be befeniciary of the owner.
        The `baseAmount` argument MUST be the amount of base set crates staked.
        The `transcendentAmount` argument MUST be the amount of transcendent set crates staked.
    */
    event Withdrawn(
        address indexed owner,
        uint256 baseAmount,
        uint256 transcendentAmount
    );
    /**
        @dev MUST emit when alpha fame rewards are updated.
        The `rewards` argument MUST be the amount of alpha fame reward since the last update.
        The `totalAlphaFameRewarded` argument MUST be the total amount of alpha fame reward.
    */
    event FameRewarded(uint256 rewards, uint256 totalAlphaFameRewarded);
    /**
        @dev MUST emit when a user spent alpha fame.
        The `user` argument MUST be the user who spent alpha fame.
        The `amount` argument MUST be the amount of spent alpha fame.
    */
    event FameSpent(address indexed user, uint256 amount);
    /**
        @dev MUST emit when a beneficiary receives more stake points.
        The `beneficiary` argument MUST be the beneficiary who receives stake points.
        The `amount` argument MUST be the amoun of stake points reveceived.
    */
    event StakePointsAdded(address indexed beneficiary, uint256 amount);
    /**
        @dev MUST emit when a beneficiary removes more stake points.
        The `beneficiary` argument MUST be the beneficiary who removes stake points.
        The `amount` argument MUST be the amoun of stake points removed.
    */
    event StakePointsRemoved(address indexed beneficiary, uint256 amount);
    /**
        @dev MUST emit when the weekly reward is updated.
        The `value` argument MUST be the new weekly reward value.
    */
    event WeeklyRewardUpdated(uint256 value);
    /**
        @dev MUST emit when the block time is updated.
        The `milliseconds` argument MUST be the new block time in milliseconds.
    */
    event BlockTimeUpdated(uint256 milliseconds);
    /**
        @dev MUST emit when the fame per block is updated.
        The `famePerBlock` argument MUST be the new fame per block.
    */
    event FamePerBlockUpdated(uint256 famePerBlock);

    /* ========== EXTERNAL FUNCTIONS ========== */
    /**
        @notice SOULD NOT accept single transfer assets.
        @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated.
        This function SHOULD reject any transfer and MUST result in the transaction being reverted by the caller.
        @param _operator  The address which initiated the transfer (i.e. msg.sender)
        @param _from      The address which previously owned the token
        @param _id        The ID of the token being transferred
        @param _value     The amount of tokens being transferred
        @param _data      Additional data with no specified format
        @return           `bytes4(keccak256("false"))`
    */
    function onERC1155Received(
        address _operator,
        address _from,
        uint256 _id,
        uint256 _value,
        bytes calldata _data
    ) external returns (bytes4);

    /**
        @notice Handle the receipt of multiple ERC1155 token types.
        @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated.
        This function MUST return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` (i.e. 0xbc197c81) if it accepts the transfer(s).
        This function MUST revert if it rejects the transfer(s).
        Return of any other value than the prescribed keccak256 generated value MUST result in the transaction being reverted by the caller.
        Reverts if the user sets a new beneficary while holding stakes.
        Reverts if _data does not cointain a valid address as the beneficiary.
        Reverts if nothing is staked.
        Reverts if anything else than base set or transcendent set from the original Assets contract are staked.
        @param _operator  The address which initiated the batch transfer (i.e. msg.sender)
        @param _from      The address which previously owned the token
        @param _ids       An array containing ids of each token being transferred (order and length must match _values array)
        @param _values    An array containing amounts of each token being transferred (order and length must match _ids array)
        @param _data      Additional data with no specified format
        @return           `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
    */
    function onERC1155BatchReceived(
        address _operator,
        address _from,
        uint256[] calldata _ids,
        uint256[] calldata _values,
        bytes calldata _data
    ) external returns (bytes4);

    /**
        @notice Withdraw a specified amount of crates.
        @dev Withdraw a specified amount of crates.
        @param baseAmount           The amount of base set crates
        @param transcendentAmount   The amount of transcendent set crates
        Reverts if there is nothing to withdraw.
    */
    function withdraw(uint256 baseAmount, uint256 transcendentAmount) external;

    /**
        @notice Withdraw all staked crates.
        @dev Withdraw all crates.
        Reverts if there is nothing to withdraw.
    */
    function withdrawAll() external;

    /**
        @notice Withdraw a specified amount of crates.
        @dev Withdraw a specified amount of crates.
        Uses Meta Transactions - transactions are signed by the owner but are executed by anybody.
        Reverts if the signature is invalid.
        Reverts if the transaction expired.
        Reverts if the transaction was executed already.
        Reverts if there is nothing to withdraw.
        Emits the `TransferBatch` event where the `to` argument is the original owner address.
        @param signature    The signature of the signing account as proof for execution allowance
        @param signer       The signing account. This SHOULD be the owner of the assets
        @param nonce        Each sent meta transaction includes a nonce to prevent that a signed transaction is executed multiple times
        @param maxTimestamp The maximum point in time before the meta transaction expired, thus becoming invalid
    */
    function metaWithdraw(
        bytes memory signature,
        address signer,
        uint256 baseAmount,
        uint256 transcendentAmount,
        uint256 nonce,
        uint256 maxTimestamp
    ) external;

    /* ========== VIEW FUNCTIONS ========== */
    /**
        @notice Get the burn nonce of a specific user.
        @dev    Get the burn nonce of a specific user / signer.
        @param  signer The requested signer
        @return The burn nonce of a specific user
    */
    function getMetaNonce(address signer) external view returns (uint256);

    /**
        @notice Get the amount of alpha fame rewarded per stake point.
        @dev    Get the amount of alpha fame rewarded per stake point. This value can only increase ever.
        @return The amount of alpha fame rewarded per stake point
    */
    function calculatedAlphaFamePerStakePoint() external view returns (uint256);

    /**
        @notice Get the current alpha fame balance of a user.
        @dev    Get the current alpha fame balance of a user.
        @param  userAddress address of the user
        @return The current alpha fame balance of a user
    */
    function calculatedAlphaFameBalance(address userAddress)
        external
        view
        returns (uint256);

    /**
        @notice Get the block time.
        @dev    Get the block time. This value is set by the admin and does not reflect the actual block time of the blockchain.
        @return The block time
    */
    function getBlockTime() external view returns (uint256);

    /**
        @notice Get the weekly alpha fame reward.
        @dev    Get the weekly alpha fame reward.
        @return The weekly alpha fame reward
    */
    function getWeeklyReward() external view returns (uint256);

    /**
        @notice Get the last update block.
        @dev    Get the last update block.
        @return The last update block
    */
    function getLastUpdateBlock() external view returns (uint256);

    /**
        @notice Get the alpha fame reward per block.
        @dev    Get the alpha fame reward per block.
        @return The alpha fame reward per block
    */
    function getFamePerBlock() external view returns (uint256);

    /**
        @notice Get the staked base set crates of a user.
        @dev    Get the staked base set crates of a user.
        @param  owner address of the owner
        @return The staked base set crates of a user
    */
    function getStakedBaseBalance(address owner)
        external
        view
        returns (uint256);

    /**
        @notice Get the staked transcendent set crates of a user.
        @dev    Get the staked transcendent set crates of a user.
        @param  owner address of the owner
        @return The staked transcendent set crates of a user
    */
    function getStakedTranscendentBalance(address owner)
        external
        view
        returns (uint256);

    /**
        @notice Get the beneficiary of a user.
        @dev    Get the beneficiary of a user.
        @param  owner address of the owner
        @return The beneficiary of a user
    */
    function getBeneficiary(address owner) external view returns (address);

    /**
        @notice Get the stake points total supply.
        @dev    Get the stake points total supply.
        @return The stake points total supply
    */
    function getStakePointsTotalSupply() external view returns (uint256);

    /**
        @notice Get the stake points balance of a user.
        @dev    Get the stake points balance of a user.
        @param  userAddress address of the user
        @return The stake points balance of a user
    */
    function getStakePointsBalance(address userAddress)
        external
        view
        returns (uint256);

    /**
        @notice Get the total amount of rewarded alpha fame.
        @dev    Get the total amount of rewarded alpha fame.
        @return The total amount of rewarded alpha fame
    */
    function getTotalAlphaFameRewarded() external view returns (uint256);

    /**
        @notice Get the total amount of spent alpha fame.
        @dev    Get the total amount of spent alpha fame.
        @return The total amount of spent alpha fame
    */
    function getTotalAlphaFameSpent() external view returns (uint256);

    /**
        @notice Get the amount of alpha fame a user has in his/her vault.
        @dev    Get the amount of alpha fame a user has in his/her vault.
        @param  userAddress address of the user
        @return The amount of alpha fame a user has in his/her vault
    */
    function getAlphaFameVault(address userAddress)
        external
        view
        returns (uint256);

    /**
        @notice Get the alpha fame debit of a user.
        @dev    Get the alpha fame debit of a user.
        @param  userAddress address of the user
        @return The alpha fame debit of a user
    */
    function getAlphaFameDebit(address userAddress)
        external
        view
        returns (uint256);

    /* ========== RESTRICTED FUNCTIONS ========== */
    /**
        @notice Spend alpha fame.
        @dev    Spend alpha fame.
        Reverts if spending amount is 0.
        Reverts if user doesn't have enough alpha fame.
        @param  from address of the user
        @param  amount amount to spend
    */
    function spendAlphaFame(address from, uint256 amount) external;

    /**
        @notice Set a new value for the weekly reward.
        @dev    Set a new value for the weekly reward.
        Reverts if value is smaller than 1e18 (as decimals).
        @param  value new weekly reward value
    */
    function setWeeklyReward(uint256 value) external;

    /**
        @notice Set a new millisecond value for the block time.
        @dev    Set a new millisecond value for the block time.
        Reverts if block time is set to 0.
        @param  milliseconds new millisecond value
    */
    function setBlockTime(uint256 milliseconds) external;
}

/**
    Note: The ERC-165 identifier for this interface is 0x4e2312e0.
*/
interface IERC1155TokenReceiver {
    /**
        @notice Handle the receipt of a single ERC1155 token type.
        @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated.
        This function MUST return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` (i.e. 0xf23a6e61) if it accepts the transfer.
        This function MUST revert if it rejects the transfer.
        Return of any other value than the prescribed keccak256 generated value MUST result in the transaction being reverted by the caller.
        @param _operator  The address which initiated the transfer (i.e. msg.sender)
        @param _from      The address which previously owned the token
        @param _id        The ID of the token being transferred
        @param _value     The amount of tokens being transferred
        @param _data      Additional data with no specified format
        @return           `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
    */
    function onERC1155Received(
        address _operator,
        address _from,
        uint256 _id,
        uint256 _value,
        bytes calldata _data
    ) external returns (bytes4);

    /**
        @notice Handle the receipt of multiple ERC1155 token types.
        @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated.
        This function MUST return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` (i.e. 0xbc197c81) if it accepts the transfer(s).
        This function MUST revert if it rejects the transfer(s).
        Return of any other value than the prescribed keccak256 generated value MUST result in the transaction being reverted by the caller.
        @param _operator  The address which initiated the batch transfer (i.e. msg.sender)
        @param _from      The address which previously owned the token
        @param _ids       An array containing ids of each token being transferred (order and length must match _values array)
        @param _values    An array containing amounts of each token being transferred (order and length must match _ids array)
        @param _data      Additional data with no specified format
        @return           `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
    */
    function onERC1155BatchReceived(
        address _operator,
        address _from,
        uint256[] calldata _ids,
        uint256[] calldata _values,
        bytes calldata _data
    ) external returns (bytes4);
}

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

/**
    @author The Calystral Team
    @title The RegistrableContractState's Interface
*/
interface IRegistrableContractState is IERC165 {
    /*==============================
    =           EVENTS             =
    ==============================*/
    /// @dev MUST emit when the contract is set to an active state.
    event Activated();
    /// @dev MUST emit when the contract is set to an inactive state.
    event Inactivated();

    /*==============================
    =          FUNCTIONS           =
    ==============================*/
    /**
        @notice Sets the contract state to active.
        @dev Sets the contract state to active.
    */
    function setActive() external;

    /**
        @notice Sets the contract state to inactive.
        @dev Sets the contract state to inactive.
    */
    function setInactive() external;

    /**
        @dev Sets the registry contract object.
        Reverts if the registryAddress doesn't implement the IRegistry interface.
        @param registryAddress The registry address
    */
    function setRegistry(address registryAddress) external;

    /**
        @notice Returns the current contract state.
        @dev Returns the current contract state.
        @return The current contract state (true == active; false == inactive)
    */
    function getIsActive() external view returns (bool);

    /**
        @notice Returns the Registry address.
        @dev Returns the Registry address.
        @return The Registry address
    */
    function getRegistryAddress() external view returns (address);

    /**
        @notice Returns the current address associated with `key` identifier.
        @dev Look-up in the Registry.
        Returns the current address associated with `key` identifier.
        @return The key identifier
    */
    function getContractAddress(uint256 key) external view returns (address);
}

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts may inherit from this and call {_registerInterface} to declare
 * their support of an interface.
 */
abstract contract ERC165 is IERC165 {
    /*
     * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
     */
    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;

    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    constructor() {
        // Derived contracts need only register support for their own interfaces,
        // we register support for ERC165 itself here
        _registerInterface(_INTERFACE_ID_ERC165);
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     *
     * Time complexity O(1), guaranteed to always use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId)
        public
        view
        override
        returns (bool)
    {
        return _supportedInterfaces[interfaceId];
    }

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See {IERC165-supportsInterface}.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal virtual {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

/**
    @author The Calystral Team
    @title The Registry's Interface
*/
interface IRegistry is IRegistrableContractState {
    /*==============================
    =           EVENTS             =
    ==============================*/
    /**
        @dev MUST emit when an entry in the Registry is set or updated.
        The `key` argument MUST be the key of the entry which is set or updated.
        The `value` argument MUST be the address of the entry which is set or updated.
    */
    event EntrySet(uint256 indexed key, address value);
    /**
        @dev MUST emit when an entry in the Registry is removed.
        The `key` argument MUST be the key of the entry which is removed.
        The `value` argument MUST be the address of the entry which is removed.
    */
    event EntryRemoved(uint256 indexed key, address value);

    /*==============================
    =          FUNCTIONS           =
    ==============================*/
    /**
        @notice Sets the MultiSigAdmin contract as Registry entry 1.
        @dev Sets the MultiSigAdmin contract as Registry entry 1.
        @param msaAddress The contract address of the MultiSigAdmin
    */
    function initializeMultiSigAdmin(address msaAddress) external;

    /**
        @notice Checks if the registry Map contains the key.
        @dev Returns true if the key is in the registry map. O(1).
        @param key  The key to search for
        @return     The boolean result
    */
    function contains(uint256 key) external view returns (bool);

    /**
        @notice Returns the registry map length.
        @dev Returns the number of key-value pairs in the registry map. O(1).
        @return     The registry map length
    */
    function length() external view returns (uint256);

    /**
        @notice Returns the key-value pair stored at position `index` in the registry map.
        @dev Returns the key-value pair stored at position `index` in the registry map. O(1).
        Note that there are no guarantees on the ordering of entries inside the
        array, and it may change when more entries are added or removed.
        Requirements:
        - `index` must be strictly less than {length}.
        @param index    The position in the registry map
        @return         The key-value pair as a tuple
    */
    function at(uint256 index) external view returns (uint256, address);

    /**
        @notice Tries to return the value associated with `key`.
        @dev Tries to return the value associated with `key`.  O(1).
        Does not revert if `key` is not in the registry map.
        @param key    The key to search for
        @return       The key-value pair as a tuple
    */
    function tryGet(uint256 key) external view returns (bool, address);

    /**
        @notice Returns the value associated with `key`.
        @dev Returns the value associated with `key`.  O(1).
        Requirements:
        - `key` must be in the registry map.
        @param key    The key to search for
        @return       The contract address
    */
    function get(uint256 key) external view returns (address);

    /**
        @notice Returns all indices, keys, addresses.
        @dev Returns all indices, keys, addresses as three seperate arrays.
        @return Indices, keys, addresses
    */
    function getAll()
        external
        view
        returns (
            uint256[] memory,
            uint256[] memory,
            address[] memory
        );

    /**
        @notice Adds a key-value pair to a map, or updates the value for an existing
        key.
        @dev Adds a key-value pair to the registry map, or updates the value for an existing
        key. O(1).
        Returns true if the key was added to the registry map, that is if it was not
        already present.
        @param key    The key as an identifier
        @param value  The address of the contract
        @return       Success as a bool
    */
    function set(uint256 key, address value) external returns (bool);

    /**
        @notice Removes a value from the registry map.
        @dev Removes a value from the registry map. O(1).
        Returns true if the key was removed from the registry map, that is if it was present.
        @param key    The key as an identifier
        @return       Success as a bool
    */
    function remove(uint256 key) external returns (bool);

    /**
        @notice Sets a contract state to active.
        @dev Sets a contract state to active.
        @param key    The key as an identifier
    */
    function setContractActiveByKey(uint256 key) external;

    /**
        @notice Sets a contract state to active.
        @dev Sets a contract state to active.
        @param contractAddress The contract's address
    */
    function setContractActiveByAddress(address contractAddress) external;

    /**
        @notice Sets all contracts within the registry to state active.
        @dev Sets all contracts within the registry to state active.
        Does NOT revert if any contract doesn't implement the RegistrableContractState interface.
        Does NOT revert if it is an externally owned user account.
    */
    function setAllContractsActive() external;

    /**
        @notice Sets a contract state to inactive.
        @dev Sets a contract state to inactive.
        @param key    The key as an identifier
    */
    function setContractInactiveByKey(uint256 key) external;

    /**
        @notice Sets a contract state to inactive.
        @dev Sets a contract state to inactive.
        @param contractAddress The contract's address
    */
    function setContractInactiveByAddress(address contractAddress) external;

    /**
        @notice Sets all contracts within the registry to state inactive.
        @dev Sets all contracts within the registry to state inactive.
        Does NOT revert if any contract doesn't implement the RegistrableContractState interface.
        Does NOT revert if it is an externally owned user account.
    */
    function setAllContractsInactive() external;
}

/**
    @author The Calystral Team
    @title A helper parent contract: Pausable & Registry
*/
contract RegistrableContractState is IRegistrableContractState, ERC165 {
    /*==============================
    =          CONSTANTS           =
    ==============================*/

    /*==============================
    =            STORAGE           =
    ==============================*/
    /// @dev Current contract state
    bool private _isActive;
    /// @dev Current registry pointer
    address private _registryAddress;

    /*==============================
    =          MODIFIERS           =
    ==============================*/
    modifier isActive() {
        _isActiveCheck();
        _;
    }

    modifier isAuthorizedAdmin() {
        _isAuthorizedAdmin();
        _;
    }

    modifier isAuthorizedAdminOrRegistry() {
        _isAuthorizedAdminOrRegistry();
        _;
    }

    /*==============================
    =          CONSTRUCTOR         =
    ==============================*/
    /**
        @notice Creates and initializes the contract.
        @dev Creates and initializes the contract.
        Registers all implemented interfaces.
        Inheriting contracts are INACTIVE by default.
    */
    constructor(address registryAddress) {
        _registryAddress = registryAddress;

        _registerInterface(type(IRegistrableContractState).interfaceId);
    }

    /*==============================
    =      PUBLIC & EXTERNAL       =
    ==============================*/

    /*==============================
    =          RESTRICTED          =
    ==============================*/
    function setActive() external override isAuthorizedAdminOrRegistry() {
        _isActive = true;

        emit Activated();
    }

    function setInactive() external override isAuthorizedAdminOrRegistry() {
        _isActive = false;

        emit Inactivated();
    }

    function setRegistry(address registryAddress)
        external
        override
        isAuthorizedAdmin()
    {
        _registryAddress = registryAddress;

        try
            _registryContract().supportsInterface(type(IRegistry).interfaceId)
        returns (bool supportsInterface) {
            require(
                supportsInterface,
                "The provided contract does not implement the Registry interface"
            );
        } catch {
            revert(
                "The provided contract does not implement the Registry interface"
            );
        }
    }

    /*==============================
    =          VIEW & PURE         =
    ==============================*/
    function getIsActive() public view override returns (bool) {
        return _isActive;
    }

    function getRegistryAddress() public view override returns (address) {
        return _registryAddress;
    }

    function getContractAddress(uint256 key)
        public
        view
        override
        returns (address)
    {
        return _registryContract().get(key);
    }

    /*==============================
    =      INTERNAL & PRIVATE      =
    ==============================*/
    /**
        @dev Returns the target Registry object.
        @return The target Registry object
    */
    function _registryContract() internal view returns (IRegistry) {
        return IRegistry(_registryAddress);
    }

    /**
        @dev Checks if the contract is in an active state.
        Reverts if the contract is INACTIVE.
    */
    function _isActiveCheck() internal view {
        require(_isActive == true, "The contract is not active");
    }

    /**
        @dev Checks if the msg.sender is the Admin.
        Reverts if msg.sender is not the Admin.
    */
    function _isAuthorizedAdmin() internal view {
        require(msg.sender == getContractAddress(1), "Unauthorized call");
    }

    /**
        @dev Checks if the msg.sender is the Admin or the Registry.
        Reverts if msg.sender is not the Admin or the Registry.
    */
    function _isAuthorizedAdminOrRegistry() internal view {
        require(
            msg.sender == _registryAddress ||
                msg.sender == getContractAddress(1),
            "Unauthorized call"
        );
    }
}

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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

/**
    Note: Simple contract to use as base for const vals
*/
contract CommonConstants {
    bytes4 internal constant ERC1155_ACCEPTED = 0xf23a6e61; // bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))
    bytes4 internal constant ERC1155_BATCH_ACCEPTED = 0xbc197c81; // bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))
}

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature)
        internal
        pure
        returns (address)
    {
        // Check the signature length
        if (signature.length != 65) {
            revert("ECDSA: invalid signature length");
        }

        // Divide the signature in r, s and v variables
        bytes32 r;
        bytes32 s;
        uint8 v;

        // ecrecover takes the signature parameters, and the only way to get them
        // currently is to use assembly.
        // solhint-disable-next-line no-inline-assembly
        assembly {
            r := mload(add(signature, 0x20))
            s := mload(add(signature, 0x40))
            v := byte(0, mload(add(signature, 0x60)))
        }

        return recover(hash, v, r, s);
    }

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

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        require(signer != address(0), "ECDSA: invalid signature");

        return signer;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * replicates the behavior of the
     * https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`]
     * JSON-RPC method.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash)
        internal
        pure
        returns (bytes32)
    {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return
            keccak256(
                abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)
            );
    }
}

/**
    @title ERC-1155 Multi Token Standard
    @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1155.md
    Note: The ERC-165 identifier for this interface is 0xd9b67a26.
 */
interface IERC1155 {
    /* is ERC165 */
    /**
        @dev Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard).
        The `_operator` argument MUST be msg.sender.
        The `_from` argument MUST be the address of the holder whose balance is decreased.
        The `_to` argument MUST be the address of the recipient whose balance is increased.
        The `_id` argument MUST be the token type being transferred.
        The `_value` argument MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by.
        When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address).
        When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address).
    */
    event TransferSingle(
        address indexed _operator,
        address indexed _from,
        address indexed _to,
        uint256 _id,
        uint256 _value
    );

    /**
        @dev Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard).
        The `_operator` argument MUST be msg.sender.
        The `_from` argument MUST be the address of the holder whose balance is decreased.
        The `_to` argument MUST be the address of the recipient whose balance is increased.
        The `_ids` argument MUST be the list of tokens being transferred.
        The `_values` argument MUST be the list of number of tokens (matching the list and order of tokens specified in _ids) the holder balance is decreased by and match what the recipient balance is increased by.
        When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address).
        When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address).
    */
    event TransferBatch(
        address indexed _operator,
        address indexed _from,
        address indexed _to,
        uint256[] _ids,
        uint256[] _values
    );

    /**
        @dev MUST emit when approval for a second party/operator address to manage all tokens for an owner address is enabled or disabled (absense of an event assumes disabled).
    */
    event ApprovalForAll(
        address indexed _owner,
        address indexed _operator,
        bool _approved
    );

    /**
        @dev MUST emit when the URI is updated for a token ID.
        URIs are defined in RFC 3986.
        The URI MUST point a JSON file that conforms to the "ERC-1155 Metadata URI JSON Schema".
    */
    event URI(string _value, uint256 indexed _id);

    /**
        @notice Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call).
        @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard).
        MUST revert if `_to` is the zero address.
        MUST revert if balance of holder for token `_id` is lower than the `_value` sent.
        MUST revert on any other error.
        MUST emit the `TransferSingle` event to reflect the balance change (see "Safe Transfer Rules" section of the standard).
        After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard).
        @param _from    Source address
        @param _to      Target address
        @param _id      ID of the token type
        @param _value   Transfer amount
        @param _data    Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to`
    */
    function safeTransferFrom(
        address _from,
        address _to,
        uint256 _id,
        uint256 _value,
        bytes calldata _data
    ) external;

    /**
        @notice Transfers `_values` amount(s) of `_ids` from the `_from` address to the `_to` address specified (with safety call).
        @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard).
        MUST revert if `_to` is the zero address.
        MUST revert if length of `_ids` is not the same as length of `_values`.
        MUST revert if any of the balance(s) of the holder(s) for token(s) in `_ids` is lower than the respective amount(s) in `_values` sent to the recipient.
        MUST revert on any other error.
        MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see "Safe Transfer Rules" section of the standard).
        Balance changes and events MUST follow the ordering of the arrays (_ids[0]/_values[0] before _ids[1]/_values[1], etc).
        After the above conditions for the transfer(s) in the batch are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard).
        @param _from    Source address
        @param _to      Target address
        @param _ids     IDs of each token type (order and length must match _values array)
        @param _values  Transfer amounts per token type (order and length must match _ids array)
        @param _data    Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `_to`
    */
    function safeBatchTransferFrom(
        address _from,
        address _to,
        uint256[] calldata _ids,
        uint256[] calldata _values,
        bytes calldata _data
    ) external;

    /**
        @notice Get the balance of an account's Tokens.
        @param _owner  The address of the token holder
        @param _id     ID of the Token
        @return        The _owner's balance of the Token type requested
     */
    function balanceOf(address _owner, uint256 _id)
        external
        view
        returns (uint256);

    /**
        @notice Get the balance of multiple account/token pairs
        @param _owners The addresses of the token holders
        @param _ids    ID of the Tokens
        @return        The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
     */
    function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids)
        external
        view
        returns (uint256[] memory);

    /**
        @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens.
        @dev MUST emit the ApprovalForAll event on success.
        @param _operator  Address to add to the set of authorized operators
        @param _approved  True if the operator is approved, false to revoke approval
    */
    function setApprovalForAll(address _operator, bool _approved) external;

    /**
        @notice Queries the approval status of an operator for a given owner.
        @param _owner     The owner of the Tokens
        @param _operator  Address of authorized operator
        @return           True if the operator is approved, false if not
    */
    function isApprovedForAll(address _owner, address _operator)
        external
        view
        returns (bool);
}

/**
    @title ERC-1155 Mixed Fungible Token Standard
 */
interface IERC1155MixedFungible {
    /**
        @notice Returns true for non-fungible token id.
        @dev    Returns true for non-fungible token id.
        @param _id  Id of the token
        @return     If a token is non-fungible
     */
    function isNonFungible(uint256 _id) external pure returns (bool);

    /**
        @notice Returns true for fungible token id.
        @dev    Returns true for fungible token id.
        @param _id  Id of the token
        @return     If a token is fungible
     */
    function isFungible(uint256 _id) external pure returns (bool);

    /**
        @notice Returns the mint# of a token type.
        @dev    Returns the mint# of a token type.
        @param _id  Id of the token
        @return     The mint# of a token type.
     */
    function getNonFungibleIndex(uint256 _id) external pure returns (uint256);

    /**
        @notice Returns the base type of a token id.
        @dev    Returns the base type of a token id.
        @param _id  Id of the token
        @return     The base type of a token id.
     */
    function getNonFungibleBaseType(uint256 _id)
        external
        pure
        returns (uint256);

    /**
        @notice Returns true if the base type of the token id is a non-fungible base type.
        @dev    Returns true if the base type of the token id is a non-fungible base type.
        @param _id  Id of the token
        @return     The non-fungible base type info as bool
     */
    function isNonFungibleBaseType(uint256 _id) external pure returns (bool);

    /**
        @notice Returns true if the base type of the token id is a fungible base type.
        @dev    Returns true if the base type of the token id is a fungible base type.
        @param _id  Id of the token
        @return     The fungible base type info as bool
     */
    function isNonFungibleItem(uint256 _id) external pure returns (bool);

    /**
        @notice Returns the owner of a token.
        @dev    Returns the owner of a token.
        @param _id  Id of the token
        @return     The owner address
     */
    function ownerOf(uint256 _id) external view returns (address);
}

/**
    @author The Calystral Team
    @title The ERC1155CalystralMixedFungibleMintable' Interface
*/
interface IERC1155CalystralMixedFungibleMintable {
    /**
        @dev MUST emit when a release timestamp is set or updated.
        The `typeId` argument MUST be the id of a type.
        The `timestamp` argument MUST be the timestamp of the release in seconds.
    */
    event OnReleaseTimestamp(uint256 indexed typeId, uint256 timestamp);

    /**
        @notice Updates the metadata base URI.
        @dev Updates the `_metadataBaseURI`.
        @param uri The metadata base URI
    */
    function updateMetadataBaseURI(string calldata uri) external;

    /**
        @notice Creates a non-fungible type.
        @dev Creates a non-fungible type. This function only creates the type and is not used for minting.
        The type also has a maxSupply since there can be multiple tokens of the same type, e.g. 100x 'Pikachu'.
        Reverts if the `maxSupply` is 0 or exceeds the `MAX_TYPE_SUPPLY`.
        @param maxSupply        The maximum amount that can be created of this type, unlimited SHOULD be 2**128 (uint128) as the max. MUST NOT be set to 0
        @param releaseTimestamp The timestamp for the release time, SHOULD be set to 1337 for releasing it right away. MUST NOT be set to 0
        @return                 The `typeId`
    */
    function createNonFungibleType(uint256 maxSupply, uint256 releaseTimestamp)
        external
        returns (uint256);

    /**
        @notice Creates a fungible type.
        @dev Creates a fungible type. This function only creates the type and is not used for minting.
        Reverts if the `maxSupply` is 0 or exceeds the `MAX_TYPE_SUPPLY`.
        @param maxSupply        The maximum amount that can be created of this type, unlimited SHOULD be 2**128 (uint128) as the max. MUST NOT be set to 0
        @param releaseTimestamp The timestamp for the release time, SHOULD be set to 1337 for releasing it right away. MUST NOT be set to 0
        @return                 The `typeId`
    */
    function createFungibleType(uint256 maxSupply, uint256 releaseTimestamp)
        external
        returns (uint256);

    /**
        @notice Mints a non-fungible type.
        @dev Mints a non-fungible type.
        Reverts if type id is not existing.
        Reverts if out of stock.
        Emits the `TransferSingle` event.
        @param typeId   The type which should be minted
        @param toArr    An array of receivers
    */
    function mintNonFungible(uint256 typeId, address[] calldata toArr) external;

    /**
        @notice Mints a fungible type.
        @dev Mints a fungible type.
        Reverts if array lengths are unequal.
        Reverts if type id is not existing.
        Reverts if out of stock.
        Emits the `TransferSingle` event.
        @param typeId   The type which should be minted
        @param toArr    An array of receivers
    */
    function mintFungible(
        uint256 typeId,
        address[] calldata toArr,
        uint256[] calldata quantitiesArr
    ) external;

    /**
        @notice Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call).
        @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard).
        Uses Meta Transactions - transactions are signed by the owner or operator of the owner but are executed by anybody.
        Reverts if the signature is invalid.
        Reverts if array lengths are unequal.
        Reverts if the transaction expired.
        Reverts if the transaction was executed already.
        Reverts if the signer is not the asset owner or approved operator of the owner.
        Reverts if `_to` is the zero address.
        Reverts if balance of holder for token `_id` is lower than the `_value` sent.
        MUST emit the `TransferSingle` event to reflect the balance change (see "Safe Transfer Rules" section of the standard).
        After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard).
        @param signature    The signature of the signing account as proof for execution allowance
        @param signer       The signing account. This SHOULD be the owner of the asset or an approved operator of the owner.
        @param _to          Target address
        @param _id          ID of the token type
        @param _value       Transfer amount
        @param _data        Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to`
        @param nonce        Each sent meta transaction includes a nonce to prevent that a signed transaction is executed multiple times
        @param maxTimestamp The maximum point in time before the meta transaction expired, thus becoming invalid
    */
    function metaSafeTransferFrom(
        bytes memory signature,
        address signer,
        address _to,
        uint256 _id,
        uint256 _value,
        bytes calldata _data,
        uint256 nonce,
        uint256 maxTimestamp
    ) external;

    /**
        @notice Transfers `_values` amount(s) of `_ids` from the `_from` address to the `_to` address specified (with safety call).
        @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard).
        Uses Meta Transactions - transactions are signed by the owner or operator of the owner but are executed by anybody.
        Reverts if the signature is invalid.
        Reverts if array lengths are unequal.
        Reverts if the transaction expired.
        Reverts if the transaction was executed already.
        Reverts if the signer is not the asset owner or approved operator of the owner.
        Reverts if `_to` is the zero address.
        Reverts if length of `_ids` is not the same as length of `_values`.
        Reverts if any of the balance(s) of the holder(s) for token(s) in `_ids` is lower than the respective amount(s) in `_values` sent to the recipient.
        MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see "Safe Transfer Rules" section of the standard).
        Balance changes and events MUST follow the ordering of the arrays (_ids[0]/_values[0] before _ids[1]/_values[1], etc).
        After the above conditions for the transfer(s) in the batch are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard).
        @param signature    The signature of the signing account as proof for execution allowance
        @param signer       The signing account. This SHOULD be the owner of the asset or an approved operator of the owner.
        @param _to          Target address
        @param _ids         IDs of each token type (order and length must match _values array)
        @param _values      Transfer amounts per token type (order and length must match _ids array)
        @param _data        Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `_to`
        @param nonce        Each sent meta transaction includes a nonce to prevent that a signed transaction is executed multiple times
        @param maxTimestamp The maximum point in time before the meta transaction expired, thus becoming invalid
    */
    function metaSafeBatchTransferFrom(
        bytes memory signature,
        address signer,
        address _to,
        uint256[] calldata _ids,
        uint256[] calldata _values,
        bytes calldata _data,
        uint256 nonce,
        uint256 maxTimestamp
    ) external;

    /**
        @notice Burns fungible and/or non-fungible tokens.
        @dev Sends FTs and/or NFTs to 0x0 address.
        Uses Meta Transactions - transactions are signed by the owner but are executed by anybody.
        Reverts if the signature is invalid.
        Reverts if array lengths are unequal.
        Reverts if the transaction expired.
        Reverts if the transaction was executed already.
        Reverts if the signer is not the asset owner.
        Emits the `TransferBatch` event where the `to` argument is the 0x0 address.
        @param signature    The signature of the signing account as proof for execution allowance
        @param signer The signing account. This SHOULD be the owner of the asset
        @param ids An array of token Ids which should be burned
        @param values An array of amounts which should be burned. The order matches the order in the ids array
        @param nonce Each sent meta transaction includes a nonce to prevent that a signed transaction is executed multiple times
        @param maxTimestamp The maximum point in time before the meta transaction expired, thus becoming invalid
    */
    function metaBatchBurn(
        bytes memory signature,
        address signer,
        uint256[] calldata ids,
        uint256[] calldata values,
        uint256 nonce,
        uint256 maxTimestamp
    ) external;

    /**
        @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens.
        @dev MUST emit the ApprovalForAll event on success.
        Uses Meta Transactions - transactions are signed by the owner but are executed by anybody.
        Reverts if the signature is invalid.
        Reverts if array lengths are unequal.
        Reverts if the transaction expired.
        Reverts if the transaction was executed already.
        Reverts if the signer is not the asset owner.
        @param signature    The signature of the signing account as proof for execution allowance
        @param signer       The signing account. This SHOULD be the owner of the asset
        @param _operator    Address to add to the set of authorized operators
        @param _approved    True if the operator is approved, false to revoke approval
        @param nonce        Each sent meta transaction includes a nonce to prevent that a signed transaction is executed multiple times
        @param maxTimestamp The maximum point in time before the meta transaction expired, thus becoming invalid
    */
    function metaSetApprovalForAll(
        bytes memory signature,
        address signer,
        address _operator,
        bool _approved,
        uint256 nonce,
        uint256 maxTimestamp
    ) external;

    /**
        @notice Sets a release timestamp.
        @dev Sets a release timestamp.
        Reverts if `timestamp` == 0.
        Reverts if the `typeId` is released already.
        @param typeId       The type which should be set or updated
        @param timestamp    The timestamp for the release time, SHOULD be set to 1337 for releasing it right away. MUST NOT be set to 0
    */
    function setReleaseTimestamp(uint256 typeId, uint256 timestamp) external;

    /**
        @notice Get the release timestamp of a type.
        @dev Get the release timestamp of a type.
        @return The release timestamp of a type.
    */
    function getReleaseTimestamp(uint256 typeId)
        external
        view
        returns (uint256);

    /**
        @notice Get all existing type Ids.
        @dev Get all existing type Ids.
        @return An array of all existing type Ids.
    */
    function getTypeIds() external view returns (uint256[] memory);

    /**
        @notice Get a specific type Id.
        @dev Get a specific type Id.
        Reverts if `typeNonce` is 0 or if it does not exist.
        @param  typeNonce The type nonce for which the id is requested
        @return A specific type Id.
    */
    function getTypeId(uint256 typeNonce) external view returns (uint256);

    /**
        @notice Get all non-fungible assets for a specific user.
        @dev Get all non-fungible assets for a specific user.
        @param  owner The address of the requested user
        @return An array of Ids that are owned by the user
    */
    function getNonFungibleAssets(address owner)
        external
        view
        returns (uint256[] memory);

    /**
        @notice Get all fungible assets for a specific user.
        @dev Get all fungible assets for a specific user.
        @param  owner The address of the requested user
        @return An array of Ids that are owned by the user
                An array for the amount owned of each Id
    */
    function getFungibleAssets(address owner)
        external
        view
        returns (uint256[] memory, uint256[] memory);

    /**
        @notice Get the type nonce.
        @dev Get the type nonce.
        @return The type nonce.
    */
    function getTypeNonce() external view returns (uint256);

    /**
        @notice The amount of tokens that have been minted of a specific type.
        @dev    The amount of tokens that have been minted of a specific type.
                Reverts if the given typeId does not exist.
        @param  typeId The requested type
        @return The minted amount
    */
    function getMintedSupply(uint256 typeId) external view returns (uint256);

    /**
        @notice The amount of tokens that can be minted of a specific type.
        @dev    The amount of tokens that can be minted of a specific type.
                Reverts if the given typeId does not exist.
        @param  typeId The requested type
        @return The maximum mintable amount
    */
    function getMaxSupply(uint256 typeId) external view returns (uint256);

    /**
        @notice Get the burn nonce of a specific user.
        @dev    Get the burn nonce of a specific user / signer.
        @param  signer The requested signer
        @return The burn nonce of a specific user
    */
    function getMetaNonce(address signer) external view returns (uint256);
}

/**
    @author The Calystral Team
    @title The Assets' Interface
*/
interface IAssets is
    IERC1155,
    IERC1155MixedFungible,
    IERC1155CalystralMixedFungibleMintable,
    IRegistrableContractState
{
    /**
        @dev MUST emit when any property type is created.
        The `propertyId` argument MUST be the id of a property.
        The `name` argument MUST be the name of this specific id.
        The `propertyType` argument MUST be the property type.
    */
    event OnCreateProperty(
        uint256 propertyId,
        string name,
        PropertyType indexed propertyType
    );
    /**
        @dev MUST emit when an int type property is updated.
        The `tokenId` argument MUST be the id of the token of which the property is updated.
        The `propertyId` argument MUST be the property id which is updated.
        The `value` argument MUST be the value to which the token's property is updated.
    */
    event OnUpdateIntProperty(
        uint256 indexed tokenId,
        uint256 indexed propertyId,
        int256 value
    );
    /**
        @dev MUST emit when an string type property is updated.
        The `tokenId` argument MUST be the id of the token of which the property is updated.
        The `propertyId` argument MUST be the property id which is updated.
        The `value` argument MUST be the value to which the token's property is updated.
    */
    event OnUpdateStringProperty(
        uint256 indexed tokenId,
        uint256 indexed propertyId,
        string value
    );
    /**
        @dev MUST emit when an address type property is updated.
        The `tokenId` argument MUST be the id of the token of which the property is updated.
        The `propertyId` argument MUST be the property id which is updated.
        The `value` argument MUST be the value to which the token's property is updated.
    */
    event OnUpdateAddressProperty(
        uint256 indexed tokenId,
        uint256 indexed propertyId,
        address value
    );
    /**
        @dev MUST emit when an byte type property is updated.
        The `tokenId` argument MUST be the id of the token of which the property is updated.
        The `propertyId` argument MUST be the property id which is updated.
        The `value` argument MUST be the value to which the token's property is updated.
    */
    event OnUpdateByteProperty(
        uint256 indexed tokenId,
        uint256 indexed propertyId,
        bytes32 value
    );
    /**
        @dev MUST emit when an int array type property is updated.
        The `tokenId` argument MUST be the id of the token of which the property is updated.
        The `propertyId` argument MUST be the property id which is updated.
        The `value` argument MUST be the value to which the token's property is updated.
    */
    event OnUpdateIntArrayProperty(
        uint256 indexed tokenId,
        uint256 indexed propertyId,
        int256[] value
    );
    /**
        @dev MUST emit when an address array type property is updated.
        The `tokenId` argument MUST be the id of the token of which the property is updated.
        The `propertyId` argument MUST be the property id which is updated.
        The `value` argument MUST be the value to which the token's property is updated.
    */
    event OnUpdateAddressArrayProperty(
        uint256 indexed tokenId,
        uint256 indexed propertyId,
        address[] value
    );

    /// @dev Enum representing all existing property types that can be used.
    enum PropertyType {INT, STRING, ADDRESS, BYTE, INTARRAY, ADDRESSARRAY}

    /**
        @notice Creates a property of type int.
        @dev Creates a property of type int.
        @param name The name for this property
        @return     The property id
    */
    function createIntProperty(string calldata name) external returns (uint256);

    /**
        @notice Creates a property of type string.
        @dev Creates a property of type string.
        @param name The name for this property
        @return     The property id
    */
    function createStringProperty(string calldata name)
        external
        returns (uint256);

    /**
        @notice Creates a property of type address.
        @dev Creates a property of type address.
        @param name The name for this property
        @return     The property id
    */
    function createAddressProperty(string calldata name)
        external
        returns (uint256);

    /**
        @notice Creates a property of type byte.
        @dev Creates a property of type byte.
        @param name The name for this property
        @return     The property id
    */
    function createByteProperty(string calldata name)
        external
        returns (uint256);

    /**
        @notice Creates a property of type int array.
        @dev Creates a property of type int array.
        @param name The name for this property
        @return     The property id
    */
    function createIntArrayProperty(string calldata name)
        external
        returns (uint256);

    /**
        @notice Creates a property of type address array.
        @dev Creates a property of type address array.
        @param name The name for this property
        @return     The property id
    */
    function createAddressArrayProperty(string calldata name)
        external
        returns (uint256);

    /**
        @notice Updates an existing int property for the passed value.
        @dev Updates an existing int property for the passed `value`.
        @param tokenId      The id of the token of which the property is updated
        @param propertyId   The property id which is updated
        @param value        The value to which the token's property is updated
    */
    function updateIntProperty(
        uint256 tokenId,
        uint256 propertyId,
        int256 value
    ) external;

    /**
        @notice Updates an existing string property for the passed value.
        @dev Updates an existing string property for the passed `value`.
        @param tokenId      The id of the token of which the property is updated
        @param propertyId   The property id which is updated
        @param value        The value to which the token's property is updated
    */
    function updateStringProperty(
        uint256 tokenId,
        uint256 propertyId,
        string calldata value
    ) external;

    /**
        @notice Updates an existing address property for the passed value.
        @dev Updates an existing address property for the passed `value`.
        @param tokenId      The id of the token of which the property is updated
        @param propertyId   The property id which is updated
        @param value        The value to which the token's property is updated
    */
    function updateAddressProperty(
        uint256 tokenId,
        uint256 propertyId,
        address value
    ) external;

    /**
        @notice Updates an existing byte property for the passed value.
        @dev Updates an existing byte property for the passed `value`.
        @param tokenId      The id of the token of which the property is updated
        @param propertyId   The property id which is updated
        @param value        The value to which the token's property is updated
    */
    function updateByteProperty(
        uint256 tokenId,
        uint256 propertyId,
        bytes32 value
    ) external;

    /**
        @notice Updates an existing int array property for the passed value.
        @dev Updates an existing int array property for the passed `value`.
        @param tokenId      The id of the token of which the property is updated
        @param propertyId   The property id which is updated
        @param value        The value to which the token's property is updated
    */
    function updateIntArrayProperty(
        uint256 tokenId,
        uint256 propertyId,
        int256[] calldata value
    ) external;

    /**
        @notice Updates an existing address array property for the passed value.
        @dev Updates an existing address array property for the passed `value`.
        @param tokenId      The id of the token of which the property is updated
        @param propertyId   The property id which is updated
        @param value        The value to which the token's property is updated
    */
    function updateAddressArrayProperty(
        uint256 tokenId,
        uint256 propertyId,
        address[] calldata value
    ) external;

    /**
        @notice Get the property type of a property.
        @dev Get the property type of a property.
        @return The property type
    */
    function getPropertyType(uint256 propertyId)
        external
        view
        returns (PropertyType);

    /**
        @notice Get the count of available properties.
        @dev Get the count of available properties.
        @return The property count
    */
    function getPropertyCounter() external view returns (uint256);
}

/**
    @author The Calystral Team
    @title Earn Synergy of Serra's Alpha Fame through Crate deposit!
*/
contract SynergyOfSerraAlphaFame is
    IFame,
    IERC1155TokenReceiver,
    RegistrableContractState,
    ReentrancyGuard,
    CommonConstants
{
    /*==============================
    =          CONSTANTS           =
    ==============================*/
    /**
        @notice Count of decimals for alpha fame.
        @dev    1^18 decimals for alpha fame.
    */
    uint256 public constant DECIMALS = 1e18;
    /**
        @notice Milliseconds per week.
        @dev    Milliseconds per week.
    */
    uint256 public constant MS_PER_WEEK = 604800000;
    /**
        @notice Each transcendent set crate rewards 2 stake points.
        @dev    Each transcendent set crate rewards 2 stake points.
    */
    uint256 public constant TRANSCENDENT_MULTIPLIER = 2;
    /**
        @notice Each base set crate rewards 1 stake points.
        @dev    Each base set crate rewards 1 stake points.
    */
    uint256 public constant BASE_MULTIPLIER = 1;
    /**
        @notice Token id of base set crate.
        @dev    Token id of base set crate.
    */
    uint256 public constant BASE_ID = 340282366920938463463374607431768211456;
    /**
        @notice Token id of transcendent set crate.
        @dev    Token id of transcendent set crate.
    */
    uint256 public constant TRANSCENDENT_ID =
        680564733841876926926749214863536422912;

    /*==============================
    =            STORAGE           =
    ==============================*/
    /**
        @notice The block time in milliseconds for the Matic Mainnet.
        @dev    The block time in milliseconds for the Matic Mainnet.
    */
    uint256 public msBlockTime = 2100;
    /**
        @notice The weekly distribution amount of alpha fame.
        @dev    The weekly distribution amount of alpha fame.
    */
    uint256 public weeklyReward;
    /**
        @notice Alpha fame distributed in each block.
        @dev    Alpha fame distributed in each block.
    */
    uint256 public famePerBlock;
    /**
        @notice Block number of the last update.
        @dev    Block number of the last update.
    */
    uint256 public lastUpdateBlock;
    /**
        @notice The amount of alpha fame reward per stake point.
        @dev    The amount of alpha fame reward per stake point.
    */
    uint256 public famePerStakePoint;

    /// @dev owner => base set crate balance
    mapping(address => uint256) private _ownerToStakedBaseBalance;
    /// @dev owner => transcendent set crate balance
    mapping(address => uint256) private _ownerToStakedTranscendentBalance;
    /// @dev owner => beneficiary
    mapping(address => address) private _ownerToBeneficiary;
    /// @dev The current total supply of stake points.
    uint256 private _stakePointsTotalSupply;
    /// @dev beneficiary => stake points balance
    mapping(address => uint256) private _stakePointsBalance;
    /// @dev The total amount of alpha fame ever rewarded.
    uint256 private _totalAlphaFameRewarded;
    /// @dev The total amount of alpha fave ever spent.
    uint256 private _totalAlphaFameSpent;
    /// @dev When a user withdraws, his current alpha fame earnings are stored in the user's vault. (Removed from the calculated formula)
    mapping(address => uint256) private _alphaFameVault;
    /// @dev This is not the actual spent value, it also contains the deficit based on the time the user wasn't staking in the past.
    mapping(address => uint256) private _alphaFameDebit;
    /// @dev signer => meta nonce
    mapping(address => uint256) private _signerToMetaNonce;

    /*==============================
    =          MODIFIERS           =
    ==============================*/
    modifier isAuthorizedAlphaFameManager() {
        _isAuthorizedAlphaFameManager();
        _;
    }

    modifier isAuthorizedAssets() {
        _isAuthorizedAssets();
        _;
    }

    modifier updateAlphaFameRewards() {
        _updateAlphaFameRewards();
        _;
    }

    /*==============================
    =          CONSTRUCTOR         =
    ==============================*/
    /**
        @notice Creates and initializes the contract.
        @dev Creates and initializes the contract.
        Registers all implemented interfaces.
        Contract is INACTIVE by default.
        @param registryAddress  Address of the Registry
    */
    constructor(address registryAddress)
        RegistrableContractState(registryAddress)
    {
        _setBlockTime(2100);

        _registerInterface(type(IFame).interfaceId);
        _registerInterface(type(IERC1155TokenReceiver).interfaceId);
    }

    /*==============================
    =      PUBLIC & EXTERNAL       =
    ==============================*/
    //@override
    function onERC1155Received(
        address,
        address,
        uint256,
        uint256,
        bytes calldata
    )
        external
        view
        override(IERC1155TokenReceiver, IFame)
        isActive()
        returns (bytes4)
    {
        return bytes4(keccak256("false"));
    }

    function withdraw(uint256 baseAmount, uint256 transcendentAmount)
        external
        override
        isActive()
    {
        _withdraw(msg.sender, baseAmount, transcendentAmount);
    }

    function withdrawAll() external override isActive() {
        _withdraw(
            msg.sender,
            _ownerToStakedBaseBalance[msg.sender],
            _ownerToStakedTranscendentBalance[msg.sender]
        );
    }

    function metaWithdraw(
        bytes memory signature,
        address signer,
        uint256 baseAmount,
        uint256 transcendentAmount,
        uint256 nonce,
        uint256 maxTimestamp
    ) external virtual override isActive() {
        // Meta Transaction
        bytes32 dataHash =
            _getWithdrawAllDataHash(
                baseAmount,
                transcendentAmount,
                nonce,
                maxTimestamp
            );
        address signaturePublicKey =
            ECDSA.recover(ECDSA.toEthSignedMessageHash(dataHash), signature);
        require(
            signer == signaturePublicKey,
            "Recovered public key does not match the signer"
        );
        require(
            block.timestamp < maxTimestamp,
            "This transaction is not valid anymore"
        );
        require(
            _signerToMetaNonce[signer] == nonce,
            "This transaction was executed already"
        );
        _signerToMetaNonce[signer]++;
        // Function Logic
        _withdraw(signer, baseAmount, transcendentAmount);
    }

    /*==============================
    =          RESTRICTED          =
    ==============================*/
    //@override
    function onERC1155BatchReceived(
        address,
        address _from,
        uint256[] calldata _ids,
        uint256[] calldata _values,
        bytes calldata _data
    )
        external
        override(IERC1155TokenReceiver, IFame)
        isAuthorizedAssets()
        updateAlphaFameRewards()
        returns (bytes4)
    {
        bytes memory addressData = _data;
        address beneficiary;
        assembly {
            beneficiary := mload(add(addressData, 20))
        }
        _stake(_from, _ids, _values, beneficiary);
        return ERC1155_BATCH_ACCEPTED;
    }

    function spendAlphaFame(address from, uint256 amount)
        external
        override
        isAuthorizedAlphaFameManager()
        updateAlphaFameRewards()
    {
        require(amount > 0, "Zero amount not allowed");
        require(calculatedAlphaFameBalance(from) >= amount, "Not enough Fame");
        _alphaFameDebit[from] += amount;
        _totalAlphaFameSpent += amount;

        emit FameSpent(from, amount);
    }

    // Value is required to have 1e18 as decimals
    function setWeeklyReward(uint256 value)
        external
        override
        isAuthorizedAlphaFameManager()
        updateAlphaFameRewards()
    {
        _setWeeklyReward(value);
    }

    function setBlockTime(uint256 milliseconds)
        external
        override
        isAuthorizedAlphaFameManager()
        updateAlphaFameRewards()
    {
        _setBlockTime(milliseconds);
    }

    /*==============================
    =          VIEW & PURE         =
    ==============================*/
    function getMetaNonce(address signer)
        public
        view
        override
        returns (uint256)
    {
        return _signerToMetaNonce[signer];
    }

    function calculatedAlphaFamePerStakePoint()
        public
        view
        override
        returns (uint256)
    {
        if (_stakePointsTotalSupply == 0) {
            return famePerStakePoint;
        }
        return
            famePerStakePoint +
            ((block.number - lastUpdateBlock) * famePerBlock) /
            _stakePointsTotalSupply;
    }

    function calculatedAlphaFameBalance(address userAddress)
        public
        view
        override
        returns (uint256)
    {
        return
            _stakePointsBalance[userAddress] *
            calculatedAlphaFamePerStakePoint() +
            _alphaFameVault[userAddress] -
            _alphaFameDebit[userAddress];
    }

    function getBlockTime() public view override returns (uint256) {
        return msBlockTime;
    }

    function getWeeklyReward() public view override returns (uint256) {
        return weeklyReward;
    }

    function getLastUpdateBlock() public view override returns (uint256) {
        return lastUpdateBlock;
    }

    function getFamePerBlock() public view override returns (uint256) {
        return famePerBlock;
    }

    function getStakedBaseBalance(address owner)
        public
        view
        override
        returns (uint256)
    {
        return _ownerToStakedBaseBalance[owner];
    }

    function getStakedTranscendentBalance(address owner)
        public
        view
        override
        returns (uint256)
    {
        return _ownerToStakedTranscendentBalance[owner];
    }

    function getBeneficiary(address owner)
        public
        view
        override
        returns (address)
    {
        return _ownerToBeneficiary[owner];
    }

    function getStakePointsTotalSupply()
        public
        view
        override
        returns (uint256)
    {
        return _stakePointsTotalSupply;
    }

    function getStakePointsBalance(address userAddress)
        public
        view
        override
        returns (uint256)
    {
        return _stakePointsBalance[userAddress];
    }

    function getTotalAlphaFameRewarded()
        public
        view
        override
        returns (uint256)
    {
        return _totalAlphaFameRewarded;
    }

    function getTotalAlphaFameSpent() public view override returns (uint256) {
        return _totalAlphaFameSpent;
    }

    function getAlphaFameVault(address userAddress)
        public
        view
        override
        returns (uint256)
    {
        return _alphaFameVault[userAddress];
    }

    function getAlphaFameDebit(address userAddress)
        public
        view
        override
        returns (uint256)
    {
        return _alphaFameDebit[userAddress];
    }

    /*==============================
    =      INTERNAL & PRIVATE      =
    ==============================*/
    /**
        @dev Stores the user's crates and rewards his/her beneficiary with stake points that earn alpha fame over time.
        Reverts if the user sets a new beneficary while holding stakes.
        Reverts if nothing is staked.
        Reverts if anything else than base set or transcendent set from the original Assets contract are staked.
        MUST emit Staked.
        @param from         The address which previously owned the token
        @param tokenIds     An array containing ids of each token being transferred (order and length must match _values array)
        @param amounts      An array containing amounts of each token being transferred (order and length must match _ids array)
        @param beneficiary  The beneficiary address
    */
    function _stake(
        address from,
        uint256[] calldata tokenIds,
        uint256[] calldata amounts,
        address beneficiary
    ) private nonReentrant() {
        require(
            _ownerToBeneficiary[from] == beneficiary ||
                (_ownerToStakedBaseBalance[from] == 0 &&
                    _ownerToStakedTranscendentBalance[from] == 0),
            "You are not allowed to benefit a new SoS account"
        );
        require(beneficiary != address(0), "Beneficiary is not set");
        _ownerToBeneficiary[from] = beneficiary;

        uint256 totalAmount;
        for (uint256 j = 0; j < amounts.length; ++j) {
            totalAmount += amounts[j];
        }
        require(totalAmount > 0, "Cannot stake 0");

        uint256 totalStakePointReward;
        uint256 baseAmount;
        uint256 transcendentAmount;
        for (uint256 i = 0; i < tokenIds.length; ++i) {
            require(
                tokenIds[i] == BASE_ID || tokenIds[i] == TRANSCENDENT_ID,
                "Asset not supported"
            );
            if (tokenIds[i] == BASE_ID) {
                baseAmount += amounts[i];
            }
            if (tokenIds[i] == TRANSCENDENT_ID) {
                transcendentAmount += amounts[i];
            }
        }
        _isGanzzahlig(baseAmount, transcendentAmount);

        _ownerToStakedBaseBalance[from] += baseAmount;
        totalStakePointReward += _calculateStakePoints(
            baseAmount,
            BASE_MULTIPLIER
        );
        _ownerToStakedTranscendentBalance[from] += transcendentAmount;
        totalStakePointReward += _calculateStakePoints(
            transcendentAmount,
            TRANSCENDENT_MULTIPLIER
        );
        _alphaFameDebit[beneficiary] +=
            totalStakePointReward *
            famePerStakePoint;
        _addStakePoints(beneficiary, totalStakePointReward);

        emit Staked(from, beneficiary, baseAmount, transcendentAmount);
    }

    /**
        @dev Readability: Calculates the amount of stake points received.
        @param crateCount        The amount of crates received.
        @param crateMultiplier   The crate's type specific multiplier.
        @return                  crateCount * crateMultiplier
    */
    function _calculateStakePoints(uint256 crateCount, uint256 crateMultiplier)
        private
        pure
        returns (uint256)
    {
        return (crateCount / DECIMALS) * crateMultiplier;
    }

    /**
        @dev Rewards the beneficiary with stake points when staked.
        Emits StakePointsAdded(beneficiary, count).
        @param beneficiary  The beneficiary.
        @param count        The count of stake points rewarded.
    */
    function _addStakePoints(address beneficiary, uint256 count) private {
        _stakePointsBalance[beneficiary] += count;
        _stakePointsTotalSupply += count;

        emit StakePointsAdded(beneficiary, count);
    }

    /**
        @dev Removes the beneficiary's stake points when unstaked.
        Emits StakePointsRemoved(beneficiary, count).
        @param beneficiary  The beneficiary.
        @param count        The count of stake points removed.
    */
    function _removeStakePoints(address beneficiary, uint256 count) private {
        _stakePointsBalance[beneficiary] -= count;
        _stakePointsTotalSupply -= count;

        emit StakePointsRemoved(beneficiary, count);
    }

    /**
        @notice Withdraws all staked crates.
        @dev Withdraws all crates and sends them back to the rightful owner (Assets contract).
        Removes all the owners stake points and stores the current earned alpha fame into his/her vault.
        Reverts if there is nothing to withdraw.
        Emits Withdrawn(owner, baseAmount, transcendentAmount).
    */
    function _withdraw(
        address owner,
        uint256 baseAmount,
        uint256 transcendentAmount
    ) private updateAlphaFameRewards() nonReentrant() {
        _isGanzzahlig(baseAmount, transcendentAmount);
        require(
            _ownerToStakedBaseBalance[owner] > 0 ||
                _ownerToStakedTranscendentBalance[owner] > 0,
            "Nothing to withdraw"
        );
        _ownerToStakedBaseBalance[owner] -= baseAmount;
        _ownerToStakedTranscendentBalance[owner] -= transcendentAmount;

        address beneficiary = _ownerToBeneficiary[owner];
        uint256 totalStakePointLoss;
        totalStakePointLoss += _calculateStakePoints(
            baseAmount,
            BASE_MULTIPLIER
        );
        totalStakePointLoss += _calculateStakePoints(
            transcendentAmount,
            TRANSCENDENT_MULTIPLIER
        );

        uint256 earned = totalStakePointLoss * famePerStakePoint;

        _removeStakePoints(beneficiary, totalStakePointLoss);
        _alphaFameVault[beneficiary] += earned;

        uint256[] memory ids = new uint256[](2);
        ids[0] = BASE_ID;
        ids[1] = TRANSCENDENT_ID;
        uint256[] memory amounts = new uint256[](2);
        amounts[0] = baseAmount;
        amounts[1] = transcendentAmount;

        IAssets(getContractAddress(2)).safeBatchTransferFrom(
            address(this),
            owner,
            ids,
            amounts,
            "0x0"
        );

        emit Withdrawn(owner, baseAmount, transcendentAmount);
    }

    /**
        @dev Get the data hash required for the meta transaction comparison for the withdraw executions.
        @param nonce        Each sent meta transaction includes a nonce to prevent that a signed transaction is executed multiple times
        @param maxTimestamp The maximum point in time before the meta transaction expired, thus becoming invalid
        @return             The keccak256 hash of the data input
    */
    function _getWithdrawAllDataHash(
        uint256 baseAmount,
        uint256 transcendentAmount,
        uint256 nonce,
        uint256 maxTimestamp
    ) private view returns (bytes32) {
        return
            keccak256(
                abi.encodePacked(
                    address(this),
                    baseAmount,
                    transcendentAmount,
                    nonce,
                    maxTimestamp
                )
            );
    }

    /**
        @dev    Set a new value for the weekly reward.
        Reverts if value is smaller than 1e18 (as decimals). It also updated the `alphaFamePerBlock` value.
        Emits WeeklyRewardUpdated(value).
        @param  value new weekly reward value
    */
    function _setWeeklyReward(uint256 value) private {
        require(
            value == 0 || value >= DECIMALS,
            "AlphaFame requires 18 decimals"
        );

        weeklyReward = value;
        _updateAlphaFamePerBlock();

        emit WeeklyRewardUpdated(value);
    }

    /**
        @dev    Set a new millisecond value for the block time. It also updated the `alphaFamePerBlock` value.
        Reverts if block time is set to 0.
        Emits BlockTimeUpdated(milliseconds).
        @param  milliseconds new millisecond value
    */
    function _setBlockTime(uint256 milliseconds) private {
        require(milliseconds != 0, "BlockTime should not be 0");

        msBlockTime = milliseconds;
        _updateAlphaFamePerBlock();

        emit BlockTimeUpdated(milliseconds);
    }

    /**
        @dev    Updates the alpha fame per block reward: Weekly Reward / (milliseconds per week / block time in milliseconds).
        Reverts if block time is set to 0.
        Emits FamePerBlockUpdated(famePerBlock).
    */
    function _updateAlphaFamePerBlock() private {
        uint256 blocksPerWeek = MS_PER_WEEK / msBlockTime;
        famePerBlock = weeklyReward / blocksPerWeek;

        emit FamePerBlockUpdated(famePerBlock);
    }

    /**
        @dev    Updates the values required for calculating the rewarded alpha fame on each smart contract interaction.
        Updates famePerStakePoint and lastUpdateBlock.
        Emits FameRewarded(rewards, _totalAlphaFameRewarded) where rewards are the alpha fame distributed since the last update.
    */
    function _updateAlphaFameRewards() private {
        uint256 previousFamePerStakePoint = famePerStakePoint;
        famePerStakePoint = calculatedAlphaFamePerStakePoint();
        lastUpdateBlock = block.number;

        uint256 rewards =
            (famePerStakePoint - previousFamePerStakePoint) *
                _stakePointsTotalSupply;
        _totalAlphaFameRewarded += rewards;

        emit FameRewarded(rewards, _totalAlphaFameRewarded);
    }

    /**
        @dev Checks if the msg.sender is the AlphaFameManager.
        Reverts if msg.sender is not the AlphaFameManager.
    */
    function _isAuthorizedAlphaFameManager() private view {
        require(
            getContractAddress(7) == msg.sender,
            "Unauthorized call. Thanks for supporting the network with your ETH."
        );
    }

    /**
        @dev Checks if the msg.sender is the Assets contract.
        Reverts if msg.sender is not the Assets contract.
    */
    function _isAuthorizedAssets() private view {
        require(
            getContractAddress(2) == msg.sender,
            "Unauthorized call. Thanks for supporting the network with your ETH."
        );
    }

    /**
        @dev Checks if crates are sent without any decimal value.
        Reverts if base or transcendent crate are not ganzzahlig.
    */
    function _isGanzzahlig(uint256 baseAmount, uint256 transcendentAmount)
        private
        pure
    {
        require(
            (baseAmount + transcendentAmount) % DECIMALS == 0,
            "Keine halben Sachen"
        );
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"registryAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[],"name":"Activated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"milliseconds","type":"uint256"}],"name":"BlockTimeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"famePerBlock","type":"uint256"}],"name":"FamePerBlockUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"rewards","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalAlphaFameRewarded","type":"uint256"}],"name":"FameRewarded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FameSpent","type":"event"},{"anonymous":false,"inputs":[],"name":"Inactivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakePointsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakePointsRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"baseAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"transcendentAmount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"WeeklyRewardUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"baseAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"transcendentAmount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[],"name":"BASE_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BASE_MULTIPLIER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MS_PER_WEEK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TRANSCENDENT_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TRANSCENDENT_MULTIPLIER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"calculatedAlphaFameBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calculatedAlphaFamePerStakePoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"famePerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"famePerStakePoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"getAlphaFameDebit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"getAlphaFameVault","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"getBeneficiary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBlockTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"key","type":"uint256"}],"name":"getContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFamePerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastUpdateBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"getMetaNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRegistryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"getStakePointsBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakePointsTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"getStakedBaseBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"getStakedTranscendentBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalAlphaFameRewarded","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalAlphaFameSpent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWeeklyReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdateBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"uint256","name":"baseAmount","type":"uint256"},{"internalType":"uint256","name":"transcendentAmount","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"maxTimestamp","type":"uint256"}],"name":"metaWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"msBlockTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_values","type":"uint256[]"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"setActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"milliseconds","type":"uint256"}],"name":"setBlockTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setInactive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"registryAddress","type":"address"}],"name":"setRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setWeeklyReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"spendAlphaFame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weeklyReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"baseAmount","type":"uint256"},{"internalType":"uint256","name":"transcendentAmount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526108346003553480156200001757600080fd5b506040516200278e3803806200278e8339810160408190526200003a9162000235565b806200004d6301ffc9a760e01b620000bd565b60018054610100600160a81b0319166101006001600160a01b038416021790556200007f6389edd2db60e01b620000bd565b5060016002556200009261083462000142565b620000a463acc1025960e01b620000bd565b620000b6630271189760e51b620000bd565b5062000286565b6001600160e01b031980821614156200011d5760405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e746572666163652069640000000060448201526064015b60405180910390fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b80620001915760405162461bcd60e51b815260206004820152601960248201527f426c6f636b54696d652073686f756c64206e6f74206265203000000000000000604482015260640162000114565b6003819055620001a0620001d7565b6040518181527f2bac24e4488fbefff44a23f5b8da63de6b144ddf04752c40a30a7176eb909f7b906020015b60405180910390a150565b600060035463240c8400620001ed919062000265565b905080600454620001ff919062000265565b60058190556040519081527f61abe4ef940312781105af1e8ac8488773fb249cee9f87f01a64e99310adf56790602001620001cc565b60006020828403121562000247578081fd5b81516001600160a01b03811681146200025e578182fd5b9392505050565b6000826200028157634e487b7160e01b81526012600452602481fd5b500490565b6124f880620002966000396000f3fe608060405234801561001057600080fd5b50600436106102de5760003560e01c80638cea71e811610186578063d6cc81fb116100e3578063f1b9ee2411610097578063f6aaf75611610071578063f6aaf75614610610578063fba7cc7914610618578063fca73f2814610623576102de565b8063f1b9ee24146105de578063f21de1e8146105e6578063f23a6e61146105fd576102de565b8063dae764a6116100c8578063dae764a6146105bf578063de174c6b146105ca578063eee39264146105d3576102de565b8063d6cc81fb146105a3578063da0adedf146105b6576102de565b8063aefa7d981161013a578063b403eeb21161011f578063b403eeb21461054e578063bc197c8114610557578063cab4f18e1461059b576102de565b8063aefa7d9814610533578063b39ac46014610546576102de565b8063a218141b1161016b578063a218141b1461050f578063a2b4439314610518578063a91ee0dc14610520576102de565b80638cea71e8146104d3578063a214661e146104e6576102de565b8063441a3e701161023f578063704c30c4116101f35780638017ec35116101cd5780638017ec35146104b0578063853828b6146104c357806387ceff09146104cb576102de565b8063704c30c41461046c578063758b1ce314610495578063760a8c2a146104a8576102de565b80635a647155116102245780635a6471551461040f578063642ad223146104385780636cc4e84014610443576102de565b8063441a3e70146103b8578063505a1b31146103cb576102de565b80632c904d7c1161029657806338b31c191161027b57806338b31c191461037f578063393a9fae146103875780633d2d51de146103b0576102de565b80632c904d7c146103475780632e0f262514610370576102de565b806307e2ee0f116102c757806307e2ee0f14610320578063175cca061461033657806318d58f721461033e576102de565b806301ffc9a7146102e3578063060b9a4f1461030b575b600080fd5b6102f66102f13660046121c7565b61062b565b60405190151581526020015b60405180910390f35b61031e610319366004612207565b610666565b005b6103286108f5565b604051908152602001610302565b600554610328565b61032860055481565b61032861035536600461200f565b6001600160a01b031660009081526008602052604090205490565b610328670de0b6b3a764000081565b600d54610328565b61032861039536600461200f565b6001600160a01b031660009081526010602052604090205490565b6103286108fc565b61031e6103c63660046122fe565b61094b565b6103f76103d936600461200f565b6001600160a01b039081166000908152600a60205260409020541690565b6040516001600160a01b039091168152602001610302565b61032861041d36600461200f565b6001600160a01b031660009081526011602052604090205490565b610328600160811b81565b61032861045136600461200f565b6001600160a01b03166000908152600c602052604090205490565b61032861047a36600461200f565b6001600160a01b03166000908152600f602052604090205490565b61031e6104a33660046122e6565b610962565b61031e61097e565b6103286104be36600461200f565b6109bd565b61031e610a26565b600354610328565b61031e6104e13660046122e6565b610a57565b6103286104f436600461200f565b6001600160a01b031660009081526009602052604090205490565b61032860065481565b610328600181565b61031e61052e36600461200f565b610a70565b6103f76105413660046122e6565b610c55565b600e54610328565b61032860035481565b61056a610565366004612047565b610ceb565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610302565b610328600281565b61031e6105b136600461217c565b610d7b565b61032860045481565b610328600160801b81565b61032860075481565b61032863240c840081565b61031e610ebc565b6103f760015461010090046001600160a01b031690565b61056a61060b366004612102565b610ef9565b600b54610328565b60015460ff166102f6565b600454610328565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020819052604090205460ff165b919050565b61066e610f2f565b604080517fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660208083019190915260348201879052605482018690526074820185905260948083018590528351808403909101815260b4830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000060d484015260f08084018290528451808503909101815261011090930190935281519101206000906107279089610f85565b9050806001600160a01b0316876001600160a01b0316146107b55760405162461bcd60e51b815260206004820152602e60248201527f5265636f7665726564207075626c6963206b657920646f6573206e6f74206d6160448201527f74636820746865207369676e657200000000000000000000000000000000000060648201526084015b60405180910390fd5b82421061082a5760405162461bcd60e51b815260206004820152602560248201527f54686973207472616e73616374696f6e206973206e6f742076616c696420616e60448201527f796d6f726500000000000000000000000000000000000000000000000000000060648201526084016107ac565b6001600160a01b03871660009081526011602052604090205484146108b75760405162461bcd60e51b815260206004820152602560248201527f54686973207472616e73616374696f6e2077617320657865637574656420616c60448201527f726561647900000000000000000000000000000000000000000000000000000060648201526084016107ac565b6001600160a01b03871660009081526011602052604081208054916108db8361243c565b91905055506108eb878787611000565b5050505050505050565b6006545b90565b6000600b546000141561091257506007546108f9565b600b546005546006546109259043612425565b61092f9190612406565b61093991906123f2565b60075461094691906123da565b905090565b610953610f2f565b61095e338383611000565b5050565b61096a6113a5565b610972611452565b61097b816114db565b50565b61098661156c565b6001805460ff1916811790556040517fed1cd0670ee0c0017f550451a038818c696d0b6a9d6ce5b369e44275573cf9b090600090a1565b6001600160a01b038116600090815260106020908152604080832054600f9092528220546109e96108fc565b6001600160a01b0385166000908152600c6020526040902054610a0c9190612406565b610a1691906123da565b610a209190612425565b92915050565b610a2e610f2f565b33600081815260086020908152604080832054600990925290912054610a55929190611000565b565b610a5f6113a5565b610a67611452565b61097b816115f0565b610a7861168e565b600180547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101006001600160a01b03841602179055610ac660015461010090046001600160a01b031690565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f60e56d110000000000000000000000000000000000000000000000000000000060048201526001600160a01b0391909116906301ffc9a79060240160206040518083038186803b158015610b4057600080fd5b505afa925050508015610b70575060408051601f3d908101601f19168201909252610b6d918101906121a7565b60015b610be25760405162461bcd60e51b815260206004820152603f60248201527f5468652070726f766964656420636f6e747261637420646f6573206e6f74206960448201527f6d706c656d656e742074686520526567697374727920696e746572666163650060648201526084016107ac565b8061095e5760405162461bcd60e51b815260206004820152603f60248201527f5468652070726f766964656420636f6e747261637420646f6573206e6f74206960448201527f6d706c656d656e742074686520526567697374727920696e746572666163650060648201526084016107ac565b6000610c6e60015461010090046001600160a01b031690565b6001600160a01b0316639507d39a836040518263ffffffff1660e01b8152600401610c9b91815260200190565b60206040518083038186803b158015610cb357600080fd5b505afa158015610cc7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a20919061202b565b6000610cf5611698565b610cfd611452565b600083838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050506014810151909150610d4b8a8a8a8a8a866116a3565b507fbc197c81000000000000000000000000000000000000000000000000000000009a9950505050505050505050565b610d836113a5565b610d8b611452565b60008111610ddb5760405162461bcd60e51b815260206004820152601760248201527f5a65726f20616d6f756e74206e6f7420616c6c6f77656400000000000000000060448201526064016107ac565b80610de5836109bd565b1015610e335760405162461bcd60e51b815260206004820152600f60248201527f4e6f7420656e6f7567682046616d65000000000000000000000000000000000060448201526064016107ac565b6001600160a01b03821660009081526010602052604081208054839290610e5b9084906123da565b9250508190555080600e6000828254610e7491906123da565b90915550506040518181526001600160a01b038316907f2f94a9bc562bc15e0c0bf27cdb43ff6bc4f8bda8358e92be8932e0e74d522351906020015b60405180910390a25050565b610ec461156c565b6001805460ff191690556040517f83b03c3d41b5de9902c98822951ff375666c0cd7fd69f8993c0267ad087734d190600090a1565b6000610f03610f2f565b507fba9154e0baa69c78e0ca563b867df81bae9d177c4ea1452c35c84386a70f0f7a9695505050505050565b6001805460ff16151514610a555760405162461bcd60e51b815260206004820152601a60248201527f54686520636f6e7472616374206973206e6f742061637469766500000000000060448201526064016107ac565b60008151604114610fd85760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016107ac565b60208201516040830151606084015160001a610ff686828585611be7565b9695505050505050565b611008611452565b60028054141561105a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107ac565b600280556110688282611d90565b6001600160a01b0383166000908152600860205260409020541515806110a557506001600160a01b03831660009081526009602052604090205415155b6110f15760405162461bcd60e51b815260206004820152601360248201527f4e6f7468696e6720746f2077697468647261770000000000000000000000000060448201526064016107ac565b6001600160a01b03831660009081526008602052604081208054849290611119908490612425565b90915550506001600160a01b03831660009081526009602052604081208054839290611146908490612425565b90915550506001600160a01b038084166000908152600a602052604081205490911690611174846001611dfa565b61117e90826123da565b905061118b836002611dfa565b61119590826123da565b90506000600754826111a79190612406565b90506111b38383611e20565b6001600160a01b0383166000908152600f6020526040812080548392906111db9084906123da565b9091555050604080516002808252606082018352600092602083019080368337019050509050600160801b8160008151811061122757634e487b7160e01b600052603260045260246000fd5b602002602001018181525050600160811b8160018151811061125957634e487b7160e01b600052603260045260246000fd5b60209081029190910101526040805160028082526060820190925260009181602001602082028036833701905050905086816000815181106112ab57634e487b7160e01b600052603260045260246000fd5b60200260200101818152505085816001815181106112d957634e487b7160e01b600052603260045260246000fd5b6020026020010181815250506112ef6002610c55565b6001600160a01b0316632eb2c2d6308a85856040518563ffffffff1660e01b81526004016113209493929190612359565b600060405180830381600087803b15801561133a57600080fd5b505af115801561134e573d6000803e3d6000fd5b5050604080518a8152602081018a90526001600160a01b038c1693507f92ccf450a286a957af52509bc1c9939d1a6a481783e142e41e2499f0bb66ebc692500160405180910390a250506001600255505050505050565b336113b06007610c55565b6001600160a01b031614610a555760405162461bcd60e51b815260206004820152604360248201527f556e617574686f72697a65642063616c6c2e205468616e6b7320666f7220737560448201527f70706f7274696e6720746865206e6574776f726b207769746820796f7572204560648201527f54482e0000000000000000000000000000000000000000000000000000000000608482015260a4016107ac565b60075461145d6108fc565b600781905543600655600b54600091611477908490612425565b6114819190612406565b905080600d600082825461149591906123da565b9091555050600d546040805183815260208101929092527f613f6f78a7f7a0f662d045455a4d367e39e337c527ba2c884bf187bf5f0ea75f910160405180910390a15050565b806115285760405162461bcd60e51b815260206004820152601960248201527f426c6f636b54696d652073686f756c64206e6f7420626520300000000000000060448201526064016107ac565b6003819055611535611ea1565b6040518181527f2bac24e4488fbefff44a23f5b8da63de6b144ddf04752c40a30a7176eb909f7b906020015b60405180910390a150565b60015461010090046001600160a01b03163314806115a4575061158f6001610c55565b6001600160a01b0316336001600160a01b0316145b610a555760405162461bcd60e51b815260206004820152601160248201527f556e617574686f72697a65642063616c6c00000000000000000000000000000060448201526064016107ac565b8015806116055750670de0b6b3a76400008110155b6116515760405162461bcd60e51b815260206004820152601e60248201527f416c70686146616d6520726571756972657320313820646563696d616c73000060448201526064016107ac565b600481905561165e611ea1565b6040518181527f82e847c349f40395e8b4bc5726500d9bb3afd01de8f4b5550b771fd248b8c6ff90602001611561565b61158f6001610c55565b336113b06002610c55565b6002805414156116f55760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107ac565b600280556001600160a01b038681166000908152600a60205260409020548116908216148061175b57506001600160a01b03861660009081526008602052604090205415801561175b57506001600160a01b038616600090815260096020526040902054155b6117cd5760405162461bcd60e51b815260206004820152603060248201527f596f7520617265206e6f7420616c6c6f77656420746f2062656e65666974206160448201527f206e657720536f53206163636f756e740000000000000000000000000000000060648201526084016107ac565b6001600160a01b0381166118235760405162461bcd60e51b815260206004820152601660248201527f42656e6566696369617279206973206e6f74207365740000000000000000000060448201526064016107ac565b6001600160a01b038681166000908152600a6020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001692841692909217909155805b838110156118b85784848281811061189457634e487b7160e01b600052603260045260246000fd5b90506020020135826118a691906123da565b91506118b18161243c565b905061186c565b50600081116119095760405162461bcd60e51b815260206004820152600e60248201527f43616e6e6f74207374616b65203000000000000000000000000000000000000060448201526064016107ac565b60008080805b88811015611aa257600160801b8a8a8381811061193c57634e487b7160e01b600052603260045260246000fd5b9050602002013514806119785750600160811b8a8a8381811061196f57634e487b7160e01b600052603260045260246000fd5b90506020020135145b6119c45760405162461bcd60e51b815260206004820152601360248201527f4173736574206e6f7420737570706f727465640000000000000000000000000060448201526064016107ac565b600160801b8a8a838181106119e957634e487b7160e01b600052603260045260246000fd5b905060200201351415611a2b57878782818110611a1657634e487b7160e01b600052603260045260246000fd5b9050602002013583611a2891906123da565b92505b600160811b8a8a83818110611a5057634e487b7160e01b600052603260045260246000fd5b905060200201351415611a9257878782818110611a7d57634e487b7160e01b600052603260045260246000fd5b9050602002013582611a8f91906123da565b91505b611a9b8161243c565b905061190f565b50611aad8282611d90565b6001600160a01b038a1660009081526008602052604081208054849290611ad59084906123da565b90915550611ae69050826001611dfa565b611af090846123da565b6001600160a01b038b16600090815260096020526040812080549295508392909190611b1d9084906123da565b90915550611b2e9050816002611dfa565b611b3890846123da565b925060075483611b489190612406565b6001600160a01b03861660009081526010602052604081208054909190611b709084906123da565b90915550611b8090508584611efa565b846001600160a01b03168a6001600160a01b03167f6c86f3fd5118b3aa8bb4f389a617046de0a3d3d477de1a1673d227f802f616dc8484604051611bce929190918252602082015260400190565b60405180910390a3505060016002555050505050505050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115611c645760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016107ac565b8360ff16601b1480611c7957508360ff16601c145b611cd05760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016107ac565b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa158015611d24573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611d875760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016107ac565b95945050505050565b670de0b6b3a7640000611da382846123da565b611dad9190612457565b1561095e5760405162461bcd60e51b815260206004820152601360248201527f4b65696e652068616c62656e2053616368656e0000000000000000000000000060448201526064016107ac565b600081611e0f670de0b6b3a7640000856123f2565b611e199190612406565b9392505050565b6001600160a01b0382166000908152600c602052604081208054839290611e48908490612425565b9250508190555080600b6000828254611e619190612425565b90915550506040518181526001600160a01b038316907f207ea6816becf95cf3c29160ef868bb47e23badff8ade2ea3ccc55cdff37f9a290602001610eb0565b600060035463240c8400611eb591906123f2565b905080600454611ec591906123f2565b60058190556040519081527f61abe4ef940312781105af1e8ac8488773fb249cee9f87f01a64e99310adf56790602001611561565b6001600160a01b0382166000908152600c602052604081208054839290611f229084906123da565b9250508190555080600b6000828254611f3b91906123da565b90915550506040518181526001600160a01b038316907fca594b3e98cbc2da82c7a8f882c3287880abbeb3573b3d2611fb3f781084ecea90602001610eb0565b8035610661816124ad565b60008083601f840112611f97578081fd5b50813567ffffffffffffffff811115611fae578182fd5b6020830191508360208083028501011115611fc857600080fd5b9250929050565b60008083601f840112611fe0578182fd5b50813567ffffffffffffffff811115611ff7578182fd5b602083019150836020828501011115611fc857600080fd5b600060208284031215612020578081fd5b8135611e19816124ad565b60006020828403121561203c578081fd5b8151611e19816124ad565b60008060008060008060008060a0898b031215612062578384fd5b883561206d816124ad565b9750602089013561207d816124ad565b9650604089013567ffffffffffffffff80821115612099578586fd5b6120a58c838d01611f86565b909850965060608b01359150808211156120bd578586fd5b6120c98c838d01611f86565b909650945060808b01359150808211156120e1578384fd5b506120ee8b828c01611fcf565b999c989b5096995094979396929594505050565b60008060008060008060a0878903121561211a578182fd5b8635612125816124ad565b95506020870135612135816124ad565b94506040870135935060608701359250608087013567ffffffffffffffff81111561215e578283fd5b61216a89828a01611fcf565b979a9699509497509295939492505050565b6000806040838503121561218e578182fd5b8235612199816124ad565b946020939093013593505050565b6000602082840312156121b8578081fd5b81518015158114611e19578182fd5b6000602082840312156121d8578081fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611e19578182fd5b60008060008060008060c0878903121561221f578182fd5b863567ffffffffffffffff80821115612236578384fd5b818901915089601f830112612249578384fd5b81358181111561225b5761225b612497565b604051601f8201601f19908116603f0116810190838211818310171561228357612283612497565b816040528281528c602084870101111561229b578687fd5b826020860160208301378660208483010152809a5050505050506122c160208801611f7b565b95989597505050506040840135936060810135936080820135935060a0909101359150565b6000602082840312156122f7578081fd5b5035919050565b60008060408385031215612310578182fd5b50508035926020909101359150565b6000815180845260208085019450808401835b8381101561234e57815187529582019590820190600101612332565b509495945050505050565b60006001600160a01b03808716835280861660208401525060a0604083015261238560a083018561231f565b8281036060840152612397818561231f565b8381036080909401939093525050600381527f30783000000000000000000000000000000000000000000000000000000000006020820152604001949350505050565b600082198211156123ed576123ed61246b565b500190565b60008261240157612401612481565b500490565b60008160001904831182151516156124205761242061246b565b500290565b6000828210156124375761243761246b565b500390565b60006000198214156124505761245061246b565b5060010190565b60008261246657612466612481565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461097b57600080fdfea26469706673582212203248de7051ddb79681e58bcff9a69f30cd683744419d21556e45c01e4c8b78c064736f6c63430008020033000000000000000000000000801b308f0213445e070f0d0cc052db38c17eda51

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

000000000000000000000000801b308f0213445e070f0d0cc052db38c17eda51

-----Decoded View---------------
Arg [0] : registryAddress (address): 0x801b308f0213445e070f0d0cc052db38c17eda51

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000801b308f0213445e070f0d0cc052db38c17eda51


Deployed ByteCode Sourcemap

72377:22278:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20082:183;;;;;;:::i;:::-;;:::i;:::-;;;9178:14:1;;9171:22;9153:41;;9141:2;9126:18;20082:183:0;;;;;;;;77972:1123;;;;;;:::i;:::-;;:::i;:::-;;82015:110;;;:::i;:::-;;;18286:25:1;;;18274:2;18259:18;82015:110:0;18241:76:1;82133:104:0;82217:12;;82133:104;;74389:27;;;;;;82245:183;;;;;;:::i;:::-;-1:-1:-1;;;;;82388:32:0;82356:7;82388:32;;;:25;:32;;;;;;;82245:183;72764:39;;72799:4;72764:39;;83194:166;83329:23;;83194:166;;83685:182;;;;;;:::i;:::-;-1:-1:-1;;;;;83831:28:0;83799:7;83831:28;;;:15;:28;;;;;;;83685:182;81054:379;;;:::i;77529:199::-;;;;;;:::i;:::-;;:::i;82643:171::-;;;;;;:::i;:::-;-1:-1:-1;;;;;82780:26:0;;;82748:7;82780:26;;;:19;:26;;;;;;;;82643:171;;;;-1:-1:-1;;;;;7990:55:1;;;7972:74;;7960:2;7945:18;82643:171:0;7927:125:1;80876:170:0;;;;;;:::i;:::-;-1:-1:-1;;;;;81012:26:0;80980:7;81012:26;;;:18;:26;;;;;;;80876:170;73673:90;;-1:-1:-1;;;73673:90:0;;82996:190;;;;;;:::i;:::-;-1:-1:-1;;;;;83146:32:0;83114:7;83146:32;;;:19;:32;;;;;;;82996:190;83495:182;;;;;;:::i;:::-;-1:-1:-1;;;;;83641:28:0;83609:7;83641:28;;;:15;:28;;;;;;;83495:182;80549:205;;;;;;:::i;:::-;;:::i;28776:133::-;;;:::i;81441:346::-;;;;;;:::i;:::-;;:::i;77736:228::-;;;:::i;81795:100::-;81876:11;;81795:100;;80344:197;;;;;;:::i;:::-;;:::i;82436:199::-;;;;;;:::i;:::-;-1:-1:-1;;;;;82587:40:0;82555:7;82587:40;;;:33;:40;;;;;;;82436:199;74540:30;;;;;;73313:43;;73355:1;73313:43;;29063:615;;;;;;:::i;:::-;;:::i;30021:175::-;;;;;;:::i;:::-;;:::i;83368:119::-;83459:20;;83368:119;;74045:33;;;;;;79234:604;;;;;;:::i;:::-;;:::i;:::-;;;9782:66:1;9770:79;;;9752:98;;9740:2;9725:18;79234:604:0;9707:149:1;73116:51:0;;73166:1;73116:51;;79846:439;;;;;;:::i;:::-;;:::i;74228:27::-;;;;;;73470:73;;-1:-1:-1;;;73470:73:0;;74726:32;;;;;;72907:47;;72945:9;72907:47;;28917:138;;;:::i;29902:111::-;;29989:16;;;;;-1:-1:-1;;;;;29989:16:0;;29902:111;77207:314;;;;;;:::i;:::-;;:::i;82822:166::-;82957:23;;82822:166;;29800:94;29877:9;;;;29800:94;;81903:104;81987:12;;81903:104;;20082:183;20224:33;;;20195:4;20224:33;;;;;;;;;;;;;20082:183;;;;:::o;77972:1123::-;27792:16;:14;:16::i;:::-;90918:208;;;7184:66:1;90965:4:0;7171:2:1;7167:15;7163:88;90918:208:0;;;;7151:101:1;;;;7268:12;;;7261:28;;;7305:12;;;7298:28;;;7342:12;;;7335:28;;;7379:13;;;;7372:29;;;90918:208:0;;;;;;;;;;7417:13:1;;;90918:208:0;;90890:251;;;;;;7683:66:1;38474:58:0;;;7671:79:1;7766:12;;;;7759:28;;;38474:58:0;;;;;;;;;;7803:12:1;;;;38474:58:0;;;38446:101;;;;;-1:-1:-1;;78501:64:0::1;::::0;78555:9:::1;78501:13;:64::i;:::-;78459:106;;78608:18;-1:-1:-1::0;;;;;78598:28:0::1;:6;-1:-1:-1::0;;;;;78598:28:0::1;;78576:124;;;::::0;-1:-1:-1;;;78576:124:0;;12253:2:1;78576:124:0::1;::::0;::::1;12235:21:1::0;12292:2;12272:18;;;12265:30;12331:34;12311:18;;;12304:62;12402:16;12382:18;;;12375:44;12436:19;;78576:124:0::1;;;;;;;;;78751:12;78733:15;:30;78711:117;;;::::0;-1:-1:-1;;;78711:117:0;;15343:2:1;78711:117:0::1;::::0;::::1;15325:21:1::0;15382:2;15362:18;;;15355:30;15421:34;15401:18;;;15394:62;15492:7;15472:18;;;15465:35;15517:19;;78711:117:0::1;15315:227:1::0;78711:117:0::1;-1:-1:-1::0;;;;;78861:26:0;::::1;;::::0;;;:18:::1;:26;::::0;;;;;:35;::::1;78839:122;;;::::0;-1:-1:-1;;;78839:122:0;;13703:2:1;78839:122:0::1;::::0;::::1;13685:21:1::0;13742:2;13722:18;;;13715:30;13781:34;13761:18;;;13754:62;13852:7;13832:18;;;13825:35;13877:19;;78839:122:0::1;13675:227:1::0;78839:122:0::1;-1:-1:-1::0;;;;;78972:26:0;::::1;;::::0;;;:18:::1;:26;::::0;;;;:28;;;::::1;::::0;::::1;:::i;:::-;;;;;;79038:49;79048:6;79056:10;79068:18;79038:9;:49::i;:::-;27819:1;;77972:1123:::0;;;;;;:::o;82015:110::-;82102:15;;82015:110;;:::o;81054:379::-;81164:7;81193:23;;81220:1;81193:28;81189:85;;;-1:-1:-1;81245:17:0;;81238:24;;81189:85;81402:23;;81373:12;;81354:15;;81339:30;;:12;:30;:::i;:::-;81338:47;;;;:::i;:::-;81337:88;;;;:::i;:::-;81304:17;;:121;;;;:::i;:::-;81284:141;;81054:379;:::o;77529:199::-;27792:16;:14;:16::i;:::-;77667:53:::1;77677:10;77689;77701:18;77667:9;:53::i;:::-;77529:199:::0;;:::o;80549:205::-;76180:31;:29;:31::i;:::-;76374:25:::1;:23;:25::i;:::-;80719:27:::2;80733:12;80719:13;:27::i;:::-;80549:205:::0;:::o;28776:133::-;27974:30;:28;:30::i;:::-;28868:4:::1;28856:16:::0;;-1:-1:-1;;28856:16:0::1;::::0;::::1;::::0;;28890:11:::1;::::0;::::1;::::0;28856:9:::1;::::0;28890:11:::1;28776:133::o:0;81441:346::-;-1:-1:-1;;;;;81751:28:0;;81564:7;81751:28;;;:15;:28;;;;;;;;;81707:15;:28;;;;;;81657:34;:32;:34::i;:::-;-1:-1:-1;;;;;81609:32:0;;;;;;:19;:32;;;;;;:82;;;;:::i;:::-;:126;;;;:::i;:::-;:170;;;;:::i;:::-;81589:190;81441:346;-1:-1:-1;;81441:346:0:o;77736:228::-;27792:16;:14;:16::i;:::-;77823:10:::1;77848:37;::::0;;;:25:::1;:37;::::0;;;;;;;;77900:33:::1;:45:::0;;;;;;;77799:157:::1;::::0;77823:10;77848:37;77799:9:::1;:157::i;:::-;77736:228::o:0;80344:197::-;76180:31;:29;:31::i;:::-;76374:25:::1;:23;:25::i;:::-;80510:23:::2;80527:5;80510:16;:23::i;29063:615::-:0;27876:20;:18;:20::i;:::-;29190:16:::1;:34:::0;;;::::1;;-1:-1:-1::0;;;;;29190:34:0;::::1;;;::::0;;29254:19:::1;29989:16:::0;;;;;-1:-1:-1;;;;;29989:16:0;;29902:111;29254:19:::1;:66;::::0;;;;29292:27:::1;29254:66;::::0;::::1;9752:98:1::0;-1:-1:-1;;;;;29254:37:0;;;::::1;::::0;::::1;::::0;9725:18:1;;29254:66:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;-1:-1:-1::0;29254:66:0::1;::::0;;::::1;;::::0;;::::1;-1:-1:-1::0;;29254:66:0::1;::::0;::::1;::::0;;;::::1;::::0;;::::1;::::0;::::1;:::i;:::-;;;29237:434;;29554:105;::::0;-1:-1:-1;;;29554:105:0;;10416:2:1;29554:105:0::1;::::0;::::1;10398:21:1::0;10455:2;10435:18;;;10428:30;10494:34;10474:18;;;10467:62;10565:33;10545:18;;;10538:61;10616:19;;29554:105:0::1;10388:253:1::0;29237:434:0::1;29404:17;29378:142;;;::::0;-1:-1:-1;;;29378:142:0;;10416:2:1;29378:142:0::1;::::0;::::1;10398:21:1::0;10455:2;10435:18;;;10428:30;10494:34;10474:18;;;10467:62;10565:33;10545:18;;;10538:61;10616:19;;29378:142:0::1;10388:253:1::0;30021:175:0;30128:7;30160:19;29989:16;;;;;-1:-1:-1;;;;;29989:16:0;;29902:111;30160:19;-1:-1:-1;;;;;30160:23:0;;30184:3;30160:28;;;;;;;;;;;;;18286:25:1;;18274:2;18259:18;;18241:76;30160:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;79234:604::-;79565:6;76280:21;:19;:21::i;:::-;76374:25:::1;:23;:25::i;:::-;79589:24:::2;79616:5;;79589:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;;;;79724:2:0::2;79707:20:::0;::::2;79701:27:::0;79707:20;;-1:-1:-1;79749:41:0::2;79756:5:::0;79763:4;;79769:7;;79701:27;79749:6:::2;:41::i;:::-;-1:-1:-1::0;79808:22:0;;79234:604;-1:-1:-1;;;;;;;;;;79234:604:0:o;79846:439::-;76180:31;:29;:31::i;:::-;76374:25:::1;:23;:25::i;:::-;80043:1:::2;80034:6;:10;80026:46;;;::::0;-1:-1:-1;;;80026:46:0;;17630:2:1;80026:46:0::2;::::0;::::2;17612:21:1::0;17669:2;17649:18;;;17642:30;17708:25;17688:18;;;17681:53;17751:18;;80026:46:0::2;17602:173:1::0;80026:46:0::2;80127:6;80091:32;80118:4;80091:26;:32::i;:::-;:42;;80083:70;;;::::0;-1:-1:-1;;;80083:70:0;;13359:2:1;80083:70:0::2;::::0;::::2;13341:21:1::0;13398:2;13378:18;;;13371:30;13437:17;13417:18;;;13410:45;13472:18;;80083:70:0::2;13331:165:1::0;80083:70:0::2;-1:-1:-1::0;;;;;80164:21:0;::::2;;::::0;;;:15:::2;:21;::::0;;;;:31;;80189:6;;80164:21;:31:::2;::::0;80189:6;;80164:31:::2;:::i;:::-;;;;;;;;80230:6;80206:20;;:30;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;80254:23:0::2;::::0;18286:25:1;;;-1:-1:-1;;;;;80254:23:0;::::2;::::0;::::2;::::0;18274:2:1;18259:18;80254:23:0::2;;;;;;;;79846:439:::0;;:::o;28917:138::-;27974:30;:28;:30::i;:::-;28999:9:::1;:17:::0;;-1:-1:-1;;28999:17:0::1;::::0;;29034:13:::1;::::0;::::1;::::0;29011:5:::1;::::0;29034:13:::1;28917:138::o:0;77207:314::-;77456:6;27792:16;:14;:16::i;:::-;-1:-1:-1;77494:18:0::1;77207:314:::0;;;;;;;;:::o;30676:115::-;30735:9;;;;;:17;;;30727:56;;;;-1:-1:-1;;;30727:56:0;;14988:2:1;30727:56:0;;;14970:21:1;15027:2;15007:18;;;15000:30;15066:28;15046:18;;;15039:56;15112:18;;30727:56:0;14960:176:1;35459:793:0;35564:7;35632:9;:16;35652:2;35632:22;35628:96;;35671:41;;-1:-1:-1;;;35671:41:0;;11199:2:1;35671:41:0;;;11181:21:1;11238:2;11218:18;;;11211:30;11277:33;11257:18;;;11250:61;11328:18;;35671:41:0;11171:181:1;35628:96:0;36085:4;36070:20;;36064:27;36131:4;36116:20;;36110:27;36185:4;36170:20;;36164:27;35793:9;36156:36;36222:22;36230:4;36156:36;36064:27;36110;36222:7;:22::i;:::-;36215:29;35459:793;-1:-1:-1;;;;;;35459:793:0:o;88646:1573::-;76374:25;:23;:25::i;:::-;33089:1:::1;33685:7:::0;::::1;:19;;33677:63;;;::::0;-1:-1:-1;;;33677:63:0;;17982:2:1;33677:63:0::1;::::0;::::1;17964:21:1::0;18021:2;18001:18;;;17994:30;18060:33;18040:18;;;18033:61;18111:18;;33677:63:0::1;17954:181:1::0;33677:63:0::1;33089:1;33818:18:::0;;88821:45:::2;88835:10:::0;88847:18;88821:13:::2;:45::i;:::-;-1:-1:-1::0;;;;;88899:32:0;::::2;88934:1;88899:32:::0;;;:25:::2;:32;::::0;;;;;:36;;;:101:::2;;-1:-1:-1::0;;;;;;88956:40:0;::::2;88999:1;88956:40:::0;;;:33:::2;:40;::::0;;;;;:44;;88899:101:::2;88877:170;;;::::0;-1:-1:-1;;;88877:170:0;;11905:2:1;88877:170:0::2;::::0;::::2;11887:21:1::0;11944:2;11924:18;;;11917:30;11983:21;11963:18;;;11956:49;12022:18;;88877:170:0::2;11877:169:1::0;88877:170:0::2;-1:-1:-1::0;;;;;89058:32:0;::::2;;::::0;;;:25:::2;:32;::::0;;;;:46;;89094:10;;89058:32;:46:::2;::::0;89094:10;;89058:46:::2;:::i;:::-;::::0;;;-1:-1:-1;;;;;;;89115:40:0;::::2;;::::0;;;:33:::2;:40;::::0;;;;:62;;89159:18;;89115:40;:62:::2;::::0;89159:18;;89115:62:::2;:::i;:::-;::::0;;;-1:-1:-1;;;;;;;89212:26:0;;::::2;89190:19;89212:26:::0;;;:19:::2;:26;::::0;;;;;;;::::2;::::0;89310:87:::2;89346:10:::0;89212:26;89310:21:::2;:87::i;:::-;89287:110;::::0;;::::2;:::i;:::-;;;89431:103;89467:18;73166:1;89431:21;:103::i;:::-;89408:126;::::0;;::::2;:::i;:::-;;;89547:14;89586:17;;89564:19;:39;;;;:::i;:::-;89547:56;;89616:52;89635:11;89648:19;89616:18;:52::i;:::-;-1:-1:-1::0;;;;;89679:28:0;::::2;;::::0;;;:15:::2;:28;::::0;;;;:38;;89711:6;;89679:28;:38:::2;::::0;89711:6;;89679:38:::2;:::i;:::-;::::0;;;-1:-1:-1;;89753:16:0::2;::::0;;89767:1:::2;89753:16:::0;;;;;::::2;::::0;;89730:20:::2;::::0;89753:16:::2;::::0;::::2;::::0;;::::2;::::0;::::2;;::::0;-1:-1:-1;89753:16:0::2;89730:39;;-1:-1:-1::0;;;89780:3:0::2;89784:1;89780:6;;;;;;-1:-1:-1::0;;;89780:6:0::2;;;;;;;;;;;;;;:16;;;::::0;::::2;-1:-1:-1::0;;;89807:3:0::2;89811:1;89807:6;;;;;;-1:-1:-1::0;;;89807:6:0::2;;;;;;;;;;::::0;;::::2;::::0;;;;;:24;89869:16:::2;::::0;;89883:1:::2;89869:16:::0;;;;;::::2;::::0;;;89842:24:::2;::::0;89869:16:::2;;;;;;;;;;;::::0;-1:-1:-1;89869:16:0::2;89842:43;;89909:10;89896:7;89904:1;89896:10;;;;;;-1:-1:-1::0;;;89896:10:0::2;;;;;;;;;;;;;;:23;;;::::0;::::2;89943:18;89930:7;89938:1;89930:10;;;;;;-1:-1:-1::0;;;89930:10:0::2;;;;;;;;;;;;;;:31;;;::::0;::::2;89982:21;90001:1;89982:18;:21::i;:::-;-1:-1:-1::0;;;;;89974:52:0::2;;90049:4;90069:5;90089:3;90107:7;89974:171;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;90163:48:0::2;::::0;;18496:25:1;;;18552:2;18537:18;;18530:34;;;-1:-1:-1;;;;;90163:48:0;::::2;::::0;-1:-1:-1;90163:48:0::2;::::0;-1:-1:-1;18469:18:1;90163:48:0::2;;;;;;;-1:-1:-1::0;;33045:1:0::1;33997:7;:22:::0;-1:-1:-1;;;;;;88646:1573:0:o;93662:225::-;93774:10;93749:21;93768:1;93749:18;:21::i;:::-;-1:-1:-1;;;;;93749:35:0;;93727:152;;;;-1:-1:-1;;;93727:152:0;;14512:2:1;93727:152:0;;;14494:21:1;14551:2;14531:18;;;14524:30;14590:34;14570:18;;;14563:62;14661:34;14641:18;;;14634:62;14733:5;14712:19;;;14705:34;14756:19;;93727:152:0;14484:297:1;93049:464:0;93139:17;;93187:34;:32;:34::i;:::-;93167:17;:54;;;93250:12;93232:15;:30;93373:23;;-1:-1:-1;;93307:45:0;;93327:25;;93307:45;:::i;:::-;93306:90;;;;:::i;:::-;93275:121;;93434:7;93407:23;;:34;;;;;;;:::i;:::-;;;;-1:-1:-1;;93481:23:0;;93459:46;;;18496:25:1;;;18552:2;18537:18;;18530:34;;;;93459:46:0;;18469:18:1;93459:46:0;;;;;;;93049:464;;:::o;92002:251::-;92074:17;92066:55;;;;-1:-1:-1;;;92066:55:0;;16152:2:1;92066:55:0;;;16134:21:1;16191:2;16171:18;;;16164:30;16230:27;16210:18;;;16203:55;16275:18;;92066:55:0;16124:175:1;92066:55:0;92134:11;:26;;;92171;:24;:26::i;:::-;92215:30;;18286:25:1;;;92215:30:0;;18274:2:1;18259:18;92215:30:0;;;;;;;;92002:251;:::o;31205:226::-;31306:16;;;;;-1:-1:-1;;;;;31306:16:0;31292:10;:30;;:86;;;31357:21;31376:1;31357:18;:21::i;:::-;-1:-1:-1;;;;;31343:35:0;:10;-1:-1:-1;;;;;31343:35:0;;31292:86;31270:153;;;;-1:-1:-1;;;31270:153:0;;11559:2:1;31270:153:0;;;11541:21:1;11598:2;11578:18;;;11571:30;11637:19;11617:18;;;11610:47;11674:18;;31270:153:0;11531:167:1;91429:293:0;91511:10;;;:31;;;72799:4;91525:5;:17;;91511:31;91489:111;;;;-1:-1:-1;;;91489:111:0;;16506:2:1;91489:111:0;;;16488:21:1;16545:2;16525:18;;;16518:30;16584:32;16564:18;;;16557:60;16634:18;;91489:111:0;16478:180:1;91489:111:0;91613:12;:20;;;91644:26;:24;:26::i;:::-;91688;;18286:25:1;;;91688:26:0;;18274:2:1;18259:18;91688:26:0;18241:76:1;30918:128:0;30995:21;31014:1;30995:18;:21::i;94034:215::-;94136:10;94111:21;94130:1;94111:18;:21::i;84766:2013::-;33089:1;33685:7;;:19;;33677:63;;;;-1:-1:-1;;;33677:63:0;;17982:2:1;33677:63:0;;;17964:21:1;18021:2;18001:18;;;17994:30;18060:33;18040:18;;;18033:61;18111:18;;33677:63:0;17954:181:1;33677:63:0;33089:1;33818:18;;-1:-1:-1;;;;;84973:25:0;;::::1;;::::0;;;:19:::1;:25;::::0;;;;;;::::1;:40:::0;;::::1;;::::0;:168:::1;;-1:-1:-1::0;;;;;;85035:31:0;::::1;;::::0;;;:25:::1;:31;::::0;;;;;:36;:105;::::1;;;-1:-1:-1::0;;;;;;85096:39:0;::::1;;::::0;;;:33:::1;:39;::::0;;;;;:44;85035:105:::1;84951:266;;;::::0;-1:-1:-1;;;84951:266:0;;16865:2:1;84951:266:0::1;::::0;::::1;16847:21:1::0;16904:2;16884:18;;;16877:30;16943:34;16923:18;;;16916:62;17014:18;16994;;;16987:46;17050:19;;84951:266:0::1;16837:238:1::0;84951:266:0::1;-1:-1:-1::0;;;;;85236:25:0;::::1;85228:60;;;::::0;-1:-1:-1;;;85228:60:0;;10848:2:1;85228:60:0::1;::::0;::::1;10830:21:1::0;10887:2;10867:18;;;10860:30;10926:24;10906:18;;;10899:52;10968:18;;85228:60:0::1;10820:172:1::0;85228:60:0::1;-1:-1:-1::0;;;;;85299:25:0;;::::1;;::::0;;;:19:::1;:25;::::0;;;;:39;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;:25;85381:97:::1;85401:18:::0;;::::1;85381:97;;;85456:7;;85464:1;85456:10;;;;;-1:-1:-1::0;;;85456:10:0::1;;;;;;;;;;;;;;;85441:25;;;;;:::i;:::-;::::0;-1:-1:-1;85421:3:0::1;::::0;::::1;:::i;:::-;;;85381:97;;;;85510:1;85496:11;:15;85488:42;;;::::0;-1:-1:-1;;;85488:42:0;;12668:2:1;85488:42:0::1;::::0;::::1;12650:21:1::0;12707:2;12687:18;;;12680:30;12746:16;12726:18;;;12719:44;12780:18;;85488:42:0::1;12640:164:1::0;85488:42:0::1;85543:29;::::0;;;85649:428:::1;85669:19:::0;;::::1;85649:428;;;-1:-1:-1::0;;;85736:8:0::1;;85745:1;85736:11;;;;;-1:-1:-1::0;;;85736:11:0::1;;;;;;;;;;;;;;;:22;:56;;;;-1:-1:-1::0;;;85762:8:0::1;;85771:1;85762:11;;;;;-1:-1:-1::0;;;85762:11:0::1;;;;;;;;;;;;;;;:30;85736:56;85710:137;;;::::0;-1:-1:-1;;;85710:137:0;;13011:2:1;85710:137:0::1;::::0;::::1;12993:21:1::0;13050:2;13030:18;;;13023:30;13089:21;13069:18;;;13062:49;13128:18;;85710:137:0::1;12983:169:1::0;85710:137:0::1;-1:-1:-1::0;;;85866:8:0::1;;85875:1;85866:11;;;;;-1:-1:-1::0;;;85866:11:0::1;;;;;;;;;;;;;;;:22;85862:87;;;85923:7;;85931:1;85923:10;;;;;-1:-1:-1::0;;;85923:10:0::1;;;;;;;;;;;;;;;85909:24;;;;;:::i;:::-;;;85862:87;-1:-1:-1::0;;;85967:8:0::1;;85976:1;85967:11;;;;;-1:-1:-1::0;;;85967:11:0::1;;;;;;;;;;;;;;;:30;85963:103;;;86040:7;;86048:1;86040:10;;;;;-1:-1:-1::0;;;86040:10:0::1;;;;;;;;;;;;;;;86018:32;;;;;:::i;:::-;;;85963:103;85690:3;::::0;::::1;:::i;:::-;;;85649:428;;;;86087:45;86101:10;86113:18;86087:13;:45::i;:::-;-1:-1:-1::0;;;;;86145:31:0;::::1;;::::0;;;:25:::1;:31;::::0;;;;:45;;86180:10;;86145:31;:45:::1;::::0;86180:10;;86145:45:::1;:::i;:::-;::::0;;;-1:-1:-1;86226:87:0::1;::::0;-1:-1:-1;86262:10:0;73355:1:::1;86226:21;:87::i;:::-;86201:112;::::0;;::::1;:::i;:::-;-1:-1:-1::0;;;;;86324:39:0;::::1;;::::0;;;:33:::1;:39;::::0;;;;:61;;86201:112;;-1:-1:-1;86367:18:0;;86324:39;;;:61:::1;::::0;86367:18;;86324:61:::1;:::i;:::-;::::0;;;-1:-1:-1;86421:103:0::1;::::0;-1:-1:-1;86457:18:0;73166:1:::1;86421:21;:103::i;:::-;86396:128;::::0;;::::1;:::i;:::-;;;86617:17;;86580:21;:54;;;;:::i;:::-;-1:-1:-1::0;;;;;86535:28:0;::::1;;::::0;;;:15:::1;:28;::::0;;;;:99;;:28;;;:99:::1;::::0;;;::::1;:::i;:::-;::::0;;;-1:-1:-1;86645:51:0::1;::::0;-1:-1:-1;86661:11:0;86674:21;86645:15:::1;:51::i;:::-;86727:11;-1:-1:-1::0;;;;;86714:57:0::1;86721:4;-1:-1:-1::0;;;;;86714:57:0::1;;86740:10;86752:18;86714:57;;;;;;18496:25:1::0;;;18552:2;18537:18;;18530:34;18484:2;18469:18;;18451:119;86714:57:0::1;;;;;;;;-1:-1:-1::0;;33045:1:0;33997:7;:22;-1:-1:-1;;;;;;;;84766:2013:0:o;36406:1529::-;36534:7;37490:66;37459:97;;;37437:181;;;;-1:-1:-1;;;37437:181:0;;14109:2:1;37437:181:0;;;14091:21:1;14148:2;14128:18;;;14121:30;14187:34;14167:18;;;14160:62;-1:-1:-1;;;14238:18:1;;;14231:32;14280:19;;37437:181:0;14081:224:1;37437:181:0;37637:1;:7;;37642:2;37637:7;:18;;;;37648:1;:7;;37653:2;37648:7;37637:18;37629:65;;;;-1:-1:-1;;;37629:65:0;;15749:2:1;37629:65:0;;;15731:21:1;15788:2;15768:18;;;15761:30;15827:34;15807:18;;;15800:62;-1:-1:-1;;;15878:18:1;;;15871:32;15920:19;;37629:65:0;15721:224:1;37629:65:0;37809:24;;;37792:14;37809:24;;;;;;;;;9432:25:1;;;9505:4;9493:17;;9473:18;;;9466:45;;;;9527:18;;;9520:34;;;9570:18;;;9563:34;;;37809:24:0;;9404:19:1;;37809:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;37809:24:0;;-1:-1:-1;;37809:24:0;;;-1:-1:-1;;;;;;;37852:20:0;;37844:57;;;;-1:-1:-1;;;37844:57:0;;10063:2:1;37844:57:0;;;10045:21:1;10102:2;10082:18;;;10075:30;10141:26;10121:18;;;10114:54;10185:18;;37844:57:0;10035:174:1;37844:57:0;37921:6;36406:1529;-1:-1:-1;;;;;36406:1529:0:o;94408:244::-;72799:4;94549:31;94562:18;94549:10;:31;:::i;:::-;94548:44;;;;:::i;:::-;:49;94526:118;;;;-1:-1:-1;;;94526:118:0;;17282:2:1;94526:118:0;;;17264:21:1;17321:2;17301:18;;;17294:30;17360:21;17340:18;;;17333:49;17399:18;;94526:118:0;17254:169:1;87079:206:0;87204:7;87262:15;87237:21;72799:4;87237:10;:21;:::i;:::-;87236:41;;;;:::i;:::-;87229:48;87079:206;-1:-1:-1;;;87079:206:0:o;88027:231::-;-1:-1:-1;;;;;88110:32:0;;;;;;:19;:32;;;;;:41;;88146:5;;88110:32;:41;;88146:5;;88110:41;:::i;:::-;;;;;;;;88189:5;88162:23;;:32;;;;;;;:::i;:::-;;;;-1:-1:-1;;88212:38:0;;18286:25:1;;;-1:-1:-1;;;;;88212:38:0;;;;;18274:2:1;18259:18;88212:38:0;18241:76:1;92500:217:0;92555:21;92593:11;;72945:9;92579:25;;;;:::i;:::-;92555:49;;92645:13;92630:12;;:28;;;;:::i;:::-;92615:12;:43;;;92676:33;;18286:25:1;;;92676:33:0;;18274:2:1;18259:18;92676:33:0;18241:76:1;87543:226:0;-1:-1:-1;;;;;87623:32:0;;;;;;:19;:32;;;;;:41;;87659:5;;87623:32;:41;;87659:5;;87623:41;:::i;:::-;;;;;;;;87702:5;87675:23;;:32;;;;;;;:::i;:::-;;;;-1:-1:-1;;87725:36:0;;18286:25:1;;;-1:-1:-1;;;;;87725:36:0;;;;;18274:2:1;18259:18;87725:36:0;18241:76:1;14:134;82:20;;111:31;82:20;111:31;:::i;153:394::-;;;280:3;273:4;265:6;261:17;257:27;247:2;;303:6;295;288:22;247:2;-1:-1:-1;331:20:1;;374:18;363:30;;360:2;;;413:8;403;396:26;360:2;457:4;449:6;445:17;433:29;;520:3;513:4;505;497:6;493:17;485:6;481:30;477:41;474:50;471:2;;;537:1;534;527:12;471:2;237:310;;;;;:::o;552:375::-;;;667:3;660:4;652:6;648:17;644:27;634:2;;692:8;682;675:26;634:2;-1:-1:-1;722:20:1;;765:18;754:30;;751:2;;;804:8;794;787:26;751:2;848:4;840:6;836:17;824:29;;900:3;893:4;884:6;876;872:19;868:30;865:39;862:2;;;917:1;914;907:12;932:257;;1044:2;1032:9;1023:7;1019:23;1015:32;1012:2;;;1065:6;1057;1050:22;1012:2;1109:9;1096:23;1128:31;1153:5;1128:31;:::i;1194:261::-;;1317:2;1305:9;1296:7;1292:23;1288:32;1285:2;;;1338:6;1330;1323:22;1285:2;1375:9;1369:16;1394:31;1419:5;1394:31;:::i;1460:1378::-;;;;;;;;;1729:3;1717:9;1708:7;1704:23;1700:33;1697:2;;;1751:6;1743;1736:22;1697:2;1795:9;1782:23;1814:31;1839:5;1814:31;:::i;:::-;1864:5;-1:-1:-1;1921:2:1;1906:18;;1893:32;1934:33;1893:32;1934:33;:::i;:::-;1986:7;-1:-1:-1;2044:2:1;2029:18;;2016:32;2067:18;2097:14;;;2094:2;;;2129:6;2121;2114:22;2094:2;2173:70;2235:7;2226:6;2215:9;2211:22;2173:70;:::i;:::-;2262:8;;-1:-1:-1;2147:96:1;-1:-1:-1;2350:2:1;2335:18;;2322:32;;-1:-1:-1;2366:16:1;;;2363:2;;;2400:6;2392;2385:22;2363:2;2444:72;2508:7;2497:8;2486:9;2482:24;2444:72;:::i;:::-;2535:8;;-1:-1:-1;2418:98:1;-1:-1:-1;2623:3:1;2608:19;;2595:33;;-1:-1:-1;2640:16:1;;;2637:2;;;2674:6;2666;2659:22;2637:2;;2718:60;2770:7;2759:8;2748:9;2744:24;2718:60;:::i;:::-;1687:1151;;;;-1:-1:-1;1687:1151:1;;-1:-1:-1;1687:1151:1;;;;;;2797:8;-1:-1:-1;;;1687:1151:1:o;2843:843::-;;;;;;;3042:3;3030:9;3021:7;3017:23;3013:33;3010:2;;;3064:6;3056;3049:22;3010:2;3108:9;3095:23;3127:31;3152:5;3127:31;:::i;:::-;3177:5;-1:-1:-1;3234:2:1;3219:18;;3206:32;3247:33;3206:32;3247:33;:::i;:::-;3299:7;-1:-1:-1;3353:2:1;3338:18;;3325:32;;-1:-1:-1;3404:2:1;3389:18;;3376:32;;-1:-1:-1;3459:3:1;3444:19;;3431:33;3487:18;3476:30;;3473:2;;;3524:6;3516;3509:22;3473:2;3568:58;3618:7;3609:6;3598:9;3594:22;3568:58;:::i;:::-;3000:686;;;;-1:-1:-1;3000:686:1;;-1:-1:-1;3000:686:1;;3645:8;;3000:686;-1:-1:-1;;;3000:686:1:o;3691:325::-;;;3820:2;3808:9;3799:7;3795:23;3791:32;3788:2;;;3841:6;3833;3826:22;3788:2;3885:9;3872:23;3904:31;3929:5;3904:31;:::i;:::-;3954:5;4006:2;3991:18;;;;3978:32;;-1:-1:-1;;;3778:238:1:o;4021:297::-;;4141:2;4129:9;4120:7;4116:23;4112:32;4109:2;;;4162:6;4154;4147:22;4109:2;4199:9;4193:16;4252:5;4245:13;4238:21;4231:5;4228:32;4218:2;;4279:6;4271;4264:22;4323:352;;4434:2;4422:9;4413:7;4409:23;4405:32;4402:2;;;4455:6;4447;4440:22;4402:2;4499:9;4486:23;4549:66;4542:5;4538:78;4531:5;4528:89;4518:2;;4636:6;4628;4621:22;4680:1325;;;;;;;4886:3;4874:9;4865:7;4861:23;4857:33;4854:2;;;4908:6;4900;4893:22;4854:2;4953:9;4940:23;4982:18;5023:2;5015:6;5012:14;5009:2;;;5044:6;5036;5029:22;5009:2;5087:6;5076:9;5072:22;5062:32;;5132:7;5125:4;5121:2;5117:13;5113:27;5103:2;;5159:6;5151;5144:22;5103:2;5200;5187:16;5222:2;5218;5215:10;5212:2;;;5228:18;;:::i;:::-;5303:2;5297:9;5271:2;5357:13;;-1:-1:-1;;5353:22:1;;;5377:2;5349:31;5345:40;5333:53;;;5401:18;;;5421:22;;;5398:46;5395:2;;;5447:18;;:::i;:::-;5487:10;5483:2;5476:22;5522:2;5514:6;5507:18;5564:7;5557:4;5552:2;5548;5544:11;5540:22;5537:35;5534:2;;;5590:6;5582;5575:22;5534:2;5655;5648:4;5644:2;5640:13;5633:4;5625:6;5621:17;5608:50;5702:6;5695:4;5690:2;5682:6;5678:15;5674:26;5667:42;5728:6;5718:16;;;;;;;5753:40;5787:4;5776:9;5772:20;5753:40;:::i;:::-;4844:1161;;5743:50;;-1:-1:-1;;;;5840:2:1;5825:18;;5812:32;;5891:2;5876:18;;5863:32;;5942:3;5927:19;;5914:33;;-1:-1:-1;5994:3:1;5979:19;;;5966:33;;-1:-1:-1;4844:1161:1:o;6010:190::-;;6122:2;6110:9;6101:7;6097:23;6093:32;6090:2;;;6143:6;6135;6128:22;6090:2;-1:-1:-1;6171:23:1;;6080:120;-1:-1:-1;6080:120:1:o;6205:258::-;;;6334:2;6322:9;6313:7;6309:23;6305:32;6302:2;;;6355:6;6347;6340:22;6302:2;-1:-1:-1;;6383:23:1;;;6453:2;6438:18;;;6425:32;;-1:-1:-1;6292:171:1:o;6468:437::-;;6559:5;6553:12;6586:6;6581:3;6574:19;6612:4;6641:2;6636:3;6632:12;6625:19;;6678:2;6671:5;6667:14;6699:3;6711:169;6725:6;6722:1;6719:13;6711:169;;;6786:13;;6774:26;;6820:12;;;;6855:15;;;;6747:1;6740:9;6711:169;;;-1:-1:-1;6896:3:1;;6529:376;-1:-1:-1;;;;;6529:376:1:o;8057:951::-;;-1:-1:-1;;;;;8543:2:1;8535:6;8531:15;8520:9;8513:34;8595:2;8587:6;8583:15;8578:2;8567:9;8563:18;8556:43;;8635:3;8630:2;8619:9;8615:18;8608:31;8662:57;8714:3;8703:9;8699:19;8691:6;8662:57;:::i;:::-;8767:9;8759:6;8755:22;8750:2;8739:9;8735:18;8728:50;8801:44;8838:6;8830;8801:44;:::i;:::-;8882:22;;;8876:3;8861:19;;;8854:51;;;;-1:-1:-1;;8929:1:1;8914:17;;8964:5;8959:2;8947:15;;8940:30;8999:2;8987:15;;8442:566;-1:-1:-1;;;;8442:566:1:o;18575:128::-;;18646:1;18642:6;18639:1;18636:13;18633:2;;;18652:18;;:::i;:::-;-1:-1:-1;18688:9:1;;18623:80::o;18708:120::-;;18774:1;18764:2;;18779:18;;:::i;:::-;-1:-1:-1;18813:9:1;;18754:74::o;18833:168::-;;18939:1;18935;18931:6;18927:14;18924:1;18921:21;18916:1;18909:9;18902:17;18898:45;18895:2;;;18946:18;;:::i;:::-;-1:-1:-1;18986:9:1;;18885:116::o;19006:125::-;;19074:1;19071;19068:8;19065:2;;;19079:18;;:::i;:::-;-1:-1:-1;19116:9:1;;19055:76::o;19136:135::-;;-1:-1:-1;;19196:17:1;;19193:2;;;19216:18;;:::i;:::-;-1:-1:-1;19263:1:1;19252:13;;19183:88::o;19276:112::-;;19334:1;19324:2;;19339:18;;:::i;:::-;-1:-1:-1;19373:9:1;;19314:74::o;19393:184::-;-1:-1:-1;;;19442:1:1;19435:88;19542:4;19539:1;19532:15;19566:4;19563:1;19556:15;19582:184;-1:-1:-1;;;19631:1:1;19624:88;19731:4;19728:1;19721:15;19755:4;19752:1;19745:15;19771:184;-1:-1:-1;;;19820:1:1;19813:88;19920:4;19917:1;19910:15;19944:4;19941:1;19934:15;19960:154;-1:-1:-1;;;;;20039:5:1;20035:54;20028:5;20025:65;20015:2;;20104:1;20101;20094:12

Swarm Source

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