S Price: $0.068131 (+1.25%)
Gas: 55 Gwei

Contract

0x81707a5Ce2139dF7f7D768b4D581FD82bd800609

Overview

S Balance

Sonic LogoSonic LogoSonic Logo0 S

S Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To
Set Bounds430080912025-08-14 15:57:01165 days ago1755187021IN
0x81707a5C...2bd800609
0 S0.0022802155.01
Update403699562025-07-26 22:39:02184 days ago1753569542IN
0x81707a5C...2bd800609
0 S0.0189663557.12
Set Bounds403698462025-07-26 22:37:45184 days ago1753569465IN
0x81707a5C...2bd800609
0 S0.002131355.34
Update402217892025-07-25 20:45:18185 days ago1753476318IN
0x81707a5C...2bd800609
0 S0.0133427255
Set Bounds402217662025-07-25 20:45:06185 days ago1753476306IN
0x81707a5C...2bd800609
0 S0.0022795555.01

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
RZRTWAPOracle

Compiler Version
v0.8.28+commit.7893614a

Optimization Enabled:
Yes with 2000 runs

Other Settings:
paris EvmVersion
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;

import "../../interfaces/IAggregatorV3.sol";
import "../../interfaces/IOracle.sol";
import "../../core/AppAccessControlled.sol";

/**
 * @title RZRTWAPOracle
 * @notice Chainlink-compatible oracle that implements a 1-hour TWAP with 5-minute update intervals
 * @dev Uses a circular buffer to store price observations and calculate TWAP
 * @dev Only executable by authorized executors
 */
