FRAX Price: $0.82 (-10.84%)

Contract

0x6A60EB9C89Bad7569F7C4612957408baD8CcC00E

Overview

FRAX Balance | FXTL Balance

0 FRAX | 968 FXTL

FRAX Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To
Renounce Role244462032025-08-20 15:18:37161 days ago1755703117IN
0x6A60EB9C...aD8CcC00E
0 FRAX0.000531190.00112528
Set Composite Fe...225200452025-07-07 1:13:21206 days ago1751850801IN
0x6A60EB9C...aD8CcC00E
0 FRAX0.000023570.00100025
Set Asset Config225200422025-07-07 1:13:15206 days ago1751850795IN
0x6A60EB9C...aD8CcC00E
0 FRAX0.000018450.00100025
Revoke Role201282002025-05-12 16:25:11261 days ago1747067111IN
0x6A60EB9C...aD8CcC00E
0 FRAX00.00000111
Grant Role201281962025-05-12 16:25:03261 days ago1747067103IN
0x6A60EB9C...aD8CcC00E
0 FRAX00.00000113
Revoke Role201281932025-05-12 16:24:57261 days ago1747067097IN
0x6A60EB9C...aD8CcC00E
0 FRAX0.000000030.00110111
Grant Role201281902025-05-12 16:24:51261 days ago1747067091IN
0x6A60EB9C...aD8CcC00E
0 FRAX0.000000050.00100112
Set Composite Fe...167913052025-02-24 10:35:21339 days ago1740393321IN
0x6A60EB9C...aD8CcC00E
0 FRAX0.000000130.00100025
Set Asset Config167913022025-02-24 10:35:15339 days ago1740393315IN
0x6A60EB9C...aD8CcC00E
0 FRAX0.000000080.00100025
Set Composite Fe...167912992025-02-24 10:35:09339 days ago1740393309IN
0x6A60EB9C...aD8CcC00E
0 FRAX0.000000130.00100025
Set Asset Config167912962025-02-24 10:35:03339 days ago1740393303IN
0x6A60EB9C...aD8CcC00E
0 FRAX0.000000080.00100025
Set Composite Fe...167907582025-02-24 10:17:07339 days ago1740392227IN
0x6A60EB9C...aD8CcC00E
0 FRAX0.000000450.00200025
Set Asset Config167907552025-02-24 10:17:01339 days ago1740392221IN
0x6A60EB9C...aD8CcC00E
0 FRAX0.000000120.00100025
Set Composite Fe...167907522025-02-24 10:16:55339 days ago1740392215IN
0x6A60EB9C...aD8CcC00E
0 FRAX0.000000250.00100025
Set Asset Config167907492025-02-24 10:16:49339 days ago1740392209IN
0x6A60EB9C...aD8CcC00E
0 FRAX0.000000130.00100025
Set Composite Fe...159284282025-02-04 11:12:47359 days ago1738667567IN
0x6A60EB9C...aD8CcC00E
0 FRAX0.000000490.00121
Set Asset Config159284252025-02-04 11:12:41359 days ago1738667561IN
0x6A60EB9C...aD8CcC00E
0 FRAX0.000000290.00121

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:
CurveAPI3CompositeWrapperWithThresholding

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 200 runs

Other Settings:
london EvmVersion, MIT license
// SPDX-License-Identifier: MIT
/* ———————————————————————————————————————————————————————————————————————————————— *
 *    _____     ______   ______     __     __   __     __     ______   __  __       *
 *   /\  __-.  /\__  _\ /\  == \   /\ \   /\ "-.\ \   /\ \   /\__  _\ /\ \_\ \      *
 *   \ \ \/\ \ \/_/\ \/ \ \  __<   \ \ \  \ \ \-.  \  \ \ \  \/_/\ \/ \ \____ \     *
 *    \ \____-    \ \_\  \ \_\ \_\  \ \_\  \ \_\\"\_\  \ \_\    \ \_\  \/\_____\    *
 *     \/____/     \/_/   \/_/ /_/   \/_/   \/_/ \/_/   \/_/     \/_/   \/_____/    *
 *                                                                                  *
 * ————————————————————————————————— dtrinity.org ————————————————————————————————— *
 *                                                                                  *
 *                                         ▲                                        *
 *                                        ▲ ▲                                       *
 *                                                                                  *
 * ———————————————————————————————————————————————————————————————————————————————— *
 * dTRINITY Protocol: https://github.com/dtrinity                                   *
 * ———————————————————————————————————————————————————————————————————————————————— */

pragma solidity 0.8.20;

import "./CurveOracleWrapper.sol";
import {IProxy} from "../interface/api3/IProxy.sol";
import "./ThresholdingUtils.sol";

/**
 * @title CurveAPI3CompositeWrapperWithThresholding
 * @notice Oracle wrapper that combines Curve pool prices with API3 prices and applies thresholding
 * @dev Used when Curve pool prices need to be converted using another token's price from API3
 */
