Contract 0x6A9D222616C90FcA5754cd1333cFD9b7fb6a4F74 1

 
 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0xe868210fdf3dad115d09bea76074285ac64618c30b150c1eab45d2ba3d1071eaInitialize361850602022-11-28 19:55:081 hr 1 min ago0x281777d3bdd096d302791f94a2e429bb98474227 IN  0x6a9d222616c90fca5754cd1333cfd9b7fb6a4f740 MATIC0.071884347 51
0x19dfffdcc9e8e309cb17adf7610f4fab66b0a8097177b0e75ed4af0312555f7fResolve360554562022-11-25 16:12:013 days 4 hrs ago0x8378f26c6cf976912bf8ec4c434f0a6081a04a26 IN  0x6a9d222616c90fca5754cd1333cfd9b7fb6a4f740 MATIC0.008040813 51
0xfc277eac6d3e617e3321e0b7cf8aee080f3b465224fd3ada8ee30f7d8fccc787Initialize359820692022-11-23 21:31:274 days 23 hrs ago0x281777d3bdd096d302791f94a2e429bb98474227 IN  0x6a9d222616c90fca5754cd1333cfd9b7fb6a4f740 MATIC0.027979616 32
0x607fad9dd07beaa70e769f0c44747f223b6a384a79699f24d0d3b8dd74974b11Add Admin359383072022-11-22 19:54:196 days 1 hr ago0x4ffcfd5007270b6e0f348fdca85f9565bb6bae4e IN  0x6a9d222616c90fca5754cd1333cfd9b7fb6a4f740 MATIC0.0047727 100
0xf151d2181e2a386bfd3b2c4347bb21a0203e184cb99947629708512fec7aeea0Initialize359378792022-11-22 19:36:346 days 1 hr ago0x281777d3bdd096d302791f94a2e429bb98474227 IN  0x6a9d222616c90fca5754cd1333cfd9b7fb6a4f740 MATIC0.093401187 61
0x3fd7390766fee487db5cc439eff27e67a53ae298928a509ff076a702ea81740cInitialize359377312022-11-22 19:31:306 days 1 hr ago0x281777d3bdd096d302791f94a2e429bb98474227 IN  0x6a9d222616c90fca5754cd1333cfd9b7fb6a4f740 MATIC0.0839968 64
0x5af192bf734db4d475e60c967e3ad0351930ae4ce3332ba8de222ba12e28d369Resolve359303422022-11-22 15:14:126 days 5 hrs ago0x17eb2c35621e02129c43bba7c682cae127a9191b IN  0x6a9d222616c90fca5754cd1333cfd9b7fb6a4f740 MATIC0.0762555 500
0xe2995bd3f0bbde43451e794233c01133c6eb6af95991f95e4c78aafe8f7c23acInitialize359005062022-11-21 21:55:176 days 23 hrs ago0x91430cad2d3975766499717fa0d66a78d814e5c5 IN  0x6a9d222616c90fca5754cd1333cfd9b7fb6a4f740 MATIC0.039633216 48
0xd4661e8d3135ac3ab9c0f561675ffacc1bc2feaddd736112d30228a670a6c23fInitialize357318922022-11-17 19:40:5611 days 1 hr ago0x281777d3bdd096d302791f94a2e429bb98474227 IN  0x6a9d222616c90fca5754cd1333cfd9b7fb6a4f740 MATIC0.029863416 41
0xd1c3ea8be68e706b5e0ac9cb7de73f8fb7bdc5b7de7455e72db40f3d98d6211cInitialize356445852022-11-15 16:47:1013 days 4 hrs ago0x281777d3bdd096d302791f94a2e429bb98474227 IN  0x6a9d222616c90fca5754cd1333cfd9b7fb6a4f740 MATIC0.07095622 79
0x712964cb837f5197296a12deada2d29d4837d7231410e1c474b710e5c5f39773Initialize356141872022-11-14 22:59:1913 days 21 hrs ago0x281777d3bdd096d302791f94a2e429bb98474227 IN  0x6a9d222616c90fca5754cd1333cfd9b7fb6a4f740 MATIC0.050296064 56
0x0a3240fcf76574ded328821d522e56590b3ff2004439c388af155c7801a3a28fInitialize356116922022-11-14 21:33:2913 days 23 hrs ago0x281777d3bdd096d302791f94a2e429bb98474227 IN  0x6a9d222616c90fca5754cd1333cfd9b7fb6a4f740 MATIC0.047604176 53
0x798e397ca52aa66f74b4d26f33a3ef375cfcce52bf37c35dcafdee880e253d82Initialize356109752022-11-14 21:07:0013 days 23 hrs ago0x281777d3bdd096d302791f94a2e429bb98474227 IN  0x6a9d222616c90fca5754cd1333cfd9b7fb6a4f740 MATIC0.099695316 111
0xb2317e557f188dc3d6f31084d5730acba25812013aef324910b1c88bb99601fdInitialize356096302022-11-14 20:20:4514 days 35 mins ago0x281777d3bdd096d302791f94a2e429bb98474227 IN  0x6a9d222616c90fca5754cd1333cfd9b7fb6a4f740 MATIC0.185918292 207
0xb3ddec625d3492d3c2ea415813b2f32f1701b8594ab6eb69d7cfac620f2bfcc0Initialize356036372022-11-14 16:54:4014 days 4 hrs ago0x281777d3bdd096d302791f94a2e429bb98474227 IN  0x6a9d222616c90fca5754cd1333cfd9b7fb6a4f740 MATIC0.03934989 45
0x3a888a9e0bbb482cb88b6001c1c90e8ddca2eea688496a5ba92b427e9a3fc052Resolve352466042022-11-05 21:24:3122 days 23 hrs ago0x2a01053193bb980f5b9ca8fa0eb516ac3317cc1a IN  0x6a9d222616c90fca5754cd1333cfd9b7fb6a4f740 MATIC0.0225911 100
0xc33d0c97bc5e893067939be484f953b1b3e2bb20ce1dee60fe3d420e2fba0ddbInitialize352035402022-11-04 20:20:3024 days 35 mins ago0x2a01053193bb980f5b9ca8fa0eb516ac3317cc1a IN  0x6a9d222616c90fca5754cd1333cfd9b7fb6a4f740 MATIC0.1547618 200
0x1655ff8b0aa502ee113f46d1429a8abe3d57a8775c8071475aeca71f5dca3baa0x60e06040348761442022-10-27 20:15:0332 days 41 mins ago0x4ffcfd5007270b6e0f348fdca85f9565bb6bae4e IN  Create: UmaCtfAdapter0 MATIC0.674480141185 214.540293312
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
UmaCtfAdapter

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 1000000 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 16 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

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

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

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

