Unichain Sepolia Testnet

Contract

0x1CB663EBf8F4cf7D988D783Df8a93B1AA85f331F
Source Code Source Code

Overview

ETH Balance

0 ETH

More Info

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Amount
Create Condition...197762852025-05-07 14:38:33282 days ago1746628713IN
0x1CB663EB...AA85f331F
0 ETH0.000000040.00000136
Create Condition...197762812025-05-07 14:38:29282 days ago1746628709IN
0x1CB663EB...AA85f331F
0 ETH0.000000040.00000137
Create Flat CFM197762782025-05-07 14:38:26282 days ago1746628706IN
0x1CB663EB...AA85f331F
0 ETH0.00000010.00000137
Create Condition...196976722025-05-06 16:48:20283 days ago1746550100IN
0x1CB663EB...AA85f331F
0 ETH0.000036790.02500068
Create Condition...196976692025-05-06 16:48:17283 days ago1746550097IN
0x1CB663EB...AA85f331F
0 ETH0.000038580.02500068
Create Condition...196976672025-05-06 16:48:15283 days ago1746550095IN
0x1CB663EB...AA85f331F
0 ETH0.000038390.02500068
Create Condition...196976642025-05-06 16:48:12283 days ago1746550092IN
0x1CB663EB...AA85f331F
0 ETH0.000038770.02500068
Create Condition...196976612025-05-06 16:48:09283 days ago1746550089IN
0x1CB663EB...AA85f331F
0 ETH0.00003840.02500068
Create Condition...196976582025-05-06 16:48:06283 days ago1746550086IN
0x1CB663EB...AA85f331F
0 ETH0.000037840.02500068
Create Condition...196976552025-05-06 16:48:03283 days ago1746550083IN
0x1CB663EB...AA85f331F
0 ETH0.000038210.02500068
Create Condition...196976522025-05-06 16:48:00283 days ago1746550080IN
0x1CB663EB...AA85f331F
0 ETH0.000038590.02500068
Create Condition...196976502025-05-06 16:47:58283 days ago1746550078IN
0x1CB663EB...AA85f331F
0 ETH0.000038210.02500068
Create Condition...196976472025-05-06 16:47:55283 days ago1746550075IN
0x1CB663EB...AA85f331F
0 ETH0.000038580.02500068
Create Condition...196976452025-05-06 16:47:53283 days ago1746550073IN
0x1CB663EB...AA85f331F
0 ETH0.000038030.02500068
Create Condition...196976412025-05-06 16:47:49283 days ago1746550069IN
0x1CB663EB...AA85f331F
0 ETH0.00003680.02500068
Create Flat CFM196976382025-05-06 16:47:46283 days ago1746550066IN
0x1CB663EB...AA85f331F
0 ETH0.000019940.02500068
Create Condition...196975932025-05-06 16:47:01283 days ago1746550021IN
0x1CB663EB...AA85f331F
0 ETH0.000000020.00000137
Create Flat CFM196975912025-05-06 16:46:59283 days ago1746550019IN
0x1CB663EB...AA85f331F
0 ETH0.00000010.00000137
Create Condition...196791832025-05-06 11:40:11283 days ago1746531611IN
0x1CB663EB...AA85f331F
0 ETH0.000000210.00000136
Create Condition...196791802025-05-06 11:40:08283 days ago1746531608IN
0x1CB663EB...AA85f331F
0 ETH0.000000210.00000136
Create Condition...196791772025-05-06 11:40:05283 days ago1746531605IN
0x1CB663EB...AA85f331F
0 ETH0.000000210.00000136
Create Condition...196791742025-05-06 11:40:02283 days ago1746531602IN
0x1CB663EB...AA85f331F
0 ETH0.000000210.00000136
Create Condition...196791722025-05-06 11:40:00283 days ago1746531600IN
0x1CB663EB...AA85f331F
0 ETH0.000000210.00000136
Create Condition...196791692025-05-06 11:39:57283 days ago1746531597IN
0x1CB663EB...AA85f331F
0 ETH0.000000210.00000136
Create Condition...196791672025-05-06 11:39:55283 days ago1746531595IN
0x1CB663EB...AA85f331F
0 ETH0.000000210.00000136
View all transactions

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To Amount
197762852025-05-07 14:38:33282 days ago1746628713
0x1CB663EB...AA85f331F
0 ETH
197762852025-05-07 14:38:33282 days ago1746628713
0x1CB663EB...AA85f331F
0 ETH
197762852025-05-07 14:38:33282 days ago1746628713
0x1CB663EB...AA85f331F
0 ETH
197762852025-05-07 14:38:33282 days ago1746628713
0x1CB663EB...AA85f331F
0 ETH
197762852025-05-07 14:38:33282 days ago1746628713
0x1CB663EB...AA85f331F
0 ETH
197762852025-05-07 14:38:33282 days ago1746628713
0x1CB663EB...AA85f331F
0 ETH
197762852025-05-07 14:38:33282 days ago1746628713
0x1CB663EB...AA85f331F
0 ETH
197762852025-05-07 14:38:33282 days ago1746628713
0x1CB663EB...AA85f331F
0 ETH
197762852025-05-07 14:38:33282 days ago1746628713
0x1CB663EB...AA85f331F
0 ETH
197762852025-05-07 14:38:33282 days ago1746628713
0x1CB663EB...AA85f331F
0 ETH
197762852025-05-07 14:38:33282 days ago1746628713
0x1CB663EB...AA85f331F
0 ETH
197762852025-05-07 14:38:33282 days ago1746628713
0x1CB663EB...AA85f331F
0 ETH
197762852025-05-07 14:38:33282 days ago1746628713
0x1CB663EB...AA85f331F
0 ETH
197762852025-05-07 14:38:33282 days ago1746628713
0x1CB663EB...AA85f331F
0 ETH
197762852025-05-07 14:38:33282 days ago1746628713
0x1CB663EB...AA85f331F
0 ETH
197762852025-05-07 14:38:33282 days ago1746628713
0x1CB663EB...AA85f331F
0 ETH
197762852025-05-07 14:38:33282 days ago1746628713
0x1CB663EB...AA85f331F
0 ETH
197762852025-05-07 14:38:33282 days ago1746628713
0x1CB663EB...AA85f331F
 Contract Creation0 ETH
197762852025-05-07 14:38:33282 days ago1746628713
0x1CB663EB...AA85f331F
0 ETH
197762812025-05-07 14:38:29282 days ago1746628709
0x1CB663EB...AA85f331F
0 ETH
197762812025-05-07 14:38:29282 days ago1746628709
0x1CB663EB...AA85f331F
0 ETH
197762812025-05-07 14:38:29282 days ago1746628709
0x1CB663EB...AA85f331F
0 ETH
197762812025-05-07 14:38:29282 days ago1746628709
0x1CB663EB...AA85f331F
0 ETH
197762812025-05-07 14:38:29282 days ago1746628709
0x1CB663EB...AA85f331F
0 ETH
197762812025-05-07 14:38:29282 days ago1746628709
0x1CB663EB...AA85f331F
0 ETH
View All Internal Transactions

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FlatCFMFactory

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 200 runs

Other Settings:
shanghai EvmVersion, GNU GPLv3 license

Contract Source Code (Solidity Standard Json-Input format)

// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.20;

import "@openzeppelin-contracts/proxy/Clones.sol";
import "@openzeppelin-contracts/token/ERC20/IERC20.sol";
import "@openzeppelin-contracts/token/ERC20/extensions/IERC20Metadata.sol";

import "./interfaces/IWrapped1155Factory.sol";
import "./interfaces/IConditionalTokens.sol";
import "./libs/String31.sol";
import "./FlatCFMOracleAdapter.sol";
import "./FlatCFM.sol";
import "./ConditionalScalarMarket.sol";
import {
    FlatCFMQuestionParams,
    GenericScalarQuestionParams,
    ScalarParams,
    WrappedConditionalTokensData,
    ConditionalScalarCTParams
} from "./Types.sol";