contract CurveAPI3CompositeWrapperWithThresholding is
    CurveOracleWrapper,
    ThresholdingUtils
{
    /* Constants */
    uint32 public constant API3_HEARTBEAT = 1 days;
    uint32 public heartbeatStaleTimeLimit = 1 hours;

    /* Errors */
    error API3InvalidPrice(address asset);

    /* Types */
    struct CompositeFeed {
        address api3Asset; // Asset to get price from API3
        address api3Proxy; // API3 proxy contract address
        ThresholdConfig curveThreshold; // Threshold config for Curve price
        ThresholdConfig api3Threshold; // Threshold config for API3 price
    }

    /* State */

    /// @notice Mapping from asset to composite feed configuration
    mapping(address => CompositeFeed) public compositeFeeds;

    /* Events */

    event CompositeFeedSet(
        address indexed asset,
        address indexed api3Asset,
        address indexed api3Proxy,
        uint256 curveLowerThresholdInBase,
        uint256 curveFixedPriceInBase,
        uint256 api3LowerThresholdInBase,
        uint256 api3FixedPriceInBase
    );

    event CompositeFeedRemoved(address indexed asset);

    constructor(
        uint256 _baseCurrencyUnit
    ) CurveOracleWrapper(_baseCurrencyUnit) {}

    /**
     * @notice Set or update composite feed configuration for an asset
     */
    function setCompositeFeed(
        address asset,
        address api3Asset,
        address api3Proxy,
        uint256 curveLowerThresholdInBase,
        uint256 curveFixedPriceInBase,
        uint256 api3LowerThresholdInBase,
        uint256 api3FixedPriceInBase
    ) external onlyRole(ORACLE_MANAGER_ROLE) {
        // Verify the asset is configured in Curve wrapper
        PoolConfig memory poolConfig = assetConfigs[asset];
        if (address(poolConfig.pool) == address(0))
            revert AssetNotConfigured(asset);

        // Verify API3 proxy can provide a price
        (int224 value, uint32 timestamp) = IProxy(api3Proxy).read();
        if (
            value <= 0 ||
            timestamp + API3_HEARTBEAT + heartbeatStaleTimeLimit <=
            block.timestamp
        ) {
            revert API3InvalidPrice(api3Asset);
        }

        compositeFeeds[asset] = CompositeFeed({
            api3Asset: api3Asset,
            api3Proxy: api3Proxy,
            curveThreshold: ThresholdConfig({
                lowerThresholdInBase: curveLowerThresholdInBase,
                fixedPriceInBase: curveFixedPriceInBase
            }),
            api3Threshold: ThresholdConfig({
                lowerThresholdInBase: api3LowerThresholdInBase,
                fixedPriceInBase: api3FixedPriceInBase
            })
        });

        emit CompositeFeedSet(
            asset,
            api3Asset,
            api3Proxy,
            curveLowerThresholdInBase,
            curveFixedPriceInBase,
            api3LowerThresholdInBase,
            api3FixedPriceInBase
        );
    }

    /**
     * @notice Remove composite feed configuration for an asset
     * @param asset Asset address
     */
    function removeCompositeFeed(
        address asset
    ) external onlyRole(ORACLE_MANAGER_ROLE) {
        delete compositeFeeds[asset];
        emit CompositeFeedRemoved(asset);
    }

    /**
     * @notice Get the composite price info for an asset
     */
    function getPriceInfo(
        address asset
    ) public view override returns (uint256 priceInBase, bool isAlive) {
        // Get Curve pool price
        (uint256 curvePriceInBase, bool curveAlive) = super.getPriceInfo(asset);
        if (!curveAlive) return (0, false);

        CompositeFeed memory feed = compositeFeeds[asset];

        // Apply threshold to Curve price if threshold is configured
        if (feed.curveThreshold.lowerThresholdInBase > 0) {
            curvePriceInBase = _applyThreshold(
                curvePriceInBase,
                feed.curveThreshold
            );
        }

        // If no composite feed for API3, return Curve price
        if (feed.api3Asset == address(0)) {
            return (curvePriceInBase, true);
        }

        // Get API3 price
        (int224 value, uint32 timestamp) = IProxy(feed.api3Proxy).read();
        bool api3Alive = value > 0 &&
            timestamp + API3_HEARTBEAT + heartbeatStaleTimeLimit >
            block.timestamp;
        if (!api3Alive) return (0, false);

        uint256 api3PriceInBase = _convertToBaseCurrencyUnit(
            uint256(uint224(value))
        );

        // Apply threshold to API3 price if threshold is configured
        if (feed.api3Threshold.lowerThresholdInBase > 0) {
            api3PriceInBase = _applyThreshold(
                api3PriceInBase,
                feed.api3Threshold
            );
        }

        // Calculate composite price
        return (
            (curvePriceInBase * api3PriceInBase) / BASE_CURRENCY_UNIT,
            true
        );
    }
}

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

pragma solidity ^0.8.20;

import {IAccessControl} from "./IAccessControl.sol";
import {Context} from "../utils/Context.sol";
import {ERC165} from "../utils/introspection/ERC165.sol";

/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```solidity
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```solidity
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
 * to enforce additional security measures for this role.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address account => bool) hasRole;
        bytes32 adminRole;
    }

    mapping(bytes32 role => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with an {AccessControlUnauthorizedAccount} error including the required role.
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role);
        _;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view virtual returns (bool) {
        return _roles[role].hasRole[account];
    }

    /**
     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
     * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

    /**
     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
     * is missing `role`.
     */
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!hasRole(role, account)) {
            revert AccessControlUnauthorizedAccount(account, role);
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleGranted} event.
     */
    function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleRevoked} event.
     */
    function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `callerConfirmation`.
     *
     * May emit a {RoleRevoked} event.
     */
    function renounceRole(bytes32 role, address callerConfirmation) public virtual {
        if (callerConfirmation != _msgSender()) {
            revert AccessControlBadConfirmation();
        }

        _revokeRole(role, callerConfirmation);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleGranted} event.
     */
    function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
        if (!hasRole(role, account)) {
            _roles[role].hasRole[account] = true;
            emit RoleGranted(role, account, _msgSender());
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleRevoked} event.
     */
    function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
        if (hasRole(role, account)) {
            _roles[role].hasRole[account] = false;
            emit RoleRevoked(role, account, _msgSender());
            return true;
        } else {
            return false;
        }
    }
}

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

pragma solidity ^0.8.20;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev The `account` is missing a role.
     */
    error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);

    /**
     * @dev The caller of a function is not the expected one.
     *
     * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
     */
    error AccessControlBadConfirmation();

    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `callerConfirmation`.
     */
    function renounceRole(bytes32 role, address callerConfirmation) external;
}

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

pragma solidity ^0.8.20;

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.20;

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

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

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

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

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

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

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

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

pragma solidity ^0.8.20;

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

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

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

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// SPDX-License-Identifier: AGPL-3.0
/* ———————————————————————————————————————————————————————————————————————————————— *
 *    _____     ______   ______     __     __   __     __     ______   __  __       *
 *   /\  __-.  /\__  _\ /\  == \   /\ \   /\ "-.\ \   /\ \   /\__  _\ /\ \_\ \      *
 *   \ \ \/\ \ \/_/\ \/ \ \  __<   \ \ \  \ \ \-.  \  \ \ \  \/_/\ \/ \ \____ \     *
 *    \ \____-    \ \_\  \ \_\ \_\  \ \_\  \ \_\\"\_\  \ \_\    \ \_\  \/\_____\    *
 *     \/____/     \/_/   \/_/ /_/   \/_/   \/_/ \/_/   \/_/     \/_/   \/_____/    *
 *                                                                                  *
 * ————————————————————————————————— dtrinity.org ————————————————————————————————— *
 *                                                                                  *
 *                                         ▲                                        *
 *                                        ▲ ▲                                       *
 *                                                                                  *
 * ———————————————————————————————————————————————————————————————————————————————— *
 * dTRINITY Protocol: https://github.com/dtrinity                                   *
 * ———————————————————————————————————————————————————————————————————————————————— */

pragma solidity ^0.8.0;

/**
 * @title IPriceOracleGetter
 * @author Aave
 * @notice Interface for the Aave price oracle.
 */
interface IPriceOracleGetter {
    /**
     * @notice Returns the base currency address
     * @dev Address 0x0 is reserved for USD as base currency.
     * @return Returns the base currency address.
     */
    function BASE_CURRENCY() external view returns (address);

    /**
     * @notice Returns the base currency unit
     * @dev 1 ether for ETH, 1e8 for USD.
     * @return Returns the base currency unit.
     */
    function BASE_CURRENCY_UNIT() external view returns (uint256);

    /**
     * @notice Returns the asset price in the base currency
     * @param asset The address of the asset
     * @return The price of the asset
     */
    function getAssetPrice(address asset) external view returns (uint256);
}

