Blockchain / Global / Address

Contract

0x48c2c4e35a487b5d85C2aef394d34aD4959FA257

Balance
0 SOMI
Transactions sent
1
Type
Contract · 10,784 bytes of code

AirseekerRegistry Verified

Compiler
solc 0.8.27+commit.40a35a09
Language
Solidity
Optimization
Yes, 1000 runs
EVM version
paris
License
—
Verified
2026-10-12

contracts/api3-server-v1/AirseekerRegistry.sol

and 17 more files

Solidity
// SPDX-License-Identifier: MIT
pragma solidity 0.8.27;

import "../vendor/@openzeppelin/contracts@5.0.2/access/Ownable.sol";
import "../utils/ExtendedSelfMulticall.sol";
import "./interfaces/IAirseekerRegistry.sol";
import "../vendor/@openzeppelin/contracts@5.0.2/utils/structs/EnumerableSet.sol";
import "./interfaces/IApi3ServerV1.sol";

/// @title A contract where active data feeds and their specs are registered by
/// the contract owner for the respective Airseeker to refer to
/// @notice Airseeker is an application that pushes API provider-signed data to
/// chain when certain conditions are met so that the data feeds served on the
/// Api3ServerV1 contract are updated according to the respective specs. In
/// other words, this contract is an on-chain configuration file for an
/// Airseeker (or multiple Airseekers in a setup with redundancy).
/// The Airseeker must know which data feeds are active (and thus need to be
/// updated), the constituting Airnode (the oracle node that API providers
/// operate to sign data) addresses and request template IDs, what the
/// respective on-chain data feed values are, what the update parameters are,
/// and the URL of the signed APIs (from which Airseeker can fetch signed data)
/// that are hosted by the respective API providers.
/// The contract owner is responsible with leaving the state of this contract
/// in a way that Airseeker expects. For example, if a dAPI name is activated
/// without registering the respective data feed, the Airseeker will not have
/// access to the data that it needs to execute updates.
contract AirseekerRegistry is
    Ownable,
    ExtendedSelfMulticall,
    IAirseekerRegistry
{
    using EnumerableSet for EnumerableSet.Bytes32Set;

    /// @notice Maximum number of Beacons in a Beacon set that can be
    /// registered
    /// @dev Api3ServerV1 introduces the concept of a Beacon, which is a
    /// single-source data feed. Api3ServerV1 allows Beacons to be read
    /// individually, or arbitrary combinations of them to be aggregated
    /// on-chain to form multiple-source data feeds, which are called Beacon
    /// sets. This contract does not support Beacon sets that consist of more
    /// than `MAXIMUM_BEACON_COUNT_IN_SET` Beacons to be registered.
    uint256 public constant override MAXIMUM_BEACON_COUNT_IN_SET = 21;

    /// @notice Maximum encoded update parameters length
    uint256 public constant override MAXIMUM_UPDATE_PARAMETERS_LENGTH = 1024;

    /// @notice Maximum signed API URL length
    uint256 public constant override MAXIMUM_SIGNED_API_URL_LENGTH = 256;

    /// @notice Api3ServerV1 contract address
    address public immutable override api3ServerV1;

    /// @notice Airnode address to signed API URL
    /// @dev An Airseeker can be configured to refer to additional signed APIs
    /// than the ones whose URLs are stored in this contract for redundancy
    mapping(address => string) public override airnodeToSignedApiUrl;

    /// @notice Data feed ID to encoded details
    mapping(bytes32 => bytes) public override dataFeedIdToDetails;

    // Api3ServerV1 uses Beacon IDs (see the `deriveBeaconId()` implementation)
    // and Beacon set IDs (see the `deriveBeaconSetId()` implementation) to
    // address data feeds. We use data feed ID as a general term to refer to a
    // Beacon ID/Beacon set ID.
    // A data feed ID is immutable (i.e., it always points to the same Beacon
    // or Beacon set). Api3ServerV1 allows a dAPI name to be pointed to a data
    // feed ID by privileged accounts to implement a mutable data feed
    // addressing scheme.
    // If the data feed ID or dAPI name should be used to read a data feed
    // depends on the use case. To support both schemes, AirseekerRegistry
    // allows data feeds specs to be defined with either the data feed ID or
    // the dAPI name.
    EnumerableSet.Bytes32Set private activeDataFeedIds;

    EnumerableSet.Bytes32Set private activeDapiNames;

    // Considering that the update parameters are typically reused between data
    // feeds, a hash map is used to avoid storing the same update parameters
    // redundantly
    mapping(bytes32 => bytes32) private dataFeedIdToUpdateParametersHash;

    mapping(bytes32 => bytes32) private dapiNameToUpdateParametersHash;

    mapping(bytes32 => bytes) private updateParametersHashToValue;

    // Length of `abi.encode(address, bytes32)`
    uint256 private constant DATA_FEED_DETAILS_LENGTH_FOR_SINGLE_BEACON =
        32 + 32;

    // Length of `abi.encode(address[2], bytes32[2])`
    uint256
        private constant DATA_FEED_DETAILS_LENGTH_FOR_BEACON_SET_WITH_TWO_BEACONS =
        32 + 32 + (32 + 2 * 32) + (32 + 2 * 32);

    // Length of
    // `abi.encode(address[MAXIMUM_BEACON_COUNT_IN_SET], bytes32[MAXIMUM_BEACON_COUNT_IN_SET])`
    uint256 private constant MAXIMUM_DATA_FEED_DETAILS_LENGTH =
        32 +
            32 +
            (32 + MAXIMUM_BEACON_COUNT_IN_SET * 32) +
            (32 + MAXIMUM_BEACON_COUNT_IN_SET * 32);

    /// @dev Reverts if the data feed ID is zero
    /// @param dataFeedId Data feed ID
    modifier onlyNonZeroDataFeedId(bytes32 dataFeedId) {
        require(dataFeedId != bytes32(0), "Data feed ID zero");
        _;
    }

    /// @dev Reverts if the dAPI name is zero
    /// @param dapiName dAPI name
    modifier onlyNonZeroDapiName(bytes32 dapiName) {
        require(dapiName != bytes32(0), "dAPI name zero");
        _;
    }

    /// @dev Reverts if the update parameters are too long
    /// @param updateParameters Update parameters
    modifier onlyValidUpdateParameters(bytes calldata updateParameters) {
        require(
            updateParameters.length <= MAXIMUM_UPDATE_PARAMETERS_LENGTH,
            "Update parameters too long"
        );
        _;
    }

    /// @param owner_ Owner address
    /// @param api3ServerV1_ Api3ServerV1 contract address
    constructor(address owner_, address api3ServerV1_) Ownable(owner_) {
        require(api3ServerV1_ != address(0), "Api3ServerV1 address zero");
        api3ServerV1 = api3ServerV1_;
    }

    /// @notice Returns the owner address
    /// @return Owner address
    function owner() public view override(Ownable, IOwnable) returns (address) {
        return super.owner();
    }

    /// @notice Overriden to be disabled
    function renounceOwnership() public pure override(Ownable, IOwnable) {
        revert("Ownership cannot be renounced");
    }

    /// @notice Overriden to be disabled
    function transferOwnership(
        address
    ) public pure override(Ownable, IOwnable) {
        revert("Ownership cannot be transferred");
    }

    /// @notice Called by the owner to set the data feed ID to be activated
    /// @param dataFeedId Data feed ID
    function setDataFeedIdToBeActivated(
        bytes32 dataFeedId
    ) external override onlyOwner onlyNonZeroDataFeedId(dataFeedId) {
        if (activeDataFeedIds.add(dataFeedId)) {
            emit ActivatedDataFeedId(dataFeedId);
        }
    }

    /// @notice Called by the owner to set the dAPI name to be activated
    /// @param dapiName dAPI name
    function setDapiNameToBeActivated(
        bytes32 dapiName
    ) external override onlyOwner onlyNonZeroDapiName(dapiName) {
        if (activeDapiNames.add(dapiName)) {
            emit ActivatedDapiName(dapiName);
        }
    }

    /// @notice Called by the owner to set the data feed ID to be deactivated
    /// @param dataFeedId Data feed ID
    function setDataFeedIdToBeDeactivated(
        bytes32 dataFeedId
    ) external override onlyOwner onlyNonZeroDataFeedId(dataFeedId) {
        if (activeDataFeedIds.remove(dataFeedId)) {
            emit DeactivatedDataFeedId(dataFeedId);
        }
    }

    /// @notice Called by the owner to set the dAPI name to be deactivated
    /// @param dapiName dAPI name
    function setDapiNameToBeDeactivated(
        bytes32 dapiName
    ) external override onlyOwner onlyNonZeroDapiName(dapiName) {
        if (activeDapiNames.remove(dapiName)) {
            emit DeactivatedDapiName(dapiName);
        }
    }

    /// @notice Called by the owner to set the data feed ID update parameters.
    /// The update parameters must be encoded in a format that Airseeker
    /// expects.
    /// @param dataFeedId Data feed ID
    /// @param updateParameters Update parameters
    function setDataFeedIdUpdateParameters(
        bytes32 dataFeedId,
        bytes calldata updateParameters
    )
        external
        override
        onlyOwner
        onlyNonZeroDataFeedId(dataFeedId)
        onlyValidUpdateParameters(updateParameters)
    {
        bytes32 updateParametersHash = keccak256(updateParameters);
        if (
            dataFeedIdToUpdateParametersHash[dataFeedId] != updateParametersHash
        ) {
            dataFeedIdToUpdateParametersHash[dataFeedId] = updateParametersHash;
            if (
                updateParametersHashToValue[updateParametersHash].length !=
                updateParameters.length
            ) {
                updateParametersHashToValue[
                    updateParametersHash
                ] = updateParameters;
            }
            emit UpdatedDataFeedIdUpdateParameters(
                dataFeedId,
                updateParameters
            );
        }
    }

    /// @notice Called by the owner to set the dAPI name update parameters.
    /// The update parameters must be encoded in a format that Airseeker
    /// expects.
    /// @param dapiName dAPI name
    /// @param updateParameters Update parameters
    function setDapiNameUpdateParameters(
        bytes32 dapiName,
        bytes calldata updateParameters
    )
        external
        override
        onlyOwner
        onlyNonZeroDapiName(dapiName)
        onlyValidUpdateParameters(updateParameters)
    {
        bytes32 updateParametersHash = keccak256(updateParameters);
        if (dapiNameToUpdateParametersHash[dapiName] != updateParametersHash) {
            dapiNameToUpdateParametersHash[dapiName] = updateParametersHash;
            if (
                updateParametersHashToValue[updateParametersHash].length !=
                updateParameters.length
            ) {
                updateParametersHashToValue[
                    updateParametersHash
                ] = updateParameters;
            }
            emit UpdatedDapiNameUpdateParameters(dapiName, updateParameters);
        }
    }

    /// @notice Called by the owner to set the signed API URL for the Airnode.
    /// The signed API must implement the specific interface that Airseeker
    /// expects.
    /// @param airnode Airnode address
    /// @param signedApiUrl Signed API URL
    function setSignedApiUrl(
        address airnode,
        string calldata signedApiUrl
    ) external override onlyOwner {
        require(airnode != address(0), "Airnode address zero");
        require(
            abi.encodePacked(signedApiUrl).length <=
                MAXIMUM_SIGNED_API_URL_LENGTH,
            "Signed API URL too long"
        );
        if (
            keccak256(abi.encodePacked(airnodeToSignedApiUrl[airnode])) !=
            keccak256(abi.encodePacked(signedApiUrl))
        ) {
            airnodeToSignedApiUrl[airnode] = signedApiUrl;
            emit UpdatedSignedApiUrl(airnode, signedApiUrl);
        }
    }

    /// @notice Registers the data feed. In the case that the data feed is a
    /// Beacon, the details should be the ABI-encoded Airnode address and
    /// template ID. In the case that the data feed is a Beacon set, the
    /// details should be the ABI-encoded Airnode addresses array and template
    /// IDs array.
    /// @param dataFeedDetails Data feed details
    /// @return dataFeedId Data feed ID
    function registerDataFeed(
        bytes calldata dataFeedDetails
    ) external override returns (bytes32 dataFeedId) {
        uint256 dataFeedDetailsLength = dataFeedDetails.length;
        if (
            dataFeedDetailsLength == DATA_FEED_DETAILS_LENGTH_FOR_SINGLE_BEACON
        ) {
            // dataFeedId maps to a Beacon
            (address airnode, bytes32 templateId) = abi.decode(
                dataFeedDetails,
                (address, bytes32)
            );
            require(airnode != address(0), "Airnode address zero");
            dataFeedId = deriveBeaconId(airnode, templateId);
        } else if (
            dataFeedDetailsLength >=
            DATA_FEED_DETAILS_LENGTH_FOR_BEACON_SET_WITH_TWO_BEACONS
        ) {
            require(
                dataFeedDetailsLength <= MAXIMUM_DATA_FEED_DETAILS_LENGTH,
                "Data feed details too long"
            );
            (address[] memory airnodes, bytes32[] memory templateIds) = abi
                .decode(dataFeedDetails, (address[], bytes32[]));
            require(
                abi.encode(airnodes, templateIds).length ==
                    dataFeedDetailsLength,
                "Data feed details trail"
            );
            uint256 beaconCount = airnodes.length;
            require(
                beaconCount == templateIds.length,
                "Parameter length mismatch"
            );
            bytes32[] memory beaconIds = new bytes32[](beaconCount);
            for (uint256 ind = 0; ind < beaconCount; ind++) {
                require(airnodes[ind] != address(0), "Airnode address zero");
                beaconIds[ind] = deriveBeaconId(
                    airnodes[ind],
                    templateIds[ind]
                );
            }
            dataFeedId = deriveBeaconSetId(beaconIds);
        } else {
            revert("Data feed details too short");
        }
        if (dataFeedIdToDetails[dataFeedId].length != dataFeedDetailsLength) {
            dataFeedIdToDetails[dataFeedId] = dataFeedDetails;
            emit RegisteredDataFeed(dataFeedId, dataFeedDetails);
        }
    }

    /// @notice In an imaginary array consisting of the active data feed IDs
    /// and active dAPI names, picks the index-th identifier, and returns all
    /// data about the respective data feed that is available. Whenever data is
    /// not available (including the case where index does not correspond to an
    /// active data feed), returns empty values.
    /// @dev Airseeker uses this function to get all the data it needs about an
    /// active data feed with a single RPC call.
    /// Since active data feed IDs and dAPI names are kept in respective
    /// EnumerableSet types, addition and removal of items to these may change
    /// the order of the remaining items. Therefore, do not depend on an index
    /// to address a specific data feed consistently.
    /// @param index Index
    /// @return dataFeedId Data feed ID
    /// @return dapiName dAPI name (`bytes32(0)` if the active data feed is
    /// identified by a data feed ID)
    /// @return dataFeedDetails Data feed details
    /// @return dataFeedValue Data feed value read from Api3ServerV1
    /// @return dataFeedTimestamp Data feed timestamp read from Api3ServerV1
    /// @return beaconValues Beacon values read from Api3ServerV1
    /// @return beaconTimestamps Beacon timestamps read from Api3ServerV1
    /// @return updateParameters Update parameters
    /// @return signedApiUrls Signed API URLs of the Beacon Airnodes
    function activeDataFeed(
        uint256 index
    )
        external
        view
        override
        returns (
            bytes32 dataFeedId,
            bytes32 dapiName,
            bytes memory dataFeedDetails,
            int224 dataFeedValue,
            uint32 dataFeedTimestamp,
            int224[] memory beaconValues,
            uint32[] memory beaconTimestamps,
            bytes memory updateParameters,
            string[] memory signedApiUrls
        )
    {
        uint256 activeDataFeedIdsLength = activeDataFeedIdCount();
        if (index < activeDataFeedIdsLength) {
            dataFeedId = activeDataFeedIds.at(index);
            updateParameters = dataFeedIdToUpdateParameters(dataFeedId);
        } else if (index < activeDataFeedIdsLength + activeDapiNames.length()) {
            dapiName = activeDapiNames.at(index - activeDataFeedIdsLength);
            dataFeedId = IApi3ServerV1(api3ServerV1).dapiNameHashToDataFeedId(
                keccak256(abi.encodePacked(dapiName))
            );
            updateParameters = dapiNameToUpdateParameters(dapiName);
        }
        if (dataFeedId != bytes32(0)) {
            dataFeedDetails = dataFeedIdToDetails[dataFeedId];
            (dataFeedValue, dataFeedTimestamp) = IApi3ServerV1(api3ServerV1)
                .dataFeeds(dataFeedId);
        }
        if (dataFeedDetails.length != 0) {
            if (
                dataFeedDetails.length ==
                DATA_FEED_DETAILS_LENGTH_FOR_SINGLE_BEACON
            ) {
                beaconValues = new int224[](1);
                beaconTimestamps = new uint32[](1);
                signedApiUrls = new string[](1);
                (address airnode, bytes32 templateId) = abi.decode(
                    dataFeedDetails,
                    (address, bytes32)
                );
                (beaconValues[0], beaconTimestamps[0]) = IApi3ServerV1(
                    api3ServerV1
                ).dataFeeds(deriveBeaconId(airnode, templateId));
                signedApiUrls[0] = airnodeToSignedApiUrl[airnode];
            } else {
                (address[] memory airnodes, bytes32[] memory templateIds) = abi
                    .decode(dataFeedDetails, (address[], bytes32[]));
                uint256 beaconCount = airnodes.length;
                beaconValues = new int224[](beaconCount);
                beaconTimestamps = new uint32[](beaconCount);
                signedApiUrls = new string[](beaconCount);
                for (uint256 ind = 0; ind < beaconCount; ind++) {
                    (beaconValues[ind], beaconTimestamps[ind]) = IApi3ServerV1(
                        api3ServerV1
                    ).dataFeeds(
                            deriveBeaconId(airnodes[ind], templateIds[ind])
                        );
                    signedApiUrls[ind] = airnodeToSignedApiUrl[airnodes[ind]];
                }
            }
        }
    }

    /// @notice Returns the number of active data feeds identified by a data
    /// feed ID or dAPI name
    /// @return Active data feed count
    function activeDataFeedCount() external view override returns (uint256) {
        return activeDataFeedIdCount() + activeDapiNameCount();
    }

    /// @notice Returns the number of active data feeds identified by a data
    /// feed ID
    /// @return Active data feed ID count
    function activeDataFeedIdCount() public view override returns (uint256) {
        return activeDataFeedIds.length();
    }

    /// @notice Returns the number of active data feeds identified by a dAPI
    /// name
    /// @return Active dAPI name count
    function activeDapiNameCount() public view override returns (uint256) {
        return activeDapiNames.length();
    }

    /// @notice Data feed ID to update parameters
    /// @param dataFeedId Data feed ID
    /// @return updateParameters Update parameters
    function dataFeedIdToUpdateParameters(
        bytes32 dataFeedId
    ) public view override returns (bytes memory updateParameters) {
        updateParameters = updateParametersHashToValue[
            dataFeedIdToUpdateParametersHash[dataFeedId]
        ];
    }

    /// @notice dAPI name to update parameters
    /// @param dapiName dAPI name
    /// @return updateParameters Update parameters
    function dapiNameToUpdateParameters(
        bytes32 dapiName
    ) public view override returns (bytes memory updateParameters) {
        updateParameters = updateParametersHashToValue[
            dapiNameToUpdateParametersHash[dapiName]
        ];
    }

    /// @notice Returns if the data feed with ID is registered
    /// @param dataFeedId Data feed ID
    /// @return If the data feed with ID is registered
    function dataFeedIsRegistered(
        bytes32 dataFeedId
    ) external view override returns (bool) {
        return dataFeedIdToDetails[dataFeedId].length != 0;
    }

    /// @notice Derives the Beacon ID from the Airnode address and template ID
    /// @param airnode Airnode address
    /// @param templateId Template ID
    /// @return beaconId Beacon ID
    function deriveBeaconId(
        address airnode,
        bytes32 templateId
    ) private pure returns (bytes32 beaconId) {
        beaconId = keccak256(abi.encodePacked(airnode, templateId));
    }

    /// @notice Derives the Beacon set ID from the Beacon IDs
    /// @param beaconIds Beacon IDs
    /// @return beaconSetId Beacon set ID
    function deriveBeaconSetId(
        bytes32[] memory beaconIds
    ) private pure returns (bytes32 beaconSetId) {
        beaconSetId = keccak256(abi.encode(beaconIds));
    }
}

