ETH Price: $3,932.79 (+5.73%)

Contract

0x9f5B558C95292f13fa9E0328Ac4D3f129C2d9562

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Fulfill Agg Requ...1289010442024-12-05 12:14:2526 mins ago1733400865IN
0x9f5B558C...29C2d9562
0 ETH0.0000073337260.00100041
Fulfill Agg Requ...1288987762024-12-05 10:58:491 hr ago1733396329IN
0x9f5B558C...29C2d9562
0 ETH0.0000066881720.00100042
Fulfill Agg Requ...1288947532024-12-05 8:44:433 hrs ago1733388283IN
0x9f5B558C...29C2d9562
0 ETH0.0000302409930.00100034
Fulfill Agg Requ...1288929782024-12-05 7:45:334 hrs ago1733384733IN
0x9f5B558C...29C2d9562
0 ETH0.0000066300820.00100043
Fulfill Agg Requ...1288911592024-12-05 6:44:555 hrs ago1733381095IN
0x9f5B558C...29C2d9562
0 ETH0.0000167897470.00100034
Fulfill Agg Requ...1288893812024-12-05 5:45:396 hrs ago1733377539IN
0x9f5B558C...29C2d9562
0 ETH0.0000091435370.0010004
Fulfill Agg Requ...1288892042024-12-05 5:39:457 hrs ago1733377185IN
0x9f5B558C...29C2d9562
0 ETH0.0000127369520.00100037
Fulfill Agg Requ...1288882942024-12-05 5:09:257 hrs ago1733375365IN
0x9f5B558C...29C2d9562
0 ETH0.0000189702070.00100037
Fulfill Agg Requ...1288876962024-12-05 4:49:297 hrs ago1733374169IN
0x9f5B558C...29C2d9562
0 ETH0.0000243723730.00100033
Fulfill Agg Requ...1288875462024-12-05 4:44:297 hrs ago1733373869IN
0x9f5B558C...29C2d9562
0 ETH0.00002014680.00100032
Fulfill Agg Requ...1288874242024-12-05 4:40:258 hrs ago1733373625IN
0x9f5B558C...29C2d9562
0 ETH0.0000384775070.00100034
Fulfill Agg Requ...1288868002024-12-05 4:19:378 hrs ago1733372377IN
0x9f5B558C...29C2d9562
0 ETH0.0000277026680.00100042
Fulfill Agg Requ...1288865002024-12-05 4:09:378 hrs ago1733371777IN
0x9f5B558C...29C2d9562
0 ETH0.0000251808120.00100045
Fulfill Agg Requ...1288859002024-12-05 3:49:378 hrs ago1733370577IN
0x9f5B558C...29C2d9562
0 ETH0.0000460746170.00100055
Fulfill Agg Requ...1288856002024-12-05 3:39:379 hrs ago1733369977IN
0x9f5B558C...29C2d9562
0 ETH0.0000155835460.00100062
Fulfill Agg Requ...1288850022024-12-05 3:19:419 hrs ago1733368781IN
0x9f5B558C...29C2d9562
0 ETH0.0000167140590.00100067
Fulfill Agg Requ...1288846922024-12-05 3:09:219 hrs ago1733368161IN
0x9f5B558C...29C2d9562
0 ETH0.0000104405440.00100056
Fulfill Agg Requ...1288842742024-12-05 2:55:259 hrs ago1733367325IN
0x9f5B558C...29C2d9562
0 ETH0.0000748851930.0010005
Fulfill Agg Requ...1288837942024-12-05 2:39:2510 hrs ago1733366365IN
0x9f5B558C...29C2d9562
0 ETH0.0000130782560.00100042
Fulfill Agg Requ...1288835002024-12-05 2:29:3710 hrs ago1733365777IN
0x9f5B558C...29C2d9562
0 ETH0.0000705840970.00100034
Fulfill Agg Requ...1288830882024-12-05 2:15:5310 hrs ago1733364953IN
0x9f5B558C...29C2d9562
0 ETH0.0001104741470.00100034
Fulfill Agg Requ...1288821922024-12-05 1:46:0110 hrs ago1733363161IN
0x9f5B558C...29C2d9562
0 ETH0.0000401568020.00100032
Fulfill Agg Requ...1288812992024-12-05 1:16:1511 hrs ago1733361375IN
0x9f5B558C...29C2d9562
0 ETH0.0000335208380.00100039
Fulfill Agg Requ...1288803732024-12-05 0:45:2311 hrs ago1733359523IN
0x9f5B558C...29C2d9562
0 ETH0.0000865165790.00100042
Send Request1288799662024-12-05 0:31:4912 hrs ago1733358709IN
0x9f5B558C...29C2d9562
0 ETH0.0000023996220.00100064
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
BrevisRequest

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 800 runs

Other Settings:
paris EvmVersion
File 1 of 12 : BrevisRequest.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

import "./FeeVault.sol";
import "../interface/IBrevisRequest.sol";
import "../interface/IBrevisProof.sol";
import "../interface/IBrevisApp.sol";
import "../lib/Lib.sol";
import "../../safeguard/BrevisAccess.sol";

contract BrevisRequest is IBrevisRequest, FeeVault, BrevisAccess {
    uint256 public requestTimeout;
    IBrevisProof public brevisProof;

    mapping(bytes32 => Request) public requests; // TODO: store hash of request data to save gas cost

    constructor(address _feeCollector, IBrevisProof _brevisProof) FeeVault(_feeCollector) {
        brevisProof = _brevisProof;
    }

    function sendRequest(bytes32 _requestId, address _refundee, address _callback) external payable {
        require(requests[_requestId].deadline == 0, "request already in queue");
        require(_refundee != address(0), "refundee not provided");
        requests[_requestId] = Request(
            block.timestamp + requestTimeout,
            msg.value,
            _refundee,
            _callback,
            RequestStatus.Pending
        );
        emit RequestSent(_requestId, msg.sender, msg.value, _callback);
    }

    function fulfillRequest(
        bytes32 _requestId,
        uint64 _chainId,
        bytes calldata _proof,
        bool _withAppProof,
        bytes calldata _appCircuitOutput
    ) external onlyActiveProver {
        require(!IBrevisProof(brevisProof).hasProof(_requestId), "proof already generated");

        bytes32 reqIdFromProof = IBrevisProof(brevisProof).submitProof(_chainId, _proof, _withAppProof); // will revert if proof is not valid
        require(_requestId == reqIdFromProof, "requestId and proof not match");
        requests[_requestId].status = RequestStatus.ZkAttested;

        emit RequestFulfilled(_requestId);

        address app = requests[_requestId].callback;
        if (app != address(0)) {
            // No matter if the call is success or not. The relayer should set correct gas limit.
            // If the call exceeds the gasleft(), as the proof data is saved ahead,
            // anyone can still call the app.callback directly to proceed
            (bool success, ) = app.call(
                abi.encodeWithSelector(IBrevisApp.brevisCallback.selector, _requestId, _appCircuitOutput)
            );
            if (!success) {
                emit RequestCallbackFailed(_requestId);
            }
        }
    }

    function fulfillAggRequests(
        uint64 _chainId,
        bytes32[] calldata _requestIds,
        bytes calldata _proof,
        Brevis.ProofData[] calldata _proofDataArray,
        bytes[] calldata _appCircuitOutputs,
        address _callback
    ) external onlyActiveProver {
        IBrevisProof(brevisProof).mustSubmitAggProof(_chainId, _requestIds, _proof);

        for (uint8 i = 1; i < _requestIds.length; i++) {
            bytes32 requestId = _requestIds[i];
            requests[requestId].status = RequestStatus.ZkAttested;
        }

        emit RequestsFulfilled(_requestIds);

        if (_callback != address(0)) {
            (bool success, ) = _callback.call(
                abi.encodeWithSelector(
                    IBrevisApp.brevisBatchCallback.selector,
                    _chainId,
                    _proofDataArray,
                    _appCircuitOutputs
                )
            );
            if (!success) {
                emit RequestsCallbackFailed(_requestIds);
            }
        }
    }

    function refund(bytes32 _requestId) external {
        require(block.timestamp > requests[_requestId].deadline);
        require(!IBrevisProof(brevisProof).hasProof(_requestId), "proof already generated");
        require(requests[_requestId].deadline != 0, "request not in queue");
        requests[_requestId].deadline = 0; //reset deadline, then user is able to send request again
        (bool sent, ) = requests[_requestId].refundee.call{value: requests[_requestId].fee, gas: 50000}("");
        require(sent, "send native failed");
        requests[_requestId].status = RequestStatus.Refunded;
        emit RequestRefunded(_requestId);
    }

    function setRequestTimeout(uint256 _timeout) external onlyOwner {
        uint256 oldTimeout = requestTimeout;
        requestTimeout = _timeout;
        emit RequestTimeoutUpdated(oldTimeout, _timeout);
    }

    function queryRequestStatus(bytes32 _requestId) external view returns (RequestStatus) {
        return requests[_requestId].status;
    }
}