// SPDX-License-Identifier: MIT
/* ———————————————————————————————————————————————————————————————————————————————— *
 *    _____     ______   ______     __     __   __     __     ______   __  __       *
 *   /\  __-.  /\__  _\ /\  == \   /\ \   /\ "-.\ \   /\ \   /\__  _\ /\ \_\ \      *
 *   \ \ \/\ \ \/_/\ \/ \ \  __<   \ \ \  \ \ \-.  \  \ \ \  \/_/\ \/ \ \____ \     *
 *    \ \____-    \ \_\  \ \_\ \_\  \ \_\  \ \_\\"\_\  \ \_\    \ \_\  \/\_____\    *
 *     \/____/     \/_/   \/_/ /_/   \/_/   \/_/ \/_/   \/_/     \/_/   \/_____/    *
 *                                                                                  *
 * ————————————————————————————————— dtrinity.org ————————————————————————————————— *
 *                                                                                  *
 *                                         ▲                                        *
 *                                        ▲ ▲                                       *
 *                                                                                  *
 * ———————————————————————————————————————————————————————————————————————————————— *
 * dTRINITY Protocol: https://github.com/dtrinity                                   *
 * ———————————————————————————————————————————————————————————————————————————————— */

pragma solidity 0.8.20;

import "contracts/lending/core/interfaces/IPriceOracleGetter.sol";

/**
 * @dev Interface for the individual oracle wrappers, to unify interface between Redstone and API3 for example
 */
interface IOracleWrapper is IPriceOracleGetter {
    function getPriceInfo(
        address asset
    ) external view returns (uint256 price, bool isAlive);
}

// SPDX-License-Identifier: MIT
/* ———————————————————————————————————————————————————————————————————————————————— *
 *    _____     ______   ______     __     __   __     __     ______   __  __       *
 *   /\  __-.  /\__  _\ /\  == \   /\ \   /\ "-.\ \   /\ \   /\__  _\ /\ \_\ \      *
 *   \ \ \/\ \ \/_/\ \/ \ \  __<   \ \ \  \ \ \-.  \  \ \ \  \/_/\ \/ \ \____ \     *
 *    \ \____-    \ \_\  \ \_\ \_\  \ \_\  \ \_\\"\_\  \ \_\    \ \_\  \/\_____\    *
 *     \/____/     \/_/   \/_/ /_/   \/_/   \/_/ \/_/   \/_/     \/_/   \/_____/    *
 *                                                                                  *
 * ————————————————————————————————— dtrinity.org ————————————————————————————————— *
 *                                                                                  *
 *                                         ▲                                        *
 *                                        ▲ ▲                                       *
 *                                                                                  *
 * ———————————————————————————————————————————————————————————————————————————————— *
 * dTRINITY Protocol: https://github.com/dtrinity                                   *
 * ———————————————————————————————————————————————————————————————————————————————— */

pragma solidity ^0.8.0;

/// @dev See DapiProxy.sol for comments about usage
interface IProxy {
    function read() external view returns (int224 value, uint32 timestamp);

    function api3ServerV1() external view returns (address);
}

// SPDX-License-Identifier: MIT
/* ———————————————————————————————————————————————————————————————————————————————— *
 *    _____     ______   ______     __     __   __     __     ______   __  __       *
 *   /\  __-.  /\__  _\ /\  == \   /\ \   /\ "-.\ \   /\ \   /\__  _\ /\ \_\ \      *
 *   \ \ \/\ \ \/_/\ \/ \ \  __<   \ \ \  \ \ \-.  \  \ \ \  \/_/\ \/ \ \____ \     *
 *    \ \____-    \ \_\  \ \_\ \_\  \ \_\  \ \_\\"\_\  \ \_\    \ \_\  \/\_____\    *
 *     \/____/     \/_/   \/_/ /_/   \/_/   \/_/ \/_/   \/_/     \/_/   \/_____/    *
 *                                                                                  *
 * ————————————————————————————————— dtrinity.org ————————————————————————————————— *
 *                                                                                  *
 *                                         ▲                                        *
 *                                        ▲ ▲                                       *
 *                                                                                  *
 * ———————————————————————————————————————————————————————————————————————————————— *
 * dTRINITY Protocol: https://github.com/dtrinity                                   *
 * ———————————————————————————————————————————————————————————————————————————————— */

pragma solidity 0.8.20;

import "../IOracleWrapper.sol";
import "@openzeppelin/contracts-5/access/AccessControl.sol";

/**
 * @title ICurveOracleWrapper
 * @notice Interface for Curve pool oracle wrappers
 */
abstract contract ICurveOracleWrapper is IOracleWrapper, AccessControl {
    /* Core state */

    /// @notice Base currency unit (e.g. 1e8 if using Aave's oracle decimals)
    uint256 public immutable BASE_CURRENCY_UNIT;

    uint256 public constant CURVE_BASE_CURRENCY_UNIT = 10 ** 18;

    uint256 public constant CURVE_RATE_PRECISION = 10 ** 18;

    /// @notice Base currency (address(0) for USD)
    address public constant BASE_CURRENCY = address(0);

    /* Events */

    event AssetConfigSet(
        address indexed asset,
        address indexed pool,
        uint256 tokenIndex
    );
    event AssetConfigRemoved(address indexed asset);

    /* Errors */

    error AssetNotConfigured(address asset);
    error InvalidPool(address pool);
    error InvalidTokenIndex(address pool, uint256 tokenIndex);
    error PriceIsZero(address asset);

    /* Roles */

    bytes32 public constant ORACLE_MANAGER_ROLE =
        keccak256("ORACLE_MANAGER_ROLE");

    constructor(uint256 _baseCurrencyUnit) {
        BASE_CURRENCY_UNIT = _baseCurrencyUnit;
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(ORACLE_MANAGER_ROLE, msg.sender);
    }

    /**
     * @notice Set or update configuration for an asset
     * @param asset Asset address
     * @param pool Curve pool address
     */
    function setAssetConfig(address asset, address pool) external virtual;

    /**
     * @notice Remove configuration for an asset
     * @param asset Asset address
     */
    function removeAssetConfig(address asset) external virtual;

    function getPriceInfo(
        address asset
    ) public view virtual override returns (uint256 price, bool isAlive);

    function getAssetPrice(
        address asset
    ) external view virtual override returns (uint256) {
        (uint256 price, bool isAlive) = getPriceInfo(asset);
        if (!isAlive) revert PriceIsZero(asset);
        return price;
    }

    function _convertToBaseCurrencyUnit(
        uint256 price
    ) internal view returns (uint256) {
        return (price * BASE_CURRENCY_UNIT) / CURVE_BASE_CURRENCY_UNIT;
    }
}

File 13 of 15 : ICurveStableNG.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

interface ICurveStableNG {
    // View functions
    function price_oracle(uint256 i) external view returns (uint256);

    function ema_price(uint256 i) external view returns (uint256);

    function last_price(uint256 i) external view returns (uint256);

    function get_p(uint256 i) external view returns (uint256);

    function coins(uint256 i) external view returns (address);

    function N_COINS() external view returns (uint256);

    function get_virtual_price() external view returns (uint256);

    function balances(uint256 i) external view returns (uint256);

    function get_balances() external view returns (uint256[] memory);

    function get_dx(
        int128 i,
        int128 j,
        uint256 dy
    ) external view returns (uint256);

    function get_dy(
        int128 i,
        int128 j,
        uint256 dx
    ) external view returns (uint256);

    function calc_token_amount(
        uint256[] memory amounts,
        bool is_deposit
    ) external view returns (uint256);