File 2 of 16 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @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 amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

    /**
     * @dev Moves `amount` 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 amount) 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 `amount` 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 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` 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 amount
    ) external returns (bool);
}

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

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

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

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

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

    string public name;

    string public symbol;

    uint8 public immutable decimals;

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

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

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

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

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

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

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

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

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

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

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

        return true;
    }

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

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

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

        return true;
    }

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

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

        balanceOf[from] -= amount;

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

        emit Transfer(from, to, amount);

        return true;
    }

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

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

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

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

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

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

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

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

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

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

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

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

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

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

File 4 of 16 : SafeTransferLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

import {ERC20} from "../tokens/ERC20.sol";

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
    /*//////////////////////////////////////////////////////////////
                             ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferETH(address to, uint256 amount) internal {
        bool success;

        assembly {
            // Transfer the ETH and store if it succeeded or not.
            success := call(gas(), to, amount, 0, 0, 0, 0)
        }

        require(success, "ETH_TRANSFER_FAILED");
    }

    /*//////////////////////////////////////////////////////////////
                            ERC20 OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferFrom(
        ERC20 token,
        address from,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), from) // Append the "from" argument.
            mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
            )
        }

        require(success, "TRANSFER_FROM_FAILED");
    }

    function safeTransfer(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "TRANSFER_FAILED");
    }

    function safeApprove(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "APPROVE_FAILED");
    }
}

File 5 of 16 : UmaCtfAdapter.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import { IERC20 } from "openzeppelin-contracts/token/ERC20/IERC20.sol";
import { ReentrancyGuard } from "openzeppelin-contracts/security/ReentrancyGuard.sol";

import { Auth } from "./mixins/Auth.sol";
import { BulletinBoard } from "./mixins/BulletinBoard.sol";

import { TransferHelper } from "./libraries/TransferHelper.sol";
import { AncillaryDataLib } from "./libraries/AncillaryDataLib.sol";

import { IFinder } from "./interfaces/IFinder.sol";
import { IAddressWhitelist } from "./interfaces/IAddressWhitelist.sol";
import { IConditionalTokens } from "./interfaces/IConditionalTokens.sol";
import { IOptimisticOracleV2 } from "./interfaces/IOptimisticOracleV2.sol";
import { IOptimisticRequester } from "./interfaces/IOptimisticRequester.sol";

import { QuestionData, IUmaCtfAdapter } from "./interfaces/IUmaCtfAdapter.sol";

/// @title UmaCtfAdapter
/// @notice Enables resolution of Polymarket CTF markets via UMA's Optimistic Oracle
contract UmaCtfAdapter is IUmaCtfAdapter, Auth, BulletinBoard, IOptimisticRequester, ReentrancyGuard {
    /*///////////////////////////////////////////////////////////////////
                            IMMUTABLES 
    //////////////////////////////////////////////////////////////////*/

    /// @notice Conditional Tokens Framework
    IConditionalTokens public immutable ctf;

    /// @notice Optimistic Oracle
    IOptimisticOracleV2 public immutable optimisticOracle;

    /// @notice Collateral Whitelist
    IAddressWhitelist public immutable collateralWhitelist;

    /// @notice Time period after which an admin can emergency resolve a condition
    uint256 public constant emergencySafetyPeriod = 2 days;

    /// @notice Unique query identifier for the Optimistic Oracle
    bytes32 public constant yesOrNoIdentifier = "YES_OR_NO_QUERY";

    /// @notice Maximum ancillary data length
    uint256 public constant maxAncillaryData = 8139;

    /// @notice Mapping of questionID to QuestionData
    mapping(bytes32 => QuestionData) public questions;

    modifier onlyOptimisticOracle() {
        if (msg.sender != address(optimisticOracle)) revert NotOptimisticOracle();
        _;
    }

    constructor(address _ctf, address _finder) {
        ctf = IConditionalTokens(_ctf);
        IFinder finder = IFinder(_finder);
        optimisticOracle = IOptimisticOracleV2(finder.getImplementationAddress("OptimisticOracleV2"));
        collateralWhitelist = IAddressWhitelist(finder.getImplementationAddress("CollateralWhitelist"));
    }

    /*///////////////////////////////////////////////////////////////////
                            PUBLIC FUNCTIONS 
    //////////////////////////////////////////////////////////////////*/

    /// @notice Initializes a question
    /// Atomically adds the question to the Adapter, prepares it on the ConditionalTokens Framework and requests a price from the OO.
    /// If a reward is provided, the caller must have approved the Adapter as spender and have enough rewardToken
    /// to pay for the price request.
    /// Prepares the condition using the Adapter as the oracle and a fixed outcome slot count = 2.
    /// @param ancillaryData - Data used to resolve a question
    /// @param rewardToken   - ERC20 token address used for payment of rewards and fees
    /// @param reward        - Reward offered to a successful proposer
    /// @param proposalBond  - Bond required to be posted by OO proposers/disputers. If 0, the default OO bond is used.
    function initialize(bytes memory ancillaryData, address rewardToken, uint256 reward, uint256 proposalBond)
        external
        returns (bytes32 questionID)
    {
        if (!collateralWhitelist.isOnWhitelist(rewardToken)) revert UnsupportedToken();

        bytes memory data = AncillaryDataLib._appendAncillaryData(msg.sender, ancillaryData);
        if (ancillaryData.length == 0 || data.length > maxAncillaryData) revert InvalidAncillaryData();

        questionID = keccak256(data);

        if (_isInitialized(questions[questionID])) revert Initialized();

        uint256 timestamp = block.timestamp;

        // Persist the question parameters in storage
        _saveQuestion(msg.sender, questionID, data, timestamp, rewardToken, reward, proposalBond);

        // Prepare the question on the CTF
        ctf.prepareCondition(address(this), questionID, 2);

        // Request a price for the question from the OO
        _requestPrice(msg.sender, timestamp, data, rewardToken, reward, proposalBond);

        emit QuestionInitialized(questionID, timestamp, msg.sender, data, rewardToken, reward, proposalBond);
    }

    /// @notice Checks whether a questionID is ready to be resolved
    /// @param questionID - The unique questionID
    function ready(bytes32 questionID) public view returns (bool) {
        return _ready(questions[questionID]);
    }

    /// @notice Resolves a question
    /// Pulls price information from the OO and resolves the underlying CTF market.
    /// Reverts if price is not available on the OO
    /// Resets the question if the price returned by the OO is the Ignore price
    /// @param questionID - The unique questionID of the question
    function resolve(bytes32 questionID) external {
        QuestionData storage questionData = questions[questionID];

        if (!_isInitialized(questionData)) revert NotInitialized();
        if (questionData.paused) revert Paused();
        if (questionData.resolved) revert Resolved();
        if (!_hasPrice(questionData)) revert NotReadyToResolve();

        // Resolve the underlying market
        return _resolve(questionID, questionData);
    }

    /// @notice Retrieves the expected payout array of the question
    /// @param questionID - The unique questionID of the question
    function getExpectedPayouts(bytes32 questionID) public view returns (uint256[] memory) {
        QuestionData storage questionData = questions[questionID];

        if (!_isInitialized(questionData)) revert NotInitialized();
        if (!_hasPrice(questionData)) revert PriceNotAvailable();

        // Fetches price from OO
        int256 price = optimisticOracle.getRequest(
            address(this), yesOrNoIdentifier, questionData.requestTimestamp, questionData.ancillaryData
        ).resolvedPrice;

        return _constructPayouts(price);
    }

    /// @notice Callback which is executed on dispute
    /// Resets the question and sends out a new price request to the OO
    /// @param ancillaryData    - Ancillary data of the request
    function priceDisputed(bytes32, uint256, bytes memory ancillaryData, uint256) external onlyOptimisticOracle {
        bytes32 questionID = keccak256(ancillaryData);
        QuestionData storage questionData = questions[questionID];

        if (questionData.reset) return;

        // If the question has not been reset previously, reset the question
        // Ensures that there are at most 2 OO Requests at a time for a question
        _reset(address(this), questionID, questionData);
    }

    /// @notice Checks if a question is initialized
    /// @param questionID - The unique questionID
    function isInitialized(bytes32 questionID) public view returns (bool) {
        return _isInitialized(questions[questionID]);
    }

    /// @notice Checks if a question has been flagged for emergency resolution
    /// @param questionID - The unique questionID
    function isFlagged(bytes32 questionID) public view returns (bool) {
        return _isFlagged(questions[questionID]);
    }

    /// @notice Gets the QuestionData for the given questionID
    /// @param questionID - The unique questionID
    function getQuestion(bytes32 questionID) external view returns (QuestionData memory) {
        return questions[questionID];
    }

    /*////////////////////////////////////////////////////////////////////
                            ADMIN ONLY FUNCTIONS 
    ///////////////////////////////////////////////////////////////////*/

    /// @notice Flags a market for emergency resolution
    /// @param questionID - The unique questionID of the question
    function flag(bytes32 questionID) external onlyAdmin {
        QuestionData storage questionData = questions[questionID];

        if (!_isInitialized(questionData)) revert NotInitialized();
        if (_isFlagged(questionData)) revert Flagged();

        questionData.emergencyResolutionTimestamp = block.timestamp + emergencySafetyPeriod;
        questionData.paused = true;

        emit QuestionFlagged(questionID);
    }

    /// @notice Allows an admin to reset a question, sending out a new price request to the OO.
    /// Failsafe to be used if the priceDisputed callback reverts during execution.
    /// @param questionID - The unique questionID
    function reset(bytes32 questionID) external onlyAdmin {
        QuestionData storage questionData = questions[questionID];
        if (!_isInitialized(questionData)) revert NotInitialized();
        if (questionData.resolved) revert Resolved();

        // Reset the question, paying for the price request from the caller
        _reset(msg.sender, questionID, questionData);
    }

    /// @notice Allows an admin to resolve a CTF market in an emergency
    /// @param questionID   - The unique questionID of the question
    /// @param payouts      - Array of position payouts for the referenced question
    function emergencyResolve(bytes32 questionID, uint256[] calldata payouts) external onlyAdmin {
        QuestionData storage questionData = questions[questionID];

        if (payouts.length != 2) revert InvalidPayouts();
        if (!_isInitialized(questionData)) revert NotInitialized();
        if (!_isFlagged(questionData)) revert NotFlagged();
        if (block.timestamp < questionData.emergencyResolutionTimestamp) revert SafetyPeriodNotPassed();

        questionData.resolved = true;
        ctf.reportPayouts(questionID, payouts);
        emit QuestionEmergencyResolved(questionID, payouts);
    }

    /// @notice Allows an admin to pause market resolution in an emergency
    /// @param questionID - The unique questionID of the question
    function pause(bytes32 questionID) external onlyAdmin {
        QuestionData storage questionData = questions[questionID];

        if (!_isInitialized(questionData)) revert NotInitialized();

        questionData.paused = true;
        emit QuestionPaused(questionID);
    }

    /// @notice Allows an admin to unpause market resolution in an emergency
    /// @param questionID - The unique questionID of the question
    function unpause(bytes32 questionID) external onlyAdmin {
        QuestionData storage questionData = questions[questionID];
        if (!_isInitialized(questionData)) revert NotInitialized();

        questionData.paused = false;
        emit QuestionUnpaused(questionID);
    }

    /*///////////////////////////////////////////////////////////////////
                            INTERNAL FUNCTIONS 
    //////////////////////////////////////////////////////////////////*/

    function _ready(QuestionData storage questionData) internal view returns (bool) {
        if (!_isInitialized(questionData)) return false;
        if (questionData.paused) return false;
        if (questionData.resolved) return false;
        return _hasPrice(questionData);
    }

    function _saveQuestion(
        address creator,
        bytes32 questionID,
        bytes memory ancillaryData,
        uint256 requestTimestamp,
        address rewardToken,
        uint256 reward,
        uint256 proposalBond
    ) internal {
        questions[questionID] = QuestionData({
            requestTimestamp: requestTimestamp,
            reward: reward,
            proposalBond: proposalBond,
            emergencyResolutionTimestamp: 0,
            resolved: false,
            paused: false,
            reset: false,
            rewardToken: rewardToken,
            creator: creator,
            ancillaryData: ancillaryData
        });
    }

    /// @notice Request a price from the Optimistic Oracle
    /// Transfers reward token from the requestor if non-zero reward is specified
    /// @param requestor        - Address of the requestor
    /// @param requestTimestamp - Timestamp used in the OO request
    /// @param ancillaryData    - Data used to resolve a question
    /// @param rewardToken      - Address of the reward token
    /// @param reward           - Reward amount, denominated in rewardToken
    /// @param bond             - Bond amount used, denominated in rewardToken
    function _requestPrice(
        address requestor,
        uint256 requestTimestamp,
        bytes memory ancillaryData,
        address rewardToken,
        uint256 reward,
        uint256 bond
    ) internal {
        if (reward > 0) {
            // If the requestor is not the Adapter, the requestor pays for the price request
            // If not, the Adapter pays for the price request
            if (requestor != address(this)) {
                TransferHelper._transferFromERC20(rewardToken, requestor, address(this), reward);
            }

            // Approve the OO as spender on the reward token from the Adapter
            if (IERC20(rewardToken).allowance(address(this), address(optimisticOracle)) < reward) {
                IERC20(rewardToken).approve(address(optimisticOracle), type(uint256).max);
            }
        }

        // Send a price request to the Optimistic oracle
        optimisticOracle.requestPrice(yesOrNoIdentifier, requestTimestamp, ancillaryData, IERC20(rewardToken), reward);

        // Ensure the price request is event based
        optimisticOracle.setEventBased(yesOrNoIdentifier, requestTimestamp, ancillaryData);

        // Ensure that the dispute callback flag is set
        optimisticOracle.setCallbacks(
            yesOrNoIdentifier,
            requestTimestamp,
            ancillaryData,
            false, // DO NOT set callback on priceProposed
            true, // DO set callback on priceDisputed
            false // DO NOT set callback on priceSettled
        );

        // Update the proposal bond on the Optimistic oracle if necessary
        if (bond > 0) optimisticOracle.setBond(yesOrNoIdentifier, requestTimestamp, ancillaryData, bond);
    }

    /// @notice Reset the question by updating the requestTimestamp field and sending a new price request to the OO
    /// @param questionID - The unique questionID
    function _reset(address requestor, bytes32 questionID, QuestionData storage questionData) internal {
        uint256 requestTimestamp = block.timestamp;
        // Update the question parameters in storage
        questionData.requestTimestamp = requestTimestamp;
        questionData.reset = true;

        // Send out a new price request with the new timestamp
        _requestPrice(
            requestor,
            requestTimestamp,
            questionData.ancillaryData,
            questionData.rewardToken,
            questionData.reward,
            questionData.proposalBond
        );

        emit QuestionReset(questionID);
    }

    /// @notice Resolves the underlying CTF market
    /// @param questionID   - The unique questionID of the question
    /// @param questionData - The question data parameters
    function _resolve(bytes32 questionID, QuestionData storage questionData) internal {
        // Get the price from the OO
        int256 price = optimisticOracle.settleAndGetPrice(
            yesOrNoIdentifier, questionData.requestTimestamp, questionData.ancillaryData
        );

        // If the OO returns the ignore price, reset the question
        if (price == _ignorePrice()) return _reset(address(this), questionID, questionData);

        // Construct the payout array for the question
        uint256[] memory payouts = _constructPayouts(price);

        // Set resolved flag
        questionData.resolved = true;

        // Resolve the underlying CTF market
        ctf.reportPayouts(questionID, payouts);

        emit QuestionResolved(questionID, price, payouts);
    }

    function _hasPrice(QuestionData storage questionData) internal view returns (bool) {
        return optimisticOracle.hasPrice(
            address(this), yesOrNoIdentifier, questionData.requestTimestamp, questionData.ancillaryData
        );
    }

    function _isFlagged(QuestionData storage questionData) internal view returns (bool) {
        return questionData.emergencyResolutionTimestamp > 0;
    }

    function _isInitialized(QuestionData storage questionData) internal view returns (bool) {
        return questionData.ancillaryData.length > 0;
    }

    /// @notice Construct the payout array given the price
    /// @param price - The price retrieved from the OO
    function _constructPayouts(int256 price) internal pure returns (uint256[] memory) {
        // Payouts: [YES, NO]
        uint256[] memory payouts = new uint256[](2);
        // Valid prices are 0, 0.5 and 1
        if (price != 0 && price != 0.5 ether && price != 1 ether) revert InvalidOOPrice();

        if (price == 0) {
            // NO: Report [Yes, No] as [0, 1]
            payouts[0] = 0;
            payouts[1] = 1;
        } else if (price == 0.5 ether) {
            // UNKNOWN: Report [Yes, No] as [1, 1], 50/50
            payouts[0] = 1;
            payouts[1] = 1;
        } else {
            // YES: Report [Yes, No] as [1, 0]
            payouts[0] = 1;
            payouts[1] = 0;
        }
        return payouts;
    }

    function _ignorePrice() internal pure returns (int256) {
        return type(int256).min;
    }
}