/// @title FlatCFMFactory
/// @notice Factory contract to create "flat" Conditional Funding Markets (CFMs)
///         and conditional scalar markets for each outcome.
contract FlatCFMFactory {
    using Clones for address;
    using String31 for string;

    /// @dev Container struct for storing Conditional Scalar Market deployment
    /// parameters temporarily.
    struct DeploymentParams {
        IERC20 collateralToken;
        uint256 metricTemplateId;
        GenericScalarQuestionParams genericScalarQuestionParams;
        bytes32 decisionConditionId;
        string[] outcomeNames;
    }

    /// @notice Maximum outcome count for decision markets (+1 for 'Invalid').
    uint256 public constant MAX_OUTCOME_COUNT = 255;

    /// @notice Maximum length for each outcome name to fit in a String31 slot.
    uint256 public constant MAX_OUTCOME_NAME_LENGTH = 25;

    /// @notice Gnosis Conditional Tokens contract.
    IConditionalTokens public immutable conditionalTokens;

    /// @notice Factory for wrapping conditional tokens into ERC20.
    IWrapped1155Factory public immutable wrapped1155Factory;

    /// @notice Implementation for cloned FlatCFM logic.
    address public immutable flatCfmImplementation;

    /// @notice Implementation for cloned ConditionalScalarMarket logic.
    address public immutable conditionalScalarMarketImplementation;

    /// @dev Tracks which outcome index is to be deployed next for each FlatCFM.
    mapping(FlatCFM => uint256) public nextOutcomeToDeploy;

    /// @dev Stores deployment parameters for each FlatCFM until
    ///      all its conditional scalar markets are created.
    mapping(FlatCFM => DeploymentParams) public paramsToDeploy;

    error InvalidOutcomeCount();
    error InvalidOutcomeNameLength(string outcomeName);
    error NoConditionalScalarMarketToDeploy();

    /// @notice Emitted when a new FlatCFM is created.
    /// @param market Address of the new FlatCFM contract.
    /// @param conditionId Conditional Tokens' condition ID.
    event FlatCFMCreated(address indexed market, bytes32 conditionId, address deployer);

    /// @notice Emitted when a new ConditionalScalarMarket is created for a specific
    ///         outcome of a FlatCFM.
    /// @param decisionMarket The associated FlatCFM.
    /// @param conditionalMarket The newly deployed ConditionalScalarMarket.
    /// @param outcomeIndex Which outcome index this market corresponds to.
    event ConditionalScalarMarketCreated(
        address indexed decisionMarket, address indexed conditionalMarket, uint256 outcomeIndex
    );

    /// @param _conditionalTokens Gnosis Conditional Tokens contract.
    /// @param _wrapped1155Factory Factory for ERC20-wrapped positions.
    constructor(IConditionalTokens _conditionalTokens, IWrapped1155Factory _wrapped1155Factory) {
        conditionalTokens = _conditionalTokens;
        wrapped1155Factory = _wrapped1155Factory;
        flatCfmImplementation = address(new FlatCFM());
        conditionalScalarMarketImplementation = address(new ConditionalScalarMarket());
    }

    /// @notice Creates a new FlatCFM (decision market).
    /// @dev 1) Asks a "decision question" via the oracle adapter.
    ///      2) Prepares condition in ConditionalTokens if not already prepared.
    ///      3) Stores parameters for subsequent scalar market deployments.
    ///      4) Deploys a FlatCFM clone.
    /// @param oracleAdapter Oracle adapter to call for question creation.
    /// @param decisionTemplateId Template ID used by the oracle for a decision question.
    /// @param metricTemplateId Template ID used by the oracle for metric (scalar) questions.
    /// @param flatCFMQParams Struct with outcome names and question opening time.
    /// @param genericScalarQuestionParams Struct with scalar range info and opening time.
    /// @param collateralToken ERC20 token used as the collateral (e.g., DAI).
    /// @param metadataUri Metadata URI for front-ends.
    /// @return cfm Deployed FlatCFM clone address.
    function createFlatCFM(
        FlatCFMOracleAdapter oracleAdapter,
        uint256 decisionTemplateId,
        uint256 metricTemplateId,
        FlatCFMQuestionParams calldata flatCFMQParams,
        GenericScalarQuestionParams calldata genericScalarQuestionParams,
        IERC20 collateralToken,
        string calldata metadataUri
    ) external payable returns (FlatCFM cfm) {
        uint256 outcomeCount = flatCFMQParams.outcomeNames.length;
        if (outcomeCount == 0 || outcomeCount > MAX_OUTCOME_COUNT) {
            revert InvalidOutcomeCount();
        }
        for (uint256 i = 0; i < outcomeCount; i++) {
            string memory outcomeName = flatCFMQParams.outcomeNames[i];
            if (bytes(outcomeName).length > MAX_OUTCOME_NAME_LENGTH) revert InvalidOutcomeNameLength(outcomeName);
        }

        cfm = FlatCFM(flatCfmImplementation.clone());

        bytes32 decisionQuestionId =
            oracleAdapter.askDecisionQuestion{value: msg.value}(decisionTemplateId, flatCFMQParams);

        // +1 for 'Invalid' slot.
        bytes32 decisionConditionId =
            conditionalTokens.getConditionId(address(cfm), decisionQuestionId, outcomeCount + 1);
        if (conditionalTokens.getOutcomeSlotCount(decisionConditionId) == 0) {
            conditionalTokens.prepareCondition(address(cfm), decisionQuestionId, outcomeCount + 1);
        }

        paramsToDeploy[cfm] = DeploymentParams({
            collateralToken: collateralToken,
            metricTemplateId: metricTemplateId,
            genericScalarQuestionParams: genericScalarQuestionParams,
            decisionConditionId: decisionConditionId,
            outcomeNames: flatCFMQParams.outcomeNames
        });

        cfm.initialize(oracleAdapter, conditionalTokens, outcomeCount, decisionQuestionId, metadataUri);

        emit FlatCFMCreated(address(cfm), decisionConditionId, msg.sender);
    }

    /// @notice Creates a ConditionalScalarMarket for the next outcome in the given FlatCFM.
    /// @dev 1) Asks the "metric question" for the outcome name.
    ///      2) Prepares condition if not already prepared.
    ///      3) Updates state for subsequent scalar market deployments.
    ///      4) Deploys a ConditionalScalarMarket clone.
    ///      This function is untrusted, therefore it takes only a FlatCFM as
    ///      argument and fetches related data from the factory storage.
    /// @param cfm The FlatCFM for which to deploy the next scalar market.
    /// @return csm The newly deployed ConditionalScalarMarket.
    function createConditionalScalarMarket(FlatCFM cfm) external payable returns (ConditionalScalarMarket csm) {
        if (paramsToDeploy[cfm].outcomeNames.length == 0) revert NoConditionalScalarMarketToDeploy();

        uint256 outcomeIndex = nextOutcomeToDeploy[cfm];
        FlatCFMOracleAdapter oracleAdapter = cfm.oracleAdapter();
        DeploymentParams memory params = paramsToDeploy[cfm];

        csm = ConditionalScalarMarket(conditionalScalarMarketImplementation.clone());

        WrappedConditionalTokensData memory wrappedCTData;
        ConditionalScalarCTParams memory conditionalScalarCTParams;

        if (outcomeIndex == cfm.outcomeCount() - 1) {
            // Once the final outcome is deployed, clean up storage for this FlatCFM.
            delete nextOutcomeToDeploy[cfm];
            delete paramsToDeploy[cfm];
        } else {
            nextOutcomeToDeploy[cfm]++;
        }

        {
            string memory outcomeName = params.outcomeNames[outcomeIndex];
            bytes32 csmQuestionId = oracleAdapter.askMetricQuestion{value: msg.value}(
                params.metricTemplateId, params.genericScalarQuestionParams, outcomeName
            );

            // 3 outcomes: Short, Long, Invalid
            bytes32 csmConditionId = conditionalTokens.getConditionId(address(csm), csmQuestionId, 3);
            if (conditionalTokens.getOutcomeSlotCount(csmConditionId) == 0) {
                conditionalTokens.prepareCondition(address(csm), csmQuestionId, 3);
            }

            bytes32 decisionCollectionId =
                conditionalTokens.getCollectionId(0, params.decisionConditionId, 1 << outcomeIndex);

            wrappedCTData = _deployWrappedConditionalTokens(
                outcomeName, params.collateralToken, decisionCollectionId, csmConditionId
            );

            conditionalScalarCTParams = ConditionalScalarCTParams({
                questionId: csmQuestionId,
                conditionId: csmConditionId,
                parentCollectionId: decisionCollectionId,
                collateralToken: params.collateralToken
            });
        }

        csm.initialize(
            oracleAdapter,
            conditionalTokens,
            wrapped1155Factory,
            conditionalScalarCTParams,
            ScalarParams({
                minValue: params.genericScalarQuestionParams.scalarParams.minValue,
                maxValue: params.genericScalarQuestionParams.scalarParams.maxValue
            }),
            wrappedCTData
        );

        emit ConditionalScalarMarketCreated(address(cfm), address(csm), outcomeIndex);
    }

    /// @dev Internal helper to deploy three wrapped ERC1155 tokens (Short, Long, Invalid)
    ///      for the nested condition, returning their data.
    function _deployWrappedConditionalTokens(
        string memory outcomeName,
        IERC20 collateralToken,
        bytes32 decisionCollectionId,
        bytes32 csmConditionId
    ) private returns (WrappedConditionalTokensData memory) {
        uint8 decimals = IERC20Metadata(address(collateralToken)).decimals();
        bytes memory shortData = abi.encodePacked(
            string.concat(outcomeName, "-Short").toString31(), string.concat(outcomeName, "-ST").toString31(), decimals
        );
        bytes memory longData = abi.encodePacked(
            string.concat(outcomeName, "-Long").toString31(), string.concat(outcomeName, "-LG").toString31(), decimals
        );
        bytes memory invalidData = abi.encodePacked(
            string.concat(outcomeName, "-Inv").toString31(), string.concat(outcomeName, "-XX").toString31(), decimals
        );

        uint256 shortPosId = conditionalTokens.getPositionId(
            collateralToken, conditionalTokens.getCollectionId(decisionCollectionId, csmConditionId, 1)
        );
        uint256 longPosId = conditionalTokens.getPositionId(
            collateralToken, conditionalTokens.getCollectionId(decisionCollectionId, csmConditionId, 2)
        );
        uint256 invalidPosId = conditionalTokens.getPositionId(
            collateralToken, conditionalTokens.getCollectionId(decisionCollectionId, csmConditionId, 4)
        );

        IERC20 wrappedShort = wrapped1155Factory.requireWrapped1155(conditionalTokens, shortPosId, shortData);
        IERC20 wrappedLong = wrapped1155Factory.requireWrapped1155(conditionalTokens, longPosId, longData);
        IERC20 wrappedInvalid = wrapped1155Factory.requireWrapped1155(conditionalTokens, invalidPosId, invalidData);

        return WrappedConditionalTokensData({
            shortData: shortData,
            longData: longData,
            invalidData: invalidData,
            shortPositionId: shortPosId,
            longPositionId: longPosId,
            invalidPositionId: invalidPosId,
            wrappedShort: wrappedShort,
            wrappedLong: wrappedLong,
            wrappedInvalid: wrappedInvalid
        });
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/Clones.sol)

pragma solidity ^0.8.20;

/**
 * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
 * deploying minimal proxy contracts, also known as "clones".
 *
 * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
 * > a minimal bytecode implementation that delegates all calls to a known, fixed address.
 *
 * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
 * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
 * deterministic method.
 */
library Clones {
    /**
     * @dev A clone instance deployment failed.
     */
    error ERC1167FailedCreateClone();

    /**
     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
     *
     * This function uses the create opcode, which should never revert.
     */
    function clone(address implementation) internal returns (address instance) {
        /// @solidity memory-safe-assembly
        assembly {
            // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
            // of the `implementation` address with the bytecode before the address.
            mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
            // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
            mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
            instance := create(0, 0x09, 0x37)
        }
        if (instance == address(0)) {
            revert ERC1167FailedCreateClone();
        }
    }

    /**
     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
     *
     * This function uses the create2 opcode and a `salt` to deterministically deploy
     * the clone. Using the same `implementation` and `salt` multiple time will revert, since
     * the clones cannot be deployed twice at the same address.
     */
    function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
        /// @solidity memory-safe-assembly
        assembly {
            // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
            // of the `implementation` address with the bytecode before the address.
            mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
            // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
            mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
            instance := create2(0, 0x09, 0x37, salt)
        }
        if (instance == address(0)) {
            revert ERC1167FailedCreateClone();
        }
    }

    /**
     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
     */
    function predictDeterministicAddress(
        address implementation,
        bytes32 salt,
        address deployer
    ) internal pure returns (address predicted) {
        /// @solidity memory-safe-assembly
        assembly {
            let ptr := mload(0x40)
            mstore(add(ptr, 0x38), deployer)
            mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)
            mstore(add(ptr, 0x14), implementation)
            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)
            mstore(add(ptr, 0x58), salt)
            mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))
            predicted := keccak256(add(ptr, 0x43), 0x55)
        }
    }

    /**
     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
     */
    function predictDeterministicAddress(
        address implementation,
        bytes32 salt
    ) internal view returns (address predicted) {
        return predictDeterministicAddress(implementation, salt, address(this));
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

// SPDX-License-Identifier: GPL-3.0-or-later
// Maps to: https://github.com/gnosis/1155-to-20/blob/master/contracts/Wrapped1155Factory.sol
pragma solidity 0.8.20;

import "@openzeppelin-contracts/token/ERC20/IERC20.sol";
import "@openzeppelin-contracts/token/ERC1155/IERC1155.sol";

interface IWrapped1155Factory {
    function requireWrapped1155(IERC1155 multiToken, uint256 tokenId, bytes calldata data) external returns (IERC20);

    function unwrap(IERC1155 multiToken, uint256 tokenId, uint256 amount, address recipient, bytes calldata data)
        external;
}

// SPDX-License-Identifier: GPL-3.0-or-later
// Maps to: https://github.com/gnosis/conditional-tokens-contracts/blob/master/contracts/ConditionalTokens.sol
pragma solidity 0.8.20;

import "@openzeppelin-contracts/token/ERC20/IERC20.sol";
import "@openzeppelin-contracts/token/ERC1155/IERC1155.sol";

interface IConditionalTokens is IERC1155 {
    function prepareCondition(address oracle, bytes32 questionId, uint256 outcomeSlotCount) external;

    function reportPayouts(bytes32 questionId, uint256[] calldata payouts) external;

    function splitPosition(
        IERC20 collateralToken,
        bytes32 parentCollectionId,
        bytes32 conditionId,
        uint256[] calldata partition,
        uint256 amount
    ) external;

    function mergePositions(
        IERC20 collateralToken,
        bytes32 parentCollectionId,
        bytes32 conditionId,
        uint256[] calldata partition,
        uint256 amount
    ) external;

    function redeemPositions(
        IERC20 collateralToken,
        bytes32 parentCollectionId,
        bytes32 conditionId,
        uint256[] calldata indexSets
    ) external;

    function getConditionId(address oracle, bytes32 questionId, uint256 outcomeSlotCount)
        external
        pure
        returns (bytes32);

    function getCollectionId(bytes32 parentCollectionId, bytes32 conditionId, uint256 indexSet)
        external
        view
        returns (bytes32);

    function getPositionId(IERC20 collateralToken, bytes32 collectionId) external pure returns (uint256);

    function payoutNumerators(bytes32 conditionId, uint256 index) external view returns (uint256);

    function payoutDenominator(bytes32 conditionId) external view returns (uint256);

    function getOutcomeSlotCount(bytes32 conditionId) external view returns (uint256);
}

// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.20;

library String31 {
    error InvalidString31Length(string value);

    /// @dev Encodes a short string (less than than 31 bytes long) to leverage
    /// short string layout.
    /// <https://docs.soliditylang.org/en/v0.8.1/internals/layout_in_storage.html#bytes-and-string>
    /// From https://github.com/gnosis/1155-to-20/pull/4#discussion_r573630922
    function toString31(string memory value) internal pure returns (bytes32 encodedString) {
        uint256 length = bytes(value).length;
        if (length > 31) revert InvalidString31Length(value);

        // Read the right-padded string data, which is guaranteed to fit into a single
        // word because its length is less than 32.
        assembly {
            encodedString := mload(add(value, 0x20))
        }

        // Now mask the string data, this ensures that the bytes past the string length
        // are all 0s.
        bytes32 mask = bytes32(type(uint256).max << ((32 - length) << 3));
        encodedString = encodedString & mask;

        // Finally, set the least significant byte to be the hex length of the encoded
        // string, that is its byte-length times two.
        encodedString = encodedString | bytes32(length << 1);
    }
}

// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.20;

import "./interfaces/IConditionalTokens.sol";
import {FlatCFMQuestionParams, GenericScalarQuestionParams} from "./Types.sol";

/// @title FlatCFMOracleAdapter
/// @notice Abstract adapter that defines how to ask decision and metric questions,
///         retrieve answers, and detect invalid outcomes.
abstract contract FlatCFMOracleAdapter {
    /// @notice Asks a "decision" (multi-outcome) question to the oracle.
    /// @param decisionTemplateId The template ID for the oracle's question format.
    /// @param flatCFMQuestionParams Includes outcome names and opening time.
    /// @return A unique questionId representing this question on the oracle.
    function askDecisionQuestion(uint256 decisionTemplateId, FlatCFMQuestionParams calldata flatCFMQuestionParams)
        external
        payable
        virtual
        returns (bytes32);

    /// @notice Asks a "metric" (scalar) question to the oracle.
    /// @param metricTemplateId The template ID for the oracle's scalar question format.
    /// @param genericScalarQuestionParams Struct containing scalar range data and opening time.
    /// @param outcomeName Descriptive name for this scalar outcome.
    /// @return A unique questionId representing this question on the oracle.
    function askMetricQuestion(
        uint256 metricTemplateId,
        GenericScalarQuestionParams calldata genericScalarQuestionParams,
        string memory outcomeName
    ) external payable virtual returns (bytes32);

    /// @notice Gets the final answer for a previously asked question.
    /// @param questionId The question ID on the oracle.
    /// @return The raw answer as returned by the oracle.
    function getAnswer(bytes32 questionId) external view virtual returns (bytes32);

    /// @notice Checks if an answer indicates an invalid result.
    /// @param answer The oracle answer.
    /// @return True if the answer maps to an Invalid outcome, false otherwise.
    function isInvalid(bytes32 answer) external pure virtual returns (bool);
}

// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.20;

import "./interfaces/IConditionalTokens.sol";
import "./FlatCFMOracleAdapter.sol";

/// @title FlatCFM
/// @notice A "flat" decision market contract that uses a bitmask-based resolution for multiple outcomes.
contract FlatCFM {
    /// @notice Oracle adapter responsible for question handling.
    FlatCFMOracleAdapter public oracleAdapter;

    /// @notice Gnosis Conditional Tokens contract.
    IConditionalTokens public conditionalTokens;

    /// @notice ID of the underlying question used to finalize the condition in the conditional tokens contract.
    bytes32 public questionId;

    /// @notice Number of outcomes (excluding the extra 'Invalid' slot).
    uint256 public outcomeCount;

    /// @notice Metadata URI for referencing external info or front-ends.
    string public metadataUri;

    /// @dev Initialization guard.
    bool public initialized;

    error AlreadyInitialized();

    /// @notice Initializes the FlatCFM contract (called once by the factory).
    /// @param _oracleAdapter Adapter to ask questions and get answers on the
    ///                       underlying oracle.
    /// @param _conditionalTokens Gnosis Conditional Tokens contract address.
    /// @param _outcomeCount Number of outcomes (excluding 'Invalid').
    /// @param _questionId The question ID used in the conditional tokens condition.
    /// @param _metadataUri Metadata URI.
    function initialize(
        FlatCFMOracleAdapter _oracleAdapter,
        IConditionalTokens _conditionalTokens,
        uint256 _outcomeCount,
        bytes32 _questionId,
        string memory _metadataUri
    ) external {
        if (initialized) revert AlreadyInitialized();
        initialized = true;

        oracleAdapter = _oracleAdapter;
        conditionalTokens = _conditionalTokens;
        outcomeCount = _outcomeCount;
        questionId = _questionId;
        metadataUri = _metadataUri;
    }

    /// @notice Resolves the condition in the conditional tokens contract based on the oracle answer.
    /// @dev Uses bitmask logic: each bit in the numeric answer indicates whether
    ///      that outcome is true (1) or false (0). The extra 'Invalid' slot is used
    ///      if the answer is out of range or flagged invalid.
    function resolve() external {
        bytes32 answer = oracleAdapter.getAnswer(questionId);
        uint256[] memory payouts = new uint256[](outcomeCount + 1);
        uint256 numericAnswer = uint256(answer);

        if (numericAnswer == 0 || numericAnswer >= (1 << outcomeCount) || oracleAdapter.isInvalid(answer)) {
            // 'Invalid' receives full payout
            payouts[outcomeCount] = 1;
        } else {
            // Each bit (i-th) in numericAnswer indicates if outcome i is 1 or 0
            for (uint256 i = 0; i < outcomeCount; i++) {
                payouts[i] = (numericAnswer >> i) & 1;
            }
        }
        conditionalTokens.reportPayouts(questionId, payouts);
    }
}

// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.20;

import "@openzeppelin-contracts/token/ERC20/IERC20.sol";
import "@openzeppelin-contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin-contracts/token/ERC1155/utils/ERC1155Holder.sol";

import "./interfaces/IWrapped1155Factory.sol";
import "./interfaces/IConditionalTokens.sol";
import {ScalarParams, ConditionalScalarCTParams, WrappedConditionalTokensData} from "./Types.sol";
import "./FlatCFMOracleAdapter.sol";

/// @title ConditionalScalarMarket
/// @notice Creates a scalar (range-based) conditional market for a single outcome.
contract ConditionalScalarMarket is ERC1155Holder {
    /// @notice Oracle adapter for scalar question resolution.
    FlatCFMOracleAdapter public oracleAdapter;

    /// @notice Gnosis Conditional Tokens contract.
    IConditionalTokens public conditionalTokens;

    /// @notice Factory for wrapping ERC1155 positions into ERC20s.
    IWrapped1155Factory public wrapped1155Factory;

    /// @notice Struct containing the Conditional Tokens parameters.
    ConditionalScalarCTParams public ctParams;

    /// @notice Defines the numeric range [minValue, maxValue] for the scalar outcome.
    ScalarParams public scalarParams;

    /// @notice Stores references to the wrapped positions for short/long/invalid.
    WrappedConditionalTokensData public wrappedCTData;

    /// @dev Initialization guard.
    bool public initialized;

    error AlreadyInitialized();
    error WrappedShortTransferFailed();
    error WrappedLongTransferFailed();
    error WrappedInvalidTransferFailed();

    /// @notice Initializes a freshly cloned ConditionalScalarMarket.
    /// @param _oracleAdapter Oracle adapter for answer resolution.
    /// @param _conditionalTokens The Gnosis Conditional Tokens contract address.
    /// @param _wrapped1155Factory Factory for wrapping/unwrapping ERC1155 positions.
    /// @param _conditionalScalarCTParams Condition Tokens data.
    /// @param _scalarParams Range for the scalar question.
    /// @param _wrappedCTData Wrapped Short/Long/Invalid positions.
    function initialize(
        FlatCFMOracleAdapter _oracleAdapter,
        IConditionalTokens _conditionalTokens,
        IWrapped1155Factory _wrapped1155Factory,
        ConditionalScalarCTParams memory _conditionalScalarCTParams,
        ScalarParams memory _scalarParams,
        WrappedConditionalTokensData memory _wrappedCTData
    ) external {
        if (initialized) revert AlreadyInitialized();
        initialized = true;

        oracleAdapter = _oracleAdapter;
        conditionalTokens = _conditionalTokens;
        wrapped1155Factory = _wrapped1155Factory;
        ctParams = _conditionalScalarCTParams;
        scalarParams = _scalarParams;
        wrappedCTData = _wrappedCTData;
    }

    /// @notice Resolves the scalar condition in the conditional tokens contract.
    /// @dev Allocates payouts to Short/Long/Invalid based on final numeric value.
    ///      The invalid outcome  gets the full payout if the oralce returns the
    ///      invalid value.
    function resolve() external {
        bytes32 answer = oracleAdapter.getAnswer(ctParams.questionId);
        uint256[] memory payouts = new uint256[](3);

        if (oracleAdapter.isInvalid(answer)) {
            // 'Invalid' outcome receives full payout
            payouts[2] = 1;
        } else {
            uint256 numericAnswer = uint256(answer);
            if (numericAnswer <= scalarParams.minValue) {
                payouts[0] = 1; // short
            } else if (numericAnswer >= scalarParams.maxValue) {
                payouts[1] = 1; // long
            } else {
                payouts[0] = scalarParams.maxValue - numericAnswer;
                payouts[1] = numericAnswer - scalarParams.minValue;
            }
        }
        conditionalTokens.reportPayouts(ctParams.questionId, payouts);
    }

    /// @notice Splits "decision outcome" ERC1155 into short/long/invalid ERC20s.
    /// @dev Burns the user’s decision outcome tokens, mints short/long/invalid ERC1155,
    ///      then wraps them into ERC20 and transfers to the user.
    /// @param amount Number of decision outcome tokens to split.
    function split(uint256 amount) external {
        // User transfers decision outcome ERC1155 to this contract.
        conditionalTokens.safeTransferFrom(
            msg.sender,
            address(this),
            conditionalTokens.getPositionId(ctParams.collateralToken, ctParams.parentCollectionId),
            amount,
            ""
        );

        // Split position. Decision outcome ERC1155 are burnt. Conditional
        // Short/Long/Invalid ERC1155 are minted to the contract.
        conditionalTokens.splitPosition(
            ctParams.collateralToken, ctParams.parentCollectionId, ctParams.conditionId, _discreetPartition(), amount
        );

        // Contract transfers Short/Long/Invalid ERC1155 to wrapped1155Factory and
        // gets back Short/Long/Invalid ERC20.
        conditionalTokens.safeTransferFrom(
            address(this), address(wrapped1155Factory), wrappedCTData.shortPositionId, amount, wrappedCTData.shortData
        );
        conditionalTokens.safeTransferFrom(
            address(this), address(wrapped1155Factory), wrappedCTData.longPositionId, amount, wrappedCTData.longData
        );
        conditionalTokens.safeTransferFrom(
            address(this),
            address(wrapped1155Factory),
            wrappedCTData.invalidPositionId,
            amount,
            wrappedCTData.invalidData
        );

        // Contract transfers Short/Long/Invalid ERC20 to user.
        if (!wrappedCTData.wrappedShort.transfer(msg.sender, amount)) {
            revert WrappedShortTransferFailed();
        }
        if (!wrappedCTData.wrappedLong.transfer(msg.sender, amount)) {
            revert WrappedLongTransferFailed();
        }
        if (!wrappedCTData.wrappedInvalid.transfer(msg.sender, amount)) {
            revert WrappedInvalidTransferFailed();
        }
    }

    /// @notice Merges short/long/invalid ERC20 back into a single "decision outcome" ERC1155.
    /// @param amount Quantity of each short/long/invalid token to merge.
    function merge(uint256 amount) external {
        // User transfers Short/Long/Invalid ERC20 to contract.
        if (!wrappedCTData.wrappedShort.transferFrom(msg.sender, address(this), amount)) {
            revert WrappedShortTransferFailed();
        }
        if (!wrappedCTData.wrappedLong.transferFrom(msg.sender, address(this), amount)) {
            revert WrappedLongTransferFailed();
        }
        if (!wrappedCTData.wrappedInvalid.transferFrom(msg.sender, address(this), amount)) {
            revert WrappedInvalidTransferFailed();
        }

        // Contract transfers Short/Long/Invalid ERC20 to wrapped1155Factory and gets
        // back Short/Long/Invalid ERC1155.
        wrapped1155Factory.unwrap(
            conditionalTokens, wrappedCTData.shortPositionId, amount, address(this), wrappedCTData.shortData
        );
        wrapped1155Factory.unwrap(
            conditionalTokens, wrappedCTData.longPositionId, amount, address(this), wrappedCTData.longData
        );
        wrapped1155Factory.unwrap(
            conditionalTokens, wrappedCTData.invalidPositionId, amount, address(this), wrappedCTData.invalidData
        );

        // Merge position. Short/Long/Invalid ERC1155 are burnt. Decision outcome
        // ERC1155 are minted.
        conditionalTokens.mergePositions(
            ctParams.collateralToken, ctParams.parentCollectionId, ctParams.conditionId, _discreetPartition(), amount
        );

        // Contract transfers decision outcome ERC1155 to user.
        conditionalTokens.safeTransferFrom(
            address(this),
            msg.sender,
            conditionalTokens.getPositionId(ctParams.collateralToken, ctParams.parentCollectionId),
            amount,
            ""
        );
    }

    /// @notice Redeems short/long/invalid tokens for collateral after resolution.
    /// @param shortAmount The amount of Short tokens to redeem.
    /// @param longAmount The amount of Long tokens to redeem.
    /// @param invalidAmount The amount of Invalid tokens to redeem.
    function redeem(uint256 shortAmount, uint256 longAmount, uint256 invalidAmount) external {
        // User transfers Short/Long/Invalid ERC20 to contract.
        if (!wrappedCTData.wrappedShort.transferFrom(msg.sender, address(this), shortAmount)) {
            revert WrappedShortTransferFailed();
        }
        if (!wrappedCTData.wrappedLong.transferFrom(msg.sender, address(this), longAmount)) {
            revert WrappedLongTransferFailed();
        }
        if (!wrappedCTData.wrappedInvalid.transferFrom(msg.sender, address(this), invalidAmount)) {
            revert WrappedInvalidTransferFailed();
        }

        // Contracts transfers Short/Long/Invalid ERC20 to wrapped1155Factory and gets
        // back Short/Long/Invalid ERC1155.
        wrapped1155Factory.unwrap(
            conditionalTokens, wrappedCTData.shortPositionId, shortAmount, address(this), wrappedCTData.shortData
        );
        wrapped1155Factory.unwrap(
            conditionalTokens, wrappedCTData.longPositionId, longAmount, address(this), wrappedCTData.longData
        );
        wrapped1155Factory.unwrap(
            conditionalTokens, wrappedCTData.invalidPositionId, invalidAmount, address(this), wrappedCTData.invalidData
        );

        // Track contract's decision outcome ERC1155 balance, in case it's > 0.
        uint256 decisionPositionId =
            conditionalTokens.getPositionId(ctParams.collateralToken, ctParams.parentCollectionId);
        uint256 initialBalance = conditionalTokens.balanceOf(address(this), decisionPositionId);

        // Redeem positions. Short/Long/Invalid/Invalid ERC1155 are burnt. Decision outcome
        // ERC1155 are minted in proportion of payouts.
        conditionalTokens.redeemPositions(
            ctParams.collateralToken, ctParams.parentCollectionId, ctParams.conditionId, _discreetPartition()
        );

        // Track contract's new decision outcome balance.
        uint256 finalBalance = conditionalTokens.balanceOf(address(this), decisionPositionId);
        uint256 redeemedAmount = finalBalance - initialBalance;

        // Contract transfers decision outcome ERC1155 redeemed amount to user.
        conditionalTokens.safeTransferFrom(address(this), msg.sender, decisionPositionId, redeemedAmount, "");
    }

    /// @dev Returns the discreet partition array [1,2,4] for the short/long/invalid outcomes.
    function _discreetPartition() private pure returns (uint256[] memory) {
        uint256[] memory partition = new uint256[](3);
        partition[0] = 1;
        partition[1] = 2;
        partition[2] = 4;
        return partition;
    }
}

File 11 of 16 : Types.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.20;

import "@openzeppelin-contracts/token/ERC20/IERC20.sol";

/// @notice Parameters for a multi-outcome (decision) question.
struct FlatCFMQuestionParams {
    string[] outcomeNames;
    /// @dev Unix timestamp when the question opens.
    uint32 openingTime;
}

/// @notice Numeric range for a scalar (metric) question.
struct ScalarParams {
    uint256 minValue;
    uint256 maxValue;
}

/// @notice Parameters for a generic scalar question, including its opening time.
struct GenericScalarQuestionParams {
    ScalarParams scalarParams;
    /// @dev Unix timestamp when the question opens.
    uint32 openingTime;
}

/// @notice Conditional Tokens params of a conditional market.
struct ConditionalScalarCTParams {
    bytes32 questionId;
    bytes32 conditionId;
    bytes32 parentCollectionId;
    IERC20 collateralToken;
}

/// @notice Data for wrapped short/long/invalid token positions.
struct WrappedConditionalTokensData {
    /// @dev ABI-encoded constructor name, symbol, decimals.
    bytes shortData;
    bytes longData;
    bytes invalidData;
    /// @dev Conditional Tokens position ids.
    uint256 shortPositionId;
    uint256 longPositionId;
    uint256 invalidPositionId;
    /// @dev ERC20s.
    IERC20 wrappedShort;
    IERC20 wrappedLong;
    IERC20 wrappedInvalid;
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.20;

import {IERC165} from "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` amount of tokens of type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the value of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(
        address[] calldata accounts,
        uint256[] calldata ids
    ) external view returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`.
     *
     * WARNING: This function can potentially allow a reentrancy attack when transferring tokens
     * to an untrusted contract, when invoking {onERC1155Received} on the receiver.
     * Ensure to follow the checks-effects-interactions pattern and consider employing
     * reentrancy guards when interacting with untrusted contracts.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `value` amount.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * WARNING: This function can potentially allow a reentrancy attack when transferring tokens
     * to an untrusted contract, when invoking {onERC1155BatchReceived} on the receiver.
     * Ensure to follow the checks-effects-interactions pattern and consider employing
     * reentrancy guards when interacting with untrusted contracts.
     *
     * Emits either a {TransferSingle} or a {TransferBatch} event, depending on the length of the array arguments.
     *
     * Requirements:
     *
     * - `ids` and `values` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external;
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/utils/ERC1155Holder.sol)

pragma solidity ^0.8.20;

import {IERC165, ERC165} from "../../../utils/introspection/ERC165.sol";
import {IERC1155Receiver} from "../IERC1155Receiver.sol";

/**
 * @dev Simple implementation of `IERC1155Receiver` that will allow a contract to hold ERC1155 tokens.
 *
 * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be
 * stuck.
 */
abstract contract ERC1155Holder is ERC165, IERC1155Receiver {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);
    }

    function onERC1155Received(
        address,
        address,
        uint256,
        uint256,
        bytes memory
    ) public virtual override returns (bytes4) {
        return this.onERC1155Received.selector;
    }

    function onERC1155BatchReceived(
        address,
        address,
        uint256[] memory,
        uint256[] memory,
        bytes memory
    ) public virtual override returns (bytes4) {
        return this.onERC1155BatchReceived.selector;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

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

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)

pragma solidity ^0.8.20;

import {IERC165} from "./IERC165.sol";

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

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/IERC1155Receiver.sol)

pragma solidity ^0.8.20;

import {IERC165} from "../../utils/introspection/IERC165.sol";

/**
 * @dev Interface that must be implemented by smart contracts in order to receive
 * ERC-1155 token transfers.
 */
interface IERC1155Receiver is IERC165 {
    /**
     * @dev Handles the receipt of a single ERC1155 token type. This function is
     * called at the end of a `safeTransferFrom` after the balance has been updated.
     *
     * NOTE: To accept the transfer, this must return
     * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
     * (i.e. 0xf23a6e61, or its own function selector).
     *
     * @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)"))` if transfer is allowed
     */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
     * @dev Handles the receipt of a multiple ERC1155 token types. This function
     * is called at the end of a `safeBatchTransferFrom` after the balances have
     * been updated.
     *
     * NOTE: To accept the transfer(s), this must return
     * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
     * (i.e. 0xbc197c81, or its own function selector).
     *
     * @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)"))` if transfer is allowed
     */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