Other files

  • contracts/api3-server-v1/interfaces/IAirseekerRegistry.sol
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    import "../../access/interfaces/IOwnable.sol";
    import "../../utils/interfaces/IExtendedSelfMulticall.sol";
    
    interface IAirseekerRegistry is IOwnable, IExtendedSelfMulticall {
        event ActivatedDataFeedId(bytes32 indexed dataFeedId);
    
        event ActivatedDapiName(bytes32 indexed dapiName);
    
        event DeactivatedDataFeedId(bytes32 indexed dataFeedId);
    
        event DeactivatedDapiName(bytes32 indexed dapiName);
    
        event UpdatedDataFeedIdUpdateParameters(
            bytes32 indexed dataFeedId,
            bytes updateParameters
        );
    
        event UpdatedDapiNameUpdateParameters(
            bytes32 indexed dapiName,
            bytes updateParameters
        );
    
        event UpdatedSignedApiUrl(address indexed airnode, string signedApiUrl);
    
        event RegisteredDataFeed(bytes32 indexed dataFeedId, bytes dataFeedDetails);
    
        function setDataFeedIdToBeActivated(bytes32 dataFeedId) external;
    
        function setDapiNameToBeActivated(bytes32 dapiName) external;
    
        function setDataFeedIdToBeDeactivated(bytes32 dataFeedId) external;
    
        function setDapiNameToBeDeactivated(bytes32 dapiName) external;
    
        function setDataFeedIdUpdateParameters(
            bytes32 dataFeedId,
            bytes calldata updateParameters
        ) external;
    
        function setDapiNameUpdateParameters(
            bytes32 dapiName,
            bytes calldata updateParameters
        ) external;
    
        function setSignedApiUrl(
            address airnode,
            string calldata signedApiUrl
        ) external;
    
        function registerDataFeed(
            bytes calldata dataFeedDetails
        ) external returns (bytes32 dataFeedId);
    
        function activeDataFeed(
            uint256 index
        )
            external
            view
            returns (
                bytes32 dataFeedId,
                bytes32 dapiName,
                bytes memory dataFeedDetails,
                int224 dataFeedValue,
                uint32 dataFeedTimestamp,
                int224[] memory beaconValues,
                uint32[] memory beaconTimestamps,
                bytes memory updateParameters,
                string[] memory signedApiUrls
            );
    
        function activeDataFeedCount() external view returns (uint256);
    
        function activeDataFeedIdCount() external view returns (uint256);
    
        function activeDapiNameCount() external view returns (uint256);
    
        function dataFeedIdToUpdateParameters(
            bytes32 dataFeedId
        ) external view returns (bytes memory updateParameters);
    
        function dapiNameToUpdateParameters(
            bytes32 dapiName
        ) external view returns (bytes memory updateParameters);
    
        function dataFeedIsRegistered(
            bytes32 dataFeedId
        ) external view returns (bool);
    
        function MAXIMUM_BEACON_COUNT_IN_SET() external view returns (uint256);
    
        function MAXIMUM_UPDATE_PARAMETERS_LENGTH() external view returns (uint256);
    
        function MAXIMUM_SIGNED_API_URL_LENGTH() external view returns (uint256);
    
        function api3ServerV1() external view returns (address);
    
        function airnodeToSignedApiUrl(
            address airnode
        ) external view returns (string memory signedApiUrl);
    
        function dataFeedIdToDetails(
            bytes32 dataFeedId
        ) external view returns (bytes memory dataFeedDetails);
    }
    
  • contracts/utils/interfaces/ISelfMulticall.sol
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    interface ISelfMulticall {
        function multicall(
            bytes[] calldata data
        ) external returns (bytes[] memory returndata);
    
        function tryMulticall(
            bytes[] calldata data
        ) external returns (bool[] memory successes, bytes[] memory returndata);
    }
    
  • contracts/access/interfaces/IAccessControlRegistryAdminned.sol
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    import "../../utils/interfaces/ISelfMulticall.sol";
    
    interface IAccessControlRegistryAdminned is ISelfMulticall {
        function accessControlRegistry() external view returns (address);
    
        function adminRoleDescription() external view returns (string memory);
    }
    
  • contracts/access/interfaces/IAccessControlRegistryAdminnedWithManager.sol
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    import "./IAccessControlRegistryAdminned.sol";
    
    interface IAccessControlRegistryAdminnedWithManager is
        IAccessControlRegistryAdminned
    {
        function manager() external view returns (address);
    
        function adminRole() external view returns (bytes32);
    }
    
  • contracts/access/interfaces/IOwnable.sol
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    interface IOwnable {
        function owner() external view returns (address);
    
        function renounceOwnership() external;
    
        function transferOwnership(address newOwner) external;
    }
    
  • contracts/api3-server-v1/interfaces/IApi3ServerV1.sol
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    import "./IOevDapiServer.sol";
    import "./IBeaconUpdatesWithSignedData.sol";
    
    interface IApi3ServerV1 is IOevDapiServer, IBeaconUpdatesWithSignedData {
        function readDataFeedWithId(
            bytes32 dataFeedId
        ) external view returns (int224 value, uint32 timestamp);
    
        function readDataFeedWithDapiNameHash(
            bytes32 dapiNameHash
        ) external view returns (int224 value, uint32 timestamp);
    
        function readDataFeedWithIdAsOevProxy(
            bytes32 dataFeedId
        ) external view returns (int224 value, uint32 timestamp);
    
        function readDataFeedWithDapiNameHashAsOevProxy(
            bytes32 dapiNameHash
        ) external view returns (int224 value, uint32 timestamp);
    
        function dataFeeds(
            bytes32 dataFeedId
        ) external view returns (int224 value, uint32 timestamp);
    
        function oevProxyToIdToDataFeed(
            address proxy,
            bytes32 dataFeedId
        ) external view returns (int224 value, uint32 timestamp);
    }
    
  • contracts/api3-server-v1/interfaces/IBeaconUpdatesWithSignedData.sol
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    import "./IDataFeedServer.sol";
    
    interface IBeaconUpdatesWithSignedData is IDataFeedServer {
        function updateBeaconWithSignedData(
            address airnode,
            bytes32 templateId,
            uint256 timestamp,
            bytes calldata data,
            bytes calldata signature
        ) external returns (bytes32 beaconId);
    }
    
  • contracts/api3-server-v1/interfaces/IDapiServer.sol
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    import "../../access/interfaces/IAccessControlRegistryAdminnedWithManager.sol";
    import "./IDataFeedServer.sol";
    
    interface IDapiServer is
        IAccessControlRegistryAdminnedWithManager,
        IDataFeedServer
    {
        event SetDapiName(
            bytes32 indexed dataFeedId,
            bytes32 indexed dapiName,
            address sender
        );
    
        function setDapiName(bytes32 dapiName, bytes32 dataFeedId) external;
    
        function dapiNameToDataFeedId(
            bytes32 dapiName
        ) external view returns (bytes32);
    
        // solhint-disable-next-line func-name-mixedcase
        function DAPI_NAME_SETTER_ROLE_DESCRIPTION()
            external
            view
            returns (string memory);
    
        function dapiNameSetterRole() external view returns (bytes32);
    
        function dapiNameHashToDataFeedId(
            bytes32 dapiNameHash
        ) external view returns (bytes32 dataFeedId);
    }
    
  • contracts/api3-server-v1/interfaces/IDataFeedServer.sol
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    import "../../utils/interfaces/IExtendedSelfMulticall.sol";
    
    interface IDataFeedServer is IExtendedSelfMulticall {
        event UpdatedBeaconWithSignedData(
            bytes32 indexed beaconId,
            int224 value,
            uint32 timestamp
        );
    
        event UpdatedBeaconSetWithBeacons(
            bytes32 indexed beaconSetId,
            int224 value,
            uint32 timestamp
        );
    
        function updateBeaconSetWithBeacons(
            bytes32[] memory beaconIds
        ) external returns (bytes32 beaconSetId);
    }
    
  • contracts/api3-server-v1/interfaces/IOevDapiServer.sol
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    import "./IOevDataFeedServer.sol";
    import "./IDapiServer.sol";
    
    interface IOevDapiServer is IOevDataFeedServer, IDapiServer {}
    
  • contracts/api3-server-v1/interfaces/IOevDataFeedServer.sol
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    import "./IDataFeedServer.sol";
    
    interface IOevDataFeedServer is IDataFeedServer {
        event UpdatedOevProxyBeaconWithSignedData(
            bytes32 indexed beaconId,
            address indexed proxy,
            bytes32 indexed updateId,
            int224 value,
            uint32 timestamp
        );
    
        event UpdatedOevProxyBeaconSetWithSignedData(
            bytes32 indexed beaconSetId,
            address indexed proxy,
            bytes32 indexed updateId,
            int224 value,
            uint32 timestamp
        );
    
        event Withdrew(
            address indexed oevProxy,
            address oevBeneficiary,
            uint256 amount
        );
    
        function updateOevProxyDataFeedWithSignedData(
            address oevProxy,
            bytes32 dataFeedId,
            bytes32 updateId,
            uint256 timestamp,
            bytes calldata data,
            bytes[] calldata packedOevUpdateSignatures
        ) external payable;
    
        function withdraw(address oevProxy) external;
    
        function oevProxyToBalance(
            address oevProxy
        ) external view returns (uint256 balance);
    }
    
  • contracts/utils/ExtendedSelfMulticall.sol
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.7;
    
    import "./SelfMulticall.sol";
    import "./interfaces/IExtendedSelfMulticall.sol";
    
    /// @title Contract that extends SelfMulticall to fetch some of the global
    /// variables
    /// @notice Available global variables are limited to the ones that Airnode
    /// tends to need
    contract ExtendedSelfMulticall is SelfMulticall, IExtendedSelfMulticall {
        /// @notice Returns the chain ID
        /// @return Chain ID
        function getChainId() external view override returns (uint256) {
            return block.chainid;
        }
    
        /// @notice Returns the account balance
        /// @param account Account address
        /// @return Account balance
        function getBalance(
            address account
        ) external view override returns (uint256) {
            return account.balance;
        }
    
        /// @notice Returns if the account contains bytecode
        /// @dev An account not containing any bytecode does not indicate that it
        /// is an EOA or it will not contain any bytecode in the future.
        /// Contract construction and `SELFDESTRUCT` updates the bytecode at the
        /// end of the transaction.
        /// @return If the account contains bytecode
        function containsBytecode(
            address account
        ) external view override returns (bool) {
            return account.code.length > 0;
        }
    
        /// @notice Returns the current block number
        /// @return Current block number
        function getBlockNumber() external view override returns (uint256) {
            return block.number;
        }
    
        /// @notice Returns the current block timestamp
        /// @return Current block timestamp
        function getBlockTimestamp() external view override returns (uint256) {
            return block.timestamp;
        }
    
        /// @notice Returns the current block basefee
        /// @return Current block basefee
        function getBlockBasefee() external view override returns (uint256) {
            return block.basefee;
        }
    }
    
  • contracts/utils/SelfMulticall.sol
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    import "./interfaces/ISelfMulticall.sol";
    
    /// @title Contract that enables calls to the inheriting contract to be batched
    /// @notice Implements two ways of batching, one requires none of the calls to
    /// revert and the other tolerates individual calls reverting
    /// @dev This implementation uses delegatecall for individual function calls.
    /// Since delegatecall is a message call, it can only be made to functions that
    /// are externally visible. This means that a contract cannot multicall its own
    /// functions that use internal/private visibility modifiers.
    /// Refer to OpenZeppelin's Multicall.sol for a similar implementation.
    contract SelfMulticall is ISelfMulticall {
        /// @notice Batches calls to the inheriting contract and reverts as soon as
        /// one of the batched calls reverts
        /// @param data Array of calldata of batched calls
        /// @return returndata Array of returndata of batched calls
        function multicall(
            bytes[] calldata data
        ) external override returns (bytes[] memory returndata) {
            uint256 callCount = data.length;
            returndata = new bytes[](callCount);
            for (uint256 ind = 0; ind < callCount; ) {
                bool success;
                // solhint-disable-next-line avoid-low-level-calls
                (success, returndata[ind]) = address(this).delegatecall(data[ind]);
                if (!success) {
                    bytes memory returndataWithRevertData = returndata[ind];
                    if (returndataWithRevertData.length > 0) {
                        // Adapted from OpenZeppelin's Address.sol
                        // solhint-disable-next-line no-inline-assembly
                        assembly {
                            let returndata_size := mload(returndataWithRevertData)
                            revert(
                                add(32, returndataWithRevertData),
                                returndata_size
                            )
                        }
                    } else {
                        revert("Multicall: No revert string");
                    }
                }
                unchecked {
                    ind++;
                }
            }
        }
    
        /// @notice Batches calls to the inheriting contract but does not revert if
        /// any of the batched calls reverts
        /// @param data Array of calldata of batched calls
        /// @return successes Array of success conditions of batched calls
        /// @return returndata Array of returndata of batched calls
        function tryMulticall(
            bytes[] calldata data
        )
            external
            override
            returns (bool[] memory successes, bytes[] memory returndata)
        {
            uint256 callCount = data.length;
            successes = new bool[](callCount);
            returndata = new bytes[](callCount);
            for (uint256 ind = 0; ind < callCount; ) {
                // solhint-disable-next-line avoid-low-level-calls
                (successes[ind], returndata[ind]) = address(this).delegatecall(
                    data[ind]
                );
                unchecked {
                    ind++;
                }
            }
        }
    }
    
  • contracts/utils/interfaces/IExtendedSelfMulticall.sol
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    import "./ISelfMulticall.sol";
    
    interface IExtendedSelfMulticall is ISelfMulticall {
        function getChainId() external view returns (uint256);
    
        function getBalance(address account) external view returns (uint256);
    
        function containsBytecode(address account) external view returns (bool);
    
        function getBlockNumber() external view returns (uint256);
    
        function getBlockTimestamp() external view returns (uint256);
    
        function getBlockBasefee() external view returns (uint256);
    }
    
  • contracts/vendor/@openzeppelin/contracts@5.0.2/access/Ownable.sol
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
    
    pragma solidity ^0.8.20;
    
    import {Context} from "../utils/Context.sol";
    
    /**
     * @dev Contract module which provides a basic access control mechanism, where
     * there is an account (an owner) that can be granted exclusive access to
     * specific functions.
     *
     * The initial owner is set to the address provided by the deployer. This can
     * later be changed with {transferOwnership}.
     *
     * This module is used through inheritance. It will make available the modifier
     * `onlyOwner`, which can be applied to your functions to restrict their use to
     * the owner.
     */
    abstract contract Ownable is Context {
        address private _owner;
    
        /**
         * @dev The caller account is not authorized to perform an operation.
         */
        error OwnableUnauthorizedAccount(address account);
    
        /**
         * @dev The owner is not a valid owner account. (eg. `address(0)`)
         */
        error OwnableInvalidOwner(address owner);
    
        event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    
        /**
         * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
         */
        constructor(address initialOwner) {
            if (initialOwner == address(0)) {
                revert OwnableInvalidOwner(address(0));
            }
            _transferOwnership(initialOwner);
        }
    
        /**
         * @dev Throws if called by any account other than the owner.
         */
        modifier onlyOwner() {
            _checkOwner();
            _;
        }
    
        /**
         * @dev Returns the address of the current owner.
         */
        function owner() public view virtual returns (address) {
            return _owner;
        }
    
        /**
         * @dev Throws if the sender is not the owner.
         */
        function _checkOwner() internal view virtual {
            if (owner() != _msgSender()) {
                revert OwnableUnauthorizedAccount(_msgSender());
            }
        }
    
        /**
         * @dev Leaves the contract without owner. It will not be possible to call
         * `onlyOwner` functions. Can only be called by the current owner.
         *
         * NOTE: Renouncing ownership will leave the contract without an owner,
         * thereby disabling any functionality that is only available to the owner.
         */
        function renounceOwnership() public virtual onlyOwner {
            _transferOwnership(address(0));
        }
    
        /**
         * @dev Transfers ownership of the contract to a new account (`newOwner`).
         * Can only be called by the current owner.
         */
        function transferOwnership(address newOwner) public virtual onlyOwner {
            if (newOwner == address(0)) {
                revert OwnableInvalidOwner(address(0));
            }
            _transferOwnership(newOwner);
        }
    
        /**
         * @dev Transfers ownership of the contract to a new account (`newOwner`).
         * Internal function without access restriction.
         */
        function _transferOwnership(address newOwner) internal virtual {
            address oldOwner = _owner;
            _owner = newOwner;
            emit OwnershipTransferred(oldOwner, newOwner);
        }
    }
    
  • contracts/vendor/@openzeppelin/contracts@5.0.2/utils/Context.sol
    // 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;
        }
    }
    
  • contracts/vendor/@openzeppelin/contracts@5.0.2/utils/structs/EnumerableSet.sol
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableSet.sol)
    // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
    
    pragma solidity ^0.8.20;
    
    /**
     * @dev Library for managing
     * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
     * types.
     *
     * Sets have the following properties:
     *
     * - Elements are added, removed, and checked for existence in constant time
     * (O(1)).
     * - Elements are enumerated in O(n). No guarantees are made on the ordering.
     *
     * ```solidity
     * contract Example {
     *     // Add the library methods
     *     using EnumerableSet for EnumerableSet.AddressSet;
     *
     *     // Declare a set state variable
     *     EnumerableSet.AddressSet private mySet;
     * }
     * ```
     *
     * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
     * and `uint256` (`UintSet`) are supported.
     *
     * [WARNING]
     * ====
     * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
     * unusable.
     * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
     *
     * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
     * array of EnumerableSet.
     * ====
     */
    library EnumerableSet {
        // To implement this library for multiple types with as little code
        // repetition as possible, we write it in terms of a generic Set type with
        // bytes32 values.
        // The Set implementation uses private functions, and user-facing
        // implementations (such as AddressSet) are just wrappers around the
        // underlying Set.
        // This means that we can only create new EnumerableSets for types that fit
        // in bytes32.
    
        struct Set {
            // Storage of set values
            bytes32[] _values;
            // Position is the index of the value in the `values` array plus 1.
            // Position 0 is used to mean a value is not in the set.
            mapping(bytes32 value => uint256) _positions;
        }
    
        /**
         * @dev Add a value to a set. O(1).
         *
         * Returns true if the value was added to the set, that is if it was not
         * already present.
         */
        function _add(Set storage set, bytes32 value) private returns (bool) {
            if (!_contains(set, value)) {
                set._values.push(value);
                // The value is stored at length-1, but we add 1 to all indexes
                // and use 0 as a sentinel value
                set._positions[value] = set._values.length;
                return true;
            } else {
                return false;
            }
        }
    
        /**
         * @dev Removes a value from a set. O(1).
         *
         * Returns true if the value was removed from the set, that is if it was
         * present.
         */
        function _remove(Set storage set, bytes32 value) private returns (bool) {
            // We cache the value's position to prevent multiple reads from the same storage slot
            uint256 position = set._positions[value];
    
            if (position != 0) {
                // Equivalent to contains(set, value)
                // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
                // the array, and then remove the last element (sometimes called as 'swap and pop').
                // This modifies the order of the array, as noted in {at}.
    
                uint256 valueIndex = position - 1;
                uint256 lastIndex = set._values.length - 1;
    
                if (valueIndex != lastIndex) {
                    bytes32 lastValue = set._values[lastIndex];
    
                    // Move the lastValue to the index where the value to delete is
                    set._values[valueIndex] = lastValue;
                    // Update the tracked position of the lastValue (that was just moved)
                    set._positions[lastValue] = position;
                }
    
                // Delete the slot where the moved value was stored
                set._values.pop();
    
                // Delete the tracked position for the deleted slot
                delete set._positions[value];
    
                return true;
            } else {
                return false;
            }
        }
    
        /**
         * @dev Returns true if the value is in the set. O(1).
         */
        function _contains(Set storage set, bytes32 value) private view returns (bool) {
            return set._positions[value] != 0;
        }
    
        /**
         * @dev Returns the number of values on the set. O(1).
         */
        function _length(Set storage set) private view returns (uint256) {
            return set._values.length;
        }
    
        /**
         * @dev Returns the value stored at position `index` in the set. O(1).
         *
         * Note that there are no guarantees on the ordering of values inside the
         * array, and it may change when more values are added or removed.
         *
         * Requirements:
         *
         * - `index` must be strictly less than {length}.
         */
        function _at(Set storage set, uint256 index) private view returns (bytes32) {
            return set._values[index];
        }
    
        /**
         * @dev Return the entire set in an array
         *
         * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
         * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
         * this function has an unbounded cost, and using it as part of a state-changing function may render the function
         * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
         */
        function _values(Set storage set) private view returns (bytes32[] memory) {
            return set._values;
        }
    
        // Bytes32Set
    
        struct Bytes32Set {
            Set _inner;
        }
    
        /**
         * @dev Add a value to a set. O(1).
         *
         * Returns true if the value was added to the set, that is if it was not
         * already present.
         */
        function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
            return _add(set._inner, value);
        }
    
        /**
         * @dev Removes a value from a set. O(1).
         *
         * Returns true if the value was removed from the set, that is if it was
         * present.
         */
        function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
            return _remove(set._inner, value);
        }
    
        /**
         * @dev Returns true if the value is in the set. O(1).
         */
        function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
            return _contains(set._inner, value);
        }
    
        /**
         * @dev Returns the number of values in the set. O(1).
         */
        function length(Bytes32Set storage set) internal view returns (uint256) {
            return _length(set._inner);
        }
    
        /**
         * @dev Returns the value stored at position `index` in the set. O(1).
         *
         * Note that there are no guarantees on the ordering of values inside the
         * array, and it may change when more values are added or removed.
         *
         * Requirements:
         *
         * - `index` must be strictly less than {length}.
         */
        function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
            return _at(set._inner, index);
        }
    
        /**
         * @dev Return the entire set in an array
         *
         * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
         * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
         * this function has an unbounded cost, and using it as part of a state-changing function may render the function
         * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
         */
        function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
            bytes32[] memory store = _values(set._inner);
            bytes32[] memory result;
    
            /// @solidity memory-safe-assembly
            assembly {
                result := store
            }
    
            return result;
        }
    
        // AddressSet
    
        struct AddressSet {
            Set _inner;
        }
    
        /**
         * @dev Add a value to a set. O(1).
         *
         * Returns true if the value was added to the set, that is if it was not
         * already present.
         */
        function add(AddressSet storage set, address value) internal returns (bool) {
            return _add(set._inner, bytes32(uint256(uint160(value))));
        }
    
        /**
         * @dev Removes a value from a set. O(1).
         *
         * Returns true if the value was removed from the set, that is if it was
         * present.
         */
        function remove(AddressSet storage set, address value) internal returns (bool) {
            return _remove(set._inner, bytes32(uint256(uint160(value))));
        }
    
        /**
         * @dev Returns true if the value is in the set. O(1).
         */
        function contains(AddressSet storage set, address value) internal view returns (bool) {
            return _contains(set._inner, bytes32(uint256(uint160(value))));
        }
    
        /**
         * @dev Returns the number of values in the set. O(1).
         */
        function length(AddressSet storage set) internal view returns (uint256) {
            return _length(set._inner);
        }
    
        /**
         * @dev Returns the value stored at position `index` in the set. O(1).
         *
         * Note that there are no guarantees on the ordering of values inside the
         * array, and it may change when more values are added or removed.
         *
         * Requirements:
         *
         * - `index` must be strictly less than {length}.
         */
        function at(AddressSet storage set, uint256 index) internal view returns (address) {
            return address(uint160(uint256(_at(set._inner, index))));
        }
    
        /**
         * @dev Return the entire set in an array
         *
         * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
         * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
         * this function has an unbounded cost, and using it as part of a state-changing function may render the function
         * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
         */
        function values(AddressSet storage set) internal view returns (address[] memory) {
            bytes32[] memory store = _values(set._inner);
            address[] memory result;
    
            /// @solidity memory-safe-assembly
            assembly {
                result := store
            }
    
            return result;
        }
    
        // UintSet
    
        struct UintSet {
            Set _inner;
        }
    
        /**
         * @dev Add a value to a set. O(1).
         *
         * Returns true if the value was added to the set, that is if it was not
         * already present.
         */
        function add(UintSet storage set, uint256 value) internal returns (bool) {
            return _add(set._inner, bytes32(value));
        }
    
        /**
         * @dev Removes a value from a set. O(1).
         *
         * Returns true if the value was removed from the set, that is if it was
         * present.
         */
        function remove(UintSet storage set, uint256 value) internal returns (bool) {
            return _remove(set._inner, bytes32(value));
        }
    
        /**
         * @dev Returns true if the value is in the set. O(1).
         */
        function contains(UintSet storage set, uint256 value) internal view returns (bool) {
            return _contains(set._inner, bytes32(value));
        }
    
        /**
         * @dev Returns the number of values in the set. O(1).
         */
        function length(UintSet storage set) internal view returns (uint256) {
            return _length(set._inner);
        }
    
        /**
         * @dev Returns the value stored at position `index` in the set. O(1).
         *
         * Note that there are no guarantees on the ordering of values inside the
         * array, and it may change when more values are added or removed.
         *
         * Requirements:
         *
         * - `index` must be strictly less than {length}.
         */
        function at(UintSet storage set, uint256 index) internal view returns (uint256) {
            return uint256(_at(set._inner, index));
        }
    
        /**
         * @dev Return the entire set in an array
         *
         * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
         * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
         * this function has an unbounded cost, and using it as part of a state-changing function may render the function
         * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
         */
        function values(UintSet storage set) internal view returns (uint256[] memory) {
            bytes32[] memory store = _values(set._inner);
            uint256[] memory result;
    
            /// @solidity memory-safe-assembly
            assembly {
                result := store
            }
    
            return result;
        }
    }
    