File 6 of 16 : IAddressWhitelist.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.15;

interface IAddressWhitelist {
    function addToWhitelist(address) external;

    function removeFromWhitelist(address) external;

    function isOnWhitelist(address) external view returns (bool);

    function getWhitelist() external view returns (address[] memory);
}

File 7 of 16 : IAuth.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

interface IAuthEE {
    error NotAdmin();

    /// @notice Emitted when a new admin is added
    event NewAdmin(address indexed admin, address indexed newAdminAddress);

    /// @notice Emitted when an admin is removed
    event RemovedAdmin(address indexed admin, address indexed removedAdmin);
}

interface IAuth is IAuthEE {
    function isAdmin(address) external view returns (bool);

    function addAdmin(address) external;

    function removeAdmin(address) external;

    function renounceAdmin() external;
}

File 8 of 16 : IConditionalTokens.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import { IERC20 } from "openzeppelin-contracts/token/ERC20/IERC20.sol";

interface IConditionalTokens {
    /// Mapping key is an condition ID. Value represents numerators of the payout vector associated with the condition. This array is initialized with a length equal to the outcome slot count. E.g. Condition with 3 outcomes [A, B, C] and two of those correct [0.5, 0.5, 0]. In Ethereum there are no decimal values, so here, 0.5 is represented by fractions like 1/2 == 0.5. That's why we need numerator and denominator values. Payout numerators are also used as a check of initialization. If the numerators array is empty (has length zero), the condition was not created/prepared. See getOutcomeSlotCount.
    function payoutNumerators(bytes32) external returns (uint256[] memory);

    /// Denominator is also used for checking if the condition has been resolved. If the denominator is non-zero, then the condition has been resolved.
    function payoutDenominator(bytes32) external returns (uint256);

    /// @dev This function prepares a condition by initializing a payout vector associated with the condition.
    /// @param oracle The account assigned to report the result for the prepared condition.
    /// @param questionId An identifier for the question to be answered by the oracle.
    /// @param outcomeSlotCount The number of outcome slots which should be used for this condition. Must not exceed 256.
    function prepareCondition(address oracle, bytes32 questionId, uint256 outcomeSlotCount) external;

    /// @dev Called by the oracle for reporting results of conditions. Will set the payout vector for the condition with the ID ``keccak256(abi.encodePacked(oracle, questionId, outcomeSlotCount))``, where oracle is the message sender, questionId is one of the parameters of this function, and outcomeSlotCount is the length of the payouts parameter, which contains the payoutNumerators for each outcome slot of the condition.
    /// @param questionId The question ID the oracle is answering for
    /// @param payouts The oracle's answer
    function reportPayouts(bytes32 questionId, uint256[] calldata payouts) external;

    /// @dev This function splits a position. If splitting from the collateral, this contract will attempt to transfer `amount` collateral from the message sender to itself. Otherwise, this contract will burn `amount` stake held by the message sender in the position being split worth of EIP 1155 tokens. Regardless, if successful, `amount` stake will be minted in the split target positions. If any of the transfers, mints, or burns fail, the transaction will revert. The transaction will also revert if the given partition is trivial, invalid, or refers to more slots than the condition is prepared with.
    /// @param collateralToken The address of the positions' backing collateral token.
    /// @param parentCollectionId The ID of the outcome collections common to the position being split and the split target positions. May be null, in which only the collateral is shared.
    /// @param conditionId The ID of the condition to split on.
    /// @param partition An array of disjoint index sets representing a nontrivial partition of the outcome slots of the given condition. E.g. A|B and C but not A|B and B|C (is not disjoint). Each element's a number which, together with the condition, represents the outcome collection. E.g. 0b110 is A|B, 0b010 is B, etc.
    /// @param amount The amount of collateral or stake to split.
    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;

    /// @dev Gets the outcome slot count of a condition.
    /// @param conditionId ID of the condition.
    /// @return Number of outcome slots associated with a condition, or zero if condition has not been prepared yet.
    function getOutcomeSlotCount(bytes32 conditionId) external view returns (uint256);

