POL Price: $0.378028 (+0.39%)
 

Overview

POL Balance

Polygon PoS Chain LogoPolygon PoS Chain LogoPolygon PoS Chain Logo0 POL

POL Value

$0.00

Sponsored

Transaction Hash
Method
Block
From
To
Craft481223532023-09-29 12:17:54349 days ago1695989874IN
0x29a76751...7aBc95557
0 POL0.0110234479.48781083
Craft481220232023-09-29 12:06:12349 days ago1695989172IN
0x29a76751...7aBc95557
0 POL0.0148955595.61855104
Craft481202282023-09-29 11:01:25349 days ago1695985285IN
0x29a76751...7aBc95557
0 POL0.0118049975.779437
Craft481202142023-09-29 11:00:55349 days ago1695985255IN
0x29a76751...7aBc95557
0 POL0.0107754377.65578113
Craft479545512023-09-25 4:50:53353 days ago1695617453IN
0x29a76751...7aBc95557
0 POL0.0115598176.56467845
Craft479540392023-09-25 4:31:02353 days ago1695616262IN
0x29a76751...7aBc95557
0 POL0.0085151483.43356213
Craft479529312023-09-25 3:49:08353 days ago1695613748IN
0x29a76751...7aBc95557
0 POL0.0087388779.76406339
Craft479524492023-09-25 3:30:44353 days ago1695612644IN
0x29a76751...7aBc95557
0 POL0.0126470181.18457715
Craft479511972023-09-25 2:44:52353 days ago1695609892IN
0x29a76751...7aBc95557
0 POL0.0126625781.28444367
Craft478945542023-09-23 16:10:18355 days ago1695485418IN
0x29a76751...7aBc95557
0 POL0.0106000183.68940653
Craft478945382023-09-23 16:09:44355 days ago1695485384IN
0x29a76751...7aBc95557
0 POL0.0115348684.65393938
Craft478942902023-09-23 16:00:32355 days ago1695484832IN
0x29a76751...7aBc95557
0 POL0.02131867120.03488461
Craft478916992023-09-23 14:26:32355 days ago1695479192IN
0x29a76751...7aBc95557
0 POL0.0131906598.46785117
Craft478863292023-09-23 11:09:09355 days ago1695467349IN
0x29a76751...7aBc95557
0 POL0.0114211490.17241499
Craft478863102023-09-23 11:08:29355 days ago1695467309IN
0x29a76751...7aBc95557
0 POL0.0146858297.26938632
Craft478098972023-09-21 12:44:23357 days ago1695300263IN
0x29a76751...7aBc95557
0 POL0.0145284996.22732374
Set Owner459315332023-08-05 8:03:18404 days ago1691222598IN
0x29a76751...7aBc95557
0 POL0.00573899120.33448758
Create Recipe458893292023-08-04 6:52:24405 days ago1691131944IN
0x29a76751...7aBc95557
0 POL0.0222425180.32164781
Create Recipe458893292023-08-04 6:52:24405 days ago1691131944IN
0x29a76751...7aBc95557
0 POL0.0222425180.32164781
Create Recipe458893292023-08-04 6:52:24405 days ago1691131944IN
0x29a76751...7aBc95557
0 POL0.0218810680.32164781
Create Recipe458893292023-08-04 6:52:24405 days ago1691131944IN
0x29a76751...7aBc95557
0 POL0.0218810680.32164781
Create Recipe458893292023-08-04 6:52:24405 days ago1691131944IN
0x29a76751...7aBc95557
0 POL0.0218810680.32164781
Create Recipe458893292023-08-04 6:52:24405 days ago1691131944IN
0x29a76751...7aBc95557
0 POL0.0332247280.32164781
Create Recipe458893292023-08-04 6:52:24405 days ago1691131944IN
0x29a76751...7aBc95557
0 POL0.027734180.32164781
Create Recipe458893292023-08-04 6:52:24405 days ago1691131944IN
0x29a76751...7aBc95557
0 POL0.027734180.32164781
View all transactions

Parent Transaction Hash Block From To
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CraftLogic

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 10000 runs

Other Settings:
default evmVersion
File 1 of 9 : CraftLogic.sol
// SPDX-License-Identifier: MIT

//                 ____    ____
//                /\___\  /\___\
//       ________/ /   /_ \/___/
//      /\_______\/   /__\___\
//     / /       /       /   /
//    / /   /   /   /   /   /
//   / /   /___/___/___/___/
//  / /   /
//  \/___/

pragma solidity 0.8.19;

import { ERC2771Context } from "@gelatonetwork/relay-context/contracts/vendor/ERC2771Context.sol";

import { BaseCraftLogic } from "./utils/BaseCraftLogic.sol";

/// @title CraftLogic
/// @dev The CraftLogic smart contract enables the creation, update, and execution of crafting recipes in PHI
// It also supports actions performed on behalf of users by a trusted relay service.
contract CraftLogic is BaseCraftLogic {
    /* -------------------------------------------------------------------------- */
    /*                               INITIALIZATION                               */
    /* -------------------------------------------------------------------------- */
    constructor(address trustedForwarder, address _gelatoRelay) ERC2771Context(trustedForwarder) {
        if (_gelatoRelay == address(0)) revert InvalidAddress("gelatoRelay address can't be 0");

        gelatoRelay = _gelatoRelay;
    }

    /**
     * @dev This function creates a new recipe. It checks if the recipe already exists,
     * ensures that the materials and artifacts arrays have at least one element,
     * and emits a RecipeCreated event.
     *
     * Requirements:
     * - The caller must be the owner.
     * - The materials and artifacts arrays must not be empty.
     *
     * @param materials the materials required for the recipe
     * @param artifacts the artifacts produced by the recipe
     * @param catalyst the catalyst required for the recipe
     */
    function createRecipe(
        Material[] calldata materials,
        Artifacts[] calldata artifacts,
        Catalyst calldata catalyst
    )
        external
        override
        onlyOwner
    {
        uint256 id = getRecipeNumber() + 1;
        _createOrUpdateRecipe(id, materials, artifacts, catalyst, true, false);
        ++recipeCount;
    }

    /**
     * @dev This function updates an existing recipe. It checks if the recipe exists,
     * ensures that the materials and artifacts arrays have at least one element,
     * and emits a RecipeUpdated event.
     *
     * Requirements:
     * - The caller must be the owner.
     * - The materials and artifacts arrays must not be empty.
     *
     * @param recipeId the ID of the recipe to update
     * @param materials the materials required for the recipe
     * @param artifacts the artifacts produced by the recipe
     * @param catalyst the catalyst required for the recipe
     * @param active the status of the recipe
     */
    function updateRecipe(
        uint256 recipeId,
        Material[] memory materials,
        Artifacts[] memory artifacts,
        Catalyst calldata catalyst,
        bool active
    )
        external
        override
        onlyOwner
    {
        _createOrUpdateRecipe(recipeId, materials, artifacts, catalyst, active, true);
    }

    /**
     * @dev This function changes the status of an existing recipe. It checks if the recipe exists,
     * and emits a ChangeRecipeStatus event.
     *
     * Requirements:
     * - The caller must be the owner.
     *
     * @param recipeId the ID of the recipe to update
     * @param active the new status of the recipe
     */
    function changeRecipeStatus(uint256 recipeId, bool active) external override onlyOwner {
        // Check if the recipe already exists
        if (recipes[recipeId].id != recipeId) revert NonExistentRecipe(recipeId);

        // Update
        Recipe storage recipe = recipes[recipeId];
        recipe.active = active;
        // Emit the ChangeRecipeStatus event
        emit ChangeRecipeStatus(recipeId, active, _msgSender());
    }
}

