Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 85 additions & 85 deletions contracts/gas-snapshots/llo-feeds.gas-snapshot

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {AccessControllerInterface} from "../../../../shared/interfaces/AccessCon
import {VerifierProxy} from "../../../v0.3.0/VerifierProxy.sol";
import {BaseTest} from "./BaseVerifierTest.t.sol";

contract VerifierProxyConstructorTest is BaseTest {
contract VerifierProxyConstructorTestV03 is BaseTest {
function test_correctlySetsTheOwner() public {
VerifierProxy proxy = new VerifierProxy(AccessControllerInterface(address(0)));
assertEq(proxy.owner(), ADMIN);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity 0.8.19;
import {AccessControllerInterface} from "../../../../shared/interfaces/AccessControllerInterface.sol";
import {BaseTest} from "./BaseVerifierTest.t.sol";

contract VerifierProxySetAccessControllerTest is BaseTest {
contract VerifierProxySetAccessControllerTestV03 is BaseTest {
event AccessControllerSet(address oldAccessController, address newAccessController);

function test_revertsIfCalledByNonOwner() public {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity 0.8.19;
import {VerifierProxy} from "../../../v0.3.0/VerifierProxy.sol";
import {BaseTest, BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol";

contract VerifierProxyUnsetVerifierTest is BaseTest {
contract VerifierProxyUnsetVerifierTestV03 is BaseTest {
function test_revertsIfNotAdmin() public {
vm.expectRevert("Only callable by owner");

Expand All @@ -18,7 +18,7 @@ contract VerifierProxyUnsetVerifierTest is BaseTest {
}
}

contract VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest is BaseTestWithConfiguredVerifierAndFeeManager {
contract VerifierProxyUnsetVerifierWithPreviouslySetVerifierTestV03 is BaseTestWithConfiguredVerifierAndFeeManager {
bytes32 internal s_configDigest;

event VerifierUnset(bytes32 configDigest, address verifierAddr);
Expand Down
126 changes: 126 additions & 0 deletions contracts/src/v0.8/llo-feeds/v0.5.0/NoOpFeeManager.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol";
import {Common} from "../libraries/Common.sol";
import {IFeeManager} from "./interfaces/IFeeManager.sol";
import {IVerifierFeeManager} from "./interfaces/IVerifierFeeManager.sol";
import {IERC165} from "@openzeppelin/[email protected]/interfaces/IERC165.sol";

/**
* @title NoOpFeeManager
* @notice A no-op implementation of IFeeManager that does not collect fees.
* @dev All functions return successfully without performing any fee collection or state changes.
* Any ETH sent to payable functions is refunded to the subscriber.
*/
contract NoOpFeeManager is IFeeManager, ITypeAndVersion {
/// @notice Error thrown when ETH refund fails
error RefundFailed();

/// @notice The scalar representing 100% discount (1e18 = 100%)
uint64 private constant PERCENTAGE_SCALAR = 1e18;

/// @inheritdoc ITypeAndVersion
function typeAndVersion() external pure override returns (string memory) {
return "NoOpFeeManager 0.5.0";
}

/// @inheritdoc IERC165
function supportsInterface(
bytes4 interfaceId
) external pure override returns (bool) {
return interfaceId == this.processFee.selector || interfaceId == this.processFeeBulk.selector;
}

/// @inheritdoc IVerifierFeeManager
function processFee(bytes calldata, bytes calldata, address subscriber) external payable override {
// Refund any ETH sent
_refund(subscriber);
}

/// @inheritdoc IVerifierFeeManager
function processFeeBulk(bytes[] calldata, bytes calldata, address subscriber) external payable override {
// Refund any ETH sent
_refund(subscriber);
}

/// @inheritdoc IVerifierFeeManager
function setFeeRecipients(bytes32, Common.AddressAndWeight[] calldata) external override {
// No-op
}

/// @inheritdoc IFeeManager
function getFeeAndReward(
address,
bytes memory,
address
) external pure override returns (Common.Asset memory fee, Common.Asset memory reward, uint256 appliedDiscount) {
// Return zero fee, zero reward, 100% discount (1e18) to indicate no fees are charged
return (fee, reward, PERCENTAGE_SCALAR);
}

/// @inheritdoc IFeeManager
function setNativeSurcharge(
uint64
) external override {
// No-op
}

/// @inheritdoc IFeeManager
function updateSubscriberDiscount(address, bytes32, address, uint64) external override {
// No-op
}

/// @inheritdoc IFeeManager
function withdraw(address, address, uint192) external override {
// No-op
}

/// @inheritdoc IFeeManager
function linkAvailableForPayment() external pure override returns (uint256) {
return 0;
}

/// @inheritdoc IFeeManager
function payLinkDeficit(
bytes32
) external override {
// No-op
}

/// @inheritdoc IFeeManager
function updateSubscriberGlobalDiscount(address, address, uint64) external override {
// No-op
}

/**
* @notice Returns 100% discount for any subscriber/feedId/token combination
* @dev Replicates public mapping getter signature from FeeManager for backwards compatibility
*/
// solhint-disable-next-line func-name-mixedcase
function s_subscriberDiscounts(address, bytes32, address) external pure returns (uint256) {
return PERCENTAGE_SCALAR;
}

/**
* @notice Returns 100% discount for any subscriber/token combination
* @dev Replicates public mapping getter signature from FeeManager for backwards compatibility
*/
// solhint-disable-next-line func-name-mixedcase
function s_globalDiscounts(address, address) external pure returns (uint256) {
return PERCENTAGE_SCALAR;
}

/**
* @notice Refunds any ETH sent to the contract
* @param recipient The address to refund ETH to
*/
function _refund(
address recipient
) internal {
if (msg.value > 0) {
(bool success,) = payable(recipient).call{value: msg.value}("");
if (!success) revert RefundFailed();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,144 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.19;
pragma solidity 0.8.19;

import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol";
import {EnumerableSet} from "@openzeppelin/[email protected]/utils/structs/EnumerableSet.sol";

import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol";
import {IChannelConfigStore} from "./interfaces/IChannelConfigStore.sol";

contract ChannelConfigStore is ConfirmedOwner, IChannelConfigStore, ITypeAndVersion {
// This contract uses uint32 for donIds when they are function arguments and
// uint256 elsewhere (e.g. in storage or event params). This inconsistency is
// ugly, but we maintain it for backwards compatibility.

using EnumerableSet for EnumerableSet.UintSet;

event NewChannelDefinition(uint256 indexed donId, uint32 version, string url, bytes32 sha);
event ChannelDefinitionAdded(uint256 indexed donId, ChannelAdderId indexed channelAdderId, string url, bytes32 sha);
event ChannelAdderSet(uint256 indexed donId, ChannelAdderId indexed channelAdderId, bool allowed);
event ChannelAdderAddressSet(ChannelAdderId indexed channelAdderId, address adderAddress);

/// @notice Thrown when a caller is not authorized to add channel definitions.
error UnauthorizedChannelAdder();

/// @notice Thrown when a ChannelAdderId is reserved.
error ReservedChannelAdderId();

// We reserve the ChannelAdderIds 0 through 999. 1 is used by the offchain code to internally
// represent the owner. The others are reserved for future use.
ChannelAdderId internal constant MIN_CHANNEL_ADDER_ID = ChannelAdderId.wrap(1000);

constructor() ConfirmedOwner(msg.sender) {}

/// @notice The version of a channel definition keyed by DON ID
// Increments by 1 on every update
/// @notice The version of a channel definition keyed by DON ID.
// Increments by 1 on every update.
mapping(uint256 => uint256) internal s_channelDefinitionVersions;

/// @notice Mapping from channel adder ID to its corresponding address
mapping(ChannelAdderId => address) internal s_channelAdderAddresses;

/// @notice Mapping from DON ID to the set of allowed channel adder IDs
mapping(uint256 => EnumerableSet.UintSet) internal s_allowedChannelAdders;

/// @notice Allows the owner to arbitrarily set channel definitions to the specified DON.
/// Unlike the channel adder, the owner can not only add, but also modify and delete
/// channel definitions. The DON enforces (in its consensus rules), that the channel
/// definitions provided by the owner are well-formed.
/// @param donId The DON ID
/// @param url The URL of the channel definition
/// @param sha The SHA hash of the channel definition
function setChannelDefinitions(uint32 donId, string calldata url, bytes32 sha) external onlyOwner {
uint32 newVersion = uint32(++s_channelDefinitionVersions[uint256(donId)]);
emit NewChannelDefinition(donId, newVersion, url, sha);
}

/// @notice Allows a channel adder to add channel definitions to the specified DON.
/// The DON enforces (in its consensus rules), that the channel definitions provided
/// by the channel adder are well-formed, purely additive, and do not overload the DON.
/// @param donId The DON ID
/// @param channelAdderId The channel adder ID
/// @param url The URL of the channel definition
/// @param sha The SHA hash of the channel definition
function addChannelDefinitions(
uint32 donId,
ChannelAdderId channelAdderId,
string calldata url,
bytes32 sha
) external {
if (msg.sender != s_channelAdderAddresses[channelAdderId]) {
revert UnauthorizedChannelAdder();
}
if (!s_allowedChannelAdders[donId].contains(ChannelAdderId.unwrap(channelAdderId))) {
revert UnauthorizedChannelAdder();
}
emit ChannelDefinitionAdded(donId, channelAdderId, url, sha);
}

/// @notice Sets the address for a channel adder ID
/// @param channelAdderId The channel adder ID
/// @param adderAddress The address to associate with the channel adder ID.
/// Set this to the zero address (or some other address that cannot make
/// calls) to disable the channel adder.
function setChannelAdderAddress(ChannelAdderId channelAdderId, address adderAddress) external onlyOwner {
if (ChannelAdderId.unwrap(channelAdderId) < ChannelAdderId.unwrap(MIN_CHANNEL_ADDER_ID)) {
revert ReservedChannelAdderId();
}
s_channelAdderAddresses[channelAdderId] = adderAddress;
emit ChannelAdderAddressSet(channelAdderId, adderAddress);
}

/// @notice Sets whether a channel adder ID is allowed for a DON
/// @param donId The DON ID
/// @param channelAdderId The channel adder ID
/// @param allowed Whether the channel adder should be allowed or removed
function setChannelAdder(uint32 donId, ChannelAdderId channelAdderId, bool allowed) external onlyOwner {
if (ChannelAdderId.unwrap(channelAdderId) < ChannelAdderId.unwrap(MIN_CHANNEL_ADDER_ID)) {
revert ReservedChannelAdderId();
}
if (allowed) {
s_allowedChannelAdders[donId].add(ChannelAdderId.unwrap(channelAdderId));
} else {
s_allowedChannelAdders[donId].remove(ChannelAdderId.unwrap(channelAdderId));
}
emit ChannelAdderSet(donId, channelAdderId, allowed);
}

/// @notice Gets the address associated with a channel adder ID
/// @param channelAdderId The channel adder ID
/// @return The address associated with the channel adder ID
function getChannelAdderAddress(
ChannelAdderId channelAdderId
) external view returns (address) {
return s_channelAdderAddresses[channelAdderId];
}

/// @notice Checks if a channel adder is allowed for a DON
/// @param donId The DON ID
/// @param channelAdderId The channel adder ID
/// @return True if the channel adder is allowed for the DON
function isChannelAdderAllowed(uint32 donId, ChannelAdderId channelAdderId) external view returns (bool) {
return s_allowedChannelAdders[donId].contains(ChannelAdderId.unwrap(channelAdderId));
}

/// @notice Gets all allowed channel adder IDs for a DON
/// @param donId The DON ID
/// @return allowedChannelAdderIds An array of allowed channel adder IDs
function getAllowedChannelAdders(
uint32 donId
) external view returns (ChannelAdderId[] memory allowedChannelAdderIds) {
// Not very gas efficient, but we don't expect this function to be called
// from onchain anyways.
uint256[] memory values = s_allowedChannelAdders[donId].values();
allowedChannelAdderIds = new ChannelAdderId[](values.length);
for (uint256 i = 0; i < values.length; i++) {
allowedChannelAdderIds[i] = ChannelAdderId.wrap(uint32(values[i]));
}
return allowedChannelAdderIds;
}

function typeAndVersion() external pure override returns (string memory) {
return "ChannelConfigStore 0.0.1";
return "ChannelConfigStore 1.0.0";
}

function supportsInterface(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,22 @@ pragma solidity 0.8.19;
import {IERC165} from "@openzeppelin/[email protected]/interfaces/IERC165.sol";

interface IChannelConfigStore is IERC165 {
type ChannelAdderId is uint32;

function setChannelDefinitions(uint32 donId, string calldata url, bytes32 sha) external;
function addChannelDefinitions(
uint32 donId,
ChannelAdderId channelAdderId,
string calldata url,
bytes32 sha
) external;
function setChannelAdderAddress(ChannelAdderId channelAdderId, address adderAddress) external;
function setChannelAdder(uint32 donId, ChannelAdderId channelAdderId, bool allowed) external;
function getChannelAdderAddress(
ChannelAdderId channelAdderId
) external view returns (address);
function isChannelAdderAllowed(uint32 donId, ChannelAdderId channelAdderId) external view returns (bool);
function getAllowedChannelAdders(
uint32 donId
) external view returns (ChannelAdderId[] memory);
}
Loading
Loading