    /// @dev Constructs a condition ID from an oracle, a question ID, and the outcome slot count for the question.
    /// @param oracle The account assigned to report the result for the prepared condition.
    /// @param questionId An identifier for the question to be answered by the oracle.
    /// @param outcomeSlotCount The number of outcome slots which should be used for this condition. Must not exceed 256.
    function getConditionId(address oracle, bytes32 questionId, uint256 outcomeSlotCount)
        external
        pure
        returns (bytes32);

    /// @dev Constructs an outcome collection ID from a parent collection and an outcome collection.
    /// @param parentCollectionId Collection ID of the parent outcome collection, or bytes32(0) if there's no parent.
    /// @param conditionId Condition ID of the outcome collection to combine with the parent outcome collection.
    /// @param indexSet Index set of the outcome collection to combine with the parent outcome collection.
    function getCollectionId(bytes32 parentCollectionId, bytes32 conditionId, uint256 indexSet)
        external
        view
        returns (bytes32);

    /// @dev Constructs a position ID from a collateral token and an outcome collection. These IDs are used as the ERC-1155 ID for this contract.
    /// @param collateralToken Collateral token which backs the position.
    /// @param collectionId ID of the outcome collection associated with this position.
    function getPositionId(IERC20 collateralToken, bytes32 collectionId) external pure returns (uint256);
}

File 9 of 16 : IFinder.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.15;

/**
 * @title Provides addresses of the live contracts implementing certain interfaces.
 * @dev Examples are the Oracle or Store interfaces.
 */
interface IFinder {
    /**
     * @notice Updates the address of the contract that implements `interfaceName`.
     * @param interfaceName bytes32 encoding of the interface name that is either changed or registered.
     * @param implementationAddress address of the deployed contract that implements the interface.
     */
    function changeImplementationAddress(bytes32 interfaceName, address implementationAddress) external;

    /**
     * @notice Gets the address of the contract that implements the given `interfaceName`.
     * @param interfaceName queried interface.
     * @return implementationAddress address of the deployed contract that implements the interface.
     */
    function getImplementationAddress(bytes32 interfaceName) external view returns (address);
}

File 10 of 16 : IOptimisticOracleV2.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

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

struct RequestSettings {
    bool eventBased; // True if the request is set to be event-based.
    bool refundOnDispute; // True if the requester should be refunded their reward on dispute.
    bool callbackOnPriceProposed; // True if callbackOnPriceProposed callback is required.
    bool callbackOnPriceDisputed; // True if callbackOnPriceDisputed callback is required.
    bool callbackOnPriceSettled; // True if callbackOnPriceSettled callback is required.
    uint256 bond; // Bond that the proposer and disputer must pay on top of the final fee.
    uint256 customLiveness; // Custom liveness value set by the requester.
}

// Struct representing a price request.
struct Request {
    address proposer; // Address of the proposer.
    address disputer; // Address of the disputer.
    IERC20 currency; // ERC20 token used to pay rewards and fees.
    bool settled; // True if the request is settled.
    RequestSettings requestSettings; // Custom settings associated with a request.
    int256 proposedPrice; // Price that the proposer submitted.
    int256 resolvedPrice; // Price resolved once the request is settled.
    uint256 expirationTime; // Time at which the request auto-settles without a dispute.
    uint256 reward; // Amount of the currency to pay to the proposer on settlement.
    uint256 finalFee; // Final fee to pay to the Store upon request to the DVM.
}

/// @title Optimistic Oracle V2 Interface
interface IOptimisticOracleV2 {
    /// @notice Requests a new price.
    /// @param identifier price identifier being requested.
    /// @param timestamp timestamp of the price being requested.
    /// @param ancillaryData ancillary data representing additional args being passed with the price request.
    /// @param currency ERC20 token used for payment of rewards and fees. Must be approved for use with the DVM.
    /// @param reward reward offered to a successful proposer. Will be pulled from the caller. Note: this can be 0,
    ///               which could make sense if the contract requests and proposes the value in the same call or
    ///               provides its own reward system.
    /// @return totalBond default bond (final fee) + final fee that the proposer and disputer will be required to pay.
    /// This can be changed with a subsequent call to setBond().
    function requestPrice(
        bytes32 identifier,
        uint256 timestamp,
        bytes memory ancillaryData,
        IERC20 currency,
        uint256 reward
    ) external returns (uint256 totalBond);

    /**
     * @notice Proposes a price value for an existing price request.
     * @param requester sender of the initial price request.
     * @param identifier price identifier to identify the existing request.
     * @param timestamp timestamp to identify the existing request.
     * @param ancillaryData ancillary data of the price being requested.
     * @param proposedPrice price being proposed.
     * @return totalBond the amount that's pulled from the proposer's wallet as a bond. The bond will be returned to
     * the proposer once settled if the proposal is correct.
     */
    function proposePrice(
        address requester,
        bytes32 identifier,
        uint256 timestamp,
        bytes memory ancillaryData,
        int256 proposedPrice
    ) external returns (uint256 totalBond);

    /**
     * @notice Disputes a price value for an existing price request with an active proposal.
     * @param requester sender of the initial price request.
     * @param identifier price identifier to identify the existing request.
     * @param timestamp timestamp to identify the existing request.
     * @param ancillaryData ancillary data of the price being requested.
     * @return totalBond the amount that's pulled from the disputer's wallet as a bond. The bond will be returned to
     * the disputer once settled if the dispute was valid (the proposal was incorrect).
     */
    function disputePrice(address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData)
        external
        returns (uint256 totalBond);

    /// @notice Set the proposal bond associated with a price request.
    /// @param identifier price identifier to identify the existing request.
    /// @param timestamp timestamp to identify the existing request.
    /// @param ancillaryData ancillary data of the price being requested.
    /// @param bond custom bond amount to set.
    /// @return totalBond new bond + final fee that the proposer and disputer will be required to pay. This can be
    /// changed again with a subsequent call to setBond().
    function setBond(bytes32 identifier, uint256 timestamp, bytes memory ancillaryData, uint256 bond)
        external
        returns (uint256 totalBond);

    /// @notice Sets the request to be an "event-based" request.
    /// @dev Calling this method has a few impacts on the request:
    ///
    /// 1. The timestamp at which the request is evaluated is the time of the proposal, not the timestamp associated
    ///    with the request.
    ///
    /// 2. The proposer cannot propose the "too early" value (TOO_EARLY_RESPONSE). This is to ensure that a proposer who
    ///    prematurely proposes a response loses their bond.
    ///
    /// 3. RefundoOnDispute is automatically set, meaning disputes trigger the reward to be automatically refunded to
    ///    the requesting contract.
    ///
    /// @param identifier price identifier to identify the existing request.
    /// @param timestamp timestamp to identify the existing request.
    /// @param ancillaryData ancillary data of the price being requested.
    function setEventBased(bytes32 identifier, uint256 timestamp, bytes memory ancillaryData) external;

    /// @notice Sets which callbacks should be enabled for the request.
    /// @param identifier price identifier to identify the existing request.
    /// @param timestamp timestamp to identify the existing request.
    /// @param ancillaryData ancillary data of the price being requested.
    /// @param callbackOnPriceProposed whether to enable the callback onPriceProposed.
    /// @param callbackOnPriceDisputed whether to enable the callback onPriceDisputed.
    /// @param callbackOnPriceSettled whether to enable the callback onPriceSettled.
    function setCallbacks(
        bytes32 identifier,
        uint256 timestamp,
        bytes memory ancillaryData,
        bool callbackOnPriceProposed,
        bool callbackOnPriceDisputed,
        bool callbackOnPriceSettled
    ) external;

    /**
     * @notice Attempts to settle an outstanding price request. Will revert if it isn't settleable.
     * @param requester sender of the initial price request.
     * @param identifier price identifier to identify the existing request.
     * @param timestamp timestamp to identify the existing request.
     * @param ancillaryData ancillary data of the price being requested.
     * @return payout the amount that the "winner" (proposer or disputer) receives on settlement. This amount includes
     * the returned bonds as well as additional rewards.
     */
    function settle(address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData)
        external
        returns (uint256 payout);

    /// @notice Retrieves a price that was previously requested by a caller. Reverts if the request is not settled
    /// or settleable. Note: this method is not view so that this call may actually settle the price request if it
    /// hasn't been settled.
    /// @param identifier price identifier to identify the existing request.
    /// @param timestamp timestamp to identify the existing request.
    /// @param ancillaryData ancillary data of the price being requested.
    /// @return resolved price.
    ////
    function settleAndGetPrice(bytes32 identifier, uint256 timestamp, bytes memory ancillaryData)
        external
        returns (int256);

    /// @notice Gets the current data structure containing all information about a price request.
    /// @param requester sender of the initial price request.
    /// @param identifier price identifier to identify the existing request.
    /// @param timestamp timestamp to identify the existing request.
    /// @param ancillaryData ancillary data of the price being requested.
    /// @return the Request data structure.
    ////
    function getRequest(address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData)
        external
        view
        returns (Request memory);

    /// @notice Checks if a given request has resolved or been settled (i.e the optimistic oracle has a price).
    /// @param requester sender of the initial price request.
    /// @param identifier price identifier to identify the existing request.
    /// @param timestamp timestamp to identify the existing request.
    /// @param ancillaryData ancillary data of the price being requested.
    /// @return true if price has resolved or settled, false otherwise.
    function hasPrice(address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData)
        external
        view
        returns (bool);
}

File 11 of 16 : IOptimisticRequester.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