    function calc_withdraw_one_coin(
        uint256 burn_amount,
        int128 i
    ) external view returns (uint256);

    function D_oracle() external view returns (uint256);

    function dynamic_fee(int128 i, int128 j) external view returns (uint256);

    // State changing functions
    function exchange(
        int128 i,
        int128 j,
        uint256 dx,
        uint256 min_dy
    ) external returns (uint256);

    function exchange(
        int128 i,
        int128 j,
        uint256 dx,
        uint256 min_dy,
        address receiver
    ) external returns (uint256);

    function exchange_received(
        int128 i,
        int128 j,
        uint256 dx,
        uint256 min_dy
    ) external returns (uint256);

    function exchange_received(
        int128 i,
        int128 j,
        uint256 dx,
        uint256 min_dy,
        address receiver
    ) external returns (uint256);

    // Liquidity functions
    function add_liquidity(
        uint256[] memory amounts,
        uint256 min_mint_amount
    ) external returns (uint256);

    function add_liquidity(
        uint256[] memory amounts,
        uint256 min_mint_amount,
        address receiver
    ) external returns (uint256);

    function remove_liquidity(
        uint256 burn_amount,
        uint256[] memory min_amounts
    ) external returns (uint256[] memory);

    function remove_liquidity(
        uint256 burn_amount,
        uint256[] memory min_amounts,
        address receiver
    ) external returns (uint256[] memory);

    function remove_liquidity(
        uint256 burn_amount,
        uint256[] memory min_amounts,
        address receiver,
        bool claim_admin_fees
    ) external returns (uint256[] memory);

    function remove_liquidity_one_coin(
        uint256 burn_amount,
        int128 i,
        uint256 min_received
    ) external returns (uint256);

    function remove_liquidity_one_coin(
        uint256 burn_amount,
        int128 i,
        uint256 min_received,
        address receiver
    ) external returns (uint256);

    function remove_liquidity_imbalance(
        uint256[] memory amounts,
        uint256 max_burn_amount
    ) external returns (uint256);

    function remove_liquidity_imbalance(
        uint256[] memory amounts,
        uint256 max_burn_amount,
        address receiver
    ) external returns (uint256);

    // Admin functions
    function ramp_A(uint256 future_A, uint256 future_time) external;

    function stop_ramp_A() external;

    function set_new_fee(
        uint256 new_fee,
        uint256 new_offpeg_fee_multiplier
    ) external;

    function set_ma_exp_time(uint256 ma_exp_time, uint256 D_ma_time) external;

    function withdraw_admin_fees() external;

    // ERC20 functions
    function transfer(address to, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);

    function approve(address spender, uint256 value) external returns (bool);

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);

    function totalSupply() external view returns (uint256);

    function balanceOf(address account) external view returns (uint256);

    function allowance(
        address owner,
        address spender
    ) external view returns (uint256);

    function nonces(address owner) external view returns (uint256);

    // Additional view functions
    function version() external view returns (string memory);

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

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

    function decimals() external view returns (uint8);

    function fee() external view returns (uint256);

    function offpeg_fee_multiplier() external view returns (uint256);

    function admin_fee() external view returns (uint256);

    function initial_A() external view returns (uint256);

    function future_A() external view returns (uint256);

    function initial_A_time() external view returns (uint256);

    function future_A_time() external view returns (uint256);

    function admin_balances(uint256 i) external view returns (uint256);

    function ma_exp_time() external view returns (uint256);

    function D_ma_time() external view returns (uint256);

    function ma_last_time() external view returns (uint256);

    function salt() external view returns (bytes32);

    function A() external view returns (uint256);

    function A_precise() external view returns (uint256);

    function stored_rates() external view returns (uint256[] memory);
}

// SPDX-License-Identifier: MIT
/* ———————————————————————————————————————————————————————————————————————————————— *
 *    _____     ______   ______     __     __   __     __     ______   __  __       *
 *   /\  __-.  /\__  _\ /\  == \   /\ \   /\ "-.\ \   /\ \   /\__  _\ /\ \_\ \      *
 *   \ \ \/\ \ \/_/\ \/ \ \  __<   \ \ \  \ \ \-.  \  \ \ \  \/_/\ \/ \ \____ \     *
 *    \ \____-    \ \_\  \ \_\ \_\  \ \_\  \ \_\\"\_\  \ \_\    \ \_\  \/\_____\    *
 *     \/____/     \/_/   \/_/ /_/   \/_/   \/_/ \/_/   \/_/     \/_/   \/_____/    *
 *                                                                                  *
 * ————————————————————————————————— dtrinity.org ————————————————————————————————— *
 *                                                                                  *
 *                                         ▲                                        *
 *                                        ▲ ▲                                       *
 *                                                                                  *
 * ———————————————————————————————————————————————————————————————————————————————— *
 * dTRINITY Protocol: https://github.com/dtrinity                                   *
 * ———————————————————————————————————————————————————————————————————————————————— */

pragma solidity 0.8.20;

import "../interface/curve/ICurveOracleWrapper.sol";
import "../interface/curve/ICurveStableNG.sol";
import "@openzeppelin/contracts-5/token/ERC20/extensions/IERC20Metadata.sol";

/**
 * @title CurveOracleWrapper
 * @notice Oracle wrapper for Curve pools
 * @dev Uses get_dy to calculate the effective exchange rate between two tokens
 */
contract CurveOracleWrapper is ICurveOracleWrapper {
    /* Constants */

    uint256 private constant REQUIRED_N_COINS = 2; // Required number of coins in pool

    /* Core state */

    /// @notice Mapping from asset to pool and token index
    mapping(address => PoolConfig) public assetConfigs;

    struct PoolConfig {
        address pool;
        uint256 tokenIndex;
    }

    constructor(
        uint256 _baseCurrencyUnit
    ) ICurveOracleWrapper(_baseCurrencyUnit) {}

    function setAssetConfig(
        address asset,
        address pool
    ) external override onlyRole(ORACLE_MANAGER_ROLE) {
        if (pool == address(0)) revert InvalidPool(pool);

        ICurveStableNG curvePool = ICurveStableNG(pool);

        try curvePool.N_COINS() returns (uint256 nCoins) {
            if (nCoins != REQUIRED_N_COINS) revert InvalidPool(pool);
        } catch {
            revert InvalidPool(pool);
        }

        uint256 tokenIndex = type(uint256).max; // Invalid initial value

        // Find the token index by iterating through coins
        for (uint256 i = 0; i < REQUIRED_N_COINS; i++) {
            if (curvePool.coins(i) == asset) {
                tokenIndex = i;
                break;
            }
        }

        if (tokenIndex == type(uint256).max)
            revert InvalidTokenIndex(pool, tokenIndex);

        assetConfigs[asset] = PoolConfig({
            pool: address(curvePool),
            tokenIndex: tokenIndex
        });

        emit AssetConfigSet(asset, pool, tokenIndex);
    }

    function removeAssetConfig(
        address asset
    ) external override onlyRole(ORACLE_MANAGER_ROLE) {
        delete assetConfigs[asset];
        emit AssetConfigRemoved(asset);
    }

    function getPriceInfo(
        address asset
    ) public view virtual override returns (uint256 price, bool isAlive) {
        PoolConfig memory config = assetConfigs[asset];
        if (address(config.pool) == address(0))
            revert AssetNotConfigured(asset);

        ICurveStableNG curvePool = ICurveStableNG(config.pool);

        uint256 unscaledPrice;
        uint256 scaledPrice;

        // Since we only support 2 coins now
        // If tokenIndex is 0, get price against token1
        // If tokenIndex is 1, get price against token0
        uint256 otherTokenIndex = config.tokenIndex == 0 ? 1 : 0;
        if (config.tokenIndex > 0) {
            // price_oracle of coins[i] against coins[0]
            unscaledPrice = curvePool.price_oracle(config.tokenIndex - 1);
        } else {
            // get the reverse EMA (price of coins[0] with regard to coins[i]):
            unscaledPrice =
                (CURVE_BASE_CURRENCY_UNIT * CURVE_BASE_CURRENCY_UNIT) /
                curvePool.price_oracle(otherTokenIndex - 1);
        }

        // Get multiplier rate
        uint256[] memory rates = curvePool.stored_rates();
        if (rates.length <= config.tokenIndex) {
            scaledPrice = unscaledPrice;
        } else {
            scaledPrice =
                (rates[config.tokenIndex] * unscaledPrice) /
                CURVE_RATE_PRECISION;
        }

        price = _convertToBaseCurrencyUnit(scaledPrice);

        isAlive = price > 0;
        return (price, isAlive);
    }
}