Settings
{
  "remappings": [
    "@openzeppelin-contracts/=dependencies/@openzeppelin-contracts-5.0.2/",
    "@realityeth/=dependencies/@realityeth-3.0.61/",
    "forge-std/=dependencies/forge-std-1.9.5/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "evmVersion": "shanghai",
  "viaIR": false
}

Contract ABI

API
[{"inputs":[{"internalType":"contract IConditionalTokens","name":"_conditionalTokens","type":"address"},{"internalType":"contract IWrapped1155Factory","name":"_wrapped1155Factory","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ERC1167FailedCreateClone","type":"error"},{"inputs":[],"name":"InvalidOutcomeCount","type":"error"},{"inputs":[{"internalType":"string","name":"outcomeName","type":"string"}],"name":"InvalidOutcomeNameLength","type":"error"},{"inputs":[{"internalType":"string","name":"value","type":"string"}],"name":"InvalidString31Length","type":"error"},{"inputs":[],"name":"NoConditionalScalarMarketToDeploy","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"decisionMarket","type":"address"},{"indexed":true,"internalType":"address","name":"conditionalMarket","type":"address"},{"indexed":false,"internalType":"uint256","name":"outcomeIndex","type":"uint256"}],"name":"ConditionalScalarMarketCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"market","type":"address"},{"indexed":false,"internalType":"bytes32","name":"conditionId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"deployer","type":"address"}],"name":"FlatCFMCreated","type":"event"},{"inputs":[],"name":"MAX_OUTCOME_COUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_OUTCOME_NAME_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"conditionalScalarMarketImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"conditionalTokens","outputs":[{"internalType":"contract IConditionalTokens","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract FlatCFM","name":"cfm","type":"address"}],"name":"createConditionalScalarMarket","outputs":[{"internalType":"contract ConditionalScalarMarket","name":"csm","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract FlatCFMOracleAdapter","name":"oracleAdapter","type":"address"},{"internalType":"uint256","name":"decisionTemplateId","type":"uint256"},{"internalType":"uint256","name":"metricTemplateId","type":"uint256"},{"components":[{"internalType":"string[]","name":"outcomeNames","type":"string[]"},{"internalType":"uint32","name":"openingTime","type":"uint32"}],"internalType":"struct FlatCFMQuestionParams","name":"flatCFMQParams","type":"tuple"},{"components":[{"components":[{"internalType":"uint256","name":"minValue","type":"uint256"},{"internalType":"uint256","name":"maxValue","type":"uint256"}],"internalType":"struct ScalarParams","name":"scalarParams","type":"tuple"},{"internalType":"uint32","name":"openingTime","type":"uint32"}],"internalType":"struct GenericScalarQuestionParams","name":"genericScalarQuestionParams","type":"tuple"},{"internalType":"contract IERC20","name":"collateralToken","type":"address"},{"internalType":"string","name":"metadataUri","type":"string"}],"name":"createFlatCFM","outputs":[{"internalType":"contract FlatCFM","name":"cfm","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"flatCfmImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract FlatCFM","name":"","type":"address"}],"name":"nextOutcomeToDeploy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract FlatCFM","name":"","type":"address"}],"name":"paramsToDeploy","outputs":[{"internalType":"contract IERC20","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"metricTemplateId","type":"uint256"},{"components":[{"components":[{"internalType":"uint256","name":"minValue","type":"uint256"},{"internalType":"uint256","name":"maxValue","type":"uint256"}],"internalType":"struct ScalarParams","name":"scalarParams","type":"tuple"},{"internalType":"uint32","name":"openingTime","type":"uint32"}],"internalType":"struct GenericScalarQuestionParams","name":"genericScalarQuestionParams","type":"tuple"},{"internalType":"bytes32","name":"decisionConditionId","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wrapped1155Factory","outputs":[{"internalType":"contract IWrapped1155Factory","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

61010060405234801562000011575f80fd5b5060405162004d5038038062004d508339810160408190526200003491620000ee565b6001600160a01b03808316608052811660a0526040516200005590620000ba565b604051809103905ff0801580156200006f573d5f803e3d5ffd5b506001600160a01b031660c0526040516200008a90620000c8565b604051809103905ff080158015620000a4573d5f803e3d5ffd5b506001600160a01b031660e052506200012b9050565b61082d806200249d83390190565b6120868062002cca83390190565b6001600160a01b0381168114620000eb575f80fd5b50565b5f806040838503121562000100575f80fd5b82516200010d81620000d6565b60208401519092506200012081620000d6565b809150509250929050565b60805160a05160c05160e0516122ad620001f05f395f8181610208015261098e01525f818160a4015261037901525f818160f401528181610e7101528181611424015281816114d7015261158a01525f818161014d01528181610426015281816104ce0152818161054f015281816106d901528181610b9401528181610c3b01528181610cc901528181610d5e01528181610e4f015281816111240152818161123301528181611341015281816114530152818161150601526115b901526122ad5ff3fe60806040526004361061008f575f3560e01c80635e8a8757116100575780635e8a87571461016f5780636583b177146101f7578063a33daed01461022a578063bd7035b614610263578063f193c04514610277575f80fd5b80630f2a714f14610093578063150c5b97146100e35780631bbf911b146101165780632656da16146101295780635bd9e2991461013c575b5f80fd5b34801561009e575f80fd5b506100c67f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100ee575f80fd5b506100c67f000000000000000000000000000000000000000000000000000000000000000081565b6100c6610124366004611884565b61028b565b6100c6610137366004611943565b610788565b348015610147575f80fd5b506100c67f000000000000000000000000000000000000000000000000000000000000000081565b34801561017a575f80fd5b506101e7610189366004611943565b600160208181525f9283526040928390208054928101548451608081018652600283015495810195865260038301546060820152948552600482015463ffffffff1692850192909252600501546001600160a01b0390921692909184565b6040516100da949392919061198d565b348015610202575f80fd5b506100c67f000000000000000000000000000000000000000000000000000000000000000081565b348015610235575f80fd5b50610255610244366004611943565b5f6020819052908152604090205481565b6040519081526020016100da565b34801561026e575f80fd5b5061025560ff81565b348015610282575f80fd5b50610255601981565b5f8061029787806119c0565b9150508015806102a7575060ff81115b156102c55760405163162cc9e360e11b815260040160405180910390fd5b5f5b81811015610373575f6102da89806119c0565b838181106102ea576102ea611a06565b90506020028101906102fc9190611a1a565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152505082519293505050601910156103605780604051630be5696d60e41b81526004016103579190611aaa565b60405180910390fd5b508061036b81611ad0565b9150506102c7565b506103a67f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610f22565b91505f8a6001600160a01b031663612b2b10348c8b6040518463ffffffff1660e01b81526004016103d8929190611b23565b60206040518083038185885af11580156103f4573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906104199190611c22565b90505f6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663852c6ae28584610458876001611c39565b6040518463ffffffff1660e01b815260040161047693929190611c52565b602060405180830381865afa158015610491573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104b59190611c22565b604051636a16e06160e11b8152600481018290529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063d42dc0c290602401602060405180830381865afa15801561051b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061053f9190611c22565b5f036105cd576001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663d96ee7548584610581876001611c39565b6040518463ffffffff1660e01b815260040161059f93929190611c52565b5f604051808303815f87803b1580156105b6575f80fd5b505af11580156105c8573d5f803e3d5ffd5b505050505b6040518060a00160405280886001600160a01b031681526020018b8152602001898036038101906105fe9190611ce1565b8152602081018390526040016106148b806119c0565b61061d91611d3b565b90526001600160a01b038581165f90815260016020818152604092839020855181546001600160a01b0319169516949094178455848101519184019190915590830151805180516002850155820151600384015581015160048301805463ffffffff191663ffffffff90921691909117905560608301516005830155608083015180516106b092600685019201906116eb565b505060405163344ebc5b60e11b81526001600160a01b038616915063689d78b690610709908f907f000000000000000000000000000000000000000000000000000000000000000090889088908d908d90600401611e0a565b5f604051808303815f87803b158015610720575f80fd5b505af1158015610732573d5f803e3d5ffd5b5050604080518481523360208201526001600160a01b03881693507ffbeaa62397dc0cdc6f99dfadf0f65d2c5337aff91d9b2624606d9384cff4d9a892500160405180910390a250505098975050505050505050565b6001600160a01b0381165f9081526001602052604081206006015481036107c257604051637c78e93160e11b815260040160405180910390fd5b6001600160a01b0382165f81815260208181526040808320548151633d9f316360e01b81529151909492633d9f316392600480820193918290030181865afa158015610810573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108349190611e50565b6001600160a01b038086165f908152600160208181526040808420815160a08101835281549096168652928301548583015280516080808201835260028501548284019081526003860154606080850191909152908352600486015463ffffffff16838601528784019290925260058501549187019190915260068401805483518186028101860190945280845297985094969394908601939192909190879084015b8282101561097f578382905f5260205f200180546108f490611e6b565b80601f016020809104026020016040519081016040528092919081815260200182805461092090611e6b565b801561096b5780601f106109425761010080835404028352916020019161096b565b820191905f5260205f20905b81548152906001019060200180831161094e57829003601f168201915b5050505050815260200190600101906108d7565b505050508152505090506109bb7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610f22565b93506109c561173f565b604080516080810182525f8082526020820181905291810182905260608101919091526001876001600160a01b031663d300cb316040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a26573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a4a9190611c22565b610a549190611ea3565b8503610aca576001600160a01b0387165f90815260208181526040808320839055600191829052822080546001600160a01b0319168155908101829055600281018290556003810182905560048101805463ffffffff191690556005810182905590610ac360068301826117a0565b5050610af3565b6001600160a01b0387165f908152602081905260408120805491610aed83611ad0565b91905055505b5f83608001518681518110610b0a57610b0a611a06565b602002602001015190505f856001600160a01b0316630a6cbfea3487602001518860400151866040518563ffffffff1660e01b8152600401610b4e93929190611eb6565b60206040518083038185885af1158015610b6a573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610b8f9190611c22565b90505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663852c6ae28a8460036040518463ffffffff1660e01b8152600401610be393929190611c52565b602060405180830381865afa158015610bfe573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c229190611c22565b604051636a16e06160e11b8152600481018290529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063d42dc0c290602401602060405180830381865afa158015610c88573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cac9190611c22565b5f03610d315760405163365bb9d560e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063d96ee75490610d03908c908690600390600401611c52565b5f604051808303815f87803b158015610d1a575f80fd5b505af1158015610d2c573d5f803e3d5ffd5b505050505b606086015160405163856296f760e01b81525f60048201819052602482019290925260018a1b60448201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063856296f790606401602060405180830381865afa158015610dab573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610dcf9190611c22565b9050610de084885f01518385610f91565b604080516080810182529485526020808601949094528481019290925287516001600160a01b039081166060860152825180840184528984018051515182525151850151948101949094529151637358fc6760e01b815290965092945089169250637358fc6791610e9e9188917f0000000000000000000000000000000000000000000000000000000000000000917f0000000000000000000000000000000000000000000000000000000000000000918891908a90600401611ee4565b5f604051808303815f87803b158015610eb5575f80fd5b505af1158015610ec7573d5f803e3d5ffd5b50505050856001600160a01b0316876001600160a01b03167f8bb015eb1bfabc147df2e34e0784fb8ed712ae428e602b91168adf2e29f97c4587604051610f1091815260200190565b60405180910390a35050505050919050565b5f763d602d80600a3d3981f3363d3d373d3d3d363d730000008260601b60e81c175f526e5af43d82803e903d91602b57fd5bf38260781b17602052603760095ff090506001600160a01b038116610f8c576040516330be1a3d60e21b815260040160405180910390fd5b919050565b610f9961173f565b5f846001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fd6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ffa919061201a565b90505f61102587604051602001611011919061203a565b604051602081830303815290604052611696565b611039886040516020016110119190612063565b8360405160200161104c93929190612089565b60405160208183030381529060405290505f6110728860405160200161101191906120ac565b6110868960405160200161101191906120d4565b8460405160200161109993929190612089565b60405160208183030381529060405290505f6110bf8960405160200161101191906120fa565b6110d38a6040516020016110119190612121565b856040516020016110e693929190612089565b60408051601f198184030181529082905263856296f760e01b825260048201899052602482018890526001604483015291505f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906339dd7530908b90839063856296f790606401602060405180830381865afa158015611173573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111979190611c22565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa1580156111de573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112029190611c22565b60405163856296f760e01b8152600481018a905260248101899052600260448201529091505f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906339dd7530908c90839063856296f790606401602060405180830381865afa158015611282573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112a69190611c22565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa1580156112ed573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113119190611c22565b60405163856296f760e01b815260048181018c9052602482018b905260448201529091505f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906339dd7530908d90839063856296f790606401602060405180830381865afa158015611390573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113b49190611c22565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa1580156113fb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061141f9190611c22565b90505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633125810e7f0000000000000000000000000000000000000000000000000000000000000000868a6040518463ffffffff1660e01b815260040161149293929190612147565b6020604051808303815f875af11580156114ae573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114d29190611e50565b90505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633125810e7f0000000000000000000000000000000000000000000000000000000000000000868a6040518463ffffffff1660e01b815260040161154593929190612147565b6020604051808303815f875af1158015611561573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115859190611e50565b90505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633125810e7f0000000000000000000000000000000000000000000000000000000000000000868a6040518463ffffffff1660e01b81526004016115f893929190612147565b6020604051808303815f875af1158015611614573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116389190611e50565b60408051610120810182529a8b5260208b0199909952978901969096526060880194909452608087019290925260a08601526001600160a01b0390811660c086015290811660e0850152909116610100830152509695505050505050565b80515f90601f8111156116be578260405163ea4500bd60e01b81526004016103579190611aaa565b602083015191505f60038260206116d59190611ea3565b5f19911b1b9290921660019190911b1792915050565b828054828255905f5260205f2090810192821561172f579160200282015b8281111561172f578251829061171f90826121bb565b5091602001919060010190611709565b5061173b9291506117be565b5090565b6040518061012001604052806060815260200160608152602001606081526020015f81526020015f81526020015f81526020015f6001600160a01b031681526020015f6001600160a01b031681526020015f6001600160a01b031681525090565b5080545f8255905f5260205f20908101906117bb91906117be565b50565b8082111561173b575f6117d182826117da565b506001016117be565b5080546117e690611e6b565b5f825580601f106117f5575050565b601f0160209004905f5260205f20908101906117bb91905b8082111561173b575f815560010161180d565b6001600160a01b03811681146117bb575f80fd5b8035610f8c81611820565b5f8083601f84011261184f575f80fd5b50813567ffffffffffffffff811115611866575f80fd5b60208301915083602082850101111561187d575f80fd5b9250929050565b5f805f805f805f80888a0361012081121561189d575f80fd5b89356118a881611820565b985060208a0135975060408a0135965060608a013567ffffffffffffffff808211156118d2575f80fd5b908b01906040828e0312156118e5575f80fd5b8197506060607f19840112156118f9575f80fd5b60808c01965061190b60e08d01611834565b95506101008c0135925080831115611921575f80fd5b505061192f8b828c0161183f565b999c989b5096995094979396929594505050565b5f60208284031215611953575f80fd5b813561195e81611820565b9392505050565b61197a82825180518252602090810151910152565b6020015163ffffffff1660409190910152565b6001600160a01b03851681526020810184905260c081016119b16040830185611965565b8260a083015295945050505050565b5f808335601e198436030181126119d5575f80fd5b83018035915067ffffffffffffffff8211156119ef575f80fd5b6020019150600581901b360382131561187d575f80fd5b634e487b7160e01b5f52603260045260245ffd5b5f808335601e19843603018112611a2f575f80fd5b83018035915067ffffffffffffffff821115611a49575f80fd5b60200191503681900382131561187d575f80fd5b5f5b83811015611a77578181015183820152602001611a5f565b50505f910152565b5f8151808452611a96816020860160208601611a5d565b601f01601f19169290920160200192915050565b602081525f61195e6020830184611a7f565b634e487b7160e01b5f52601160045260245ffd5b5f60018201611ae157611ae1611abc565b5060010190565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b803563ffffffff81168114610f8c575f80fd5b5f604084835260208181850152608084018535601e19873603018112611b47575f80fd5b8601803583820167ffffffffffffffff80831115611b63575f80fd5b8260051b803603831315611b75575f80fd5b878a018890529483905260a09489018501945f908a01603e1936879003015b85831015611bf8578b8803609f190182528435818112611bb2575f80fd5b87018a8101908a013585811115611bc7575f80fd5b803603821315611bd5575f80fd5b611be08a8284611ae8565b99505050938801936001929092019190880190611b94565b50505050505050611c0a828701611b10565b63ffffffff8116606087015292509695505050505050565b5f60208284031215611c32575f80fd5b5051919050565b80820180821115611c4c57611c4c611abc565b92915050565b6001600160a01b039390931683526020830191909152604082015260600190565b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff81118282101715611caa57611caa611c73565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611cd957611cd9611c73565b604052919050565b5f8183036060811215611cf2575f80fd5b611cfa611c87565b6040821215611d07575f80fd5b611d0f611c87565b91508335825260208401356020830152818152611d2e60408501611b10565b6020820152949350505050565b5f67ffffffffffffffff80841115611d5557611d55611c73565b8360051b6020611d66818301611cb0565b868152918501918181019036841115611d7d575f80fd5b865b84811015611dfe57803586811115611d96575f8081fd5b8801601f3681830112611da8575f8081fd5b813588811115611dba57611dba611c73565b611dcb818301601f19168801611cb0565b91508082523687828501011115611de1575f8081fd5b80878401888401375f908201870152845250918301918301611d7f565b50979650505050505050565b6001600160a01b03878116825286166020820152604081018590526060810184905260a0608082018190525f90611e449083018486611ae8565b98975050505050505050565b5f60208284031215611e60575f80fd5b815161195e81611820565b600181811c90821680611e7f57607f821691505b602082108103611e9d57634e487b7160e01b5f52602260045260245ffd5b50919050565b81810381811115611c4c57611c4c611abc565b838152611ec66020820184611965565b60a060808201525f611edb60a0830184611a7f565b95945050505050565b5f61014060018060a01b03808a168452808916602085015280881660408501528651606085015260208701516080850152604087015160a08501528060608801511660c085015250611f4360e084018680518252602090810151910152565b610120818185015284518183860152611f60610260860182611a7f565b92505050602084015161013f198085840301610160860152611f828383611a7f565b925060408601519150808584030161018086015250611fa18282611a7f565b91505060608401516101a084015260808401516101c084015260a08401516101e084015260c0840151611fe06102008501826001600160a01b03169052565b5060e08401516001600160a01b038116610220850152506101008401516001600160a01b0381166102408501525098975050505050505050565b5f6020828403121561202a575f80fd5b815160ff8116811461195e575f80fd5b5f825161204b818460208701611a5d565b650b54da1bdc9d60d21b920191825250600601919050565b5f8251612074818460208701611a5d565b620b54d560ea1b920191825250600301919050565b928352602083019190915260f81b6001600160f81b031916604082015260410190565b5f82516120bd818460208701611a5d565b642d4c6f6e6760d81b920191825250600501919050565b5f82516120e5818460208701611a5d565b622d4c4760e81b920191825250600301919050565b5f825161210b818460208701611a5d565b6316a4b73b60e11b920191825250600401919050565b5f8251612132818460208701611a5d565b6205ab0b60eb1b920191825250600301919050565b60018060a01b0384168152826020820152606060408201525f611edb6060830184611a7f565b601f8211156121b6575f81815260208120601f850160051c810160208610156121935750805b601f850160051c820191505b818110156121b25782815560010161219f565b5050505b505050565b815167ffffffffffffffff8111156121d5576121d5611c73565b6121e9816121e38454611e6b565b8461216d565b602080601f83116001811461221c575f84156122055750858301515b5f19600386901b1c1916600185901b1785556121b2565b5f85815260208120601f198616915b8281101561224a5788860151825594840194600190910190840161222b565b508582101561226757878501515f19600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220413315467d072404041d7cd3556c0120cf43a93cde811d1676bdb8a29029438064736f6c63430008140033608060405234801561000f575f80fd5b506108108061001d5f395ff3fe608060405234801561000f575f80fd5b5060043610610085575f3560e01c8063689d78b611610058578063689d78b6146100f257806377a4d55914610105578063b06a5c521461011a578063d300cb3114610131575f80fd5b8063158ef93e146100895780632810e1d6146100ab5780633d9f3163146100b55780635bd9e299146100df575b5f80fd5b6005546100969060ff1681565b60405190151581526020015b60405180910390f35b6100b361013a565b005b5f546100c7906001600160a01b031681565b6040516001600160a01b0390911681526020016100a2565b6001546100c7906001600160a01b031681565b6100b361010036600461048d565b61035d565b61010d6103d6565b6040516100a2919061056f565b61012360025481565b6040519081526020016100a2565b61012360035481565b5f8054600254604051638a4599c760e01b81526001600160a01b0390921691638a4599c79161016f9160040190815260200190565b602060405180830381865afa15801561018a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101ae91906105ba565b90505f60035460016101c091906105e5565b67ffffffffffffffff8111156101d8576101d8610479565b604051908082528060200260200182016040528015610201578160200160208202803683370190505b5090508180158061021857506003546001901b8110155b8061028857505f54604051637cadacdd60e11b8152600481018590526001600160a01b039091169063f95b59ba90602401602060405180830381865afa158015610264573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061028891906105fe565b156102b457600182600354815181106102a3576102a3610624565b6020026020010181815250506102f8565b5f5b6003548110156102f6578082901c6001168382815181106102d9576102d9610624565b6020908102919091010152806102ee81610638565b9150506102b6565b505b600154600254604051633124a62b60e21b81526001600160a01b039092169163c49298ac9161032b918690600401610650565b5f604051808303815f87803b158015610342575f80fd5b505af1158015610354573d5f803e3d5ffd5b50505050505050565b60055460ff16156103805760405162dc149f60e41b815260040160405180910390fd5b6005805460ff191660019081179091555f80546001600160a01b038089166001600160a01b031992831617909255825491871691161790556003839055600282905560046103ce828261071e565b505050505050565b600480546103e39061069c565b80601f016020809104026020016040519081016040528092919081815260200182805461040f9061069c565b801561045a5780601f106104315761010080835404028352916020019161045a565b820191905f5260205f20905b81548152906001019060200180831161043d57829003601f168201915b505050505081565b6001600160a01b0381168114610476575f80fd5b50565b634e487b7160e01b5f52604160045260245ffd5b5f805f805f60a086880312156104a1575f80fd5b85356104ac81610462565b945060208601356104bc81610462565b93506040860135925060608601359150608086013567ffffffffffffffff808211156104e6575f80fd5b818801915088601f8301126104f9575f80fd5b81358181111561050b5761050b610479565b604051601f8201601f19908116603f0116810190838211818310171561053357610533610479565b816040528281528b602084870101111561054b575f80fd5b826020860160208301375f6020848301015280955050505050509295509295909350565b5f6020808352835180828501525f5b8181101561059a5785810183015185820160400152820161057e565b505f604082860101526040601f19601f8301168501019250505092915050565b5f602082840312156105ca575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156105f8576105f86105d1565b92915050565b5f6020828403121561060e575f80fd5b8151801515811461061d575f80fd5b9392505050565b634e487b7160e01b5f52603260045260245ffd5b5f60018201610649576106496105d1565b5060010190565b5f60408201848352602060408185015281855180845260608601915082870193505f5b8181101561068f57845183529383019391830191600101610673565b5090979650505050505050565b600181811c908216806106b057607f821691505b6020821081036106ce57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f821115610719575f81815260208120601f850160051c810160208610156106fa5750805b601f850160051c820191505b818110156103ce57828155600101610706565b505050565b815167ffffffffffffffff81111561073857610738610479565b61074c81610746845461069c565b846106d4565b602080601f83116001811461077f575f84156107685750858301515b5f19600386901b1c1916600185901b1785556103ce565b5f85815260208120601f198616915b828110156107ad5788860151825594840194600190910190840161078e565b50858210156107ca57878501515f19600388901b60f8161c191681555b5050505050600190811b0190555056fea26469706673582212200302e9335a6789d0f63a1fbd4d62e49ef21250c444c7faf70fa074d38f17b1b264736f6c63430008140033608060405234801561000f575f80fd5b506120698061001d5f395ff3fe608060405234801561000f575f80fd5b50600436106100ef575f3560e01c80633d9f316311610093578063b819220511610063578063b819220514610230578063bc197c8114610243578063dbceb0051461027b578063f23a6e611461028e575f80fd5b80633d9f3163146101db5780635bd9e299146101ed5780637358fc67146102005780638d3a163c14610213575f80fd5b8063150c5b97116100ce578063150c5b9714610186578063158ef93e146101b157806324a47aeb146101be5780632810e1d6146101d3575f80fd5b80629da161146100f357806301ffc9a7146101405780631481f80014610163575b5f80fd5b600354600454600554600654610112939291906001600160a01b031684565b604080519485526020850193909352918301526001600160a01b031660608201526080015b60405180910390f35b61015361014e3660046116a4565b6102ad565b6040519015158152602001610137565b600754600854610171919082565b60408051928352602083019190915201610137565b600254610199906001600160a01b031681565b6040516001600160a01b039091168152602001610137565b6012546101539060ff1681565b6101d16101cc3660046116d2565b6102e3565b005b6101d1610727565b5f54610199906001600160a01b031681565b600154610199906001600160a01b031681565b6101d161020e36600461193a565b610961565b61021b610ab7565b60405161013799989796959493929190611a4d565b6101d161023e366004611ac8565b610c94565b610262610251366004611b6e565b63bc197c8160e01b95945050505050565b6040516001600160e01b03199091168152602001610137565b6101d16102893660046116d2565b6111dd565b61026261029c366004611c15565b63f23a6e6160e01b95945050505050565b5f6001600160e01b03198216630271189760e51b14806102dd57506301ffc9a760e01b6001600160e01b03198316145b92915050565b600f546040516323b872dd60e01b81526001600160a01b03909116906323b872dd9061031790339030908690600401611c79565b6020604051808303815f875af1158015610333573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103579190611c9d565b61037457604051631850dc2d60e31b815260040160405180910390fd5b6010546040516323b872dd60e01b81526001600160a01b03909116906323b872dd906103a890339030908690600401611c79565b6020604051808303815f875af11580156103c4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103e89190611c9d565b61040557604051634ee3756160e11b815260040160405180910390fd5b6011546040516323b872dd60e01b81526001600160a01b03909116906323b872dd9061043990339030908690600401611c79565b6020604051808303815f875af1158015610455573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104799190611c9d565b6104965760405163a2e6cb3f60e01b815260040160405180910390fd5b600254600154600c546040516314abb2c960e21b81526001600160a01b03938416936352aecb24936104d49391169186903090600990600401611d6d565b5f604051808303815f87803b1580156104eb575f80fd5b505af11580156104fd573d5f803e3d5ffd5b5050600254600154600d546040516314abb2c960e21b81526001600160a01b0393841695506352aecb249450610540939092169186903090600a90600401611d6d565b5f604051808303815f87803b158015610557575f80fd5b505af1158015610569573d5f803e3d5ffd5b5050600254600154600e546040516314abb2c960e21b81526001600160a01b0393841695506352aecb2494506105ac939092169186903090600b90600401611d6d565b5f604051808303815f87803b1580156105c3575f80fd5b505af11580156105d5573d5f803e3d5ffd5b50506001546006546005546004546001600160a01b039384169550639e7212ad94509290911691610604611619565b866040518663ffffffff1660e01b8152600401610625959493929190611ddf565b5f604051808303815f87803b15801561063c575f80fd5b505af115801561064e573d5f803e3d5ffd5b505060015460065460055460405163039dd75360e41b81526001600160a01b03928316600482015260248101919091529116925063f242432a91503090339084906339dd753090604401602060405180830381865afa1580156106b3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106d79190611e1d565b856040518563ffffffff1660e01b81526004016106f79493929190611e34565b5f604051808303815f87803b15801561070e575f80fd5b505af1158015610720573d5f803e3d5ffd5b5050505050565b5f8054600354604051638a4599c760e01b81526001600160a01b0390921691638a4599c79161075c9160040190815260200190565b602060405180830381865afa158015610777573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061079b9190611e1d565b604080516003808252608082019092529192505f919060208201606080368337019050505f54604051637cadacdd60e11b8152600481018590529192506001600160a01b03169063f95b59ba90602401602060405180830381865afa158015610806573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061082a9190611c9d565b156108555760018160028151811061084457610844611e6b565b6020026020010181815250506108fd565b60075482908111610885576001825f8151811061087457610874611e6b565b6020026020010181815250506108fb565b60085481106108a35760018260018151811061087457610874611e6b565b6008546108b1908290611e7f565b825f815181106108c3576108c3611e6b565b60209081029190910101526007546108db9082611e7f565b826001815181106108ee576108ee611e6b565b6020026020010181815250505b505b600154600354604051633124a62b60e21b81526001600160a01b039092169163c49298ac91610930918590600401611e9e565b5f604051808303815f87803b158015610947575f80fd5b505af1158015610959573d5f803e3d5ffd5b505050505050565b60125460ff16156109845760405162dc149f60e41b815260040160405180910390fd5b6012805460ff191660019081179091555f80546001600160a01b03808a166001600160a01b03199283161790925582548883169082161790925560028054878316908416179055845160035560208086015160045560408601516005556060860151600680549190931693169290921790558251600755820151600855805181906009908190610a149082611f08565b5060208201516001820190610a299082611f08565b5060408201516002820190610a3e9082611f08565b50606082015160038201556080820151600482015560a0820151600582015560c08201516006820180546001600160a01b03199081166001600160a01b039384161790915560e0840151600784018054831691841691909117905561010090930151600890920180549093169116179055505050505050565b600980548190610ac690611cbc565b80601f0160208091040260200160405190810160405280929190818152602001828054610af290611cbc565b8015610b3d5780601f10610b1457610100808354040283529160200191610b3d565b820191905f5260205f20905b815481529060010190602001808311610b2057829003601f168201915b505050505090806001018054610b5290611cbc565b80601f0160208091040260200160405190810160405280929190818152602001828054610b7e90611cbc565b8015610bc95780601f10610ba057610100808354040283529160200191610bc9565b820191905f5260205f20905b815481529060010190602001808311610bac57829003601f168201915b505050505090806002018054610bde90611cbc565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0a90611cbc565b8015610c555780601f10610c2c57610100808354040283529160200191610c55565b820191905f5260205f20905b815481529060010190602001808311610c3857829003601f168201915b50505060038401546004850154600586015460068701546007880154600890980154969793969295509093506001600160a01b03908116928116911689565b600f546040516323b872dd60e01b81526001600160a01b03909116906323b872dd90610cc890339030908890600401611c79565b6020604051808303815f875af1158015610ce4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d089190611c9d565b610d2557604051631850dc2d60e31b815260040160405180910390fd5b6010546040516323b872dd60e01b81526001600160a01b03909116906323b872dd90610d5990339030908790600401611c79565b6020604051808303815f875af1158015610d75573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d999190611c9d565b610db657604051634ee3756160e11b815260040160405180910390fd5b6011546040516323b872dd60e01b81526001600160a01b03909116906323b872dd90610dea90339030908690600401611c79565b6020604051808303815f875af1158015610e06573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e2a9190611c9d565b610e475760405163a2e6cb3f60e01b815260040160405180910390fd5b600254600154600c546040516314abb2c960e21b81526001600160a01b03938416936352aecb2493610e859391169188903090600990600401611d6d565b5f604051808303815f87803b158015610e9c575f80fd5b505af1158015610eae573d5f803e3d5ffd5b5050600254600154600d546040516314abb2c960e21b81526001600160a01b0393841695506352aecb249450610ef1939092169187903090600a90600401611d6d565b5f604051808303815f87803b158015610f08575f80fd5b505af1158015610f1a573d5f803e3d5ffd5b5050600254600154600e546040516314abb2c960e21b81526001600160a01b0393841695506352aecb249450610f5d939092169186903090600b90600401611d6d565b5f604051808303815f87803b158015610f74575f80fd5b505af1158015610f86573d5f803e3d5ffd5b505060015460065460055460405163039dd75360e41b81526001600160a01b03928316600482015260248101919091525f9450911691506339dd753090604401602060405180830381865afa158015610fe1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110059190611e1d565b600154604051627eeac760e11b8152306004820152602481018390529192505f916001600160a01b039091169062fdd58e90604401602060405180830381865afa158015611055573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110799190611e1d565b6001546006546005546004549394506001600160a01b03928316936301b7037c93909216916110a6611619565b6040518563ffffffff1660e01b81526004016110c59493929190611fc4565b5f604051808303815f87803b1580156110dc575f80fd5b505af11580156110ee573d5f803e3d5ffd5b5050600154604051627eeac760e11b8152306004820152602481018690525f93506001600160a01b03909116915062fdd58e90604401602060405180830381865afa15801561113f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111639190611e1d565b90505f6111708383611e7f565b600154604051637921219560e11b81529192506001600160a01b03169063f242432a906111a7903090339089908790600401611e34565b5f604051808303815f87803b1580156111be575f80fd5b505af11580156111d0573d5f803e3d5ffd5b5050505050505050505050565b60015460065460055460405163039dd75360e41b81526001600160a01b039283166004820152602481019190915291169063f242432a903390309084906339dd753090604401602060405180830381865afa15801561123e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112629190611e1d565b856040518563ffffffff1660e01b81526004016112829493929190611e34565b5f604051808303815f87803b158015611299575f80fd5b505af11580156112ab573d5f803e3d5ffd5b50506001546006546005546004546001600160a01b0393841695506372ce4275945092909116916112da611619565b866040518663ffffffff1660e01b81526004016112fb959493929190611ddf565b5f604051808303815f87803b158015611312575f80fd5b505af1158015611324573d5f803e3d5ffd5b5050600154600254600c54604051637921219560e11b81526001600160a01b03938416955063f242432a94506113669330931691908790600990600401611ffa565b5f604051808303815f87803b15801561137d575f80fd5b505af115801561138f573d5f803e3d5ffd5b5050600154600254600d54604051637921219560e11b81526001600160a01b03938416955063f242432a94506113d19330931691908790600a90600401611ffa565b5f604051808303815f87803b1580156113e8575f80fd5b505af11580156113fa573d5f803e3d5ffd5b5050600154600254600e54604051637921219560e11b81526001600160a01b03938416955063f242432a945061143c9330931691908790600b90600401611ffa565b5f604051808303815f87803b158015611453575f80fd5b505af1158015611465573d5f803e3d5ffd5b5050600f5460405163a9059cbb60e01b8152336004820152602481018590526001600160a01b03909116925063a9059cbb91506044016020604051808303815f875af11580156114b7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114db9190611c9d565b6114f857604051631850dc2d60e31b815260040160405180910390fd5b60105460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb906044016020604051808303815f875af1158015611546573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061156a9190611c9d565b61158757604051634ee3756160e11b815260040160405180910390fd5b60115460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb906044016020604051808303815f875af11580156115d5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115f99190611c9d565b6116165760405163a2e6cb3f60e01b815260040160405180910390fd5b50565b604080516003808252608082019092526060915f91906020820184803683370190505090506001815f8151811061165257611652611e6b565b60200260200101818152505060028160018151811061167357611673611e6b565b60200260200101818152505060048160028151811061169457611694611e6b565b6020908102919091010152919050565b5f602082840312156116b4575f80fd5b81356001600160e01b0319811681146116cb575f80fd5b9392505050565b5f602082840312156116e2575f80fd5b5035919050565b6001600160a01b0381168114611616575f80fd5b634e487b7160e01b5f52604160045260245ffd5b604051610120810167ffffffffffffffff81118282101715611735576117356116fd565b60405290565b6040516080810167ffffffffffffffff81118282101715611735576117356116fd565b604051601f8201601f1916810167ffffffffffffffff81118282101715611787576117876116fd565b604052919050565b803561179a816116e9565b919050565b5f604082840312156117af575f80fd5b6040516040810181811067ffffffffffffffff821117156117d2576117d26116fd565b604052823581526020928301359281019290925250919050565b5f82601f8301126117fb575f80fd5b813567ffffffffffffffff811115611815576118156116fd565b611828601f8201601f191660200161175e565b81815284602083860101111561183c575f80fd5b816020850160208301375f918101602001919091529392505050565b5f6101208284031215611869575f80fd5b611871611711565b9050813567ffffffffffffffff8082111561188a575f80fd5b611896858386016117ec565b835260208401359150808211156118ab575f80fd5b6118b7858386016117ec565b602084015260408401359150808211156118cf575f80fd5b506118dc848285016117ec565b604083015250606082013560608201526080820135608082015260a082013560a082015261190c60c0830161178f565b60c082015261191d60e0830161178f565b60e082015261010061193081840161178f565b9082015292915050565b5f805f805f80868803610140811215611951575f80fd5b873561195c816116e9565b9650602088013561196c816116e9565b9550604088013561197c816116e9565b94506080605f198201121561198f575f80fd5b5061199861173b565b606088013581526080880135602082015260a0880135604082015260c08801356119c1816116e9565b606082015292506119d58860e0890161179f565b915061012087013567ffffffffffffffff8111156119f1575f80fd5b6119fd89828a01611858565b9150509295509295509295565b5f81518084525f5b81811015611a2e57602081850181015186830182015201611a12565b505f602082860101526020601f19601f83011685010191505092915050565b5f610120808352611a608184018d611a0a565b90508281036020840152611a74818c611a0a565b90508281036040840152611a88818b611a0a565b60608401999099525050608081019590955260a08501939093526001600160a01b0391821660c0850152811660e084015216610100909101529392505050565b5f805f60608486031215611ada575f80fd5b505081359360208301359350604090920135919050565b5f82601f830112611b00575f80fd5b8135602067ffffffffffffffff821115611b1c57611b1c6116fd565b8160051b611b2b82820161175e565b9283528481018201928281019087851115611b44575f80fd5b83870192505b84831015611b6357823582529183019190830190611b4a565b979650505050505050565b5f805f805f60a08688031215611b82575f80fd5b8535611b8d816116e9565b94506020860135611b9d816116e9565b9350604086013567ffffffffffffffff80821115611bb9575f80fd5b611bc589838a01611af1565b94506060880135915080821115611bda575f80fd5b611be689838a01611af1565b93506080880135915080821115611bfb575f80fd5b50611c08888289016117ec565b9150509295509295909350565b5f805f805f60a08688031215611c29575f80fd5b8535611c34816116e9565b94506020860135611c44816116e9565b93506040860135925060608601359150608086013567ffffffffffffffff811115611c6d575f80fd5b611c08888289016117ec565b6001600160a01b039384168152919092166020820152604081019190915260600190565b5f60208284031215611cad575f80fd5b815180151581146116cb575f80fd5b600181811c90821680611cd057607f821691505b602082108103611cee57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f8154611d0081611cbc565b808552602060018381168015611d1d5760018114611d3757611d62565b60ff1985168884015283151560051b880183019550611d62565b865f52825f205f5b85811015611d5a5781548a8201860152908301908401611d3f565b890184019650505b505050505092915050565b6001600160a01b03868116825260208201869052604082018590528316606082015260a0608082018190525f90611b6390830184611cf4565b5f8151808452602080850194508084015f5b83811015611dd457815187529582019590820190600101611db8565b509495945050505050565b60018060a01b038616815284602082015283604082015260a060608201525f611e0b60a0830185611da6565b90508260808301529695505050505050565b5f60208284031215611e2d575f80fd5b5051919050565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a0608082018190525f9082015260c00190565b634e487b7160e01b5f52603260045260245ffd5b818103818111156102dd57634e487b7160e01b5f52601160045260245ffd5b828152604060208201525f611eb66040830184611da6565b949350505050565b601f821115611f03575f81815260208120601f850160051c81016020861015611ee45750805b601f850160051c820191505b8181101561095957828155600101611ef0565b505050565b815167ffffffffffffffff811115611f2257611f226116fd565b611f3681611f308454611cbc565b84611ebe565b602080601f831160018114611f69575f8415611f525750858301515b5f19600386901b1c1916600185901b178555610959565b5f85815260208120601f198616915b82811015611f9757888601518255948401946001909101908401611f78565b5085821015611fb457878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b60018060a01b0385168152836020820152826040820152608060608201525f611ff06080830184611da6565b9695505050505050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a0608082018190525f90611b6390830184611cf456fea26469706673582212202993dddd75af0a1e1d282fbe071211f81c58ae99d39859503428081da1c8720864736f6c634300081400330000000000000000000000001301d3c29a8723fae7ee1343203ea16bd7845996000000000000000000000000d7869be21bbb2fe897e294935bbe74a5a3222f91

Deployed Bytecode

0x60806040526004361061008f575f3560e01c80635e8a8757116100575780635e8a87571461016f5780636583b177146101f7578063a33daed01461022a578063bd7035b614610263578063f193c04514610277575f80fd5b80630f2a714f14610093578063150c5b97146100e35780631bbf911b146101165780632656da16146101295780635bd9e2991461013c575b5f80fd5b34801561009e575f80fd5b506100c67f0000000000000000000000005ab98af2edeed751ffa7ff6314d876466607e44f81565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100ee575f80fd5b506100c67f000000000000000000000000d7869be21bbb2fe897e294935bbe74a5a3222f9181565b6100c6610124366004611884565b61028b565b6100c6610137366004611943565b610788565b348015610147575f80fd5b506100c67f0000000000000000000000001301d3c29a8723fae7ee1343203ea16bd784599681565b34801561017a575f80fd5b506101e7610189366004611943565b600160208181525f9283526040928390208054928101548451608081018652600283015495810195865260038301546060820152948552600482015463ffffffff1692850192909252600501546001600160a01b0390921692909184565b6040516100da949392919061198d565b348015610202575f80fd5b506100c67f0000000000000000000000000199f82b32944934522e9b5d971b69ed9c0a762681565b348015610235575f80fd5b50610255610244366004611943565b5f6020819052908152604090205481565b6040519081526020016100da565b34801561026e575f80fd5b5061025560ff81565b348015610282575f80fd5b50610255601981565b5f8061029787806119c0565b9150508015806102a7575060ff81115b156102c55760405163162cc9e360e11b815260040160405180910390fd5b5f5b81811015610373575f6102da89806119c0565b838181106102ea576102ea611a06565b90506020028101906102fc9190611a1a565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152505082519293505050601910156103605780604051630be5696d60e41b81526004016103579190611aaa565b60405180910390fd5b508061036b81611ad0565b9150506102c7565b506103a67f0000000000000000000000005ab98af2edeed751ffa7ff6314d876466607e44f6001600160a01b0316610f22565b91505f8a6001600160a01b031663612b2b10348c8b6040518463ffffffff1660e01b81526004016103d8929190611b23565b60206040518083038185885af11580156103f4573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906104199190611c22565b90505f6001600160a01b037f0000000000000000000000001301d3c29a8723fae7ee1343203ea16bd78459961663852c6ae28584610458876001611c39565b6040518463ffffffff1660e01b815260040161047693929190611c52565b602060405180830381865afa158015610491573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104b59190611c22565b604051636a16e06160e11b8152600481018290529091507f0000000000000000000000001301d3c29a8723fae7ee1343203ea16bd78459966001600160a01b03169063d42dc0c290602401602060405180830381865afa15801561051b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061053f9190611c22565b5f036105cd576001600160a01b037f0000000000000000000000001301d3c29a8723fae7ee1343203ea16bd78459961663d96ee7548584610581876001611c39565b6040518463ffffffff1660e01b815260040161059f93929190611c52565b5f604051808303815f87803b1580156105b6575f80fd5b505af11580156105c8573d5f803e3d5ffd5b505050505b6040518060a00160405280886001600160a01b031681526020018b8152602001898036038101906105fe9190611ce1565b8152602081018390526040016106148b806119c0565b61061d91611d3b565b90526001600160a01b038581165f90815260016020818152604092839020855181546001600160a01b0319169516949094178455848101519184019190915590830151805180516002850155820151600384015581015160048301805463ffffffff191663ffffffff90921691909117905560608301516005830155608083015180516106b092600685019201906116eb565b505060405163344ebc5b60e11b81526001600160a01b038616915063689d78b690610709908f907f0000000000000000000000001301d3c29a8723fae7ee1343203ea16bd784599690889088908d908d90600401611e0a565b5f604051808303815f87803b158015610720575f80fd5b505af1158015610732573d5f803e3d5ffd5b5050604080518481523360208201526001600160a01b03881693507ffbeaa62397dc0cdc6f99dfadf0f65d2c5337aff91d9b2624606d9384cff4d9a892500160405180910390a250505098975050505050505050565b6001600160a01b0381165f9081526001602052604081206006015481036107c257604051637c78e93160e11b815260040160405180910390fd5b6001600160a01b0382165f81815260208181526040808320548151633d9f316360e01b81529151909492633d9f316392600480820193918290030181865afa158015610810573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108349190611e50565b6001600160a01b038086165f908152600160208181526040808420815160a08101835281549096168652928301548583015280516080808201835260028501548284019081526003860154606080850191909152908352600486015463ffffffff16838601528784019290925260058501549187019190915260068401805483518186028101860190945280845297985094969394908601939192909190879084015b8282101561097f578382905f5260205f200180546108f490611e6b565b80601f016020809104026020016040519081016040528092919081815260200182805461092090611e6b565b801561096b5780601f106109425761010080835404028352916020019161096b565b820191905f5260205f20905b81548152906001019060200180831161094e57829003601f168201915b5050505050815260200190600101906108d7565b505050508152505090506109bb7f0000000000000000000000000199f82b32944934522e9b5d971b69ed9c0a76266001600160a01b0316610f22565b93506109c561173f565b604080516080810182525f8082526020820181905291810182905260608101919091526001876001600160a01b031663d300cb316040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a26573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a4a9190611c22565b610a549190611ea3565b8503610aca576001600160a01b0387165f90815260208181526040808320839055600191829052822080546001600160a01b0319168155908101829055600281018290556003810182905560048101805463ffffffff191690556005810182905590610ac360068301826117a0565b5050610af3565b6001600160a01b0387165f908152602081905260408120805491610aed83611ad0565b91905055505b5f83608001518681518110610b0a57610b0a611a06565b602002602001015190505f856001600160a01b0316630a6cbfea3487602001518860400151866040518563ffffffff1660e01b8152600401610b4e93929190611eb6565b60206040518083038185885af1158015610b6a573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610b8f9190611c22565b90505f7f0000000000000000000000001301d3c29a8723fae7ee1343203ea16bd78459966001600160a01b031663852c6ae28a8460036040518463ffffffff1660e01b8152600401610be393929190611c52565b602060405180830381865afa158015610bfe573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c229190611c22565b604051636a16e06160e11b8152600481018290529091507f0000000000000000000000001301d3c29a8723fae7ee1343203ea16bd78459966001600160a01b03169063d42dc0c290602401602060405180830381865afa158015610c88573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cac9190611c22565b5f03610d315760405163365bb9d560e21b81526001600160a01b037f0000000000000000000000001301d3c29a8723fae7ee1343203ea16bd7845996169063d96ee75490610d03908c908690600390600401611c52565b5f604051808303815f87803b158015610d1a575f80fd5b505af1158015610d2c573d5f803e3d5ffd5b505050505b606086015160405163856296f760e01b81525f60048201819052602482019290925260018a1b60448201527f0000000000000000000000001301d3c29a8723fae7ee1343203ea16bd78459966001600160a01b03169063856296f790606401602060405180830381865afa158015610dab573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610dcf9190611c22565b9050610de084885f01518385610f91565b604080516080810182529485526020808601949094528481019290925287516001600160a01b039081166060860152825180840184528984018051515182525151850151948101949094529151637358fc6760e01b815290965092945089169250637358fc6791610e9e9188917f0000000000000000000000001301d3c29a8723fae7ee1343203ea16bd7845996917f000000000000000000000000d7869be21bbb2fe897e294935bbe74a5a3222f91918891908a90600401611ee4565b5f604051808303815f87803b158015610eb5575f80fd5b505af1158015610ec7573d5f803e3d5ffd5b50505050856001600160a01b0316876001600160a01b03167f8bb015eb1bfabc147df2e34e0784fb8ed712ae428e602b91168adf2e29f97c4587604051610f1091815260200190565b60405180910390a35050505050919050565b5f763d602d80600a3d3981f3363d3d373d3d3d363d730000008260601b60e81c175f526e5af43d82803e903d91602b57fd5bf38260781b17602052603760095ff090506001600160a01b038116610f8c576040516330be1a3d60e21b815260040160405180910390fd5b919050565b610f9961173f565b5f846001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fd6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ffa919061201a565b90505f61102587604051602001611011919061203a565b604051602081830303815290604052611696565b611039886040516020016110119190612063565b8360405160200161104c93929190612089565b60405160208183030381529060405290505f6110728860405160200161101191906120ac565b6110868960405160200161101191906120d4565b8460405160200161109993929190612089565b60405160208183030381529060405290505f6110bf8960405160200161101191906120fa565b6110d38a6040516020016110119190612121565b856040516020016110e693929190612089565b60408051601f198184030181529082905263856296f760e01b825260048201899052602482018890526001604483015291505f906001600160a01b037f0000000000000000000000001301d3c29a8723fae7ee1343203ea16bd784599616906339dd7530908b90839063856296f790606401602060405180830381865afa158015611173573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111979190611c22565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa1580156111de573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112029190611c22565b60405163856296f760e01b8152600481018a905260248101899052600260448201529091505f906001600160a01b037f0000000000000000000000001301d3c29a8723fae7ee1343203ea16bd784599616906339dd7530908c90839063856296f790606401602060405180830381865afa158015611282573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112a69190611c22565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa1580156112ed573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113119190611c22565b60405163856296f760e01b815260048181018c9052602482018b905260448201529091505f906001600160a01b037f0000000000000000000000001301d3c29a8723fae7ee1343203ea16bd784599616906339dd7530908d90839063856296f790606401602060405180830381865afa158015611390573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113b49190611c22565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa1580156113fb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061141f9190611c22565b90505f7f000000000000000000000000d7869be21bbb2fe897e294935bbe74a5a3222f916001600160a01b0316633125810e7f0000000000000000000000001301d3c29a8723fae7ee1343203ea16bd7845996868a6040518463ffffffff1660e01b815260040161149293929190612147565b6020604051808303815f875af11580156114ae573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114d29190611e50565b90505f7f000000000000000000000000d7869be21bbb2fe897e294935bbe74a5a3222f916001600160a01b0316633125810e7f0000000000000000000000001301d3c29a8723fae7ee1343203ea16bd7845996868a6040518463ffffffff1660e01b815260040161154593929190612147565b6020604051808303815f875af1158015611561573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115859190611e50565b90505f7f000000000000000000000000d7869be21bbb2fe897e294935bbe74a5a3222f916001600160a01b0316633125810e7f0000000000000000000000001301d3c29a8723fae7ee1343203ea16bd7845996868a6040518463ffffffff1660e01b81526004016115f893929190612147565b6020604051808303815f875af1158015611614573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116389190611e50565b60408051610120810182529a8b5260208b0199909952978901969096526060880194909452608087019290925260a08601526001600160a01b0390811660c086015290811660e0850152909116610100830152509695505050505050565b80515f90601f8111156116be578260405163ea4500bd60e01b81526004016103579190611aaa565b602083015191505f60038260206116d59190611ea3565b5f19911b1b9290921660019190911b1792915050565b828054828255905f5260205f2090810192821561172f579160200282015b8281111561172f578251829061171f90826121bb565b5091602001919060010190611709565b5061173b9291506117be565b5090565b6040518061012001604052806060815260200160608152602001606081526020015f81526020015f81526020015f81526020015f6001600160a01b031681526020015f6001600160a01b031681526020015f6001600160a01b031681525090565b5080545f8255905f5260205f20908101906117bb91906117be565b50565b8082111561173b575f6117d182826117da565b506001016117be565b5080546117e690611e6b565b5f825580601f106117f5575050565b601f0160209004905f5260205f20908101906117bb91905b8082111561173b575f815560010161180d565b6001600160a01b03811681146117bb575f80fd5b8035610f8c81611820565b5f8083601f84011261184f575f80fd5b50813567ffffffffffffffff811115611866575f80fd5b60208301915083602082850101111561187d575f80fd5b9250929050565b5f805f805f805f80888a0361012081121561189d575f80fd5b89356118a881611820565b985060208a0135975060408a0135965060608a013567ffffffffffffffff808211156118d2575f80fd5b908b01906040828e0312156118e5575f80fd5b8197506060607f19840112156118f9575f80fd5b60808c01965061190b60e08d01611834565b95506101008c0135925080831115611921575f80fd5b505061192f8b828c0161183f565b999c989b5096995094979396929594505050565b5f60208284031215611953575f80fd5b813561195e81611820565b9392505050565b61197a82825180518252602090810151910152565b6020015163ffffffff1660409190910152565b6001600160a01b03851681526020810184905260c081016119b16040830185611965565b8260a083015295945050505050565b5f808335601e198436030181126119d5575f80fd5b83018035915067ffffffffffffffff8211156119ef575f80fd5b6020019150600581901b360382131561187d575f80fd5b634e487b7160e01b5f52603260045260245ffd5b5f808335601e19843603018112611a2f575f80fd5b83018035915067ffffffffffffffff821115611a49575f80fd5b60200191503681900382131561187d575f80fd5b5f5b83811015611a77578181015183820152602001611a5f565b50505f910152565b5f8151808452611a96816020860160208601611a5d565b601f01601f19169290920160200192915050565b602081525f61195e6020830184611a7f565b634e487b7160e01b5f52601160045260245ffd5b5f60018201611ae157611ae1611abc565b5060010190565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b803563ffffffff81168114610f8c575f80fd5b5f604084835260208181850152608084018535601e19873603018112611b47575f80fd5b8601803583820167ffffffffffffffff80831115611b63575f80fd5b8260051b803603831315611b75575f80fd5b878a018890529483905260a09489018501945f908a01603e1936879003015b85831015611bf8578b8803609f190182528435818112611bb2575f80fd5b87018a8101908a013585811115611bc7575f80fd5b803603821315611bd5575f80fd5b611be08a8284611ae8565b99505050938801936001929092019190880190611b94565b50505050505050611c0a828701611b10565b63ffffffff8116606087015292509695505050505050565b5f60208284031215611c32575f80fd5b5051919050565b80820180821115611c4c57611c4c611abc565b92915050565b6001600160a01b039390931683526020830191909152604082015260600190565b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff81118282101715611caa57611caa611c73565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611cd957611cd9611c73565b604052919050565b5f8183036060811215611cf2575f80fd5b611cfa611c87565b6040821215611d07575f80fd5b611d0f611c87565b91508335825260208401356020830152818152611d2e60408501611b10565b6020820152949350505050565b5f67ffffffffffffffff80841115611d5557611d55611c73565b8360051b6020611d66818301611cb0565b868152918501918181019036841115611d7d575f80fd5b865b84811015611dfe57803586811115611d96575f8081fd5b8801601f3681830112611da8575f8081fd5b813588811115611dba57611dba611c73565b611dcb818301601f19168801611cb0565b91508082523687828501011115611de1575f8081fd5b80878401888401375f908201870152845250918301918301611d7f565b50979650505050505050565b6001600160a01b03878116825286166020820152604081018590526060810184905260a0608082018190525f90611e449083018486611ae8565b98975050505050505050565b5f60208284031215611e60575f80fd5b815161195e81611820565b600181811c90821680611e7f57607f821691505b602082108103611e9d57634e487b7160e01b5f52602260045260245ffd5b50919050565b81810381811115611c4c57611c4c611abc565b838152611ec66020820184611965565b60a060808201525f611edb60a0830184611a7f565b95945050505050565b5f61014060018060a01b03808a168452808916602085015280881660408501528651606085015260208701516080850152604087015160a08501528060608801511660c085015250611f4360e084018680518252602090810151910152565b610120818185015284518183860152611f60610260860182611a7f565b92505050602084015161013f198085840301610160860152611f828383611a7f565b925060408601519150808584030161018086015250611fa18282611a7f565b91505060608401516101a084015260808401516101c084015260a08401516101e084015260c0840151611fe06102008501826001600160a01b03169052565b5060e08401516001600160a01b038116610220850152506101008401516001600160a01b0381166102408501525098975050505050505050565b5f6020828403121561202a575f80fd5b815160ff8116811461195e575f80fd5b5f825161204b818460208701611a5d565b650b54da1bdc9d60d21b920191825250600601919050565b5f8251612074818460208701611a5d565b620b54d560ea1b920191825250600301919050565b928352602083019190915260f81b6001600160f81b031916604082015260410190565b5f82516120bd818460208701611a5d565b642d4c6f6e6760d81b920191825250600501919050565b5f82516120e5818460208701611a5d565b622d4c4760e81b920191825250600301919050565b5f825161210b818460208701611a5d565b6316a4b73b60e11b920191825250600401919050565b5f8251612132818460208701611a5d565b6205ab0b60eb1b920191825250600301919050565b60018060a01b0384168152826020820152606060408201525f611edb6060830184611a7f565b601f8211156121b6575f81815260208120601f850160051c810160208610156121935750805b601f850160051c820191505b818110156121b25782815560010161219f565b5050505b505050565b815167ffffffffffffffff8111156121d5576121d5611c73565b6121e9816121e38454611e6b565b8461216d565b602080601f83116001811461221c575f84156122055750858301515b5f19600386901b1c1916600185901b1785556121b2565b5f85815260208120601f198616915b8281101561224a5788860151825594840194600190910190840161222b565b508582101561226757878501515f19600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220413315467d072404041d7cd3556c0120cf43a93cde811d1676bdb8a29029438064736f6c63430008140033

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

0000000000000000000000001301d3c29a8723fae7ee1343203ea16bd7845996000000000000000000000000d7869be21bbb2fe897e294935bbe74a5a3222f91

-----Decoded View---------------
Arg [0] : _conditionalTokens (address): 0x1301d3C29A8723fae7Ee1343203eA16bd7845996
Arg [1] : _wrapped1155Factory (address): 0xD7869bE21bBb2Fe897e294935bbe74A5a3222F91

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000001301d3c29a8723fae7ee1343203ea16bd7845996
Arg [1] : 000000000000000000000000d7869be21bbb2fe897e294935bbe74a5a3222f91


Deployed Bytecode Sourcemap

821:11305:10:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1831:46;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;178:32:16;;;160:51;;148:2;133:18;1831:46:10;;;;;;;;1712:55;;;;;;;;;;;;;;;4668:1896;;;;;;:::i;:::-;;:::i;7207:2613::-;;;;;;:::i;:::-;;:::i;1584:53::-;;;;;;;;;;;;;;;2294:58;;;;;;;;;;-1:-1:-1;2294:58:10;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2294:58:10;;;;;;;;;;;;;;;;;;:::i;1957:62::-;;;;;;;;;;;;;;;2107:54;;;;;;;;;;-1:-1:-1;2107:54:10;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;4754:25:16;;;4742:2;4727:18;2107:54:10;4608:177:16;1339:47:10;;;;;;;;;;;;1383:3;1339:47;;1473:52;;;;;;;;;;;;1523:2;1473:52;;4668:1896;5035:11;;5081:27;:14;;:27;:::i;:::-;:34;-1:-1:-1;;5129:17:10;;;:53;;;1383:3;5150:12;:32;5129:53;5125:112;;;5205:21;;-1:-1:-1;;;5205:21:10;;;;;;;;;;;5125:112;5251:9;5246:241;5270:12;5266:1;:16;5246:241;;;5303:25;5331:27;:14;;:27;:::i;:::-;5359:1;5331:30;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;5303:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5379:25:10;;5303:58;;-1:-1:-1;;;1523:2:10;-1:-1:-1;5375:101:10;;;5464:11;5439:37;;-1:-1:-1;;;5439:37:10;;;;;;;;:::i;:::-;;;;;;;;5375:101;-1:-1:-1;5284:3:10;;;;:::i;:::-;;;;5246:241;;;;5511:29;:21;-1:-1:-1;;;;;5511:27:10;;:29::i;:::-;5497:44;;5552:26;5593:13;-1:-1:-1;;;;;5593:33:10;;5634:9;5645:18;5665:14;5593:87;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5552:128;-1:-1:-1;5725:27:10;-1:-1:-1;;;;;5767:17:10;:32;;5808:3;5552:128;5834:16;:12;5849:1;5834:16;:::i;:::-;5767:84;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5865:58;;-1:-1:-1;;;5865:58:10;;;;;4754:25:16;;;5725:126:10;;-1:-1:-1;5865:17:10;-1:-1:-1;;;;;5865:37:10;;;;4727:18:16;;5865:58:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5927:1;5865:63;5861:180;;-1:-1:-1;;;;;5944:17:10;:34;;5987:3;5993:18;6013:16;:12;6028:1;6013:16;:::i;:::-;5944:86;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5861:180;6073:301;;;;;;;;6121:15;-1:-1:-1;;;;;6073:301:10;;;;;6168:16;6073:301;;;;6227:27;6073:301;;;;;;;;;;:::i;:::-;;;;;;;;;;;6336:27;:14;;:27;:::i;:::-;6073:301;;;:::i;:::-;;;-1:-1:-1;;;;;6051:19:10;;;;;;;:14;:19;;;;;;;;;:323;;;;-1:-1:-1;;;;;;6051:323:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6051:323:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;6385:95:10;;-1:-1:-1;;;6385:95:10;;-1:-1:-1;;;;;6385:14:10;;;-1:-1:-1;6385:14:10;;:95;;6400:13;;6415:17;;6434:12;;6448:18;;6468:11;;;;6385:95;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6496:61:10;;;14116:25:16;;;6546:10:10;14172:2:16;14157:18;;14150:60;-1:-1:-1;;;;;6496:61:10;;;-1:-1:-1;6496:61:10;;-1:-1:-1;14089:18:16;6496:61:10;;;;;;;5048:1516;;;4668:1896;;;;;;;;;;:::o;7207:2613::-;-1:-1:-1;;;;;7328:19:10;;7285:27;7328:19;;;:14;:19;;;;;:32;;:39;:44;;7324:92;;7381:35;;-1:-1:-1;;;7381:35:10;;;;;;;;;;;7324:92;-1:-1:-1;;;;;7450:24:10;;7427:20;7450:24;;;;;;;;;;;;7521:19;;-1:-1:-1;;;7521:19:10;;;;7450:24;;;7521:17;;:19;;;;;;;;;;;7450:24;7521:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;7583:19:10;;;7550:30;7583:19;;;:14;:19;;;;;;;;7550:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7484:56;;-1:-1:-1;7550:30:10;;7583:19;;7550:52;;;;;;;;;:30;;:52;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7643:45;:37;-1:-1:-1;;;;;7643:43:10;;:45::i;:::-;7613:76;;7700:49;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7869:1:10;7848:3;-1:-1:-1;;;;;7848:16:10;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:22;;;;:::i;:::-;7832:12;:38;7828:283;;-1:-1:-1;;;;;7979:24:10;;:19;:24;;;;;;;;;;;7972:31;;;8024:14;:19;;;;;;8017:26;;-1:-1:-1;;;;;;8017:26:10;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;8017:26:10;;;;;;;;;8024:19;8017:26;;;;7979:19;8017:26;:::i;:::-;;;7828:283;;;-1:-1:-1;;;;;8074:24:10;;:19;:24;;;;;;;;;;:26;;;;;;:::i;:::-;;;;;;7828:283;8135:25;8163:6;:19;;;8183:12;8163:33;;;;;;;;:::i;:::-;;;;;;;8135:61;;8210:21;8234:13;-1:-1:-1;;;;;8234:31:10;;8273:9;8301:6;:23;;;8326:6;:34;;;8362:11;8234:153;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8210:177;;8450:22;8475:17;-1:-1:-1;;;;;8475:32:10;;8516:3;8522:13;8537:1;8475:64;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8557:53;;-1:-1:-1;;;8557:53:10;;;;;4754:25:16;;;8450:89:10;;-1:-1:-1;8557:17:10;-1:-1:-1;;;;;8557:37:10;;;;4727:18:16;;8557:53:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8614:1;8557:58;8553:163;;8635:66;;-1:-1:-1;;;8635:66:10;;-1:-1:-1;;;;;8635:17:10;:34;;;;:66;;8678:3;;8684:13;;8699:1;;8635:66;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8553:163;8814:26;;;;8777:83;;-1:-1:-1;;;8777:83:10;;8730:28;8777:83;;;16113:25:16;;;16154:18;;;16147:34;;;;8842:1:10;:17;;16197:18:16;;;16190:34;8777:17:10;-1:-1:-1;;;;;8777:33:10;;;;16086:18:16;;8777:83:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8730:130;;8891:136;8940:11;8953:6;:22;;;8977:20;8999:14;8891:31;:136::i;:::-;9070:244;;;;;;;;;;;;;;;;;;;;;;;;;;9277:22;;-1:-1:-1;;;;;9070:244:10;;;;;;;9492:196;;;;;;;9533:34;;;;;:47;:56;9492:196;;9617:34;:47;:56;;;9492:196;;;;;;;9335:390;;-1:-1:-1;;;9335:390:10;;8875:152;;-1:-1:-1;9070:244:10;;-1:-1:-1;9335:14:10;;;-1:-1:-1;9335:14:10;;:390;;9363:13;;9390:17;;9421:18;;9070:244;;9492:196;8875:152;;9335:390;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9794:3;-1:-1:-1;;;;;9741:72:10;9780:3;-1:-1:-1;;;;;9741:72:10;;9800:12;9741:72;;;;4754:25:16;;4742:2;4727:18;;4608:177;9741:72:10;;;;;;;;7314:2506;;;;;7207:2613;;;:::o;1047:787:0:-;1104:16;1436:48;1418:14;1412:4;1408:25;1402:4;1398:36;1395:90;1389:4;1382:104;1643:32;1626:14;1620:4;1616:25;1613:63;1607:4;1600:77;1718:4;1712;1709:1;1702:21;1690:33;-1:-1:-1;;;;;;1746:22:0;;1742:86;;1791:26;;-1:-1:-1;;;1791:26:0;;;;;;;;;;;1742:86;1047:787;;;:::o;9978:2146:10:-;10179:35;;:::i;:::-;10226:14;10266:15;-1:-1:-1;;;;;10243:49:10;;:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10226:68;;10304:22;10359:49;10373:11;10359:36;;;;;;;;:::i;:::-;;;;;;;;;;;;;:47;:49::i;:::-;10410:46;10424:11;10410:33;;;;;;;;:::i;:46::-;10458:8;10329:147;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;10304:172;;10486:21;10540:48;10554:11;10540:35;;;;;;;;:::i;:48::-;10590:46;10604:11;10590:33;;;;;;;;:::i;:46::-;10638:8;10510:146;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;10486:170;;10666:24;10723:47;10737:11;10723:34;;;;;;;;:::i;:47::-;10772:46;10786:11;10772:33;;;;;;;;:::i;:46::-;10820:8;10693:145;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;10693:145:10;;;;;;;;;;-1:-1:-1;;;10932:74:10;;;;;16113:25:16;;;16154:18;;;16147:34;;;11004:1:10;16197:18:16;;;16190:34;10693:145:10;-1:-1:-1;10849:18:10;;-1:-1:-1;;;;;10870:17:10;:31;;;;10915:15;;10870:31;;10932:33;;16086:18:16;;10932:74:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10870:146;;-1:-1:-1;;;;;;10870:146:10;;;;;;;-1:-1:-1;;;;;22418:32:16;;;10870:146:10;;;22400:51:16;22467:18;;;22460:34;22373:18;;10870:146:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11108:74;;-1:-1:-1;;;11108:74:10;;;;;16113:25:16;;;16154:18;;;16147:34;;;11180:1:10;16197:18:16;;;16190:34;10849:167:10;;-1:-1:-1;11026:17:10;;-1:-1:-1;;;;;11046:17:10;:31;;;;11091:15;;11046:31;;11108:33;;16086:18:16;;11108:74:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11046:146;;-1:-1:-1;;;;;;11046:146:10;;;;;;;-1:-1:-1;;;;;22418:32:16;;;11046:146:10;;;22400:51:16;22467:18;;;22460:34;22373:18;;11046:146:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11287:74;;-1:-1:-1;;;11287:74:10;;11359:1;11287:74;;;16113:25:16;;;16154:18;;;16147:34;;;16197:18;;;16190:34;11026:166:10;;-1:-1:-1;11202:20:10;;-1:-1:-1;;;;;11225:17:10;:31;;;;11270:15;;11225:31;;11287:33;;16086:18:16;;11287:74:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11225:146;;-1:-1:-1;;;;;;11225:146:10;;;;;;;-1:-1:-1;;;;;22418:32:16;;;11225:146:10;;;22400:51:16;22467:18;;;22460:34;22373:18;;11225:146:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11202:169;;11382:19;11404:18;-1:-1:-1;;;;;11404:37:10;;11442:17;11461:10;11473:9;11404:79;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11382:101;;11493:18;11514;-1:-1:-1;;;;;11514:37:10;;11552:17;11571:9;11582:8;11514:77;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11493:98;;11601:21;11625:18;-1:-1:-1;;;;;11625:37:10;;11663:17;11682:12;11696:11;11625:83;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11726:391;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;11726:391:10;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11726:391:10;9978:2146;-1:-1:-1;;;;;;9978:2146:10:o;428:861:15:-;542:19;;492:21;;584:2;575:11;;571:52;;;617:5;595:28;;-1:-1:-1;;;595:28:15;;;;;;;;:::i;571:52::-;830:4;823:5;819:16;813:23;796:40;;967:12;1029:1;1018:6;1013:2;:11;;;;:::i;:::-;-1:-1:-1;;1012:18:15;;990:41;1058:20;;;;1280:1;1270:11;;;;1246:36;;;-1:-1:-1;;428:861:15:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;588:153:16;-1:-1:-1;;;;;685:31:16;;675:42;;665:70;;731:1;728;721:12;746:164;822:20;;851:53;822:20;851:53;:::i;915:348::-;967:8;977:6;1031:3;1024:4;1016:6;1012:17;1008:27;998:55;;1049:1;1046;1039:12;998:55;-1:-1:-1;1072:20:16;;1115:18;1104:30;;1101:50;;;1147:1;1144;1137:12;1101:50;1184:4;1176:6;1172:17;1160:29;;1236:3;1229:4;1220:6;1212;1208:19;1204:30;1201:39;1198:59;;;1253:1;1250;1243:12;1198:59;915:348;;;;;:::o;1268:1309::-;1524:6;1532;1540;1548;1556;1564;1572;1580;1624:9;1615:7;1611:23;1654:3;1650:2;1646:12;1643:32;;;1671:1;1668;1661:12;1643:32;1710:9;1697:23;1729:53;1776:5;1729:53;:::i;:::-;1801:5;-1:-1:-1;1853:2:16;1838:18;;1825:32;;-1:-1:-1;1904:2:16;1889:18;;1876:32;;-1:-1:-1;1959:2:16;1944:18;;1931:32;1982:18;2012:14;;;2009:34;;;2039:1;2036;2029:12;2009:34;2062:22;;;;2118:2;2100:16;;;2096:25;2093:45;;;2134:1;2131;2124:12;2093:45;2157:2;2147:12;;2194:2;2187:3;2183:8;2179:2;2175:17;2171:26;2168:46;;;2210:1;2207;2200:12;2168:46;2248:3;2237:9;2233:19;2223:29;;2271:47;2313:3;2302:9;2298:19;2271:47;:::i;:::-;2261:57;;2371:3;2360:9;2356:19;2343:33;2327:49;;2401:2;2391:8;2388:16;2385:36;;;2417:1;2414;2407:12;2385:36;;;2456:61;2509:7;2498:8;2487:9;2483:24;2456:61;:::i;:::-;1268:1309;;;;-1:-1:-1;1268:1309:16;;-1:-1:-1;1268:1309:16;;;;;;2536:8;-1:-1:-1;;;1268:1309:16:o;2806:285::-;2881:6;2934:2;2922:9;2913:7;2909:23;2905:32;2902:52;;;2950:1;2947;2940:12;2902:52;2989:9;2976:23;3008:53;3055:5;3008:53;:::i;:::-;3080:5;2806:285;-1:-1:-1;;;2806:285:16:o;3828:209::-;3909:49;3954:3;3946:5;3940:12;3649;;3637:25;;3711:4;3700:16;;;3694:23;3678:14;;3671:47;3571:153;3909:49;4011:4;4000:16;3994:23;4019:10;3990:40;3983:4;3974:14;;;;3967:64;3828:209::o;4042:561::-;-1:-1:-1;;;;;4395:32:16;;4377:51;;4459:2;4444:18;;4437:34;;;4364:3;4349:19;;4480:73;4549:2;4534:18;;4526:6;4480:73;:::i;:::-;4590:6;4584:3;4573:9;4569:19;4562:35;4042:561;;;;;;;:::o;4790:557::-;4895:4;4901:6;4961:11;4948:25;5055:2;5051:7;5040:8;5024:14;5020:29;5016:43;4996:18;4992:68;4982:96;;5074:1;5071;5064:12;4982:96;5101:33;;5153:20;;;-1:-1:-1;5196:18:16;5185:30;;5182:50;;;5228:1;5225;5218:12;5182:50;5261:4;5249:17;;-1:-1:-1;5312:1:16;5308:14;;;5292;5288:35;5278:46;;5275:66;;;5337:1;5334;5327:12;5352:127;5413:10;5408:3;5404:20;5401:1;5394:31;5444:4;5441:1;5434:15;5468:4;5465:1;5458:15;5484:522;5562:4;5568:6;5628:11;5615:25;5722:2;5718:7;5707:8;5691:14;5687:29;5683:43;5663:18;5659:68;5649:96;;5741:1;5738;5731:12;5649:96;5768:33;;5820:20;;;-1:-1:-1;5863:18:16;5852:30;;5849:50;;;5895:1;5892;5885:12;5849:50;5928:4;5916:17;;-1:-1:-1;5959:14:16;5955:27;;;5945:38;;5942:58;;;5996:1;5993;5986:12;6011:250;6096:1;6106:113;6120:6;6117:1;6114:13;6106:113;;;6196:11;;;6190:18;6177:11;;;6170:39;6142:2;6135:10;6106:113;;;-1:-1:-1;;6253:1:16;6235:16;;6228:27;6011:250::o;6266:271::-;6308:3;6346:5;6340:12;6373:6;6368:3;6361:19;6389:76;6458:6;6451:4;6446:3;6442:14;6435:4;6428:5;6424:16;6389:76;:::i;:::-;6519:2;6498:15;-1:-1:-1;;6494:29:16;6485:39;;;;6526:4;6481:50;;6266:271;-1:-1:-1;;6266:271:16:o;6542:220::-;6691:2;6680:9;6673:21;6654:4;6711:45;6752:2;6741:9;6737:18;6729:6;6711:45;:::i;6767:127::-;6828:10;6823:3;6819:20;6816:1;6809:31;6859:4;6856:1;6849:15;6883:4;6880:1;6873:15;6899:135;6938:3;6959:17;;;6956:43;;6979:18;;:::i;:::-;-1:-1:-1;7026:1:16;7015:13;;6899:135::o;7039:267::-;7128:6;7123:3;7116:19;7180:6;7173:5;7166:4;7161:3;7157:14;7144:43;-1:-1:-1;7232:1:16;7207:16;;;7225:4;7203:27;;;7196:38;;;;7288:2;7267:15;;;-1:-1:-1;;7263:29:16;7254:39;;;7250:50;;7039:267::o;7311:163::-;7378:20;;7438:10;7427:22;;7417:33;;7407:61;;7464:1;7461;7454:12;7479:1961;7679:4;7708:2;7737:6;7726:9;7719:25;7763:2;7801;7796;7785:9;7781:18;7774:30;7842:3;7831:9;7827:19;7894:6;7881:20;7981:2;7977:7;7968:6;7952:14;7948:27;7944:41;7924:18;7920:66;7910:94;;8000:1;7997;7990:12;7910:94;8026:31;;8080:19;;8123:14;;;8156:18;8186:14;;;8183:34;;;8213:1;8210;8203:12;8183:34;8243:6;8240:1;8236:14;8295:2;8279:14;8275:23;8266:7;8262:37;8259:57;;;8312:1;8309;8302:12;8259:57;8332:18;;;8325:30;;;8390:22;;;;8443:3;8474:18;;;8470:28;;;8546:1;;8428:19;;-1:-1:-1;;8574:14:16;8570:26;;;8566:40;8615:673;8629:6;8626:1;8623:13;8615:673;;;8694:22;;;-1:-1:-1;;8690:37:16;8678:50;;8769:20;;8812:29;;;8802:57;;8855:1;8852;8845:12;8802:57;8882:32;;8996:11;;;;8956;;8943:25;9023:16;;;9020:36;;;9052:1;9049;9042:12;9020:36;9105:8;9089:14;9085:29;9076:7;9072:43;9069:63;;;9128:1;9125;9118:12;9069:63;9155:53;9201:6;9191:8;9182:7;9155:53;:::i;:::-;9145:63;-1:-1:-1;;;9231:15:16;;;;8651:1;8644:9;;;;;9266:12;;;;8615:673;;;8619:3;;;;;;;9317:34;9347:2;9339:6;9335:15;9317:34;:::i;:::-;3805:10;3794:22;;9407:2;9392:18;;3782:35;9297:54;-1:-1:-1;9428:6:16;7479:1961;-1:-1:-1;;;;;;7479:1961:16:o;9445:184::-;9515:6;9568:2;9556:9;9547:7;9543:23;9539:32;9536:52;;;9584:1;9581;9574:12;9536:52;-1:-1:-1;9607:16:16;;9445:184;-1:-1:-1;9445:184:16:o;9634:125::-;9699:9;;;9720:10;;;9717:36;;;9733:18;;:::i;:::-;9634:125;;;;:::o;9764:345::-;-1:-1:-1;;;;;9984:32:16;;;;9966:51;;10048:2;10033:18;;10026:34;;;;10091:2;10076:18;;10069:34;9954:2;9939:18;;9764:345::o;10485:127::-;10546:10;10541:3;10537:20;10534:1;10527:31;10577:4;10574:1;10567:15;10601:4;10598:1;10591:15;10617:257;10689:4;10683:11;;;10721:17;;10768:18;10753:34;;10789:22;;;10750:62;10747:88;;;10815:18;;:::i;:::-;10851:4;10844:24;10617:257;:::o;10879:275::-;10950:2;10944:9;11015:2;10996:13;;-1:-1:-1;;10992:27:16;10980:40;;11050:18;11035:34;;11071:22;;;11032:62;11029:88;;;11097:18;;:::i;:::-;11133:2;11126:22;10879:275;;-1:-1:-1;10879:275:16:o;11159:579::-;11263:6;11307:9;11298:7;11294:23;11337:2;11333;11329:11;11326:31;;;11353:1;11350;11343:12;11326:31;11379:22;;:::i;:::-;11421:4;11417:2;11413:13;11410:33;;;11439:1;11436;11429:12;11410:33;11467:22;;:::i;:::-;11452:37;;11527:9;11514:23;11505:7;11498:40;11600:2;11589:9;11585:18;11572:32;11567:2;11558:7;11554:16;11547:58;11628:7;11621:5;11614:22;11668:39;11701:4;11690:9;11686:20;11668:39;:::i;:::-;11663:2;11652:14;;11645:63;11656:5;11159:579;-1:-1:-1;;;;11159:579:16:o;11743:1543::-;11881:9;11915:18;11956:2;11948:6;11945:14;11942:40;;;11962:18;;:::i;:::-;12008:6;12005:1;12001:14;12034:4;12058:28;12082:2;12078;12074:11;12058:28;:::i;:::-;12120:19;;;12190:14;;;;12155:12;;;;12227:14;12216:26;;12213:46;;;12255:1;12252;12245:12;12213:46;12279:5;12293:960;12309:6;12304:3;12301:15;12293:960;;;12395:3;12382:17;12431:2;12418:11;12415:19;12412:109;;;12475:1;12504:2;12500;12493:14;12412:109;12544:23;;12590:4;12634:14;12621:11;;;12617:32;12607:130;;12691:1;12720:2;12716;12709:14;12607:130;12773:2;12760:16;12799:2;12795;12792:10;12789:36;;;12805:18;;:::i;:::-;12851:51;12875:11;;;-1:-1:-1;;12871:25:16;12867:34;;12851:51;:::i;:::-;12838:64;;12929:2;12922:5;12915:17;12973:14;12968:2;12963;12959;12955:11;12951:20;12948:40;12945:130;;;13029:1;13058:2;13054;13047:14;12945:130;13130:2;13125;13121;13117:11;13112:2;13105:5;13101:14;13088:45;13178:1;13157:14;;;13153:23;;13146:34;13193:18;;-1:-1:-1;13231:12:16;;;;12326;;12293:960;;;-1:-1:-1;13275:5:16;11743:1543;-1:-1:-1;;;;;;;11743:1543:16:o;13291:646::-;-1:-1:-1;;;;;13656:15:16;;;13638:34;;13708:15;;13703:2;13688:18;;13681:43;13755:2;13740:18;;13733:34;;;13798:2;13783:18;;13776:34;;;13618:3;13841;13826:19;;13819:32;;;13581:4;;13868:63;;13911:19;;13903:6;13895;13868:63;:::i;:::-;13860:71;13291:646;-1:-1:-1;;;;;;;;13291:646:16:o;14221:302::-;14320:6;14373:2;14361:9;14352:7;14348:23;14344:32;14341:52;;;14389:1;14386;14379:12;14341:52;14421:9;14415:16;14440:53;14487:5;14440:53;:::i;14528:380::-;14607:1;14603:12;;;;14650;;;14671:61;;14725:4;14717:6;14713:17;14703:27;;14671:61;14778:2;14770:6;14767:14;14747:18;14744:38;14741:161;;14824:10;14819:3;14815:20;14812:1;14805:31;14859:4;14856:1;14849:15;14887:4;14884:1;14877:15;14741:161;;14528:380;;;:::o;14913:128::-;14980:9;;;15001:11;;;14998:37;;;15015:18;;:::i;15046:494::-;15341:6;15330:9;15323:25;15357:73;15426:2;15415:9;15411:18;15403:6;15357:73;:::i;:::-;15467:3;15461;15450:9;15446:19;15439:32;15304:4;15488:46;15529:3;15518:9;15514:19;15506:6;15488:46;:::i;:::-;15480:54;15046:494;-1:-1:-1;;;;;15046:494:16:o;16235:2325::-;16789:4;16818:3;16857:1;16853;16848:3;16844:11;16840:19;16898:2;16890:6;16886:15;16875:9;16868:34;16950:2;16942:6;16938:15;16933:2;16922:9;16918:18;16911:43;17002:2;16994:6;16990:15;16985:2;16974:9;16970:18;16963:43;17048:6;17042:13;17037:2;17026:9;17022:18;17015:41;17111:2;17103:6;17099:15;17093:22;17087:3;17076:9;17072:19;17065:51;17171:2;17163:6;17159:15;17153:22;17147:3;17136:9;17132:19;17125:51;17241:2;17235;17227:6;17223:15;17217:22;17213:31;17207:3;17196:9;17192:19;17185:60;;17254:59;17308:3;17297:9;17293:19;17285:6;3649:12;;3637:25;;3711:4;3700:16;;;3694:23;3678:14;;3671:47;3571:153;17254:59;17332:3;17371:2;17366;17355:9;17351:18;17344:30;17409:6;17403:13;17452:2;17447;17436:9;17432:18;17425:30;17478:52;17525:3;17514:9;17510:19;17496:12;17478:52;:::i;:::-;17464:66;;;;17579:2;17571:6;17567:15;17561:22;17606:3;17602:8;17675:2;17663:9;17655:6;17651:22;17647:31;17641:3;17630:9;17626:19;17619:60;17702:41;17736:6;17720:14;17702:41;:::i;:::-;17688:55;;17792:2;17784:6;17780:15;17774:22;17752:44;;17861:2;17849:9;17841:6;17837:22;17833:31;17827:3;17816:9;17812:19;17805:60;;17888:41;17922:6;17906:14;17888:41;:::i;:::-;17874:55;;;17984:2;17976:6;17972:15;17966:22;17960:3;17949:9;17945:19;17938:51;18044:3;18036:6;18032:16;18026:23;18020:3;18009:9;18005:19;17998:52;18105:3;18097:6;18093:16;18087:23;18081:3;18070:9;18066:19;18059:52;18160:3;18152:6;18148:16;18142:23;18174:76;18245:3;18234:9;18230:19;18214:14;-1:-1:-1;;;;;309:31:16;297:44;;222:125;18174:76;-1:-1:-1;18299:3:16;18287:16;;18281:23;-1:-1:-1;;;;;309:31:16;;18384:3;18369:19;;297:44;-1:-1:-1;18438:6:16;18426:19;;18420:26;-1:-1:-1;;;;;309:31:16;;18526:3;18511:19;;297:44;-1:-1:-1;18548:6:16;16235:2325;-1:-1:-1;;;;;;;;16235:2325:16:o;18565:273::-;18633:6;18686:2;18674:9;18665:7;18661:23;18657:32;18654:52;;;18702:1;18699;18692:12;18654:52;18734:9;18728:16;18784:4;18777:5;18773:16;18766:5;18763:27;18753:55;;18804:1;18801;18794:12;18843:446;19064:3;19102:6;19096:13;19118:66;19177:6;19172:3;19165:4;19157:6;19153:17;19118:66;:::i;:::-;-1:-1:-1;;;19206:16:16;;19231:23;;;-1:-1:-1;19281:1:16;19270:13;;18843:446;-1:-1:-1;18843:446:16:o;19294:443::-;19515:3;19553:6;19547:13;19569:66;19628:6;19623:3;19616:4;19608:6;19604:17;19569:66;:::i;:::-;-1:-1:-1;;;19657:16:16;;19682:20;;;-1:-1:-1;19729:1:16;19718:13;;19294:443;-1:-1:-1;19294:443:16:o;19742:338::-;19923:19;;;19967:2;19958:12;;19951:28;;;;20035:3;20013:16;-1:-1:-1;;;;;;20009:36:16;20004:2;19995:12;;19988:58;20071:2;20062:12;;19742:338::o;20085:445::-;20306:3;20344:6;20338:13;20360:66;20419:6;20414:3;20407:4;20399:6;20395:17;20360:66;:::i;:::-;-1:-1:-1;;;20448:16:16;;20473:22;;;-1:-1:-1;20522:1:16;20511:13;;20085:445;-1:-1:-1;20085:445:16:o;20535:443::-;20756:3;20794:6;20788:13;20810:66;20869:6;20864:3;20857:4;20849:6;20845:17;20810:66;:::i;:::-;-1:-1:-1;;;20898:16:16;;20923:20;;;-1:-1:-1;20970:1:16;20959:13;;20535:443;-1:-1:-1;20535:443:16:o;20983:444::-;21204:3;21242:6;21236:13;21258:66;21317:6;21312:3;21305:4;21297:6;21293:17;21258:66;:::i;:::-;-1:-1:-1;;;21346:16:16;;21371:21;;;-1:-1:-1;21419:1:16;21408:13;;20983:444;-1:-1:-1;20983:444:16:o;21432:443::-;21653:3;21691:6;21685:13;21707:66;21766:6;21761:3;21754:4;21746:6;21742:17;21707:66;:::i;:::-;-1:-1:-1;;;21795:16:16;;21820:20;;;-1:-1:-1;21867:1:16;21856:13;;21432:443;-1:-1:-1;21432:443:16:o;23169:413::-;23428:1;23424;23419:3;23415:11;23411:19;23403:6;23399:32;23388:9;23381:51;23468:6;23463:2;23452:9;23448:18;23441:34;23511:2;23506;23495:9;23491:18;23484:30;23362:4;23531:45;23572:2;23561:9;23557:18;23549:6;23531:45;:::i;24005:545::-;24107:2;24102:3;24099:11;24096:448;;;24143:1;24168:5;24164:2;24157:17;24213:4;24209:2;24199:19;24283:2;24271:10;24267:19;24264:1;24260:27;24254:4;24250:38;24319:4;24307:10;24304:20;24301:47;;;-1:-1:-1;24342:4:16;24301:47;24397:2;24392:3;24388:12;24385:1;24381:20;24375:4;24371:31;24361:41;;24452:82;24470:2;24463:5;24460:13;24452:82;;;24515:17;;;24496:1;24485:13;24452:82;;;24456:3;;;24096:448;24005:545;;;:::o;24726:1352::-;24852:3;24846:10;24879:18;24871:6;24868:30;24865:56;;;24901:18;;:::i;:::-;24930:97;25020:6;24980:38;25012:4;25006:11;24980:38;:::i;:::-;24974:4;24930:97;:::i;:::-;25082:4;;25146:2;25135:14;;25163:1;25158:663;;;;25865:1;25882:6;25879:89;;;-1:-1:-1;25934:19:16;;;25928:26;25879:89;-1:-1:-1;;24683:1:16;24679:11;;;24675:24;24671:29;24661:40;24707:1;24703:11;;;24658:57;25981:81;;25128:944;;25158:663;23952:1;23945:14;;;23989:4;23976:18;;-1:-1:-1;;25194:20:16;;;25312:236;25326:7;25323:1;25320:14;25312:236;;;25415:19;;;25409:26;25394:42;;25507:27;;;;25475:1;25463:14;;;;25342:19;;25312:236;;;25316:3;25576:6;25567:7;25564:19;25561:201;;;25637:19;;;25631:26;-1:-1:-1;;25720:1:16;25716:14;;;25732:3;25712:24;25708:37;25704:42;25689:58;25674:74;;25561:201;-1:-1:-1;;;;;25808:1:16;25792:14;;;25788:22;25775:36;;-1:-1:-1;24726:1352:16:o

Swarm Source

ipfs://2993dddd75af0a1e1d282fbe071211f81c58ae99d39859503428081da1c87208

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
0x1CB663EBf8F4cf7D988D783Df8a93B1AA85f331F
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ 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.