contract RZRTWAPOracle is IAggregatorV3, AppAccessControlled {
    struct Observation {
        uint256 timestamp;
        int256 price;
    }

    struct RoundData {
        uint80 roundId;
        int256 answer;
        uint256 startedAt;
        uint256 updatedAt;
        uint80 answeredInRound;
    }

    mapping(uint80 => RoundData) public roundData;

    IOracle public oracle;
    uint256 public constant WINDOW_SIZE = 2 hours;
    uint256 public constant UPDATE_INTERVAL = 5 minutes;
    uint256 public constant MAX_OBSERVATIONS = 24; // 2 hours / 5 minutes = 24 observations

    uint256 public upperBound;
    uint256 public lowerBound;

    Observation[] public observations;
    uint256 public currentIndex;
    uint256 public lastUpdateTime;

    event ObservationAdded(uint256 timestamp, int256 price);

    /**
     * @notice Constructor
     * @param _oracle The oracle to use for price data
     * @param _authority The authority contract for access control
     */
    constructor(IOracle _oracle, address _authority, uint256 _upperBound, uint256 _lowerBound) {
        require(address(_oracle) != address(0), "Invalid oracle address");
        require(address(_authority) != address(0), "Invalid authority address");

        __AppAccessControlled_init(_authority);

        oracle = _oracle;
        upperBound = _upperBound;
        lowerBound = _lowerBound;

        // Initialize with first observation
        int256 initialPrice = int256(_oracle.getPrice());
        observations.push(Observation({timestamp: block.timestamp, price: initialPrice}));
        lastUpdateTime = block.timestamp;

        emit ObservationAdded(block.timestamp, initialPrice);
    }

    function setBounds(uint256 _upperBound, uint256 _lowerBound) external onlyExecutor {
        require(_upperBound > _lowerBound, "Invalid bounds");
        upperBound = _upperBound;
        lowerBound = _lowerBound;
    }

    /**
     * @notice Updates the price observation
     * @dev Can only be called by authorized executors every 30 minutes
     */
    function update() external onlyExecutor {
        require(block.timestamp >= lastUpdateTime + UPDATE_INTERVAL, "Too early to update");

        int256 price = int256(oracle.getPrice());
        require(price > 0, "Invalid price");

        if (observations.length < MAX_OBSERVATIONS) {
            observations.push(Observation({timestamp: block.timestamp, price: price}));
        } else {
            currentIndex = (currentIndex + 1) % MAX_OBSERVATIONS;
            observations[currentIndex] = Observation({timestamp: block.timestamp, price: price});
        }

        lastUpdateTime = block.timestamp;

        // record round data
        int256 twap = getTwap();
        require(twap > int256(lowerBound) && twap < int256(upperBound), "TWAP out of bounds");
        roundData[uint80(block.timestamp)] = RoundData({
            roundId: uint80(block.timestamp),
            answer: twap / 1e10,
            startedAt: block.timestamp,
            updatedAt: block.timestamp,
            answeredInRound: uint80(block.timestamp)
        });

        emit ObservationAdded(block.timestamp, twap);
    }

    /**
     * @notice Returns an observation
     * @param _index The index of the observation
     * @return obs The observation
     */
    function getObservation(uint256 _index) external view returns (Observation memory) {
        require(_index < observations.length, "Index out of bounds");
        return observations[_index];
    }

    /**
     * @notice Calculates the TWAP over the 4-hour window
     * @return twap The time-weighted average price
     */
    function getTwap() public view returns (int256 twap) {
        require(observations.length > 0, "No observations");

        uint256 endTime = block.timestamp;
        uint256 startTime = endTime - WINDOW_SIZE;

        uint256 totalTime = 0;
        int256 weightedSum = 0;

        for (uint256 i = 0; i < observations.length; i++) {
            Observation memory obs = observations[i];

            if (obs.timestamp >= startTime) {
                uint256 timeWeight = obs.timestamp - startTime;
                weightedSum += obs.price * int256(timeWeight);
                totalTime += timeWeight;
            }
        }

        require(totalTime > 0, "No observations in window");
        twap = weightedSum / int256(totalTime);
    }

    // IAggregatorV3 Interface Implementation

    /**
     * @notice Returns the number of decimals used to get its user representation
     */
    function decimals() external pure override returns (uint8) {
        return 8;
    }

    /**
     * @notice Returns the description of the oracle
     */
    function description() external pure override returns (string memory) {
        return "";
    }

    /**
     * @notice Returns the version of the oracle
     */
    function version() external pure override returns (uint256) {
        return 1;
    }

    /**
     * @notice Returns the latest answer (TWAP price)
     */
    function latestAnswer() external view override returns (int256) {
        return roundData[uint80(lastUpdateTime)].answer;
    }

    /**
     * @notice Returns the latest round data
     * @dev Returns the TWAP as the answer with current timestamp
     */
    function latestRoundData()
        external
        view
        override
        returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
    {
        RoundData memory round = roundData[uint80(lastUpdateTime)];
        return (round.roundId, round.answer, round.startedAt, round.updatedAt, round.answeredInRound);
    }

    /**
     * @notice Returns round data for a specific round
     * @dev For this implementation, returns the same as latestRoundData
     * @param _roundId The round ID (unused in this implementation)
     */
    function getRoundData(uint80 _roundId)
        external
        view
        override
        returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
    {
        RoundData memory round = roundData[_roundId];
        return (
            _roundId, // roundId
            round.answer, // answer
            round.startedAt, // startedAt
            round.updatedAt, // updatedAt
            _roundId // answeredInRound
        );
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (proxy/utils/Initializable.sol)

pragma solidity ^0.8.20;

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
 * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
 * case an upgrade adds a module that needs to be initialized.
 *
 * For example:
 *
 * [.hljs-theme-light.nopadding]
 * ```solidity
 * contract MyToken is ERC20Upgradeable {
 *     function initialize() initializer public {
 *         __ERC20_init("MyToken", "MTK");
 *     }
 * }
 *
 * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
 *     function initializeV2() reinitializer(2) public {
 *         __ERC20Permit_init("MyToken");
 *     }
 * }
 * ```
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
 * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() {
 *     _disableInitializers();
 * }
 * ```
 * ====
 */
abstract contract Initializable {
    /**
     * @dev Storage of the initializable contract.
     *
     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
     * when using with upgradeable contracts.
     *
     * @custom:storage-location erc7201:openzeppelin.storage.Initializable
     */
    struct InitializableStorage {
        /**
         * @dev Indicates that the contract has been initialized.
         */
        uint64 _initialized;
        /**
         * @dev Indicates that the contract is in the process of being initialized.
         */
        bool _initializing;
    }

    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;

    /**
     * @dev The contract is already initialized.
     */
    error InvalidInitialization();

    /**
     * @dev The contract is not initializing.
     */
    error NotInitializing();

    /**
     * @dev Triggered when the contract has been initialized or reinitialized.
     */
    event Initialized(uint64 version);

    /**
     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
     * `onlyInitializing` functions can be used to initialize parent contracts.
     *
     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
     * production.
     *
     * Emits an {Initialized} event.
     */
    modifier initializer() {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        // Cache values to avoid duplicated sloads
        bool isTopLevelCall = !$._initializing;
        uint64 initialized = $._initialized;

        // Allowed calls:
        // - initialSetup: the contract is not in the initializing state and no previous version was
        //                 initialized
        // - construction: the contract is initialized at version 1 (no reinitialization) and the
        //                 current contract is just being deployed
        bool initialSetup = initialized == 0 && isTopLevelCall;
        bool construction = initialized == 1 && address(this).code.length == 0;

        if (!initialSetup && !construction) {
            revert InvalidInitialization();
        }
        $._initialized = 1;
        if (isTopLevelCall) {
            $._initializing = true;
        }
        _;
        if (isTopLevelCall) {
            $._initializing = false;
            emit Initialized(1);
        }
    }

    /**
     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
     * used to initialize parent contracts.
     *
     * A reinitializer may be used after the original initialization step. This is essential to configure modules that
     * are added through upgrades and that require initialization.
     *
     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
     * cannot be nested. If one is invoked in the context of another, execution will revert.
     *
     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
     * a contract, executing them in the right order is up to the developer or operator.
     *
     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
     *
     * Emits an {Initialized} event.
     */
    modifier reinitializer(uint64 version) {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        if ($._initializing || $._initialized >= version) {
            revert InvalidInitialization();
        }
        $._initialized = version;
        $._initializing = true;
        _;
        $._initializing = false;
        emit Initialized(version);
    }

    /**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} and {reinitializer} modifiers, directly or indirectly.
     */
    modifier onlyInitializing() {
        _checkInitializing();
        _;
    }

    /**
     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
     */
    function _checkInitializing() internal view virtual {
        if (!_isInitializing()) {
            revert NotInitializing();
        }
    }

    /**
     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
     * through proxies.
     *
     * Emits an {Initialized} event the first time it is successfully executed.
     */
    function _disableInitializers() internal virtual {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        if ($._initializing) {
            revert InvalidInitialization();
        }
        if ($._initialized != type(uint64).max) {
            $._initialized = type(uint64).max;
            emit Initialized(type(uint64).max);
        }
    }

    /**
     * @dev Returns the highest version that has been initialized. See {reinitializer}.
     */
    function _getInitializedVersion() internal view returns (uint64) {
        return _getInitializableStorage()._initialized;
    }

    /**
     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
     */
    function _isInitializing() internal view returns (bool) {
        return _getInitializableStorage()._initializing;
    }

    /**
     * @dev Pointer to storage slot. Allows integrators to override it with a custom storage location.
     *
     * NOTE: Consider following the ERC-7201 formula to derive storage locations.
     */
    function _initializableStorageSlot() internal pure virtual returns (bytes32) {
        return INITIALIZABLE_STORAGE;
    }

    /**
     * @dev Returns a pointer to the storage namespace.
     */
    // solhint-disable-next-line var-name-mixedcase
    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
        bytes32 slot = _initializableStorageSlot();
        assembly {
            $.slot := slot
        }
    }
}

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

pragma solidity ^0.8.20;

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

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

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

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

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

pragma solidity ^0.8.20;

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

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

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

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

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

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

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

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

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.28;

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "../interfaces/IAppAuthority.sol";

interface ISonicFeeMRegistry {
    function selfRegister(uint256 projectID) external;
}

/// @title AppAccessControlled
/// @notice This contract is used to control access to the App contract
abstract contract AppAccessControlled is Initializable {
    /// @notice Event emitted when the authority is updated
    /// @param authority The new authority
    event AuthorityUpdated(IAppAuthority indexed authority);

    /// @notice The authority contract
    IAppAuthority public authority;

    /// @notice Initializes the AppAccessControlled contract
    /// @dev This function is only callable once
    /// @param _authority The address of the authority contract
    function __AppAccessControlled_init(address _authority) internal {
        _setAuthority(IAppAuthority(_authority));
    }

    /// @notice Modifier to check if the caller is a governor
    /// @dev This modifier is only callable by the governor
    modifier onlyGovernor() {
        require(authority.isGovernor(msg.sender), "UNAUTHORIZED");
        _;
    }

    /// @notice Modifier to check if the caller is a guardian or governor
    /// @dev This modifier is only callable by the guardian or governor
    modifier onlyGuardianOrGovernor() {
        require(authority.isGuardian(msg.sender) || authority.isGovernor(msg.sender), "UNAUTHORIZED");
        _;
    }

    /// @notice Modifier to check if the caller is a reserve manager
    /// @dev This modifier is only callable by the reserve manager
    modifier onlyReserveManager() {
        require(authority.isReserveManager(msg.sender), "UNAUTHORIZED");
        _;
    }

    /// @notice Modifier to check if the caller is a reserve depositor
    /// @dev This modifier is only callable by the reserve depositor
    modifier onlyReserveDepositor() {
        require(authority.isReserveDepositor(msg.sender), "UNAUTHORIZED");
        _;
    }

    /// @notice Modifier to check if the caller is a guardian
    /// @dev This modifier is only callable by the guardian
    modifier onlyGuardian() {
        require(authority.isGuardian(msg.sender), "UNAUTHORIZED");
        _;
    }

    /// @notice Modifier to check if the caller is a policy
    /// @dev This modifier is only callable by the policy
    modifier onlyPolicy() {
        require(authority.isPolicy(msg.sender), "UNAUTHORIZED");
        _;
    }

    /// @notice Modifier to check if the caller is the treasury
    /// @dev This modifier is only callable by the treasury
    modifier onlyTreasury() {
        require(authority.isTreasury(msg.sender), "UNAUTHORIZED");
        _;
    }

    /// @notice Modifier to check if the caller is an executor
    /// @dev This modifier is only callable by the executor
    modifier onlyExecutor() {
        require(authority.isExecutor(msg.sender), "UNAUTHORIZED");
        _;
    }

    /// @notice Modifier to check if the caller is a bond manager
    /// @dev This modifier is only callable by the bond manager
    modifier onlyBondManager() {
        require(authority.isBondManager(msg.sender), "UNAUTHORIZED");
        _;
    }

    /// @notice Sets the authority for the contract
    /// @dev This function is only callable by the governor
    /// @param _newAuthority The address of the new authority
    function setAuthority(IAppAuthority _newAuthority) external onlyGovernor {
        _setAuthority(_newAuthority);
    }

    /// @notice Sets the authority for the contract
    /// @dev This function is only callable by the governor
    /// @param _newAuthority The address of the new authority
    function _setAuthority(IAppAuthority _newAuthority) internal {
        authority = _newAuthority;
        emit AuthorityUpdated(_newAuthority);
    }

    /// @notice Sets the project ID for the fee registry
    /// @dev This function is only callable by the governor
    /// @param registry The address of the fee registry
    /// @param projectID The project ID to set
    function setFeeMProjectId(address registry, uint256 projectID) external onlyGovernor {
        ISonicFeeMRegistry(registry).selfRegister(projectID);
    }
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;

/**
 * @title IAggregatorV3
 *     @notice Copied directly from chainlink website as standard interface for oracles
 */
interface IAggregatorV3 {
    function decimals() external view returns (uint8);

    function description() external view returns (string memory);

    function version() external view returns (uint256);

    function latestAnswer() external view returns (int256);

    // getRoundData and latestRoundData should both raise "No data present"
    // if they do not have data to report, instead of returning unset values
    // which could be misinterpreted as actual reported values.
    function getRoundData(uint80 _roundId)
        external
        view
        returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);

    function latestRoundData()
        external
        view
        returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
}

File 7 of 10 : IAppAuthority.sol
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.28;

import "./IAppTreasury.sol";

/// @title IAppAuthority
/// @notice Interface for managing different roles and authorities in the application
/// @dev This interface defines the core access control functionality for the application, including role management,
/// treasury management, and candidate tracking for various roles in the system
interface IAppAuthority {
    /// @notice Emitted when the treasury address is updated
    /// @param newTreasury The address of the new treasury
    /// @param oldTreasury The address of the old treasury
    event TreasuryUpdated(address indexed newTreasury, address indexed oldTreasury);

    /// @notice Emitted when the operations treasury address is updated
    /// @param newOperationsTreasury The address of the new operations treasury
    /// @param oldOperationsTreasury The address of the old operations treasury
    event OperationsTreasuryUpdated(address indexed newOperationsTreasury, address indexed oldOperationsTreasury);

    /// @notice Adds a new governor to the system
    /// @param _newGovernor The address of the new governor to add
    function addGovernor(address _newGovernor) external;

    /// @notice Adds a new guardian to the system
    /// @param _newGuardian The address of the new guardian to add
    function addGuardian(address _newGuardian) external;

    /// @notice Adds a new policy to the system
    /// @param _newPolicy The address of the new policy to add
    function addPolicy(address _newPolicy) external;

    /// @notice Adds a new reserve manager to the system
    /// @param _newReserveManager The address of the new reserve manager to add
    function addReserveManager(address _newReserveManager) external;

    /// @notice Adds a new executor to the system
    /// @param _newExecutor The address of the new executor to add
    function addExecutor(address _newExecutor) external;

    /// @notice Adds a new bond manager to the system
    /// @param _newBondManager The address of the new bond manager to add
    function addBondManager(address _newBondManager) external;

    /// @notice Adds a new reserve depositor to the system
    /// @param _newReserveDepositor The address of the new reserve depositor to add
    function addReserveDepositor(address _newReserveDepositor) external;

    /// @notice Removes an existing governor from the system
    /// @param _oldGovernor The address of the governor to remove
    function removeGovernor(address _oldGovernor) external;

    /// @notice Removes an existing guardian from the system
    /// @param _oldGuardian The address of the guardian to remove
    function removeGuardian(address _oldGuardian) external;

    /// @notice Removes an existing policy from the system
    /// @param _oldPolicy The address of the policy to remove
    function removePolicy(address _oldPolicy) external;

    /// @notice Removes an existing reserve manager from the system
    /// @param _oldReserveManager The address of the reserve manager to remove
    function removeReserveManager(address _oldReserveManager) external;

    /// @notice Removes an existing executor from the system
    /// @param _oldExecutor The address of the executor to remove
    function removeExecutor(address _oldExecutor) external;

    /// @notice Removes an existing bond manager from the system
    /// @param _oldBondManager The address of the bond manager to remove
    function removeBondManager(address _oldBondManager) external;

    /// @notice Sets the operations treasury address
    /// @param _newOperationsTreasury The address of the new operations treasury
    function setOperationsTreasury(address _newOperationsTreasury) external;

    /// @notice Sets the treasury address
    /// @param _newTreasury The address of the new treasury
    function setTreasury(address _newTreasury) external;

    /// @notice Removes an existing reserve depositor from the system
    /// @param _oldReserveDepositor The address of the reserve depositor to remove
    function removeReserveDepositor(address _oldReserveDepositor) external;

    /// @notice Checks if an address is a governor
    /// @param account The address to check
    /// @return bool True if the address is a governor, false otherwise
    function isGovernor(address account) external view returns (bool);

    /// @notice Checks if an address is a bond manager
    /// @param account The address to check
    /// @return bool True if the address is a bond manager, false otherwise
    function isBondManager(address account) external view returns (bool);

    /// @notice Checks if an address is a guardian
    /// @param account The address to check
    /// @return bool True if the address is a guardian, false otherwise
    function isGuardian(address account) external view returns (bool);

    /// @notice Checks if an address is a policy
    /// @param account The address to check
    /// @return bool True if the address is a policy, false otherwise
    function isPolicy(address account) external view returns (bool);

    /// @notice Checks if an address is an executor
    /// @param account The address to check
    /// @return bool True if the address is an executor, false otherwise
    function isExecutor(address account) external view returns (bool);

    /// @notice Checks if an address is the treasury
    /// @param account The address to check
    /// @return bool True if the address is the treasury, false otherwise
    function isTreasury(address account) external view returns (bool);

    /// @notice Checks if an address is a reserve manager
    /// @param account The address to check
    /// @return bool True if the address is a reserve manager, false otherwise
    function isReserveManager(address account) external view returns (bool);

    /// @notice Checks if an address is a reserve depositor
    /// @param account The address to check
    /// @return bool True if the address is a reserve depositor, false otherwise
    function isReserveDepositor(address account) external view returns (bool);

    /// @notice Returns the address of the operations treasury
    /// @return address The address of the operations treasury
    function operationsTreasury() external view returns (address);

    /// @notice Returns the treasury contract instance
    /// @return IAppTreasury The treasury contract instance
    function treasury() external view returns (IAppTreasury);

    /// @notice Returns an array of all candidates for a given role
    /// @param role The role to get candidates for (e.g., GOVERNOR_ROLE, GUARDIAN_ROLE, etc.)
    /// @return candidates Array of addresses that are candidates for the given role
    function getAllCandidates(bytes32 role) external view returns (address[] memory candidates);

    /// @notice Returns an array of all reserve depositor candidates
    /// @return candidates Array of addresses that are reserve depositor candidates
    function getAllReserveDepositorCandidates() external view returns (address[] memory candidates);

    /// @notice Returns an array of all executor candidates
    /// @return candidates Array of addresses that are executor candidates
    function getAllExecutorCandidates() external view returns (address[] memory candidates);

    /// @notice Returns an array of all policy candidates
    /// @return candidates Array of addresses that are policy candidates
    function getAllPolicyCandidates() external view returns (address[] memory candidates);

    /// @notice Returns an array of all reserve manager candidates
    /// @return candidates Array of addresses that are reserve manager candidates
    function getAllReserveManagerCandidates() external view returns (address[] memory candidates);

    /// @notice Returns an array of all guardian candidates
    /// @return candidates Array of addresses that are guardian candidates
    function getAllGuardianCandidates() external view returns (address[] memory candidates);

    /// @notice Returns an array of all governor candidates
    /// @return candidates Array of addresses that are governor candidates
    function getAllGovernorCandidates() external view returns (address[] memory candidates);

    /// @notice Returns an array of all bond manager candidates
    /// @return candidates Array of addresses that are bond manager candidates
    function getAllBondManagerCandidates() external view returns (address[] memory candidates);
}

// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.8.28;

import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

interface IAppOracle {
    event OracleUpdated(address indexed token, address indexed oracle);

    // Errors
    error OracleNotFound(address token);
    error OracleAlreadyExists(address token);
    error OracleInactive(address token);
    error InvalidOracleAddress();
    error InvalidTokenAddress();

    /// @notice Initializes the AppOracle contract
    /// @dev This function is only callable once
    /// @param _authority The address of the authority contract
    /// @param _dre The address of the dre contract
    function initialize(address _authority, address _dre) external;

    /**
     * @notice Update the oracle for a token
     * @param token The token address
     * @param oracle The oracle contract
     */
    function updateOracle(address token, address oracle) external;

    /**
     * @notice Get the price for a token
     * @param token The token address
     * @return price The token price
     */
    function getPrice(address token) external view returns (uint256);

    /**
     * @notice Get the price for a token in RZR
     * @param token The token address
     * @return price The token price in RZR
     */
    function getPriceInToken(address token) external view returns (uint256 price);

    /**
     * @notice Get the price for a token in RZR for an amount
     * @param token The token address
     * @param amount The amount of the token
     * @return price The token price in RZR for the amount
     */
    function getPriceInTokenForAmount(address token, uint256 amount) external view returns (uint256 price);

    /**
     * @notice Get the price for RZR
     * @return price The RZR price
     */
    function getTokenPrice() external view returns (uint256);

    /**
     * @notice Set the price for RZR
     * @param newFloorPrice The new RZR price
     */
    function setTokenPrice(uint256 newFloorPrice) external;

    /**
     * @notice Get the price for a token for an amount
     * @param token The token address
     * @param amount The amount of the token
     * @return price The token price for the amount
     */
    function getPriceForAmount(address token, uint256 amount) external view returns (uint256);
}

// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.8.28;

import "./IAppOracle.sol";

interface IAppTreasury {
    /**
     * @notice allow approved address to deposit an asset for app
     * @param _amount uint256 amount of token to deposit
     * @param _token address of token to deposit
     * @param _profit uint256 amount of profit to mint
     * @return send_ uint256 amount of app minted
     */
    function deposit(uint256 _amount, address _token, uint256 _profit) external returns (uint256 send_);

    /**
     * @notice allow approved address to burn app for reserves
     * @param _amount amount of app to burn
     * @param _token address of the token to burn
     */
    function withdraw(uint256 _amount, address _token) external;

    /**
     * @notice Returns the value of a token in RZR, 18 decimals
     * @param _token The address of the token
     * @param _amount The amount of the token
     * @return value_ The value of the token in RZR
     */
    function tokenValueE18(address _token, uint256 _amount) external view returns (uint256 value_);

    /**
     * @notice allow approved address to mint app
     * @param _recipient address of the recipient
     * @param _amount amount of app to mint
     */
    function mint(address _recipient, uint256 _amount) external;

    /**
     * @notice allow approved address to manage the reserves of the treasury
     * @param _token address of the token to manage
     * @param _amount amount of the token to manage
     * @param _recipient address of the recipient
     * @return value amount of app that was managed
     */
    function manage(address _token, uint256 _amount, address _recipient) external returns (uint256 value);

    /**
     * @notice allow approved address to enable a token as a reserve
     * @param _address address to enable
     */
    function enable(address _address) external;

    /**
     * @notice Returns the backing ratio of the treasury in RZR terms (1e18)
     * @return backingRatio_ The backing ratio (1e18)
     */
    function backingRatioE18() external view returns (uint256);

    /**
     * @notice allow approved address to disable a token as a reserve
     * @param _address address to disable
     */
    function disable(address _address) external;

    /**
     * @notice Sets the credit reserves of the treasury
     * @param _credit The amount of reserves (in RZR terms) that has been credited to the treasury but not yet deposited
     */
    function setCreditReserves(uint256 _credit) external;

    /**
     * @notice Sets the unbacked supply of the treasury
     * @param _unbacked The amount of RZR that is in the minted but not yet backed
     */
    function setUnbackedSupply(uint256 _unbacked) external;

    /**
     * @notice Credit is amount of reserves (in RZR terms) that has been credited to the treasury but
     * not yet deposited in. This is important in the case that the collateral asset for RZR exists somewhere else
     * (such as in an RWA for example).
     *
     * This is particulary important in case of PSM modules where RZR is minted into a lending protocol for example
     * and RZR is taken out only when it it being borrowed with an over-collateralized position.
     *
     * @dev Credit is not included in the total supply of RZR.
     * @return credit_ The amount of reserves (in RZR terms) that has been credited to the treasury but not yet minted
     */
    function creditReserves() external view returns (uint256 credit_);

    /**
     * @notice Returns the actual supply of RZR excluding credit
     * @return actualSupply_ The actual supply of RZR excluding credit
     */
    function actualSupply() external view returns (uint256 actualSupply_);

    /**
     * @notice Returns the amount of RZR that has been minted but not yet backed
     * @return unbackedSupply_ The amount of RZR
     */
    function unbackedSupply() external view returns (uint256 unbackedSupply_);

    /**
     * @notice Returns the excess reserves of the treasury in RZR terms (excluding credit and debit)
     * that is not backing the RZR supply
     * @return excessReserves_ The excess reserves of the treasury in RZR terms
     */
    function excessReserves() external view returns (uint256);

    /**
     * @notice Returns the total reserves of the treasury in RZR terms (including credit and debit)
     * @return totalReserves_ The total reserves of the treasury in RZR terms
     */
    function totalReserves() external view returns (uint256);

    /**
     * @notice Returns the total supply of RZR (including credit and debit)
     * @return totalSupply_ The total supply of RZR
     */
    function totalSupply() external view returns (uint256 totalSupply_);

    /**
     * @notice Returns the actual reserves of the treasury in RZR terms excluding credit and debit
     * @return actualReserves_ The actual reserves of the treasury in RZR terms
     */
    function actualReserves() external view returns (uint256 actualReserves_);

    /**
     * @notice Sets the reserve fee
     * @param _reserveFee The new reserve fee
     */
    function setReserveFee(uint256 _reserveFee) external;

    /**
     * @notice Syncs the reserves of the treasury
     */
    function syncReserves() external;

    /**
     * @notice Calculates the total reserves of the treasury in RZR terms (including credit and debit)
     * @return reserves_ The total reserves of the treasury in RZR terms
     */
    function calculateReserves() external view returns (uint256 reserves_);

    /**
     * @notice Calculates the actual reserves of the treasury in RZR terms excluding credit and debit
     * @return actualReserves_ The actual reserves of the treasury in RZR terms
     */
    function calculateActualReserves() external view returns (uint256 actualReserves_);

    /**
     * @notice Gets the reserve fee
     * @return reserveFee_ The reserve fee
     */
    function reserveFee() external view returns (uint256 reserveFee_);

    /**
     * @notice Gets the app oracle
     * @return appOracle_ The app oracle
     */
    function appOracle() external view returns (IAppOracle appOracle_);

    /**
     * @notice Gets the enabled tokens
     * @return enabledTokens_ The enabled tokens
     */
    function enabledTokens(address _token) external view returns (bool enabledTokens_);

    /**
     * @notice Gets the basis points
     * @return basisPoints_ The basis points
     */
    function BASIS_POINTS() external view returns (uint256 basisPoints_);

    /**
     * @notice Gets the tokens enabled in the treasury
     * @return tokens_ The tokens
     */
    function tokens() external view returns (address[] memory tokens_);

    /**
     * @notice Gets the token at a given index in the enabled tokens array
     * @param _index The index of the token
     * @return token_ The token at the given index
     */
    function tokenAt(uint256 _index) external view returns (address token_);

    /**
     * @notice Gets the number of enabled tokens
     * @return length_ The number of enabled tokens
     */
    function enabledTokensLength() external view returns (uint256 length_);

    /**
     * @notice Gets the reserve cap for a token
     * @param _token The address of the token
     * @return cap_ The reserve cap for the token
     */
    function reserveCaps(address _token) external view returns (uint256 cap_);

    /**
     * @notice Gets the reserve debt for a token
     * @param _token The address of the token
     * @return debt_ The reserve debt for the token
     */
    function reserveDebts(address _token) external view returns (uint256 debt_);

    /**
     * @notice Sets the reserve cap for a token
     * @param _token The address of the token
     * @param _cap The reserve cap for the token
     */
    function setReserveCap(address _token, uint256 _cap) external;

    /**
     * @notice Sets the reserve debt for a token
     * @param _token The address of the token
     * @param _debt The reserve debt for the token
     */
    function setReserveDebt(address _token, uint256 _debt) external;

    /* ========== EVENTS ========== */

    event Deposit(address indexed token, uint256 amount, uint256 value);
    event Withdrawal(address indexed token, uint256 amount, uint256 value);
    event Managed(address indexed token, uint256 amount);
    event ReservesAudited(
        uint256 indexed totalReserves, uint256 indexed creditReserves, uint256 indexed totalReservesWithCredit
    );
    event Minted(address indexed caller, address indexed recipient, uint256 amount);
    event TokenEnabled(address addr, bool result);
    event CreditReservesSet(uint256 newCredit, uint256 oldCredit);
    event UnbackedSupplySet(uint256 newUnbacked, uint256 oldUnbacked);
    event ReserveFeeSet(uint256 newFee, uint256 oldFee);
    event ReserveCapSet(address indexed token, uint256 cap);
    event ReserveDebtSet(address indexed token, uint256 debt);
}

File 10 of 10 : IOracle.sol
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.28;

interface IOracle {
    function getPrice() external view returns (uint256);
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"contract IOracle","name":"_oracle","type":"address"},{"internalType":"address","name":"_authority","type":"address"},{"internalType":"uint256","name":"_upperBound","type":"uint256"},{"internalType":"uint256","name":"_lowerBound","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IAppAuthority","name":"authority","type":"address"}],"name":"AuthorityUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"int256","name":"price","type":"int256"}],"name":"ObservationAdded","type":"event"},{"inputs":[],"name":"MAX_OBSERVATIONS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UPDATE_INTERVAL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WINDOW_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"authority","outputs":[{"internalType":"contract IAppAuthority","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getObservation","outputs":[{"components":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"int256","name":"price","type":"int256"}],"internalType":"struct RZRTWAPOracle.Observation","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint80","name":"_roundId","type":"uint80"}],"name":"getRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTwap","outputs":[{"internalType":"int256","name":"twap","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestAnswer","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lowerBound","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"observations","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"int256","name":"price","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"contract IOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint80","name":"","type":"uint80"}],"name":"roundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IAppAuthority","name":"_newAuthority","type":"address"}],"name":"setAuthority","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_upperBound","type":"uint256"},{"internalType":"uint256","name":"_lowerBound","type":"uint256"}],"name":"setBounds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"registry","type":"address"},{"internalType":"uint256","name":"projectID","type":"uint256"}],"name":"setFeeMProjectId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"update","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"upperBound","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"}]

608060405234801561001057600080fd5b506040516114b93803806114b983398101604081905261002f9161029c565b6001600160a01b03841661008a5760405162461bcd60e51b815260206004820152601660248201527f496e76616c6964206f7261636c6520616464726573730000000000000000000060448201526064015b60405180910390fd5b6001600160a01b0383166100e05760405162461bcd60e51b815260206004820152601960248201527f496e76616c696420617574686f726974792061646472657373000000000000006044820152606401610081565b6100e983610233565b600280546001600160a01b0319166001600160a01b0386169081179091556003839055600482815560408051634c6afee560e11b81529051600093926398d5fdca928082019260209290918290030181865afa15801561014d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017191906102e4565b6040805180820182524280825260208083018581526005805460018101825560009190915293517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0600290950294850155517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db190930192909255600781905582519081529081018390529192507f785095453f120c02778bcf93a306c6e0a4554368990ce4136b8854d071c34394910160405180910390a150505050506102fd565b61023c8161023f565b50565b600080546001600160a01b0319166001600160a01b038316908117825560405190917f2f658b440c35314f52658ea8a740e05b284cdc84dc9ae01e891f21b8933e7cad91a250565b6001600160a01b038116811461023c57600080fd5b600080600080608085870312156102b257600080fd5b84516102bd81610287565b60208601519094506102ce81610287565b6040860151606090960151949790965092505050565b6000602082840312156102f657600080fd5b5051919050565b6111ad8061030c6000396000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c80637dc0d1d0116100e3578063bc81bae81161008c578063c909e6ce11610066578063c909e6ce146103d3578063f5fec8b1146103e6578063feaf968c1461041457600080fd5b8063bc81bae81461036b578063bf7e214f146103b7578063c8f33c91146103ca57600080fd5b8063a2e62045116100bd578063a2e6204514610351578063a384d6ff14610359578063b09ad8a01461036257600080fd5b80637dc0d1d01461026e57806389ac4147146102995780639a6fc8f5146102a257600080fd5b8063509ef27c116101455780635d752a9a1161011f5780635d752a9a146102395780637284e416146102415780637a9e5e4b1461025b57600080fd5b8063509ef27c1461020257806350d25bcd1461020b57806354fd4d501461023257600080fd5b806326987b601161017657806326987b60146101d4578063313ce567146101eb5780633ca52526146101fa57600080fd5b80630f93b45e14610192578063252c09d7146101a7575b600080fd5b6101a56101a0366004610ebb565b610482565b005b6101ba6101b5366004610ee7565b6105be565b604080519283526020830191909152015b60405180910390f35b6101dd60065481565b6040519081526020016101cb565b604051600881526020016101cb565b6101dd601881565b6101dd611c2081565b60075469ffffffffffffffffffff16600090815260016020819052604090912001546101dd565b60016101dd565b6101dd6105ec565b604080516020810182526000815290516101cb9190610f00565b6101a5610269366004610f6c565b610757565b600254610281906001600160a01b031681565b6040516001600160a01b0390911681526020016101cb565b6101dd61012c81565b61031a6102b0366004610f90565b69ffffffffffffffffffff818116600090815260016020818152604092839020835160a08101855281548616815292810154918301829052600281015493830184905260038101546060840181905260049091015490941660809092019190915292939091908490565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a0016101cb565b6101a5610823565b6101dd60045481565b6101dd60035481565b61031a610379366004610f90565b60016020819052600091825260409091208054918101546002820154600383015460049093015469ffffffffffffffffffff94851694929391921685565b600054610281906001600160a01b031681565b6101dd60075481565b6101a56103e1366004610fbc565b610c80565b6103f96103f4366004610ee7565b610d9a565b604080518251815260209283015192810192909252016101cb565b61031a60075469ffffffffffffffffffff908116600090815260016020818152604092839020835160a0810185528154861680825293820154928101839052600282015494810185905260038201546060820181905260049092015490951660809095018590529193909394565b6000546040517fe43581b80000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b039091169063e43581b890602401602060405180830381865afa1580156104e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105079190610fde565b6105475760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b60448201526064015b60405180910390fd5b6040517f1e60fd14000000000000000000000000000000000000000000000000000000008152600481018290526001600160a01b03831690631e60fd1490602401600060405180830381600087803b1580156105a257600080fd5b505af11580156105b6573d6000803e3d6000fd5b505050505050565b600581815481106105ce57600080fd5b60009182526020909120600290910201805460019091015490915082565b60055460009061063e5760405162461bcd60e51b815260206004820152600f60248201527f4e6f206f62736572766174696f6e730000000000000000000000000000000000604482015260640161053e565b42600061064d611c2083611016565b905060008060005b6005548110156106f3576000600582815481106106745761067461102f565b9060005260206000209060020201604051806040016040529081600082015481526020016001820154815250509050848160000151106106ea5780516000906106be908790611016565b90508082602001516106d09190611045565b6106da9085611091565b93506106e681866110b9565b9450505b50600101610655565b50600082116107445760405162461bcd60e51b815260206004820152601960248201527f4e6f206f62736572766174696f6e7320696e2077696e646f7700000000000000604482015260640161053e565b61074e82826110e2565b94505050505090565b6000546040517fe43581b80000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b039091169063e43581b890602401602060405180830381865afa1580156107b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107dc9190610fde565b6108175760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b604482015260640161053e565b61082081610e46565b50565b6000546040517fdebfda300000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b039091169063debfda3090602401602060405180830381865afa158015610884573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a89190610fde565b6108e35760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b604482015260640161053e565b61012c6007546108f391906110b9565b4210156109425760405162461bcd60e51b815260206004820152601360248201527f546f6f206561726c7920746f2075706461746500000000000000000000000000604482015260640161053e565b600254604080517f98d5fdca00000000000000000000000000000000000000000000000000000000815290516000926001600160a01b0316916398d5fdca9160048083019260209291908290030181865afa1580156109a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c9919061114a565b905060008113610a1b5760405162461bcd60e51b815260206004820152600d60248201527f496e76616c696420707269636500000000000000000000000000000000000000604482015260640161053e565b60055460181115610aa15760408051808201909152428152602081018281526005805460018101825560009190915291517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0600290930292830155517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db190910155610b0c565b60186006546001610ab291906110b9565b610abc9190611163565b600681905550604051806040016040528042815260200182815250600560065481548110610aec57610aec61102f565b600091825260209182902083516002909202019081559101516001909101555b426007556000610b1a6105ec565b905060045481138015610b2e575060035481125b610b7a5760405162461bcd60e51b815260206004820152601260248201527f54574150206f7574206f6620626f756e64730000000000000000000000000000604482015260640161053e565b6040518060a001604052804269ffffffffffffffffffff1681526020016402540be40083610ba891906110e2565b8152426020808301829052604080840183905269ffffffffffffffffffff80841660609586018190526000908152600180855290839020875181547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000090811691851691909117825588860151928201929092558784015160028201559587015160038701556080909601516004909501805490961694169390931790935581519081529182018390527f785095453f120c02778bcf93a306c6e0a4554368990ce4136b8854d071c34394910160405180910390a15050565b6000546040517fdebfda300000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b039091169063debfda3090602401602060405180830381865afa158015610ce1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d059190610fde565b610d405760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b604482015260640161053e565b808211610d8f5760405162461bcd60e51b815260206004820152600e60248201527f496e76616c696420626f756e6473000000000000000000000000000000000000604482015260640161053e565b600391909155600455565b60408051808201909152600080825260208201526005548210610dff5760405162461bcd60e51b815260206004820152601360248201527f496e646578206f7574206f6620626f756e647300000000000000000000000000604482015260640161053e565b60058281548110610e1257610e1261102f565b9060005260206000209060020201604051806040016040529081600082015481526020016001820154815250509050919050565b600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038316908117825560405190917f2f658b440c35314f52658ea8a740e05b284cdc84dc9ae01e891f21b8933e7cad91a250565b6001600160a01b038116811461082057600080fd5b60008060408385031215610ece57600080fd5b8235610ed981610ea6565b946020939093013593505050565b600060208284031215610ef957600080fd5b5035919050565b602081526000825180602084015260005b81811015610f2e5760208186018101516040868401015201610f11565b5060006040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b600060208284031215610f7e57600080fd5b8135610f8981610ea6565b9392505050565b600060208284031215610fa257600080fd5b813569ffffffffffffffffffff81168114610f8957600080fd5b60008060408385031215610fcf57600080fd5b50508035926020909101359150565b600060208284031215610ff057600080fd5b81518015158114610f8957600080fd5b634e487b7160e01b600052601160045260246000fd5b8181038181111561102957611029611000565b92915050565b634e487b7160e01b600052603260045260246000fd5b808202600082127f80000000000000000000000000000000000000000000000000000000000000008414161561107d5761107d611000565b818105831482151761102957611029611000565b80820182811260008312801582168215821617156110b1576110b1611000565b505092915050565b8082018082111561102957611029611000565b634e487b7160e01b600052601260045260246000fd5b6000826110f1576110f16110cc565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561114557611145611000565b500590565b60006020828403121561115c57600080fd5b5051919050565b600082611172576111726110cc565b50069056fea2646970667358221220631ae20ae70562342f45437f662632e494e199aabf8ab0c38ed77cb84d8357c764736f6c634300081c00330000000000000000000000006b1fc5bf99e8700f5fbb33d535e76c475e47ea2100000000000000000000000007249bd92625641f9e3dba360967c3b18ee28af2000000000000000000000000000000000000000000000000000000002faf0800000000000000000000000000000000000000000000000000000000000bebc200

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061018d5760003560e01c80637dc0d1d0116100e3578063bc81bae81161008c578063c909e6ce11610066578063c909e6ce146103d3578063f5fec8b1146103e6578063feaf968c1461041457600080fd5b8063bc81bae81461036b578063bf7e214f146103b7578063c8f33c91146103ca57600080fd5b8063a2e62045116100bd578063a2e6204514610351578063a384d6ff14610359578063b09ad8a01461036257600080fd5b80637dc0d1d01461026e57806389ac4147146102995780639a6fc8f5146102a257600080fd5b8063509ef27c116101455780635d752a9a1161011f5780635d752a9a146102395780637284e416146102415780637a9e5e4b1461025b57600080fd5b8063509ef27c1461020257806350d25bcd1461020b57806354fd4d501461023257600080fd5b806326987b601161017657806326987b60146101d4578063313ce567146101eb5780633ca52526146101fa57600080fd5b80630f93b45e14610192578063252c09d7146101a7575b600080fd5b6101a56101a0366004610ebb565b610482565b005b6101ba6101b5366004610ee7565b6105be565b604080519283526020830191909152015b60405180910390f35b6101dd60065481565b6040519081526020016101cb565b604051600881526020016101cb565b6101dd601881565b6101dd611c2081565b60075469ffffffffffffffffffff16600090815260016020819052604090912001546101dd565b60016101dd565b6101dd6105ec565b604080516020810182526000815290516101cb9190610f00565b6101a5610269366004610f6c565b610757565b600254610281906001600160a01b031681565b6040516001600160a01b0390911681526020016101cb565b6101dd61012c81565b61031a6102b0366004610f90565b69ffffffffffffffffffff818116600090815260016020818152604092839020835160a08101855281548616815292810154918301829052600281015493830184905260038101546060840181905260049091015490941660809092019190915292939091908490565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a0016101cb565b6101a5610823565b6101dd60045481565b6101dd60035481565b61031a610379366004610f90565b60016020819052600091825260409091208054918101546002820154600383015460049093015469ffffffffffffffffffff94851694929391921685565b600054610281906001600160a01b031681565b6101dd60075481565b6101a56103e1366004610fbc565b610c80565b6103f96103f4366004610ee7565b610d9a565b604080518251815260209283015192810192909252016101cb565b61031a60075469ffffffffffffffffffff908116600090815260016020818152604092839020835160a0810185528154861680825293820154928101839052600282015494810185905260038201546060820181905260049092015490951660809095018590529193909394565b6000546040517fe43581b80000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b039091169063e43581b890602401602060405180830381865afa1580156104e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105079190610fde565b6105475760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b60448201526064015b60405180910390fd5b6040517f1e60fd14000000000000000000000000000000000000000000000000000000008152600481018290526001600160a01b03831690631e60fd1490602401600060405180830381600087803b1580156105a257600080fd5b505af11580156105b6573d6000803e3d6000fd5b505050505050565b600581815481106105ce57600080fd5b60009182526020909120600290910201805460019091015490915082565b60055460009061063e5760405162461bcd60e51b815260206004820152600f60248201527f4e6f206f62736572766174696f6e730000000000000000000000000000000000604482015260640161053e565b42600061064d611c2083611016565b905060008060005b6005548110156106f3576000600582815481106106745761067461102f565b9060005260206000209060020201604051806040016040529081600082015481526020016001820154815250509050848160000151106106ea5780516000906106be908790611016565b90508082602001516106d09190611045565b6106da9085611091565b93506106e681866110b9565b9450505b50600101610655565b50600082116107445760405162461bcd60e51b815260206004820152601960248201527f4e6f206f62736572766174696f6e7320696e2077696e646f7700000000000000604482015260640161053e565b61074e82826110e2565b94505050505090565b6000546040517fe43581b80000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b039091169063e43581b890602401602060405180830381865afa1580156107b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107dc9190610fde565b6108175760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b604482015260640161053e565b61082081610e46565b50565b6000546040517fdebfda300000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b039091169063debfda3090602401602060405180830381865afa158015610884573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a89190610fde565b6108e35760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b604482015260640161053e565b61012c6007546108f391906110b9565b4210156109425760405162461bcd60e51b815260206004820152601360248201527f546f6f206561726c7920746f2075706461746500000000000000000000000000604482015260640161053e565b600254604080517f98d5fdca00000000000000000000000000000000000000000000000000000000815290516000926001600160a01b0316916398d5fdca9160048083019260209291908290030181865afa1580156109a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c9919061114a565b905060008113610a1b5760405162461bcd60e51b815260206004820152600d60248201527f496e76616c696420707269636500000000000000000000000000000000000000604482015260640161053e565b60055460181115610aa15760408051808201909152428152602081018281526005805460018101825560009190915291517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0600290930292830155517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db190910155610b0c565b60186006546001610ab291906110b9565b610abc9190611163565b600681905550604051806040016040528042815260200182815250600560065481548110610aec57610aec61102f565b600091825260209182902083516002909202019081559101516001909101555b426007556000610b1a6105ec565b905060045481138015610b2e575060035481125b610b7a5760405162461bcd60e51b815260206004820152601260248201527f54574150206f7574206f6620626f756e64730000000000000000000000000000604482015260640161053e565b6040518060a001604052804269ffffffffffffffffffff1681526020016402540be40083610ba891906110e2565b8152426020808301829052604080840183905269ffffffffffffffffffff80841660609586018190526000908152600180855290839020875181547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000090811691851691909117825588860151928201929092558784015160028201559587015160038701556080909601516004909501805490961694169390931790935581519081529182018390527f785095453f120c02778bcf93a306c6e0a4554368990ce4136b8854d071c34394910160405180910390a15050565b6000546040517fdebfda300000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b039091169063debfda3090602401602060405180830381865afa158015610ce1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d059190610fde565b610d405760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b604482015260640161053e565b808211610d8f5760405162461bcd60e51b815260206004820152600e60248201527f496e76616c696420626f756e6473000000000000000000000000000000000000604482015260640161053e565b600391909155600455565b60408051808201909152600080825260208201526005548210610dff5760405162461bcd60e51b815260206004820152601360248201527f496e646578206f7574206f6620626f756e647300000000000000000000000000604482015260640161053e565b60058281548110610e1257610e1261102f565b9060005260206000209060020201604051806040016040529081600082015481526020016001820154815250509050919050565b600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038316908117825560405190917f2f658b440c35314f52658ea8a740e05b284cdc84dc9ae01e891f21b8933e7cad91a250565b6001600160a01b038116811461082057600080fd5b60008060408385031215610ece57600080fd5b8235610ed981610ea6565b946020939093013593505050565b600060208284031215610ef957600080fd5b5035919050565b602081526000825180602084015260005b81811015610f2e5760208186018101516040868401015201610f11565b5060006040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b600060208284031215610f7e57600080fd5b8135610f8981610ea6565b9392505050565b600060208284031215610fa257600080fd5b813569ffffffffffffffffffff81168114610f8957600080fd5b60008060408385031215610fcf57600080fd5b50508035926020909101359150565b600060208284031215610ff057600080fd5b81518015158114610f8957600080fd5b634e487b7160e01b600052601160045260246000fd5b8181038181111561102957611029611000565b92915050565b634e487b7160e01b600052603260045260246000fd5b808202600082127f80000000000000000000000000000000000000000000000000000000000000008414161561107d5761107d611000565b818105831482151761102957611029611000565b80820182811260008312801582168215821617156110b1576110b1611000565b505092915050565b8082018082111561102957611029611000565b634e487b7160e01b600052601260045260246000fd5b6000826110f1576110f16110cc565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561114557611145611000565b500590565b60006020828403121561115c57600080fd5b5051919050565b600082611172576111726110cc565b50069056fea2646970667358221220631ae20ae70562342f45437f662632e494e199aabf8ab0c38ed77cb84d8357c764736f6c634300081c0033

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

0000000000000000000000006b1fc5bf99e8700f5fbb33d535e76c475e47ea2100000000000000000000000007249bd92625641f9e3dba360967c3b18ee28af2000000000000000000000000000000000000000000000000000000002faf0800000000000000000000000000000000000000000000000000000000000bebc200

-----Decoded View---------------
Arg [0] : _oracle (address): 0x6b1fC5Bf99e8700f5fbb33D535e76c475E47ea21
Arg [1] : _authority (address): 0x07249bd92625641f9E3DBa360967C3b18eE28AF2
Arg [2] : _upperBound (uint256): 800000000
Arg [3] : _lowerBound (uint256): 200000000

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000006b1fc5bf99e8700f5fbb33d535e76c475e47ea21
Arg [1] : 00000000000000000000000007249bd92625641f9e3dba360967c3b18ee28af2
Arg [2] : 000000000000000000000000000000000000000000000000000000002faf0800
Arg [3] : 000000000000000000000000000000000000000000000000000000000bebc200


Block Transaction Gas Used Reward
view all blocks ##produced##

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ 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.