File 2 of 12 : Pausable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

File 3 of 12 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 4 of 12 : RLPReader.sol
// SPDX-License-Identifier: Apache-2.0

/*
 * @author Hamdi Allam [email protected]
 * Please reach out with any questions or concerns
 */
pragma solidity >=0.5.10 <0.9.0;

library RLPReader {
    uint8 constant STRING_SHORT_START = 0x80;
    uint8 constant STRING_LONG_START = 0xb8;
    uint8 constant LIST_SHORT_START = 0xc0;
    uint8 constant LIST_LONG_START = 0xf8;
    uint8 constant WORD_SIZE = 32;

    struct RLPItem {
        uint256 len;
        uint256 memPtr;
    }

    struct Iterator {
        RLPItem item; // Item that's being iterated over.
        uint256 nextPtr; // Position of the next item in the list.
    }

    /*
     * @dev Returns the next element in the iteration. Reverts if it has not next element.
     * @param self The iterator.
     * @return The next element in the iteration.
     */
    function next(Iterator memory self) internal pure returns (RLPItem memory) {
        require(hasNext(self));

        uint256 ptr = self.nextPtr;
        uint256 itemLength = _itemLength(ptr);
        self.nextPtr = ptr + itemLength;

        return RLPItem(itemLength, ptr);
    }

    /*
     * @dev Returns true if the iteration has more elements.
     * @param self The iterator.
     * @return true if the iteration has more elements.
     */
    function hasNext(Iterator memory self) internal pure returns (bool) {
        RLPItem memory item = self.item;
        return self.nextPtr < item.memPtr + item.len;
    }

    /*
     * @param item RLP encoded bytes
     */
    function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) {
        uint256 memPtr;
        assembly {
            memPtr := add(item, 0x20)
        }

        return RLPItem(item.length, memPtr);
    }

    /*
     * @dev Create an iterator. Reverts if item is not a list.
     * @param self The RLP item.
     * @return An 'Iterator' over the item.
     */
    function iterator(RLPItem memory self) internal pure returns (Iterator memory) {
        require(isList(self));

        uint256 ptr = self.memPtr + _payloadOffset(self.memPtr);
        return Iterator(self, ptr);
    }

    /*
     * @param the RLP item.
     */
    function rlpLen(RLPItem memory item) internal pure returns (uint256) {
        return item.len;
    }

    /*
     * @param the RLP item.
     * @return (memPtr, len) pair: location of the item's payload in memory.
     */
    function payloadLocation(RLPItem memory item) internal pure returns (uint256, uint256) {
        uint256 offset = _payloadOffset(item.memPtr);
        uint256 memPtr = item.memPtr + offset;
        uint256 len = item.len - offset; // data length
        return (memPtr, len);
    }

    /*
     * @param the RLP item.
     */
    function payloadLen(RLPItem memory item) internal pure returns (uint256) {
        (, uint256 len) = payloadLocation(item);
        return len;
    }

    /*
     * @param the RLP item containing the encoded list.
     */
    function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) {
        require(isList(item));

        uint256 items = numItems(item);
        RLPItem[] memory result = new RLPItem[](items);

        uint256 memPtr = item.memPtr + _payloadOffset(item.memPtr);
        uint256 dataLen;
        for (uint256 i = 0; i < items; i++) {
            dataLen = _itemLength(memPtr);
            result[i] = RLPItem(dataLen, memPtr);
            memPtr = memPtr + dataLen;
        }

        return result;
    }

    // @return indicator whether encoded payload is a list. negate this function call for isData.
    function isList(RLPItem memory item) internal pure returns (bool) {
        if (item.len == 0) return false;

        uint8 byte0;
        uint256 memPtr = item.memPtr;
        assembly {
            byte0 := byte(0, mload(memPtr))
        }

        if (byte0 < LIST_SHORT_START) return false;
        return true;
    }

    /*
     * @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory.
     * @return keccak256 hash of RLP encoded bytes.
     */
    function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) {
        uint256 ptr = item.memPtr;
        uint256 len = item.len;
        bytes32 result;
        assembly {
            result := keccak256(ptr, len)
        }
        return result;
    }

    /*
     * @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory.
     * @return keccak256 hash of the item payload.
     */
    function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) {
        (uint256 memPtr, uint256 len) = payloadLocation(item);
        bytes32 result;
        assembly {
            result := keccak256(memPtr, len)
        }
        return result;
    }

    /** RLPItem conversions into data types **/

    // @returns raw rlp encoding in bytes
    function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) {
        bytes memory result = new bytes(item.len);
        if (result.length == 0) return result;

        uint256 ptr;
        assembly {
            ptr := add(0x20, result)
        }

        copy(item.memPtr, ptr, item.len);
        return result;
    }

    // any non-zero byte except "0x80" is considered true
    function toBoolean(RLPItem memory item) internal pure returns (bool) {
        require(item.len == 1);
        uint256 result;
        uint256 memPtr = item.memPtr;
        assembly {
            result := byte(0, mload(memPtr))
        }

        // SEE Github Issue #5.
        // Summary: Most commonly used RLP libraries (i.e Geth) will encode
        // "0" as "0x80" instead of as "0". We handle this edge case explicitly
        // here.
        if (result == 0 || result == STRING_SHORT_START) {
            return false;
        } else {
            return true;
        }
    }

    function toAddress(RLPItem memory item) internal pure returns (address) {
        // 1 byte for the length prefix
        require(item.len == 21);

        return address(uint160(toUint(item)));
    }

    function toUint(RLPItem memory item) internal pure returns (uint256) {
        require(item.len > 0 && item.len <= 33);

        (uint256 memPtr, uint256 len) = payloadLocation(item);

        uint256 result;
        assembly {
            result := mload(memPtr)

            // shift to the correct location if neccesary
            if lt(len, 32) {
                result := div(result, exp(256, sub(32, len)))
            }
        }

        return result;
    }

    // enforces 32 byte length
    function toUintStrict(RLPItem memory item) internal pure returns (uint256) {
        // one byte prefix
        require(item.len == 33);

        uint256 result;
        uint256 memPtr = item.memPtr + 1;
        assembly {
            result := mload(memPtr)
        }

        return result;
    }

    function toBytes(RLPItem memory item) internal pure returns (bytes memory) {
        require(item.len > 0);

        (uint256 memPtr, uint256 len) = payloadLocation(item);
        bytes memory result = new bytes(len);

        uint256 destPtr;
        assembly {
            destPtr := add(0x20, result)
        }

        copy(memPtr, destPtr, len);
        return result;
    }

    /*
     * Private Helpers
     */

    // @return number of payload items inside an encoded list.
    function numItems(RLPItem memory item) private pure returns (uint256) {
        if (item.len == 0) return 0;

        uint256 count = 0;
        uint256 currPtr = item.memPtr + _payloadOffset(item.memPtr);
        uint256 endPtr = item.memPtr + item.len;
        while (currPtr < endPtr) {
            currPtr = currPtr + _itemLength(currPtr); // skip over an item
            count++;
        }

        return count;
    }

    // @return entire rlp item byte length
    function _itemLength(uint256 memPtr) private pure returns (uint256) {
        uint256 itemLen;
        uint256 byte0;
        assembly {
            byte0 := byte(0, mload(memPtr))
        }

        if (byte0 < STRING_SHORT_START) {
            itemLen = 1;
        } else if (byte0 < STRING_LONG_START) {
            itemLen = byte0 - STRING_SHORT_START + 1;
        } else if (byte0 < LIST_SHORT_START) {
            assembly {
                let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is
                memPtr := add(memPtr, 1) // skip over the first byte

                /* 32 byte word size */
                let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len
                itemLen := add(dataLen, add(byteLen, 1))
            }
        } else if (byte0 < LIST_LONG_START) {
            itemLen = byte0 - LIST_SHORT_START + 1;
        } else {
            assembly {
                let byteLen := sub(byte0, 0xf7)
                memPtr := add(memPtr, 1)

                let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length
                itemLen := add(dataLen, add(byteLen, 1))
            }
        }

        return itemLen;
    }

    // @return number of bytes until the data
    function _payloadOffset(uint256 memPtr) private pure returns (uint256) {
        uint256 byte0;
        assembly {
            byte0 := byte(0, mload(memPtr))
        }

        if (byte0 < STRING_SHORT_START) {
            return 0;
        } else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START)) {
            return 1;
        } else if (byte0 < LIST_SHORT_START) {
            // being explicit
            return byte0 - (STRING_LONG_START - 1) + 1;
        } else {
            return byte0 - (LIST_LONG_START - 1) + 1;
        }
    }

    /*
     * @param src Pointer to source
     * @param dest Pointer to destination
     * @param len Amount of memory to copy from the source
     */
    function copy(uint256 src, uint256 dest, uint256 len) private pure {
        if (len == 0) return;

        // copy as many word sizes as possible
        for (; len >= WORD_SIZE; len -= WORD_SIZE) {
            assembly {
                mstore(dest, mload(src))
            }

            src += WORD_SIZE;
            dest += WORD_SIZE;
        }

        if (len > 0) {
            // left over bytes. Mask is used to remove unwanted bytes from the word
            uint256 mask = 256 ** (WORD_SIZE - len) - 1;
            assembly {
                let srcpart := and(mload(src), not(mask)) // zero out src
                let destpart := and(mload(dest), mask) // retrieve the bytes
                mstore(dest, or(destpart, srcpart))
            }
        }
    }
}