File 15 of 15 : ThresholdingUtils.sol
// SPDX-License-Identifier: MIT
/* ———————————————————————————————————————————————————————————————————————————————— *
 *    _____     ______   ______     __     __   __     __     ______   __  __       *
 *   /\  __-.  /\__  _\ /\  == \   /\ \   /\ "-.\ \   /\ \   /\__  _\ /\ \_\ \      *
 *   \ \ \/\ \ \/_/\ \/ \ \  __<   \ \ \  \ \ \-.  \  \ \ \  \/_/\ \/ \ \____ \     *
 *    \ \____-    \ \_\  \ \_\ \_\  \ \_\  \ \_\\"\_\  \ \_\    \ \_\  \/\_____\    *
 *     \/____/     \/_/   \/_/ /_/   \/_/   \/_/ \/_/   \/_/     \/_/   \/_____/    *
 *                                                                                  *
 * ————————————————————————————————— dtrinity.org ————————————————————————————————— *
 *                                                                                  *
 *                                         ▲                                        *
 *                                        ▲ ▲                                       *
 *                                                                                  *
 * ———————————————————————————————————————————————————————————————————————————————— *
 * dTRINITY Protocol: https://github.com/dtrinity                                   *
 * ———————————————————————————————————————————————————————————————————————————————— */

pragma solidity 0.8.20;

abstract contract ThresholdingUtils {
    /* Types */
    struct ThresholdConfig {
        /// @notice The minimum price after which thresholding is applied. Not a price cap, but a trigger point.
        /// @dev If lowerThresholdInBase == fixedPriceInBase: Acts as an upper threshold
        /// @dev If lowerThresholdInBase < fixedPriceInBase: Acts as "price rounding up" (e.g. if USDC > 0.997 then round to 1)
        /// @dev If lowerThresholdInBase > fixedPriceInBase: Acts as "price rounding down" (e.g. if USDC > 1.003 then round to 1)
        uint256 lowerThresholdInBase;
        uint256 fixedPriceInBase;
    }

    /**
     * @notice Apply threshold to a price value
     * @param priceInBase The price to check against threshold
     * @param thresholdConfig The threshold configuration
     * @return The original price or fixed price based on threshold
     */
    function _applyThreshold(
        uint256 priceInBase,
        ThresholdConfig memory thresholdConfig
    ) internal pure returns (uint256) {
        if (priceInBase > thresholdConfig.lowerThresholdInBase) {
            return thresholdConfig.fixedPriceInBase;
        }
        return priceInBase;
    }
}