File 2 of 9 : ERC2771Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (metatx/ERC2771Context.sol)

pragma solidity ^0.8.1;

/**
 * @dev Context variant with ERC2771 support.
 */
// based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol
abstract contract ERC2771Context {
    address private immutable _trustedForwarder;

    constructor(address trustedForwarder) {
        _trustedForwarder = trustedForwarder;
    }

    function isTrustedForwarder(address forwarder)
        public
        view
        virtual
        returns (bool)
    {
        return forwarder == _trustedForwarder;
    }

    function _msgSender() internal view virtual returns (address sender) {
        if (isTrustedForwarder(msg.sender)) {
            // The assembly code is more direct than the Solidity version using `abi.decode`.
            /// @solidity memory-safe-assembly
            assembly {
                sender := shr(96, calldataload(sub(calldatasize(), 20)))
            }
        } else {
            return msg.sender;
        }
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        if (isTrustedForwarder(msg.sender)) {
            return msg.data[:msg.data.length - 20];
        } else {
            return msg.data;
        }
    }
}

File 3 of 9 : BaseCraftLogic.sol
// SPDX-License-Identifier: MIT

//                 ____    ____
//                /\___\  /\___\
//       ________/ /   /_ \/___/
//      /\_______\/   /__\___\
//     / /       /       /   /
//    / /   /   /   /   /   /
//   / /   /___/___/___/___/
//  / /   /
//  \/___/

pragma solidity 0.8.19;

import { ERC2771Context } from "@gelatonetwork/relay-context/contracts/vendor/ERC2771Context.sol";
import { MultiOwner } from "../utils/MultiOwner.sol";
import { ReentrancyGuard } from "@openzeppelin/security/ReentrancyGuard.sol";

import { ITokenBurner } from "../interfaces/ITokenBurner.sol";
import { ICatalyst } from "../interfaces/ICatalyst.sol";
import { ITokenCrafter } from "../interfaces/ITokenCrafter.sol";
import { IUGCCraftableObjectFactory } from "../interfaces/IUGCCraftableObjectFactory.sol";