File 5 of 12 : BrevisAccess.sol
// SPDX-License-Identifier: GPL-3.0-only

pragma solidity ^0.8.18;

import "./Pauser.sol";

// prover and pauser access control using a single map lookup
abstract contract BrevisAccess is Pauser {
    enum ProverState {
        Null,
        Active,
        Paused
    }
    mapping(address => ProverState) public proverStates;
    address[] public provers;

    event ProverAdded(address account);
    event ProverRemoved(address account);

    modifier onlyProver() {
        require(proverStates[msg.sender] != ProverState.Null, "invalid prover");
        _;
    }

    modifier onlyActiveProver() {
        require(proverStates[msg.sender] == ProverState.Active, "invalid prover");
        _;
    }

    function addProvers(address[] memory _accounts) public onlyOwner {
        ProverState state = paused() ? ProverState.Paused : ProverState.Active;
        for (uint256 i = 0; i < _accounts.length; i++) {
            _addProver(_accounts[i], state);
        }
    }

    function removeProvers(address[] memory _accounts) public onlyOwner {
        for (uint256 i = 0; i < _accounts.length; i++) {
            _removeProver(_accounts[i]);
        }
    }

    function pause() public override onlyPauser {
        _pause();
        for (uint256 i = 0; i < provers.length; i++) {
            proverStates[provers[i]] = ProverState.Paused;
        }
    }

    function unpause() public override onlyPauser {
        _unpause();
        for (uint256 i = 0; i < provers.length; i++) {
            proverStates[provers[i]] = ProverState.Active;
        }
    }

    function numProvers() public view returns (uint256) {
        return provers.length;
    }

    function isActiveProver(address _account) public view returns (bool) {
        return proverStates[_account] == ProverState.Active;
    }

    function _addProver(address _account, ProverState _state) private {
        require(proverStates[_account] == ProverState.Null, "account is prover");
        provers.push(_account);
        proverStates[_account] = _state;
        emit ProverAdded(_account);
    }

    function _removeProver(address _account) private {
        require(proverStates[_account] != ProverState.Null, "account is not prover");
        uint256 lastIndex = provers.length - 1;
        for (uint256 i = 0; i < provers.length; i++) {
            if (provers[i] == _account) {
                if (i < lastIndex) {
                    provers[i] = provers[lastIndex];
                }
                provers.pop();
                delete proverStates[_account];
                emit ProverRemoved(_account);
                return;
            }
        }
        revert("prover not found"); // this should never happen
    }
}

File 6 of 12 : Ownable.sol
// SPDX-License-Identifier: GPL-3.0-only

pragma solidity ^0.8.18;

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 *
 * This adds a normal func that setOwner if _owner is address(0). So we can't allow
 * renounceOwnership. So we can support Proxy based upgradable contract
 */
