ETH Price: $1,777.90 (+4.31%)

Contract

0x7d244d4a6D3D932146B9fAD46C433052489DED3a

Overview

ETH Balance

0 ETH

ETH Value

$0.00

Multichain Info

No addresses found
Age:1H
Reset Filter

Transaction Hash
Method
Block
From
To

There are no matching entries

1 Internal Transaction and > 10 Token Transfers found.

Latest 1 internal transaction

Parent Transaction Hash Block From To
106289902025-03-07 19:55:4946 days ago1741377349  Contract Creation0 ETH

Loading...
Loading

Minimal Proxy Contract for 0x776b25f71c7e08cbd99f3578f0b8a4628502df2e

Contract Name:
ConditionalScalarMarket

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)

File 1 of 11 : ConditionalScalarMarket.sol
// 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 2 of 11 : IERC20.sol
// 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);
}

File 3 of 11 : IERC1155.sol
// 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;
}

File 4 of 11 : ERC1155Holder.sol
// 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;
    }
}

File 5 of 11 : IWrapped1155Factory.sol
// 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;
}

File 6 of 11 : IConditionalTokens.sol
// 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);
}

File 7 of 11 : 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;
}

File 8 of 11 : FlatCFMOracleAdapter.sol
// 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);
}

File 9 of 11 : IERC165.sol
// 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);
}

File 10 of 11 : ERC165.sol
// 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;
    }
}

File 11 of 11 : IERC1155Receiver.sol
// 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,
  "libraries": {}
}

Contract ABI

API
[{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"WrappedInvalidTransferFailed","type":"error"},{"inputs":[],"name":"WrappedLongTransferFailed","type":"error"},{"inputs":[],"name":"WrappedShortTransferFailed","type":"error"},{"inputs":[],"name":"conditionalTokens","outputs":[{"internalType":"contract IConditionalTokens","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ctParams","outputs":[{"internalType":"bytes32","name":"questionId","type":"bytes32"},{"internalType":"bytes32","name":"conditionId","type":"bytes32"},{"internalType":"bytes32","name":"parentCollectionId","type":"bytes32"},{"internalType":"contract IERC20","name":"collateralToken","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract FlatCFMOracleAdapter","name":"_oracleAdapter","type":"address"},{"internalType":"contract IConditionalTokens","name":"_conditionalTokens","type":"address"},{"internalType":"contract IWrapped1155Factory","name":"_wrapped1155Factory","type":"address"},{"components":[{"internalType":"bytes32","name":"questionId","type":"bytes32"},{"internalType":"bytes32","name":"conditionId","type":"bytes32"},{"internalType":"bytes32","name":"parentCollectionId","type":"bytes32"},{"internalType":"contract IERC20","name":"collateralToken","type":"address"}],"internalType":"struct ConditionalScalarCTParams","name":"_conditionalScalarCTParams","type":"tuple"},{"components":[{"internalType":"uint256","name":"minValue","type":"uint256"},{"internalType":"uint256","name":"maxValue","type":"uint256"}],"internalType":"struct ScalarParams","name":"_scalarParams","type":"tuple"},{"components":[{"internalType":"bytes","name":"shortData","type":"bytes"},{"internalType":"bytes","name":"longData","type":"bytes"},{"internalType":"bytes","name":"invalidData","type":"bytes"},{"internalType":"uint256","name":"shortPositionId","type":"uint256"},{"internalType":"uint256","name":"longPositionId","type":"uint256"},{"internalType":"uint256","name":"invalidPositionId","type":"uint256"},{"internalType":"contract IERC20","name":"wrappedShort","type":"address"},{"internalType":"contract IERC20","name":"wrappedLong","type":"address"},{"internalType":"contract IERC20","name":"wrappedInvalid","type":"address"}],"internalType":"struct WrappedConditionalTokensData","name":"_wrappedCTData","type":"tuple"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"merge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"oracleAdapter","outputs":[{"internalType":"contract FlatCFMOracleAdapter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shortAmount","type":"uint256"},{"internalType":"uint256","name":"longAmount","type":"uint256"},{"internalType":"uint256","name":"invalidAmount","type":"uint256"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resolve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"scalarParams","outputs":[{"internalType":"uint256","name":"minValue","type":"uint256"},{"internalType":"uint256","name":"maxValue","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"split","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wrapped1155Factory","outputs":[{"internalType":"contract IWrapped1155Factory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wrappedCTData","outputs":[{"internalType":"bytes","name":"shortData","type":"bytes"},{"internalType":"bytes","name":"longData","type":"bytes"},{"internalType":"bytes","name":"invalidData","type":"bytes"},{"internalType":"uint256","name":"shortPositionId","type":"uint256"},{"internalType":"uint256","name":"longPositionId","type":"uint256"},{"internalType":"uint256","name":"invalidPositionId","type":"uint256"},{"internalType":"contract IERC20","name":"wrappedShort","type":"address"},{"internalType":"contract IERC20","name":"wrappedLong","type":"address"},{"internalType":"contract IERC20","name":"wrappedInvalid","type":"address"}],"stateMutability":"view","type":"function"}]

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
[ 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.