abstract contract BaseCraftLogic is ReentrancyGuard, MultiOwner, ERC2771Context {
    /* -------------------------------------------------------------------------- */
    /*                                   CONFIG                                   */
    /* -------------------------------------------------------------------------- */
    // The address used for Gelato Relay.
    address public gelatoRelay;
    // The address used for UGCCraftableObjectFactory.
    address public ugcFactory;

    // Whitelist for material objects and artifacts that can be used in recipes
    mapping(address => bool) private _whitelist;
    /* -------------------------------------------------------------------------- */
    /*                                   STORAGE                                  */
    /* -------------------------------------------------------------------------- */
    uint256 public recipeCount;

    // Define an array to store the recipes
    mapping(uint256 => Recipe) internal recipes;

    struct Material {
        address tokenAddress; // The address of the ERC1155 contract for this material
        uint256 tokenId; // The ID of the token in the ERC1155 contract
        uint256 amount; // The amount of the token required
    }

    struct Artifacts {
        address tokenAddress; // The address of the ERC1155 contract for this Artifacts
        uint256 tokenId; // The ID of the token in the ERC1155 contract
        uint256 amount; // The amount of the token required
    }

    struct Catalyst {
        address tokenAddress; // The address of the ERC20/ERC721/ERC1155 contract for this catalyst
        uint256 tokenId; // The ID of the token in the contract : ERC20 => 0
        uint256 amount; // The required balance of the token
        TokenType tokenType; // Type of the token: 0 = ERC20, 1 = ERC721, 2 = ERC1155
    }

    struct Recipe {
        uint256 id;
        Material[] materials;
        Artifacts[] artifacts;
        Catalyst catalyst; // ERC20/ERC721/ERC1155
        address creator;
        bool active;
    }

    enum TokenType {
        ERC20,
        ERC721,
        ERC1155
    }

    /* -------------------------------------------------------------------------- */
    /*                                   EVENTS                                   */
    /* -------------------------------------------------------------------------- */
    // Event emitted when a new artifact is crafte
    event Crafted(address indexed crafter, uint256 recipeId);
    // Event emitted when a new recipe is created
    event RecipeCreated(uint256 indexed recipeId, address indexed owner);
    // Event emitted when a new recipe is created
    event RecipeUpdated(uint256 indexed recipeId, address indexed owner);
    // Event emitted when the GelatoRelay address is set.
    event SetGelatoRelay(address indexed oldGelatoRelay, address indexed newGelatoRelay);
    // Event emitted when the UGCFactory address is set.
    event SetUgcFactory(address indexed oldUgcFactory, address indexed ugcFactory);
    // Event emitted when a craft is performed by a relayer
    event CraftedByRelayer(uint256 indexed recipeId, address indexed relayer);
    // Event emitted when a new recipe is created
    event ChangeRecipeStatus(uint256 indexed recipeId, bool active, address indexed owner);
    // Event emitted when an address is added to the whitelist.
    event AddedToWhitelist(address indexed sender, address indexed whitelistedAddress);
    // Event emitted when an address is removed from the whitelist.
    event RemovedFromWhitelist(address indexed sender, address indexed unwhitelistedAddress);

    /* -------------------------------------------------------------------------- */
    /*                                   ERRORS                                   */
    /* -------------------------------------------------------------------------- */
    // Error thrown when an invalid address is provided. The reason for invalidity is provided as a parameter.
    error InvalidAddress(string reason);
    // Error thrown when the caller is not the creator of the recipe.
    error NotRecipeCreator(uint256 recipeId);
    // Error thrown when the required condition for a catalyst is not satisfied during crafting.
    error CatalystConditionNotSatisfied();
    // Error to throw if the function call is not made by an GelatoRelay.
    error OnlyGelatoRelay();
    // Error thrown when trying to craft using an inactive recipe.
    error RecipeInactive(uint256 recipeId);
    // Error thrown when trying to create a recipe that already exists.
    error ExistentCraft(uint256 id);
    // Error thrown when trying to update a recipe that doesn't exist.
    error NonExistentRecipe(uint256 id);
    // Error thrown when trying to create or update a recipe without any materials.
    error EmptyMaterialsArray();
    // Error thrown when trying to create or update a recipe without any artifacts.
    error EmptyArtifactsArray();
    // Error thrown if not a smart contract but an EOA
    error MustBeAContract();
    // Error thrown if an address is not whitelisted or created by UGCCraftableObjectFactory
    error MustBeWhitelistedOrCreatedByUGCFactory();

    /* -------------------------------------------------------------------------- */
    /*                                  Utility                                   */
    /* -------------------------------------------------------------------------- */

    function _checkSize(address addr) private view returns (uint256 extSize) {
        assembly {
            extSize := extcodesize(addr) // returns 0 if EOA, >0 if smart contract
        }
    }

    function _validateCraftContract(address addr) internal view {
        if (_checkSize(addr) == 0) {
            revert MustBeAContract();
        }

        if (!_whitelist[addr] && !IUGCCraftableObjectFactory(ugcFactory).checkUGCAddress(addr)) {
            revert MustBeWhitelistedOrCreatedByUGCFactory();
        }
    }

    function addToWhitelist(address addr) external onlyOwner {
        _whitelist[addr] = true;
        emit AddedToWhitelist(msg.sender, addr);
    }

    function removeFromWhitelist(address addr) external onlyOwner {
        _whitelist[addr] = false;
        emit RemovedFromWhitelist(msg.sender, addr);
    }

    /// @dev Set an UGCCraftableObjectFactory contract
    function setUgcFactory(address _ugcFactory) external onlyOwner {
        if (_ugcFactory == address(0)) {
            revert InvalidAddress({ reason: "cant set address(0)" });
        }
        if (_checkSize(_ugcFactory) == 0) revert MustBeAContract();

        address oldUgcFactory = ugcFactory;
        ugcFactory = _ugcFactory;
        emit SetUgcFactory(oldUgcFactory, ugcFactory);
    }
    /* -------------------------------------------------------------------------- */
    /*                                  MODIFIERS                                 */
    /* -------------------------------------------------------------------------- */

    modifier onlyRecipeCreator(uint256 recipeId) {
        if (_msgSender() != recipes[recipeId].creator) revert NotRecipeCreator(recipeId);
        _;
    }

    /* -------------------------------------------------------------------------- */
    /*                                    Craft                                   */
    /* -------------------------------------------------------------------------- */
    // 0:ERC20, 1:ERC721, 2:ERC1155
    function _checkCatalystCondition(Catalyst memory catalyst) internal view {
        if (catalyst.tokenType == TokenType.ERC20 && !_enoughERC20Balance(catalyst)) {
            revert CatalystConditionNotSatisfied();
        } else if (catalyst.tokenType == TokenType.ERC721 && !_correctERC721Owner(catalyst)) {
            revert CatalystConditionNotSatisfied();
        } else if (catalyst.tokenType == TokenType.ERC1155 && !_enoughERC1155Balance(catalyst)) {
            revert CatalystConditionNotSatisfied();
        }
    }

    function _enoughERC20Balance(Catalyst memory catalyst) internal view returns (bool) {
        return ICatalyst(catalyst.tokenAddress).balanceOf(_msgSender()) >= catalyst.amount;
    }

    function _correctERC721Owner(Catalyst memory catalyst) internal view returns (bool) {
        return ICatalyst(catalyst.tokenAddress).ownerOf(catalyst.tokenId) == _msgSender();
    }

    function _enoughERC1155Balance(Catalyst memory catalyst) internal view returns (bool) {
        return ICatalyst(catalyst.tokenAddress).balanceOf(_msgSender(), catalyst.tokenId) >= catalyst.amount;
    }

    /**
     * @dev This function allows users to craft an artifact with a given recipeId.
     * The function first checks if the recipe is active and satisfies the catalyst condition,
     * then it burns the required materials and mints the new artifact.
     *
     * @param recipeId ID of the recipe to be used for crafting.
     */
    function craft(uint256 recipeId) external virtual nonReentrant {
        _craft(recipeId);
    }

    function _craft(uint256 recipeId) private {
        // Retrieve the recipe
        Recipe storage recipe = recipes[recipeId];

        // Ensure the recipe is active
        if (!recipe.active) revert RecipeInactive(recipeId);

        // Check catalyst condition
        Catalyst memory catalyst = recipe.catalyst;
        if (catalyst.tokenAddress != address(0)) {
            _checkCatalystCondition(catalyst);
        }

        // Burn the required materials
        uint256 materialsLength = recipe.materials.length;
        for (uint256 i; i < materialsLength;) {
            Material memory material = recipe.materials[i];
            ITokenBurner(material.tokenAddress).burnObject(_msgSender(), material.tokenId, material.amount);
            unchecked {
                ++i;
            }
        }

        // Mint the artifacts
        uint256 artifactsLength = recipe.artifacts.length;
        for (uint256 i; i < artifactsLength;) {
            Artifacts memory artifact = recipe.artifacts[i];
            ITokenCrafter(artifact.tokenAddress).craftObject(_msgSender(), recipeId, artifact.tokenId, artifact.amount);
            unchecked {
                ++i;
            }
        }
        // Emit the Crafted event
        emit Crafted(_msgSender(), recipeId);
    }

    /* -------------------------------------------------------------------------- */
    /*                               Recipe Utility                               */
    /* -------------------------------------------------------------------------- */
    /**
     * @dev This function returns the Recipe structure for a given recipeId.
     *
     * @param recipeId ID of the recipe to be retrieved.
     */
    function getRecipe(uint256 recipeId) external view virtual returns (Recipe memory) {
        return recipes[recipeId];
    }

    // These methods need to be implemented by subclasses
    function getRecipeNumber() public view virtual returns (uint256) {
        return recipeCount;
    }

    function createRecipe(
        Material[] calldata materials,
        Artifacts[] calldata artifacts,
        Catalyst calldata catalyst
    )
        external
        virtual;

    function updateRecipe(
        uint256 recipeId,
        Material[] memory materials,
        Artifacts[] memory artifacts,
        Catalyst calldata catalyst,
        bool active
    )
        external
        virtual;

    function changeRecipeStatus(uint256 recipeId, bool active) external virtual;

    function _createOrUpdateRecipe(
        uint256 recipeId,
        Material[] memory materials,
        Artifacts[] memory artifacts,
        Catalyst calldata catalyst,
        bool active,
        bool isUpdate // true:= update, false:= create
    )
        internal
    {
        // Check if the recipe already exists
        if (recipes[recipeId].id == recipeId && !isUpdate) revert ExistentCraft(recipeId);
        if (recipes[recipeId].id != recipeId && isUpdate) revert NonExistentRecipe(recipeId);

        uint256 materialsLength = materials.length;
        uint256 artifactsLength = artifacts.length;
        // Check that materials and artifacts arrays have at least one element
        if (materialsLength == 0) revert EmptyMaterialsArray();
        if (artifactsLength == 0) revert EmptyArtifactsArray();

        if (catalyst.tokenAddress != address(0)) {
            if (_checkSize(catalyst.tokenAddress) == 0) revert MustBeAContract();
        }
        // Update or Create a new recipe
        Recipe storage recipe = recipes[recipeId];
        recipe.id = recipeId;
        recipe.creator = _msgSender();
        recipe.active = active;
        recipe.catalyst = catalyst;

        // Update the materials array
        delete recipe.materials;
        for (uint256 i; i < materialsLength;) {
            _validateCraftContract(materials[i].tokenAddress);
            recipe.materials.push(materials[i]);
            unchecked {
                ++i;
            }
        }

        // Update the artifacts array
        delete recipe.artifacts;
        for (uint256 i; i < artifactsLength;) {
            _validateCraftContract(artifacts[i].tokenAddress);
            recipe.artifacts.push(artifacts[i]);
            unchecked {
                ++i;
            }
        }
        // Emit the RecipeCreated event
        if (isUpdate) {
            emit RecipeUpdated(recipeId, _msgSender());
        } else {
            emit RecipeCreated(recipeId, _msgSender());
        }
    }

    /* -------------------------------------------------------------------------- */
    /*                               RelayCraft                                  */
    /* -------------------------------------------------------------------------- */
    /// @dev Set a new GelatoRelay address
    function setGelatoRelay(address _gelatoRelay) external onlyOwner {
        if (_gelatoRelay == address(0)) {
            revert InvalidAddress({ reason: "cant set address(0)" });
        }
        if (_checkSize(_gelatoRelay) == 0) revert MustBeAContract();

        address oldGelatoRelay = gelatoRelay;
        gelatoRelay = _gelatoRelay;
        emit SetGelatoRelay(oldGelatoRelay, gelatoRelay);
    }

    modifier onlyGelatoRelay() {
        if (!_isGelatoRelay(msg.sender)) revert OnlyGelatoRelay();
        _;
    }

    function _isGelatoRelay(address _forwarder) internal view returns (bool) {
        return _forwarder == gelatoRelay;
    }

    // Function to craft object by relayer.
    function craftByRelayer(uint256 recipeId) external nonReentrant onlyGelatoRelay {
        _craft(recipeId);
        // Emit an event indicating that this function was called by a relayer
        emit CraftedByRelayer(recipeId, msg.sender);
    }
}