abstract contract Ownable {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _setOwner(msg.sender);
    }

    /**
     * @dev Only to be called by inherit contracts, in their init func called by Proxy
     * we require _owner == address(0), which is only possible when it's a delegateCall
     * because constructor sets _owner in contract state.
     */
    function initOwner() internal {
        require(_owner == address(0), "owner already set");
        _setOwner(msg.sender);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == msg.sender, "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 7 of 12 : Pauser.sol
// SPDX-License-Identifier: GPL-3.0-only

pragma solidity ^0.8.18;

import "@openzeppelin/contracts/security/Pausable.sol";
import "./Ownable.sol";

abstract contract Pauser is Ownable, Pausable {
    mapping(address => bool) public pausers;
    address[] public pauserList;

    event PauserAdded(address account);
    event PauserRemoved(address account);

    constructor() {
        _addPauser(msg.sender);
    }

    modifier onlyPauser() {
        require(isPauser(msg.sender), "Caller is not pauser");
        _;
    }

    function pause() public virtual onlyPauser {
        _pause();
    }

    function unpause() public virtual onlyPauser {
        _unpause();
    }

    function isPauser(address account) public view returns (bool) {
        return pausers[account];
    }

    function addPauser(address account) public onlyOwner {
        _addPauser(account);
    }

    function addPausers(address[] memory accounts) public onlyOwner {
        for (uint256 i = 0; i < accounts.length; i++) {
            _addPauser(accounts[i]);
        }
    }

    function removePauser(address account) public onlyOwner {
        _removePauser(account);
    }

    function removePausers(address[] memory accounts) public onlyOwner {
        for (uint256 i = 0; i < accounts.length; i++) {
            _removePauser(accounts[i]);
        }
    }

    function renouncePauser() public {
        _removePauser(msg.sender);
    }

    function numPausers() public view returns (uint256) {
        return pauserList.length;
    }

    function _addPauser(address account) private {
        require(!isPauser(account), "Account is already pauser");
        pauserList.push(account);
        pausers[account] = true;
        emit PauserAdded(account);
    }

    function _removePauser(address account) private {
        require(isPauser(account), "Account is not pauser");
        uint256 lastIndex = pauserList.length - 1;
        for (uint256 i = 0; i < pauserList.length; i++) {
            if (pauserList[i] == account) {
                if (i < lastIndex) {
                    pauserList[i] = pauserList[lastIndex];
                }
                pauserList.pop();
                pausers[account] = false;
                emit PauserRemoved(account);
                return;
            }
        }
        revert("pauser not found"); // this should never happen
    }
}

File 8 of 12 : FeeVault.sol
// SPDX-License-Identifier: GPL-3.0-only

pragma solidity >=0.8.18;

import "../../safeguard/Ownable.sol";

/**
 * @title Allows the owner to set fee collector and allows fee collectors to collect fees
 */
contract FeeVault is Ownable {
    address public feeCollector;

    event FeeCollected(uint256 amount, address receiver);
    event FeeCollectorUpdated(address from, address to);

    constructor(address _feeCollector) {
        feeCollector = _feeCollector;
    }

    modifier onlyFeeCollector() {
        require(msg.sender == feeCollector, "not fee collector");
        _;
    }

    function collectFee(uint256 _amount, address _to) external onlyFeeCollector {
        (bool sent, ) = _to.call{value: _amount, gas: 50000}("");
        require(sent, "send native failed");
        emit FeeCollected(_amount, _to);
    }

    function setFeeCollector(address _feeCollector) external onlyOwner {
        address oldFeeCollector = feeCollector;
        feeCollector = _feeCollector;
        emit FeeCollectorUpdated(oldFeeCollector, _feeCollector);
    }

    receive() external payable {}
}

File 9 of 12 : IBrevisApp.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

import "../lib/Lib.sol";

interface IBrevisApp {
    function brevisCallback(bytes32 _requestId, bytes calldata _appCircuitOutput) external;

    function brevisBatchCallback(
        uint64 _chainId,
        Brevis.ProofData[] calldata _proofDataArray,
        bytes[] calldata _appCircuitOutputs
    ) external;
}

File 10 of 12 : IBrevisProof.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

import "../lib/Lib.sol";

interface IBrevisProof {
    function submitProof(
        uint64 _chainId,
        bytes calldata _proofWithPubInputs,
        bool _withAppProof
    ) external returns (bytes32 _requestId);

    function hasProof(bytes32 _requestId) external view returns (bool);

    // used by contract app
    function validateRequest(bytes32 _requestId, uint64 _chainId, Brevis.ExtractInfos memory _info) external view;

    function getProofData(bytes32 _requestId) external view returns (Brevis.ProofData memory);

    // return appCommitHash and appVkHash
    function getProofAppData(bytes32 _requestId) external view returns (bytes32, bytes32);

    function mustValidateRequest(
        uint64 _chainId,
        Brevis.ProofData calldata _proofData,
        bytes32 _merkleRoot,
        bytes32[] calldata _merkleProof,
        uint8 _nodeIndex
    ) external view;

    function mustValidateRequests(uint64 _chainId, Brevis.ProofData[] calldata _proofDataArray) external view;

    function mustSubmitAggProof(
        uint64 _chainId,
        bytes32[] calldata _requestIds,
        bytes calldata _proofWithPubInputs
    ) external;
}

File 11 of 12 : IBrevisRequest.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

import "../lib/Lib.sol";

interface IBrevisRequest {
    enum RequestStatus {
        Pending,
        ZkAttested,
        Refunded
    }

    struct Request {
        uint256 deadline;
        uint256 fee;
        address refundee;
        address callback;
        RequestStatus status;
    }

    event RequestSent(bytes32 requestId, address sender, uint256 fee, address callback);
    event RequestFulfilled(bytes32 requestId);
    event RequestsFulfilled(bytes32[] requestId);
    event RequestRefunded(bytes32 requestId);
    event RequestCallbackFailed(bytes32 requestId);
    event RequestsCallbackFailed(bytes32[] requestIds);
    event RequestTimeoutUpdated(uint256 from, uint256 to);

    function sendRequest(bytes32 _requestId, address _refundee, address _callback) external payable;

    function fulfillRequest(
        bytes32 _requestId,
        uint64 _chainId,
        bytes calldata _proof,
        bool _withAppProof,
        bytes calldata _appCircuitOutput
    ) external;

    function fulfillAggRequests(
        uint64 _chainId,
        bytes32[] calldata _requestIds,
        bytes calldata _proof,
        Brevis.ProofData[] calldata _proofDataArray,
        bytes[] calldata _appCircuitOutputs,
        address _callback
    ) external;

    function refund(bytes32 _requestId) external;

    function queryRequestStatus(bytes32 _requestId) external view returns (RequestStatus);
}

File 12 of 12 : Lib.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

import "../../lib/RLPReader.sol";

library Brevis {
    uint256 constant NumField = 5; // supports at most 5 fields per receipt log

    struct ReceiptInfo {
        uint64 blkNum;
        uint64 receiptIndex; // ReceiptIndex in the block
        LogInfo[NumField] logs;
    }

    struct LogInfo {
        LogExtraInfo logExtraInfo;
        uint64 logIndex; // LogIndex of the field
        bytes32 value;
    }

    struct LogExtraInfo {
        uint8 valueFromTopic;
        uint64 valueIndex; // index of the fields in topic or data
        address contractAddress;
        bytes32 logTopic0;
    }

    struct StorageInfo {
        bytes32 blockHash;
        address account;
        bytes32 slot;
        bytes32 slotValue;
        uint64 blockNumber;
    }

    struct TransactionInfo {
        bytes32 leafHash;
        bytes32 blockHash;
        uint64 blockNumber;
        uint64 blockTime;
        bytes leafRlpPrefix;
    }

    struct ExtractInfos {
        bytes32 smtRoot;
        ReceiptInfo[] receipts;
        StorageInfo[] stores;
        TransactionInfo[] txs;
    }

    // retrieved from proofData, to align the logs with circuit...
    struct ProofData {
        bytes32 commitHash;
        bytes32 vkHash;
        bytes32 appCommitHash; // zk-program computing circuit commit hash
        bytes32 appVkHash; // zk-program computing circuit Verify Key hash
        bytes32 smtRoot; // for zk-program computing proof only
    }
}

library Tx {
    using RLPReader for bytes;
    using RLPReader for uint;
    using RLPReader for RLPReader.RLPItem;

    struct TxInfo {
        uint64 chainId;
        uint64 nonce;
        uint256 gasTipCap;
        uint256 gasFeeCap;
        uint256 gas;
        address to;
        uint256 value;
        bytes data;
        address from; // calculate from V R S
    }

    // support DynamicFeeTxType for now
    function decodeTx(bytes calldata txRaw) public pure returns (TxInfo memory info) {
        uint8 txType = uint8(txRaw[0]);
        require(txType == 2, "not a DynamicFeeTxType");

        bytes memory rlpData = txRaw[1:];
        RLPReader.RLPItem[] memory values = rlpData.toRlpItem().toList();
        info.chainId = uint64(values[0].toUint());
        info.nonce = uint64(values[1].toUint());
        info.gasTipCap = values[2].toUint();
        info.gasFeeCap = values[3].toUint();
        info.gas = values[4].toUint();
        info.to = values[5].toAddress();
        info.value = values[6].toUint();
        info.data = values[7].toBytes();

        (uint8 v, bytes32 r, bytes32 s) = (
            uint8(values[9].toUint()),
            bytes32(values[10].toBytes()),
            bytes32(values[11].toBytes())
        );
        // remove r,s,v and adjust length field
        bytes memory unsignedTxRaw;
        uint16 unsignedTxRawDataLength;
        uint8 prefix = uint8(txRaw[1]);
        uint8 lenBytes = prefix - 0xf7; // assume lenBytes won't larger than 2, means the tx rlp data size won't exceed 2^16
        if (lenBytes == 1) {
            unsignedTxRawDataLength = uint8(bytes1(txRaw[2:3])) - 67; //67 is the bytes of r,s,v
        } else {
            unsignedTxRawDataLength = uint16(bytes2(txRaw[2:2 + lenBytes])) - 67;
        }
        if (unsignedTxRawDataLength <= 55) {
            unsignedTxRaw = abi.encodePacked(txRaw[:2], txRaw[3:txRaw.length - 67]);
            unsignedTxRaw[1] = bytes1(0xc0 + uint8(unsignedTxRawDataLength));
        } else {
            if (unsignedTxRawDataLength <= 255) {
                unsignedTxRaw = abi.encodePacked(
                    txRaw[0],
                    bytes1(0xf8),
                    bytes1(uint8(unsignedTxRawDataLength)),
                    txRaw[2 + lenBytes:txRaw.length - 67]
                );
            } else {
                unsignedTxRaw = abi.encodePacked(
                    txRaw[0],
                    bytes1(0xf9),
                    bytes2(unsignedTxRawDataLength),
                    txRaw[2 + lenBytes:txRaw.length - 67]
                );
            }
        }
        info.from = recover(keccak256(unsignedTxRaw), r, s, v);
    }

    function recover(bytes32 message, bytes32 r, bytes32 s, uint8 v) internal pure returns (address) {
        if (v < 27) {
            v += 27;
        }
        return ecrecover(message, v, r, s);
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 800
  },
  "viaIR": true,
  "evmVersion": "paris",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_feeCollector","type":"address"},{"internalType":"contract IBrevisProof","name":"_brevisProof","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"}],"name":"FeeCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"FeeCollectorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"PauserAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"PauserRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"ProverAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"ProverRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"requestId","type":"bytes32"}],"name":"RequestCallbackFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"requestId","type":"bytes32"}],"name":"RequestFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"requestId","type":"bytes32"}],"name":"RequestRefunded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"requestId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"address","name":"callback","type":"address"}],"name":"RequestSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"from","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"to","type":"uint256"}],"name":"RequestTimeoutUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32[]","name":"requestIds","type":"bytes32[]"}],"name":"RequestsCallbackFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32[]","name":"requestId","type":"bytes32[]"}],"name":"RequestsFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addPauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"addPausers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_accounts","type":"address[]"}],"name":"addProvers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"brevisProof","outputs":[{"internalType":"contract IBrevisProof","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"collectFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeCollector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"_chainId","type":"uint64"},{"internalType":"bytes32[]","name":"_requestIds","type":"bytes32[]"},{"internalType":"bytes","name":"_proof","type":"bytes"},{"components":[{"internalType":"bytes32","name":"commitHash","type":"bytes32"},{"internalType":"bytes32","name":"vkHash","type":"bytes32"},{"internalType":"bytes32","name":"appCommitHash","type":"bytes32"},{"internalType":"bytes32","name":"appVkHash","type":"bytes32"},{"internalType":"bytes32","name":"smtRoot","type":"bytes32"}],"internalType":"struct Brevis.ProofData[]","name":"_proofDataArray","type":"tuple[]"},{"internalType":"bytes[]","name":"_appCircuitOutputs","type":"bytes[]"},{"internalType":"address","name":"_callback","type":"address"}],"name":"fulfillAggRequests","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"internalType":"uint64","name":"_chainId","type":"uint64"},{"internalType":"bytes","name":"_proof","type":"bytes"},{"internalType":"bool","name":"_withAppProof","type":"bool"},{"internalType":"bytes","name":"_appCircuitOutput","type":"bytes"}],"name":"fulfillRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isActiveProver","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isPauser","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numPausers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numProvers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pauserList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"pausers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"proverStates","outputs":[{"internalType":"enum BrevisAccess.ProverState","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"provers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"}],"name":"queryRequestStatus","outputs":[{"internalType":"enum IBrevisRequest.RequestStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"}],"name":"refund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removePauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"removePausers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_accounts","type":"address[]"}],"name":"removeProvers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renouncePauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requestTimeout","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"requests","outputs":[{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"address","name":"refundee","type":"address"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"enum IBrevisRequest.RequestStatus","name":"status","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"internalType":"address","name":"_refundee","type":"address"},{"internalType":"address","name":"_callback","type":"address"}],"name":"sendRequest","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeCollector","type":"address"}],"name":"setFeeCollector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timeout","type":"uint256"}],"name":"setRequestTimeout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