ABI · 44 entries
json
[
  {
    "type": "constructor",
    "inputs": [
      {
        "name": "owner_",
        "type": "address",
        "internalType": "address"
      },
      {
        "name": "api3ServerV1_",
        "type": "address",
        "internalType": "address"
      }
    ],
    "stateMutability": "nonpayable"
  },
  {
    "name": "OwnableInvalidOwner",
    "type": "error",
    "inputs": [
      {
        "name": "owner",
        "type": "address",
        "internalType": "address"
      }
    ]
  },
  {
    "name": "OwnableUnauthorizedAccount",
    "type": "error",
    "inputs": [
      {
        "name": "account",
        "type": "address",
        "internalType": "address"
      }
    ]
  },
  {
    "name": "ActivatedDapiName",
    "type": "event",
    "inputs": [
      {
        "name": "dapiName",
        "type": "bytes32",
        "indexed": true,
        "internalType": "bytes32"
      }
    ],
    "anonymous": false
  },
  {
    "name": "ActivatedDataFeedId",
    "type": "event",
    "inputs": [
      {
        "name": "dataFeedId",
        "type": "bytes32",
        "indexed": true,
        "internalType": "bytes32"
      }
    ],
    "anonymous": false
  },
  {
    "name": "DeactivatedDapiName",
    "type": "event",
    "inputs": [
      {
        "name": "dapiName",
        "type": "bytes32",
        "indexed": true,
        "internalType": "bytes32"
      }
    ],
    "anonymous": false
  },
  {
    "name": "DeactivatedDataFeedId",
    "type": "event",
    "inputs": [
      {
        "name": "dataFeedId",
        "type": "bytes32",
        "indexed": true,
        "internalType": "bytes32"
      }
    ],
    "anonymous": false
  },
  {
    "name": "OwnershipTransferred",
    "type": "event",
    "inputs": [
      {
        "name": "previousOwner",
        "type": "address",
        "indexed": true,
        "internalType": "address"
      },
      {
        "name": "newOwner",
        "type": "address",
        "indexed": true,
        "internalType": "address"
      }
    ],
    "anonymous": false
  },
  {
    "name": "RegisteredDataFeed",
    "type": "event",
    "inputs": [
      {
        "name": "dataFeedId",
        "type": "bytes32",
        "indexed": true,
        "internalType": "bytes32"
      },
      {
        "name": "dataFeedDetails",
        "type": "bytes",
        "indexed": false,
        "internalType": "bytes"
      }
    ],
    "anonymous": false
  },
  {
    "name": "UpdatedDapiNameUpdateParameters",
    "type": "event",
    "inputs": [
      {
        "name": "dapiName",
        "type": "bytes32",
        "indexed": true,
        "internalType": "bytes32"
      },
      {
        "name": "updateParameters",
        "type": "bytes",
        "indexed": false,
        "internalType": "bytes"
      }
    ],
    "anonymous": false
  },
  {
    "name": "UpdatedDataFeedIdUpdateParameters",
    "type": "event",
    "inputs": [
      {
        "name": "dataFeedId",
        "type": "bytes32",
        "indexed": true,
        "internalType": "bytes32"
      },
      {
        "name": "updateParameters",
        "type": "bytes",
        "indexed": false,
        "internalType": "bytes"
      }
    ],
    "anonymous": false
  },
  {
    "name": "UpdatedSignedApiUrl",
    "type": "event",
    "inputs": [
      {
        "name": "airnode",
        "type": "address",
        "indexed": true,
        "internalType": "address"
      },
      {
        "name": "signedApiUrl",
        "type": "string",
        "indexed": false,
        "internalType": "string"
      }
    ],
    "anonymous": false
  },
  {
    "name": "MAXIMUM_BEACON_COUNT_IN_SET",
    "type": "function",
    "inputs": [],
    "outputs": [
      {
        "name": "",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "MAXIMUM_SIGNED_API_URL_LENGTH",
    "type": "function",
    "inputs": [],
    "outputs": [
      {
        "name": "",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "MAXIMUM_UPDATE_PARAMETERS_LENGTH",
    "type": "function",
    "inputs": [],
    "outputs": [
      {
        "name": "",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "activeDapiNameCount",
    "type": "function",
    "inputs": [],
    "outputs": [
      {
        "name": "",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "activeDataFeed",
    "type": "function",
    "inputs": [
      {
        "name": "index",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "outputs": [
      {
        "name": "dataFeedId",
        "type": "bytes32",
        "internalType": "bytes32"
      },
      {
        "name": "dapiName",
        "type": "bytes32",
        "internalType": "bytes32"
      },
      {
        "name": "dataFeedDetails",
        "type": "bytes",
        "internalType": "bytes"
      },
      {
        "name": "dataFeedValue",
        "type": "int224",
        "internalType": "int224"
      },
      {
        "name": "dataFeedTimestamp",
        "type": "uint32",
        "internalType": "uint32"
      },
      {
        "name": "beaconValues",
        "type": "int224[]",
        "internalType": "int224[]"
      },
      {
        "name": "beaconTimestamps",
        "type": "uint32[]",
        "internalType": "uint32[]"
      },
      {
        "name": "updateParameters",
        "type": "bytes",
        "internalType": "bytes"
      },
      {
        "name": "signedApiUrls",
        "type": "string[]",
        "internalType": "string[]"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "activeDataFeedCount",
    "type": "function",
    "inputs": [],
    "outputs": [
      {
        "name": "",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "activeDataFeedIdCount",
    "type": "function",
    "inputs": [],
    "outputs": [
      {
        "name": "",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "airnodeToSignedApiUrl",
    "type": "function",
    "inputs": [
      {
        "name": "",
        "type": "address",
        "internalType": "address"
      }
    ],
    "outputs": [
      {
        "name": "",
        "type": "string",
        "internalType": "string"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "api3ServerV1",
    "type": "function",
    "inputs": [],
    "outputs": [
      {
        "name": "",
        "type": "address",
        "internalType": "address"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "containsBytecode",
    "type": "function",
    "inputs": [
      {
        "name": "account",
        "type": "address",
        "internalType": "address"
      }
    ],
    "outputs": [
      {
        "name": "",
        "type": "bool",
        "internalType": "bool"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "dapiNameToUpdateParameters",
    "type": "function",
    "inputs": [
      {
        "name": "dapiName",
        "type": "bytes32",
        "internalType": "bytes32"
      }
    ],
    "outputs": [
      {
        "name": "updateParameters",
        "type": "bytes",
        "internalType": "bytes"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "dataFeedIdToDetails",
    "type": "function",
    "inputs": [
      {
        "name": "",
        "type": "bytes32",
        "internalType": "bytes32"
      }
    ],
    "outputs": [
      {
        "name": "",
        "type": "bytes",
        "internalType": "bytes"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "dataFeedIdToUpdateParameters",
    "type": "function",
    "inputs": [
      {
        "name": "dataFeedId",
        "type": "bytes32",
        "internalType": "bytes32"
      }
    ],
    "outputs": [
      {
        "name": "updateParameters",
        "type": "bytes",
        "internalType": "bytes"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "dataFeedIsRegistered",
    "type": "function",
    "inputs": [
      {
        "name": "dataFeedId",
        "type": "bytes32",
        "internalType": "bytes32"
      }
    ],
    "outputs": [
      {
        "name": "",
        "type": "bool",
        "internalType": "bool"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "getBalance",
    "type": "function",
    "inputs": [
      {
        "name": "account",
        "type": "address",
        "internalType": "address"
      }
    ],
    "outputs": [
      {
        "name": "",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "getBlockBasefee",
    "type": "function",
    "inputs": [],
    "outputs": [
      {
        "name": "",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "getBlockNumber",
    "type": "function",
    "inputs": [],
    "outputs": [
      {
        "name": "",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "getBlockTimestamp",
    "type": "function",
    "inputs": [],
    "outputs": [
      {
        "name": "",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "getChainId",
    "type": "function",
    "inputs": [],
    "outputs": [
      {
        "name": "",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "multicall",
    "type": "function",
    "inputs": [
      {
        "name": "data",
        "type": "bytes[]",
        "internalType": "bytes[]"
      }
    ],
    "outputs": [
      {
        "name": "returndata",
        "type": "bytes[]",
        "internalType": "bytes[]"
      }
    ],
    "stateMutability": "nonpayable"
  },
  {
    "name": "owner",
    "type": "function",
    "inputs": [],
    "outputs": [
      {
        "name": "",
        "type": "address",
        "internalType": "address"
      }
    ],
    "stateMutability": "view"
  },
  {
    "name": "registerDataFeed",
    "type": "function",
    "inputs": [
      {
        "name": "dataFeedDetails",
        "type": "bytes",
        "internalType": "bytes"
      }
    ],
    "outputs": [
      {
        "name": "dataFeedId",
        "type": "bytes32",
        "internalType": "bytes32"
      }
    ],
    "stateMutability": "nonpayable"
  },
  {
    "name": "renounceOwnership",
    "type": "function",
    "inputs": [],
    "outputs": [],
    "stateMutability": "pure"
  },
  {
    "name": "setDapiNameToBeActivated",
    "type": "function",
    "inputs": [
      {
        "name": "dapiName",
        "type": "bytes32",
        "internalType": "bytes32"
      }
    ],
    "outputs": [],
    "stateMutability": "nonpayable"
  },
  {
    "name": "setDapiNameToBeDeactivated",
    "type": "function",
    "inputs": [
      {
        "name": "dapiName",
        "type": "bytes32",
        "internalType": "bytes32"
      }
    ],
    "outputs": [],
    "stateMutability": "nonpayable"
  },
  {
    "name": "setDapiNameUpdateParameters",
    "type": "function",
    "inputs": [
      {
        "name": "dapiName",
        "type": "bytes32",
        "internalType": "bytes32"
      },
      {
        "name": "updateParameters",
        "type": "bytes",
        "internalType": "bytes"
      }
    ],
    "outputs": [],
    "stateMutability": "nonpayable"
  },
  {
    "name": "setDataFeedIdToBeActivated",
    "type": "function",
    "inputs": [
      {
        "name": "dataFeedId",
        "type": "bytes32",
        "internalType": "bytes32"
      }
    ],
    "outputs": [],
    "stateMutability": "nonpayable"
  },
  {
    "name": "setDataFeedIdToBeDeactivated",
    "type": "function",
    "inputs": [
      {
        "name": "dataFeedId",
        "type": "bytes32",
        "internalType": "bytes32"
      }
    ],
    "outputs": [],
    "stateMutability": "nonpayable"
  },
  {
    "name": "setDataFeedIdUpdateParameters",
    "type": "function",
    "inputs": [
      {
        "name": "dataFeedId",
        "type": "bytes32",
        "internalType": "bytes32"
      },
      {
        "name": "updateParameters",
        "type": "bytes",
        "internalType": "bytes"
      }
    ],
    "outputs": [],
    "stateMutability": "nonpayable"
  },
  {
    "name": "setSignedApiUrl",
    "type": "function",
    "inputs": [
      {
        "name": "airnode",
        "type": "address",
        "internalType": "address"
      },
      {
        "name": "signedApiUrl",
        "type": "string",
        "internalType": "string"
      }
    ],
    "outputs": [],
    "stateMutability": "nonpayable"
  },
  {
    "name": "transferOwnership",
    "type": "function",
    "inputs": [
      {
        "name": "",
        "type": "address",
        "internalType": "address"
      }
    ],
    "outputs": [],
    "stateMutability": "pure"
  },
  {
    "name": "tryMulticall",
    "type": "function",
    "inputs": [
      {
        "name": "data",
        "type": "bytes[]",
        "internalType": "bytes[]"
      }
    ],
    "outputs": [
      {
        "name": "successes",
        "type": "bool[]",
        "internalType": "bool[]"
      },
      {
        "name": "returndata",
        "type": "bytes[]",
        "internalType": "bytes[]"
      }
    ],
    "stateMutability": "nonpayable"
  }
]