File 4 of 9 : MultiOwner.sol
// SPDX-License-Identifier: MIT

//                 ____    ____
//                /\___\  /\___\
//       ________/ /   /_ \/___/
//      /\_______\/   /__\___\
//     / /       /       /   /
//    / /   /   /   /   /   /
//   / /   /___/___/___/___/
//  / /   /
//  \/___/

pragma solidity 0.8.19;

/**
 * @dev Contracts to manage multiple owners.
 */
abstract contract MultiOwner {
    /* -------------------------------------------------------------------------- */
    /*                                   STORAGE                                  */
    /* -------------------------------------------------------------------------- */
    mapping(address => bool) private _owners;

    /* -------------------------------------------------------------------------- */
    /*                                   EVENTS                                   */
    /* -------------------------------------------------------------------------- */
    event OwnershipGranted(address indexed operator, address indexed target);
    event OwnershipRemoved(address indexed operator, address indexed target);

    /* -------------------------------------------------------------------------- */
    /*                                   ERRORS                                   */
    /* -------------------------------------------------------------------------- */
    error InvalidOwner();

    /* -------------------------------------------------------------------------- */
    /*                               INITIALIZATION                               */
    /* -------------------------------------------------------------------------- */
    /**
     * @dev Initializes the contract setting and set the deployer as the initial owner.
     */
    constructor() {
        _owners[msg.sender] = true;
    }

    /* -------------------------------------------------------------------------- */
    /*                                  MODIFIERS                                 */
    /* -------------------------------------------------------------------------- */
    /**
     * @dev Throws an error if called by any account other than the owner.
     */
    modifier onlyOwner() {
        if (!_owners[msg.sender]) revert InvalidOwner();
        _;
    }

    /* -------------------------------------------------------------------------- */
    /*                                   PUBLIC                                   */
    /* -------------------------------------------------------------------------- */
    /**
     * @dev Returns the address of the current owner.
     */
    function ownerCheck(address targetAddress) external view virtual returns (bool) {
        return _owners[targetAddress];
    }

    /**
     * @dev Sets the address of the owner.
     */
    function setOwner(address newOwner) external virtual onlyOwner {
        _owners[newOwner] = true;
        emit OwnershipGranted(msg.sender, newOwner);
    }

    /**
     * @dev Removes the address from the owner list.
     */
    function removeOwner(address oldOwner) external virtual onlyOwner {
        _owners[oldOwner] = false;
        emit OwnershipRemoved(msg.sender, oldOwner);
    }
}

File 5 of 9 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @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 making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

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

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == _ENTERED;
    }
}

File 6 of 9 : ITokenBurner.sol
// SPDX-License-Identifier: MIT

//                 ____    ____
//                /\___\  /\___\
//       ________/ /   /_ \/___/
//      /\_______\/   /__\___\
//     / /       /       /   /
//    / /   /   /   /   /   /
//   / /   /___/___/___/___/
//  / /   /
//  \/___/

pragma solidity 0.8.19;

interface ITokenBurner {
    function burnObject(address from, uint256 tokenId, uint256 amount) external;
}

File 7 of 9 : ICatalyst.sol
// SPDX-License-Identifier: MIT

//                 ____    ____
//                /\___\  /\___\
//       ________/ /   /_ \/___/
//      /\_______\/   /__\___\
//     / /       /       /   /
//    / /   /   /   /   /   /
//   / /   /___/___/___/___/
//  / /   /
//  \/___/

pragma solidity 0.8.19;

interface ICatalyst {
    function balanceOf(address account) external view returns (uint256);
    function ownerOf(uint256 tokenId) external view returns (address);
    function balanceOf(address account, uint256 id) external view returns (uint256);
}

File 8 of 9 : ITokenCrafter.sol
// SPDX-License-Identifier: MIT

//                 ____    ____
//                /\___\  /\___\
//       ________/ /   /_ \/___/
//      /\_______\/   /__\___\
//     / /       /       /   /
//    / /   /   /   /   /   /
//   / /   /___/___/___/___/
//  / /   /
//  \/___/

pragma solidity 0.8.19;

interface ITokenCrafter {
    function craftObject(address to, uint256 recipeId, uint256 tokenId, uint256 amount) external;
}

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

//                 ____    ____
//                /\___\  /\___\
//       ________/ /   /_ \/___/
//      /\_______\/   /__\___\
//     / /       /       /   /
//    / /   /   /   /   /   /
//   / /   /___/___/___/___/
//  / /   /
//  \/___/

pragma solidity 0.8.19;

interface IUGCCraftableObjectFactory {
    function checkUGCAddress(address _address) external view returns (bool);
}