608034620001c8576200213b90601f38839003908101601f19168201906001600160401b03821183831017620001cd5780839160409586948552833981010312620001c85780516001600160a01b039182821691829003620001c85760208091015192808416809403620001c85760009081549360018060a01b031994338682161784558751923391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08580a3600180546001600160a81b031916919091179055338252600283528582205460ff1662000186575060035468010000000000000000811015620001725760018101806003558110156200015e5781869160037f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f89594528382200133868254161790553381526002835220600160ff198254161790558451338152a1600754161760075551611f579081620001e48239f35b634e487b7160e01b82526032600452602482fd5b634e487b7160e01b82526041600452602482fd5b62461bcd60e51b815260048101839052601960248201527f4163636f756e7420697320616c726561647920706175736572000000000000006044820152606490fd5b600080fd5b634e487b7160e01b600052604160045260246000fdfe6080604052600436101561001b575b361561001957600080fd5b005b6000803560e01c8063158535ff146116345780633f20b4c9146116165780633f4ba83a1461152c57806346fbf68e14610d535780634f4fef181461150e57806358a16b44146114f05780635c975abb146114ca578063622b6af414611467578063677625f2146112da5780636a9617351461102a5780636b2c0f5514610ff35780636ef8d66d14610fd95780637249fbb614610e555780637ff7b0d214610d9057806380f51c1214610d5357806382dc1ec414610d195780638456cb5914610c0a5780638da5cb5b14610be45780639d86698514610b76578063a036e79914610b26578063a42dce8014610aa0578063b6979c3e14610a68578063c415b95c14610a41578063c7f5aaa014610a1a578063da47dc3214610809578063e6c6fcec146107b9578063e79b7a5114610760578063ec64842e14610719578063ecdafd46146102f9578063f2fde38b14610210578063fabc74f5146101cc5763fd1190ea14610187575061000e565b346101c95760203660031901126101c957600435906005548210156101c95760206001600160a01b036101b9846116c4565b9190546040519260031b1c168152f35b80fd5b50346101c95760203660031901126101c95760ff60406020926001600160a01b036101f56116fb565b168152600484522054166040519061020c81611823565b8152f35b50346101c95760203660031901126101c95761022a6116fb565b8154906001600160a01b0380831691610244338414611874565b1691821561028e5773ffffffffffffffffffffffffffffffffffffffff1916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608490fd5b50346101c95760c03660031901126101c95760043567ffffffffffffffff811681036107155760243567ffffffffffffffff81116107115761033f903690600401611843565b918360443567ffffffffffffffff8111610715576103619036906004016117f5565b919067ffffffffffffffff60643511610715573660236064350112156107155767ffffffffffffffff60643560040135116107155736602460a060643560040135026064350101116107155760843567ffffffffffffffff8111610711576103cd903690600401611843565b9290936001600160a01b0360a4351660a43503610715573382526004602052610408600160ff60408520541661040281611823565b14611d87565b6001600160a01b0360075416803b156107115767ffffffffffffffff838861046d8b978d9661045b6040519a8b998a988997633ab58d6f60e21b8952166004880152606060248801526064870191611e98565b84810360031901604486015291611e37565b03925af18015610706576106d6575b5060015b8560ff82161061068357507fc9f9dbb4a40f26672580c28841452a59f824f5c0053e412183cfec77e76570ef60405160208152806104c2602082018989611e98565b0390a16001600160a01b0360a435166104d9578580f35b85916040519363ed1fe83b60e01b602086015267ffffffffffffffff60848601911660248601526060604486015260643560040135905260a4840191602460643501845b606435600401358110610642575050602319858403016064860152808352602083019060208160051b850101938386915b8383106105d5575050505050509161057081839403601f19810183528261172c565b6020815191018260a4355af1610584611e58565b5015610592575b8080808580f35b7fa27ac73d985dc053bec967c59a530feb90be0582343095d7b85ec7e7c3fef208916105cb604051928392602084526020840191611e98565b0390a1388061058b565b9193959092949650601f198282030186528635601e198436030181121561063e578301906020823592019167ffffffffffffffff811161063a57803603831361063a576106286020928392600195611e37565b98019601930190918a9695949261054e565b8c80fd5b8b80fd5b813585526020808301359086015260408083013590860152606080830135908601526080808301359086015289955060a0948501949091019060010161051d565b611fe08160051b168501358752600860205260036040882001600160a01b60ff60a01b1982541617905560ff808216146106c25760ff16600101610480565b634e487b7160e01b87526011600452602487fd5b67ffffffffffffffff81979297116106f257604052943861047c565b634e487b7160e01b82526041600452602482fd5b6040513d89823e3d90fd5b8280fd5b5080fd5b50346101c95760203660031901126101c95760ff60406020926001600160a01b036107426116fb565b1681526004845220541661075581611823565b600160405191148152f35b50346101c95761076f36611764565b906001600160a01b0391610787838354163314611874565b815b81518110156107b557806107ab856107a46107b094866118e4565b5116611b0d565b6118bf565b610789565b8280f35b50346101c9576107c836611764565b906001600160a01b03916107e0838354163314611874565b815b81518110156107b557806107ab856107fd61080494866118e4565b5116611944565b6107e2565b5060603660031901126101c957600435610821611716565b604435906001600160a01b03808316809303610a16578385526020916008835260408620546109d157811690811561098c576006544201908142116106c2576040519160a0830183811067ffffffffffffffff82111761097857917f4eede03ca33645529b4d82428b024149165298c901cf7453f68eb43bd3d3b6589795939160809795936040528252600384830192348452604081019485526060810194878652898201948c8652898d526008885260408d2092518355516001830155836002830191511673ffffffffffffffffffffffffffffffffffffffff19825416179055019251167fffffffffffffffffffffff00000000000000000000000000000000000000000074ff00000000000000000000000000000000000000008454935161094b81611823565b61095481611823565b60a01b1692161717905560405192835233908301523460408301526060820152a180f35b634e487b7160e01b89526041600452602489fd5b60405162461bcd60e51b815260048101849052601560248201527f726566756e646565206e6f742070726f766964656400000000000000000000006044820152606490fd5b60405162461bcd60e51b815260048101849052601860248201527f7265717565737420616c726561647920696e20717565756500000000000000006044820152606490fd5b8480fd5b50346101c957806003193601126101c95760206001600160a01b0360075416604051908152f35b50346101c957806003193601126101c95760206001600160a01b0360015416604051908152f35b50346101c95760203660031901126101c95760ff6003604060209360043581526008855220015460a01c166040519061020c81611823565b50346101c95760203660031901126101c9577f5d16ad41baeb009cd23eb8f6c7cde5c2e0cd5acf4a33926ab488875c37c37f386040610add6116fb565b6001600160a01b03610af3818654163314611874565b806001549216908173ffffffffffffffffffffffffffffffffffffffff198416176001558351921682526020820152a180f35b50346101c957610b3536611764565b906001600160a01b0391610b4d838354163314611874565b815b81518110156107b557806107ab85610b6a610b7194866118e4565b5116611bf3565b610b4f565b50346101c95760203660031901126101c957604060a09160043581526008602052208054906001810154906001600160a01b03906003826002830154169101549060ff82871c169360405195865260208601526040850152166060830152610bdd81611823565b6080820152f35b50346101c957806003193601126101c9576001600160a01b036020915416604051908152f35b50346101c957806003193601126101c9573381526002602090808252610c3660ff6040852054166118f8565b600191825460ff8160a01c16610cd45760ff60a01b19600160a01b91161783557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25881604051338152a183835b610c8a578480f35b600554811015610cd057806001600160a01b03610ca9610cca936116c4565b90549060031b1c16865260048352604086208460ff198254161790556118bf565b83610c82565b8480f35b60405162461bcd60e51b815260048101839052601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606490fd5b50346101c95760203660031901126101c957610d50610d366116fb565b610d4b6001600160a01b038454163314611874565b611b0d565b80f35b50346101c95760203660031901126101c95760ff60406020926001600160a01b03610d7c6116fb565b168152600284522054166040519015158152f35b50346101c95760403660031901126101c957600435610dad611716565b6001600160a01b039182600154163303610e10577ff10cda68996dfb656d49ab0db3c62cc5f0849710633671a337171c3ad92551869282610e01868080808760409961c350f1610dfb611e58565b50611ed5565b8351928352166020820152a180f35b60405162461bcd60e51b815260206004820152601160248201527f6e6f742066656520636f6c6c6563746f720000000000000000000000000000006044820152606490fd5b50346101c95760208060031936011261071557600435808352600882526040832054421115610711576001600160a01b036024838260075416604051928380926371e8f36b60e11b82528760048301525afa8015610fce57610ebf918691610fa1575b5015611deb565b81845260088352604084205415610f5c5790610f22848080807ffea410cb461deba9fe807dde02d6641d82e1bf09ecc88ecfa0f2ffadf2a1fdfe979686825260088852600160408320918383556002830154169101549061c350f1610dfb611e58565b80845260088252600360408520017402000000000000000000000000000000000000000060ff60a01b19825416179055604051908152a180f35b60405162461bcd60e51b815260048101849052601460248201527f72657175657374206e6f7420696e2071756575650000000000000000000000006044820152606490fd5b610fc19150853d8711610fc7575b610fb9818361172c565b810190611dd3565b38610eb8565b503d610faf565b6040513d87823e3d90fd5b50346101c957806003193601126101c957610d5033611bf3565b50346101c95760203660031901126101c957610d506110106116fb565b6110256001600160a01b038454163314611874565b611bf3565b50346101c95760a03660031901126101c95760043560243567ffffffffffffffff8082168092036112d657604435818111610a165761106d9036906004016117f5565b606493919335928315158094036112a9576084359081116112a9576110969036906004016117f5565b929093338852602095600487526110b9600160ff60408c20541661040281611823565b6001600160a01b03938460075416908a604051956371e8f36b60e11b87528b60048801528a87602481875afa9586156112cb576111028c9761112c9985916112b4575015611deb565b60405197889687958694630979240d60e21b86526004860152606060248601526064850191611e37565b90604483015203925af1908115610706578791611283575b50850361123e57908592918584526008855260036040852001600160a01b60ff60a01b198254161790557f85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e685604051888152a18584526008855260036040852001541690816111b1578380f35b836111e56111f382956040519283918a830196633ceb5b5160e11b88528c6024850152604060448501526064840191611e37565b03601f19810183528261172c565b51925af16111ff611e58565b501561120e575b828180808380f35b7ff9e9ac125efc63eaa0638c58fd8a1ab11673bae30202f01909611e4ebdbe9b4e91604051908152a13880611206565b60405162461bcd60e51b815260048101859052601d60248201527f72657175657374496420616e642070726f6f66206e6f74206d617463680000006044820152606490fd5b90508481813d83116112ad575b61129a818361172c565b810103126112a9575138611144565b8680fd5b503d611290565b610fc19150893d8b11610fc757610fb9818361172c565b6040513d84823e3d90fd5b8380fd5b50346101c9576112e936611764565b6001600160a01b036112ff818454163314611874565b60ff91600192839281845460a01c1660001461145d576002929594955b85965b611327578580f35b8051871015611459578161133b88836118e4565b5116808752602090600482528460408920541661135781611823565b611414576005805490680100000000000000008210156114005792826113cd8a9b9c946113ad856113f9988e7fef1fa0a4d797341645c201a742cf59be633da0589e0e3cda511cfc90cd039684980190556116c4565b90919082549060031b916001600160a01b03809116831b921b1916179055565b808c526004825260408c206113e18a611823565b60ff19815416898b16179055604051908152a16118bf565b969561131f565b634e487b7160e01b8a52604160045260248afd5b60405162461bcd60e51b815260048101839052601160248201527f6163636f756e742069732070726f7665720000000000000000000000000000006044820152606490fd5b8580f35b839295949561131c565b50346101c95760203660031901126101c9577f87a73c061f18ffd513249d1d727921e40e348948b01e2979efb36ef4f5204a6360406004356114b46001600160a01b038554163314611874565b600654908060065582519182526020820152a180f35b50346101c957806003193601126101c957602060ff60015460a01c166040519015158152f35b50346101c957806003193601126101c9576020600354604051908152f35b50346101c957806003193601126101c9576020600554604051908152f35b50346101c957806003193601126101c95733815260206002815261155660ff6040842054166118f8565b600190815460ff8160a01c16156115d1579060ff60a01b1983921682557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa81604051338152a183915b6115a7578380f35b6005548210156115cd576115c7826001600160a01b03610ca986956116c4565b9161159f565b8380f35b60405162461bcd60e51b815260048101839052601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606490fd5b50346101c957806003193601126101c9576020600654604051908152f35b50346101c95760203660031901126101c957600435906003548210156101c95760206001600160a01b0361166784611677565b90549060031b1c16604051908152f35b6003548110156116ae5760036000527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0190600090565b634e487b7160e01b600052603260045260246000fd5b6005548110156116ae5760056000527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00190600090565b600435906001600160a01b038216820361171157565b600080fd5b602435906001600160a01b038216820361171157565b90601f8019910116810190811067ffffffffffffffff82111761174e57604052565b634e487b7160e01b600052604160045260246000fd5b6020806003198301126117115767ffffffffffffffff91600435838111611711578160238201121561171157806004013593841161174e578360051b90604051946117b18584018761172c565b855260248486019282010192831161171157602401905b8282106117d6575050505090565b81356001600160a01b03811681036117115781529083019083016117c8565b9181601f840112156117115782359167ffffffffffffffff8311611711576020838186019501011161171157565b6003111561182d57565b634e487b7160e01b600052602160045260246000fd5b9181601f840112156117115782359167ffffffffffffffff8311611711576020808501948460051b01011161171157565b1561187b57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b60001981146118ce5760010190565b634e487b7160e01b600052601160045260246000fd5b80518210156116ae5760209160051b010190565b156118ff57565b60405162461bcd60e51b815260206004820152601460248201527f43616c6c6572206973206e6f74207061757365720000000000000000000000006044820152606490fd5b6001600160a01b0380911691600083815260049360209185835260409060ff828220541661197181611823565b15611aca57600580546000198082019890918911611ab757835b8354811015611a7457818761199f836116c4565b929054600393841b1c16146119bd57506119b8906118bf565b61198b565b92939495969798999091818310611a4f575b5050505081548015611a3c57917fd64d11086d859b73cf85a91ca06cbc484398acabe3d9a1b26d4366dff377d9859798918594930190611a26611a11836116c4565b6001600160a01b0382549160031b1b19169055565b55848252855220805460ff1916905551908152a1565b634e487b7160e01b845260318952602484fd5b611a6b93611a5f6113ad936116c4565b9054911b1c16916116c4565b388080806119cf565b855162461bcd60e51b8152808c01899052601060248201527f70726f766572206e6f7420666f756e64000000000000000000000000000000006044820152606490fd5b634e487b7160e01b845260118a52602484fd5b815162461bcd60e51b8152808801859052601560248201527f6163636f756e74206973206e6f742070726f76657200000000000000000000006044820152606490fd5b6001600160a01b03811690600090828252600260205260ff604083205416611bae5760035468010000000000000000811015611b9a57602092611b7e7f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f895936113ad84600160409601600355611677565b8281526002845220805460ff19166001179055604051908152a1565b634e487b7160e01b83526041600452602483fd5b60405162461bcd60e51b815260206004820152601960248201527f4163636f756e7420697320616c726561647920706175736572000000000000006044820152606490fd5b6001600160a01b038091169160009280845260029060209180835260409060ff828820541615611d4357600380546000198082019890918911611d2f57895b8354811015611ceb578682611c4683611677565b905490871b1c1614611c6057611c5b906118bf565b611c32565b909192939495969798808210611cc6575b50505081548015611cb257918493917fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e9899930190611a26611a1183611677565b634e487b7160e01b89526031600452602489fd5b611ce392611cd66113ad92611677565b905490871b1c1691611677565b388080611c71565b855162461bcd60e51b815260048101899052601060248201527f706175736572206e6f7420666f756e64000000000000000000000000000000006044820152606490fd5b634e487b7160e01b8a52601160045260248afd5b815162461bcd60e51b815260048101859052601560248201527f4163636f756e74206973206e6f742070617573657200000000000000000000006044820152606490fd5b15611d8e57565b60405162461bcd60e51b815260206004820152600e60248201527f696e76616c69642070726f7665720000000000000000000000000000000000006044820152606490fd5b90816020910312611711575180151581036117115790565b15611df257565b60405162461bcd60e51b815260206004820152601760248201527f70726f6f6620616c72656164792067656e6572617465640000000000000000006044820152606490fd5b908060209392818452848401376000828201840152601f01601f1916010190565b3d15611e93573d9067ffffffffffffffff821161174e5760405191611e87601f8201601f19166020018461172c565b82523d6000602084013e565b606090565b90918281527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83116117115760209260051b809284830137010190565b15611edc57565b60405162461bcd60e51b815260206004820152601260248201527f73656e64206e6174697665206661696c656400000000000000000000000000006044820152606490fdfea2646970667358221220cb83371e4bb2cab2b0e264d087b92078b9f5b7d9f693e1eec474f2a7597f0ca864736f6c6343000814003300000000000000000000000058b529f9084d7eaa598eb3477fe36064c5b7bbc10000000000000000000000006cd95817f275bdf5c9cc401cbccbffd99c7f186a