/// @title Optimistic Requester
interface IOptimisticRequester {
    /// @notice Callback for disputes.
    /// @param identifier price identifier being requested.
    /// @param timestamp timestamp of the price being requested.
    /// @param ancillaryData ancillary data of the price being requested.
    /// @param refund refund received in the case that refundOnDispute was enabled.
    function priceDisputed(bytes32 identifier, uint256 timestamp, bytes memory ancillaryData, uint256 refund)
        external;
}

File 12 of 16 : IUmaCtfAdapter.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

struct QuestionData {
    /// @notice Request timestamp, set when a request is made to the Optimistic Oracle
    /// @dev Used to identify the request and NOT used by the DVM to determine validity
    uint256 requestTimestamp;
    /// @notice Reward offered to a successful proposer
    uint256 reward;
    /// @notice Additional bond required by Optimistic oracle proposers/disputers
    uint256 proposalBond;
    /// @notice Emergency resolution timestamp, set when a market is flagged for emergency resolution
    uint256 emergencyResolutionTimestamp;
    /// @notice Flag marking whether a question is resolved
    bool resolved;
    /// @notice Flag marking whether a question is paused
    bool paused;
    /// @notice Flag marking whether a question has been reset. A question can only be reset once
    bool reset;
    /// @notice ERC20 token address used for payment of rewards, proposal bonds and fees
    address rewardToken;
    /// @notice The address of the question creator
    address creator;
    /// @notice Data used to resolve a condition
    bytes ancillaryData;
}

interface IUmaCtfAdapterEE {
    error NotInitialized();
    error NotFlagged();
    error NotReadyToResolve();
    error Resolved();
    error Initialized();
    error UnsupportedToken();
    error Flagged();
    error Paused();
    error SafetyPeriodNotPassed();
    error PriceNotAvailable();
    error InvalidAncillaryData();
    error NotOptimisticOracle();
    error InvalidOOPrice();
    error InvalidPayouts();

    /// @notice Emitted when a questionID is initialized
    event QuestionInitialized(
        bytes32 indexed questionID,
        uint256 indexed requestTimestamp,
        address indexed creator,
        bytes ancillaryData,
        address rewardToken,
        uint256 reward,
        uint256 proposalBond
    );

    /// @notice Emitted when a question is paused by an authorized user
    event QuestionPaused(bytes32 indexed questionID);

    /// @notice Emitted when a question is unpaused by an authorized user
    event QuestionUnpaused(bytes32 indexed questionID);

    /// @notice Emitted when a question is flagged by an admin for emergency resolution
    event QuestionFlagged(bytes32 indexed questionID);

    /// @notice Emitted when a question is reset
    event QuestionReset(bytes32 indexed questionID);

    /// @notice Emitted when a question is resolved
    event QuestionResolved(bytes32 indexed questionID, int256 indexed settledPrice, uint256[] payouts);

    /// @notice Emitted when a question is emergency resolved
    event QuestionEmergencyResolved(bytes32 indexed questionID, uint256[] payouts);
}

interface IUmaCtfAdapter is IUmaCtfAdapterEE {
    function initialize(bytes memory, address, uint256, uint256) external returns (bytes32);

    function resolve(bytes32) external;

    function flag(bytes32) external;

    function reset(bytes32) external;

    function pause(bytes32) external;

    function unpause(bytes32) external;

    function getQuestion(bytes32) external returns (QuestionData memory);

    function ready(bytes32) external view returns (bool);
}

File 13 of 16 : AncillaryDataLib.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

library AncillaryDataLib {
    string private constant initializerPrefix = ",initializer:";

    /// @notice Appends the initializer address to the ancillaryData
    /// @param initializer      - The initializer address
    /// @param ancillaryData    - The ancillary data
    function _appendAncillaryData(address initializer, bytes memory ancillaryData)
        internal
        pure
        returns (bytes memory)
    {
        return abi.encodePacked(ancillaryData, initializerPrefix, _toUtf8BytesAddress(initializer));
    }

    /// @notice Returns a UTF8-encoded address
    /// Source: UMA Protocol's AncillaryDataLib
    /// https://github.com/UMAprotocol/protocol/blob/9967e70e7db3f262fde0dc9d89ea04d4cd11ed97/packages/core/contracts/common/implementation/AncillaryData.sol
    /// Will return address in all lower case characters and without the leading 0x.
    /// @param addr - The address to encode.
    function _toUtf8BytesAddress(address addr) internal pure returns (bytes memory) {
        return abi.encodePacked(
            _toUtf8Bytes32Bottom(bytes32(bytes20(addr)) >> 128), bytes8(_toUtf8Bytes32Bottom(bytes20(addr)))
        );
    }

    /// @notice Converts the bottom half of a bytes32 input to hex in a highly gas-optimized way.
    /// Source: the brilliant implementation at https://gitter.im/ethereum/solidity?at=5840d23416207f7b0ed08c9b.
    function _toUtf8Bytes32Bottom(bytes32 bytesIn) private pure returns (bytes32) {
        unchecked {
            uint256 x = uint256(bytesIn);

            // Nibble interleave
            x = x & 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff;
            x = (x | (x * 2 ** 64)) & 0x0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff;
            x = (x | (x * 2 ** 32)) & 0x00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff;
            x = (x | (x * 2 ** 16)) & 0x0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff;
            x = (x | (x * 2 ** 8)) & 0x00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff;
            x = (x | (x * 2 ** 4)) & 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f;

            // Hex encode
            uint256 h = (x & 0x0808080808080808080808080808080808080808080808080808080808080808) / 8;
            uint256 i = (x & 0x0404040404040404040404040404040404040404040404040404040404040404) / 4;
            uint256 j = (x & 0x0202020202020202020202020202020202020202020202020202020202020202) / 2;
            x = x + (h & (i | j)) * 0x27 + 0x3030303030303030303030303030303030303030303030303030303030303030;

            // Return the result.
            return bytes32(x);
        }
    }
}

File 14 of 16 : TransferHelper.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import { SafeTransferLib, ERC20 } from "solmate/utils/SafeTransferLib.sol";

/// @title TransferHelper
/// @notice Helper library to transfer tokens
library TransferHelper {
    /// @notice Transfers tokens from the targeted address to the given destination
    /// @param token    - The contract address of the token to be transferred
    /// @param from     - The originating address from which the tokens will be transferred
    /// @param to       - The destination address of the transfer
    /// @param amount   - The amount to be transferred
    function _transferFromERC20(address token, address from, address to, uint256 amount) internal {
        SafeTransferLib.safeTransferFrom(ERC20(token), from, to, amount);
    }
}

File 15 of 16 : Auth.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import { IAuth } from "../interfaces/IAuth.sol";

/// @title Auth
/// @notice Provides access control modifiers
abstract contract Auth is IAuth {
    /// @notice Auth
    mapping(address => uint256) public admins;

    modifier onlyAdmin() {
        if (admins[msg.sender] != 1) revert NotAdmin();
        _;
    }

    constructor() {
        admins[msg.sender] = 1;
    }

    /// @notice Adds an Admin
    /// @param admin - The address of the admin
    function addAdmin(address admin) external onlyAdmin {
        admins[admin] = 1;
        emit NewAdmin(msg.sender, admin);
    }

    /// @notice Removes an admin
    /// @param admin - The address of the admin to be removed
    function removeAdmin(address admin) external onlyAdmin {
        admins[admin] = 0;
        emit RemovedAdmin(msg.sender, admin);
    }

    /// @notice Renounces Admin privileges from the caller
    function renounceAdmin() external onlyAdmin {
        admins[msg.sender] = 0;
        emit RemovedAdmin(msg.sender, msg.sender);
    }

    /// @notice Checks if an address is an admin
    /// @param addr - The address to be checked
    function isAdmin(address addr) external view returns (bool) {
        return admins[addr] == 1;
    }
}

File 16 of 16 : BulletinBoard.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

/// @title Bulletin Board
/// @notice A registry containing ancillary data updates
abstract contract BulletinBoard {
    struct AncillaryDataUpdate {
        uint256 timestamp;
        bytes update;
    }

    /// @notice Mapping to an array of Ancillary data updates for questions
    mapping(bytes32 => AncillaryDataUpdate[]) public updates;

    /// @notice Emitted when an ancillary data update is posted
    event AncillaryDataUpdated(bytes32 indexed questionID, address indexed owner, bytes update);

    /// @notice Post an update for the question
    /// Anyone can post an update for any questionID, but users should only consider updates posted by the question creator
    /// @param questionID   - The unique questionID
    /// @param update       - The update for the question
    function postUpdate(bytes32 questionID, bytes memory update) external {
        bytes32 id = keccak256(abi.encode(questionID, msg.sender));
        updates[id].push(AncillaryDataUpdate({timestamp: block.timestamp, update: update}));
    }

    /// @notice Gets all updates for a questionID and owner
    /// @param questionID   - The unique questionID
    /// @param owner        - The address of the question initializer
    function getUpdates(bytes32 questionID, address owner) public view returns (AncillaryDataUpdate[] memory) {
        return updates[keccak256(abi.encode(questionID, owner))];
    }

    /// @notice Gets the latest update for a questionID and owner
    /// @param questionID   - The unique questionID
    /// @param owner        - The address of the question initializer
    function getLatestUpdate(bytes32 questionID, address owner) external view returns (AncillaryDataUpdate memory) {
        AncillaryDataUpdate[] memory currentUpdates = getUpdates(questionID, owner);
        if (currentUpdates.length == 0) return AncillaryDataUpdate({timestamp: 0, update: ""});
        return currentUpdates[currentUpdates.length - 1];
    }
}