Settings
{
  "remappings": [
    "@gelatonetwork/=node_modules/@gelatonetwork/",
    "@openzeppelin/=lib/openzeppelin-contracts/contracts/",
    "@prb/test/=lib/prb-test/src/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "openzeppelin/=lib/openzeppelin-contracts/contracts/",
    "prb-test/=lib/prb-test/src/",
    "src/=src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 10000
  },
  "metadata": {
    "bytecodeHash": "none",
    "appendCBOR": false
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"trustedForwarder","type":"address"},{"internalType":"address","name":"_gelatoRelay","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CatalystConditionNotSatisfied","type":"error"},{"inputs":[],"name":"EmptyArtifactsArray","type":"error"},{"inputs":[],"name":"EmptyMaterialsArray","type":"error"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ExistentCraft","type":"error"},{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"InvalidOwner","type":"error"},{"inputs":[],"name":"MustBeAContract","type":"error"},{"inputs":[],"name":"MustBeWhitelistedOrCreatedByUGCFactory","type":"error"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"NonExistentRecipe","type":"error"},{"inputs":[{"internalType":"uint256","name":"recipeId","type":"uint256"}],"name":"NotRecipeCreator","type":"error"},{"inputs":[],"name":"OnlyGelatoRelay","type":"error"},{"inputs":[{"internalType":"uint256","name":"recipeId","type":"uint256"}],"name":"RecipeInactive","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"whitelistedAddress","type":"address"}],"name":"AddedToWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"recipeId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"active","type":"bool"},{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"ChangeRecipeStatus","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"crafter","type":"address"},{"indexed":false,"internalType":"uint256","name":"recipeId","type":"uint256"}],"name":"Crafted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"recipeId","type":"uint256"},{"indexed":true,"internalType":"address","name":"relayer","type":"address"}],"name":"CraftedByRelayer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"target","type":"address"}],"name":"OwnershipGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"target","type":"address"}],"name":"OwnershipRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"recipeId","type":"uint256"},{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"RecipeCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"recipeId","type":"uint256"},{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"RecipeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"unwhitelistedAddress","type":"address"}],"name":"RemovedFromWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldGelatoRelay","type":"address"},{"indexed":true,"internalType":"address","name":"newGelatoRelay","type":"address"}],"name":"SetGelatoRelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldUgcFactory","type":"address"},{"indexed":true,"internalType":"address","name":"ugcFactory","type":"address"}],"name":"SetUgcFactory","type":"event"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"addToWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"recipeId","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"}],"name":"changeRecipeStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"recipeId","type":"uint256"}],"name":"craft","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"recipeId","type":"uint256"}],"name":"craftByRelayer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseCraftLogic.Material[]","name":"materials","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseCraftLogic.Artifacts[]","name":"artifacts","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum BaseCraftLogic.TokenType","name":"tokenType","type":"uint8"}],"internalType":"struct BaseCraftLogic.Catalyst","name":"catalyst","type":"tuple"}],"name":"createRecipe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gelatoRelay","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"recipeId","type":"uint256"}],"name":"getRecipe","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseCraftLogic.Material[]","name":"materials","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseCraftLogic.Artifacts[]","name":"artifacts","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum BaseCraftLogic.TokenType","name":"tokenType","type":"uint8"}],"internalType":"struct BaseCraftLogic.Catalyst","name":"catalyst","type":"tuple"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct BaseCraftLogic.Recipe","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRecipeNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"isTrustedForwarder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"targetAddress","type":"address"}],"name":"ownerCheck","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"recipeCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"removeFromWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"oldOwner","type":"address"}],"name":"removeOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gelatoRelay","type":"address"}],"name":"setGelatoRelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_ugcFactory","type":"address"}],"name":"setUgcFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ugcFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"recipeId","type":"uint256"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseCraftLogic.Material[]","name":"materials","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseCraftLogic.Artifacts[]","name":"artifacts","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum BaseCraftLogic.TokenType","name":"tokenType","type":"uint8"}],"internalType":"struct BaseCraftLogic.Catalyst","name":"catalyst","type":"tuple"},{"internalType":"bool","name":"active","type":"bool"}],"name":"updateRecipe","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a06040523480156200001157600080fd5b5060405162002363380380620023638339810160408190526200003491620000f8565b60016000818155338152602082905260409020805460ff191690911790556001600160a01b038083166080528116620000b457604051630b0f5aa160e11b815260206004820152601e60248201527f67656c61746f52656c617920616464726573732063616e277420626520300000604482015260640160405180910390fd5b600280546001600160a01b0319166001600160a01b03929092169190911790555062000130565b80516001600160a01b0381168114620000f357600080fd5b919050565b600080604083850312156200010c57600080fd5b6200011783620000db565b91506200012760208401620000db565b90509250929050565b60805161221062000153600039600081816102290152610dec01526122106000f3fe608060405234801561001057600080fd5b50600436106101355760003560e01c806369cfdf74116100b2578063dc16426011610081578063ed8a4bca11610066578063ed8a4bca146102c1578063f3917bd2146102d4578063f8d12a41146102e757600080fd5b8063dc1642601461029b578063e43252d7146102ae57600080fd5b806369cfdf74146102595780638ab1d6811461026257806397cbd5b514610275578063bb9572911461028857600080fd5b806323bf2f67116101095780634118b070116100ee5780634118b070146101f457806353e330f214610206578063572b6c051461021957600080fd5b806323bf2f67146101885780633552221a146101c957600080fd5b8062fc38b81461013a57806313af40351461014f578063173825d9146101625780631cac4dc914610175575b600080fd5b61014d610148366004611b05565b610307565b005b61014d61015d366004611b05565b61046a565b61014d610170366004611b05565b610521565b61014d610183366004611b47565b6105d2565b6101b4610196366004611b05565b6001600160a01b031660009081526001602052604090205460ff1690565b60405190151581526020015b60405180910390f35b6002546101dc906001600160a01b031681565b6040516001600160a01b0390911681526020016101c0565b6005545b6040519081526020016101c0565b61014d610214366004611b05565b61070a565b6101b4610227366004611b05565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0390811691161490565b6101f860055481565b61014d610270366004611b05565b610868565b61014d610283366004611b77565b610919565b61014d610296366004611bf4565b6109a8565b61014d6102a9366004611db8565b610ad8565b61014d6102bc366004611b05565b610b37565b6003546101dc906001600160a01b031681565b61014d6102e2366004611b77565b610beb565b6102fa6102f5366004611b77565b610c06565b6040516101c09190611f61565b3360009081526001602052604090205460ff16610350576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381166103c5576040517f161eb54200000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f63616e742073657420616464726573732830290000000000000000000000000060448201526064015b60405180910390fd5b803b600003610400576040517f6a69700800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907fc54464cec915fe977cf453c1adb8e32edda6652965b6a345c32ed4c79a6b75b190600090a35050565b3360009081526001602052604090205460ff166104b3576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038116600081815260016020819052604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169092179091555133917f619792ba07bec101df538ab277befa333e4cf1c0274f11de7be2a9507b9c9a0691a350565b3360009081526001602052604090205460ff1661056a576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03811660008181526001602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555133917fc191551a88c5609788f3532bd94c06479b61b0040eec65f9cd985428ffea643091a350565b3360009081526001602052604090205460ff1661061b576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600660205260409020548214610665576040517fbb4dde3c000000000000000000000000000000000000000000000000000000008152600481018390526024016103bc565b60008281526006602052604090206007810180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000841515021790556106c0610de8565b6001600160a01b0316837f81401af55d5e5b19605b1d723d712d50b4c28b0b355a7aad37c3cdfcd0701756846040516106fd911515815260200190565b60405180910390a3505050565b3360009081526001602052604090205460ff16610753576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381166107c3576040517f161eb54200000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f63616e742073657420616464726573732830290000000000000000000000000060448201526064016103bc565b803b6000036107fe576040517f6a69700800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907fda8be21788d879b5a0e06c4760b930def99e1b439a5751534f60df9fc56ac3c690600090a35050565b3360009081526001602052604090205460ff166108b1576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03811660008181526004602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555133917fd288ab5da2e1f37cf384a1565a3f905ad289b092fbdd31950dbbfef148c04f8891a350565b610921610e4a565b6002546001600160a01b03163314610965576040517fb8cfdf8700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61096e81610ebd565b604051339082907f8c2f4bbdd223372eba908078d1988d3fda491bafc476c076d4336d86feaac82690600090a36109a56001600055565b50565b3360009081526001602052604090205460ff166109f1576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006109fc60055490565b610a07906001612087565b9050610abd818787808060200260200160405190810160405280939291908181526020016000905b82821015610a5b57610a4c606083028601368190038101906120a0565b81526020019060010190610a2f565b50505050508686808060200260200160405190810160405280939291908181526020016000905b82821015610aae57610a9f606083028601368190038101906120a0565b81526020019060010190610a82565b50505050508560016000611213565b600560008154610acc906120bc565b90915550505050505050565b3360009081526001602052604090205460ff16610b21576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b3085858585856001611213565b5050505050565b3360009081526001602052604090205460ff16610b80576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03811660008181526004602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555133917f0c4b48e75a1f7ab0a9a2f786b5d6c1f7789020403bff177fb54d46edb89ccc0091a350565b610bf3610e4a565b610bfc81610ebd565b6109a56001600055565b610c0e611a2f565b600660008381526020019081526020016000206040518060c00160405290816000820154815260200160018201805480602002602001604051908101604052809291908181526020016000905b82821015610cb0576000848152602090819020604080516060810182526003860290920180546001600160a01b0316835260018082015484860152600290910154918301919091529083529092019101610c5b565b50505050815260200160028201805480602002602001604051908101604052809291908181526020016000905b82821015610d32576000848152602090819020604080516060810182526003860290920180546001600160a01b0316835260018082015484860152600290910154918301919091529083529092019101610cdd565b50505090825250604080516080810182526003840180546001600160a01b031682526004850154602083810191909152600586015493830193909352600685015492909301929091606083019060ff166002811115610d9357610d93611eca565b6002811115610da457610da4611eca565b9052508152600791909101546001600160a01b038116602083015274010000000000000000000000000000000000000000900460ff16151560409091015292915050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163303610e4557507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b503390565b600260005403610eb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016103bc565b6002600055565b6000818152600660205260409020600781015474010000000000000000000000000000000000000000900460ff16610f24576040517f2fc63a09000000000000000000000000000000000000000000000000000000008152600481018390526024016103bc565b604080516080810182526003830180546001600160a01b0316825260048401546020830152600584015492820192909252600683015460009290606083019060ff166002811115610f7757610f77611eca565b6002811115610f8857610f88611eca565b90525080519091506001600160a01b031615610fa757610fa781611636565b600182015460005b818110156110b0576000846001018281548110610fce57610fce6120f4565b600091825260209182902060408051606081018252600390930290910180546001600160a01b031680845260018201549484019490945260020154908201529150630990b67e61101c610de8565b602084015160408086015190517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b03909316600484015260248301919091526044820152606401600060405180830381600087803b15801561108c57600080fd5b505af11580156110a0573d6000803e3d6000fd5b5050505081600101915050610faf565b50600283015460005b818110156111c15760008560020182815481106110d8576110d86120f4565b600091825260209182902060408051606081018252600390930290910180546001600160a01b0316808452600182015494840194909452600201549082015291506367087cf9611126610de8565b602084015160408086015190517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b039093166004840152602483018c905260448301919091526064820152608401600060405180830381600087803b15801561119d57600080fd5b505af11580156111b1573d6000803e3d6000fd5b50505050816001019150506110b9565b506111ca610de8565b6001600160a01b03167f1914df0e092e50096eec94a2c4eb530f37d294e6b836499035312d8c033b1b7a8660405161120491815260200190565b60405180910390a25050505050565b6000868152600660205260409020548614801561122e575080155b15611268576040517f449e38d4000000000000000000000000000000000000000000000000000000008152600481018790526024016103bc565b60008681526006602052604090205486148015906112835750805b156112bd576040517fbb4dde3c000000000000000000000000000000000000000000000000000000008152600481018790526024016103bc565b8451845160008290036112fc576040517f078c300a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611336576040517f11d427d900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006113456020870187611b05565b6001600160a01b0316146113a0576113676113636020870187611b05565b3b90565b6000036113a0576040517f6a69700800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008881526006602052604090208881556113b9610de8565b6007820180546001600160a01b03929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909216919091177401000000000000000000000000000000000000000087151502179055856003820161141f8282612123565b506114309050600182016000611a8b565b60005b838110156114ea57611461898281518110611450576114506120f4565b60200260200101516000015161175c565b81600101898281518110611477576114776120f4565b602090810291909101810151825460018082018555600094855293839020825160039092020180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0390921691909117815591810151828401556040015160029091015501611433565b506114f9600282016000611a8b565b60005b828110156115a257611519888281518110611450576114506120f4565b8160020188828151811061152f5761152f6120f4565b602090810291909101810151825460018082018555600094855293839020825160039092020180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909216919091178155918101518284015560400151600290910155016114fc565b5083156115ec576115b1610de8565b6001600160a01b0316897f912747a2c1131151700deb4729f4d22c8f696d2eb38845d781d7cb3c671063a860405160405180910390a361162b565b6115f4610de8565b6001600160a01b0316897fcaa26b4e405345650cea2a9c6c1a0318cd5530c48ef83bad7b115065212c5a4660405160405180910390a35b505050505050505050565b60008160600151600281111561164e5761164e611eca565b148015611661575061165f8161187b565b155b15611698576040517f3f9b4c5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001816060015160028111156116b0576116b0611eca565b1480156116c357506116c181611926565b155b156116fa576040517f3f9b4c5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028160600151600281111561171257611712611eca565b1480156117255750611723816119c0565b155b156109a5576040517f3f9b4c5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b803b600003611797576040517f6a69700800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03811660009081526004602052604090205460ff1615801561184457506003546040517f9bb9c4820000000000000000000000000000000000000000000000000000000081526001600160a01b03838116600483015290911690639bb9c48290602401602060405180830381865afa15801561181e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184291906121bd565b155b156109a5576040517f46eba53d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000816040015182600001516001600160a01b03166370a0823161189d610de8565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b0390911660048201526024015b602060405180830381865afa1580156118fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061191e91906121da565b101592915050565b6000611930610de8565b6001600160a01b031682600001516001600160a01b0316636352211e84602001516040518263ffffffff1660e01b815260040161196f91815260200190565b602060405180830381865afa15801561198c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b091906121f3565b6001600160a01b03161492915050565b6000816040015182600001516001600160a01b031662fdd58e6119e1610de8565b60208601516040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b03909216600483015260248201526044016118dd565b6040518060c00160405280600081526020016060815260200160608152602001611a776040805160808101825260008082526020820181905291810182905290606082015290565b815260006020820181905260409091015290565b50805460008255600302906000526020600020908101906109a591905b80821115611aec5780547fffffffffffffffffffffffff00000000000000000000000000000000000000001681556000600182018190556002820155600301611aa8565b5090565b6001600160a01b03811681146109a557600080fd5b600060208284031215611b1757600080fd5b8135611b2281611af0565b9392505050565b80151581146109a557600080fd5b8035611b4281611b29565b919050565b60008060408385031215611b5a57600080fd5b823591506020830135611b6c81611b29565b809150509250929050565b600060208284031215611b8957600080fd5b5035919050565b60008083601f840112611ba257600080fd5b50813567ffffffffffffffff811115611bba57600080fd5b602083019150836020606083028501011115611bd557600080fd5b9250929050565b600060808284031215611bee57600080fd5b50919050565b600080600080600060c08688031215611c0c57600080fd5b853567ffffffffffffffff80821115611c2457600080fd5b611c3089838a01611b90565b90975095506020880135915080821115611c4957600080fd5b50611c5688828901611b90565b9094509250611c6a90508760408801611bdc565b90509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060608284031215611cb757600080fd5b6040516060810181811067ffffffffffffffff82111715611cda57611cda611c76565b6040529050808235611ceb81611af0565b8082525060208301356020820152604083013560408201525092915050565b600067ffffffffffffffff80841115611d2557611d25611c76565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8660051b011681018181108382111715611d6757611d67611c76565b604052848152915050602080820190606090818602850187811115611d8b57600080fd5b855b81811015611dac57611d9f8982611ca5565b8552938201938301611d8d565b50505050509392505050565b60008060008060006101008688031215611dd157600080fd5b85359450602086013567ffffffffffffffff80821115611df057600080fd5b818801915088601f830112611e0457600080fd5b611e1389833560208501611d0a565b95506040880135915080821115611e2957600080fd5b508601601f81018813611e3b57600080fd5b611e4a88823560208401611d0a565b935050611e5a8760608801611bdc565b9150611c6a60e08701611b37565b600081518084526020808501945080840160005b83811015611ebf57611eac87835180516001600160a01b0316825260208082015190830152604090810151910152565b6060969096019590820190600101611e7c565b509495945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6001600160a01b0381511682526020810151602083015260408101516040830152606081015160038110611f56577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b806060840152505050565b60208082528251828201528281015161012060408401819052815161014085018190526000939283019184916101608701905b80841015611fda57611fc482865180516001600160a01b0316825260208082015190830152604090810151910152565b6060820191508585019450600184019350611f94565b50604088015194507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08782030160608801526120168186611e68565b9450506060870151925061202d6080870184611ef9565b60808701516001600160a01b031661010087015260a090960151151595909401949094529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561209a5761209a612058565b92915050565b6000606082840312156120b257600080fd5b611b228383611ca5565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036120ed576120ed612058565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b813561212e81611af0565b6001600160a01b0381167fffffffffffffffffffffffff00000000000000000000000000000000000000008354161782555060208201356001820155604082013560028201556003810160608301356003811061218a57600080fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541660ff8216811783555050505050565b6000602082840312156121cf57600080fd5b8151611b2281611b29565b6000602082840312156121ec57600080fd5b5051919050565b60006020828403121561220557600080fd5b8151611b2281611af056000000000000000000000000d8253782c45a12053594b9deb72d8e8ab2fca54c000000000000000000000000d8253782c45a12053594b9deb72d8e8ab2fca54c

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101355760003560e01c806369cfdf74116100b2578063dc16426011610081578063ed8a4bca11610066578063ed8a4bca146102c1578063f3917bd2146102d4578063f8d12a41146102e757600080fd5b8063dc1642601461029b578063e43252d7146102ae57600080fd5b806369cfdf74146102595780638ab1d6811461026257806397cbd5b514610275578063bb9572911461028857600080fd5b806323bf2f67116101095780634118b070116100ee5780634118b070146101f457806353e330f214610206578063572b6c051461021957600080fd5b806323bf2f67146101885780633552221a146101c957600080fd5b8062fc38b81461013a57806313af40351461014f578063173825d9146101625780631cac4dc914610175575b600080fd5b61014d610148366004611b05565b610307565b005b61014d61015d366004611b05565b61046a565b61014d610170366004611b05565b610521565b61014d610183366004611b47565b6105d2565b6101b4610196366004611b05565b6001600160a01b031660009081526001602052604090205460ff1690565b60405190151581526020015b60405180910390f35b6002546101dc906001600160a01b031681565b6040516001600160a01b0390911681526020016101c0565b6005545b6040519081526020016101c0565b61014d610214366004611b05565b61070a565b6101b4610227366004611b05565b7f000000000000000000000000d8253782c45a12053594b9deb72d8e8ab2fca54c6001600160a01b0390811691161490565b6101f860055481565b61014d610270366004611b05565b610868565b61014d610283366004611b77565b610919565b61014d610296366004611bf4565b6109a8565b61014d6102a9366004611db8565b610ad8565b61014d6102bc366004611b05565b610b37565b6003546101dc906001600160a01b031681565b61014d6102e2366004611b77565b610beb565b6102fa6102f5366004611b77565b610c06565b6040516101c09190611f61565b3360009081526001602052604090205460ff16610350576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381166103c5576040517f161eb54200000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f63616e742073657420616464726573732830290000000000000000000000000060448201526064015b60405180910390fd5b803b600003610400576040517f6a69700800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907fc54464cec915fe977cf453c1adb8e32edda6652965b6a345c32ed4c79a6b75b190600090a35050565b3360009081526001602052604090205460ff166104b3576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038116600081815260016020819052604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169092179091555133917f619792ba07bec101df538ab277befa333e4cf1c0274f11de7be2a9507b9c9a0691a350565b3360009081526001602052604090205460ff1661056a576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03811660008181526001602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555133917fc191551a88c5609788f3532bd94c06479b61b0040eec65f9cd985428ffea643091a350565b3360009081526001602052604090205460ff1661061b576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600660205260409020548214610665576040517fbb4dde3c000000000000000000000000000000000000000000000000000000008152600481018390526024016103bc565b60008281526006602052604090206007810180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000841515021790556106c0610de8565b6001600160a01b0316837f81401af55d5e5b19605b1d723d712d50b4c28b0b355a7aad37c3cdfcd0701756846040516106fd911515815260200190565b60405180910390a3505050565b3360009081526001602052604090205460ff16610753576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381166107c3576040517f161eb54200000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f63616e742073657420616464726573732830290000000000000000000000000060448201526064016103bc565b803b6000036107fe576040517f6a69700800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907fda8be21788d879b5a0e06c4760b930def99e1b439a5751534f60df9fc56ac3c690600090a35050565b3360009081526001602052604090205460ff166108b1576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03811660008181526004602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555133917fd288ab5da2e1f37cf384a1565a3f905ad289b092fbdd31950dbbfef148c04f8891a350565b610921610e4a565b6002546001600160a01b03163314610965576040517fb8cfdf8700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61096e81610ebd565b604051339082907f8c2f4bbdd223372eba908078d1988d3fda491bafc476c076d4336d86feaac82690600090a36109a56001600055565b50565b3360009081526001602052604090205460ff166109f1576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006109fc60055490565b610a07906001612087565b9050610abd818787808060200260200160405190810160405280939291908181526020016000905b82821015610a5b57610a4c606083028601368190038101906120a0565b81526020019060010190610a2f565b50505050508686808060200260200160405190810160405280939291908181526020016000905b82821015610aae57610a9f606083028601368190038101906120a0565b81526020019060010190610a82565b50505050508560016000611213565b600560008154610acc906120bc565b90915550505050505050565b3360009081526001602052604090205460ff16610b21576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b3085858585856001611213565b5050505050565b3360009081526001602052604090205460ff16610b80576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03811660008181526004602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555133917f0c4b48e75a1f7ab0a9a2f786b5d6c1f7789020403bff177fb54d46edb89ccc0091a350565b610bf3610e4a565b610bfc81610ebd565b6109a56001600055565b610c0e611a2f565b600660008381526020019081526020016000206040518060c00160405290816000820154815260200160018201805480602002602001604051908101604052809291908181526020016000905b82821015610cb0576000848152602090819020604080516060810182526003860290920180546001600160a01b0316835260018082015484860152600290910154918301919091529083529092019101610c5b565b50505050815260200160028201805480602002602001604051908101604052809291908181526020016000905b82821015610d32576000848152602090819020604080516060810182526003860290920180546001600160a01b0316835260018082015484860152600290910154918301919091529083529092019101610cdd565b50505090825250604080516080810182526003840180546001600160a01b031682526004850154602083810191909152600586015493830193909352600685015492909301929091606083019060ff166002811115610d9357610d93611eca565b6002811115610da457610da4611eca565b9052508152600791909101546001600160a01b038116602083015274010000000000000000000000000000000000000000900460ff16151560409091015292915050565b60007f000000000000000000000000d8253782c45a12053594b9deb72d8e8ab2fca54c6001600160a01b03163303610e4557507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b503390565b600260005403610eb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016103bc565b6002600055565b6000818152600660205260409020600781015474010000000000000000000000000000000000000000900460ff16610f24576040517f2fc63a09000000000000000000000000000000000000000000000000000000008152600481018390526024016103bc565b604080516080810182526003830180546001600160a01b0316825260048401546020830152600584015492820192909252600683015460009290606083019060ff166002811115610f7757610f77611eca565b6002811115610f8857610f88611eca565b90525080519091506001600160a01b031615610fa757610fa781611636565b600182015460005b818110156110b0576000846001018281548110610fce57610fce6120f4565b600091825260209182902060408051606081018252600390930290910180546001600160a01b031680845260018201549484019490945260020154908201529150630990b67e61101c610de8565b602084015160408086015190517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b03909316600484015260248301919091526044820152606401600060405180830381600087803b15801561108c57600080fd5b505af11580156110a0573d6000803e3d6000fd5b5050505081600101915050610faf565b50600283015460005b818110156111c15760008560020182815481106110d8576110d86120f4565b600091825260209182902060408051606081018252600390930290910180546001600160a01b0316808452600182015494840194909452600201549082015291506367087cf9611126610de8565b602084015160408086015190517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b039093166004840152602483018c905260448301919091526064820152608401600060405180830381600087803b15801561119d57600080fd5b505af11580156111b1573d6000803e3d6000fd5b50505050816001019150506110b9565b506111ca610de8565b6001600160a01b03167f1914df0e092e50096eec94a2c4eb530f37d294e6b836499035312d8c033b1b7a8660405161120491815260200190565b60405180910390a25050505050565b6000868152600660205260409020548614801561122e575080155b15611268576040517f449e38d4000000000000000000000000000000000000000000000000000000008152600481018790526024016103bc565b60008681526006602052604090205486148015906112835750805b156112bd576040517fbb4dde3c000000000000000000000000000000000000000000000000000000008152600481018790526024016103bc565b8451845160008290036112fc576040517f078c300a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611336576040517f11d427d900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006113456020870187611b05565b6001600160a01b0316146113a0576113676113636020870187611b05565b3b90565b6000036113a0576040517f6a69700800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008881526006602052604090208881556113b9610de8565b6007820180546001600160a01b03929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909216919091177401000000000000000000000000000000000000000087151502179055856003820161141f8282612123565b506114309050600182016000611a8b565b60005b838110156114ea57611461898281518110611450576114506120f4565b60200260200101516000015161175c565b81600101898281518110611477576114776120f4565b602090810291909101810151825460018082018555600094855293839020825160039092020180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0390921691909117815591810151828401556040015160029091015501611433565b506114f9600282016000611a8b565b60005b828110156115a257611519888281518110611450576114506120f4565b8160020188828151811061152f5761152f6120f4565b602090810291909101810151825460018082018555600094855293839020825160039092020180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909216919091178155918101518284015560400151600290910155016114fc565b5083156115ec576115b1610de8565b6001600160a01b0316897f912747a2c1131151700deb4729f4d22c8f696d2eb38845d781d7cb3c671063a860405160405180910390a361162b565b6115f4610de8565b6001600160a01b0316897fcaa26b4e405345650cea2a9c6c1a0318cd5530c48ef83bad7b115065212c5a4660405160405180910390a35b505050505050505050565b60008160600151600281111561164e5761164e611eca565b148015611661575061165f8161187b565b155b15611698576040517f3f9b4c5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001816060015160028111156116b0576116b0611eca565b1480156116c357506116c181611926565b155b156116fa576040517f3f9b4c5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028160600151600281111561171257611712611eca565b1480156117255750611723816119c0565b155b156109a5576040517f3f9b4c5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b803b600003611797576040517f6a69700800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03811660009081526004602052604090205460ff1615801561184457506003546040517f9bb9c4820000000000000000000000000000000000000000000000000000000081526001600160a01b03838116600483015290911690639bb9c48290602401602060405180830381865afa15801561181e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184291906121bd565b155b156109a5576040517f46eba53d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000816040015182600001516001600160a01b03166370a0823161189d610de8565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b0390911660048201526024015b602060405180830381865afa1580156118fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061191e91906121da565b101592915050565b6000611930610de8565b6001600160a01b031682600001516001600160a01b0316636352211e84602001516040518263ffffffff1660e01b815260040161196f91815260200190565b602060405180830381865afa15801561198c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b091906121f3565b6001600160a01b03161492915050565b6000816040015182600001516001600160a01b031662fdd58e6119e1610de8565b60208601516040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b03909216600483015260248201526044016118dd565b6040518060c00160405280600081526020016060815260200160608152602001611a776040805160808101825260008082526020820181905291810182905290606082015290565b815260006020820181905260409091015290565b50805460008255600302906000526020600020908101906109a591905b80821115611aec5780547fffffffffffffffffffffffff00000000000000000000000000000000000000001681556000600182018190556002820155600301611aa8565b5090565b6001600160a01b03811681146109a557600080fd5b600060208284031215611b1757600080fd5b8135611b2281611af0565b9392505050565b80151581146109a557600080fd5b8035611b4281611b29565b919050565b60008060408385031215611b5a57600080fd5b823591506020830135611b6c81611b29565b809150509250929050565b600060208284031215611b8957600080fd5b5035919050565b60008083601f840112611ba257600080fd5b50813567ffffffffffffffff811115611bba57600080fd5b602083019150836020606083028501011115611bd557600080fd5b9250929050565b600060808284031215611bee57600080fd5b50919050565b600080600080600060c08688031215611c0c57600080fd5b853567ffffffffffffffff80821115611c2457600080fd5b611c3089838a01611b90565b90975095506020880135915080821115611c4957600080fd5b50611c5688828901611b90565b9094509250611c6a90508760408801611bdc565b90509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060608284031215611cb757600080fd5b6040516060810181811067ffffffffffffffff82111715611cda57611cda611c76565b6040529050808235611ceb81611af0565b8082525060208301356020820152604083013560408201525092915050565b600067ffffffffffffffff80841115611d2557611d25611c76565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8660051b011681018181108382111715611d6757611d67611c76565b604052848152915050602080820190606090818602850187811115611d8b57600080fd5b855b81811015611dac57611d9f8982611ca5565b8552938201938301611d8d565b50505050509392505050565b60008060008060006101008688031215611dd157600080fd5b85359450602086013567ffffffffffffffff80821115611df057600080fd5b818801915088601f830112611e0457600080fd5b611e1389833560208501611d0a565b95506040880135915080821115611e2957600080fd5b508601601f81018813611e3b57600080fd5b611e4a88823560208401611d0a565b935050611e5a8760608801611bdc565b9150611c6a60e08701611b37565b600081518084526020808501945080840160005b83811015611ebf57611eac87835180516001600160a01b0316825260208082015190830152604090810151910152565b6060969096019590820190600101611e7c565b509495945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6001600160a01b0381511682526020810151602083015260408101516040830152606081015160038110611f56577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b806060840152505050565b60208082528251828201528281015161012060408401819052815161014085018190526000939283019184916101608701905b80841015611fda57611fc482865180516001600160a01b0316825260208082015190830152604090810151910152565b6060820191508585019450600184019350611f94565b50604088015194507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08782030160608801526120168186611e68565b9450506060870151925061202d6080870184611ef9565b60808701516001600160a01b031661010087015260a090960151151595909401949094529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561209a5761209a612058565b92915050565b6000606082840312156120b257600080fd5b611b228383611ca5565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036120ed576120ed612058565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b813561212e81611af0565b6001600160a01b0381167fffffffffffffffffffffffff00000000000000000000000000000000000000008354161782555060208201356001820155604082013560028201556003810160608301356003811061218a57600080fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541660ff8216811783555050505050565b6000602082840312156121cf57600080fd5b8151611b2281611b29565b6000602082840312156121ec57600080fd5b5051919050565b60006020828403121561220557600080fd5b8151611b2281611af056

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

000000000000000000000000d8253782c45a12053594b9deb72d8e8ab2fca54c000000000000000000000000d8253782c45a12053594b9deb72d8e8ab2fca54c

-----Decoded View---------------
Arg [0] : trustedForwarder (address): 0xd8253782c45a12053594b9deB72d8e8aB2Fca54c
Arg [1] : _gelatoRelay (address): 0xd8253782c45a12053594b9deB72d8e8aB2Fca54c

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000d8253782c45a12053594b9deb72d8e8ab2fca54c
Arg [1] : 000000000000000000000000d8253782c45a12053594b9deb72d8e8ab2fca54c


Block Transaction Gas Used Reward
view all blocks produced

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

Validator Index Block Amount
View All Withdrawals

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

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