Deployed Bytecode

0x6080604052600436101561001b575b361561001957600080fd5b005b6000803560e01c8063158535ff146116345780633f20b4c9146116165780633f4ba83a1461152c57806346fbf68e14610d535780634f4fef181461150e57806358a16b44146114f05780635c975abb146114ca578063622b6af414611467578063677625f2146112da5780636a9617351461102a5780636b2c0f5514610ff35780636ef8d66d14610fd95780637249fbb614610e555780637ff7b0d214610d9057806380f51c1214610d5357806382dc1ec414610d195780638456cb5914610c0a5780638da5cb5b14610be45780639d86698514610b76578063a036e79914610b26578063a42dce8014610aa0578063b6979c3e14610a68578063c415b95c14610a41578063c7f5aaa014610a1a578063da47dc3214610809578063e6c6fcec146107b9578063e79b7a5114610760578063ec64842e14610719578063ecdafd46146102f9578063f2fde38b14610210578063fabc74f5146101cc5763fd1190ea14610187575061000e565b346101c95760203660031901126101c957600435906005548210156101c95760206001600160a01b036101b9846116c4565b9190546040519260031b1c168152f35b80fd5b50346101c95760203660031901126101c95760ff60406020926001600160a01b036101f56116fb565b168152600484522054166040519061020c81611823565b8152f35b50346101c95760203660031901126101c95761022a6116fb565b8154906001600160a01b0380831691610244338414611874565b1691821561028e5773ffffffffffffffffffffffffffffffffffffffff1916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608490fd5b50346101c95760c03660031901126101c95760043567ffffffffffffffff811681036107155760243567ffffffffffffffff81116107115761033f903690600401611843565b918360443567ffffffffffffffff8111610715576103619036906004016117f5565b919067ffffffffffffffff60643511610715573660236064350112156107155767ffffffffffffffff60643560040135116107155736602460a060643560040135026064350101116107155760843567ffffffffffffffff8111610711576103cd903690600401611843565b9290936001600160a01b0360a4351660a43503610715573382526004602052610408600160ff60408520541661040281611823565b14611d87565b6001600160a01b0360075416803b156107115767ffffffffffffffff838861046d8b978d9661045b6040519a8b998a988997633ab58d6f60e21b8952166004880152606060248801526064870191611e98565b84810360031901604486015291611e37565b03925af18015610706576106d6575b5060015b8560ff82161061068357507fc9f9dbb4a40f26672580c28841452a59f824f5c0053e412183cfec77e76570ef60405160208152806104c2602082018989611e98565b0390a16001600160a01b0360a435166104d9578580f35b85916040519363ed1fe83b60e01b602086015267ffffffffffffffff60848601911660248601526060604486015260643560040135905260a4840191602460643501845b606435600401358110610642575050602319858403016064860152808352602083019060208160051b850101938386915b8383106105d5575050505050509161057081839403601f19810183528261172c565b6020815191018260a4355af1610584611e58565b5015610592575b8080808580f35b7fa27ac73d985dc053bec967c59a530feb90be0582343095d7b85ec7e7c3fef208916105cb604051928392602084526020840191611e98565b0390a1388061058b565b9193959092949650601f198282030186528635601e198436030181121561063e578301906020823592019167ffffffffffffffff811161063a57803603831361063a576106286020928392600195611e37565b98019601930190918a9695949261054e565b8c80fd5b8b80fd5b813585526020808301359086015260408083013590860152606080830135908601526080808301359086015289955060a0948501949091019060010161051d565b611fe08160051b168501358752600860205260036040882001600160a01b60ff60a01b1982541617905560ff808216146106c25760ff16600101610480565b634e487b7160e01b87526011600452602487fd5b67ffffffffffffffff81979297116106f257604052943861047c565b634e487b7160e01b82526041600452602482fd5b6040513d89823e3d90fd5b8280fd5b5080fd5b50346101c95760203660031901126101c95760ff60406020926001600160a01b036107426116fb565b1681526004845220541661075581611823565b600160405191148152f35b50346101c95761076f36611764565b906001600160a01b0391610787838354163314611874565b815b81518110156107b557806107ab856107a46107b094866118e4565b5116611b0d565b6118bf565b610789565b8280f35b50346101c9576107c836611764565b906001600160a01b03916107e0838354163314611874565b815b81518110156107b557806107ab856107fd61080494866118e4565b5116611944565b6107e2565b5060603660031901126101c957600435610821611716565b604435906001600160a01b03808316809303610a16578385526020916008835260408620546109d157811690811561098c576006544201908142116106c2576040519160a0830183811067ffffffffffffffff82111761097857917f4eede03ca33645529b4d82428b024149165298c901cf7453f68eb43bd3d3b6589795939160809795936040528252600384830192348452604081019485526060810194878652898201948c8652898d526008885260408d2092518355516001830155836002830191511673ffffffffffffffffffffffffffffffffffffffff19825416179055019251167fffffffffffffffffffffff00000000000000000000000000000000000000000074ff00000000000000000000000000000000000000008454935161094b81611823565b61095481611823565b60a01b1692161717905560405192835233908301523460408301526060820152a180f35b634e487b7160e01b89526041600452602489fd5b60405162461bcd60e51b815260048101849052601560248201527f726566756e646565206e6f742070726f766964656400000000000000000000006044820152606490fd5b60405162461bcd60e51b815260048101849052601860248201527f7265717565737420616c726561647920696e20717565756500000000000000006044820152606490fd5b8480fd5b50346101c957806003193601126101c95760206001600160a01b0360075416604051908152f35b50346101c957806003193601126101c95760206001600160a01b0360015416604051908152f35b50346101c95760203660031901126101c95760ff6003604060209360043581526008855220015460a01c166040519061020c81611823565b50346101c95760203660031901126101c9577f5d16ad41baeb009cd23eb8f6c7cde5c2e0cd5acf4a33926ab488875c37c37f386040610add6116fb565b6001600160a01b03610af3818654163314611874565b806001549216908173ffffffffffffffffffffffffffffffffffffffff198416176001558351921682526020820152a180f35b50346101c957610b3536611764565b906001600160a01b0391610b4d838354163314611874565b815b81518110156107b557806107ab85610b6a610b7194866118e4565b5116611bf3565b610b4f565b50346101c95760203660031901126101c957604060a09160043581526008602052208054906001810154906001600160a01b03906003826002830154169101549060ff82871c169360405195865260208601526040850152166060830152610bdd81611823565b6080820152f35b50346101c957806003193601126101c9576001600160a01b036020915416604051908152f35b50346101c957806003193601126101c9573381526002602090808252610c3660ff6040852054166118f8565b600191825460ff8160a01c16610cd45760ff60a01b19600160a01b91161783557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25881604051338152a183835b610c8a578480f35b600554811015610cd057806001600160a01b03610ca9610cca936116c4565b90549060031b1c16865260048352604086208460ff198254161790556118bf565b83610c82565b8480f35b60405162461bcd60e51b815260048101839052601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606490fd5b50346101c95760203660031901126101c957610d50610d366116fb565b610d4b6001600160a01b038454163314611874565b611b0d565b80f35b50346101c95760203660031901126101c95760ff60406020926001600160a01b03610d7c6116fb565b168152600284522054166040519015158152f35b50346101c95760403660031901126101c957600435610dad611716565b6001600160a01b039182600154163303610e10577ff10cda68996dfb656d49ab0db3c62cc5f0849710633671a337171c3ad92551869282610e01868080808760409961c350f1610dfb611e58565b50611ed5565b8351928352166020820152a180f35b60405162461bcd60e51b815260206004820152601160248201527f6e6f742066656520636f6c6c6563746f720000000000000000000000000000006044820152606490fd5b50346101c95760208060031936011261071557600435808352600882526040832054421115610711576001600160a01b036024838260075416604051928380926371e8f36b60e11b82528760048301525afa8015610fce57610ebf918691610fa1575b5015611deb565b81845260088352604084205415610f5c5790610f22848080807ffea410cb461deba9fe807dde02d6641d82e1bf09ecc88ecfa0f2ffadf2a1fdfe979686825260088852600160408320918383556002830154169101549061c350f1610dfb611e58565b80845260088252600360408520017402000000000000000000000000000000000000000060ff60a01b19825416179055604051908152a180f35b60405162461bcd60e51b815260048101849052601460248201527f72657175657374206e6f7420696e2071756575650000000000000000000000006044820152606490fd5b610fc19150853d8711610fc7575b610fb9818361172c565b810190611dd3565b38610eb8565b503d610faf565b6040513d87823e3d90fd5b50346101c957806003193601126101c957610d5033611bf3565b50346101c95760203660031901126101c957610d506110106116fb565b6110256001600160a01b038454163314611874565b611bf3565b50346101c95760a03660031901126101c95760043560243567ffffffffffffffff8082168092036112d657604435818111610a165761106d9036906004016117f5565b606493919335928315158094036112a9576084359081116112a9576110969036906004016117f5565b929093338852602095600487526110b9600160ff60408c20541661040281611823565b6001600160a01b03938460075416908a604051956371e8f36b60e11b87528b60048801528a87602481875afa9586156112cb576111028c9761112c9985916112b4575015611deb565b60405197889687958694630979240d60e21b86526004860152606060248601526064850191611e37565b90604483015203925af1908115610706578791611283575b50850361123e57908592918584526008855260036040852001600160a01b60ff60a01b198254161790557f85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e685604051888152a18584526008855260036040852001541690816111b1578380f35b836111e56111f382956040519283918a830196633ceb5b5160e11b88528c6024850152604060448501526064840191611e37565b03601f19810183528261172c565b51925af16111ff611e58565b501561120e575b828180808380f35b7ff9e9ac125efc63eaa0638c58fd8a1ab11673bae30202f01909611e4ebdbe9b4e91604051908152a13880611206565b60405162461bcd60e51b815260048101859052601d60248201527f72657175657374496420616e642070726f6f66206e6f74206d617463680000006044820152606490fd5b90508481813d83116112ad575b61129a818361172c565b810103126112a9575138611144565b8680fd5b503d611290565b610fc19150893d8b11610fc757610fb9818361172c565b6040513d84823e3d90fd5b8380fd5b50346101c9576112e936611764565b6001600160a01b036112ff818454163314611874565b60ff91600192839281845460a01c1660001461145d576002929594955b85965b611327578580f35b8051871015611459578161133b88836118e4565b5116808752602090600482528460408920541661135781611823565b611414576005805490680100000000000000008210156114005792826113cd8a9b9c946113ad856113f9988e7fef1fa0a4d797341645c201a742cf59be633da0589e0e3cda511cfc90cd039684980190556116c4565b90919082549060031b916001600160a01b03809116831b921b1916179055565b808c526004825260408c206113e18a611823565b60ff19815416898b16179055604051908152a16118bf565b969561131f565b634e487b7160e01b8a52604160045260248afd5b60405162461bcd60e51b815260048101839052601160248201527f6163636f756e742069732070726f7665720000000000000000000000000000006044820152606490fd5b8580f35b839295949561131c565b50346101c95760203660031901126101c9577f87a73c061f18ffd513249d1d727921e40e348948b01e2979efb36ef4f5204a6360406004356114b46001600160a01b038554163314611874565b600654908060065582519182526020820152a180f35b50346101c957806003193601126101c957602060ff60015460a01c166040519015158152f35b50346101c957806003193601126101c9576020600354604051908152f35b50346101c957806003193601126101c9576020600554604051908152f35b50346101c957806003193601126101c95733815260206002815261155660ff6040842054166118f8565b600190815460ff8160a01c16156115d1579060ff60a01b1983921682557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa81604051338152a183915b6115a7578380f35b6005548210156115cd576115c7826001600160a01b03610ca986956116c4565b9161159f565b8380f35b60405162461bcd60e51b815260048101839052601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606490fd5b50346101c957806003193601126101c9576020600654604051908152f35b50346101c95760203660031901126101c957600435906003548210156101c95760206001600160a01b0361166784611677565b90549060031b1c16604051908152f35b6003548110156116ae5760036000527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0190600090565b634e487b7160e01b600052603260045260246000fd5b6005548110156116ae5760056000527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00190600090565b600435906001600160a01b038216820361171157565b600080fd5b602435906001600160a01b038216820361171157565b90601f8019910116810190811067ffffffffffffffff82111761174e57604052565b634e487b7160e01b600052604160045260246000fd5b6020806003198301126117115767ffffffffffffffff91600435838111611711578160238201121561171157806004013593841161174e578360051b90604051946117b18584018761172c565b855260248486019282010192831161171157602401905b8282106117d6575050505090565b81356001600160a01b03811681036117115781529083019083016117c8565b9181601f840112156117115782359167ffffffffffffffff8311611711576020838186019501011161171157565b6003111561182d57565b634e487b7160e01b600052602160045260246000fd5b9181601f840112156117115782359167ffffffffffffffff8311611711576020808501948460051b01011161171157565b1561187b57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b60001981146118ce5760010190565b634e487b7160e01b600052601160045260246000fd5b80518210156116ae5760209160051b010190565b156118ff57565b60405162461bcd60e51b815260206004820152601460248201527f43616c6c6572206973206e6f74207061757365720000000000000000000000006044820152606490fd5b6001600160a01b0380911691600083815260049360209185835260409060ff828220541661197181611823565b15611aca57600580546000198082019890918911611ab757835b8354811015611a7457818761199f836116c4565b929054600393841b1c16146119bd57506119b8906118bf565b61198b565b92939495969798999091818310611a4f575b5050505081548015611a3c57917fd64d11086d859b73cf85a91ca06cbc484398acabe3d9a1b26d4366dff377d9859798918594930190611a26611a11836116c4565b6001600160a01b0382549160031b1b19169055565b55848252855220805460ff1916905551908152a1565b634e487b7160e01b845260318952602484fd5b611a6b93611a5f6113ad936116c4565b9054911b1c16916116c4565b388080806119cf565b855162461bcd60e51b8152808c01899052601060248201527f70726f766572206e6f7420666f756e64000000000000000000000000000000006044820152606490fd5b634e487b7160e01b845260118a52602484fd5b815162461bcd60e51b8152808801859052601560248201527f6163636f756e74206973206e6f742070726f76657200000000000000000000006044820152606490fd5b6001600160a01b03811690600090828252600260205260ff604083205416611bae5760035468010000000000000000811015611b9a57602092611b7e7f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f895936113ad84600160409601600355611677565b8281526002845220805460ff19166001179055604051908152a1565b634e487b7160e01b83526041600452602483fd5b60405162461bcd60e51b815260206004820152601960248201527f4163636f756e7420697320616c726561647920706175736572000000000000006044820152606490fd5b6001600160a01b038091169160009280845260029060209180835260409060ff828820541615611d4357600380546000198082019890918911611d2f57895b8354811015611ceb578682611c4683611677565b905490871b1c1614611c6057611c5b906118bf565b611c32565b909192939495969798808210611cc6575b50505081548015611cb257918493917fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e9899930190611a26611a1183611677565b634e487b7160e01b89526031600452602489fd5b611ce392611cd66113ad92611677565b905490871b1c1691611677565b388080611c71565b855162461bcd60e51b815260048101899052601060248201527f706175736572206e6f7420666f756e64000000000000000000000000000000006044820152606490fd5b634e487b7160e01b8a52601160045260248afd5b815162461bcd60e51b815260048101859052601560248201527f4163636f756e74206973206e6f742070617573657200000000000000000000006044820152606490fd5b15611d8e57565b60405162461bcd60e51b815260206004820152600e60248201527f696e76616c69642070726f7665720000000000000000000000000000000000006044820152606490fd5b90816020910312611711575180151581036117115790565b15611df257565b60405162461bcd60e51b815260206004820152601760248201527f70726f6f6620616c72656164792067656e6572617465640000000000000000006044820152606490fd5b908060209392818452848401376000828201840152601f01601f1916010190565b3d15611e93573d9067ffffffffffffffff821161174e5760405191611e87601f8201601f19166020018461172c565b82523d6000602084013e565b606090565b90918281527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83116117115760209260051b809284830137010190565b15611edc57565b60405162461bcd60e51b815260206004820152601260248201527f73656e64206e6174697665206661696c656400000000000000000000000000006044820152606490fdfea2646970667358221220cb83371e4bb2cab2b0e264d087b92078b9f5b7d9f693e1eec474f2a7597f0ca864736f6c63430008140033

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

00000000000000000000000058b529f9084d7eaa598eb3477fe36064c5b7bbc10000000000000000000000006cd95817f275bdf5c9cc401cbccbffd99c7f186a

-----Decoded View---------------
Arg [0] : _feeCollector (address): 0x58b529F9084D7eAA598EB3477Fe36064C5B7bbC1
Arg [1] : _brevisProof (address): 0x6CD95817F275bDf5C9cC401CbCcbFfd99c7f186A

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000058b529f9084d7eaa598eb3477fe36064c5b7bbc1
Arg [1] : 0000000000000000000000006cd95817f275bdf5c9cc401cbccbffd99c7f186a


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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