Settings
{
  "remappings": [
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/",
    "openzeppelin/=lib/openzeppelin-contracts/contracts/",
    "solmate/=lib/solmate/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 1000000
  },
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_ctf","type":"address"},{"internalType":"address","name":"_finder","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Flagged","type":"error"},{"inputs":[],"name":"Initialized","type":"error"},{"inputs":[],"name":"InvalidAncillaryData","type":"error"},{"inputs":[],"name":"InvalidOOPrice","type":"error"},{"inputs":[],"name":"InvalidPayouts","type":"error"},{"inputs":[],"name":"NotAdmin","type":"error"},{"inputs":[],"name":"NotFlagged","type":"error"},{"inputs":[],"name":"NotInitialized","type":"error"},{"inputs":[],"name":"NotOptimisticOracle","type":"error"},{"inputs":[],"name":"NotReadyToResolve","type":"error"},{"inputs":[],"name":"Paused","type":"error"},{"inputs":[],"name":"PriceNotAvailable","type":"error"},{"inputs":[],"name":"Resolved","type":"error"},{"inputs":[],"name":"SafetyPeriodNotPassed","type":"error"},{"inputs":[],"name":"UnsupportedToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"questionID","type":"bytes32"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"bytes","name":"update","type":"bytes"}],"name":"AncillaryDataUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":true,"internalType":"address","name":"newAdminAddress","type":"address"}],"name":"NewAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"questionID","type":"bytes32"},{"indexed":false,"internalType":"uint256[]","name":"payouts","type":"uint256[]"}],"name":"QuestionEmergencyResolved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"questionID","type":"bytes32"}],"name":"QuestionFlagged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"questionID","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"requestTimestamp","type":"uint256"},{"indexed":true,"internalType":"address","name":"creator","type":"address"},{"indexed":false,"internalType":"bytes","name":"ancillaryData","type":"bytes"},{"indexed":false,"internalType":"address","name":"rewardToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"proposalBond","type":"uint256"}],"name":"QuestionInitialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"questionID","type":"bytes32"}],"name":"QuestionPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"questionID","type":"bytes32"}],"name":"QuestionReset","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"questionID","type":"bytes32"},{"indexed":true,"internalType":"int256","name":"settledPrice","type":"int256"},{"indexed":false,"internalType":"uint256[]","name":"payouts","type":"uint256[]"}],"name":"QuestionResolved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"questionID","type":"bytes32"}],"name":"QuestionUnpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":true,"internalType":"address","name":"removedAdmin","type":"address"}],"name":"RemovedAdmin","type":"event"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"addAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"admins","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collateralWhitelist","outputs":[{"internalType":"contract IAddressWhitelist","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ctf","outputs":[{"internalType":"contract IConditionalTokens","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"questionID","type":"bytes32"},{"internalType":"uint256[]","name":"payouts","type":"uint256[]"}],"name":"emergencyResolve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencySafetyPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"questionID","type":"bytes32"}],"name":"flag","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"questionID","type":"bytes32"}],"name":"getExpectedPayouts","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"questionID","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"}],"name":"getLatestUpdate","outputs":[{"components":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bytes","name":"update","type":"bytes"}],"internalType":"struct BulletinBoard.AncillaryDataUpdate","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"questionID","type":"bytes32"}],"name":"getQuestion","outputs":[{"components":[{"internalType":"uint256","name":"requestTimestamp","type":"uint256"},{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"proposalBond","type":"uint256"},{"internalType":"uint256","name":"emergencyResolutionTimestamp","type":"uint256"},{"internalType":"bool","name":"resolved","type":"bool"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"reset","type":"bool"},{"internalType":"address","name":"rewardToken","type":"address"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"bytes","name":"ancillaryData","type":"bytes"}],"internalType":"struct QuestionData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"questionID","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"}],"name":"getUpdates","outputs":[{"components":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bytes","name":"update","type":"bytes"}],"internalType":"struct BulletinBoard.AncillaryDataUpdate[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"ancillaryData","type":"bytes"},{"internalType":"address","name":"rewardToken","type":"address"},{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"proposalBond","type":"uint256"}],"name":"initialize","outputs":[{"internalType":"bytes32","name":"questionID","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"questionID","type":"bytes32"}],"name":"isFlagged","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"questionID","type":"bytes32"}],"name":"isInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxAncillaryData","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"optimisticOracle","outputs":[{"internalType":"contract IOptimisticOracleV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"questionID","type":"bytes32"}],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"questionID","type":"bytes32"},{"internalType":"bytes","name":"update","type":"bytes"}],"name":"postUpdate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"ancillaryData","type":"bytes"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"priceDisputed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"questions","outputs":[{"internalType":"uint256","name":"requestTimestamp","type":"uint256"},{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"proposalBond","type":"uint256"},{"internalType":"uint256","name":"emergencyResolutionTimestamp","type":"uint256"},{"internalType":"bool","name":"resolved","type":"bool"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"reset","type":"bool"},{"internalType":"address","name":"rewardToken","type":"address"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"bytes","name":"ancillaryData","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"questionID","type":"bytes32"}],"name":"ready","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"removeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"questionID","type":"bytes32"}],"name":"reset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"questionID","type":"bytes32"}],"name":"resolve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"questionID","type":"bytes32"}],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"updates","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bytes","name":"update","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"yesOrNoIdentifier","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"}]