Settings
{
  "evmVersion": "london",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": [],
  "viaIR": true,
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"uint256","name":"_baseCurrencyUnit","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"API3InvalidPrice","type":"error"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"AssetNotConfigured","type":"error"},{"inputs":[{"internalType":"address","name":"pool","type":"address"}],"name":"InvalidPool","type":"error"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"tokenIndex","type":"uint256"}],"name":"InvalidTokenIndex","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"PriceIsZero","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"}],"name":"AssetConfigRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenIndex","type":"uint256"}],"name":"AssetConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"}],"name":"CompositeFeedRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"api3Asset","type":"address"},{"indexed":true,"internalType":"address","name":"api3Proxy","type":"address"},{"indexed":false,"internalType":"uint256","name":"curveLowerThresholdInBase","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"curveFixedPriceInBase","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"api3LowerThresholdInBase","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"api3FixedPriceInBase","type":"uint256"}],"name":"CompositeFeedSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"API3_HEARTBEAT","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BASE_CURRENCY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BASE_CURRENCY_UNIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CURVE_BASE_CURRENCY_UNIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CURVE_RATE_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ORACLE_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"assetConfigs","outputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"tokenIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"compositeFeeds","outputs":[{"internalType":"address","name":"api3Asset","type":"address"},{"internalType":"address","name":"api3Proxy","type":"address"},{"components":[{"internalType":"uint256","name":"lowerThresholdInBase","type":"uint256"},{"internalType":"uint256","name":"fixedPriceInBase","type":"uint256"}],"internalType":"struct ThresholdingUtils.ThresholdConfig","name":"curveThreshold","type":"tuple"},{"components":[{"internalType":"uint256","name":"lowerThresholdInBase","type":"uint256"},{"internalType":"uint256","name":"fixedPriceInBase","type":"uint256"}],"internalType":"struct ThresholdingUtils.ThresholdConfig","name":"api3Threshold","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getAssetPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getPriceInfo","outputs":[{"internalType":"uint256","name":"priceInBase","type":"uint256"},{"internalType":"bool","name":"isAlive","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"heartbeatStaleTimeLimit","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"removeAssetConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"removeCompositeFeed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"pool","type":"address"}],"name":"setAssetConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"api3Asset","type":"address"},{"internalType":"address","name":"api3Proxy","type":"address"},{"internalType":"uint256","name":"curveLowerThresholdInBase","type":"uint256"},{"internalType":"uint256","name":"curveFixedPriceInBase","type":"uint256"},{"internalType":"uint256","name":"api3LowerThresholdInBase","type":"uint256"},{"internalType":"uint256","name":"api3FixedPriceInBase","type":"uint256"}],"name":"setCompositeFeed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

60a03461008657601f61144a38819003918201601f19168301916001600160401b0383118484101761008b57808492602094604052833981010312610086575160805261004b336100a1565b506100553361011f565b50610e1063ffffffff19600254161760025560405161126a90816101c082396080518181816105f10152610e580152f35b600080fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b031660008181527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604081205490919060ff1661011b57818052816020526040822081835260205260408220600160ff19825416179055339160008051602061142a8339815191528180a4600190565b5090565b6001600160a01b031660008181527ffb8036e0bab3828a1a1cce97396031bc7ea8a361699e1bc9c4844f3aeee78d6e60205260408120549091907fced6982f480260bdd8ad5cb18ff2854f0306d78d904ad6cc107e8f3a0f526c189060ff166101ba57808352826020526040832082845260205260408320600160ff1982541617905560008051602061142a833981519152339380a4600190565b50509056fe608080604052600436101561001357600080fd5b60003560e01c90816301ffc9a714610a515750806322dd40ef14610134578063248a9ca314610a225780632ecac6fc146109fe5780632f2ff15d146109bf57806336568abe14610978578063519ffff1146108fa5780637609d7f6146108a957806381a69511146106145780638c89b64f146105d95780638edbf436146105a857806391d148541461055b578063a085a79314610311578063a217fddf14610222578063b3596f07146102ba578063bfc69e1c1461027f578063d547741f1461023e578063e19f470014610222578063f667e428146101bb578063f99256d514610139578063fbc12e5c146101345763ffceb4151461011157600080fd5b3461012f57600036600319011261012f576020604051620151808152f35b600080fd5b610aa4565b3461012f57602036600319011261012f5760c06001600160a01b038061015d610add565b1660005260036020526020604060002081838254169360018301541691610192600461018b60028401610b63565b9201610b63565b9260405195865282860152805160408601520151606084015280516080840152015160a0820152f35b3461012f57602036600319011261012f576101d4610add565b6101dc610b81565b6001600160a01b031660008181526001602081905260408220828155018190557fecd58386925932344b9d411955c289f1af8401c69c40aa31dfcab72b21759f459080a2005b3461012f57600036600319011261012f57602060405160008152f35b3461012f57604036600319011261012f5761027d60043561025d610ac7565b90806000526000602052610278600160406000200154610bfb565b610c9f565b005b3461012f57600036600319011261012f5760206040517fced6982f480260bdd8ad5cb18ff2854f0306d78d904ad6cc107e8f3a0f526c188152f35b3461012f57602036600319011261012f576102d3610add565b6102dc81610d84565b919091156102ef57602082604051908152f35b6040516349e1879f60e11b81526001600160a01b039091166004820152602490fd5b3461012f57604036600319011261012f5761032a610add565b610332610ac7565b9061033b610b81565b6001600160a01b0382811692831561054257604051630293577560e41b8152602092908381600481895afa60009181610513575b5061038d57604051630f4c971b60e21b815260048101879052602490fd5b6002036104fa57928316926000199160005b6002811061044e575b5060001983146104225750907fe15adf635f0230f04a10c533ae4edc6ee52f6aab68fd00497903ec8ffac72e0a92916001604051916103e683610af3565b878352848301908482528760005282865260406000209351166bffffffffffffffffffffffff60a01b84541617835551910155604051908152a3005b60405163152a07eb60e11b81526001600160a01b03919091166004820152602481019290925250604490fd5b60405163c661065760e01b81526004810182905285816024818b5afa9081156104ee57879185916000916104b3575b5016146104ab5760001981146104955760010161039f565b634e487b7160e01b600052601160045260246000fd5b9250866103a8565b925050508581813d83116104e7575b6104cc8183610b41565b8101031261012f5751838116810361012f578387918a61047d565b503d6104c2565b6040513d6000823e3d90fd5b604051630f4c971b60e21b815260048101869052602490fd5b9091508481813d831161053b575b61052b8183610b41565b8101031261012f5751908761036f565b503d610521565b604051630f4c971b60e21b815260048101859052602490fd5b3461012f57604036600319011261012f57610574610ac7565b600435600052600060205260406000209060018060a01b0316600052602052602060ff604060002054166040519015158152f35b3461012f57602036600319011261012f5760406105cb6105c6610add565b610d84565b825191825215156020820152f35b3461012f57600036600319011261012f5760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b3461012f5760e036600319011261012f5761062d610add565b610635610ac7565b906044356001600160a01b038116810361012f57610651610b81565b60018060a01b0382166000526001602052604060002060405161067381610af3565b60206001808060a01b038454169384845201549101521561088857604080516315f789a960e21b815290816004816001600160a01b0386165afa9081156104ee57600090600092610855575b50600090601b0b139081159161082c575b5061080b576040516106e181610af3565b60643581526084356020820152600560206040516106fe81610af3565b60a435815260c43582820152816040519461071886610b25565b60018060a01b038916865281860160018060a01b0388168152604087019182526060870193845260018060a01b0389166000526003835260406000209660018060a01b039051166bffffffffffffffffffffffff60a01b9081895416178855600188019160018060a01b0390511690825416179055518051600287015501516003850155518051600485015501519101557f850d28bf2d8acb532d6827d537f97debaff0eca8e001f53619215543091448e76080604051926064358452608435602085015260a435604085015260c435606085015260018060a01b03169460018060a01b03169360018060a01b031692a4005b6040516314de66af60e31b81526001600160a01b0384166004820152602490fd5b6108369150610d42565b61084a63ffffffff91826002541690610d59565b4291161115846106d0565b6000925061087b915060403d604011610881575b6108738183610b41565b810190610d14565b916106bf565b503d610869565b604051630f10d83760e11b81526001600160a01b0383166004820152602490fd5b3461012f57602036600319011261012f576001600160a01b03806108cb610add565b1660009081526001602081815260409283902080549201548351949092166001600160a01b0316845283015290f35b3461012f57602036600319011261012f57610913610add565b61091b610b81565b60018060a01b0316806000526003602052600060056040822082815582600182015582600282015582600382015582600482015501557fdabc58d0456c50872fa82879bc9ce7f6a455b4372db632857a62de4abd099691600080a2005b3461012f57604036600319011261012f57610991610ac7565b336001600160a01b038216036109ad5761027d90600435610c9f565b60405163334bd91960e11b8152600490fd5b3461012f57604036600319011261012f5761027d6004356109de610ac7565b908060005260006020526109f9600160406000200154610bfb565b610c21565b3461012f57600036600319011261012f57602063ffffffff60025416604051908152f35b3461012f57602036600319011261012f5760043560005260006020526020600160406000200154604051908152f35b3461012f57602036600319011261012f576004359063ffffffff60e01b821680920361012f57602091637965db0b60e01b8114908115610a93575b5015158152f35b6301ffc9a760e01b14905083610a8c565b3461012f57600036600319011261012f576020604051670de0b6b3a76400008152f35b602435906001600160a01b038216820361012f57565b600435906001600160a01b038216820361012f57565b6040810190811067ffffffffffffffff821117610b0f57604052565b634e487b7160e01b600052604160045260246000fd5b6080810190811067ffffffffffffffff821117610b0f57604052565b90601f8019910116810190811067ffffffffffffffff821117610b0f57604052565b90604051610b7081610af3565b602060018294805484520154910152565b3360009081527ffb8036e0bab3828a1a1cce97396031bc7ea8a361699e1bc9c4844f3aeee78d6e60205260409020547fced6982f480260bdd8ad5cb18ff2854f0306d78d904ad6cc107e8f3a0f526c189060ff1615610bdd5750565b6044906040519063e2517d3f60e01b82523360048301526024820152fd5b80600052600060205260406000203360005260205260ff6040600020541615610bdd5750565b9060009180835282602052604083209160018060a01b03169182845260205260ff60408420541615600014610c9a57808352826020526040832082845260205260408320600160ff198254161790557f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d339380a4600190565b505090565b9060009180835282602052604083209160018060a01b03169182845260205260ff604084205416600014610c9a5780835282602052604083208284526020526040832060ff1981541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a4600190565b919082604091031261012f57815180601b0b810361012f5760209092015163ffffffff8116810361012f5790565b906201518063ffffffff8093160191821161049557565b91909163ffffffff8080941691160191821161049557565b8181029291811591840414171561049557565b60018060a01b03809116916000918383526001926020848152604095868320968051610daf81610af3565b87868a5416998a8352015498848201998a5215611206578590511697805115806000146111fe5760ff895b169061116357508051600019810199908a1161114f57825199636872765360e01b8b5260048b0152848a602481845afa8015611145578690611111575b869798999a50915b83519788809363fd0684b160e01b825260049a8b915afa918215611107578792611056575b50815190519081811161101b57505050905b7f0000000000000000000000000000000000000000000000000000000000000000968792610e8e670de0b6b3a7640000948592610d71565b0493841561100d57865260038552818620948251610eab81610b25565b828754168152828c88015416918101918252610eda89610ecd60028a01610b63565b98868401998a5201610b63565b9660608201978852518051610ffa575b5051821615610fed575182516315f789a960e21b815291839183918a918391165afa908115610fe35786928792610fc2575b50508582601b0b139081610f9a575b5015610f8e57610f5c93929190610f4c9088906001600160e01b0316610d71565b0491518051610f7d575b50610d71565b918315610f6a575050049190565b634e487b7160e01b825260129052602490fd5b610f87919261121e565b9038610f56565b50505050935050508190565b610fa49150610d42565b610fb863ffffffff91826002541690610d59565b4291161138610f2b565b610fdc935080919250903d10610881576108738183610b41565b3880610f1c565b82513d88823e3d90fd5b5050505093505050509190565b6110069084929761121e565b9590610eea565b505050505050935050508190565b8110156110435760051b01840151670de0b6b3a76400009161103c91610d71565b0490610e56565b634e487b7160e01b875260328852602487fd5b9091503d8088833e6110688183610b41565b8101868282031261110357815167ffffffffffffffff928382116110e8570181601f820112156110ff5780519283116110ec578260051b908651936110af8a840186610b41565b845288808501928201019283116110e85788809101915b8383106110d857505050509038610e44565b82518152918101918991016110c6565b8980fd5b634e487b7160e01b895260418a52602489fd5b8880fd5b8780fd5b84513d89823e3d90fd5b50848a813d831161113e575b6111278183610b41565b8101031261113a57985197988998610e17565b8580fd5b503d61111d565b83513d88823e3d90fd5b634e487b7160e01b86526011600452602486fd5b600019810199908a1161114f57825199636872765360e01b8b5260048b0152848a602481845afa998a1561114557869a6111cf575b5089156111bb5785969798996ec097ce7bc90715b34b9f10000000000491610e1f565b634e487b7160e01b86526012600452602486fd5b9099508481813d83116111f7575b6111e78183610b41565b8101031261113a57519838611198565b503d6111dd565b60ff86610dda565b8151630f10d83760e11b815260048101849052602490fd5b908051821161122b575090565b6020915001519056fea26469706673582212204229ee23bf16241261683918880c83344dddeec14278f5efe427ff3df032833f64736f6c634300081400332f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d0000000000000000000000000000000000000000000000000000000005f5e100

Deployed Bytecode

0x608080604052600436101561001357600080fd5b60003560e01c90816301ffc9a714610a515750806322dd40ef14610134578063248a9ca314610a225780632ecac6fc146109fe5780632f2ff15d146109bf57806336568abe14610978578063519ffff1146108fa5780637609d7f6146108a957806381a69511146106145780638c89b64f146105d95780638edbf436146105a857806391d148541461055b578063a085a79314610311578063a217fddf14610222578063b3596f07146102ba578063bfc69e1c1461027f578063d547741f1461023e578063e19f470014610222578063f667e428146101bb578063f99256d514610139578063fbc12e5c146101345763ffceb4151461011157600080fd5b3461012f57600036600319011261012f576020604051620151808152f35b600080fd5b610aa4565b3461012f57602036600319011261012f5760c06001600160a01b038061015d610add565b1660005260036020526020604060002081838254169360018301541691610192600461018b60028401610b63565b9201610b63565b9260405195865282860152805160408601520151606084015280516080840152015160a0820152f35b3461012f57602036600319011261012f576101d4610add565b6101dc610b81565b6001600160a01b031660008181526001602081905260408220828155018190557fecd58386925932344b9d411955c289f1af8401c69c40aa31dfcab72b21759f459080a2005b3461012f57600036600319011261012f57602060405160008152f35b3461012f57604036600319011261012f5761027d60043561025d610ac7565b90806000526000602052610278600160406000200154610bfb565b610c9f565b005b3461012f57600036600319011261012f5760206040517fced6982f480260bdd8ad5cb18ff2854f0306d78d904ad6cc107e8f3a0f526c188152f35b3461012f57602036600319011261012f576102d3610add565b6102dc81610d84565b919091156102ef57602082604051908152f35b6040516349e1879f60e11b81526001600160a01b039091166004820152602490fd5b3461012f57604036600319011261012f5761032a610add565b610332610ac7565b9061033b610b81565b6001600160a01b0382811692831561054257604051630293577560e41b8152602092908381600481895afa60009181610513575b5061038d57604051630f4c971b60e21b815260048101879052602490fd5b6002036104fa57928316926000199160005b6002811061044e575b5060001983146104225750907fe15adf635f0230f04a10c533ae4edc6ee52f6aab68fd00497903ec8ffac72e0a92916001604051916103e683610af3565b878352848301908482528760005282865260406000209351166bffffffffffffffffffffffff60a01b84541617835551910155604051908152a3005b60405163152a07eb60e11b81526001600160a01b03919091166004820152602481019290925250604490fd5b60405163c661065760e01b81526004810182905285816024818b5afa9081156104ee57879185916000916104b3575b5016146104ab5760001981146104955760010161039f565b634e487b7160e01b600052601160045260246000fd5b9250866103a8565b925050508581813d83116104e7575b6104cc8183610b41565b8101031261012f5751838116810361012f578387918a61047d565b503d6104c2565b6040513d6000823e3d90fd5b604051630f4c971b60e21b815260048101869052602490fd5b9091508481813d831161053b575b61052b8183610b41565b8101031261012f5751908761036f565b503d610521565b604051630f4c971b60e21b815260048101859052602490fd5b3461012f57604036600319011261012f57610574610ac7565b600435600052600060205260406000209060018060a01b0316600052602052602060ff604060002054166040519015158152f35b3461012f57602036600319011261012f5760406105cb6105c6610add565b610d84565b825191825215156020820152f35b3461012f57600036600319011261012f5760206040517f0000000000000000000000000000000000000000000000000000000005f5e1008152f35b3461012f5760e036600319011261012f5761062d610add565b610635610ac7565b906044356001600160a01b038116810361012f57610651610b81565b60018060a01b0382166000526001602052604060002060405161067381610af3565b60206001808060a01b038454169384845201549101521561088857604080516315f789a960e21b815290816004816001600160a01b0386165afa9081156104ee57600090600092610855575b50600090601b0b139081159161082c575b5061080b576040516106e181610af3565b60643581526084356020820152600560206040516106fe81610af3565b60a435815260c43582820152816040519461071886610b25565b60018060a01b038916865281860160018060a01b0388168152604087019182526060870193845260018060a01b0389166000526003835260406000209660018060a01b039051166bffffffffffffffffffffffff60a01b9081895416178855600188019160018060a01b0390511690825416179055518051600287015501516003850155518051600485015501519101557f850d28bf2d8acb532d6827d537f97debaff0eca8e001f53619215543091448e76080604051926064358452608435602085015260a435604085015260c435606085015260018060a01b03169460018060a01b03169360018060a01b031692a4005b6040516314de66af60e31b81526001600160a01b0384166004820152602490fd5b6108369150610d42565b61084a63ffffffff91826002541690610d59565b4291161115846106d0565b6000925061087b915060403d604011610881575b6108738183610b41565b810190610d14565b916106bf565b503d610869565b604051630f10d83760e11b81526001600160a01b0383166004820152602490fd5b3461012f57602036600319011261012f576001600160a01b03806108cb610add565b1660009081526001602081815260409283902080549201548351949092166001600160a01b0316845283015290f35b3461012f57602036600319011261012f57610913610add565b61091b610b81565b60018060a01b0316806000526003602052600060056040822082815582600182015582600282015582600382015582600482015501557fdabc58d0456c50872fa82879bc9ce7f6a455b4372db632857a62de4abd099691600080a2005b3461012f57604036600319011261012f57610991610ac7565b336001600160a01b038216036109ad5761027d90600435610c9f565b60405163334bd91960e11b8152600490fd5b3461012f57604036600319011261012f5761027d6004356109de610ac7565b908060005260006020526109f9600160406000200154610bfb565b610c21565b3461012f57600036600319011261012f57602063ffffffff60025416604051908152f35b3461012f57602036600319011261012f5760043560005260006020526020600160406000200154604051908152f35b3461012f57602036600319011261012f576004359063ffffffff60e01b821680920361012f57602091637965db0b60e01b8114908115610a93575b5015158152f35b6301ffc9a760e01b14905083610a8c565b3461012f57600036600319011261012f576020604051670de0b6b3a76400008152f35b602435906001600160a01b038216820361012f57565b600435906001600160a01b038216820361012f57565b6040810190811067ffffffffffffffff821117610b0f57604052565b634e487b7160e01b600052604160045260246000fd5b6080810190811067ffffffffffffffff821117610b0f57604052565b90601f8019910116810190811067ffffffffffffffff821117610b0f57604052565b90604051610b7081610af3565b602060018294805484520154910152565b3360009081527ffb8036e0bab3828a1a1cce97396031bc7ea8a361699e1bc9c4844f3aeee78d6e60205260409020547fced6982f480260bdd8ad5cb18ff2854f0306d78d904ad6cc107e8f3a0f526c189060ff1615610bdd5750565b6044906040519063e2517d3f60e01b82523360048301526024820152fd5b80600052600060205260406000203360005260205260ff6040600020541615610bdd5750565b9060009180835282602052604083209160018060a01b03169182845260205260ff60408420541615600014610c9a57808352826020526040832082845260205260408320600160ff198254161790557f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d339380a4600190565b505090565b9060009180835282602052604083209160018060a01b03169182845260205260ff604084205416600014610c9a5780835282602052604083208284526020526040832060ff1981541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a4600190565b919082604091031261012f57815180601b0b810361012f5760209092015163ffffffff8116810361012f5790565b906201518063ffffffff8093160191821161049557565b91909163ffffffff8080941691160191821161049557565b8181029291811591840414171561049557565b60018060a01b03809116916000918383526001926020848152604095868320968051610daf81610af3565b87868a5416998a8352015498848201998a5215611206578590511697805115806000146111fe5760ff895b169061116357508051600019810199908a1161114f57825199636872765360e01b8b5260048b0152848a602481845afa8015611145578690611111575b869798999a50915b83519788809363fd0684b160e01b825260049a8b915afa918215611107578792611056575b50815190519081811161101b57505050905b7f0000000000000000000000000000000000000000000000000000000005f5e100968792610e8e670de0b6b3a7640000948592610d71565b0493841561100d57865260038552818620948251610eab81610b25565b828754168152828c88015416918101918252610eda89610ecd60028a01610b63565b98868401998a5201610b63565b9660608201978852518051610ffa575b5051821615610fed575182516315f789a960e21b815291839183918a918391165afa908115610fe35786928792610fc2575b50508582601b0b139081610f9a575b5015610f8e57610f5c93929190610f4c9088906001600160e01b0316610d71565b0491518051610f7d575b50610d71565b918315610f6a575050049190565b634e487b7160e01b825260129052602490fd5b610f87919261121e565b9038610f56565b50505050935050508190565b610fa49150610d42565b610fb863ffffffff91826002541690610d59565b4291161138610f2b565b610fdc935080919250903d10610881576108738183610b41565b3880610f1c565b82513d88823e3d90fd5b5050505093505050509190565b6110069084929761121e565b9590610eea565b505050505050935050508190565b8110156110435760051b01840151670de0b6b3a76400009161103c91610d71565b0490610e56565b634e487b7160e01b875260328852602487fd5b9091503d8088833e6110688183610b41565b8101868282031261110357815167ffffffffffffffff928382116110e8570181601f820112156110ff5780519283116110ec578260051b908651936110af8a840186610b41565b845288808501928201019283116110e85788809101915b8383106110d857505050509038610e44565b82518152918101918991016110c6565b8980fd5b634e487b7160e01b895260418a52602489fd5b8880fd5b8780fd5b84513d89823e3d90fd5b50848a813d831161113e575b6111278183610b41565b8101031261113a57985197988998610e17565b8580fd5b503d61111d565b83513d88823e3d90fd5b634e487b7160e01b86526011600452602486fd5b600019810199908a1161114f57825199636872765360e01b8b5260048b0152848a602481845afa998a1561114557869a6111cf575b5089156111bb5785969798996ec097ce7bc90715b34b9f10000000000491610e1f565b634e487b7160e01b86526012600452602486fd5b9099508481813d83116111f7575b6111e78183610b41565b8101031261113a57519838611198565b503d6111dd565b60ff86610dda565b8151630f10d83760e11b815260048101849052602490fd5b908051821161122b575090565b6020915001519056fea26469706673582212204229ee23bf16241261683918880c83344dddeec14278f5efe427ff3df032833f64736f6c63430008140033

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

0000000000000000000000000000000000000000000000000000000005f5e100

-----Decoded View---------------
Arg [0] : _baseCurrencyUnit (uint256): 100000000

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000005f5e100


Block Transaction Difficulty 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.