60e06040523480156200001157600080fd5b50604051620039c4380380620039c483398101604081905262000034916200019a565b33600090815260208190526040908190206001908190556002556001600160a01b0383811660805290516302abf57960e61b81527127b83a34b6b4b9ba34b1a7b930b1b632ab1960711b6004820152829182169063aafd5e4090602401602060405180830381865afa158015620000af573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000d59190620001d2565b6001600160a01b0390811660a0526040516302abf57960e61b81527f436f6c6c61746572616c57686974656c6973740000000000000000000000000060048201529082169063aafd5e4090602401602060405180830381865afa15801562000141573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001679190620001d2565b6001600160a01b031660c05250620001f7915050565b80516001600160a01b03811681146200019557600080fd5b919050565b60008060408385031215620001ae57600080fd5b620001b9836200017d565b9150620001c9602084016200017d565b90509250929050565b600060208284031215620001e557600080fd5b620001f0826200017d565b9392505050565b60805160a05160c05161373b620002896000396000818161048101526116ff015260008181610214015281816105b9015281816108b001528181611b2301528181611d44015281816121df0152818161229801528181612372015281816124500152818161251601526125f101526000818161026501528181611382015281816118a10152611e94015261373b6000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806378165a4811610104578063c66d4c6c116100a2578063ed56531a11610071578063ed56531a146104b6578063f7b637bb146104c9578063f8063207146104dc578063fcac49a2146104ef57600080fd5b8063c66d4c6c1461044b578063dddb468014610455578063e4ee614a1461047c578063ed3c7d40146104a357600080fd5b806395addb90116100de57806395addb90146103dc5780639ce7c0e014610405578063bf2dde3814610418578063c0cab0a21461042b57600080fd5b806378165a48146103a057806389ab0871146103b35780638bad0c0a146103d457600080fd5b806334e5e28e1161017157806358c039cd1161014b57806358c039cd146103515780635c23bdf5146103715780636b5acc6314610384578063704802751461038d57600080fd5b806334e5e28e146102e3578063429b62e514610303578063555c56fc1461033157600080fd5b806322302922116101ad578063223029221461020f57806322a9339f1461026057806324d7806c146102875780632f4dae9f146102d057600080fd5b8063072d1259146101d45780630d8f2372146101e95780631785f53c146101fc575b600080fd5b6101e76101e2366004612af1565b610502565b005b6101e76101f7366004612b38565b6105a1565b6101e761020a366004612bb5565b610655565b6102367f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6102367f000000000000000000000000000000000000000000000000000000000000000081565b6102c0610295366004612bb5565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205460011490565b6040519015158152602001610257565b6101e76102de366004612bd9565b6106f0565b6102f66102f1366004612bd9565b6107df565b6040516102579190612c2d565b610323610311366004612bb5565b60006020819052908152604090205481565b604051908152602001610257565b61034461033f366004612c40565b610965565b6040516102579190612d05565b61036461035f366004612bd9565b610abc565b6040516102579190612d85565b6101e761037f366004612bd9565b610c85565b610323611fcb81565b6101e761039b366004612bb5565b610da2565b6101e76103ae366004612bd9565b610e3e565b6103c66103c1366004612e4c565b610f7f565b604051610257929190612e6e565b6101e7611048565b6103ef6103ea366004612bd9565b6110cc565b6040516102579a99989796959493929190612e87565b6101e7610413366004612f04565b6111ce565b6102c0610426366004612bd9565b61142b565b61043e610439366004612c40565b611444565b6040516102579190612f83565b6103236202a30081565b6103237f5945535f4f525f4e4f5f5155455259000000000000000000000000000000000081565b6102367f000000000000000000000000000000000000000000000000000000000000000081565b6101e76104b1366004612bd9565b6114cd565b6101e76104c4366004612bd9565b6115ad565b6102c06104d7366004612bd9565b6116a0565b6103236104ea366004612f96565b6116b7565b6102c06104fd366004612bd9565b611980565b60408051602081018490523391810191909152600090606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206000818152600180845284822086860190955242865285840188815285548083018755958352939091208551600290950201938455915190945090820190610599908261308e565b505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610610576040517f05cef85500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8151602080840191909120600081815260039092526040909120600481015462010000900460ff161561064457505061064f565b610599308383611997565b50505050565b3360009081526020819052604090205460011461069e576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152602081905260408082208290555133917f787a2e12f4a55b658b8f573c32432ee11a5e8b51677d1e1e937aaf6a0bb5776e91a350565b33600090815260208190526040902054600114610739576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260036020526040902061075081611ac5565b610786576040517f87138d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405182907f92d28918c5574e7fc0f4f948c39502682c81cfb4089b07b83f95b3264e5e5e0690600090a25050565b60008181526003602052604090206060906107f981611ac5565b61082f576040517f87138d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61083881611ae1565b61086e576040517f579a480100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80546040517fa9904f9b00000000000000000000000000000000000000000000000000000000815260009173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163a9904f9b9161090c9130917f5945535f4f525f4e4f5f51554552590000000000000000000000000000000000916006890190600401613243565b61020060405180830381865afa15801561092a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094e919061334d565b60c00151905061095d81611bc0565b949350505050565b606060016000848460405160200161099d92919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b604051602081830303815290604052805190602001208152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610aaf578382906000526020600020906002020160405180604001604052908160008201548152602001600182018054610a1e90612ff5565b80601f0160208091040260200160405190810160405280929190818152602001828054610a4a90612ff5565b8015610a975780601f10610a6c57610100808354040283529160200191610a97565b820191906000526020600020905b815481529060010190602001808311610a7a57829003601f168201915b505050505081525050815260200190600101906109e1565b5050505090505b92915050565b610b4460405180610140016040528060008152602001600081526020016000815260200160008152602001600015158152602001600015158152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b60008281526003602081815260409283902083516101408101855281548152600182015492810192909252600281015493820193909352908201546060820152600482015460ff808216151560808401526101008083048216151560a0850152620100008304909116151560c0840152630100000090910473ffffffffffffffffffffffffffffffffffffffff90811660e08401526005840154169082015260068201805491929161012084019190610bfc90612ff5565b80601f0160208091040260200160405190810160405280929190818152602001828054610c2890612ff5565b8015610c755780601f10610c4a57610100808354040283529160200191610c75565b820191906000526020600020905b815481529060010190602001808311610c5857829003601f168201915b5050505050815250509050919050565b6000818152600360205260409020610c9c81611ac5565b610cd2576040517f87138d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004810154610100900460ff1615610d16576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600481015460ff1615610d55576040517fea00f1a000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d5e81611ae1565b610d94576040517fb488fe4b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d9e8282611d02565b5050565b33600090815260208190526040902054600114610deb576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260208190526040808220600190555133917ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc91a350565b33600090815260208190526040902054600114610e87576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600360205260409020610e9e81611ac5565b610ed4576040517f87138d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600381015415610f10576040517fe8e3a25900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f1d6202a30042613427565b60038201556004810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010017905560405182907f2435a0347185933b12027c6f394a5fd9c03646dba233e956f50658719dfc0b3590600090a25050565b60016020528160005260406000208181548110610f9b57600080fd5b906000526020600020906002020160009150915050806000015490806001018054610fc590612ff5565b80601f0160208091040260200160405190810160405280929190818152602001828054610ff190612ff5565b801561103e5780601f106110135761010080835404028352916020019161103e565b820191906000526020600020905b81548152906001019060200180831161102157829003601f168201915b5050505050905082565b33600090815260208190526040902054600114611091576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000818152602081905260408082208290555182917f787a2e12f4a55b658b8f573c32432ee11a5e8b51677d1e1e937aaf6a0bb5776e91a3565b60036020819052600091825260409091208054600182015460028301549383015460048401546005850154600686018054959794969495939460ff8085169561010086048216956201000081049092169473ffffffffffffffffffffffffffffffffffffffff6301000000909304831694921692919061114b90612ff5565b80601f016020809104026020016040519081016040528092919081815260200182805461117790612ff5565b80156111c45780601f10611199576101008083540402835291602001916111c4565b820191906000526020600020905b8154815290600101906020018083116111a757829003601f168201915b505050505090508a565b33600090815260208190526040902054600114611217576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526003602052604090206002821461125f576040517f663493a000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61126881611ac5565b61129e576040517f87138d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60038101546112d9576040517fbb825d1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060030154421015611317576040517f2a2c257c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040517fc49298ac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163c49298ac916113b9918891889188910161348e565b600060405180830381600087803b1580156113d357600080fd5b505af11580156113e7573d6000803e3d6000fd5b50505050837f6edb5841a476c9c29c34a652d1a44f785fe71a6157a3da9a6a6a589a1bd2945a848460405161141d9291906134b1565b60405180910390a250505050565b6000818152600360208190526040822001541515610ab6565b60408051808201909152600081526060602082015260006114658484610965565b9050805160000361149d5760405180604001604052806000815260200160405180602001604052806000815250815250915050610ab6565b80600182516114ac91906134c5565b815181106114bc576114bc6134dc565b602002602001015191505092915050565b33600090815260208190526040902054600114611516576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260036020526040902061152d81611ac5565b611563576040517f87138d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600481015460ff16156115a2576040517fea00f1a000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d9e338383611997565b336000908152602081905260409020546001146115f6576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260036020526040902061160d81611ac5565b611643576040517f87138d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010017905560405182907f6ded7250a9d5f79aef5add44600fc20a74a0af6f4730baa4fc4ab87bf484b81290600090a25050565b6000818152600360205260408120610ab690611ac5565b6040517f3a3ab67200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526000917f000000000000000000000000000000000000000000000000000000000000000090911690633a3ab67290602401602060405180830381865afa158015611748573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176c919061350b565b6117a2576040517f6a17288200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006117ae3387611f3a565b90508551600014806117c25750611fcb8151115b156117f9576040517f9702d51200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8080519060200120915061181e60036000848152602001908152602001600020611ac5565b15611855576040517f5daa87a000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b42611865338484848a8a8a611fa5565b6040517fd96ee75400000000000000000000000000000000000000000000000000000000815230600482015260248101849052600260448201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063d96ee75490606401600060405180830381600087803b1580156118fa57600080fd5b505af115801561190e573d6000803e3d6000fd5b5050505061192033828489898961216d565b3373ffffffffffffffffffffffffffffffffffffffff1681847feee0897acd6893adcaf2ba5158191b3601098ab6bece35c5d57874340b64c5b7858a8a8a60405161196e9493929190613526565b60405180910390a45050949350505050565b6000818152600360205260408120610ab690612698565b428082556004820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff1662010000179055600682018054611a949186918491906119e290612ff5565b80601f0160208091040260200160405190810160405280929190818152602001828054611a0e90612ff5565b8015611a5b5780601f10611a3057610100808354040283529160200191611a5b565b820191906000526020600020905b815481529060010190602001808311611a3e57829003601f168201915b50505050508560040160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff168660010154876002015461216d565b60405183907f7981b5832932948db4e32a4a16a0f44b2ce7ff088574afb9364b313f70f82e8f90600090a250505050565b600080826006018054611ad790612ff5565b9050119050919050565b80546040517fbc58ccaa00000000000000000000000000000000000000000000000000000000815260009173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163bc58ccaa91611b7f9130917f5945535f4f525f4e4f5f51554552590000000000000000000000000000000000916006890190600401613243565b602060405180830381865afa158015611b9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab6919061350b565b604080516002808252606080830184529260009291906020830190803683370190505090508215801590611bfc5750826706f05b59d3b2000014155b8015611c10575082670de0b6b3a764000014155b15611c47576040517f86c9649e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611c9657600081600081518110611c6457611c646134dc565b602002602001018181525050600181600181518110611c8557611c856134dc565b602002602001018181525050610ab6565b826706f05b59d3b2000003611cba57600181600081518110611c6457611c646134dc565b600181600081518110611ccf57611ccf6134dc565b602002602001018181525050600081600181518110611cf057611cf06134dc565b60200260200101818152505092915050565b80546040517f53b5923900000000000000000000000000000000000000000000000000000000815260009173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016916353b5923991611d9f917f5945535f4f525f4e4f5f515545525900000000000000000000000000000000009190600688019060040161356b565b6020604051808303816000875af1158015611dbe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de2919061358a565b90507f80000000000000000000000000000000000000000000000000000000000000008103611e1b57611e16308484611997565b505050565b6000611e2682611bc0565b600480850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040517fc49298ac00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163c49298ac91611ec99188918691016135a3565b600060405180830381600087803b158015611ee357600080fd5b505af1158015611ef7573d6000803e3d6000fd5b5050505081847f566c3fbdd12dd86bb341787f6d531f79fd7ad4ce7e3ae2d15ac0ca1b601af9df83604051611f2c9190612c2d565b60405180910390a350505050565b6060816040518060400160405280600d81526020017f2c696e697469616c697a65723a00000000000000000000000000000000000000815250611f7c856126e7565b604051602001611f8e939291906135bc565b604051602081830303815290604052905092915050565b604051806101400160405280858152602001838152602001828152602001600081526020016000151581526020016000151581526020016000151581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff16815260200186815250600360008881526020019081526020016000206000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a81548160ff02191690831515021790555060a08201518160040160016101000a81548160ff02191690831515021790555060c08201518160040160026101000a81548160ff02191690831515021790555060e08201518160040160036101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101008201518160050160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610120820151816006019081612161919061308e565b50505050505050505050565b81156123355773ffffffffffffffffffffffffffffffffffffffff8616301461219c5761219c83873085612775565b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602483015283919085169063dd62ed3e90604401602060405180830381865afa158015612231573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612255919061358a565b1015612335576040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602483015284169063095ea7b3906044016020604051808303816000875af115801561230f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612333919061350b565b505b6040517f11df92f100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906311df92f1906123cf907f5945535f4f525f4e4f5f515545525900000000000000000000000000000000009089908990899089906004016135ff565b6020604051808303816000875af11580156123ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612412919061358a565b506040517f120698af00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063120698af906124a9907f5945535f4f525f4e4f5f515545525900000000000000000000000000000000009089908990600401613648565b600060405180830381600087803b1580156124c357600080fd5b505af11580156124d7573d6000803e3d6000fd5b50506040517ff327b07500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016925063f327b0759150612579907f5945535f4f525f4e4f5f5155455259000000000000000000000000000000000090899089906000906001908290600401613667565b600060405180830381600087803b15801561259357600080fd5b505af11580156125a7573d6000803e3d6000fd5b505050506000811115610599576040517fad5a755a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063ad5a755a9061264c907f5945535f4f525f4e4f5f51554552590000000000000000000000000000000000908990899087906004016136a6565b6020604051808303816000875af115801561266b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268f919061358a565b50505050505050565b60006126a382611ac5565b6126af57506000919050565b6004820154610100900460ff16156126c957506000919050565b600482015460ff16156126de57506000919050565b610ab682611ae1565b60606127086fffffffffffffffffffffffffffffffff602084901c16612781565b6127238360601b6bffffffffffffffffffffffff1916612781565b60405160200161275f9291909182527fffffffffffffffff00000000000000000000000000000000000000000000000016602082015260280190565b6040516020818303038152906040529050919050565b61064f84848484612923565b6000808260001c9050806fffffffffffffffffffffffffffffffff169050806801000000000000000002811777ffffffffffffffff0000000000000000ffffffffffffffff169050806401000000000281177bffffffff00000000ffffffff00000000ffffffff00000000ffffffff16905080620100000281177dffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff169050806101000281177eff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff1690508060100281177f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f16905060006008827f080808080808080808080808080808080808080808080808080808080808080816816128a5576128a56136d6565b0460047f040404040404040404040404040404040404040404040404040404040404040484160460027f020202020202020202020202020202020202020202020202020202020202020285160417166027029091017f3030303030303030303030303030303030303030303030303030303030303030019392505050565b60006040517f23b872dd0000000000000000000000000000000000000000000000000000000081528460048201528360248201528260448201526020600060648360008a5af13d15601f3d11600160005114161716915050806129e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c4544000000000000000000000000604482015260640160405180910390fd5b5050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715612a4057612a406129ed565b60405290565b600082601f830112612a5757600080fd5b813567ffffffffffffffff80821115612a7257612a726129ed565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612ab857612ab86129ed565b81604052838152866020858801011115612ad157600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215612b0457600080fd5b82359150602083013567ffffffffffffffff811115612b2257600080fd5b612b2e85828601612a46565b9150509250929050565b60008060008060808587031215612b4e57600080fd5b8435935060208501359250604085013567ffffffffffffffff811115612b7357600080fd5b612b7f87828801612a46565b949793965093946060013593505050565b73ffffffffffffffffffffffffffffffffffffffff81168114612bb257600080fd5b50565b600060208284031215612bc757600080fd5b8135612bd281612b90565b9392505050565b600060208284031215612beb57600080fd5b5035919050565b600081518084526020808501945080840160005b83811015612c2257815187529582019590820190600101612c06565b509495945050505050565b602081526000612bd26020830184612bf2565b60008060408385031215612c5357600080fd5b823591506020830135612c6581612b90565b809150509250929050565b60005b83811015612c8b578181015183820152602001612c73565b8381111561064f5750506000910152565b60008151808452612cb4816020860160208601612c70565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b80518252600060208201516040602085015261095d6040850182612c9c565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015612d78577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452612d66858351612ce6565b94509285019290850190600101612d2c565b5092979650505050505050565b602081528151602082015260208201516040820152604082015160608201526060820151608082015260006080830151612dc360a084018215159052565b5060a083015180151560c08401525060c083015180151560e08401525060e0830151610100612e098185018373ffffffffffffffffffffffffffffffffffffffff169052565b8401519050610120612e328482018373ffffffffffffffffffffffffffffffffffffffff169052565b84015161014084810152905061095d610160840182612c9c565b60008060408385031215612e5f57600080fd5b50508035926020909101359150565b82815260406020820152600061095d6040830184612c9c565b60006101408c83528b60208401528a6040840152896060840152881515608084015287151560a084015286151560c084015273ffffffffffffffffffffffffffffffffffffffff80871660e08501528086166101008501525080610120840152612ef381840185612c9c565b9d9c50505050505050505050505050565b600080600060408486031215612f1957600080fd5b83359250602084013567ffffffffffffffff80821115612f3857600080fd5b818601915086601f830112612f4c57600080fd5b813581811115612f5b57600080fd5b8760208260051b8501011115612f7057600080fd5b6020830194508093505050509250925092565b602081526000612bd26020830184612ce6565b60008060008060808587031215612fac57600080fd5b843567ffffffffffffffff811115612fc357600080fd5b612fcf87828801612a46565b9450506020850135612fe081612b90565b93969395505050506040820135916060013590565b600181811c9082168061300957607f821691505b602082108103613042577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f821115611e1657600081815260208120601f850160051c8101602086101561306f5750805b601f850160051c820191505b818110156105995782815560010161307b565b815167ffffffffffffffff8111156130a8576130a86129ed565b6130bc816130b68454612ff5565b84613048565b602080601f83116001811461310f57600084156130d95750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610599565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561315c5788860151825594840194600190910190840161313d565b508582101561319857878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600081546131b581612ff5565b8085526020600183811680156131d2576001811461320a57613238565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b8901019550613238565b866000528260002060005b858110156132305781548a8201860152908301908401613215565b890184019650505b505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff8516815283602082015282604082015260806060820152600061327e60808301846131a8565b9695505050505050565b805161329381612b90565b919050565b8051801515811461329357600080fd5b600060e082840312156132ba57600080fd5b60405160e0810181811067ffffffffffffffff821117156132dd576132dd6129ed565b6040529050806132ec83613298565b81526132fa60208401613298565b602082015261330b60408401613298565b604082015261331c60608401613298565b606082015261332d60808401613298565b608082015260a083015160a082015260c083015160c08201525092915050565b6000610200828403121561336057600080fd5b613368612a1c565b61337183613288565b815261337f60208401613288565b602082015261339060408401613288565b60408201526133a160608401613298565b60608201526133b384608085016132a8565b608082015261016083015160a082015261018083015160c08201526101a083015160e08201526101c08301516101008201526101e09092015161012083015250919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561343a5761343a6133f8565b500190565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561347157600080fd5b8260051b8083602087013760009401602001938452509192915050565b8381526040602082015260006134a860408301848661343f565b95945050505050565b60208152600061095d60208301848661343f565b6000828210156134d7576134d76133f8565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561351d57600080fd5b612bd282613298565b6080815260006135396080830187612c9c565b73ffffffffffffffffffffffffffffffffffffffff959095166020830152506040810192909252606090910152919050565b8381528260208201526060604082015260006134a860608301846131a8565b60006020828403121561359c57600080fd5b5051919050565b82815260406020820152600061095d6040830184612bf2565b600084516135ce818460208901612c70565b8451908301906135e2818360208901612c70565b84519101906135f5818360208801612c70565b0195945050505050565b85815284602082015260a06040820152600061361e60a0830186612c9c565b73ffffffffffffffffffffffffffffffffffffffff94909416606083015250608001529392505050565b8381528260208201526060604082015260006134a86060830184612c9c565b86815285602082015260c06040820152600061368660c0830187612c9c565b9415156060830152509115156080830152151560a0909101529392505050565b8481528360208201526080604082015260006136c56080830185612c9c565b905082606083015295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea2646970667358221220239ab9e8271b3afc9238b83bae1ff4338e1d5deebca724ab3bda8b8bc69fbe7b64736f6c634300080f00330000000000000000000000004d97dcd97ec945f40cf65f87097ace5ea047604500000000000000000000000009aea4b2242abc8bb4bb78d537a67a245a7bec64

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

0000000000000000000000004d97dcd97ec945f40cf65f87097ace5ea047604500000000000000000000000009aea4b2242abc8bb4bb78d537a67a245a7bec64

-----Decoded View---------------
Arg [0] : _ctf (address): 0x4d97dcd97ec945f40cf65f87097ace5ea0476045
Arg [1] : _finder (address): 0x09aea4b2242abc8bb4bb78d537a67a245a7bec64

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000004d97dcd97ec945f40cf65f87097ace5ea0476045
Arg [1] : 00000000000000000000000009aea4b2242abc8bb4bb78d537a67a245a7bec64


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